| use {io, sys, Evented, Ready, Poll, PollOpt, Token}; |
| use deprecated::TryAccept; |
| use io::MapNonBlock; |
| use std::io::{Read, Write}; |
| use std::path::Path; |
| pub use std::net::Shutdown; |
| use std::process; |
| |
| pub use sys::Io; |
| |
| #[derive(Debug)] |
| pub struct UnixSocket { |
| sys: sys::UnixSocket, |
| } |
| |
| impl UnixSocket { |
| /// Returns a new, unbound, non-blocking Unix domain socket |
| pub fn stream() -> io::Result<UnixSocket> { |
| sys::UnixSocket::stream() |
| .map(From::from) |
| } |
| |
| /// Connect the socket to the specified address |
| pub fn connect<P: AsRef<Path> + ?Sized>(self, addr: &P) -> io::Result<(UnixStream, bool)> { |
| let complete = match self.sys.connect(addr) { |
| Ok(()) => true, |
| Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => false, |
| Err(e) => return Err(e), |
| }; |
| Ok((From::from(self.sys), complete)) |
| } |
| |
| /// Bind the socket to the specified address |
| pub fn bind<P: AsRef<Path> + ?Sized>(&self, addr: &P) -> io::Result<()> { |
| self.sys.bind(addr) |
| } |
| |
| /// Listen for incoming requests |
| pub fn listen(self, backlog: usize) -> io::Result<UnixListener> { |
| self.sys.listen(backlog)?; |
| Ok(From::from(self.sys)) |
| } |
| |
| pub fn try_clone(&self) -> io::Result<UnixSocket> { |
| self.sys.try_clone() |
| .map(From::from) |
| } |
| } |
| |
| impl Evented for UnixSocket { |
| fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> { |
| self.sys.register(poll, token, interest, opts) |
| } |
| |
| fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> { |
| self.sys.reregister(poll, token, interest, opts) |
| } |
| |
| fn deregister(&self, poll: &Poll) -> io::Result<()> { |
| self.sys.deregister(poll) |
| } |
| } |
| |
| impl From<sys::UnixSocket> for UnixSocket { |
| fn from(sys: sys::UnixSocket) -> UnixSocket { |
| UnixSocket { sys: sys } |
| } |
| } |
| |
| /* |
| * |
| * ===== UnixStream ===== |
| * |
| */ |
| |
| #[derive(Debug)] |
| pub struct UnixStream { |
| sys: sys::UnixSocket, |
| } |
| |
| impl UnixStream { |
| pub fn connect<P: AsRef<Path> + ?Sized>(path: &P) -> io::Result<UnixStream> { |
| UnixSocket::stream() |
| .and_then(|sock| sock.connect(path)) |
| .map(|(sock, _)| sock) |
| } |
| |
| pub fn try_clone(&self) -> io::Result<UnixStream> { |
| self.sys.try_clone() |
| .map(From::from) |
| } |
| |
| pub fn shutdown(&self, how: Shutdown) -> io::Result<usize> { |
| self.sys.shutdown(how).map(|_| 0) |
| } |
| |
| pub fn read_recv_fd(&mut self, buf: &mut [u8]) -> io::Result<(usize, Option<RawFd>)> { |
| self.sys.read_recv_fd(buf) |
| } |
| |
| pub fn try_read_recv_fd(&mut self, buf: &mut [u8]) -> io::Result<Option<(usize, Option<RawFd>)>> { |
| self.read_recv_fd(buf).map_non_block() |
| } |
| |
| pub fn write_send_fd(&mut self, buf: &[u8], fd: RawFd) -> io::Result<usize> { |
| self.sys.write_send_fd(buf, fd) |
| } |
| |
| pub fn try_write_send_fd(&mut self, buf: &[u8], fd: RawFd) -> io::Result<Option<usize>> { |
| self.write_send_fd(buf, fd).map_non_block() |
| } |
| } |
| |
| impl Read for UnixStream { |
| fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
| self.sys.read(buf) |
| } |
| } |
| |
| impl Write for UnixStream { |
| fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
| self.sys.write(buf) |
| } |
| |
| fn flush(&mut self) -> io::Result<()> { |
| self.sys.flush() |
| } |
| } |
| |
| impl Evented for UnixStream { |
| fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> { |
| self.sys.register(poll, token, interest, opts) |
| } |
| |
| fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> { |
| self.sys.reregister(poll, token, interest, opts) |
| } |
| |
| fn deregister(&self, poll: &Poll) -> io::Result<()> { |
| self.sys.deregister(poll) |
| } |
| } |
| |
| impl From<sys::UnixSocket> for UnixStream { |
| fn from(sys: sys::UnixSocket) -> UnixStream { |
| UnixStream { sys: sys } |
| } |
| } |
| |
| /* |
| * |
| * ===== UnixListener ===== |
| * |
| */ |
| |
| #[derive(Debug)] |
| pub struct UnixListener { |
| sys: sys::UnixSocket, |
| } |
| |
| impl UnixListener { |
| pub fn bind<P: AsRef<Path> + ?Sized>(addr: &P) -> io::Result<UnixListener> { |
| UnixSocket::stream().and_then(|sock| { |
| sock.bind(addr)?; |
| sock.listen(256) |
| }) |
| } |
| |
| pub fn accept(&self) -> io::Result<UnixStream> { |
| self.sys.accept().map(From::from) |
| } |
| |
| pub fn try_clone(&self) -> io::Result<UnixListener> { |
| self.sys.try_clone().map(From::from) |
| } |
| } |
| |
| impl Evented for UnixListener { |
| fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> { |
| self.sys.register(poll, token, interest, opts) |
| } |
| |
| fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> { |
| self.sys.reregister(poll, token, interest, opts) |
| } |
| |
| fn deregister(&self, poll: &Poll) -> io::Result<()> { |
| self.sys.deregister(poll) |
| } |
| } |
| |
| impl TryAccept for UnixListener { |
| type Output = UnixStream; |
| |
| fn accept(&self) -> io::Result<Option<UnixStream>> { |
| UnixListener::accept(self).map_non_block() |
| } |
| } |
| |
| impl From<sys::UnixSocket> for UnixListener { |
| fn from(sys: sys::UnixSocket) -> UnixListener { |
| UnixListener { sys: sys } |
| } |
| } |
| |
| /* |
| * |
| * ===== Pipe ===== |
| * |
| */ |
| |
| pub fn pipe() -> io::Result<(PipeReader, PipeWriter)> { |
| let (rd, wr) = sys::pipe()?; |
| Ok((From::from(rd), From::from(wr))) |
| } |
| |
| #[derive(Debug)] |
| pub struct PipeReader { |
| io: Io, |
| } |
| |
| impl PipeReader { |
| pub fn from_stdout(stdout: process::ChildStdout) -> io::Result<Self> { |
| match sys::set_nonblock(stdout.as_raw_fd()) { |
| Err(e) => return Err(e), |
| _ => {}, |
| } |
| return Ok(PipeReader::from(unsafe { Io::from_raw_fd(stdout.into_raw_fd()) })); |
| } |
| pub fn from_stderr(stderr: process::ChildStderr) -> io::Result<Self> { |
| match sys::set_nonblock(stderr.as_raw_fd()) { |
| Err(e) => return Err(e), |
| _ => {}, |
| } |
| return Ok(PipeReader::from(unsafe { Io::from_raw_fd(stderr.into_raw_fd()) })); |
| } |
| } |
| |
| impl Read for PipeReader { |
| fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
| self.io.read(buf) |
| } |
| } |
| |
| impl<'a> Read for &'a PipeReader { |
| fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
| (&self.io).read(buf) |
| } |
| } |
| |
| impl Evented for PipeReader { |
| fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> { |
| self.io.register(poll, token, interest, opts) |
| } |
| |
| fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> { |
| self.io.reregister(poll, token, interest, opts) |
| } |
| |
| fn deregister(&self, poll: &Poll) -> io::Result<()> { |
| self.io.deregister(poll) |
| } |
| } |
| |
| impl From<Io> for PipeReader { |
| fn from(io: Io) -> PipeReader { |
| PipeReader { io: io } |
| } |
| } |
| |
| #[derive(Debug)] |
| pub struct PipeWriter { |
| io: Io, |
| } |
| |
| impl PipeWriter { |
| pub fn from_stdin(stdin: process::ChildStdin) -> io::Result<Self> { |
| match sys::set_nonblock(stdin.as_raw_fd()) { |
| Err(e) => return Err(e), |
| _ => {}, |
| } |
| return Ok(PipeWriter::from(unsafe { Io::from_raw_fd(stdin.into_raw_fd()) })); |
| } |
| } |
| |
| impl Write for PipeWriter { |
| fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
| self.io.write(buf) |
| } |
| |
| fn flush(&mut self) -> io::Result<()> { |
| self.io.flush() |
| } |
| } |
| |
| impl<'a> Write for &'a PipeWriter { |
| fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
| (&self.io).write(buf) |
| } |
| |
| fn flush(&mut self) -> io::Result<()> { |
| (&self.io).flush() |
| } |
| } |
| |
| impl Evented for PipeWriter { |
| fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> { |
| self.io.register(poll, token, interest, opts) |
| } |
| |
| fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> { |
| self.io.reregister(poll, token, interest, opts) |
| } |
| |
| fn deregister(&self, poll: &Poll) -> io::Result<()> { |
| self.io.deregister(poll) |
| } |
| } |
| |
| impl From<Io> for PipeWriter { |
| fn from(io: Io) -> PipeWriter { |
| PipeWriter { io: io } |
| } |
| } |
| |
| /* |
| * |
| * ===== Conversions ===== |
| * |
| */ |
| |
| use std::os::unix::io::{RawFd, IntoRawFd, AsRawFd, FromRawFd}; |
| |
| impl IntoRawFd for UnixSocket { |
| fn into_raw_fd(self) -> RawFd { |
| self.sys.into_raw_fd() |
| } |
| } |
| |
| impl AsRawFd for UnixSocket { |
| fn as_raw_fd(&self) -> RawFd { |
| self.sys.as_raw_fd() |
| } |
| } |
| |
| impl FromRawFd for UnixSocket { |
| unsafe fn from_raw_fd(fd: RawFd) -> UnixSocket { |
| UnixSocket { sys: FromRawFd::from_raw_fd(fd) } |
| } |
| } |
| |
| impl IntoRawFd for UnixStream { |
| fn into_raw_fd(self) -> RawFd { |
| self.sys.into_raw_fd() |
| } |
| } |
| |
| impl AsRawFd for UnixStream { |
| fn as_raw_fd(&self) -> RawFd { |
| self.sys.as_raw_fd() |
| } |
| } |
| |
| impl FromRawFd for UnixStream { |
| unsafe fn from_raw_fd(fd: RawFd) -> UnixStream { |
| UnixStream { sys: FromRawFd::from_raw_fd(fd) } |
| } |
| } |
| |
| impl IntoRawFd for UnixListener { |
| fn into_raw_fd(self) -> RawFd { |
| self.sys.into_raw_fd() |
| } |
| } |
| |
| impl AsRawFd for UnixListener { |
| fn as_raw_fd(&self) -> RawFd { |
| self.sys.as_raw_fd() |
| } |
| } |
| |
| impl FromRawFd for UnixListener { |
| unsafe fn from_raw_fd(fd: RawFd) -> UnixListener { |
| UnixListener { sys: FromRawFd::from_raw_fd(fd) } |
| } |
| } |
| |
| impl IntoRawFd for PipeReader { |
| fn into_raw_fd(self) -> RawFd { |
| self.io.into_raw_fd() |
| } |
| } |
| |
| impl AsRawFd for PipeReader { |
| fn as_raw_fd(&self) -> RawFd { |
| self.io.as_raw_fd() |
| } |
| } |
| |
| impl FromRawFd for PipeReader { |
| unsafe fn from_raw_fd(fd: RawFd) -> PipeReader { |
| PipeReader { io: FromRawFd::from_raw_fd(fd) } |
| } |
| } |
| |
| impl IntoRawFd for PipeWriter { |
| fn into_raw_fd(self) -> RawFd { |
| self.io.into_raw_fd() |
| } |
| } |
| |
| impl AsRawFd for PipeWriter { |
| fn as_raw_fd(&self) -> RawFd { |
| self.io.as_raw_fd() |
| } |
| } |
| |
| impl FromRawFd for PipeWriter { |
| unsafe fn from_raw_fd(fd: RawFd) -> PipeWriter { |
| PipeWriter { io: FromRawFd::from_raw_fd(fd) } |
| } |
| } |