Fortune for comfork's current commit: Middle blessing − 中吉master
parent
e64abf4f06
commit
6020491a09
@ -0,0 +1,137 @@
|
|||||||
|
//! Wrapper around internal pipes fds.
|
||||||
|
//!
|
||||||
|
//! These pipe fds are valid across forks, and can be used for IPC between parent and non-exec()d child process forks.
|
||||||
|
use super::*;
|
||||||
|
use errno::Errno;
|
||||||
|
use std::{error, fmt};
|
||||||
|
|
||||||
|
/// Kind of pipe error
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub enum ErrorKind
|
||||||
|
{
|
||||||
|
/// Failed to create pipes
|
||||||
|
Create,
|
||||||
|
/// Unknown error
|
||||||
|
Unknown,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A raw unix pipe
|
||||||
|
pub type RawPipe = i32;
|
||||||
|
|
||||||
|
/// Create a raw pipe pair.
|
||||||
|
pub(crate) fn unix_pipe() -> Result<(i32, i32), Error>
|
||||||
|
{
|
||||||
|
use libc::pipe;
|
||||||
|
let mut pipe_fds: [libc::c_int; 2] = [-1;2];
|
||||||
|
if unsafe{pipe(pipe_fds.as_mut_ptr())} == 0 {
|
||||||
|
Ok((i32::from(pipe_fds[0]), i32::from(pipe_fds[1])))
|
||||||
|
} else {
|
||||||
|
Err(ErrorKind::Create.into_error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ErrorKind
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
Self::Create => write!(f, "failed to create raw pipes"),
|
||||||
|
_ => write!(f, "unknown error"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An error on a pipe operation
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Error(ErrorKind, Errno);
|
||||||
|
|
||||||
|
impl ErrorKind
|
||||||
|
{
|
||||||
|
/// Consume into `Error` using the last `errno` value, if it's not set then return `val`.
|
||||||
|
#[inline] pub(crate) fn try_into_error_or<T>(self, val: T) -> Result<T, Error>
|
||||||
|
{
|
||||||
|
Error::or_last(self, val)
|
||||||
|
}
|
||||||
|
/// Consume into `Error` using the last `errno` value, if it's not set then return the result of `fun`.
|
||||||
|
#[inline] pub(crate) fn try_into_error_or_with<F, T>(self, fun: F) -> Result<T, Error>
|
||||||
|
where F: FnOnce() -> T
|
||||||
|
{
|
||||||
|
Error::or_last_with(self, fun)
|
||||||
|
}
|
||||||
|
/// Consume into `Error` using the last `errno` value.
|
||||||
|
pub(crate) fn try_into_error(self) -> Result<(), Error>
|
||||||
|
{
|
||||||
|
Error::last(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Consume into an `Error` using the last `errno` value.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
/// If `errno` was success.
|
||||||
|
#[inline] pub(crate) fn into_error(self) -> Error
|
||||||
|
{
|
||||||
|
Self::try_into_error(self).expect_err("Expected an error to be set in errno")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error
|
||||||
|
{
|
||||||
|
/// Create a new error of this kind from the last set errno if it's not success.
|
||||||
|
/// If it is, return `val`.
|
||||||
|
#[inline] pub(crate) fn or_last<T>(err: ErrorKind, val: T) -> Result<T, Self>
|
||||||
|
{
|
||||||
|
Self::or_last_with(err, move || val)
|
||||||
|
}
|
||||||
|
/// Create a new error of this kind from the last set errno if it's not success.
|
||||||
|
/// If it is, return the result of `fun`.
|
||||||
|
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) {
|
||||||
|
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() {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The kind of pipe error
|
||||||
|
#[inline] pub fn kind(&self) -> &ErrorKind
|
||||||
|
{
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The errno value
|
||||||
|
#[inline] pub fn error(&self) -> &Errno
|
||||||
|
{
|
||||||
|
&self.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl error::Error for Error
|
||||||
|
{
|
||||||
|
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
||||||
|
Some(&self.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl fmt::Display for Error
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||||||
|
{
|
||||||
|
write!(f, "{}: {}", self.0, self.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in new issue