diff --git a/library/std/src/os/mikros/syscalls.rs b/library/std/src/os/mikros/syscalls.rs index b3fe02a2849..a2b28e3e540 100644 --- a/library/std/src/os/mikros/syscalls.rs +++ b/library/std/src/os/mikros/syscalls.rs @@ -11,8 +11,8 @@ pub fn get_initrd() -> &'static [u8] { } #[stable(feature = "mikros", since = "1.80.0")] -pub fn new_process(entry_point: u64, space: AddressSpace, args: &[&[u8]]) -> Result { - syscalls::new_process(entry_point, space, args) +pub fn new_process(entry_point: u64, space: AddressSpace) -> Result { + syscalls::new_process(entry_point, space) } #[stable(feature = "mikros", since = "1.80.0")] diff --git a/library/std/src/sys/pal/mikros/args.rs b/library/std/src/sys/pal/mikros/args.rs index 2762a5156a0..d1124bd8323 100644 --- a/library/std/src/sys/pal/mikros/args.rs +++ b/library/std/src/sys/pal/mikros/args.rs @@ -1,15 +1,23 @@ -use crate::ffi::{CStr, OsString}; -use crate::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; -use crate::{fmt, ptr}; +use super::syscalls; +use crate::ffi::OsString; +use crate::fmt; +use crate::os::mikros::ffi::OsStringExt; +use crate::os::mikros::ipc::rpc; +use crate::sync::OnceLock; -static ARGC: AtomicUsize = AtomicUsize::new(0); -static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut()); +static ARGS: OnceLock> = OnceLock::new(); -/// SAFETY: This function must be called either exactly once, -/// or if called more than once must always be called with the same values -pub unsafe fn init(argc: isize, argv: *const *const u8) { - ARGC.store(argc as usize, Ordering::Relaxed); - ARGV.store(argv as *mut _, Ordering::Relaxed); +pub fn init() { + ARGS.get_or_init(|| { + if let Some(proc_man_pid) = syscalls::try_get_registered(3) { + let args_raw: Vec<(u32, Vec)> = + postcard::from_bytes(&rpc::send_call(proc_man_pid, 8, 3, &[]).get_return()) + .unwrap(); + args_raw.into_iter().map(|(_, arg)| OsString::from_vec(arg)).collect::>() + } else { + Vec::new() + } + }); } #[derive(Copy, Clone)] @@ -30,30 +38,26 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { - let argc = ARGC.load(Ordering::Relaxed); - if self.pos == argc { + let args = ARGS.get().unwrap(); + if self.pos == args.len() { None } else { - let argv = ARGV.load(Ordering::Relaxed); - let arg = unsafe { - let arg_ptr = argv.add(self.pos).read(); - OsString::from_encoded_bytes_unchecked( - CStr::from_ptr(arg_ptr.cast()).to_owned().into_bytes(), - ) - }; + let arg = args[self.pos].clone(); self.pos += 1; Some(arg) } } fn size_hint(&self) -> (usize, Option) { - let argc = ARGC.load(Ordering::Relaxed); - (argc - self.pos, Some(argc - self.pos)) + let args = ARGS.get().unwrap(); + let remaining = args.len() - self.pos; + (remaining, Some(remaining)) } } impl ExactSizeIterator for Args { fn len(&self) -> usize { - ARGC.load(Ordering::Relaxed).into() + let args = ARGS.get().unwrap(); + args.len() } } diff --git a/library/std/src/sys/pal/mikros/common.rs b/library/std/src/sys/pal/mikros/common.rs index a6957639875..546cb0868ef 100644 --- a/library/std/src/sys/pal/mikros/common.rs +++ b/library/std/src/sys/pal/mikros/common.rs @@ -4,10 +4,10 @@ // SAFETY: must be called only once during runtime initialization. // NOTE: this is not guaranteed to run, for example when Rust code is called externally. -pub unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) { +pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) { rpc::init(); super::stdio::init(); - unsafe { super::args::init(argc, argv) }; + super::args::init(); } // SAFETY: must be called only once during runtime cleanup. diff --git a/library/std/src/sys/pal/mikros/process.rs b/library/std/src/sys/pal/mikros/process.rs index eda26ad9415..6b253ac3501 100644 --- a/library/std/src/sys/pal/mikros/process.rs +++ b/library/std/src/sys/pal/mikros/process.rs @@ -1,7 +1,7 @@ use super::stdio::{STDERR_FD, STDIN_FD, STDOUT_FD}; use super::syscalls; pub use crate::ffi::OsString as EnvKey; -use crate::ffi::{CString, OsStr, OsString}; +use crate::ffi::{OsStr, OsString}; use crate::num::NonZero; use crate::os::mikros::Errno; use crate::os::mikros::ipc::rpc; @@ -128,13 +128,12 @@ pub fn spawn( let path = Path::new(&self.program); let binary = crate::fs::read(path)?; let (space, entry) = crate::os::mikros::loader::Loader::load(&binary); - let args_owned = self + let args = self .args .iter() - .map(|arg| CString::new(arg.clone().into_encoded_bytes()).unwrap()) - .collect::>(); - let args = args_owned.iter().map(|arg| arg.to_bytes_with_nul()).collect::>(); - let pid = super::syscalls::new_process(entry as _, space, args.as_slice()).unwrap(); + .map(|arg| (0, arg.clone().into_encoded_bytes())) + .collect::)>>(); + let pid = super::syscalls::new_process(entry as _, space).unwrap(); if let Some(vfs_pid) = syscalls::try_get_registered(0) { let res: Result<(), Errno> = postcard::from_bytes( &rpc::send_call(vfs_pid, 2, 4, &postcard::to_allocvec(&(pid, stdio)).unwrap()) @@ -143,6 +142,14 @@ pub fn spawn( .unwrap(); res?; }; + if let Some(proc_man_pid) = syscalls::try_get_registered(3) { + let res: Result<(), Errno> = postcard::from_bytes( + &rpc::send_call(proc_man_pid, 8, 2, &postcard::to_allocvec(&(pid, args)).unwrap()) + .get_return(), + ) + .unwrap(); + res?; + }; syscalls::wake_new(pid).unwrap(); Ok((Process { pid }, StdioPipes { stdin: None, stdout: None, stderr: None })) } diff --git a/library/std/src/sys/pal/mikros/start.rs b/library/std/src/sys/pal/mikros/start.rs index 3f15f5b1a94..bc76bf21724 100644 --- a/library/std/src/sys/pal/mikros/start.rs +++ b/library/std/src/sys/pal/mikros/start.rs @@ -1,5 +1,5 @@ -use crate::arch::asm; use crate::ffi::{c_char, c_int}; +use crate::ptr; extern "C" { fn main(argc: c_int, argv: *const *const c_char) -> c_int; @@ -8,11 +8,8 @@ #[no_mangle] #[allow(unused)] pub extern "C" fn _start() { - let argc; - let argv; unsafe { - asm!("int 0x80", in("rax") 19, lateout("rax") argv, lateout("rcx") argc); - let code = main(argc, argv); + let code = main(0, ptr::null()); crate::sys::os::exit(code); }; } diff --git a/library/std/src/sys/pal/mikros/syscalls.rs b/library/std/src/sys/pal/mikros/syscalls.rs index a509b53d6fa..ec43fb15bce 100644 --- a/library/std/src/sys/pal/mikros/syscalls.rs +++ b/library/std/src/sys/pal/mikros/syscalls.rs @@ -69,9 +69,8 @@ pub(crate) fn copy_to( } } -pub fn new_process(entry_point: u64, space: AddressSpace, args: &[&[u8]]) -> Result { - let (err, pid) = - syscall4r2(8, entry_point, space.into_raw(), args.len() as u64, args.as_ptr() as u64); +pub fn new_process(entry_point: u64, space: AddressSpace) -> Result { + let (err, pid) = syscall2r2(8, entry_point, space.into_raw()); if err == 1 { Err(()) } else { Ok(pid) } } @@ -143,8 +142,6 @@ pub fn wait_for_ipc_message() { syscall0(18); } -// Syscall 19: Get CLI arguments, used by crt0 startup code to provide argc and argv. Not needed in Rust. - /// ## Safety /// /// The caller must ensure that no undefined behavior or memory safety