#![cfg(target_os = "linux")]
extern crate udev;
extern crate mio;
extern crate libc;
pub use udev::{Attribute, Attributes, Context, Device, Event, EventType,
Property, Properties, Error as UdevError};
mod util;
use std::io;
use std::os::unix::io::{AsRawFd, RawFd};
use std::ffi::OsStr;
use mio::{Ready, Poll, PollOpt, Token};
use mio::event::Evented;
use mio::unix::EventedFd;
pub struct MonitorBuilder {
builder: udev::MonitorBuilder,
}
impl MonitorBuilder {
#[inline(always)]
pub fn new(context: &Context) -> io::Result<Self> {
Ok(MonitorBuilder { builder: udev::MonitorBuilder::new(context)? })
}
#[inline(always)]
pub fn match_subsystem<T>(&mut self, subsystem: T) -> io::Result<()>
where T: AsRef<OsStr>,
{
Ok(self.builder.match_subsystem::<T>(subsystem)?)
}
#[inline(always)]
pub fn match_subsystem_devtype<T, U>(&mut self,
subsystem: T,
devtype: U) -> io::Result<()>
where T: AsRef<OsStr>,
U: AsRef<OsStr>,
{
Ok(self.builder.match_subsystem_devtype::<T, U>(subsystem, devtype)?)
}
#[inline(always)]
pub fn match_tag<T>(&mut self, tag: T) -> io::Result<()>
where T: AsRef<OsStr>,
{
Ok(self.builder.match_tag::<T>(tag)?)
}
#[inline(always)]
pub fn clear_filters(&mut self) -> io::Result<()> {
Ok(self.builder.clear_filters()?)
}
pub fn listen(self) -> io::Result<MonitorSocket> {
Ok(MonitorSocket::new(self.builder.listen()?)?)
}
}
pub struct MonitorSocket {
monitor: udev::MonitorSocket,
}
impl MonitorSocket {
fn new(monitor: udev::MonitorSocket) -> io::Result<MonitorSocket> {
use libc::{fcntl, F_GETFD, FD_CLOEXEC, F_SETFD, F_GETFL, F_SETFL, O_NONBLOCK};
use util::cvt;
let fd = monitor.as_raw_fd();
let r = unsafe { cvt(fcntl(fd, F_GETFD))? };
if !((r & FD_CLOEXEC) == FD_CLOEXEC) {
unsafe { cvt(fcntl(fd, F_SETFD, r | FD_CLOEXEC))? };
}
let r = unsafe { cvt(fcntl(fd, F_GETFL))? };
if !((r & O_NONBLOCK) == O_NONBLOCK) {
unsafe { cvt(fcntl(fd, F_SETFL, r | O_NONBLOCK))? };
}
Ok(MonitorSocket { monitor })
}
#[inline(always)]
fn fd(&self) -> RawFd {
self.monitor.as_raw_fd()
}
}
impl Evented for MonitorSocket {
fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt)
-> io::Result<()>
{
EventedFd(&self.fd()).register(poll, token, interest, opts)
}
fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt)
-> io::Result<()>
{
EventedFd(&self.fd()).reregister(poll, token, interest, opts)
}
fn deregister(&self, poll: &Poll) -> io::Result<()> {
EventedFd(&self.fd()).deregister(poll)
}
}
impl Iterator for MonitorSocket {
type Item = Event;
fn next(&mut self) -> Option<Self::Item> {
self.monitor.next()
}
}