Compare commits

..

2 Commits

Author SHA1 Message Date
b78fffd9b0
mikros: implement read_dir 2024-10-04 12:27:43 -05:00
b9a358e1c5
mikros: Update file RPC to use Errno as error type 2024-10-04 12:03:11 -05:00
3 changed files with 109 additions and 34 deletions

View File

@ -139,6 +139,42 @@ pub enum Errno {
EWRZERO = 137, EWRZERO = 137,
} }
use serde::de::{self, Deserialize, Deserializer, Unexpected};
use crate::fmt;
#[unstable(feature = "mikros_internals", issue = "none")]
impl<'de> Deserialize<'de> for crate::os::mikros::Errno {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_i32(ErrnoVisitor)
}
}
struct ErrnoVisitor;
impl<'de> de::Visitor<'de> for ErrnoVisitor {
type Value = crate::os::mikros::Errno;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("errno")
}
fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
where
E: de::Error,
{
use crate::convert::TryFrom;
if let Ok(errno) = Errno::try_from(v) {
Ok(errno)
} else {
Err(E::invalid_value(Unexpected::Signed(v as i64), &self))
}
}
}
#[stable(feature = "mikros", since = "1.80.0")] #[stable(feature = "mikros", since = "1.80.0")]
impl TryFrom<i32> for Errno { impl TryFrom<i32> for Errno {
type Error = i32; type Error = i32;
@ -489,3 +525,10 @@ fn from(error: crate::io::Error) -> Self {
Self::from(error.kind()) Self::from(error.kind())
} }
} }
#[stable(feature = "mikros", since = "1.80.0")]
impl From<Errno> for crate::io::Error {
fn from(error: Errno) -> Self {
Self::from_raw_os_error(error)
}
}

View File

