From 1c3e06f29ad59c084c00725bf7041c2af126b22d Mon Sep 17 00:00:00 2001 From: Matias Linares Date: Sun, 15 Nov 2015 21:21:23 -0300 Subject: Clean of zombie process. The spawn of process within the exec_cmd function now are handled by a new function (collect_zombies). For reference, this code was taken from the _zombie_ crate. --- Cargo.lock | 11 ++++++++--- src/command.rs | 40 ++++++++++++---------------------------- src/dotwm.rs | 4 +++- src/main.rs | 3 ++- 4 files changed, 25 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4058f90..b881a57 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,8 +2,8 @@ name = "dotwm" version = "0.1.0" dependencies = [ - "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "x11 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "x11 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -11,6 +11,11 @@ name = "libc" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "libc" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "pkg-config" version = "0.3.6" @@ -18,7 +23,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "x11" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/command.rs b/src/command.rs index fe42b22..09259af 100644 --- a/src/command.rs +++ b/src/command.rs @@ -2,10 +2,11 @@ //! use std::ffi::OsStr; use std::process::{Command,Child}; -use std::io::{Result, Error, ErrorKind}; +use std::io::Result; use libc::c_int; use libc::pid_t; +use std::ptr; const WNOHANG: c_int = 0x00000001; @@ -14,34 +15,17 @@ extern { pub fn waitpid(pid: pid_t, stat_loc: *mut c_int, options: c_int) -> pid_t; } -/// Extension to the Child struct that allows to check the status without block the -/// current thread. -pub trait ChildExt { - fn wait_nohang(&mut self) -> Result; -} - -impl ChildExt for Child { - /// Checks if the calling child is a zombie and try to kill it, returning - /// if it was killed or not. - fn wait_nohang(&mut self) -> Result { - let mut stat = 0i32; - let pid = unsafe { waitpid(self.id() as i32, &mut stat, WNOHANG) }; - if pid < 0 { - Err(Error::new(ErrorKind::NotFound, format!("pid not found {}", pid))) - } else { - if pid > 0 { - Ok(self.wait() - .map(|x| { - x.success() - }).unwrap_or(false)) - } else { - Ok(false) - } - } - } -} - /// Executes the given command. pub fn exec_cmd>(program: S, args: &[S]) -> Result { Command::new(program).args(args).spawn() } + +/// Collect all the zombies. There's no need to add another dependency for this +/// since it's trivial to implement. +/// +/// See https://github.com/Kintaro/zombie for reference. +pub fn collect_zombies() { + unsafe { + while waitpid(-1, ptr::null_mut(), WNOHANG) > 0 {} + }; +} diff --git a/src/dotwm.rs b/src/dotwm.rs index e94b17f..d528899 100644 --- a/src/dotwm.rs +++ b/src/dotwm.rs @@ -29,10 +29,12 @@ unsafe extern "C" fn error_handler(d: *mut Display, evptr: *mut XErrorEvent) -> } pub struct DotWM { + /// Reference to the X display. pub display: *mut Display, + /// References to all the windows. + pub window_list: Vec, // Map with the keys as (key, mod) cw_idx: usize, - pub window_list: Vec, } /// DotWM state. diff --git a/src/main.rs b/src/main.rs index 02df6fd..4a0c545 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,7 @@ pub mod dotwm; pub mod event; use dotwm::DotWM; -use command::exec_cmd; +use command::{exec_cmd,collect_zombies}; use event::{Event,next_event}; use safe_x11::grab_key; @@ -157,5 +157,6 @@ fn main() { }, _ => (), } + collect_zombies(); } } -- cgit v1.2.3-70-g09d2