summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2017-07-30 15:51:29 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2017-07-30 15:51:29 +0000
commitf8768e93d8a8961b700b375d47fa3fe1ff2a346a (patch)
tree66683a388111db0d38947fe1dd6621313daf29ab
parent318441d9d9ecde4a976a5d9ae2c9172e7da7d9ce (diff)
parente19ffab8b1615f6cc617f0972317e0131ec8d62d (diff)
downloadnix-f8768e93d8a8961b700b375d47fa3fe1ff2a346a.zip
Merge #672
672: add poll module in Android r=Susurrus `poll` functions are defined in Android as well. libc is missing some constant, but once rust-lang/libc#663 is merged, it'll be good to merge here. Closes #711
-rw-r--r--CHANGELOG.md4
-rw-r--r--src/lib.rs1
-rw-r--r--src/poll.rs82
-rw-r--r--test/test.rs1
4 files changed, 82 insertions, 6 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d5064c9c..688b0dcc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -34,6 +34,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- On Linux and Android, added support for receiving `PTRACE_O_TRACESYSGOOD`
events from `wait` and `waitpid` using `WaitStatus::PtraceSyscall`
([#566](https://github.com/nix-rust/nix/pull/566)).
+- Added `nix::poll` module for all platforms
+ ([#672](https://github.com/nix-rust/nix/pull/672))
+- Added `nix::ppoll` function for FreeBSD and DragonFly
+ ([#672](https://github.com/nix-rust/nix/pull/672))
### Changed
- The `ioctl!` macro and its variants now allow the generated functions to have
diff --git a/src/lib.rs b/src/lib.rs
index 3518efac..cadc7fb4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -39,7 +39,6 @@ pub mod mqueue;
pub mod pty;
-#[cfg(any(target_os = "linux", target_os = "macos"))]
pub mod poll;
pub mod net;
diff --git a/src/poll.rs b/src/poll.rs
index afc5bd9c..60c31ace 100644
--- a/src/poll.rs
+++ b/src/poll.rs
@@ -1,11 +1,20 @@
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
use sys::time::TimeSpec;
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
use sys::signal::SigSet;
+use std::os::unix::io::RawFd;
use libc;
use {Errno, Result};
+/// This is a wrapper around `libc::pollfd`.
+///
+/// It's meant to be used as an argument to the [`poll`](fn.poll.html) and
+/// [`ppoll`](fn.ppoll.html) functions to specify the events of interest
+/// for a specific file descriptor.
+///
+/// After a call to `poll` or `ppoll`, the events that occured can be
+/// retrieved by calling [`revents()`](#method.revents) on the `PollFd`.
#[repr(C)]
#[derive(Clone, Copy)]
pub struct PollFd {
@@ -13,7 +22,9 @@ pub struct PollFd {
}
impl PollFd {
- pub fn new(fd: libc::c_int, events: EventFlags) -> PollFd {
+ /// Creates a new `PollFd` specifying the events of interest
+ /// for a given file descriptor.
+ pub fn new(fd: RawFd, events: EventFlags) -> PollFd {
PollFd {
pollfd: libc::pollfd {
fd: fd,
@@ -23,26 +34,82 @@ impl PollFd {
}
}
+ /// Returns the events that occured in the last call to `poll` or `ppoll`.
pub fn revents(&self) -> Option<EventFlags> {
EventFlags::from_bits(self.pollfd.revents)
}
}
libc_bitflags! {
+ /// These flags define the different events that can be monitored by `poll` and `ppoll`
pub flags EventFlags: libc::c_short {
+ /// There is data to read.
POLLIN,
+ /// There is some exceptional condition on the file descriptor.
+ ///
+ /// Possibilities include:
+ ///
+ /// * There is out-of-band data on a TCP socket (see
+ /// [tcp(7)](http://man7.org/linux/man-pages/man7/tcp.7.html)).
+ /// * A pseudoterminal master in packet mode has seen a state
+ /// change on the slave (see
+ /// [ioctl_tty(2)](http://man7.org/linux/man-pages/man2/ioctl_tty.2.html)).
+ /// * A cgroup.events file has been modified (see
+ /// [cgroups(7)](http://man7.org/linux/man-pages/man7/cgroups.7.html)).
POLLPRI,
+ /// Writing is now possible, though a write larger that the
+ /// available space in a socket or pipe will still block (unless
+ /// `O_NONBLOCK` is set).
POLLOUT,
+ /// Equivalent to [`POLLIN`](constant.POLLIN.html)
POLLRDNORM,
+ /// Equivalent to [`POLLOUT`](constant.POLLOUT.html)
POLLWRNORM,
+ /// Priority band data can be read (generally unused on Linux).
POLLRDBAND,
+ /// Priority data may be written.
POLLWRBAND,
+ /// Error condition (only returned in
+ /// [`PollFd::revents`](struct.PollFd.html#method.revents);
+ /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
+ /// This bit is also set for a file descriptor referring to the
+ /// write end of a pipe when the read end has been closed.
POLLERR,
+ /// Hang up (only returned in [`PollFd::revents`](struct.PollFd.html#method.revents);
+ /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
+ /// Note that when reading from a channel such as a pipe or a stream
+ /// socket, this event merely indicates that the peer closed its
+ /// end of the channel. Subsequent reads from the channel will
+ /// return 0 (end of file) only after all outstanding data in the
+ /// channel has been consumed.
POLLHUP,
+ /// Invalid request: `fd` not open (only returned in
+ /// [`PollFd::revents`](struct.PollFd.html#method.revents);
+ /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
POLLNVAL,
}
}
+/// `poll` waits for one of a set of file descriptors to become ready to perform I/O.
+/// ([`poll(2)`](http://man7.org/linux/man-pages/man2/poll.2.html))
+///
+/// `fds` contains all [`PollFd`](struct.PollFd.html) to poll.
+/// The function will return as soon as any event occur for any of these `PollFd`s.
+///
+/// The `timeout` argument specifies the number of milliseconds that `poll()`
+/// should block waiting for a file descriptor to become ready. The call
+/// will block until either:
+///
+/// * a file descriptor becomes ready;
+/// * the call is interrupted by a signal handler; or
+/// * the timeout expires.
+///
+/// Note that the timeout interval will be rounded up to the system clock
+/// granularity, and kernel scheduling delays mean that the blocking
+/// interval may overrun by a small amount. Specifying a negative value
+/// in timeout means an infinite timeout. Specifying a timeout of zero
+/// causes `poll()` to return immediately, even if no file descriptors are
+/// ready.
pub fn poll(fds: &mut [PollFd], timeout: libc::c_int) -> Result<libc::c_int> {
let res = unsafe {
libc::poll(fds.as_mut_ptr() as *mut libc::pollfd,
@@ -53,7 +120,14 @@ pub fn poll(fds: &mut [PollFd], timeout: libc::c_int) -> Result<libc::c_int> {
Errno::result(res)
}
-#[cfg(any(target_os = "linux", target_os = "android"))]
+/// `ppoll()` allows an application to safely wait until either a file
+/// descriptor becomes ready or until a signal is caught.
+/// ([`poll(2)`](http://man7.org/linux/man-pages/man2/poll.2.html))
+///
+/// `ppoll` behaves like `poll`, but let you specify what signals may interrupt it
+/// with the `sigmask` argument.
+///
+#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
pub fn ppoll(fds: &mut [PollFd], timeout: TimeSpec, sigmask: SigSet) -> Result<libc::c_int> {
diff --git a/test/test.rs b/test/test.rs
index fab499ce..1d22b59a 100644
--- a/test/test.rs
+++ b/test/test.rs
@@ -15,7 +15,6 @@ mod test_fcntl;
mod test_mq;
mod test_net;
mod test_nix_path;
-#[cfg(any(target_os = "linux", target_os = "macos"))]
mod test_poll;
mod test_pty;
#[cfg(any(target_os = "linux", target_os = "android"))]