@ -6,7 +6,7 @@
use crate::hash::{Hash, Hasher}; use crate::hash::{Hash, Hasher};
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
use crate::os::mikros::ipc::rpc; use crate::os::mikros::ipc::rpc;
use crate::os::mikros::syscalls; use crate::os::mikros::{Errno, syscalls};
use crate::path::{Path, PathBuf}; use crate::path::{Path, PathBuf};
use crate::sys::time::SystemTime; use crate::sys::time::SystemTime;
use crate::sys::unsupported; use crate::sys::unsupported;
@ -43,9 +43,16 @@ pub struct FileAttr {
size: u64, size: u64,
} }
pub struct ReadDir(!); #[derive(Debug)]
pub struct ReadDir {
path: PathBuf,
fs_pid: u64,
fd: u64,
}
pub struct DirEntry(!); pub struct DirEntry {
path: PathBuf,
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct OpenOptions {} pub struct OpenOptions {}
@ -169,35 +176,46 @@ fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
} }
} }
impl fmt::Debug for ReadDir {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0
}
}
impl Iterator for ReadDir { impl Iterator for ReadDir {
type Item = io::Result<DirEntry>; type Item = io::Result<DirEntry>;
fn next(&mut self) -> Option<io::Result<DirEntry>> { fn next(&mut self) -> Option<io::Result<DirEntry>> {
self.0 let msg_data =
&rpc::send_call(self.fs_pid, 7, 0, &postcard::to_allocvec(&self.fd).unwrap())
.get_return();
let entry_res: Result<Option<String>, Errno> = postcard::from_bytes(msg_data).unwrap();
let entry_name = match entry_res.transpose()? {
Ok(val) => val,
Err(e) => return Some(Err(e.into())),
};
let mut entry_path = self.path.clone();
entry_path.push(entry_name);
Some(Ok(DirEntry { path: entry_path }))
}
}
impl Drop for ReadDir {
fn drop(&mut self) {
let _ = &rpc::send_call(self.fs_pid, 7, 1, &postcard::to_allocvec(&self.fd).unwrap())
.get_return();
} }
} }
impl DirEntry { impl DirEntry {
pub fn path(&self) -> PathBuf { pub fn path(&self) -> PathBuf {
self.0 self.path.clone()
} }
pub fn file_name(&self) -> OsString { pub fn file_name(&self) -> OsString {
self.0 self.path.file_name().unwrap().to_owned()
} }
pub fn metadata(&self) -> io::Result<FileAttr> { pub fn metadata(&self) -> io::Result<FileAttr> {
self.0 unsupported()
} }
pub fn file_type(&self) -> io::Result<FileType> { pub fn file_type(&self) -> io::Result<FileType> {
self.0 unsupported()
} }
} }
@ -221,22 +239,21 @@ pub fn open(path: &Path, _opts: &OpenOptions) -> io::Result<File> {
break pid; break pid;
} }
}; };
let open_res: Result<(u64, u64), ()> = postcard::from_bytes( let open_res: Result<(u64, u64), Errno> = postcard::from_bytes(
&rpc::send_call(vfs_pid, 2, 2, &postcard::to_allocvec(path).unwrap()).get_return(), &rpc::send_call(vfs_pid, 2, 2, &postcard::to_allocvec(path).unwrap()).get_return(),
) )
.unwrap(); .unwrap();
let (fs_pid, fd) = let (fs_pid, fd) = open_res?;
open_res.map_err(|_| io::Error::new(io::ErrorKind::NotFound, "No such file"))?;
Ok(Self { fs_pid, fd }) Ok(Self { fs_pid, fd })
} }
pub fn file_attr(&self) -> io::Result<FileAttr> { pub fn file_attr(&self) -> io::Result<FileAttr> {
let size_res: Option<u64> = postcard::from_bytes( let size_res: Result<u64, Errno> = postcard::from_bytes(
&rpc::send_call(self.fs_pid, 1, 3, &postcard::to_allocvec(&self.fd).unwrap()) &rpc::send_call(self.fs_pid, 1, 3, &postcard::to_allocvec(&self.fd).unwrap())
.get_return(), .get_return(),
) )
.unwrap(); .unwrap();
let size = size_res.unwrap_or(0); let size = size_res?;
Ok(FileAttr { size }) Ok(FileAttr { size })
} }
@ -260,8 +277,8 @@ pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
&postcard::to_allocvec(&(self.fd, buf.len())).unwrap(), &postcard::to_allocvec(&(self.fd, buf.len())).unwrap(),
) )
.get_return(); .get_return();
let read_res: Result<&[u8], ()> = postcard::from_bytes(msg_data).unwrap(); let read_res: Result<&[u8], Errno> = postcard::from_bytes(msg_data).unwrap();
let read_data = read_res.unwrap(); let read_data = read_res?;
let copy_len = usize::min(read_data.len(), buf.len()); let copy_len = usize::min(read_data.len(), buf.len());
buf[0..copy_len].copy_from_slice(&read_data[0..copy_len]); buf[0..copy_len].copy_from_slice(&read_data[0..copy_len]);
Ok(copy_len) Ok(copy_len)
@ -283,20 +300,20 @@ pub fn read_buf(&self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
&postcard::to_allocvec(&(self.fd, cursor.capacity())).unwrap(), &postcard::to_allocvec(&(self.fd, cursor.capacity())).unwrap(),
) )
.get_return(); .get_return();
let read_res: Result<&[u8], ()> = postcard::from_bytes(msg_data).unwrap(); let read_res: Result<&[u8], Errno> = postcard::from_bytes(msg_data).unwrap();
let read_data = read_res.unwrap(); let read_data = read_res?;
let copy_len = usize::min(read_data.len(), cursor.capacity()); let copy_len = usize::min(read_data.len(), cursor.capacity());
cursor.append(&read_data[0..copy_len]); cursor.append(&read_data[0..copy_len]);
Ok(()) Ok(())
} }
pub fn write(&self, buf: &[u8]) -> io::Result<usize> { pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
let write_res: Result<(), ()> = postcard::from_bytes( let write_res: Result<(), Errno> = postcard::from_bytes(
&rpc::send_call(self.fs_pid, 1, 1, &postcard::to_allocvec(&(self.fd, buf)).unwrap()) &rpc::send_call(self.fs_pid, 1, 1, &postcard::to_allocvec(&(self.fd, buf)).unwrap())
.get_return(), .get_return(),
) )
.unwrap(); .unwrap();
write_res.unwrap(); write_res?;
Ok(buf.len()) Ok(buf.len())
} }
@ -318,17 +335,17 @@ pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
SeekFrom::End(offset) => postcard::to_allocvec(&(self.fd, 1u8, offset)).unwrap(), SeekFrom::End(offset) => postcard::to_allocvec(&(self.fd, 1u8, offset)).unwrap(),
SeekFrom::Current(offset) => postcard::to_allocvec(&(self.fd, 2u8, offset)).unwrap(), SeekFrom::Current(offset) => postcard::to_allocvec(&(self.fd, 2u8, offset)).unwrap(),
}; };
let seek_res: u64 = let seek_res: Result<u64, Errno> =
postcard::from_bytes(&rpc::send_call(self.fs_pid, 1, 8, &args).get_return()).unwrap(); postcard::from_bytes(&rpc::send_call(self.fs_pid, 1, 8, &args).get_return()).unwrap();
Ok(seek_res) Ok(seek_res?)
} }
pub fn duplicate(&self) -> io::Result<File> { pub fn duplicate(&self) -> io::Result<File> {
let msg_data = let msg_data =
&rpc::send_call(self.fs_pid, 1, 4, &postcard::to_allocvec(&self.fd).unwrap()) &rpc::send_call(self.fs_pid, 1, 4, &postcard::to_allocvec(&self.fd).unwrap())
.get_return(); .get_return();
let dup_res: Option<u64> = postcard::from_bytes(msg_data).unwrap(); let dup_res: Result<u64, Errno> = postcard::from_bytes(msg_data).unwrap();
let dup_data = dup_res.unwrap(); let dup_data = dup_res?;
Ok(Self { fs_pid: self.fs_pid, fd: dup_data }) Ok(Self { fs_pid: self.fs_pid, fd: dup_data })
} }
@ -364,8 +381,18 @@ fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
} }
} }
pub fn readdir(_p: &Path) -> io::Result<ReadDir> { pub fn readdir(path: &Path) -> io::Result<ReadDir> {
unsupported() let vfs_pid = loop {
if let Some(pid) = syscalls::try_get_registered(0) {
break pid;
}
};
let open_res: Result<(u64, u64), Errno> = postcard::from_bytes(
&rpc::send_call(vfs_pid, 2, 6, &postcard::to_allocvec(path).unwrap()).get_return(),
)
.unwrap();
let (fs_pid, fd) = open_res?;
Ok(ReadDir { path: path.to_owned(), fs_pid, fd })
} }
pub fn unlink(_p: &Path) -> io::Result<()> { pub fn unlink(_p: &Path) -> io::Result<()> {

View File

@ -3,6 +3,7 @@
pub use crate::ffi::OsString as EnvKey; pub use crate::ffi::OsString as EnvKey;
use crate::ffi::{CString, OsStr, OsString}; use crate::ffi::{CString, OsStr, OsString};
use crate::num::NonZero; use crate::num::NonZero;
use crate::os::mikros::Errno;
use crate::os::mikros::ipc::rpc; use crate::os::mikros::ipc::rpc;
use crate::path::Path; use crate::path::Path;
use crate::sys::fs::File; use crate::sys::fs::File;
@ -128,7 +129,7 @@ pub fn spawn(
}; };
let stdio = [stdin, stdout, stderr]; let stdio = [stdin, stdout, stderr];
let path = Path::new(&self.program); let path = Path::new(&self.program);
let binary = crate::fs::read(path).unwrap(); 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_owned = self
.args .args
@ -138,8 +139,12 @@ pub fn spawn(
let args = args_owned.iter().map(|arg| arg.to_bytes_with_nul()).collect::<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, 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) { if let Some(vfs_pid) = syscalls::try_get_registered(0) {
let _ = &rpc::send_call(vfs_pid, 2, 4, &postcard::to_allocvec(&(pid, stdio)).unwrap()) let res: Result<(), Errno> = postcard::from_bytes(
.get_return(); &rpc::send_call(vfs_pid, 2, 4, &postcard::to_allocvec(&(pid, stdio)).unwrap())
.get_return(),
)
.unwrap();
res?;
}; };
syscalls::wake_new(pid).unwrap(); syscalls::wake_new(pid).unwrap();
Ok((Process { dummy: () }, StdioPipes { stdin: None, stdout: None, stderr: None })) Ok((Process { dummy: () }, StdioPipes { stdin: None, stdout: None, stderr: None }))