Started `sys/fork` module: Safe Rust wrappers around forking. Sets up message passing and error reporting/value returning from the child to the parent (TODO).

Boxed sys `Error` types.

Fortune for comfork's current commit: Small blessing − 小吉
master
Avril 3 years ago
parent 76fe936970
commit 20d29a5613
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -56,3 +56,8 @@ fn _debug_if_test()
};
}
}
/// 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>()];);
}

@ -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<pipe::Error> 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)
}
}

@ -4,3 +4,4 @@ use super::*;
pub mod errno;
pub mod pipe;
pub mod fork;

@ -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<F, T>(err: ErrorKind, fun: F) -> Result<T, Self>
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)
}
}

Loading…
Cancel
Save