cyfs_util/process/
daemon.rs1#[cfg(unix)]
2pub mod daemon {
3 use cyfs_base::BuckyError;
4
5 use std::process::{exit, Command};
6
7 use nix::{
8 sys::wait::{waitpid, WaitStatus},
9 unistd::{fork, setsid, ForkResult},
10 };
11
12 pub fn launch_as_daemon(cmd_line: &str) -> Result<(), BuckyError> {
13 let ret = unsafe { fork() }.map_err(|e| {
14 let msg = format!("fork error: {}", e);
15 error!("{}", msg);
16
17 BuckyError::from(msg)
18 })?;
19
20 match ret {
21 ForkResult::Parent { child } => {
22 info!("fork child as daemon success: {}", child);
23
24 match waitpid(child, None) {
25 Ok(status) => {
26 info!("fork child exit: {} {:?}", child, status);
27 if let WaitStatus::Exited(_pid, code) = status {
28 if code == 0 {
29 return Ok(());
30 }
31 }
32
33 let msg = format!("fork child but wait error: {}, {:?}", child, status);
34 error!("{}", msg);
35
36 Err(BuckyError::from(msg))
37 }
38 Err(e) => {
39 let msg = format!("fork child wait error: {} {}", child, e);
40 error!("{}", msg);
41
42 Err(BuckyError::from(msg))
43 }
44 }
45 }
46
47 ForkResult::Child => {
48 match setsid() {
49 Ok(sid) => {
50 info!("new sid: {}", sid);
51 }
52 Err(e) => {
53 error!("setsid error: {}", e);
54 exit(1);
55 }
56 }
57
58 let mut parts: Vec<&str> = crate::ProcessUtil::parse_cmd(cmd_line);
59 assert!(parts.len() > 0);
60
61 let mut cmd = Command::new(parts[0]);
62 if parts.len() > 1 {
63 parts.remove(0);
64 cmd.args(&parts);
65 }
66
67 let code = match cmd.spawn() {
68 Ok(_) => {
69 info!("spawn daemon success!");
70 0
71 }
72 Err(err) => {
73 error!("spawn daemon error: {}", err);
74 1
75 }
76 };
77
78 exit(code);
79 }
80 }
81 }
82}
83
84#[cfg(windows)]
85pub mod daemon {
86 use cyfs_base::BuckyError;
87 use std::process::{Command, Stdio};
88
89 pub fn launch_as_daemon(cmd_line: &str) -> Result<(), BuckyError> {
90 let mut parts: Vec<&str> = crate::ProcessUtil::parse_cmd(cmd_line);
91 assert!(parts.len() > 0);
92
93 let mut cmd = Command::new(parts[0]);
94 if parts.len() > 1 {
95 parts.remove(0);
96 cmd.args(&parts);
97 }
98
99 crate::ProcessUtil::detach(&mut cmd);
100
101 cmd.stdin(Stdio::null())
102 .stdout(Stdio::null())
103 .stderr(Stdio::null());
104
105 match cmd.spawn() {
106 Ok(_) => {
107 info!("spawn as daemon success: {}", cmd_line);
108
109 Ok(())
110 }
111 Err(err) => {
112 let msg = format!("spawn as daemon error: {} {}", cmd_line, err);
113 error!("{}", msg);
114
115 Err(BuckyError::from(msg))
116 }
117 }
118 }
119}