alacritty

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit cadbb86eb78854d4aff2e7b38089d75067e41b96
parent f57bd6e12f7e94b767b34a208c66dc88c93f704e
Author: Vineeth Sagar <39757522+vsag96@users.noreply.github.com>
Date:   Fri,  7 Dec 2018 03:08:34 +0530

Detach Child process to avoid zombie processes

This makes use of the common double-fork behavior to prevent
spawning zombie processes every time a URL is clicked.

Diffstat:
MCHANGELOG.md | 1+
Msrc/input.rs | 29+++++------------------------
Msrc/util.rs | 43++++++++++++++++++++++++++++---------------
3 files changed, 34 insertions(+), 39 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed a bad type conversion which could cause underflow on a window resize - Alacritty now spawns a login shell on macOS, as with Terminal.app and iTerm2 +- Fixed zombie processes sticking around after launching URLs ## Version 0.2.3 diff --git a/src/input.rs b/src/input.rs @@ -20,10 +20,7 @@ //! determine what to do when a non-modifier key is pressed. use std::borrow::Cow; use std::mem; -use std::process::Command; use std::time::Instant; -#[cfg(not(windows))] -use std::os::unix::process::CommandExt; use copypasta::{Clipboard, Load, Buffer as ClipboardBuffer}; use glutin::{ElementState, MouseButton, TouchPhase, MouseScrollDelta, ModifiersState, KeyboardInput}; @@ -35,6 +32,7 @@ use index::{Line, Column, Side, Point}; use term::SizeInfo; use term::mode::TermMode; use util::fmt::Red; +use util::start_daemon; pub const FONT_SIZE_STEP: f32 = 0.5; @@ -239,26 +237,9 @@ impl Action { Action::Command(ref program, ref args) => { trace!("running command: {} {:?}", program, args); - #[cfg(not(windows))] - let spawned = Command::new(program) - .args(args) - .before_exec(|| { - // Detach forked process from Alacritty. This will cause - // init or whatever to clean up child processes for us. - unsafe { ::libc::daemon(1, 0); } - Ok(()) - }) - .spawn(); - - #[cfg(windows)] - let spawned = Command::new(program) - .args(args) - .spawn(); - - match spawned - { - Ok(child) => { - debug!("spawned new proc with pid: {}", child.id()); + match start_daemon(program, args) { + Ok(_) => { + debug!("spawned new proc"); }, Err(err) => { warn!("couldn't run command: {}", err); @@ -557,7 +538,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> { let mut args = launcher.args().to_vec(); args.push(text); - match Command::new(launcher.program()).args(&args).spawn() { + match start_daemon(launcher.program(), &args) { Ok(_) => debug!("Launched: {} {:?}", launcher.program(), args), Err(_) => warn!("Unable to launch: {} {:?}", launcher.program(), args), } diff --git a/src/util.rs b/src/util.rs @@ -11,25 +11,20 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -use std::cmp; - -#[cfg(not(feature = "nightly"))] -#[inline(always)] -pub unsafe fn unlikely(x: bool) -> bool { - x -} - -#[cfg(feature = "nightly")] -pub use ::std::intrinsics::unlikely; +#[cfg(not(windows))] +use std::os::unix::process::CommandExt; +use std::process::Command; +use std::{cmp, io}; /// Threading utilities pub mod thread { /// Like `thread::spawn`, but with a `name` argument pub fn spawn_named<F, T, S>(name: S, f: F) -> ::std::thread::JoinHandle<T> - where F: FnOnce() -> T, - F: Send + 'static, - T: Send + 'static, - S: Into<String> + where + F: FnOnce() -> T, + F: Send + 'static, + T: Send + 'static, + S: Into<String>, { ::std::thread::Builder::new() .name(name.into()) @@ -37,7 +32,7 @@ pub mod thread { .expect("thread spawn works") } - pub use ::std::thread::*; + pub use std::thread::*; } pub fn limit<T: Ord>(value: T, min: T, max: T) -> T { @@ -81,6 +76,24 @@ pub mod fmt { } } +#[cfg(not(windows))] +pub fn start_daemon(program: &str, args: &[String]) -> io::Result<()> { + Command::new(program) + .args(args) + .before_exec(|| unsafe { + ::libc::daemon(1, 0); + Ok(()) + }) + .spawn()? + .wait() + .map(|_| ()) +} + +#[cfg(windows)] +pub fn start_daemon(program: &str, args: &[String]) -> io::Result<()> { + Command::new(program).args(args).spawn().map(|_| ()) +} + #[cfg(test)] mod tests { use super::limit;