dbus-launch 0.2.0

A D-Bus daemon launcher
Documentation
use libc::{self, c_int, c_void};
use std::io::{Error, Read, Result, Write};
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};

pub(crate) struct Pipe {
    fd: c_int,
}

impl Pipe {
    #[cfg(not(target_os = "macos"))]
    pub fn new() -> Result<(Pipe, Pipe)> {
        let mut fds = [0; 2];
        if unsafe { libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC) } == -1 {
            return Err(Error::last_os_error());
        }
        let r = unsafe { Pipe::from_raw_fd(fds[0]) };
        let w = unsafe { Pipe::from_raw_fd(fds[1]) };
        Ok((r, w))
    }

    #[cfg(target_os = "macos")]
    pub fn new() -> Result<(Pipe, Pipe)> {
        use crate::sys::set_close_on_exec;

        let mut fds = [0; 2];
        if unsafe { libc::pipe(fds.as_mut_ptr()) } == -1 {
            return Err(Error::last_os_error());
        }
        let r = unsafe { Pipe::from_raw_fd(fds[0]) };
        let w = unsafe { Pipe::from_raw_fd(fds[1]) };
        set_close_on_exec(r.as_raw_fd(), true)?;
        set_close_on_exec(w.as_raw_fd(), true)?;
        Ok((r, w))
    }
}

impl FromRawFd for Pipe {
    unsafe fn from_raw_fd(fd: RawFd) -> Pipe {
        Pipe { fd }
    }
}

impl IntoRawFd for Pipe {
    fn into_raw_fd(self) -> RawFd {
        let Pipe { fd } = self;
        fd
    }
}

impl AsRawFd for Pipe {
    fn as_raw_fd(&self) -> RawFd {
        self.fd
    }
}

impl Read for Pipe {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        let n =
            unsafe { libc::read(self.fd, buf.as_mut_ptr() as *mut c_void, buf.len()) };
        if n == -1 {
            Err(Error::last_os_error())
        } else {
            Ok(n as usize)
        }
    }
}

impl Write for Pipe {
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        let n = unsafe { libc::write(self.fd, buf.as_ptr() as *mut c_void, buf.len()) };
        if n == -1 {
            Err(Error::last_os_error())
        } else {
            Ok(n as usize)
        }
    }

    fn flush(&mut self) -> Result<()> {
        Ok(())
    }
}

impl Drop for Pipe {
    fn drop(&mut self) {
        unsafe { libc::close(self.fd) };
    }
}