Add support for process command-line arguments
This commit is contained in:
parent
0fbb38cd2f
commit
aefc4ee221
@ -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) -> Result<u64, ()> {
|
||||
syscalls::new_process(entry_point, space)
|
||||
pub fn new_process(entry_point: u64, space: AddressSpace, args: &[&[u8]]) -> Result<u64, ()> {
|
||||
syscalls::new_process(entry_point, space, args)
|
||||
}
|
||||
|
||||
#[stable(feature = "mikros", since = "1.80.0")]
|
||||
|
@ -1,31 +1,60 @@
|
||||
use crate::ffi::OsString;
|
||||
use crate::ffi::{CStr, OsString};
|
||||
use crate::fmt;
|
||||
use crate::ptr;
|
||||
use crate::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
|
||||
|
||||
pub struct Args {}
|
||||
static ARGC: AtomicUsize = AtomicUsize::new(0);
|
||||
static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
|
||||
|
||||
/// 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);
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Args {
|
||||
pos: usize,
|
||||
}
|
||||
|
||||
pub fn args() -> Args {
|
||||
Args {}
|
||||
Args { pos: 0 }
|
||||
}
|
||||
|
||||
impl fmt::Debug for Args {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_list().finish()
|
||||
f.debug_list().entries(self.clone()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for Args {
|
||||
type Item = OsString;
|
||||
fn next(&mut self) -> Option<OsString> {
|
||||
None
|
||||
let argc = ARGC.load(Ordering::Relaxed);
|
||||
if self.pos == argc {
|
||||
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(),
|
||||
)
|
||||
};
|
||||
self.pos += 1;
|
||||
Some(arg)
|
||||
}
|
||||
}
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(0, Some(0))
|
||||
let argc = ARGC.load(Ordering::Relaxed);
|
||||
(argc - self.pos, Some(argc - self.pos))
|
||||
}
|
||||
}
|
||||
|
||||
impl ExactSizeIterator for Args {
|
||||
fn len(&self) -> usize {
|
||||
0
|
||||
ARGC.load(Ordering::Relaxed).into()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,9 @@
|
||||
|
||||
// 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();
|
||||
unsafe { super::args::init(argc, argv) };
|
||||
}
|
||||
|
||||
// SAFETY: must be called only once during runtime cleanup.
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::ffi::{OsStr, OsString};
|
||||
use crate::ffi::{CString, OsStr, OsString};
|
||||
use crate::fmt;
|
||||
use crate::io;
|
||||
use crate::num::NonZero;
|
||||
@ -107,7 +107,13 @@ pub fn spawn(
|
||||
let path = Path::new(&self.program);
|
||||
let binary = crate::fs::read(path).unwrap();
|
||||
let (space, entry) = crate::os::mikros::loader::Loader::load(&binary);
|
||||
super::syscalls::new_process(entry as _, space).unwrap();
|
||||
let args_owned = self
|
||||
.args
|
||||
.iter()
|
||||
.map(|arg| CString::new(arg.clone().into_encoded_bytes()).unwrap())
|
||||
.collect::<Vec<CString>>();
|
||||
let args = args_owned.iter().map(|arg| arg.to_bytes_with_nul()).collect::<Vec<&[u8]>>();
|
||||
super::syscalls::new_process(entry as _, space, args.as_slice()).unwrap();
|
||||
Ok((Process { dummy: () }, StdioPipes { stdin: None, stdout: None, stderr: None }))
|
||||
}
|
||||
|
||||
|
@ -68,8 +68,9 @@ pub(crate) fn copy_to(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_process(entry_point: u64, space: AddressSpace) -> Result<u64, ()> {
|
||||
let (err, pid) = syscall2r2(8, entry_point, space.into_raw());
|
||||
pub fn new_process(entry_point: u64, space: AddressSpace, args: &[&[u8]]) -> Result<u64, ()> {
|
||||
let (err, pid) =
|
||||
syscall4r2(8, entry_point, space.into_raw(), args.len() as u64, args.as_ptr() as u64);
|
||||
if err == 1 { Err(()) } else { Ok(pid) }
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user