Skip to content

Commit ced32a0

Browse files
committed
Fix exec
1 parent 01e8378 commit ced32a0

File tree

1 file changed

+10
-56
lines changed

1 file changed

+10
-56
lines changed

src/libstd/sys/redox/process.rs

Lines changed: 10 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use path::Path;
1818
use sys::fd::FileDesc;
1919
use sys::fs::{File, OpenOptions};
2020
use sys::pipe::{self, AnonPipe};
21-
use sys::{self, cvt};
21+
use sys::cvt;
2222

2323
////////////////////////////////////////////////////////////////////////////////
2424
// Command
@@ -145,78 +145,32 @@ impl Command {
145145

146146
pub fn spawn(&mut self, default: Stdio, needs_stdin: bool)
147147
-> io::Result<(Process, StdioPipes)> {
148-
const CLOEXEC_MSG_FOOTER: &'static [u8] = b"NOEX";
149-
150148
if self.saw_nul {
151149
return Err(io::Error::new(ErrorKind::InvalidInput,
152150
"nul byte found in provided data"));
153151
}
154152

155153
let (ours, theirs) = self.setup_io(default, needs_stdin)?;
156-
let (input, output) = sys::pipe::anon_pipe()?;
157154

158155
let pid = unsafe {
159-
match cvt(libc::clone(0))? {
156+
match cvt(libc::clone(libc::CLONE_VFORK))? {
160157
0 => {
161-
drop(input);
162158
let err = self.do_exec(theirs);
163-
let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;
164-
let bytes = [
165-
(errno >> 24) as u8,
166-
(errno >> 16) as u8,
167-
(errno >> 8) as u8,
168-
(errno >> 0) as u8,
169-
CLOEXEC_MSG_FOOTER[0], CLOEXEC_MSG_FOOTER[1],
170-
CLOEXEC_MSG_FOOTER[2], CLOEXEC_MSG_FOOTER[3]
171-
];
172-
// pipe I/O up to PIPE_BUF bytes should be atomic, and then
173-
// we want to be sure we *don't* run at_exit destructors as
174-
// we're being torn down regardless
175-
assert!(output.write(&bytes).is_ok());
176-
let _ = libc::exit(1);
159+
let _ = libc::exit((-err.raw_os_error().unwrap_or(libc::EINVAL)) as usize);
177160
unreachable!();
178161
}
179162
n => n as pid_t,
180163
}
181164
};
182165

183-
let mut p = Process { pid: pid, status: None };
184-
drop(output);
185-
let mut bytes = [0; 8];
186-
187-
// loop to handle EINTR
188-
loop {
189-
match input.read(&mut bytes) {
190-
Ok(0) => return Ok((p, ours)),
191-
Ok(8) => {
192-
assert!(combine(CLOEXEC_MSG_FOOTER) == combine(&bytes[4.. 8]),
193-
"Validation on the CLOEXEC pipe failed: {:?}", bytes);
194-
let errno = combine(&bytes[0.. 4]);
195-
assert!(p.wait().is_ok(),
196-
"wait() should either return Ok or panic");
197-
return Err(Error::from_raw_os_error(errno))
198-
}
199-
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
200-
Err(e) => {
201-
assert!(p.wait().is_ok(),
202-
"wait() should either return Ok or panic");
203-
panic!("the CLOEXEC pipe failed: {:?}", e)
204-
},
205-
Ok(..) => { // pipe I/O up to PIPE_BUF bytes should be atomic
206-
assert!(p.wait().is_ok(),
207-
"wait() should either return Ok or panic");
208-
panic!("short read on the CLOEXEC pipe")
209-
}
166+
let mut status_mux = 0;
167+
if cvt(libc::waitpid(pid, &mut status_mux, libc::WNOHANG))? == pid {
168+
match libc::Error::demux(status_mux) {
169+
Ok(status) => Ok((Process { pid: pid, status: Some(ExitStatus::from(status as c_int)) }, ours)),
170+
Err(err) => Err(io::Error::from_raw_os_error(err.errno)),
210171
}
211-
}
212-
213-
fn combine(arr: &[u8]) -> i32 {
214-
let a = arr[0] as u32;
215-
let b = arr[1] as u32;
216-
let c = arr[2] as u32;
217-
let d = arr[3] as u32;
218-
219-
((a << 24) | (b << 16) | (c << 8) | (d << 0)) as i32
172+
} else {
173+
Ok((Process { pid: pid, status: None }, ours))
220174
}
221175
}
222176

0 commit comments

Comments
 (0)