about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2018-01-30 17:10:53 +0800
committerGitHub <noreply@github.com>2018-01-30 17:10:53 +0800
commit4dbfc8ddbfd091aefa4b0af674b6625378ce34fe (patch)
treebf5724b80636bc2a853c3178fc8790ecb83fc655 /src/libstd
parentf06a391a40dca2adc4ba15385ec27ecd949ed103 (diff)
parent077d3434aa8a2a3064afcc1c9406a49d0acf0a8d (diff)
downloadrust-4dbfc8ddbfd091aefa4b0af674b6625378ce34fe.tar.gz
rust-4dbfc8ddbfd091aefa4b0af674b6625378ce34fe.zip
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
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/process.rs6
-rw-r--r--src/libstd/sys/unix/process/process_common.rs16
2 files changed, 17 insertions, 5 deletions
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index 5c66ac6ddde..9b2f815b713 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -1843,4 +1843,10 @@ mod tests {
         }
         assert!(events > 0);
     }
+
+    #[test]
+    fn test_command_implements_send() {
+        fn take_send_type<T: Send>(_: T) {}
+        take_send_type(Command::new(""))
+    }
 }
diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs
index c53bcdbf8e3..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 {
@@ -92,7 +98,7 @@ impl 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 @@ 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.
@@ -133,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)]