Skip to content

Instantly share code, notes, and snippets.

@xandkar
Forked from AGWA/select.rs
Created September 26, 2022 15:52
Show Gist options
  • Save xandkar/ae14212fe0750e87e18f2fff6142e47b to your computer and use it in GitHub Desktop.
Save xandkar/ae14212fe0750e87e18f2fff6142e47b to your computer and use it in GitHub Desktop.
Very simple Rust wrapper around pselect
/* Copyright (C) 2017 Andrew Ayer
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name(s) of the above copyright
* holders shall not be used in advertising or otherwise to promote the
* sale, use or other dealings in this Software without prior written
* authorization.
*/
extern crate libc;
use std::{io,mem,ptr,time};
use std::os::unix::io::RawFd;
pub struct FdSet(libc::fd_set);
impl FdSet {
pub fn new() -> FdSet {
unsafe {
let mut raw_fd_set = mem::uninitialized::<libc::fd_set>();
libc::FD_ZERO(&mut raw_fd_set);
FdSet(raw_fd_set)
}
}
pub fn clear(&mut self, fd: RawFd) {
unsafe {
libc::FD_CLR(fd, &mut self.0);
}
}
pub fn set(&mut self, fd: RawFd) {
unsafe {
libc::FD_SET(fd, &mut self.0);
}
}
pub fn is_set(&mut self, fd: RawFd) -> bool {
unsafe {
libc::FD_ISSET(fd, &mut self.0)
}
}
}
pub fn pselect (nfds: libc::c_int,
readfds: Option<&mut FdSet>,
writefds: Option<&mut FdSet>,
errorfds: Option<&mut FdSet>,
timeout: Option<&libc::timespec>,
sigmask: Option<&libc::sigset_t>) -> io::Result<usize> {
fn to_fdset_ptr (opt: Option<&mut FdSet>) -> *mut libc::fd_set {
match opt {
None => ptr::null_mut(),
Some(&mut FdSet(ref mut raw_fd_set)) => raw_fd_set,
}
}
fn to_ptr<T> (opt: Option<&T>) -> *const T {
match opt {
None => ptr::null::<T>(),
Some(p) => p,
}
}
match unsafe {
libc::pselect(nfds,
to_fdset_ptr(readfds),
to_fdset_ptr(writefds),
to_fdset_ptr(errorfds),
to_ptr(timeout),
to_ptr(sigmask))
} {
-1 => Err(io::Error::last_os_error()),
res => Ok(res as usize),
}
}
pub fn make_timespec(duration: time::Duration) -> libc::timespec {
libc::timespec {
tv_sec: duration.as_secs() as i64,
tv_nsec: duration.subsec_nanos() as i64,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment