| 1 | use nix::sys::select::*; |
| 2 | use nix::sys::signal::SigSet; |
| 3 | use nix::sys::time::{TimeSpec, TimeValLike}; |
| 4 | use nix::unistd::{pipe, write}; |
| 5 | use std::os::unix::io::{AsRawFd, BorrowedFd, FromRawFd, OwnedFd}; |
| 6 | |
| 7 | #[test] |
| 8 | pub fn test_pselect() { |
| 9 | let _mtx = crate::SIGNAL_MTX.lock(); |
| 10 | |
| 11 | let (r1, w1) = pipe().unwrap(); |
| 12 | write(w1, b"hi!" ).unwrap(); |
| 13 | let r1 = unsafe { OwnedFd::from_raw_fd(r1) }; |
| 14 | let (r2, _w2) = pipe().unwrap(); |
| 15 | let r2 = unsafe { OwnedFd::from_raw_fd(r2) }; |
| 16 | |
| 17 | let mut fd_set = FdSet::new(); |
| 18 | fd_set.insert(&r1); |
| 19 | fd_set.insert(&r2); |
| 20 | |
| 21 | let timeout = TimeSpec::seconds(10); |
| 22 | let sigmask = SigSet::empty(); |
| 23 | assert_eq!( |
| 24 | 1, |
| 25 | pselect(None, &mut fd_set, None, None, &timeout, &sigmask).unwrap() |
| 26 | ); |
| 27 | assert!(fd_set.contains(&r1)); |
| 28 | assert!(!fd_set.contains(&r2)); |
| 29 | } |
| 30 | |
| 31 | #[test] |
| 32 | pub fn test_pselect_nfds2() { |
| 33 | let (r1, w1) = pipe().unwrap(); |
| 34 | write(w1, b"hi!" ).unwrap(); |
| 35 | let r1 = unsafe { OwnedFd::from_raw_fd(r1) }; |
| 36 | let (r2, _w2) = pipe().unwrap(); |
| 37 | let r2 = unsafe { OwnedFd::from_raw_fd(r2) }; |
| 38 | |
| 39 | let mut fd_set = FdSet::new(); |
| 40 | fd_set.insert(&r1); |
| 41 | fd_set.insert(&r2); |
| 42 | |
| 43 | let timeout = TimeSpec::seconds(10); |
| 44 | assert_eq!( |
| 45 | 1, |
| 46 | pselect( |
| 47 | std::cmp::max(r1.as_raw_fd(), r2.as_raw_fd()) + 1, |
| 48 | &mut fd_set, |
| 49 | None, |
| 50 | None, |
| 51 | &timeout, |
| 52 | None |
| 53 | ) |
| 54 | .unwrap() |
| 55 | ); |
| 56 | assert!(fd_set.contains(&r1)); |
| 57 | assert!(!fd_set.contains(&r2)); |
| 58 | } |
| 59 | |
| 60 | macro_rules! generate_fdset_bad_fd_tests { |
| 61 | ($fd:expr, $($method:ident),* $(,)?) => { |
| 62 | $( |
| 63 | #[test] |
| 64 | #[should_panic] |
| 65 | fn $method() { |
| 66 | let bad_fd = unsafe{BorrowedFd::borrow_raw($fd)}; |
| 67 | FdSet::new().$method(&bad_fd); |
| 68 | } |
| 69 | )* |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | mod test_fdset_too_large_fd { |
| 74 | use super::*; |
| 75 | use std::convert::TryInto; |
| 76 | generate_fdset_bad_fd_tests!( |
| 77 | FD_SETSIZE.try_into().unwrap(), |
| 78 | insert, |
| 79 | remove, |
| 80 | contains, |
| 81 | ); |
| 82 | } |
| 83 | |