about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/io/process.rs29
-rw-r--r--src/libstd/libc.rs6
2 files changed, 32 insertions, 3 deletions
diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs
index 2da79eba7bc..4f4d2d793f6 100644
--- a/src/libstd/io/process.rs
+++ b/src/libstd/io/process.rs
@@ -331,7 +331,9 @@ impl Process {
     /// signals (SIGTERM/SIGKILL/SIGINT) are translated to `TerminateProcess`.
     ///
     /// Additionally, a signal number of 0 can check for existence of the target
-    /// process.
+    /// process. Note, though, that on some platforms signals will continue to
+    /// be successfully delivered if the child has exited, but not yet been
+    /// reaped.
     pub fn kill(id: libc::pid_t, signal: int) -> IoResult<()> {
         LocalIo::maybe_raise(|io| io.kill(id, signal))
     }
@@ -342,8 +344,16 @@ impl Process {
     /// Sends the specified signal to the child process, returning whether the
     /// signal could be delivered or not.
     ///
-    /// Note that this is purely a wrapper around libuv's `uv_process_kill`
-    /// function.
+    /// Note that signal 0 is interpreted as a poll to check whether the child
+    /// process is still alive or not. If an error is returned, then the child
+    /// process has exited.
+    ///
+    /// On some unix platforms signals will continue to be received after a
+    /// child has exited but not yet been reaped. In order to report the status
+    /// of signal delivery correctly, unix implementations may invoke
+    /// `waitpid()` with `WNOHANG` in order to reap the child as necessary.
+    ///
+    /// # Errors
     ///
     /// If the signal delivery fails, the corresponding error is returned.
     pub fn signal(&mut self, signal: int) -> IoResult<()> {
@@ -833,4 +843,17 @@ mod tests {
         p.signal_kill().unwrap();
         assert!(!p.wait().success());
     })
+
+    iotest!(fn test_zero() {
+        let mut p = sleeper();
+        p.signal_kill().unwrap();
+        for _ in range(0, 20) {
+            if p.signal(0).is_err() {
+                assert!(!p.wait().success());
+                return
+            }
+            timer::sleep(100);
+        }
+        fail!("never saw the child go away");
+    })
 }
diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs
index 42221f07449..972002fe34e 100644
--- a/src/libstd/libc.rs
+++ b/src/libstd/libc.rs
@@ -2356,6 +2356,8 @@ pub mod consts {
 
             pub static CLOCK_REALTIME: c_int = 0;
             pub static CLOCK_MONOTONIC: c_int = 1;
+
+            pub static WNOHANG: c_int = 1;
         }
         pub mod posix08 {
         }
@@ -2802,6 +2804,8 @@ pub mod consts {
 
             pub static CLOCK_REALTIME: c_int = 0;
             pub static CLOCK_MONOTONIC: c_int = 4;
+
+            pub static WNOHANG: c_int = 1;
         }
         pub mod posix08 {
         }
@@ -3187,6 +3191,8 @@ pub mod consts {
             pub static PTHREAD_CREATE_JOINABLE: c_int = 1;
             pub static PTHREAD_CREATE_DETACHED: c_int = 2;
             pub static PTHREAD_STACK_MIN: size_t = 8192;
+
+            pub static WNOHANG: c_int = 1;
         }
         pub mod posix08 {
         }