-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Jean Pierre Dudey <[email protected]>
- Loading branch information
0 parents
commit fe36f28
Showing
16 changed files
with
731 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
/target | ||
**/*.rs.bk | ||
Cargo.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[workspace] | ||
members = ["mio-udev", "tokio-udev", "udev-sys", "udev"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[package] | ||
name = "mio-udev" | ||
version = "0.1.0" | ||
authors = ["Jean Pierre Dudey <[email protected]>"] | ||
|
||
[dependencies] | ||
udev = { path = "../udev", version = "0.1.0" } | ||
mio = "0.6" | ||
libc = "0.2" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
#![cfg(target_os = "linux")] | ||
|
||
extern crate udev; | ||
extern crate mio; | ||
extern crate libc; | ||
|
||
mod util; | ||
|
||
use std::io; | ||
use std::os::unix::io::{AsRawFd, RawFd}; | ||
|
||
use mio::{Ready, Poll, PollOpt, Token}; | ||
use mio::event::Evented; | ||
use mio::unix::EventedFd; | ||
|
||
#[derive(Debug)] | ||
pub struct MonitorIo { | ||
monitor: udev::Monitor, | ||
} | ||
|
||
impl MonitorIo { | ||
/// Creates a new monitor io object from an existing udev monitor. | ||
/// | ||
/// # Notes | ||
/// | ||
/// It marks the file descriptor as `FD_CLOEXEC` and sets the `O_NONBLOCK` | ||
/// flag. | ||
pub fn from_monitor(monitor: udev::Monitor) -> io::Result<MonitorIo> { | ||
use libc::{fcntl, F_GETFD, FD_CLOEXEC, F_SETFD, F_GETFL, F_SETFL, O_NONBLOCK}; | ||
use util::cvt; | ||
|
||
let fd = monitor.as_raw_fd(); | ||
|
||
// Make sure the udev file descriptor is marked as CLOEXEC. | ||
let r = unsafe { cvt(fcntl(fd, F_GETFD))? }; | ||
|
||
if !((r & FD_CLOEXEC) == FD_CLOEXEC) { | ||
unsafe { cvt(fcntl(fd, F_SETFD, r | FD_CLOEXEC))? }; | ||
} | ||
|
||
// Some older versions of udev are not non-blocking by default, | ||
// so make sure this is set | ||
let r = unsafe { cvt(fcntl(fd, F_GETFL))? }; | ||
|
||
if !((r & O_NONBLOCK) == O_NONBLOCK) { | ||
unsafe { cvt(fcntl(fd, F_SETFL, r | O_NONBLOCK))? }; | ||
} | ||
|
||
Ok(MonitorIo { monitor }) | ||
} | ||
|
||
pub fn receive_device(&self) -> io::Result<udev::Device> { | ||
self.monitor.receive_device() | ||
} | ||
|
||
#[inline(always)] | ||
fn fd(&self) -> RawFd { | ||
self.monitor.as_raw_fd() | ||
} | ||
} | ||
|
||
impl Evented for MonitorIo { | ||
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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
use std::{io, ops::Neg}; | ||
|
||
#[doc(hidden)] | ||
pub trait One { | ||
fn one() -> Self; | ||
} | ||
|
||
macro_rules! one { | ||
($($t:ident)*) => ($( | ||
impl One for $t { fn one() -> $t { 1 } } | ||
)*) | ||
} | ||
|
||
one! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize } | ||
|
||
pub fn cvt<T: One + PartialEq + Neg<Output=T>>(t: T) -> io::Result<T> { | ||
let one: T = T::one(); | ||
if t == -one { | ||
Err(io::Error::last_os_error()) | ||
} else { | ||
Ok(t) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[package] | ||
name = "tokio-udev" | ||
version = "0.1.0" | ||
authors = ["Jean Pierre Dudey <[email protected]>"] | ||
|
||
[dependencies] | ||
libc = "0.2" | ||
|
||
mio-udev = { path = "../mio-udev", version = "0.1.0" } | ||
mio = "0.6" | ||
udev = { path = "../udev", version = "0.1.0" } | ||
|
||
futures = "0.1" | ||
tokio-reactor = "0.1" | ||
|
||
[dev-dependencies] | ||
tokio = "0.1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
extern crate tokio_udev; | ||
extern crate tokio; | ||
extern crate futures; | ||
|
||
use futures::{Future, stream::Stream}; | ||
|
||
use tokio_udev::{USB_SUBSYSTEM, USB_DEVICE, UDEV_MONITOR}; | ||
|
||
fn main() { | ||
let monitor = tokio_udev::Builder::new() | ||
.add_match(USB_SUBSYSTEM, USB_DEVICE) | ||
.build(UDEV_MONITOR) | ||
.expect("couldn't create monitor"); | ||
|
||
let hotplug_stream = monitor.for_each(|device| { | ||
println!("====================="); | ||
println!(" Usb HotPlug Event "); | ||
println!("====================="); | ||
println!("devpath: \"{:?}\"", device.get_devpath()?); | ||
println!("action: \"{}\"", device.get_action()?); | ||
|
||
Ok(()) | ||
}) | ||
.map_err(|e| { | ||
println!("error: {}", e); | ||
}); | ||
|
||
tokio::run(hotplug_stream); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#![cfg(target_os = "linux")] | ||
|
||
//! # tokio udev | ||
extern crate libc; | ||
|
||
extern crate udev; | ||
extern crate mio_udev; | ||
extern crate mio; | ||
|
||
extern crate futures; | ||
extern crate tokio_reactor; | ||
|
||
mod monitor; | ||
|
||
pub use udev::{Subsystem, DeviceType, MonitorName, USB_SUBSYSTEM, USB_DEVICE, UDEV_MONITOR}; | ||
|
||
pub use monitor::{Builder, Monitor}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
use std::io; | ||
|
||
use {mio, udev, mio_udev}; | ||
use tokio_reactor::PollEvented; | ||
use futures::{Async, Poll, stream::Stream}; | ||
|
||
#[derive(Debug)] | ||
pub struct Builder { | ||
match_filters: Vec<(udev::Subsystem, udev::DeviceType)>, | ||
} | ||
|
||
impl Builder { | ||
pub fn new() -> Builder { | ||
Builder { | ||
match_filters: Vec::new(), | ||
} | ||
} | ||
|
||
pub fn add_match(mut self, | ||
subsystem: udev::Subsystem, | ||
devtype: udev::DeviceType) -> Builder { | ||
self.match_filters.push((subsystem, devtype)); | ||
self | ||
} | ||
|
||
pub fn build(self, name: udev::MonitorName) -> io::Result<Monitor> { | ||
let context = udev::Context::new(); | ||
let monitor = udev::Monitor::new_from_netlink(&context, name); | ||
|
||
for filter in self.match_filters { | ||
monitor.filter_add_match_subsystem_devtype(filter.0, filter.1)?; | ||
} | ||
|
||
monitor.enable_receiving()?; | ||
|
||
Monitor::new(monitor) | ||
} | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct Monitor { | ||
io: PollEvented<mio_udev::MonitorIo>, | ||
} | ||
|
||
impl Monitor { | ||
pub fn new(monitor: udev::Monitor) -> io::Result<Monitor> { | ||
let io = PollEvented::new(mio_udev::MonitorIo::from_monitor(monitor)?); | ||
Ok(Monitor { io }) | ||
} | ||
|
||
pub fn poll_receive(&self) -> Poll<Option<udev::Device>, io::Error> { | ||
if let Async::NotReady = self.io.poll_read_ready(mio::Ready::readable())? { | ||
return Ok(Async::NotReady); | ||
} | ||
|
||
match self.io.get_ref().receive_device() { | ||
Ok(device) => Ok(Async::Ready(Some(device))), | ||
Err(e) => { | ||
if e.kind() == io::ErrorKind::WouldBlock { | ||
self.io.clear_read_ready(mio::Ready::readable())?; | ||
Ok(Async::NotReady) | ||
} else { | ||
Err(e) | ||
} | ||
}, | ||
} | ||
|
||
} | ||
} | ||
|
||
impl Stream for Monitor { | ||
type Item = udev::Device; | ||
type Error = io::Error; | ||
|
||
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> { | ||
self.poll_receive() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[package] | ||
name = "udev-sys" | ||
version = "0.1.0" | ||
authors = ["Jean Pierre Dudey <[email protected]>"] | ||
|
||
[dependencies] | ||
libc = "0.2" |
Oops, something went wrong.