corcovado/sys/unix/
mod.rs

1use libc::{self, c_int};
2
3#[macro_use]
4pub mod dlsym;
5
6#[cfg(any(
7    target_os = "android",
8    target_os = "illumos",
9    target_os = "linux",
10    target_os = "solaris"
11))]
12mod epoll;
13
14#[cfg(any(
15    target_os = "android",
16    target_os = "illumos",
17    target_os = "linux",
18    target_os = "solaris"
19))]
20pub use self::epoll::{Events, Selector};
21
22#[cfg(any(
23    target_os = "dragonfly",
24    target_os = "freebsd",
25    target_os = "ios",
26    target_os = "macos",
27    target_os = "netbsd",
28    target_os = "openbsd"
29))]
30mod kqueue;
31
32#[cfg(any(
33    target_os = "dragonfly",
34    target_os = "freebsd",
35    target_os = "ios",
36    target_os = "macos",
37    target_os = "netbsd",
38    target_os = "openbsd"
39))]
40pub use self::kqueue::{Events, Selector};
41
42mod awakener;
43mod eventedfd;
44mod io;
45mod ready;
46
47pub use self::awakener::Awakener;
48pub use self::eventedfd::EventedFd;
49// pub use self::io::{set_nonblock, Io};
50pub use self::io::Io;
51pub use self::ready::{UnixReady, READY_ALL};
52
53// pub use iovec::IoVec;
54
55use std::os::unix::io::FromRawFd;
56
57pub 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
86trait IsMinusOne {
87    fn is_minus_one(&self) -> bool;
88}
89
90impl IsMinusOne for i32 {
91    fn is_minus_one(&self) -> bool {
92        *self == -1
93    }
94}
95impl IsMinusOne for isize {
96    fn is_minus_one(&self) -> bool {
97        *self == -1
98    }
99}
100
101fn cvt<T: IsMinusOne>(t: T) -> ::io::Result<T> {
102    use std::io;
103
104    if t.is_minus_one() {
105        Err(io::Error::last_os_error())
106    } else {
107        Ok(t)
108    }
109}