You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
1.6 KiB

//! ABstractions over `fork()`
use super::*;
use libc::{
fork,
setgid,
setuid,
};
use std::{fmt, error};
use std::io::{
self,
Read,
Write,
};
use std::marker::Unpin;
use errno::Errno;
/// Information on how to set-up child process.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ForkInfo
{
uid: Option<u32>,
gid: Option<u32>,
}
/// 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)
}
}