1 use libc::{self, c_int};
2
3 #[macro_use]
4 pub mod dlsym;
5
6 #[cfg(any(
7 target_os = "android",
8 target_os = "illumos",
9 target_os = "linux",
10 target_os = "solaris"
11 ))]
12 mod epoll;
13
14 #[cfg(any(
15 target_os = "android",
16 target_os = "illumos",
17 target_os = "linux",
18 target_os = "solaris"
19 ))]
20 pub use self::epoll::{Events, Selector};
21
22 #[cfg(any(target_os = "bitrig", target_os = "dragonfly",
23 target_os = "freebsd", target_os = "ios", target_os = "macos",
24 target_os = "netbsd", target_os = "openbsd"))]
25 mod kqueue;
26
27 #[cfg(any(target_os = "bitrig", target_os = "dragonfly",
28 target_os = "freebsd", target_os = "ios", target_os = "macos",
29 target_os = "netbsd", target_os = "openbsd"))]
30 pub use self::kqueue::{Events, Selector};
31
32 mod awakener;
33 mod eventedfd;
34 mod io;
35 mod ready;
36 mod tcp;
37 mod udp;
38 mod uio;
39
40 #[cfg(feature = "with-deprecated")]
41 mod uds;
42
43 pub use self::awakener::Awakener;
44 pub use self::eventedfd::EventedFd;
45 pub use self::io::{Io, set_nonblock};
46 pub use self::ready::{UnixReady, READY_ALL};
47 pub use self::tcp::{TcpStream, TcpListener};
48 pub use self::udp::UdpSocket;
49
50 #[cfg(feature = "with-deprecated")]
51 pub use self::uds::UnixSocket;
52
53 pub use iovec::IoVec;
54
55 use std::os::unix::io::FromRawFd;
56
pipe() -> ::io::Result<(Io, Io)>57 pub fn pipe() -> ::io::Result<(Io, Io)> {
58 // Use pipe2 for atomically setting O_CLOEXEC if we can, but otherwise
59 // just fall back to using `pipe`.
60 dlsym!(fn pipe2(*mut c_int, c_int) -> c_int);
61
62 let mut pipes = [0; 2];
63 unsafe {
64 match pipe2.get() {
65 Some(pipe2_fn) => {
66 let flags = libc::O_NONBLOCK | libc::O_CLOEXEC;
67 cvt(pipe2_fn(pipes.as_mut_ptr(), flags))?;
68 Ok((Io::from_raw_fd(pipes[0]), Io::from_raw_fd(pipes[1])))
69 }
70 None => {
71 cvt(libc::pipe(pipes.as_mut_ptr()))?;
72 // Ensure the pipe are closed if any of the system calls below
73 // fail.
74 let r = Io::from_raw_fd(pipes[0]);
75 let w = Io::from_raw_fd(pipes[1]);
76 cvt(libc::fcntl(pipes[0], libc::F_SETFD, libc::FD_CLOEXEC))?;
77 cvt(libc::fcntl(pipes[1], libc::F_SETFD, libc::FD_CLOEXEC))?;
78 cvt(libc::fcntl(pipes[0], libc::F_SETFL, libc::O_NONBLOCK))?;
79 cvt(libc::fcntl(pipes[1], libc::F_SETFL, libc::O_NONBLOCK))?;
80 Ok((r, w))
81 }
82 }
83 }
84 }
85
86 trait IsMinusOne {
is_minus_one(&self) -> bool87 fn is_minus_one(&self) -> bool;
88 }
89
90 impl IsMinusOne for i32 {
is_minus_one(&self) -> bool91 fn is_minus_one(&self) -> bool { *self == -1 }
92 }
93 impl IsMinusOne for isize {
is_minus_one(&self) -> bool94 fn is_minus_one(&self) -> bool { *self == -1 }
95 }
96
cvt<T: IsMinusOne>(t: T) -> ::io::Result<T>97 fn cvt<T: IsMinusOne>(t: T) -> ::io::Result<T> {
98 use std::io;
99
100 if t.is_minus_one() {
101 Err(io::Error::last_os_error())
102 } else {
103 Ok(t)
104 }
105 }
106