From 1c4e8852dd2881870d470d16e25a18e377ab1ded Mon Sep 17 00:00:00 2001 From: jD91mZM2 <me@krake.one> Date: Sun, 12 Aug 2018 20:35:45 +0200 Subject: [PATCH] Migrate to new FEXEC system call --- Cargo.lock | 8 +++- src/crt0/src/lib.rs | 44 ++++++------------- src/platform/Cargo.toml | 2 +- src/platform/src/redox/mod.rs | 82 +++++++++++++++-------------------- src/stdlib/src/lib.rs | 2 + 5 files changed, 57 insertions(+), 81 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5750edb8c..2ba130772 100644 --- a/Cargo.lock +++ b/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" diff --git a/src/crt0/src/lib.rs b/src/crt0/src/lib.rs index a4e49a3dd..c9cc2739a 100644 --- a/src/crt0/src/lib.rs +++ b/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] diff --git a/src/platform/Cargo.toml b/src/platform/Cargo.toml index 6c179a9fc..7a313fea4 100644 --- a/src/platform/Cargo.toml +++ b/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" diff --git a/src/platform/src/redox/mod.rs b/src/platform/src/redox/mod.rs index 6d9afdb3b..24637c02a 100644 --- a/src/platform/src/redox/mod.rs +++ b/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 { diff --git a/src/stdlib/src/lib.rs b/src/stdlib/src/lib.rs index 724f1363f..7e82a41cd 100644 --- a/src/stdlib/src/lib.rs +++ b/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 }; -- GitLab