Skip to content

Commit 4dbfc8d

Browse files
authored
Rollup merge of rust-lang#47760 - little-dude:master, r=alexcrichton
implement Send for process::Command on unix closes rust-lang#47751
2 parents f06a391 + 077d343 commit 4dbfc8d

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

src/libstd/process.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1843,4 +1843,10 @@ mod tests {
18431843
}
18441844
assert!(events > 0);
18451845
}
1846+
1847+
#[test]
1848+
fn test_command_implements_send() {
1849+
fn take_send_type<T: Send>(_: T) {}
1850+
take_send_type(Command::new(""))
1851+
}
18461852
}

src/libstd/sys/unix/process/process_common.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub struct Command {
4545
// other keys.
4646
program: CString,
4747
args: Vec<CString>,
48-
argv: Vec<*const c_char>,
48+
argv: Argv,
4949
env: CommandEnv<DefaultEnvKey>,
5050

5151
cwd: Option<CString>,
@@ -58,6 +58,12 @@ pub struct Command {
5858
stderr: Option<Stdio>,
5959
}
6060

61+
// Create a new type for argv, so that we can make it `Send`
62+
struct Argv(Vec<*const c_char>);
63+
64+
// It is safe to make Argv Send, because it contains pointers to memory owned by `Command.args`
65+
unsafe impl Send for Argv {}
66+
6167
// passed back to std::process with the pipes connected to the child, if any
6268
// were requested
6369
pub struct StdioPipes {
@@ -92,7 +98,7 @@ impl Command {
9298
let mut saw_nul = false;
9399
let program = os2c(program, &mut saw_nul);
94100
Command {
95-
argv: vec![program.as_ptr(), ptr::null()],
101+
argv: Argv(vec![program.as_ptr(), ptr::null()]),
96102
program,
97103
args: Vec::new(),
98104
env: Default::default(),
@@ -111,8 +117,8 @@ impl Command {
111117
// Overwrite the trailing NULL pointer in `argv` and then add a new null
112118
// pointer.
113119
let arg = os2c(arg, &mut self.saw_nul);
114-
self.argv[self.args.len() + 1] = arg.as_ptr();
115-
self.argv.push(ptr::null());
120+
self.argv.0[self.args.len() + 1] = arg.as_ptr();
121+
self.argv.0.push(ptr::null());
116122

117123
// Also make sure we keep track of the owned value to schedule a
118124
// destructor for this memory.
@@ -133,7 +139,7 @@ impl Command {
133139
self.saw_nul
134140
}
135141
pub fn get_argv(&self) -> &Vec<*const c_char> {
136-
&self.argv
142+
&self.argv.0
137143
}
138144

139145
#[allow(dead_code)]

0 commit comments

Comments
 (0)