xref: /third_party/rust/crates/rustix/tests/io/poll.rs (revision b8a62b91)
1use rustix::fd::{AsFd, AsRawFd, FromRawFd, IntoRawFd, OwnedFd};
2#[cfg(not(windows))]
3use rustix::io::{poll, retry_on_intr};
4use rustix::io::{PollFd, PollFlags};
5
6#[cfg(not(windows))]
7#[test]
8fn test_poll() {
9    use rustix::io::{pipe, read, write};
10
11    // Create a pipe.
12    let (reader, writer) = pipe().unwrap();
13    let mut poll_fds = [PollFd::new(&reader, PollFlags::IN)];
14    assert_eq!(poll_fds[0].as_fd().as_raw_fd(), reader.as_fd().as_raw_fd());
15
16    // `poll` should say there's nothing ready to be read from the pipe.
17    let num = retry_on_intr(|| poll(&mut poll_fds, 0)).unwrap();
18    assert_eq!(num, 0);
19    assert!(poll_fds[0].revents().is_empty());
20    assert_eq!(poll_fds[0].as_fd().as_raw_fd(), reader.as_fd().as_raw_fd());
21
22    // Write a byte to the pipe.
23    assert_eq!(retry_on_intr(|| write(&writer, b"a")).unwrap(), 1);
24
25    // `poll` should now say there's data to be read.
26    let num = retry_on_intr(|| poll(&mut poll_fds, -1)).unwrap();
27    assert_eq!(num, 1);
28    assert_eq!(poll_fds[0].revents(), PollFlags::IN);
29    assert_eq!(poll_fds[0].as_fd().as_raw_fd(), reader.as_fd().as_raw_fd());
30
31    let mut temp = poll_fds[0].clone();
32    assert_eq!(temp.revents(), PollFlags::IN);
33    temp.clear_revents();
34    assert!(temp.revents().is_empty());
35
36    // Read the byte from the pipe.
37    let mut buf = [b'\0'];
38    assert_eq!(retry_on_intr(|| read(&reader, &mut buf)).unwrap(), 1);
39    assert_eq!(buf[0], b'a');
40    assert_eq!(poll_fds[0].as_fd().as_raw_fd(), reader.as_fd().as_raw_fd());
41
42    // Poll should now say there's no more data to be read.
43    let num = retry_on_intr(|| poll(&mut poll_fds, 0)).unwrap();
44    assert_eq!(num, 0);
45    assert!(poll_fds[0].revents().is_empty());
46    assert_eq!(poll_fds[0].as_fd().as_raw_fd(), reader.as_fd().as_raw_fd());
47}
48
49#[test]
50fn test_poll_fd_set_fd() {
51    // Make up some file descriptors so that we can test that set_fd works.
52    let a = unsafe { OwnedFd::from_raw_fd(777) };
53    let mut poll_fd = PollFd::new(&a, PollFlags::empty());
54    assert_eq!(poll_fd.as_fd().as_raw_fd(), 777);
55
56    let b = unsafe { OwnedFd::from_raw_fd(888) };
57    poll_fd.set_fd(&b);
58    assert_eq!(poll_fd.as_fd().as_raw_fd(), 888);
59
60    // Don't attempt to close our made-up file descriptors.
61    let _ = a.into_raw_fd();
62    let _ = b.into_raw_fd();
63}
64