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