Migrate to new FEXEC system call
This commit is contained in:
Generated
+7
-1
@@ -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"
|
||||
|
||||
+12
-30
@@ -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]
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
e(syscall::execve(c_str(path), &args)) as c_int
|
||||
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::fexec(*fd as usize, &args, &envs)) as c_int
|
||||
}
|
||||
|
||||
pub fn fchdir(fd: c_int) -> c_int {
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user