1 extern crate libudev;
2 extern crate libc;
3
4 use std::io;
5 use std::ptr;
6 use std::thread;
7 use std::time::Duration;
8
9 use std::os::unix::io::{AsRawFd};
10
11 use libc::{c_void,c_int,c_short,c_ulong,timespec};
12
13 #[repr(C)]
14 struct pollfd {
15 fd: c_int,
16 events: c_short,
17 revents: c_short,
18 }
19
20 #[repr(C)]
21 struct sigset_t {
22 __private: c_void
23 }
24
25 #[allow(non_camel_case_types)]
26 type nfds_t = c_ulong;
27
28 const POLLIN: c_short = 0x0001;
29
30 extern "C" {
ppoll(fds: *mut pollfd, nfds: nfds_t, timeout_ts: *mut libc::timespec, sigmask: *const sigset_t) -> c_int31 fn ppoll(fds: *mut pollfd, nfds: nfds_t, timeout_ts: *mut libc::timespec, sigmask: *const sigset_t) -> c_int;
32 }
33
main()34 fn main() {
35 let context = libudev::Context::new().unwrap();
36 monitor(&context).unwrap();
37 }
38
monitor(context: &libudev::Context) -> io::Result<()>39 fn monitor(context: &libudev::Context) -> io::Result<()> {
40 let mut monitor = try!(libudev::Monitor::new(&context));
41
42 try!(monitor.match_subsystem_devtype("usb", "usb_device"));
43 let mut socket = try!(monitor.listen());
44
45 let mut fds = vec!(pollfd { fd: socket.as_raw_fd(), events: POLLIN, revents: 0 });
46
47 loop {
48 let result = unsafe { ppoll((&mut fds[..]).as_mut_ptr(), fds.len() as nfds_t, ptr::null_mut(), ptr::null()) };
49
50 if result < 0 {
51 return Err(io::Error::last_os_error());
52 }
53
54 let event = match socket.receive_event() {
55 Some(evt) => evt,
56 None => {
57 thread::sleep(Duration::from_millis(10));
58 continue;
59 }
60 };
61
62 println!("{}: {} {} (subsystem={}, sysname={}, devtype={})",
63 event.sequence_number(),
64 event.event_type(),
65 event.syspath().to_str().unwrap_or("---"),
66 event.subsystem().to_str().unwrap_or(""),
67 event.sysname().to_str().unwrap_or(""),
68 event.devtype().map_or("", |s| { s.to_str().unwrap_or("") }));
69 }
70 }
71