2
2
use sys:: time:: TimeSpec ;
3
3
#[ cfg( any( target_os = "android" , target_os = "dragonfly" , target_os = "freebsd" , target_os = "linux" ) ) ]
4
4
use sys:: signal:: SigSet ;
5
+ use std:: os:: unix:: io:: RawFd ;
5
6
6
7
use libc;
7
8
use { Errno , Result } ;
8
9
10
+ /// This is a wrapper around `libc::pollfd`.
11
+ ///
12
+ /// It's meant to be used as an argument to the [`poll`](fn.poll.html) and
13
+ /// [`ppoll`](fn.ppoll.html) functions to specify the events of interes
14
+ /// for a specific file descriptor.
15
+ ///
16
+ /// After a call to `poll` or `ppoll`, the events that occured can be
17
+ /// retrieved by calling [`revents()`](#method.revents) on the `PollFd`.
9
18
#[ repr( C ) ]
10
19
#[ derive( Clone , Copy ) ]
11
20
pub struct PollFd {
12
21
pollfd : libc:: pollfd ,
13
22
}
14
23
15
24
impl PollFd {
16
- pub fn new ( fd : libc:: c_int , events : EventFlags ) -> PollFd {
25
+ /// Creates a new `PollFd` specifying the events of interested
26
+ /// for a given file descriptor.
27
+ pub fn new ( fd : RawFd , events : EventFlags ) -> PollFd {
17
28
PollFd {
18
29
pollfd : libc:: pollfd {
19
30
fd : fd,
@@ -23,26 +34,82 @@ impl PollFd {
23
34
}
24
35
}
25
36
37
+ /// Returns the events that occured in the last call to `poll` or `ppoll`.
26
38
pub fn revents ( & self ) -> Option < EventFlags > {
27
39
EventFlags :: from_bits ( self . pollfd . revents )
28
40
}
29
41
}
30
42
31
43
libc_bitflags ! {
44
+ /// These flags define the different events that can be monitored by `poll` and `ppoll`
32
45
pub flags EventFlags : libc:: c_short {
46
+ /// There is data to read.
33
47
POLLIN ,
48
+ /// There is some exceptional condition on the file descriptor.
49
+ ///
50
+ /// Possibilities include:
51
+ ///
52
+ /// * There is out-of-band data on a TCP socket (see
53
+ /// [tcp(7)](http://man7.org/linux/man-pages/man7/tcp.7.html)).
54
+ /// * A pseudoterminal master in packet mode has seen a state
55
+ /// change on the slave (see
56
+ /// [ioctl_tty(2)](http://man7.org/linux/man-pages/man2/ioctl_tty.2.html)).
57
+ /// * A cgroup.events file has been modified (see
58
+ /// [cgroups(7)](http://man7.org/linux/man-pages/man7/cgroups.7.html)).
34
59
POLLPRI ,
60
+ /// Writing is now possible, though a write larger that the
61
+ /// available space in a socket or pipe will still block (unless
62
+ /// `O_NONBLOCK` is set).
35
63
POLLOUT ,
64
+ /// Equivalent to [`POLLIN`](constant.POLLIN.html)
36
65
POLLRDNORM ,
66
+ /// Equivalent to [`POLLOUT`](constant.POLLOUT.html)
37
67
POLLWRNORM ,
68
+ /// Priority band data can be read (generally unused on Linux).
38
69
POLLRDBAND ,
70
+ /// Priority data may be written.
39
71
POLLWRBAND ,
72
+ /// Error condition (only returned in
73
+ /// [`PollFd::revents`](struct.PollFd.html#method.revents);
74
+ /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
75
+ /// This bit is also set for a file descriptor referring to the
76
+ /// write end of a pipe when the read end has been closed.
40
77
POLLERR ,
78
+ /// Hang up (only returned in [`PollFd::revents`](struct.PollFd.html#method.revents);
79
+ /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
80
+ /// Note that when reading from a channel such as a pipe or a stream
81
+ /// socket, this event merely indicates that the peer closed its
82
+ /// end of the channel. Subsequent reads from the channel will
83
+ /// return 0 (end of file) only after all outstanding data in the
84
+ /// channel has been consumed.
41
85
POLLHUP ,
86
+ /// Invalid request: `fd` not open (only returned in
87
+ /// [`PollFd::revents`](struct.PollFd.html#method.revents);
88
+ /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
42
89
POLLNVAL ,
43
90
}
44
91
}
45
92
93
+ /// `poll` waits for one of a set of file descriptors to become ready to perform I/O.
94
+ /// ([`poll(2)`](http://man7.org/linux/man-pages/man2/poll.2.html))
95
+ ///
96
+ /// `fds` is a slice containing all [`PollFd`](struct.PollFd.html) to poll.
97
+ /// The function will return as soon as one event registered in one of the `PollFd` occurs.
98
+ ///
99
+ /// The `timeout` argument specifies the number of milliseconds that `poll()`
100
+ /// should block waiting for a file descriptor to become ready. The call
101
+ /// will block until either:
102
+ ///
103
+ /// * a file descriptor becomes ready;
104
+ /// * the call is interrupted by a signal handler; or
105
+ /// * the timeout expires.
106
+ ///
107
+ /// Note that the timeout interval will be rounded up to the system clock
108
+ /// granularity, and kernel scheduling delays mean that the blocking
109
+ /// interval may overrun by a small amount. Specifying a negative value
110
+ /// in timeout means an infinite timeout. Specifying a timeout of zero
111
+ /// causes `poll()` to return immediately, even if no file descriptors are
112
+ /// ready.
46
113
pub fn poll ( fds : & mut [ PollFd ] , timeout : libc:: c_int ) -> Result < libc:: c_int > {
47
114
let res = unsafe {
48
115
libc:: poll ( fds. as_mut_ptr ( ) as * mut libc:: pollfd ,
@@ -53,6 +120,13 @@ pub fn poll(fds: &mut [PollFd], timeout: libc::c_int) -> Result<libc::c_int> {
53
120
Errno :: result ( res)
54
121
}
55
122
123
+ /// `ppoll()` allows an application to safely wait until either a file
124
+ /// descriptor becomes ready or until a signal is caught.
125
+ /// ([`poll(2)`](http://man7.org/linux/man-pages/man2/poll.2.html))
126
+ ///
127
+ /// `ppoll` behaves like `poll`, but let you precise what signals may interrupt it
128
+ /// with the `sigmask` argument.
129
+ ///
56
130
#[ cfg( any( target_os = "android" , target_os = "dragonfly" , target_os = "freebsd" , target_os = "linux" ) ) ]
57
131
pub fn ppoll ( fds : & mut [ PollFd ] , timeout : TimeSpec , sigmask : SigSet ) -> Result < libc:: c_int > {
58
132
0 commit comments