From 3de73589d1c4b8f1b28e5e5d2b0c08259aa19643 Mon Sep 17 00:00:00 2001 From: Vlad Krasnov Date: Tue, 26 Mar 2019 09:36:11 -0400 Subject: [PATCH 1/2] Allow an action by the master process right before exit --- src/lib.rs | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4ff3414de..8f535ec72 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,6 +34,7 @@ //! .umask(0o777) // Set umask, `0o027` by default. //! .stdout(stdout) // Redirect stdout to `/tmp/daemon.out`. //! .stderr(stderr) // Redirect stderr to `/tmp/daemon.err`. +//! .exit_action(|| println!("Executed before master process exits")) //! .privileged_action(|| "Executed before drop privileges"); //! //! match daemonize.start() { @@ -249,6 +250,7 @@ pub struct Daemonize { umask: mode_t, root: Option, privileged_action: Box T>, + exit_action: Box, stdin: Stdio, stdout: Stdio, stderr: Stdio, @@ -282,6 +284,7 @@ impl Daemonize<()> { group: None, umask: 0o027, privileged_action: Box::new(|| ()), + exit_action: Box::new(|| ()), root: None, stdin: Stdio::devnull(), stdout: Stdio::devnull(), @@ -342,6 +345,14 @@ impl Daemonize { new } + /// Execute `action` just before exiting the parent process. Most common usecase is to syncronize with + /// forked processes. + pub fn exit_action(self, action: F) -> Daemonize { + let mut new: Daemonize = unsafe { transmute(self) }; + new.exit_action = Box::new(action); + new + } + /// Configuration for the child process's standard output stream. pub fn stdout>(mut self, stdio: S) -> Self { self.stdout = stdio.into(); @@ -370,13 +381,13 @@ impl Daemonize { unsafe { let pid_file_fd = maptry!(self.pid_file.clone(), create_pid_file); - try!(perform_fork()); + try!(self.perform_fork(true)); - try!(set_current_dir(self.directory).map_err(|_| DaemonizeError::ChangeDirectory)); + try!(set_current_dir(&self.directory).map_err(|_| DaemonizeError::ChangeDirectory)); try!(set_sid()); umask(self.umask); - try!(perform_fork()); + try!(self.perform_fork(false)); try!(redirect_standard_streams(self.stdin, self.stdout, self.stderr)); @@ -408,17 +419,20 @@ impl Daemonize { } } -} - -unsafe fn perform_fork() -> Result<()> { - let pid = fork(); - if pid < 0 { - Err(DaemonizeError::Fork) - } else if pid == 0 { - Ok(()) - } else { - exit(0) + unsafe fn perform_fork(&self, do_exit_action: bool) -> Result<()> { + let pid = fork(); + if pid < 0 { + Err(DaemonizeError::Fork) + } else if pid == 0 { + Ok(()) + } else { + if do_exit_action { + (self.exit_action)(); + } + exit(0) + } } + } unsafe fn set_sid() -> Result<()> { From ef41fbee7b494a551255174c7d60af16a91e15f5 Mon Sep 17 00:00:00 2001 From: Vlad Krasnov Date: Tue, 26 Mar 2019 12:17:03 -0400 Subject: [PATCH 2/2] Resolve issues --- src/lib.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8f535ec72..69cef4240 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -345,12 +345,11 @@ impl Daemonize { new } - /// Execute `action` just before exiting the parent process. Most common usecase is to syncronize with + /// Execute `action` just before exiting the parent process. Most common usecase is to synchronize with /// forked processes. - pub fn exit_action(self, action: F) -> Daemonize { - let mut new: Daemonize = unsafe { transmute(self) }; - new.exit_action = Box::new(action); - new + pub fn exit_action(mut self, action: F) -> Daemonize { + self.exit_action = Box::new(action); + self } /// Configuration for the child process's standard output stream.