Function nc::fork

source ·
pub unsafe fn fork() -> Result<pid_t, Errno>
Expand description

Create a child process.

§Example

let pid = unsafe { nc::fork() };
assert!(pid.is_ok());
let pid = pid.unwrap();
assert!(pid >= 0);
Examples found in repository?
examples/pidfd.rs (line 24)
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());
    }
}