aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/daemon.rs
diff options
context:
space:
mode:
authorKirill Chibisov <contact@kchibisov.com>2020-07-10 22:32:44 +0300
committerGitHub <noreply@github.com>2020-07-10 22:32:44 +0300
commit8bd2c13490f8cb6ad6b0c1104f9586b3554efea2 (patch)
tree6909d3be00c72c3c5acdd173aa7f411a1bc6b445 /alacritty/src/daemon.rs
parentb78f3d133960dad38ad21e808723e51661b59881 (diff)
downloadr-alacritty-8bd2c13490f8cb6ad6b0c1104f9586b3554efea2.tar.gz
r-alacritty-8bd2c13490f8cb6ad6b0c1104f9586b3554efea2.tar.bz2
r-alacritty-8bd2c13490f8cb6ad6b0c1104f9586b3554efea2.zip
Add option to run command on bell
Fixes #1528.
Diffstat (limited to 'alacritty/src/daemon.rs')
-rw-r--r--alacritty/src/daemon.rs76
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(|_| ())
+ }
+}