diff --git a/src/ext/macros.rs b/src/ext/macros.rs index f9081e1..66770c6 100644 --- a/src/ext/macros.rs +++ b/src/ext/macros.rs @@ -52,7 +52,12 @@ fn _debug_if_test() ($($tt:tt)*) => { const _:() = { $($tt)* - () + () }; } } + +/// Show a compiler error message telling you the size in bytes of a type. +#[macro_export] macro_rules! show_size_of { + ($t:ty) => (const _: [(); 0] = [(); ::core::mem::size_of::<$t>()];); +} diff --git a/src/sys/fork.rs b/src/sys/fork.rs new file mode 100644 index 0000000..2c64c49 --- /dev/null +++ b/src/sys/fork.rs @@ -0,0 +1,71 @@ +//! ABstractions over `fork()` +use super::*; + +use libc::{ + fork, + setgid, + setuid, +}; +use std::{fmt, error}; + +use errno::Errno; + +/// THe kind of error from forking +#[derive(Debug)] +#[non_exhaustive] +pub enum ErrorKind +{ + Unknown, + + Fork, + SetUid, + SetGid, + + Return(&'static str), + + // For temporary pipe that sends / recvs status of child's setup and returned object if any. + Pipe(pipe::ErrorKind), +} + +/// An error in either forking or communicating with the child process during its setup. +#[derive(Debug)] +#[repr(transparent)] +pub struct Error(Box<(ErrorKind, Errno)>); + +impl From for Error +{ + fn from(from: pipe::Error) -> Self + { + let (k, n) = *from.0; + Self(Box::new((ErrorKind::Pipe(k), n))) + } +} + +impl fmt::Display for ErrorKind +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + match self { + Self::SetUid => write!(f, "child `setuid()` failed"), + Self::SetGid => write!(f, "child `setgid()` failed"), + Self::Return(tynm) => write!(f, "failed to read from child its return value of type ({})", tynm), + Self::Fork => write!(f, "fork() failed"), + + _ => write!(f, "unknown"), + } + } +} + +impl error::Error for Error +{ + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + Some(&self.0.1) + } +} +impl fmt::Display for Error +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + write!(f, "{}: {}", self.0.1, self.0.1) + } +} diff --git a/src/sys/mod.rs b/src/sys/mod.rs index 7b2d59a..1d0a6d2 100644 --- a/src/sys/mod.rs +++ b/src/sys/mod.rs @@ -4,3 +4,4 @@ use super::*; pub mod errno; pub mod pipe; +pub mod fork; diff --git a/src/sys/pipe.rs b/src/sys/pipe.rs index 6bd40b5..c9d3571 100644 --- a/src/sys/pipe.rs +++ b/src/sys/pipe.rs @@ -272,7 +272,7 @@ impl fmt::Display for ErrorKind /// An error on a pipe operation #[derive(Debug)] -pub struct Error(ErrorKind, Errno); +pub struct Error(pub(super) Box<(ErrorKind, Errno)>); impl ErrorKind { @@ -316,50 +316,50 @@ impl Error pub(crate) fn or_last_with(err: ErrorKind, fun: F) -> Result where F: FnOnce() -> T { - Err(Self(err, match Errno::or_last_with(fun) { + Err(Self(Box::new((err, match Errno::or_last_with(fun) { Ok(v) => return Ok(v), Err(e) => e, - })) + })))) } /// Create a new error of this kind from the last set errno (if it's not success.) pub(crate) fn last(err: ErrorKind) -> Result<(), Self> { - Err(Self(err, match Errno::last() { + Err(Self(Box::new((err, match Errno::last() { Ok(()) => return Ok(()), Err(e) => e, - })) + })))) } /// Create a new error of this kind with this errno value #[inline] pub fn new(kind: ErrorKind, err: Errno) -> Self { - Self(kind, err) + Self(Box::new((kind, err))) } /// The kind of pipe error #[inline] pub fn kind(&self) -> &ErrorKind { - &self.0 + &self.0.0 } /// The errno value #[inline] pub fn error(&self) -> &Errno { - &self.1 + &self.0.1 } } impl error::Error for Error { fn source(&self) -> Option<&(dyn error::Error + 'static)> { - Some(&self.1) + Some(&self.0.1) } } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}: {}", self.0, self.1) + write!(f, "{}: {}", self.0.0, self.0.1) } }