diff options
-rw-r--r-- | src/sys/ioctl/platform/linux.rs | 67 | ||||
-rw-r--r-- | test/sys/test_ioctl.rs | 13 |
2 files changed, 61 insertions, 19 deletions
diff --git a/src/sys/ioctl/platform/linux.rs b/src/sys/ioctl/platform/linux.rs index 39245461..15066b75 100644 --- a/src/sys/ioctl/platform/linux.rs +++ b/src/sys/ioctl/platform/linux.rs @@ -90,47 +90,78 @@ macro_rules! iorw { ($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::READ | $crate::sys::ioctl::WRITE, $ty, $nr, $sz)) } +/// Convert raw ioctl return value to a Nix result +#[macro_export] +macro_rules! convert_ioctl_res { + ($w:expr) => ( + { + let res = $w; + if res < 0 { + return Err($crate::Error::Sys($crate::errno::Errno::last())) + } + Ok(res) // res may contain useful information for user + } + ); +} + /// Declare a wrapper function around an ioctl. #[macro_export] macro_rules! ioctl { (bad $name:ident with $nr:expr) => ( - pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int, data: *mut u8) -> $crate::sys::ioctl::libc::c_int { - $crate::sys::ioctl::ioctl(fd, $nr as $crate::sys::ioctl::libc::c_ulong, data) + pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int, + data: *mut u8) + -> $crate::Result<$crate::sys::ioctl::libc::c_int> { + convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, $nr as $crate::sys::ioctl::libc::c_ulong, data)) } - ); + ); (none $name:ident with $ioty:expr, $nr:expr) => ( - pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int) -> $crate::sys::ioctl::libc::c_int { - $crate::sys::ioctl::ioctl(fd, io!($ioty, $nr) as $crate::sys::ioctl::libc::c_ulong) + pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int) + -> $crate::Result<$crate::sys::ioctl::libc::c_int> { + convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, io!($ioty, $nr) as $crate::sys::ioctl::libc::c_ulong)) } - ); + ); (read $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( - pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int, val: *mut $ty) -> $crate::sys::ioctl::libc::c_int { - $crate::sys::ioctl::ioctl(fd, ior!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::libc::c_ulong, val) + pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int, + val: *mut $ty) + -> $crate::Result<$crate::sys::ioctl::libc::c_int> { + convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, ior!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::libc::c_ulong, val)) } ); (write $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( - pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int, val: *const $ty) -> $crate::sys::ioctl::libc::c_int { - $crate::sys::ioctl::ioctl(fd, ior!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::libc::c_ulong, val) + pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int, + val: *const $ty) + -> $crate::Result<$crate::sys::ioctl::libc::c_int> { + convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, ior!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::libc::c_ulong, val)) } ); (readwrite $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( - pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int, val: *mut $ty) -> $crate::sys::ioctl::libc::c_int { - $crate::sys::ioctl::ioctl(fd, iorw!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::libc::c_ulong, val) + pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int, + val: *mut $ty) + -> $crate::Result<$crate::sys::ioctl::libc::c_int> { + convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, iorw!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::libc::c_ulong, val)) } ); (read buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( - pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int, val: *mut $ty, len: usize) -> $crate::sys::ioctl::libc::c_int { - $crate::sys::ioctl::ioctl(fd, ior!($ioty, $nr, len) as $crate::sys::ioctl::libc::c_ulong, val) + pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int, + val: *mut $ty, + len: usize) + -> $crate::Result<$crate::sys::ioctl::libc::c_int> { + convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, ior!($ioty, $nr, len) as $crate::sys::ioctl::libc::c_ulong, val)) } ); (write buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( - pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int, val: *const $ty, len: usize) -> $crate::sys::ioctl::libc::c_int { - $crate::sys::ioctl::ioctl(fd, ior!($ioty, $nr, len) as $crate::sys::ioctl::libc::c_ulong, val) + pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int, + val: *const $ty, + len: usize) -> $crate::Result<$crate::sys::ioctl::libc::c_int> { + convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, ior!($ioty, $nr, len) as $crate::sys::ioctl::libc::c_ulong, val)) } ); (readwrite buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( - pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int, val: *const $ty, len: usize) -> $crate::sys::ioctl::libc::c_int { - $crate::sys::ioctl::ioctl(fd, iorw!($ioty, $nr, len) as $crate::sys::ioctl::libc::c_ulong, val) + pub unsafe fn $name(fd: $crate::sys::ioctl::libc::c_int, + val: *const $ty, + len: usize) + -> $crate::Result<$crate::sys::ioctl::libc::c_int> { + convert_ioctl_res!($crate::sys::ioctl::ioctl(fd, iorw!($ioty, $nr, len) as $crate::sys::ioctl::libc::c_ulong, val)) } ); } diff --git a/test/sys/test_ioctl.rs b/test/sys/test_ioctl.rs index 90de9d87..94eca447 100644 --- a/test/sys/test_ioctl.rs +++ b/test/sys/test_ioctl.rs @@ -1,5 +1,16 @@ +#![allow(dead_code)] + #![cfg(target_os = "linux")] // no ioctl support for osx yet -use nix::sys::ioctl::*; + +// Simple tests to ensure macro generated fns compile +ioctl!(bad do_bad with 0x1234); +ioctl!(none do_none with 0, 0); +ioctl!(read read_test with 0, 0; u32); +ioctl!(write write_test with 0, 0; u64); +ioctl!(readwrite readwrite_test with 0, 0; u64); +ioctl!(read buf readbuf_test with 0, 0; u32); +ioctl!(write buf writebuf_test with 0, 0; u32); +ioctl!(readwrite buf readwritebuf_test with 0, 0; u32); // See C code for source of values for op calculations: // https://gist.github.com/posborne/83ea6880770a1aef332e |