mikros: Properly implement stdio
This commit is contained in:
parent
b3b12eec10
commit
5ff8990346
@ -5,6 +5,7 @@
|
||||
// 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) {
|
||||
rpc::init();
|
||||
super::stdio::init();
|
||||
unsafe { super::args::init(argc, argv) };
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
pub struct File {
|
||||
pub(crate) fs_pid: u64,
|
||||
pub(crate) fd: u64,
|
||||
pos: AtomicUsize,
|
||||
pub(crate) pos: AtomicUsize,
|
||||
}
|
||||
|
||||
pub struct FileAttr {
|
||||
|
@ -1,6 +1,9 @@
|
||||
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::num::NonZero;
|
||||
use crate::os::mikros::ipc::rpc;
|
||||
use crate::path::Path;
|
||||
use crate::sys::fs::File;
|
||||
use crate::sys::pipe::AnonPipe;
|
||||
@ -36,8 +39,8 @@ pub enum Stdio {
|
||||
Inherit,
|
||||
Null,
|
||||
MakePipe,
|
||||
ParentStdout,
|
||||
ParentStderr,
|
||||
//ParentStdout,
|
||||
//ParentStderr,
|
||||
#[allow(dead_code)] // This variant exists only for the Debug impl
|
||||
InheritFile(File),
|
||||
}
|
||||
@ -102,6 +105,28 @@ pub fn spawn(
|
||||
_default: Stdio,
|
||||
_needs_stdin: bool,
|
||||
) -> io::Result<(Process, StdioPipes)> {
|
||||
let stdin = match self.stdin.take() {
|
||||
None => None,
|
||||
Some(Stdio::Null) => None,
|
||||
Some(Stdio::Inherit) => *STDIN_FD.get().unwrap(),
|
||||
Some(Stdio::MakePipe) => todo!(),
|
||||
Some(Stdio::InheritFile(file)) => Some((file.fs_pid, file.fd)),
|
||||
};
|
||||
let stdout = match self.stdout.take() {
|
||||
None => None,
|
||||
Some(Stdio::Null) => None,
|
||||
Some(Stdio::Inherit) => *STDOUT_FD.get().unwrap(),
|
||||
Some(Stdio::MakePipe) => todo!(),
|
||||
Some(Stdio::InheritFile(file)) => Some((file.fs_pid, file.fd)),
|
||||
};
|
||||
let stderr = match self.stderr.take() {
|
||||
None => None,
|
||||
Some(Stdio::Null) => None,
|
||||
Some(Stdio::Inherit) => *STDERR_FD.get().unwrap(),
|
||||
Some(Stdio::MakePipe) => todo!(),
|
||||
Some(Stdio::InheritFile(file)) => Some((file.fs_pid, file.fd)),
|
||||
};
|
||||
let stdio = [stdin, stdout, stderr];
|
||||
let path = Path::new(&self.program);
|
||||
let binary = crate::fs::read(path).unwrap();
|
||||
let (space, entry) = crate::os::mikros::loader::Loader::load(&binary);
|
||||
@ -111,7 +136,11 @@ pub fn spawn(
|
||||
.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();
|
||||
let pid = super::syscalls::new_process(entry as _, space, args.as_slice()).unwrap();
|
||||
if let Some(vfs_pid) = syscalls::try_get_registered(0) {
|
||||
let _ = &rpc::send_call(vfs_pid, 2, 4, &postcard::to_allocvec(&(pid, stdio)).unwrap())
|
||||
.get_return();
|
||||
};
|
||||
Ok((Process { dummy: () }, StdioPipes { stdin: None, stdout: None, stderr: None }))
|
||||
}
|
||||
|
||||
@ -128,13 +157,13 @@ fn from(pipe: AnonPipe) -> Stdio {
|
||||
|
||||
impl From<io::Stdout> for Stdio {
|
||||
fn from(_: io::Stdout) -> Stdio {
|
||||
Stdio::ParentStdout
|
||||
Stdio::Inherit
|
||||
}
|
||||
}
|
||||
|
||||
impl From<io::Stderr> for Stdio {
|
||||
fn from(_: io::Stderr) -> Stdio {
|
||||
Stdio::ParentStderr
|
||||
Stdio::Inherit
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,14 @@
|
||||
use crate::arch::asm;
|
||||
//use crate::arch::asm;
|
||||
use super::fs::File;
|
||||
use super::syscalls;
|
||||
use crate::io;
|
||||
use crate::os::mikros::ipc::rpc;
|
||||
use crate::sync::atomic::AtomicUsize;
|
||||
use crate::sync::OnceLock;
|
||||
|
||||
pub(crate) static STDIN_FD: OnceLock<Option<(u64, u64)>> = OnceLock::new();
|
||||
pub(crate) static STDOUT_FD: OnceLock<Option<(u64, u64)>> = OnceLock::new();
|
||||
pub(crate) static STDERR_FD: OnceLock<Option<(u64, u64)>> = OnceLock::new();
|
||||
|
||||
pub struct Stdin;
|
||||
pub struct Stdout;
|
||||
@ -12,8 +21,13 @@ pub const fn new() -> Stdin {
|
||||
}
|
||||
|
||||
impl io::Read for Stdin {
|
||||
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
|
||||
Ok(0)
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let Some(fd) = *STDIN_FD.get().unwrap() else {
|
||||
return Ok(0);
|
||||
};
|
||||
let file = File { fs_pid: fd.0, fd: fd.1, pos: AtomicUsize::new(0) };
|
||||
let num_bytes = file.read(buf)?;
|
||||
Ok(num_bytes)
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,12 +39,17 @@ pub const fn new() -> Stdout {
|
||||
|
||||
impl io::Write for Stdout {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
for byte in buf {
|
||||
unsafe {
|
||||
asm!("int 0x80", in("rax") 0, in ("rcx") *byte as u64);
|
||||
};
|
||||
}
|
||||
Ok(buf.len())
|
||||
//for byte in buf {
|
||||
// unsafe {
|
||||
// asm!("int 0x80", in("rax") 0, in ("rcx") *byte as u64);
|
||||
// };
|
||||
//}
|
||||
//Ok(buf.len())
|
||||
let Some(fd) = *STDOUT_FD.get().unwrap() else {
|
||||
return Ok(0);
|
||||
};
|
||||
let file = File { fs_pid: fd.0, fd: fd.1, pos: AtomicUsize::new(0) };
|
||||
file.write(buf)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
@ -46,12 +65,17 @@ pub const fn new() -> Stderr {
|
||||
|
||||
impl io::Write for Stderr {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
for byte in buf {
|
||||
unsafe {
|
||||
asm!("int 0x80", in("rax") 0, in ("rcx") *byte as u64);
|
||||
};
|
||||
}
|
||||
Ok(buf.len())
|
||||
//for byte in buf {
|
||||
// unsafe {
|
||||
// asm!("int 0x80", in("rax") 0, in ("rcx") *byte as u64);
|
||||
// };
|
||||
//}
|
||||
//Ok(buf.len())
|
||||
let Some(fd) = *STDERR_FD.get().unwrap() else {
|
||||
return Ok(0);
|
||||
};
|
||||
let file = File { fs_pid: fd.0, fd: fd.1, pos: AtomicUsize::new(0) };
|
||||
file.write(buf)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
@ -59,7 +83,7 @@ fn flush(&mut self) -> io::Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
pub const STDIN_BUF_SIZE: usize = 0;
|
||||
pub const STDIN_BUF_SIZE: usize = 8192;
|
||||
|
||||
pub fn is_ebadf(_err: &io::Error) -> bool {
|
||||
true
|
||||
@ -68,3 +92,17 @@ pub fn is_ebadf(_err: &io::Error) -> bool {
|
||||
pub fn panic_output() -> Option<impl io::Write> {
|
||||
Some(Stderr::new())
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
let Some(vfs_pid) = syscalls::try_get_registered(0) else {
|
||||
STDIN_FD.get_or_init(|| None);
|
||||
STDOUT_FD.get_or_init(|| None);
|
||||
STDERR_FD.get_or_init(|| None);
|
||||
return;
|
||||
};
|
||||
let stdio: [Option<(u64, u64)>; 3] =
|
||||
postcard::from_bytes(&rpc::send_call(vfs_pid, 2, 5, &[]).get_return()).unwrap();
|
||||
STDIN_FD.get_or_init(|| stdio[0]);
|
||||
STDOUT_FD.get_or_init(|| stdio[1]);
|
||||
STDERR_FD.get_or_init(|| stdio[2]);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user