about summary refs log tree commit diff
path: root/src/libstd/process.rs
diff options
context:
space:
mode:
authorJeremy Soller <jackpot51@gmail.com>2016-12-12 14:55:09 -0700
committerJeremy Soller <jackpot51@gmail.com>2016-12-12 14:55:09 -0700
commit7e7775ce7bfc916ce723bd1fdaf4ae54662c6627 (patch)
tree235a9c38e42bacdb671da33bc49ffc8a4aba17a4 /src/libstd/process.rs
parentc61baa0fc7a85bd2bcce34aac05ed739261cf037 (diff)
parent6483bdd860fd89fc68846d4cc94c7ae3307a84c1 (diff)
downloadrust-7e7775ce7bfc916ce723bd1fdaf4ae54662c6627.tar.gz
rust-7e7775ce7bfc916ce723bd1fdaf4ae54662c6627.zip
Merge branch 'master' into redox
Diffstat (limited to 'src/libstd/process.rs')
-rw-r--r--src/libstd/process.rs74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index c99fda9febc..858537dd2de 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -253,6 +253,14 @@ impl Command {
     /// Builder methods are provided to change these defaults and
     /// otherwise configure the process.
     ///
+    /// If `program` is not an absolute path, the `PATH` will be searched in
+    /// an OS-defined way.
+    ///
+    /// The search path to be used may be controlled by setting the
+    /// `PATH` environment variable on the Command,
+    /// but this has some implementation limitations on Windows
+    /// (see https://github.com/rust-lang/rust/issues/37519).
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -819,6 +827,14 @@ impl Child {
 /// will be run. If a clean shutdown is needed it is recommended to only call
 /// this function at a known point where there are no more destructors left
 /// to run.
+///
+/// # Examples
+///
+/// ```
+/// use std::process;
+///
+/// process::exit(0);
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn exit(code: i32) -> ! {
     ::sys_common::cleanup();
@@ -1159,4 +1175,62 @@ mod tests {
             Ok(_) => panic!(),
         }
     }
+
+    /// Test that process creation flags work by debugging a process.
+    /// Other creation flags make it hard or impossible to detect
+    /// behavioral changes in the process.
+    #[test]
+    #[cfg(windows)]
+    fn test_creation_flags() {
+        use os::windows::process::CommandExt;
+        use sys::c::{BOOL, DWORD, INFINITE};
+        #[repr(C, packed)]
+        struct DEBUG_EVENT {
+            pub event_code: DWORD,
+            pub process_id: DWORD,
+            pub thread_id: DWORD,
+            // This is a union in the real struct, but we don't
+            // need this data for the purposes of this test.
+            pub _junk: [u8; 164],
+        }
+
+        extern "system" {
+            fn WaitForDebugEvent(lpDebugEvent: *mut DEBUG_EVENT, dwMilliseconds: DWORD) -> BOOL;
+            fn ContinueDebugEvent(dwProcessId: DWORD, dwThreadId: DWORD,
+                                  dwContinueStatus: DWORD) -> BOOL;
+        }
+
+        const DEBUG_PROCESS: DWORD = 1;
+        const EXIT_PROCESS_DEBUG_EVENT: DWORD = 5;
+        const DBG_EXCEPTION_NOT_HANDLED: DWORD = 0x80010001;
+
+        let mut child = Command::new("cmd")
+            .creation_flags(DEBUG_PROCESS)
+            .stdin(Stdio::piped()).spawn().unwrap();
+        child.stdin.take().unwrap().write_all(b"exit\r\n").unwrap();
+        let mut events = 0;
+        let mut event = DEBUG_EVENT {
+            event_code: 0,
+            process_id: 0,
+            thread_id: 0,
+            _junk: [0; 164],
+        };
+        loop {
+            if unsafe { WaitForDebugEvent(&mut event as *mut DEBUG_EVENT, INFINITE) } == 0 {
+                panic!("WaitForDebugEvent failed!");
+            }
+            events += 1;
+
+            if event.event_code == EXIT_PROCESS_DEBUG_EVENT {
+                break;
+            }
+
+            if unsafe { ContinueDebugEvent(event.process_id,
+                                           event.thread_id,
+                                           DBG_EXCEPTION_NOT_HANDLED) } == 0 {
+                panic!("ContinueDebugEvent failed!");
+            }
+        }
+        assert!(events > 0);
+    }
 }