alnyan/yggdrasil: better argument passing from kernel
This commit is contained in:
@@ -2,17 +2,15 @@ use crate::ffi::OsString;
|
||||
use crate::fmt;
|
||||
use crate::mem::size_of;
|
||||
use crate::str::FromStr;
|
||||
use crate::sys::yggdrasil::util::KStringList;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone)]
|
||||
pub struct Args {
|
||||
list: KStringList,
|
||||
index: usize,
|
||||
iter: crate::slice::Iter<'static, &'static str>,
|
||||
}
|
||||
|
||||
pub fn args() -> Args {
|
||||
Args { list: unsafe { KStringList::new(super::ARGS) }, index: 0 }
|
||||
unsafe { Args { iter: super::ARGS.assume_init_ref().iter() } }
|
||||
}
|
||||
|
||||
impl fmt::Debug for Args {
|
||||
@@ -25,22 +23,15 @@ impl Iterator for Args {
|
||||
type Item = OsString;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.index == self.list.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let str = self.list.get(self.index);
|
||||
self.index += 1;
|
||||
|
||||
let os_str = OsString::from_str(str).unwrap();
|
||||
|
||||
let item = self.iter.next()?;
|
||||
let os_str = OsString::from_str(item).unwrap();
|
||||
Some(os_str)
|
||||
}
|
||||
}
|
||||
|
||||
impl ExactSizeIterator for Args {
|
||||
fn len(&self) -> usize {
|
||||
self.list.len()
|
||||
self.iter.len()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ pub(self) use yggdrasil_rt;
|
||||
|
||||
mod util;
|
||||
|
||||
use yggdrasil_rt::process::ExitCode as OsExitCode;
|
||||
use yggdrasil_rt::process::{ExitCode as OsExitCode, ProgramArgumentInner};
|
||||
use yggdrasil_rt::Error as OsError;
|
||||
|
||||
use crate::path::Path;
|
||||
@@ -46,8 +46,9 @@ use crate::path::Path;
|
||||
//
|
||||
// 0x000: args pointer
|
||||
// 0x008: envs pointer
|
||||
static mut ARGS: usize = 0;
|
||||
// static mut ARGS: usize = 0;
|
||||
// TODO handle this in better way
|
||||
static mut ARGS: MaybeUninit<&'static [&'static str]> = MaybeUninit::uninit();
|
||||
static mut ENVS: MaybeUninit<HashMap<OsString, OsString>> = MaybeUninit::uninit();
|
||||
|
||||
#[doc(hidden)]
|
||||
@@ -163,23 +164,14 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
|
||||
}
|
||||
|
||||
unsafe fn init_kernel_arg(program_arg: usize) {
|
||||
#[repr(C)]
|
||||
struct Header {
|
||||
args_ptr: usize,
|
||||
envs_ptr: usize,
|
||||
};
|
||||
|
||||
#[allow(fuzzy_provenance_casts)]
|
||||
let hdr = program_arg as *const Header;
|
||||
|
||||
ARGS = (*hdr).args_ptr;
|
||||
let env_list = util::KStringList::new((*hdr).envs_ptr);
|
||||
let arg = &*(program_arg as *const ProgramArgumentInner<'static>);
|
||||
|
||||
ARGS.write(arg.args);
|
||||
let mut envs = ENVS.write(HashMap::new());
|
||||
|
||||
for i in 0..env_list.len() {
|
||||
let line = env_list.get(i);
|
||||
let Some((key, value)) = line.split_once('=') else {
|
||||
for pair in arg.env {
|
||||
let Some((key, value)) = pair.split_once('=') else {
|
||||
continue;
|
||||
};
|
||||
let key = OsString::from_str(key).unwrap();
|
||||
|
||||
@@ -6,7 +6,6 @@ use crate::io;
|
||||
use crate::marker::PhantomData;
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::str::FromStr;
|
||||
use crate::sys::yggdrasil::util::KStringList;
|
||||
|
||||
use yggdrasil_rt::Error as OsError;
|
||||
|
||||
|
||||
@@ -1,51 +1,6 @@
|
||||
use crate::env;
|
||||
use crate::mem::size_of;
|
||||
use crate::path::PathBuf;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct KStringList {
|
||||
base: usize,
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl KStringList {
|
||||
pub unsafe fn new(base: usize) -> Self {
|
||||
if base == 0 {
|
||||
panic!("Program arguments not initialized");
|
||||
}
|
||||
|
||||
let len = unsafe {
|
||||
#[allow(fuzzy_provenance_casts)]
|
||||
(base as *const usize).read()
|
||||
};
|
||||
|
||||
Self { base, len }
|
||||
}
|
||||
|
||||
pub fn get(&self, index: usize) -> &'static str {
|
||||
assert!(index < self.len);
|
||||
let len = unsafe {
|
||||
#[allow(fuzzy_provenance_casts)]
|
||||
(Self::item(self.base, index) as *const usize).read()
|
||||
};
|
||||
let ptr = unsafe {
|
||||
#[allow(fuzzy_provenance_casts)]
|
||||
((Self::item(self.base, index) + size_of::<usize>()) as *const *const u8).read()
|
||||
};
|
||||
let slice = unsafe { crate::slice::from_raw_parts(ptr, len) };
|
||||
|
||||
crate::str::from_utf8(slice).unwrap()
|
||||
}
|
||||
|
||||
pub const fn len(&self) -> usize {
|
||||
self.len
|
||||
}
|
||||
|
||||
const fn item(base: usize, index: usize) -> usize {
|
||||
base + (/* array len */1 + /* pair */ 2 * index) * size_of::<usize>()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_binary(name: &str) -> Option<String> {
|
||||
// Already an absolute path
|
||||
if name.starts_with('/') {
|
||||
|
||||
Reference in New Issue
Block a user