diff options
| author | bors <bors@rust-lang.org> | 2016-12-05 06:53:56 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-12-05 06:53:56 +0000 |
| commit | b4f4b65f9934b2728e9be0c02855aba3b31ad311 (patch) | |
| tree | b016cf9e2fc2c3bd023d3d014e1966589a83ddad /src/libstd/process.rs | |
| parent | 6bc551a261de4b62a50761e624dc8fd27c85c4ce (diff) | |
| parent | e6975e974841c59a6e67e8a158b306f29d35d513 (diff) | |
| download | rust-b4f4b65f9934b2728e9be0c02855aba3b31ad311.tar.gz rust-b4f4b65f9934b2728e9be0c02855aba3b31ad311.zip | |
Auto merge of #38098 - luser:windows-commandext, r=alexcrichton
Add std::os::windows::process::CommandExt. Fixes #37827 This adds a CommandExt trait for Windows along with an implementation of it for std::process::Command with methods to set the process creation flags that are passed to CreateProcess.
Diffstat (limited to 'src/libstd/process.rs')
| -rw-r--r-- | src/libstd/process.rs | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 9e1b57c7412..bfc36d5b21f 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1167,4 +1167,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); + } } |
