Clean up the pipe-hup test slightly

This commit is contained in:
Alex Crichton
2016-12-08 16:30:18 -08:00
parent 5bab8e85b9
commit f036691681
2 changed files with 33 additions and 64 deletions
+1 -1
View File
@@ -20,4 +20,4 @@ slab = "0.3"
[dev-dependencies]
env_logger = { version = "0.3", default-features = false }
nix = "0.7"
libc = "0.2"
+32 -63
View File
@@ -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<usize> {
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<T> {
io: PollEvented<RawFdWrap<T>>,
}
impl<T> io::Read for StdStream<T> where T: io::Read {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.io.read(buf)
}
}
struct RawFdWrap<T>(T);
impl<T> RawFdWrap<T> {
fn new(fd: T) -> io::Result<Self>
where T: AsRawFd {
try!(set_nonblock(&fd));
Ok(RawFdWrap(fd))
}
}
impl<T> io::Read for RawFdWrap<T> where T: io::Read {
impl io::Read for MyFile {
fn read(&mut self, bytes: &mut [u8]) -> io::Result<usize> {
self.0.read(bytes)
}
}
impl<T> Evented for RawFdWrap<T> 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<T> Evented for RawFdWrap<T> 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();
}
}