mod file_desc_wrapper;
mod permissions;
mod pipe;
use crate::sys;
use crate::IntoInner;
use std::io::{Read, Result, Seek, SeekFrom, Write};
use std::process::Stdio;
pub use self::file_desc_wrapper::FileDescWrapper;
pub use self::permissions::Permissions;
pub use self::pipe::Pipe;
pub use crate::sys::io::getpid;
#[derive(Debug, PartialEq, Eq)]
pub struct FileDesc(sys::io::RawIo);
impl FileDesc {
#[cfg(unix)]
pub unsafe fn new(fd: ::std::os::unix::io::RawFd) -> Self {
Self::from_inner(sys::io::RawIo::new(fd))
}
#[cfg(windows)]
pub unsafe fn new(handle: ::std::os::windows::io::RawHandle) -> Self {
Self::from_inner(sys::io::RawIo::new(handle))
}
pub fn duplicate(&self) -> Result<Self> {
Ok(Self::from_inner(self.inner().duplicate()?))
}
#[cfg(unix)]
pub fn set_nonblock(&mut self, set: bool) -> Result<()> {
self.inner_mut().set_nonblock(set)
}
fn read(&self, buf: &mut [u8]) -> Result<usize> {
self.inner().read_inner(buf)
}
fn write(&self, buf: &[u8]) -> Result<usize> {
self.inner().write_inner(buf)
}
fn flush(&self) -> Result<()> {
self.inner().flush_inner()
}
fn seek(&self, pos: SeekFrom) -> Result<u64> {
self.inner().seek(pos)
}
}
impl IntoInner for FileDesc {
type Inner = sys::io::RawIo;
fn inner(&self) -> &Self::Inner {
&self.0
}
fn inner_mut(&mut self) -> &mut Self::Inner {
&mut self.0
}
fn into_inner(self) -> Self::Inner {
self.0
}
fn from_inner(inner: Self::Inner) -> Self {
FileDesc(inner)
}
}
impl Into<Stdio> for FileDesc {
fn into(self) -> Stdio {
self.into_inner().into()
}
}
impl Read for FileDesc {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
FileDesc::read(self, buf)
}
}
impl<'a> Read for &'a FileDesc {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
FileDesc::read(self, buf)
}
}
impl Write for FileDesc {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
FileDesc::write(self, buf)
}
fn flush(&mut self) -> Result<()> {
FileDesc::flush(self)
}
}
impl<'a> Write for &'a FileDesc {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
FileDesc::write(self, buf)
}
fn flush(&mut self) -> Result<()> {
FileDesc::flush(self)
}
}
impl Seek for FileDesc {
fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
FileDesc::seek(self, pos)
}
}
impl<'a> Seek for &'a FileDesc {
fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
FileDesc::seek(self, pos)
}
}
pub(crate) fn dup_stdio() -> Result<(FileDesc, FileDesc, FileDesc)> {
let (stdin, stdout, stderr) = sys::io::dup_stdio()?;
Ok((
FileDesc::from_inner(stdin),
FileDesc::from_inner(stdout),
FileDesc::from_inner(stderr),
))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn ensure_file_desc_is_send_and_sync() {
fn send_and_sync<T: Send + Sync>() {}
send_and_sync::<FileDesc>();
}
}