about summary refs log tree commit diff
path: root/src/libstd/sys/redox/process.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd/sys/redox/process.rs')
-rw-r--r--src/libstd/sys/redox/process.rs41
1 files changed, 28 insertions, 13 deletions
diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs
index 2037616e6ac..f85834dff5d 100644
--- a/src/libstd/sys/redox/process.rs
+++ b/src/libstd/sys/redox/process.rs
@@ -9,15 +9,17 @@
 // except according to those terms.
 
 use env::{split_paths};
-use ffi::OsStr;
+use ffi::{CStr, OsStr};
 use os::unix::ffi::OsStrExt;
 use fmt;
 use io::{self, Error, ErrorKind};
 use iter;
 use libc::{EXIT_SUCCESS, EXIT_FAILURE};
 use path::{Path, PathBuf};
+use ptr;
 use sys::fd::FileDesc;
 use sys::fs::{File, OpenOptions};
+use sys::os::{ENV_LOCK, environ};
 use sys::pipe::{self, AnonPipe};
 use sys::{cvt, syscall};
 use sys_common::process::{CommandEnv, DefaultEnvKey};
@@ -297,12 +299,6 @@ impl Command {
             t!(callback());
         }
 
-        let args: Vec<[usize; 2]> = iter::once(
-            [self.program.as_ptr() as usize, self.program.len()]
-        ).chain(
-            self.args.iter().map(|arg| [arg.as_ptr() as usize, arg.len()])
-        ).collect();
-
         self.env.apply();
 
         let program = if self.program.contains(':') || self.program.contains('/') {
@@ -321,14 +317,33 @@ impl Command {
             None
         };
 
-        if let Some(program) = program {
-            if let Err(err) = syscall::execve(program.as_os_str().as_bytes(), &args) {
-                io::Error::from_raw_os_error(err.errno as i32)
-            } else {
-                panic!("return from exec without err");
+        let fd = if let Some(program) = program {
+            t!(cvt(syscall::open(program.as_os_str().as_bytes(), syscall::O_RDONLY)))
+        } else {
+            return io::Error::from_raw_os_error(syscall::ENOENT);
+        };
+
+        let mut args: Vec<[usize; 2]> = iter::once(
+            [self.program.as_ptr() as usize, self.program.len()]
+        ).chain(
+            self.args.iter().map(|arg| [arg.as_ptr() as usize, arg.len()])
+        ).collect();
+
+        let mut vars: Vec<[usize; 2]> = Vec::new();
+        unsafe {
+            let _guard = ENV_LOCK.lock();
+            let mut environ = *environ();
+            while *environ != ptr::null() {
+                let var = CStr::from_ptr(*environ).to_bytes();
+                vars.push([var.as_ptr() as usize, var.len()]);
+                environ = environ.offset(1);
             }
+        }
+
+        if let Err(err) = syscall::fexec(fd, &args, &vars) {
+            io::Error::from_raw_os_error(err.errno as i32)
         } else {
-            io::Error::from_raw_os_error(syscall::ENOENT)
+            panic!("return from exec without err");
         }
     }