diff --git a/Cargo.toml b/Cargo.toml index a02abe807..31b5001fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,4 +20,4 @@ slab = "0.3" [dev-dependencies] env_logger = { version = "0.3", default-features = false } -nix = "0.7" +libc = "0.2" diff --git a/tests/pipe-hup.rs b/tests/pipe-hup.rs index acb1af5d7..9fae3e760 100644 --- a/tests/pipe-hup.rs +++ b/tests/pipe-hup.rs @@ -2,20 +2,18 @@ extern crate env_logger; extern crate futures; -extern crate nix; +extern crate libc; extern crate mio; extern crate tokio_core; -use std::io; -use std::os::unix::io::{AsRawFd, RawFd}; -use std::time::Duration; +use std::fs::File; +use std::io::{self, Write}; +use std::os::unix::io::{AsRawFd, FromRawFd}; use std::thread; +use std::time::Duration; use mio::{Evented, PollOpt, Ready, Token}; use mio::unix::EventedFd; -use nix::fcntl::{fcntl, O_NONBLOCK}; -use nix::fcntl::FcntlArg::F_SETFL; -use nix::unistd::{close, pipe, read, write}; use tokio_core::io::read_to_end; use tokio_core::reactor::{Core, PollEvented}; @@ -27,51 +25,25 @@ macro_rules! t { }) } -fn set_nonblock(s: &AsRawFd) -> io::Result<()> { - fcntl(s.as_raw_fd(), F_SETFL(O_NONBLOCK)).map_err(from_nix_error) - .map(|_| ()) -} +struct MyFile(File); -fn from_nix_error(err: nix::Error) -> io::Error { - io::Error::from_raw_os_error(err.errno() as i32) -} - -struct PipeSource(RawFd); - -impl io::Read for PipeSource { - fn read(&mut self, bytes: &mut [u8]) -> io::Result { - read(self.as_raw_fd(), bytes).map_err(from_nix_error) +impl MyFile { + fn new(file: File) -> MyFile { + unsafe { + let r = libc::fcntl(file.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK); + assert!(r != -1, "fcntl error: {}", io::Error::last_os_error()); + } + MyFile(file) } } -pub struct StdStream { - io: PollEvented>, -} - -impl io::Read for StdStream where T: io::Read { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.io.read(buf) - } -} - -struct RawFdWrap(T); - -impl RawFdWrap { - fn new(fd: T) -> io::Result - where T: AsRawFd { - - try!(set_nonblock(&fd)); - Ok(RawFdWrap(fd)) - } -} - -impl io::Read for RawFdWrap where T: io::Read { +impl io::Read for MyFile { fn read(&mut self, bytes: &mut [u8]) -> io::Result { self.0.read(bytes) } } -impl Evented for RawFdWrap where T: AsRawFd { +impl Evented for MyFile { fn register(&self, poll: &mio::Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> { EventedFd(&self.0.as_raw_fd()).register(poll, token, interest | Ready::hup(), opts) @@ -85,31 +57,28 @@ impl Evented for RawFdWrap where T: AsRawFd { } } -impl AsRawFd for PipeSource { - fn as_raw_fd(&self) -> RawFd { - self.0 - } -} - #[test] fn hup() { drop(env_logger::init()); let mut l = t!(Core::new()); - let (source, sink) = pipe().unwrap(); - let t = thread::spawn(move || { - write(sink, b"Hello!\n").unwrap(); - write(sink, b"Good bye!\n").unwrap(); - thread::sleep(Duration::from_millis(100)); - close(sink).unwrap(); - }); + unsafe { + let mut pipes = [0; 2]; + assert!(libc::pipe(pipes.as_mut_ptr()) != -1, + "pipe error: {}", io::Error::last_os_error()); + let read = File::from_raw_fd(pipes[0]); + let mut write = File::from_raw_fd(pipes[1]); + let t = thread::spawn(move || { + write.write_all(b"Hello!\n").unwrap(); + write.write_all(b"Good bye!\n").unwrap(); + thread::sleep(Duration::from_millis(100)); + }); - let source = StdStream { - io: PollEvented::new(RawFdWrap::new(PipeSource(source)).unwrap(), &l.handle()).unwrap() - }; + let source = PollEvented::new(MyFile::new(read), &l.handle()).unwrap(); - let reader = read_to_end(source, Vec::new()); - let (_, content) = t!(l.run(reader)); - assert_eq!(&b"Hello!\nGood bye!\n"[..], &content[..]); - t.join().unwrap(); + let reader = read_to_end(source, Vec::new()); + let (_, content) = t!(l.run(reader)); + assert_eq!(&b"Hello!\nGood bye!\n"[..], &content[..]); + t.join().unwrap(); + } }