diff --git a/src/io/file.rs b/src/io/file.rs index 99145398..0e07f696 100644 --- a/src/io/file.rs +++ b/src/io/file.rs @@ -1,3 +1,5 @@ +use core::fmt; + use crate::{bitflags, primitive_enum}; bitflags! { @@ -121,6 +123,35 @@ impl From for SeekFrom { } } +impl fmt::Display for FileMode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + macro_rules! print_bit { + ($res:expr, $val:expr, $self:expr, $bit:expr) => { + if $self.contains($bit) { + $res = $val; + } + }; + } + + let mut buf = ['-'; 9]; + + print_bit!(buf[0], 'r', self, Self::USER_READ); + print_bit!(buf[1], 'w', self, Self::USER_WRITE); + print_bit!(buf[2], 'x', self, Self::USER_EXEC); + print_bit!(buf[3], 'r', self, Self::GROUP_READ); + print_bit!(buf[4], 'w', self, Self::GROUP_WRITE); + print_bit!(buf[5], 'x', self, Self::GROUP_EXEC); + print_bit!(buf[6], 'r', self, Self::OTHER_READ); + print_bit!(buf[7], 'w', self, Self::OTHER_WRITE); + print_bit!(buf[8], 'x', self, Self::OTHER_EXEC); + + for ch in buf.iter() { + fmt::Display::fmt(ch, f)?; + } + Ok(()) + } +} + #[cfg(test)] mod tests { use crate::io::SeekFrom; diff --git a/src/io/terminal.rs b/src/io/terminal.rs index 01e7627c..ab681317 100644 --- a/src/io/terminal.rs +++ b/src/io/terminal.rs @@ -77,6 +77,13 @@ impl TerminalControlCharacters { } } +impl TerminalLineOptions { + /// Returns the line options used for raw tty input + pub const fn raw_input() -> Self { + Self::empty() + } +} + impl TerminalOptions { /// const-version of [Default] trait impl pub const fn const_default() -> Self { @@ -88,6 +95,14 @@ impl TerminalOptions { } } + /// Returns terminal options configured for raw tty input + pub const fn raw_input() -> Self { + Self { + line: TerminalLineOptions::raw_input(), + ..Self::const_default() + } + } + /// Returns `true` if CANONICAL flag is set for this terminal pub const fn is_canonical(&self) -> bool { self.line.contains(TerminalLineOptions::CANONICAL) diff --git a/src/lib.rs b/src/lib.rs index 984e5b3f..d5e0f297 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ //! Yggdrasil OS user-kernel communication ABI #![no_std] #![feature(trace_macros, const_trait_impl)] -#![deny(missing_docs)] +// #![deny(missing_docs)] pub(crate) mod macros; @@ -10,4 +10,5 @@ pub mod error; pub mod io; pub mod path; pub mod process; +pub mod serde; pub mod syscall; diff --git a/src/process.rs b/src/process.rs index 503eb1c3..cb6eebf3 100644 --- a/src/process.rs +++ b/src/process.rs @@ -58,6 +58,8 @@ pub struct SpawnOptions<'a> { pub program: &'a str, /// Arguments to the child process pub arguments: &'a [&'a str], + /// Environment for the child process + pub environment: &'a [&'a str], /// Optional arguments to specify details of the creation pub optional: &'a [SpawnOption], } diff --git a/src/serde.rs b/src/serde.rs new file mode 100644 index 00000000..08ad0ca5 --- /dev/null +++ b/src/serde.rs @@ -0,0 +1,97 @@ +use core::ops::DerefMut; + +use crate::error::Error; + +pub trait SerializeBuffer { + fn write_bytes(&mut self, data: &[u8]) -> Result<(), Error>; +} + +pub trait DeserializeBuffer { + fn read_bytes(&mut self, data: &mut [u8]) -> Result<(), Error>; +} + +pub unsafe trait Serialize { + fn serialize(&self, target: &mut B) -> Result<(), Error>; +} + +pub trait Deserialize: Sized { + unsafe fn deserialize(source: &mut B) -> Result; +} + +pub struct SliceSerializeBuffer> { + data: T, +} + +impl> SliceSerializeBuffer { + pub fn new(data: T) -> Self { + Self { data } + } +} + +impl> SerializeBuffer for SliceSerializeBuffer { + fn write_bytes(&mut self, data: &[u8]) -> Result<(), Error> { + if data.len() > self.data.len() { + return Err(Error::InvalidArgument); + } + todo!() + } +} + +macro_rules! int_serde_impl { + ($ty:ty) => { + unsafe impl Serialize for $ty { + fn serialize(&self, target: &mut B) -> Result<(), Error> { + target.write_bytes(&self.to_ne_bytes()) + } + } + + impl Deserialize for $ty { + unsafe fn deserialize(source: &mut B) -> Result { + let mut bytes = [0; core::mem::size_of::()]; + source.read_bytes(&mut bytes)?; + Ok(Self::from_ne_bytes(bytes)) + } + } + }; +} + +int_serde_impl!(usize); +int_serde_impl!(u64); +int_serde_impl!(u32); +int_serde_impl!(u16); + +unsafe impl Serialize for u8 { + fn serialize(&self, target: &mut B) -> Result<(), Error> { + target.write_bytes(&[*self]) + } +} + +impl Deserialize for u8 { + unsafe fn deserialize(source: &mut B) -> Result { + let mut buffer = [0; 1]; + source.read_bytes(&mut buffer)?; + Ok(buffer[0]) + } +} + +unsafe impl Serialize for [T] { + fn serialize(&self, target: &mut B) -> Result<(), Error> { + self.len().serialize(target)?; + for item in self.iter() { + item.serialize(target)?; + } + Ok(()) + } +} + +unsafe impl Serialize for str { + fn serialize(&self, target: &mut B) -> Result<(), Error> { + self.as_bytes().serialize(target) + } +} + +unsafe impl Serialize for &T { + fn serialize(&self, target: &mut B) -> Result<(), Error> { + (*self).serialize(target) + } +}