Forked from
redox-os / relibc
2077 commits behind the upstream repository.
-
Jeremy Soller authoredJeremy Soller authored
start.rs 1.84 KiB
use alloc::Vec;
use core::ptr;
use header::{stdio, stdlib};
use platform;
use platform::types::*;
use platform::{Pal, Sys};
#[repr(C)]
pub struct Stack {
argc: isize,
argv0: *const c_char,
}
impl Stack {
fn argc(&self) -> isize {
self.argc
}
fn argv(&self) -> *const *const c_char {
&self.argv0 as *const _
}
fn envp(&self) -> *const *const c_char {
unsafe { self.argv().offset(self.argc() + 1) }
}
}
#[inline(never)]
#[no_mangle]
pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
extern "C" {
fn _init();
fn main(argc: isize, argv: *const *const c_char, envp: *const *const c_char) -> c_int;
}
let argc = sp.argc();
let argv = sp.argv();
let envp = sp.envp();
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 *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);
}
platform::inner_environ.push(buf);
}
platform::inner_environ.push(ptr::null_mut());
platform::environ = platform::inner_environ.as_mut_ptr();
// Initialize stdin/stdout/stderr, see https://github.com/rust-lang/rust/issues/51718
stdio::stdin = stdio::default_stdin.get();
stdio::stdout = stdio::default_stdout.get();
stdio::stderr = stdio::default_stderr.get();
_init();
stdlib::exit(main(
argc,
argv,
// not envp, because programs like bash try to modify this *const*
// pointer :|
platform::environ as *const *const c_char,
));
unreachable!();
}