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
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)
|
|
}
|
|
}
|