`sys/pipe`: Started syncronous `Pipe` wrapper, with `WriteHalf` and `ReadHalf`.

Fortune for comfork's current commit: Half blessing − 半吉
master
Avril 3 years ago
parent 6020491a09
commit c78e3d9fa0

@ -4,6 +4,7 @@
use super::*; use super::*;
use errno::Errno; use errno::Errno;
use std::{error, fmt}; use std::{error, fmt};
use std::ops::Drop;
/// Kind of pipe error /// Kind of pipe error
#[derive(Debug)] #[derive(Debug)]
@ -31,6 +32,97 @@ pub(crate) fn unix_pipe() -> Result<(i32, i32), Error>
} }
} }
/// A writer for a bi-directinoal unix pipe
///
/// Created by splitting `Pipe`, data written to this is available to be read from its `ReadHalf` counterpart.
#[derive(Debug, PartialEq, Eq)]
pub struct WriteHalf(i32);
/// A reader for a bi-directional unix pipe.
///
/// Created by splitting `Pipe`, data read from this is data that was sent to its `WriteHalf` counterpart.
#[derive(Debug, PartialEq, Eq)]
pub struct ReadHalf(i32);
/// A bi-drectional unix pipe
///
/// Data written to the pipe is available to be read from it (unless the pipe is mismatched.)
#[derive(Debug, PartialEq, Eq)]
pub struct Pipe
{
tx: i32,
rx: i32,
}
impl Pipe
{
/// Split this pipe into a read and write half.
///
/// Data written to the `WriteHalf` is sent to the `ReadHalf` (unless the pipe is mismatched.)
#[inline] pub fn split(self) -> (WriteHalf, ReadHalf)
{
(WriteHalf(self.tx), ReadHalf(self.rx))
}
/// Create a `Pipe` from two halves.
///
/// # Mismatched halves
/// The halves do not need to have originated from the same `Pipe`.
/// If they are not, then writing to the `Pipe` will send the data to its original receiver, and reading from it will take the data from its original sender.
#[inline] pub fn unsplit(tx: WriteHalf, rx: ReadHalf) -> Self
{
Self::new_from_raw((tx.0, rx.0))
}
/// Create a new `Pipe` from a pair of raw file descriptors.
///
/// # Safety
/// Does not check that the integers provided are valid and open file descriptors.
#[inline(always)] fn new_from_raw((tx, rx): (i32, i32)) -> Self
{
Self{tx,rx}
}
/// Create a new `Pipe` from a pair of raw file descriptors.
///
/// # Safety
/// The caller must check that `tx` and `rx` are valid, open file descriptors
// TODO: When writing the async version make sure to state that the fds need to be non-blocking.
/// Does not check that the integers provided are valid and open file descriptors.
#[inline] pub unsafe fn from_raw(tx: i32, rx: i32) -> Self
{
Self::new_from_raw((tx, rx))
}
}
//TODO: Impl io::Read +/ io::Write for the types above
impl Drop for ReadHalf
{
fn drop(&mut self) {
unsafe {
libc::close(self.0);
}
}
}
impl Drop for WriteHalf
{
fn drop(&mut self) {
unsafe {
libc::close(self.0);
}
}
}
impl Drop for Pipe
{
fn drop(&mut self) {
unsafe {
libc::close(self.tx);
libc::close(self.rx);
}
}
}
impl fmt::Display for ErrorKind impl fmt::Display for ErrorKind
{ {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
@ -55,7 +147,7 @@ impl ErrorKind
} }
/// Consume into `Error` using the last `errno` value, if it's not set then return the result of `fun`. /// 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> #[inline] pub(crate) fn try_into_error_or_with<F, T>(self, fun: F) -> Result<T, Error>
where F: FnOnce() -> T where F: FnOnce() -> T
{ {
Error::or_last_with(self, fun) Error::or_last_with(self, fun)
} }

Loading…
Cancel
Save