about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorgareth <gareth@gareth-N56VM.(none)>2013-04-11 21:51:39 +0100
committergareth <gareth@gareth-N56VM.(none)>2013-04-11 21:51:39 +0100
commit995d44416b203b5b3ba619250ff8effdcf205049 (patch)
treed0313bebcaf8bb7ed331865c52abb923c899b8b1 /src
parent483e95a35c9f3ab01666de4808134af26fded68c (diff)
downloadrust-995d44416b203b5b3ba619250ff8effdcf205049.tar.gz
rust-995d44416b203b5b3ba619250ff8effdcf205049.zip
Make destroy() send SIGTERM and add a new method called
force_destroy() that sends SIGKILL - as suggested by 
@thestinger.
Diffstat (limited to 'src')
-rw-r--r--src/libcore/libc.rs3
-rw-r--r--src/libcore/run.rs53
2 files changed, 44 insertions, 12 deletions
diff --git a/src/libcore/libc.rs b/src/libcore/libc.rs
index e17a6be3f1f..02c72bcd2f0 100644
--- a/src/libcore/libc.rs
+++ b/src/libcore/libc.rs
@@ -864,6 +864,7 @@ pub mod consts {
             pub static F_TLOCK : int = 2;
             pub static F_ULOCK : int = 0;
             pub static SIGKILL : int = 9;
+            pub static SIGTERM : int = 15;
         }
         pub mod posix01 {
         }
@@ -932,6 +933,7 @@ pub mod consts {
             pub static F_TLOCK : int = 2;
             pub static F_ULOCK : int = 0;
             pub static SIGKILL : int = 9;
+            pub static SIGTERM : int = 15;
         }
         pub mod posix01 {
         }
@@ -1001,6 +1003,7 @@ pub mod consts {
             pub static F_TLOCK : int = 2;
             pub static F_ULOCK : int = 0;
             pub static SIGKILL : int = 9;
+            pub static SIGTERM : int = 15;
         }
         pub mod posix01 {
         }
diff --git a/src/libcore/run.rs b/src/libcore/run.rs
index e7602cff492..f6f4b9a397d 100644
--- a/src/libcore/run.rs
+++ b/src/libcore/run.rs
@@ -63,10 +63,22 @@ pub trait Program {
     fn finish(&mut self) -> int;
 
     /**
-     * Forcibly terminate the program. On Posix OSs SIGKILL will be sent
-     * to the process. On Win32 TerminateProcess(..) will be called.
+     * Terminate the program, giving it a chance to clean itself up if
+     * this is supported by the operating system.
+     *
+     * On Posix OSs SIGTERM will be sent to the process. On Win32
+     * TerminateProcess(..) will be called.
      */
     fn destroy(&mut self);
+
+    /**
+     * Terminate the program as soon as possible without giving it a
+     * chance to clean itself up.
+     *
+     * On Posix OSs SIGKILL will be sent to the process. On Win32
+     * TerminateProcess(..) will be called.
+     */
+    fn force_destroy(&mut self);
 }
 
 
@@ -266,13 +278,13 @@ pub fn start_program(prog: &str, args: &[~str]) -> @Program {
         return waitpid(r.pid);
     }
 
-    fn destroy_repr(r: &mut ProgRepr) {
-        killpid(r.pid);
+    fn destroy_repr(r: &mut ProgRepr, force: bool) {
+        killpid(r.pid, force);
         finish_repr(&mut *r);
         close_repr_outputs(&mut *r);
 
         #[cfg(windows)]
-        fn killpid(pid: pid_t) {
+        fn killpid(pid: pid_t, _force: bool) {
             unsafe {
                 libc::funcs::extra::kernel32::TerminateProcess(
                     cast::transmute(pid), 1);
@@ -280,10 +292,16 @@ pub fn start_program(prog: &str, args: &[~str]) -> @Program {
         }
 
         #[cfg(unix)]
-        fn killpid(pid: pid_t) {
+        fn killpid(pid: pid_t, force: bool) {
+
+            let signal = if force {
+                libc::consts::os::posix88::SIGKILL
+            } else {
+                libc::consts::os::posix88::SIGTERM
+            };
+
             unsafe {
-                libc::funcs::posix88::signal::kill(
-                    pid, libc::consts::os::posix88::SIGKILL as c_int);
+                libc::funcs::posix88::signal::kill(pid, signal as c_int);
             }
         }
     }
@@ -321,7 +339,8 @@ pub fn start_program(prog: &str, args: &[~str]) -> @Program {
         }
         fn close_input(&mut self) { close_repr_input(&mut self.r); }
         fn finish(&mut self) -> int { finish_repr(&mut self.r) }
-        fn destroy(&mut self) { destroy_repr(&mut self.r); }
+        fn destroy(&mut self) { destroy_repr(&mut self.r, false); }
+        fn force_destroy(&mut self) { destroy_repr(&mut self.r, true); }
     }
 
     let mut repr = ProgRepr {
@@ -559,10 +578,9 @@ mod tests {
         p.destroy(); // ...and nor should this (and nor should the destructor)
     }
 
-    #[test]
     #[cfg(unix)] // there is no way to sleep on windows from inside libcore...
-    pub fn test_destroy_actually_kills() {
-        let path = Path("test/core-run-test-destroy-actually-kills.tmp");
+    pub fn test_destroy_actually_kills(force: bool) {
+        let path = Path(fmt!("test/core-run-test-destroy-actually-kills-%?.tmp", force));
 
         os::remove_file(&path);
 
@@ -580,6 +598,17 @@ mod tests {
         assert!(!path.exists());
     }
 
+    #[test]
+    #[cfg(unix)]
+    pub fn test_unforced_destroy_actually_kills() {
+        test_destroy_actually_kills(false);
+    }
+
+    #[test]
+    #[cfg(unix)]
+    pub fn test_forced_destroy_actually_kills() {
+        test_destroy_actually_kills(true);
+    }
 }
 
 // Local Variables: