1
2
3
4
5
6
7
8
9
10
11
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
use libc;
use std::process::exit;
pub enum Fork {
Parent(libc::pid_t),
Child,
}
pub fn fork() -> Result<Fork, libc::pid_t> {
let res = unsafe { libc::fork() };
match res {
-1 => Err(res),
0 => Ok(Fork::Child),
res => Ok(Fork::Parent(res)),
}
}
pub fn setsid() -> Result<libc::pid_t, libc::pid_t> {
let res = unsafe { libc::setsid() };
match res {
-1 => Err(res),
res => Ok(res),
}
}
pub fn daemon() -> Result<Fork, libc::pid_t> {
match fork() {
Ok(Fork::Parent(_)) => exit(0),
Ok(Fork::Child) => match setsid() {
Ok(_) => fork(),
Err(n) => Err(n),
},
Err(n) => Err(n),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_fork() {
match fork() {
Ok(Fork::Parent(child)) => assert!(child > 0),
Ok(Fork::Child) => println!("child process"),
Err(_) => assert!(false),
}
}
}