diff --git a/include/bits/unistd.h b/include/bits/unistd.h new file mode 100644 index 0000000000..a7167d047a --- /dev/null +++ b/include/bits/unistd.h @@ -0,0 +1,7 @@ +#ifndef _BITS_UNISTD_H +#define _BITS_UNISTD_H + +int execl(const char *path, const char* argv0, ...); +int execle(const char *path, const char* argv0, ...); + +#endif diff --git a/include/bits/exec.h b/src/c/unistd.c similarity index 83% rename from include/bits/exec.h rename to src/c/unistd.c index 94024518ba..a2a78ce727 100644 --- a/include/bits/exec.h +++ b/src/c/unistd.c @@ -1,5 +1,7 @@ -#ifndef _BITS_EXEC_H -#define _BITS_EXEC_H +#include +#include + +int execv(const char *path, char *const *argv); int execl(const char *path, const char* argv0, ...) { @@ -22,6 +24,8 @@ int execl(const char *path, const char* argv0, ...) } } +int execve(const char *path, char *const *argv, char *const *envp); + int execle(const char *path, const char* argv0, ...) { int argc; diff --git a/src/platform/Cargo.toml b/src/platform/Cargo.toml index dd5ba725ac..e25b8251c0 100644 --- a/src/platform/Cargo.toml +++ b/src/platform/Cargo.toml @@ -8,6 +8,3 @@ sc = "0.2" [target.'cfg(target_os = "redox")'.dependencies] redox_syscall = "0.1" - -[dependencies] -ralloc = { path = "../../ralloc" } diff --git a/src/platform/src/lib.rs b/src/platform/src/lib.rs index 78bc4c39ca..4919e61308 100644 --- a/src/platform/src/lib.rs +++ b/src/platform/src/lib.rs @@ -2,8 +2,6 @@ #![no_std] #![allow(non_camel_case_types)] -#![feature(alloc)] -#![feature(global_allocator)] //TODO #![feature(thread_local)] #[cfg(all(not(feature = "no_std"), target_os = "linux"))] @@ -24,17 +22,12 @@ mod sys; #[path = "redox/mod.rs"] mod sys; -extern crate alloc; -extern crate ralloc; - pub mod types; use core::fmt; use types::*; -#[global_allocator] -static ALLOCATOR: ralloc::Allocator = ralloc::Allocator; //TODO #[thread_local] #[allow(non_upper_case_globals)] #[no_mangle] diff --git a/src/platform/src/redox/mod.rs b/src/platform/src/redox/mod.rs index 71019375f7..b72e5d72b6 100644 --- a/src/platform/src/redox/mod.rs +++ b/src/platform/src/redox/mod.rs @@ -1,7 +1,6 @@ use core::ptr; use core::slice; use core::mem; -use alloc::Vec; use syscall; use syscall::flag::*; use syscall::data::TimeSpec as redox_timespec; @@ -68,58 +67,6 @@ pub fn dup2(fd1: c_int, fd2: c_int) -> c_int { e(syscall::dup2(fd1 as usize, fd2 as usize, &[])) as c_int } -pub fn execve(path: *const c_char, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int { - unsafe { - 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() { - let n = match syscall::write(fd, &slice[sep + 1..]) { - Ok(n) => n, - 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 mut args: Vec<[usize; 2]> = Vec::new(); - let mut arg = argv; - while !(*arg).is_null() { - args.push([*arg as usize, c_str(*arg).len()]); - arg = arg.offset(1); - } - - e(syscall::execve(c_str(path), &args)) as c_int - } -} - pub fn exit(status: c_int) -> ! { let _ = syscall::exit(status as usize); loop {} diff --git a/src/unistd/cbindgen.toml b/src/unistd/cbindgen.toml index ef4ad8123a..a10250c6dd 100644 --- a/src/unistd/cbindgen.toml +++ b/src/unistd/cbindgen.toml @@ -1,6 +1,6 @@ -sys_includes = ["stddef.h", "stdint.h", "sys/types.h", "stdarg.h", "bits/exec.h"] +sys_includes = ["stddef.h", "stdint.h", "sys/types.h"] include_guard = "_UNISTD_H" -trailer = "#include " +trailer = "#include \n#include " language = "C" [enum] diff --git a/src/unistd/src/lib.rs b/src/unistd/src/lib.rs index db90a9feaf..c6a85a53a5 100644 --- a/src/unistd/src/lib.rs +++ b/src/unistd/src/lib.rs @@ -33,7 +33,7 @@ pub const STDOUT_FILENO: c_int = 1; pub const STDERR_FILENO: c_int = 2; #[no_mangle] -pub static mut environ: *const *mut c_char = 0 as *const *mut c_char; +pub static mut environ: *const *mut c_char = ptr::null(); #[no_mangle] pub extern "C" fn _exit(status: c_int) { @@ -120,17 +120,76 @@ pub extern "C" fn encrypt(block: [c_char; 64], edflag: c_int) { // } #[no_mangle] -pub extern "C" fn execv(path: *const c_char, argv: *const *mut c_char) -> c_int { - unsafe { execve(path, argv, environ) } +pub unsafe extern "C" fn execv(path: *const c_char, argv: *const *mut c_char) -> c_int { + execve(path, argv, environ) } #[no_mangle] -pub extern "C" fn execve( +pub unsafe extern "C" fn execve( path: *const c_char, argv: *const *mut c_char, envp: *const *mut c_char, ) -> c_int { - platform::execve(path, argv, envp) + #[cfg(target_os = "linux")] { + platform::execve(path, argv, envp) + } + #[cfg(target_os = "redox")] { + 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 platform::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() { + let n = match syscall::write(fd, &slice[sep + 1..]) { + Ok(n) => n, + err => { + return e(err) as c_int; + } + }; + } + // Cleanup after adding the variable. + match platform::syscall::close(fd) { + Ok(_) => (), + err => { + return e(err) as c_int; + } + } + } + err => { + return e(err) as c_int; + } + } + } + } + env = env.offset(1); + } + + let mut len = 0; + for i in 0.. { + if (*arg.offset(i)).is_null() { + len = i; + break; + } + } + + let mut args: Vec<[usize; 2]> = Vec::with_capacity(len); + let mut arg = argv; + while !(*arg).is_null() { + args.push([*arg as usize, c_str(*arg).len()]); + arg = arg.offset(1); + } + + e(platform::syscall::execve(c_str(path), &args)) as c_int + } } #[no_mangle] diff --git a/tests/exec.c b/tests/exec.c index 4a09e743b5..213df7f8d3 100644 --- a/tests/exec.c +++ b/tests/exec.c @@ -1,4 +1,5 @@ #include +#include int main(int argc, char** argv) { char *const args[1] = {"arg"}; diff --git a/tests/expected/exec.stderr b/tests/expected/exec.stderr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/expected/exec.stdout b/tests/expected/exec.stdout new file mode 100644 index 0000000000..980a0d5f19 --- /dev/null +++ b/tests/expected/exec.stdout @@ -0,0 +1 @@ +Hello World!