diff options
Diffstat (limited to 'alacritty/src/daemon.rs')
-rw-r--r-- | alacritty/src/daemon.rs | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/alacritty/src/daemon.rs b/alacritty/src/daemon.rs new file mode 100644 index 00000000..4a6b6f83 --- /dev/null +++ b/alacritty/src/daemon.rs @@ -0,0 +1,76 @@ +use std::ffi::OsStr; +use std::fmt::Debug; +use std::io; +#[cfg(not(windows))] +use std::os::unix::process::CommandExt; +#[cfg(windows)] +use std::os::windows::process::CommandExt; +use std::process::{Command, Stdio}; + +use log::{debug, warn}; + +#[cfg(windows)] +use winapi::um::winbase::{CREATE_NEW_PROCESS_GROUP, CREATE_NO_WINDOW}; + +/// Start the daemon and log error on failure. +pub fn start_daemon<I, S>(program: &str, args: I) +where + I: IntoIterator<Item = S> + Debug + Copy, + S: AsRef<OsStr>, +{ + match spawn_daemon(program, args) { + Ok(_) => debug!("Launched {} with args {:?}", program, args), + Err(_) => warn!("Unable to launch {} with args {:?}", program, args), + } +} + +#[cfg(windows)] +fn spawn_daemon<I, S>(program: &str, args: I) -> io::Result<()> +where + I: IntoIterator<Item = S> + Copy, + S: AsRef<OsStr>, +{ + // Setting all the I/O handles to null and setting the + // CREATE_NEW_PROCESS_GROUP and CREATE_NO_WINDOW has the effect + // that console applications will run without opening a new + // console window. + Command::new(program) + .args(args) + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .creation_flags(CREATE_NEW_PROCESS_GROUP | CREATE_NO_WINDOW) + .spawn() + .map(|_| ()) +} + +#[cfg(not(windows))] +fn spawn_daemon<I, S>(program: &str, args: I) -> io::Result<()> +where + I: IntoIterator<Item = S> + Copy, + S: AsRef<OsStr>, +{ + unsafe { + Command::new(program) + .args(args) + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .pre_exec(|| { + match libc::fork() { + -1 => return Err(io::Error::last_os_error()), + 0 => (), + _ => libc::_exit(0), + } + + if libc::setsid() == -1 { + return Err(io::Error::last_os_error()); + } + + Ok(()) + }) + .spawn()? + .wait() + .map(|_| ()) + } +} |