about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorJeremy Soller <jackpot51@gmail.com>2016-11-09 20:52:30 -0700
committerJeremy Soller <jackpot51@gmail.com>2016-11-09 20:52:30 -0700
commitced32a08f3bf7325bf3fe6488e21b108f996abc5 (patch)
treed9af3131bf73f5f94a62727eccfcb66fbf627376 /src/libstd/sys
parent01e837807095e99d68ecf9c0b38527288281dd02 (diff)
downloadrust-ced32a08f3bf7325bf3fe6488e21b108f996abc5.tar.gz
rust-ced32a08f3bf7325bf3fe6488e21b108f996abc5.zip
Fix exec
Diffstat (limited to 'src/libstd/sys')
-rw-r--r--src/libstd/sys/redox/process.rs66
1 files changed, 10 insertions, 56 deletions
diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs
index b6968f285d7..ad50d1de283 100644
--- a/src/libstd/sys/redox/process.rs
+++ b/src/libstd/sys/redox/process.rs
@@ -18,7 +18,7 @@ use path::Path;
 use sys::fd::FileDesc;
 use sys::fs::{File, OpenOptions};
 use sys::pipe::{self, AnonPipe};
-use sys::{self, cvt};
+use sys::cvt;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Command
@@ -145,78 +145,32 @@ impl Command {
 
     pub fn spawn(&mut self, default: Stdio, needs_stdin: bool)
                  -> io::Result<(Process, StdioPipes)> {
-        const CLOEXEC_MSG_FOOTER: &'static [u8] = b"NOEX";
-
         if self.saw_nul {
             return Err(io::Error::new(ErrorKind::InvalidInput,
                                       "nul byte found in provided data"));
         }
 
         let (ours, theirs) = self.setup_io(default, needs_stdin)?;
-        let (input, output) = sys::pipe::anon_pipe()?;
 
         let pid = unsafe {
-            match cvt(libc::clone(0))? {
+            match cvt(libc::clone(libc::CLONE_VFORK))? {
                 0 => {
-                    drop(input);
                     let err = self.do_exec(theirs);
-                    let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;
-                    let bytes = [
-                        (errno >> 24) as u8,
-                        (errno >> 16) as u8,
-                        (errno >>  8) as u8,
-                        (errno >>  0) as u8,
-                        CLOEXEC_MSG_FOOTER[0], CLOEXEC_MSG_FOOTER[1],
-                        CLOEXEC_MSG_FOOTER[2], CLOEXEC_MSG_FOOTER[3]
-                    ];
-                    // pipe I/O up to PIPE_BUF bytes should be atomic, and then
-                    // we want to be sure we *don't* run at_exit destructors as
-                    // we're being torn down regardless
-                    assert!(output.write(&bytes).is_ok());
-                    let _ = libc::exit(1);
+                    let _ = libc::exit((-err.raw_os_error().unwrap_or(libc::EINVAL)) as usize);
                     unreachable!();
                 }
                 n => n as pid_t,
             }
         };
 
-        let mut p = Process { pid: pid, status: None };
-        drop(output);
-        let mut bytes = [0; 8];
-
-        // loop to handle EINTR
-        loop {
-            match input.read(&mut bytes) {
-                Ok(0) => return Ok((p, ours)),
-                Ok(8) => {
-                    assert!(combine(CLOEXEC_MSG_FOOTER) == combine(&bytes[4.. 8]),
-                            "Validation on the CLOEXEC pipe failed: {:?}", bytes);
-                    let errno = combine(&bytes[0.. 4]);
-                    assert!(p.wait().is_ok(),
-                            "wait() should either return Ok or panic");
-                    return Err(Error::from_raw_os_error(errno))
-                }
-                Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
-                Err(e) => {
-                    assert!(p.wait().is_ok(),
-                            "wait() should either return Ok or panic");
-                    panic!("the CLOEXEC pipe failed: {:?}", e)
-                },
-                Ok(..) => { // pipe I/O up to PIPE_BUF bytes should be atomic
-                    assert!(p.wait().is_ok(),
-                            "wait() should either return Ok or panic");
-                    panic!("short read on the CLOEXEC pipe")
-                }
+        let mut status_mux = 0;
+        if cvt(libc::waitpid(pid, &mut status_mux, libc::WNOHANG))? == pid {
+            match libc::Error::demux(status_mux) {
+                Ok(status) => Ok((Process { pid: pid, status: Some(ExitStatus::from(status as c_int)) }, ours)),
+                Err(err) => Err(io::Error::from_raw_os_error(err.errno)),
             }
-        }
-
-        fn combine(arr: &[u8]) -> i32 {
-            let a = arr[0] as u32;
-            let b = arr[1] as u32;
-            let c = arr[2] as u32;
-            let d = arr[3] as u32;
-
-            ((a << 24) | (b << 16) | (c << 8) | (d << 0)) as i32
+        } else {
+            Ok((Process { pid: pid, status: None }, ours))
         }
     }