extern crate libc; #[cfg(feature = "mio06")] extern crate mio06; #[cfg(feature = "mio07")] extern crate mio07; #[cfg(feature = "mio08")] extern crate mio08; extern crate udev; use std::io; #[cfg(not(any(feature = "mio06", feature = "mio07", feature = "mio08")))] mod poll { use std::io; use std::ptr; use std::thread; use std::time::Duration; use std::os::unix::io::AsRawFd; use libc::{c_int, c_short, c_ulong, c_void}; #[repr(C)] #[allow(non_camel_case_types)] struct pollfd { fd: c_int, events: c_short, revents: c_short, } #[repr(C)] #[allow(non_camel_case_types)] struct sigset_t { __private: c_void, } #[allow(non_camel_case_types)] type nfds_t = c_ulong; const POLLIN: c_short = 0x0001; extern "C" { fn ppoll( fds: *mut pollfd, nfds: nfds_t, timeout_ts: *mut libc::timespec, sigmask: *const sigset_t, ) -> c_int; } pub fn poll(socket: udev::MonitorSocket) -> io::Result<()> { println!("Use syspoll"); let mut fds = vec![pollfd { fd: socket.as_raw_fd(), events: POLLIN, revents: 0, }]; loop { let result = unsafe { ppoll( (&mut fds[..]).as_mut_ptr(), fds.len() as nfds_t, ptr::null_mut(), ptr::null(), ) }; if result < 0 { return Err(io::Error::last_os_error()); } let event = match socket.iter().next() { Some(evt) => evt, None => { thread::sleep(Duration::from_millis(10)); continue; } }; super::print_event(event); } } } #[cfg(feature = "mio06")] mod poll { use std::io; use mio06::{Events, Poll, PollOpt, Ready, Token}; pub fn poll(mut socket: udev::MonitorSocket) -> io::Result<()> { println!("Use mio06 poll"); let poll = Poll::new()?; let mut events = Events::with_capacity(1024); poll.register( &mut socket, Token(0), Ready::readable() | Ready::writable(), PollOpt::edge(), )?; loop { poll.poll(&mut events, None)?; for event in &events { if event.token() == Token(0) && event.readiness().is_writable() { socket.iter().for_each(|x| super::print_event(x)); } } } } } #[cfg(any(feature = "mio07", feature = "mio08"))] mod poll { use std::io; #[cfg(feature = "mio07")] use mio07::{Events, Interest, Poll, Token}; #[cfg(feature = "mio08")] use mio08::{Events, Interest, Poll, Token}; pub fn poll(mut socket: udev::MonitorSocket) -> io::Result<()> { let version = if cfg!(feature = "mio07") { "mio07" } else if cfg!(feature = "mio08") { "mio08" } else { "mio-unknown" }; println!("Use {} poll", version); let mut poll = Poll::new()?; let mut events = Events::with_capacity(1024); poll.registry().register( &mut socket, Token(0), Interest::READABLE | Interest::WRITABLE, )?; loop { poll.poll(&mut events, None)?; for event in &events { if event.token() == Token(0) && event.is_writable() { socket.iter().for_each(|x| super::print_event(x)); } } } } } fn print_event(event: udev::Event) { println!( "{}: {} {} (subsystem={}, sysname={}, devtype={})", event.sequence_number(), event.event_type(), event.syspath().to_str().unwrap_or("---"), event .subsystem() .map_or("", |s| { s.to_str().unwrap_or("") }), event.sysname().to_str().unwrap_or(""), event.devtype().map_or("", |s| { s.to_str().unwrap_or("") }) ); } // Use `mio::poll` as poller by compile with: // `cargo run --example monitor --features "mio08"` fn main() -> io::Result<()> { let socket = udev::MonitorBuilder::new()? // .match_subsystem_devtype("usb", "usb_device")? .match_subsystem_devtype("block", "disk")? .listen()?; poll::poll(socket) }