Skip to main content

c/
daemon.rs

1// Copyright (c) 2026 Meng Zhuo
2// SPDX-License-Identifier: BSD-3-Clause
3
4// daemon() - ported from musl/src/legacy/daemon.c
5// Included from libc/src/lib.rs in the "unistd.h: process primitives" section.
6
7const ROOT_PATH: &[u8] = b"/\0";
8const DEV_NULL: &[u8] = b"/dev/null\0";
9
10#[no_mangle]
11pub unsafe extern "C" fn daemon(nochdir: c_int, noclose: c_int) -> c_int {
12    if nochdir == 0 {
13        let r = sys_chdir(ROOT_PATH.as_ptr());
14        if r < 0 {
15            ERRNO!() = (-r) as c_int;
16            return -1;
17        }
18    }
19    if noclose == 0 {
20        let fd = sys_open(DEV_NULL.as_ptr(), O_RDWR as i64, 0);
21        if fd < 0 {
22            ERRNO!() = (-fd) as c_int;
23            return -1;
24        }
25        let mut failed = false;
26        let mut err = 0i64;
27        let r0 = sys_dup2(fd as i32, 0);
28        if r0 < 0 {
29            failed = true;
30            err = -r0;
31        }
32        let r1 = sys_dup2(fd as i32, 1);
33        if r1 < 0 && !failed {
34            failed = true;
35            err = -r1;
36        }
37        let r2 = sys_dup2(fd as i32, 2);
38        if r2 < 0 && !failed {
39            failed = true;
40            err = -r2;
41        }
42        if fd > 2 {
43            sys_close(fd);
44        }
45        if failed {
46            ERRNO!() = err as c_int;
47            return -1;
48        }
49    }
50    let ret = sys_fork();
51    match ret {
52        0 => {}
53        -1 => {
54            ERRNO!() = (-ret) as c_int;
55            return -1;
56        }
57        _ => _exit(0),
58    }
59    let r = sys_setsid();
60    if r < 0 {
61        ERRNO!() = (-r) as c_int;
62        return -1;
63    }
64    let ret = sys_fork();
65    match ret {
66        0 => {}
67        -1 => {
68            ERRNO!() = (-ret) as c_int;
69            return -1;
70        }
71        _ => _exit(0),
72    }
73    0
74}