Change:
Now a tracking issue for on Windows. Open questions: Should we provide a method of adding* flags as opposed to setting them entirely? Would be a bit more composition-friendly. Also, don't forget to add to the prelude when stabilizing! There's a currently-unused codepath in the Windows implementation of that can set : It looks like historically there was a method to set this but it got removed. Unfortunately there's currently no way to set this, and no other way to set the flags, so for a project I'm working on I basically had to reimplement for Windows: I think we need some way to set this, even if it's Windows-specific. There are a bunch of other flags that can be specified, so maybe a way to set arbitrary flags would be useful? (v=vs.85).aspx I think this would fit nicely onto a Windows equivalent of the  trait, maybe something like:
Seems reasonable to me!
I'm always in favor of adding more Windows specific extension traits to expose useful functionality that other platforms don't seem to have.
I have a patch, it just took me a while to write a test for it. I'm trying to sort out the stability annotations for the new APIs--can I just use this issue as the tracking issue for the new feature?
Sure!
To the open question: I had first written the API as originally proposed: with a method to set the flags directly. Then I thought that might make it difficult if callers wanted to set different flags in different places, so I split it into and methods, but Alex asked me to change it back. I'm not sure it's that important, I don't think there are that many process creation flags that it would be useful to set from a library context, and callers can always aggregate flags into a u32 and just call with that value.
fcp merge With the one remaining open question I think it's safe to stabilize as this is still consistent with our approach to custom flags in other areas of platform-specific extensions as well.
Team member has proposed to merge this. The next step is review by the rest of the tagged teams: [x] [x] [x] [x] [x] [x] No concerns currently listed. Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
:bell: This is now entering its final comment period, as per the . :bell: psst I wasn't able to add the label, please do so.

Discussion:
Ok(_) => panic!(), } } <ins> /// 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"exitrn").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); } </ins> }

use os::windows::io::{FromRawHandle, RawHandle, AsRawHandle, IntoRawHandle}; use process; use sys; <del> use sys_common::{AsInner, FromInner, IntoInner}; </del> <ins> use sys_common::{AsInnerMut, AsInner, FromInner, IntoInner}; </ins> #[stable(feature = "process_extensions", since = "1.2.0")] impl FromRawHandle for process::Stdio {

process::ExitStatus::from_inner(From::from(raw)) } } <ins> /// Windows-specific extensions to the `std::process::Command` builder #[unstable(feature = "windows_process_extensions", issue = "37827")] pub trait CommandExt { /// Sets the [process creation flags][1] to be passed to `CreateProcess`. /// /// These will always be ORed with `CREATE_UNICODE_ENVIRONMENT`. /// [1]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx #[unstable(feature = "windows_process_extensions", issue = "37827")] fn creation_flags(&mut self, flags: u32) -> &mut process::Command; } #[unstable(feature = "windows_process_extensions", issue = "37827")] impl CommandExt for process::Command { fn creation_flags(&mut self, flags: u32) -> &mut process::Command { self.as_inner_mut().creation_flags(flags); self } } </ins>

args: Vec<OsString>, env: Option<HashMap<OsString, OsString>>, cwd: Option<OsString>, <ins> flags: u32, </ins> detach: bool, // not currently exposed in std::process stdin: Option<Stdio>, stdout: Option<Stdio>,

args: Vec::new(), env: None, cwd: None, <ins> flags: 0, </ins> detach: false, stdin: None, stdout: None,

pub fn stderr(&mut self, stderr: Stdio) { self.stderr = Some(stderr); } <ins> pub fn creation_flags(&mut self, flags: u32) { self.flags = flags; } </ins> pub fn spawn(&mut self, default: Stdio, needs_stdin: bool) -> io::Result<(Process, StdioPipes)> {

cmd_str.push(0); // add null terminator // stolen from the libuv code. <del> let mut flags = c::CREATE_UNICODE_ENVIRONMENT; </del> <ins> let mut flags = self.flags | c::CREATE_UNICODE_ENVIRONMENT; </ins> if self.detach { flags |= c::DETACHED_PROCESS | c::CREATE_NEW_PROCESS_GROUP; }