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