Function nc::exit

source ·
pub unsafe fn exit(status: i32) -> !
Expand description

Terminate current process.

§Example

unsafe { nc::exit(0); }
Examples found in repository?
examples/mprotect.rs (line 70)
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
fn main() {
    // Register SIGSEGV handler.
    let sa = nc::sigaction_t {
        sa_handler: handle_segfault as nc::sighandler_t,
        sa_flags: nc::SA_SIGINFO,
        ..nc::sigaction_t::default()
    };
    let mut old_sa = nc::sigaction_t::default();
    let ret = unsafe {
        nc::rt_sigaction(
            nc::SIGSEGV,
            &sa,
            &mut old_sa,
            mem::size_of::<nc::sigset_t>(),
        )
    };
    assert!(ret.is_ok());

    // Initialize an anonymous mapping with 4 pages.
    let map_length = 4 * nc::PAGE_SIZE;
    #[cfg(target_arch = "arm")]
    let addr = unsafe {
        nc::mmap2(
            0,
            map_length,
            nc::PROT_READ | nc::PROT_WRITE,
            nc::MAP_PRIVATE | nc::MAP_ANONYMOUS,
            -1,
            0,
        )
    };

    #[cfg(not(target_arch = "arm"))]
    let addr = unsafe {
        nc::mmap(
            0,
            map_length,
            nc::PROT_READ | nc::PROT_WRITE,
            nc::MAP_PRIVATE | nc::MAP_ANONYMOUS,
            -1,
            0,
        )
    };
    assert!(addr.is_ok());
    let addr = addr.unwrap();

    // Set the third page readonly. And we will run into SIGSEGV when updating it.
    let ret = unsafe { nc::mprotect(addr + 2 * nc::PAGE_SIZE, nc::PAGE_SIZE, nc::PROT_READ) };
    assert!(ret.is_ok());

    for p in addr..(addr + map_length) {
        unsafe {
            *(p as *mut u8) = 42;
        }
    }

    let ret = unsafe { nc::munmap(addr, map_length) };
    assert!(ret.is_ok());
    unsafe { nc::exit(0) };
}
More examples
Hide additional examples
examples/tee.rs (line 91)
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
fn main() {
    let output_file = "/tmp/nc-splice";
    let ret = unsafe {
        nc::openat(
            nc::AT_FDCWD,
            output_file,
            nc::O_WRONLY | nc::O_CREAT | nc::O_TRUNC,
            0o644,
        )
    };
    assert!(ret.is_ok());
    let fd = ret.unwrap();

    // Tee stdin to stdout
    loop {
        let stdin_fileno = 0;
        let stdout_fileno = 1;
        let ret = unsafe {
            nc::tee(
                stdin_fileno,
                stdout_fileno,
                usize::MAX,
                nc::SPLICE_F_NONBLOCK,
            )
        };
        let mut tee_len = match ret {
            Ok(0) => break,
            Err(nc::EAGAIN) => continue,
            Err(errno) => {
                eprintln!("tee error: {}", nc::strerror(errno));
                unsafe { nc::exit(1) };
            }
            Ok(len) => len,
        };

        // Consume stdin by splicing it to a file.
        while tee_len > 0 {
            let ret = unsafe {
                nc::splice(
                    stdin_fileno,
                    None,
                    fd,
                    None,
                    tee_len as usize,
                    nc::SPLICE_F_MOVE,
                )
            };
            match ret {
                Err(errno) => {
                    eprintln!("splice error: {}", nc::strerror(errno));
                    break;
                }
                Ok(len) => tee_len -= len,
            }
        }
    }

    let ret = unsafe { nc::close(fd) };
    assert!(ret.is_ok());
}
examples/pidfd.rs (line 55)
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
fn run_main() {
    const STDOUT_FD: i32 = 1;

    let pid = unsafe { nc::fork() };
    assert!(pid.is_ok());
    if pid == Ok(0) {
        let curr_pid = unsafe { nc::getpid() };
        println!("In child process, pid: {}", curr_pid);
        let path = "/tmp/nc-pidfdopen";
        let fd = unsafe {
            nc::openat(
                nc::AT_FDCWD,
                path,
                nc::O_CREAT | nc::O_WRONLY | nc::O_TRUNC,
                0o644,
            )
        };
        assert!(fd.is_ok());
        let fd = fd.unwrap();
        let ret = unsafe { nc::dup3(fd, STDOUT_FD, 0) };
        assert!(ret.is_ok());
        println!("[child] stdout redirected to file!");

        let t = nc::timespec_t {
            tv_sec: 2,
            tv_nsec: 0,
        };
        unsafe {
            let ret = nc::nanosleep(&t, None);
            assert!(ret.is_ok());
            let ret = nc::close(fd);
            assert!(ret.is_ok());
            let ret = nc::unlinkat(nc::AT_FDCWD, path, 0);
            assert!(ret.is_ok());
            nc::exit(0);
        }
    }

    let pid = pid.unwrap();
    println!("[parent] child pid: {}", pid);

    let t = nc::timespec_t {
        tv_sec: 2,
        tv_nsec: 0,
    };
    let ret = unsafe { nc::nanosleep(&t, None) };
    assert!(ret.is_ok());

    let pidfd = unsafe { nc::pidfd_open(pid, 0) };
    assert!(pidfd.is_ok());
    let pidfd = pidfd.unwrap();

    let ret = unsafe { nc::pidfd_getfd(pidfd, STDOUT_FD, 0) };
    println!("ret: {:?}", ret);
    if let Err(errno) = ret {
        eprintln!("pidfd_getfd() failed, err: {}", nc::strerror(errno));
    }
    let child_stdout_fd = ret.unwrap();
    let msg = "Hello, msg from parent process\n";
    let ret = unsafe { nc::write(child_stdout_fd, msg.as_ptr() as usize, msg.len()) };
    assert!(ret.is_ok());
    let nwrite = ret.unwrap();
    assert_eq!(nwrite as usize, msg.len());

    let mut info = nc::siginfo_t::default();
    let ret = unsafe { nc::pidfd_send_signal(pidfd, nc::SIGKILL, &mut info, 0) };
    println!("ret: {:?}", ret);
    if let Err(errno) = ret {
        eprintln!("pidfd_send_signal() failed, err: {}", nc::strerror(errno));
    }

    unsafe {
        let ret = nc::close(pidfd);
        assert!(ret.is_ok());
        let ret = nc::close(child_stdout_fd);
        assert!(ret.is_ok());
    }
}