diff --git a/src/crt0/src/lib.rs b/src/crt0/src/lib.rs index 36bb335b63b1dddb2e21d1972d00a4301093cf2d..749f87342884f8ea3c71863f25a4dca5fde45918 100644 --- a/src/crt0/src/lib.rs +++ b/src/crt0/src/lib.rs @@ -5,6 +5,7 @@ #![feature(linkage)] #![feature(naked_functions)] #![feature(panic_implementation)] +#![feature(lang_items)] extern crate platform; @@ -74,3 +75,19 @@ pub extern "C" fn rust_begin_unwind(pi: &::core::panic::PanicInfo) -> ! { platform::exit(1); } + +#[lang = "oom"] +#[linkage = "weak"] +#[no_mangle] +pub extern "C" fn rust_oom(layout: ::core::alloc::Layout) -> ! { + use core::fmt::Write; + + let mut w = platform::FileWriter(2); + let _ = w.write_fmt(format_args!( + "RELIBC OOM: {} bytes aligned to {} bytes\n", + layout.size(), + layout.align() + )); + + platform::exit(1); +} diff --git a/src/platform/src/lib.rs b/src/platform/src/lib.rs index d33c63c060528ed63a346dcaf4112035d1a919a1..ac831cb1be80a1d24eaabd6176eeb5fe1baae594 100644 --- a/src/platform/src/lib.rs +++ b/src/platform/src/lib.rs @@ -2,9 +2,11 @@ #![no_std] #![allow(non_camel_case_types)] +#![feature(alloc)] //TODO #![feature(thread_local)] extern crate ralloc; +extern crate alloc; #[cfg(all(not(feature = "no_std"), target_os = "linux"))] #[macro_use] diff --git a/src/platform/src/redox/mod.rs b/src/platform/src/redox/mod.rs index 970add4aa3bf32c544ee45d0dc1ae8adec9c1706..47fbcbfeb625233fe973734d832d090e3e58fb58 100644 --- a/src/platform/src/redox/mod.rs +++ b/src/platform/src/redox/mod.rs @@ -72,6 +72,71 @@ pub fn exit(status: c_int) -> ! { loop {} } +pub unsafe extern "C" fn execve( + path: *const c_char, + argv: *const *mut c_char, + 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() { + 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 len = 0; + for i in 0.. { + if (*argv.offset(i)).is_null() { + len = i; + 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); + } + + e(syscall::execve(c_str(path), &args)) as c_int +} + pub fn fchdir(fd: c_int) -> c_int { let path: &mut [u8] = &mut [0; 4096]; if e(syscall::fpath(fd as usize, path)) == !0 { diff --git a/src/unistd/src/lib.rs b/src/unistd/src/lib.rs index b4ef768e110e451772402ed105128527e7f8d0d0..4ab290939556a56fd567b79313171b00e800fbc3 100644 --- a/src/unistd/src/lib.rs +++ b/src/unistd/src/lib.rs @@ -133,72 +133,7 @@ pub unsafe extern "C" fn execve( argv: *const *mut c_char, envp: *const *mut c_char, ) -> c_int { - #[cfg(target_os = "linux")] - { - platform::execve(path, argv, envp) - } - #[cfg(target_os = "redox")] - { - use alloc::Vec; - use platform::syscall::flag::*; - use platform::{c_str, e}; - - 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 platform::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 (*argv.offset(i)).is_null() { - len = i; - 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); - } - - e(platform::syscall::execve(c_str(path), &args)) as c_int - } + platform::execve(path, argv, envp) } #[no_mangle]