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.
106 lines
2.3 KiB
106 lines
2.3 KiB
//! `pipe()` related operations
|
|
|
|
use super::*;
|
|
use errno::Errno;
|
|
use std::{
|
|
fmt,
|
|
};
|
|
|
|
/// Represents an error on `pipe()` related operations
|
|
#[derive(Debug)]
|
|
pub enum Error {
|
|
|
|
Create,
|
|
Read,
|
|
Write,
|
|
Broken,
|
|
|
|
Unknown,
|
|
}
|
|
impl std::error::Error for Error{}
|
|
impl std::fmt::Display for Error
|
|
{
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
|
{
|
|
match self {
|
|
Self::Create => write!(f, "failed to create pipe"),
|
|
Self::Read => write!(f, "failed to read from pipe"),
|
|
Self::Write => write!(f, "failed to write to pipe"),
|
|
Self::Broken => write!(f, "broken pipe"),
|
|
_ => write!(f, "unknown error"),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Create with `pipe()`
|
|
pub(super) fn unix_pipe() -> Result<(i32,i32), Errno<Error>>
|
|
{
|
|
use libc::{
|
|
pipe,
|
|
};
|
|
let mut pipe_fd: [libc::c_int; 2] = [0;2];
|
|
if unsafe{pipe(&mut pipe_fd[0] as *mut libc::c_int)} == 0{
|
|
Ok((pipe_fd[0], pipe_fd[1]))
|
|
} else {
|
|
Err(Error::Create.into())
|
|
}
|
|
}
|
|
|
|
/// Write to a pipe
|
|
pub(super) fn pipe_write(output: i32, buf: impl AsRef<[u8]>) -> Result<usize, Errno<Error>>
|
|
{
|
|
let buf = buf.as_ref();
|
|
let len = buf.len();
|
|
|
|
let read = unsafe{libc::write(output, &buf[0] as *const u8 as *const libc::c_void, len)};
|
|
|
|
if read < 0 {
|
|
Err(Error::Write.into())
|
|
} else {
|
|
Ok(read as usize)
|
|
}
|
|
}
|
|
|
|
|
|
pub(super) fn pipe_read(input: i32, mut buf: impl AsMut<[u8]>) -> Result<usize, Errno<Error>>
|
|
{
|
|
let buf = buf.as_mut();
|
|
let len = buf.len();
|
|
|
|
let read = unsafe{libc::read(input, &mut buf[0] as *mut u8 as *mut libc::c_void, len)};
|
|
|
|
if read < 0 {
|
|
Err(Error::Read.into())
|
|
} else {
|
|
Ok(read as usize)
|
|
}
|
|
}
|
|
|
|
pub(super) unsafe fn pipe_write_value<T: ?Sized>(fd: i32, value: &T) -> Result<(), Errno<Error>>
|
|
{
|
|
let sz = std::mem::size_of_val(value);
|
|
|
|
let write = pipe_write(fd, std::slice::from_raw_parts(value as *const T as *const u8, sz))?;
|
|
if write == sz {
|
|
Ok(())
|
|
} else {
|
|
Err(Error::Broken.into())
|
|
}
|
|
}
|
|
|
|
pub(super) unsafe fn pipe_read_value<T>(fd: i32) -> Result<T, Errno<Error>>
|
|
{
|
|
use malloc_array::heap;
|
|
|
|
let mut buf = heap![unsafe 0u8; std::mem::size_of::<T>()];
|
|
|
|
let read = pipe_read(fd, &mut buf)?;
|
|
|
|
if read == buf.len() {
|
|
let ptr = buf.reinterpret::<T>();
|
|
Ok(ptr.as_ptr().read())
|
|
} else {
|
|
Err(Error::Broken.into())
|
|
}
|
|
}
|