aboutsummaryrefslogtreecommitdiff
path: root/src/command.rs
diff options
context:
space:
mode:
authorMatias Linares <matiaslina@openmailbox.org>2015-11-08 23:02:00 -0300
committerMatias Linares <matiaslina@openmailbox.org>2015-11-08 23:02:00 -0300
commitacf4a04b7452b6dd2e69064b4f85144b8445bbe9 (patch)
treeaef2d5caab26bab04b300ef232ca75578716fa7f /src/command.rs
downloaddotwm-acf4a04b7452b6dd2e69064b4f85144b8445bbe9.tar.gz
Initial commit
This initial commit has the following: * We can spawn a terminal. * Given a new window, we can move it around the screen, but only the window that was created, all the other windows disappear on the void, so.. :( and that's it
Diffstat (limited to 'src/command.rs')
-rw-r--r--src/command.rs47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/command.rs b/src/command.rs
new file mode 100644
index 0000000..ddfa269
--- /dev/null
+++ b/src/command.rs
@@ -0,0 +1,47 @@
+//! Command execution module.
+//!
+use std::ffi::OsStr;
+use std::process::{Command,Child};
+use std::io::{Result, Error, ErrorKind};
+
+use libc::c_int;
+use libc::types::os::arch::posix88::pid_t;
+
+const WNOHANG: c_int = 0x00000001;
+
+extern {
+ /// wait for a child process to stop or terminate.
+ 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<bool>;
+}
+
+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<bool> {
+ 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<S: AsRef<OsStr>>(program: S, args: &[S]) -> Result<Child> {
+ Command::new(program).args(args).spawn()
+}