Rollup merge of #47760 - little-dude:master, r=alexcrichton

implement Send for process::Command on unix

closes https://github.com/rust-lang/rust/issues/47751
This commit is contained in:
kennytm
2018-01-30 17:10:53 +08:00
committed by GitHub
2 changed files with 17 additions and 5 deletions
+6
View File
@@ -1843,4 +1843,10 @@ fn ContinueDebugEvent(dwProcessId: DWORD, dwThreadId: DWORD,
}
assert!(events > 0);
}
#[test]
fn test_command_implements_send() {
fn take_send_type<T: Send>(_: T) {}
take_send_type(Command::new(""))
}
}
+11 -5
View File
@@ -45,7 +45,7 @@ pub struct Command {
// other keys.
program: CString,
args: Vec<CString>,
argv: Vec<*const c_char>,
argv: Argv,
env: CommandEnv<DefaultEnvKey>,
cwd: Option<CString>,
@@ -58,6 +58,12 @@ pub struct Command {
stderr: Option<Stdio>,
}
// Create a new type for argv, so that we can make it `Send`
struct Argv(Vec<*const c_char>);
// It is safe to make Argv Send, because it contains pointers to memory owned by `Command.args`
unsafe impl Send for Argv {}
// passed back to std::process with the pipes connected to the child, if any
// were requested
pub struct StdioPipes {
@@ -92,7 +98,7 @@ pub fn new(program: &OsStr) -> Command {
let mut saw_nul = false;
let program = os2c(program, &mut saw_nul);
Command {
argv: vec![program.as_ptr(), ptr::null()],
argv: Argv(vec![program.as_ptr(), ptr::null()]),
program,
args: Vec::new(),
env: Default::default(),
@@ -111,8 +117,8 @@ pub fn arg(&mut self, arg: &OsStr) {
// Overwrite the trailing NULL pointer in `argv` and then add a new null
// pointer.
let arg = os2c(arg, &mut self.saw_nul);
self.argv[self.args.len() + 1] = arg.as_ptr();
self.argv.push(ptr::null());
self.argv.0[self.args.len() + 1] = arg.as_ptr();
self.argv.0.push(ptr::null());
// Also make sure we keep track of the owned value to schedule a
// destructor for this memory.
@@ -133,7 +139,7 @@ pub fn saw_nul(&self) -> bool {
self.saw_nul
}
pub fn get_argv(&self) -> &Vec<*const c_char> {
&self.argv
&self.argv.0
}
#[allow(dead_code)]