use std::ffi::{CString,OsStr}; use std::ops::Deref; use std::os::unix::io::{RawFd,AsRawFd};
use ::context::{Context}; use ::device::{Device}; use ::handle::prelude::*;
/// Monitors for device events. /// /// A monitor communicates with the kernel over a socket. Filtering events is performed efficiently /// in the kernel, and only events that match the filters are received by the socket. Filters must /// be setup before listening for events. pubstruct Monitor<'a> {
context: &'a Context,
monitor: *mut ::ffi::udev_monitor
}
impl<'a> Drop for Monitor<'a> { fn drop(&mutself) { unsafe {
::ffi::udev_monitor_unref(self.monitor);
}
}
}
impl<'a> Monitor<'a> { /// Creates a new `Monitor`. pubfn new(context: &'a Context) -> ::Result<Self> { let name = CString::new("udev").unwrap();
let ptr = try_alloc!(unsafe {
::ffi::udev_monitor_new_from_netlink(context.as_ptr(), name.as_ptr())
});
Ok(Monitor {
context: context,
monitor: ptr
})
}
/// Adds a filter that matches events for devices with the given subsystem. pubfn match_subsystem<T: AsRef<OsStr>>(&mutself, subsystem: T) -> ::Result<()> { let subsystem = try!(::util::os_str_to_cstring(subsystem));
/// Adds a filter that matches events for devices with the given subsystem and device type. pubfn match_subsystem_devtype<T: AsRef<OsStr>, U: AsRef<OsStr>>(&mutself, subsystem: T, devtype: U) -> ::Result<()> { let subsystem = try!(::util::os_str_to_cstring(subsystem)); let devtype = try!(::util::os_str_to_cstring(devtype));
/// Adds a filter that matches events for devices with the given tag. pubfn match_tag<T: AsRef<OsStr>>(&mutself, tag: T) -> ::Result<()> { let tag = try!(::util::os_str_to_cstring(tag));
/// Removes all filters currently set on the monitor. pubfn clear_filters(&mutself) -> ::Result<()> {
::util::errno_to_result(unsafe {
::ffi::udev_monitor_filter_remove(self.monitor)
})
}
/// Listens for events matching the current filters. /// /// This method consumes the `Monitor`. pubfn listen(self) -> ::Result<MonitorSocket<'a>> { try!(::util::errno_to_result(unsafe {
::ffi::udev_monitor_enable_receiving(self.monitor)
}));
Ok(MonitorSocket { inner: self })
}
}
/// An active monitor that can receive events. /// /// The events received by a `MonitorSocket` match the filters setup by the `Monitor` that created /// the socket. /// /// Monitors are initially setup to receive events from the kernel via a nonblocking socket. A /// variant of `poll()` should be used on the file descriptor returned by the `AsRawFd` trait to /// wait for new events. pubstruct MonitorSocket<'a> {
inner: Monitor<'a>
}
/// Provides raw access to the monitor's socket. impl<'a> AsRawFd for MonitorSocket<'a> { /// Returns the file descriptor of the monitor's socket. fn as_raw_fd(&self) -> RawFd { unsafe {
::ffi::udev_monitor_get_fd(self.inner.monitor)
}
}
}
impl<'a> MonitorSocket<'a> { /// Receives the next available event from the monitor. /// /// This method does not block. If no events are available, it returns `None` immediately. pubfn receive_event<'b>(&'b mutself) -> Option<Event<'a>> { let device = unsafe {
::ffi::udev_monitor_receive_device(self.inner.monitor)
};
if device.is_null() {
None
} else { let device = ::device::new(self.inner.context, device);
Some(Event { device: device })
}
}
}
/// Types of events that can be received from udev. #[derive(Debug,Clone,Copy,PartialEq,Eq)] pubenum EventType { /// A device was added.
Add,
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.