From 3668bbdf3ac05f2cc458baf30640b9d2f66c0d65 Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Tue, 14 Nov 2023 14:39:15 +0200 Subject: [PATCH] alnyan/yggdrasil: [unsafe] make env writable --- library/std/src/sys/yggdrasil/mod.rs | 22 +++++++++++-- library/std/src/sys/yggdrasil/os.rs | 47 +++++++++++++--------------- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/library/std/src/sys/yggdrasil/mod.rs b/library/std/src/sys/yggdrasil/mod.rs index 211f206bb75..d181bd052d7 100644 --- a/library/std/src/sys/yggdrasil/mod.rs +++ b/library/std/src/sys/yggdrasil/mod.rs @@ -1,7 +1,11 @@ #![allow(unused)] #![allow(nonstandard_style)] +use crate::collections::HashMap; +use crate::ffi::OsString; use crate::io::{Error as IoError, ErrorKind, RawOsError}; +use crate::mem::MaybeUninit; +use crate::str::FromStr; #[path = "../unix/cmath.rs"] pub mod cmath; @@ -43,7 +47,8 @@ use crate::path::Path; // 0x000: args pointer // 0x008: envs pointer static mut ARGS: usize = 0; -static mut ENVS: usize = 0; +// TODO handle this in better way +static mut ENVS: MaybeUninit> = MaybeUninit::uninit(); #[doc(hidden)] pub trait IsNegative { @@ -168,7 +173,20 @@ unsafe fn init_kernel_arg(program_arg: usize) { let hdr = program_arg as *const Header; ARGS = (*hdr).args_ptr; - ENVS = (*hdr).envs_ptr; + let env_list = util::KStringList::new((*hdr).envs_ptr); + + 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 { + continue; + }; + let key = OsString::from_str(key).unwrap(); + let value = OsString::from_str(value).unwrap(); + + envs.insert(key, value); + } } #[cfg(not(test))] diff --git a/library/std/src/sys/yggdrasil/os.rs b/library/std/src/sys/yggdrasil/os.rs index b596c6b8472..6daa2f72d70 100644 --- a/library/std/src/sys/yggdrasil/os.rs +++ b/library/std/src/sys/yggdrasil/os.rs @@ -1,3 +1,4 @@ +use crate::collections::hash_map; use crate::error::Error as StdError; use crate::ffi::{OsStr, OsString}; use crate::fmt; @@ -12,8 +13,7 @@ use yggdrasil_rt::Error as OsError; pub struct SplitPaths<'a>(!, PhantomData<&'a ()>); pub struct Env { - list: KStringList, - index: usize, + it: hash_map::Iter<'static, OsString, OsString>, } impl !Send for Env {} @@ -23,26 +23,15 @@ impl Iterator for Env { type Item = (OsString, OsString); fn next(&mut self) -> Option<(OsString, OsString)> { - loop { - if self.index >= self.list.len() { - return None; - } - let item_str = self.list.get(self.index); - self.index += 1; - - let Some((key, value)) = item_str.split_once('=') else { - continue; - }; - - let key = OsString::from_str(key).unwrap(); - let value = OsString::from_str(value).unwrap(); - break Some((key, value)); + match self.it.next() { + Some((k, v)) => Some((k.clone(), v.clone())), + None => None, } } - // fn size_hint(&self) -> (usize, Option) { - // todo!() - // } + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } } pub fn split_paths(_path: &OsStr) -> SplitPaths<'_> { @@ -122,17 +111,23 @@ pub fn current_exe() -> io::Result { } pub fn env() -> Env { - Env { list: unsafe { KStringList::new(super::ENVS) }, index: 0 } + Env { it: unsafe { super::ENVS.assume_init_ref().iter() } } } -pub fn getenv(_name: &OsStr) -> Option { - todo!() +pub fn getenv(name: &OsStr) -> Option { + unsafe { super::ENVS.assume_init_ref().get(name).cloned() } } -pub fn setenv(_name: &OsStr, _value: &OsStr) -> io::Result<()> { - todo!() +pub fn setenv(name: &OsStr, value: &OsStr) -> io::Result<()> { + unsafe { + super::ENVS.assume_init_mut().insert(name.to_owned(), value.to_owned()); + } + Ok(()) } -pub fn unsetenv(_name: &OsStr) -> io::Result<()> { - todo!() +pub fn unsetenv(name: &OsStr) -> io::Result<()> { + unsafe { + super::ENVS.assume_init_mut().remove(name); + } + Ok(()) }