diff options
| author | Corentin Henry <corentinhenry@gmail.com> | 2018-01-26 07:22:43 -0800 | 
|---|---|---|
| committer | Corentin Henry <corentinhenry@gmail.com> | 2018-01-26 07:22:58 -0800 | 
| commit | 9e6ed17c4f5befef64fa9e8a1d2b2f155c345cac (patch) | |
| tree | 71555ec1dc85c80bc964272905d6d8ae79755f77 /src/libstd/sys/unix/process/process_common.rs | |
| parent | 831ff775703eb5126f741fc3be1cf829ec060011 (diff) | |
| download | rust-9e6ed17c4f5befef64fa9e8a1d2b2f155c345cac.tar.gz rust-9e6ed17c4f5befef64fa9e8a1d2b2f155c345cac.zip | |
make Command.argv Send on unix platforms
Implementing Send for a specific field rather than the whole struct is safer: if a field is changed/modified and becomes non-Send, we can catch it.
Diffstat (limited to 'src/libstd/sys/unix/process/process_common.rs')
| -rw-r--r-- | src/libstd/sys/unix/process/process_common.rs | 21 | 
1 files changed, 11 insertions, 10 deletions
| diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index b09fc36dee0..7e057401fab 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -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 { @@ -87,17 +93,12 @@ pub enum Stdio { Fd(FileDesc), } -// Command is not Send by default due to the Command.argv field containing a raw pointers. However -// it is safe to implement Send, because anyway, these pointers point to memory owned by the -// Command.args field. -unsafe impl Send for Command {} - impl Command { 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(), @@ -116,8 +117,8 @@ impl Command { // 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. @@ -138,7 +139,7 @@ impl Command { self.saw_nul } pub fn get_argv(&self) -> &Vec<*const c_char> { - &self.argv + &self.argv.0 } #[allow(dead_code)] | 
