Browse Source

Migrate to new FEXEC system call

jD91mZM2 6 years ago
parent
commit
1c4e8852dd
5 changed files with 57 additions and 81 deletions
  1. 7 1
      Cargo.lock
  2. 13 31
      src/crt0/src/lib.rs
  3. 1 1
      src/platform/Cargo.toml
  4. 34 48
      src/platform/src/redox/mod.rs
  5. 2 0
      src/stdlib/src/lib.rs

+ 7 - 1
Cargo.lock

@@ -245,7 +245,7 @@ name = "platform"
 version = "0.1.0"
 dependencies = [
  "ralloc 1.0.0",
- "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (git+https://gitlab.redox-os.org/redox-os/syscall.git?branch=relibc)",
  "sc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "spin 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -312,6 +312,11 @@ name = "rand_core"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "redox_syscall"
+version = "0.1.40"
+source = "git+https://gitlab.redox-os.org/redox-os/syscall.git?branch=relibc#739aef47b8e6b300874945c3c33bb9550414b5b8"
+
 [[package]]
 name = "redox_syscall"
 version = "0.1.40"
@@ -797,6 +802,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
 "checksum rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "12397506224b2f93e6664ffc4f664b29be8208e5157d3d90b44f09b5fae470ea"
 "checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
+"checksum redox_syscall 0.1.40 (git+https://gitlab.redox-os.org/redox-os/syscall.git?branch=relibc)" = "<none>"
 "checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
 "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
 "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"

+ 13 - 31
src/crt0/src/lib.rs

@@ -53,7 +53,6 @@ impl Stack {
         &self.argv0 as *const *const u8
     }
 
-    #[cfg(not(target_os = "redox"))]
     fn envp(&self) -> *const *const u8 {
         unsafe { self.argv().offset(self.argc() + 1) }
     }
@@ -69,34 +68,24 @@ pub unsafe extern "C" fn _start_rust(sp: &'static Stack) -> ! {
     let argc = sp.argc();
     let argv = sp.argv();
 
-    #[cfg(target_os = "redox")]
-    {
-        // TODO: Redox will support environ like on linux, eventually.
-        // We could implement it using the env: scheme here, but eh.
-        platform::inner_environ = Vec::with_capacity(1);
-    }
-    #[cfg(not(target_os = "redox"))]
     let envp = sp.envp();
-    #[cfg(not(target_os = "redox"))]
-    {
+    let mut len = 0;
+    while *envp.offset(len) != ptr::null() {
+        len += 1;
+    }
+    platform::inner_environ = Vec::with_capacity(len as usize + 1);
+    for i in 0..len {
+        let mut item = *envp.offset(i);
         let mut len = 0;
-        while *envp.offset(len) != ptr::null() {
+        while *item.offset(len) != 0 {
             len += 1;
         }
-        platform::inner_environ = Vec::with_capacity(len as usize + 1);
-        for i in 0..len {
-            let mut item = *envp.offset(i);
-            let mut len = 0;
-            while *item.offset(len) != 0 {
-                len += 1;
-            }
-
-            let buf = platform::alloc(len as usize + 1) as *mut c_char;
-            for i in 0..=len {
-                *buf.offset(i) = *item.offset(i) as c_char;
-            }
-            platform::inner_environ.push(buf);
+
+        let buf = platform::alloc(len as usize + 1) as *mut c_char;
+        for i in 0..=len {
+            *buf.offset(i) = *item.offset(i) as c_char;
         }
+        platform::inner_environ.push(buf);
     }
     platform::inner_environ.push(ptr::null_mut());
     platform::environ = platform::inner_environ.as_mut_ptr();
@@ -106,18 +95,11 @@ pub unsafe extern "C" fn _start_rust(sp: &'static Stack) -> ! {
     stdio::stdout = stdio::default_stdout.get();
     stdio::stderr = stdio::default_stderr.get();
 
-    #[cfg(not(target_os = "redox"))]
     platform::exit(main(
         argc,
         argv as *const *const c_char,
         envp as *const *const c_char,
     ));
-    #[cfg(target_os = "redox")]
-    platform::exit(main(
-        argc,
-        argv as *const *const c_char,
-        platform::environ as *const *const c_char
-    ));
 }
 
 #[panic_implementation]

+ 1 - 1
src/platform/Cargo.toml

@@ -12,5 +12,5 @@ optional = true
 sc = "0.2"
 
 [target.'cfg(target_os = "redox")'.dependencies]
-redox_syscall = "0.1"
+redox_syscall = { git = "https://gitlab.redox-os.org/redox-os/syscall.git", branch = "relibc" }
 spin = "0.4"

+ 34 - 48
src/platform/src/redox/mod.rs

@@ -196,65 +196,51 @@ pub fn exit(status: c_int) -> ! {
 
 pub unsafe extern "C" fn execve(
     path: *const c_char,
-    argv: *const *mut c_char,
-    envp: *const *mut c_char,
+    mut argv: *const *mut c_char,
+    mut envp: *const *mut c_char,
 ) -> c_int {
     use alloc::Vec;
-    use syscall::flag::*;
-
-    let mut env = envp;
-    while !(*env).is_null() {
-        let slice = c_str(*env);
-        // Should always contain a =, but worth checking
-        if let Some(sep) = slice.iter().position(|&c| c == b'=') {
-            // If the environment variable has no name, do not attempt
-            // to add it to the env.
-            if sep > 0 {
-                let mut path = b"env:".to_vec();
-                path.extend_from_slice(&slice[..sep]);
-                match syscall::open(&path, O_WRONLY | O_CREAT) {
-                    Ok(fd) => {
-                        // If the environment variable has no value, there
-                        // is no need to write anything to the env scheme.
-                        if sep + 1 < slice.len() {
-                            match syscall::write(fd, &slice[sep + 1..]) {
-                                Ok(_) => (),
-                                err => {
-                                    return e(err) as c_int;
-                                }
-                            }
-                        }
-                        // Cleanup after adding the variable.
-                        match syscall::close(fd) {
-                            Ok(_) => (),
-                            err => {
-                                return e(err) as c_int;
-                            }
-                        }
-                    }
-                    err => {
-                        return e(err) as c_int;
-                    }
-                }
-            }
-        }
-        env = env.offset(1);
-    }
+
+    let fd = match RawFile::open(path, 0, 0) {
+        Ok(fd) => fd,
+        Err(_) => return -1
+    };
 
     let mut len = 0;
     while !(*argv.offset(len)).is_null() {
         len += 1;
-        break;
     }
 
     let mut args: Vec<[usize; 2]> = Vec::with_capacity(len as usize);
-    let mut arg = argv;
-    while !(*arg).is_null() {
-        args.push([*arg as usize, c_str(*arg).len()]);
-        arg = arg.offset(1);
+    while !(*argv).is_null() {
+        let arg = *argv;
+
+        let mut len = 0;
+        while *arg.offset(len) != 0 {
+            len += 1;
+        }
+        args.push([*arg as usize, len as usize]);
+        argv = argv.offset(1);
+    }
+
+    let mut len = 0;
+    while !(*envp.offset(len)).is_null() {
+        len += 1;
+    }
+
+    let mut envs: Vec<[usize; 2]> = Vec::with_capacity(len as usize);
+    while !(*envp).is_null() {
+        let env = *envp;
+
+        let mut len = 0;
+        while *env.offset(len) != 0 {
+            len += 1;
+        }
+        envs.push([*env as usize, len as usize]);
+        envp = envp.offset(1);
     }
 
-    e(syscall::execve(c_str(path), &args)) as c_int
+    e(syscall::fexec(*fd as usize, &args, &envs)) as c_int
 }
 
 pub fn fchdir(fd: c_int) -> c_int {

+ 2 - 0
src/stdlib/src/lib.rs

@@ -525,6 +525,7 @@ pub unsafe extern "C" fn putenv(insert: *mut c_char) -> c_int {
         assert_eq!(platform::inner_environ[i], ptr::null_mut(), "environ did not end with null");
         platform::inner_environ[i] = insert;
         platform::inner_environ.push(ptr::null_mut());
+        platform::environ = platform::inner_environ.as_mut_ptr();
     }
     0
 }
@@ -618,6 +619,7 @@ pub unsafe extern "C" fn setenv(mut key: *const c_char, mut value: *const c_char
         let i = platform::inner_environ.len() - 1;
         assert_eq!(platform::inner_environ[i], ptr::null_mut(), "environ did not end with null");
         platform::inner_environ.push(ptr::null_mut());
+        platform::environ = platform::inner_environ.as_mut_ptr();
         i
     };