diff options
author | Bryant Mairs <bryant@mai.rs> | 2017-07-18 09:36:49 -0700 |
---|---|---|
committer | Marcin Mielniczuk <marmistrz.dev@zoho.eu> | 2017-07-25 09:09:52 +0200 |
commit | 3cf4cc68174ebe126a537ba8f29c29243201d917 (patch) | |
tree | 678f2958a9f4fdab2d05002d2ebd5e5b618a3926 /src/sys | |
parent | 7b078473b8ab52742c7ce46e338fc1ad98355dc8 (diff) | |
download | nix-3cf4cc68174ebe126a537ba8f29c29243201d917.zip |
Split ioctl!(write ...) into write_ptr and write_int
There two different write semantics used with ioctls: one involves
passing a pointer the other involves passing an int. Previously the
ioctl! macro did not distinguish between these cases and left it up
to the user to set the proper datatype. This previous version was
not type safe and prone to errors. The solution here is to split the
"write" variant into a "write_ptr" and "write_int" variant that makes
the semantics more explicit and improves type safety by specifying
arguments better.
Diffstat (limited to 'src/sys')
-rw-r--r-- | src/sys/ioctl/mod.rs | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/src/sys/ioctl/mod.rs b/src/sys/ioctl/mod.rs index 43114a5c..058fc60a 100644 --- a/src/sys/ioctl/mod.rs +++ b/src/sys/ioctl/mod.rs @@ -80,7 +80,22 @@ //! The return value for `ioctl` functions generated by the `ioctl!` macro are `nix::Error`s. //! These are generated by assuming the return value of the ioctl is `-1` on error and everything //! else is a valid return value. If this is not the case, `Result::map` can be used to map some -//! of the range of "good" values (-2..-Inf, 0..Inf) into a smaller range in a helper function. +//! of the range of "good" values (-Inf..-2, 0..Inf) into a smaller range in a helper function. +//! +//! Writing `ioctl`s generally use pointers as their data source and these should use the +//! `write_ptr` variant. But in some cases an `int` is passed directly. For these `ioctl`s use the +//! `write_int` variant of the `ioctl!` macro. This variant does not take a type as the last argument: +//! +//! ``` +//! # #[macro_use] extern crate nix; +//! const HCI_IOC_MAGIC: u8 = b'k'; +//! const HCI_IOC_HCIDEVUP: u8 = 1; +//! ioctl!(write_int hci_dev_up with HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP); +//! # fn main() {} +//! ``` +//! +//! Some `ioctl`s don't transfer any data, and those should use the `none` variant. This variant +//! doesn't take a type and so it is declared similar to the `write_int` variant shown above. //! //! The mode for a given `ioctl` should be clear from the documentation if it has good //! documentation. Otherwise it will be clear based on the macro used to generate the `ioctl` @@ -196,13 +211,20 @@ macro_rules! ioctl { convert_ioctl_res!($crate::libc::ioctl(fd, ior!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) } ); - (write $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( + (write_ptr $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( pub unsafe fn $name(fd: $crate::libc::c_int, - data: $ty) + data: *const $ty) -> $crate::Result<$crate::libc::c_int> { convert_ioctl_res!($crate::libc::ioctl(fd, iow!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) } ); + (write_int $name:ident with $ioty:expr, $nr:expr) => ( + pub unsafe fn $name(fd: $crate::libc::c_int, + data: $crate::libc::c_int) + -> $crate::Result<$crate::libc::c_int> { + convert_ioctl_res!($crate::libc::ioctl(fd, iow!($ioty, $nr, ::std::mem::size_of::<$crate::libc::c_int>()) as $crate::sys::ioctl::ioctl_num_type, data)) + } + ); (readwrite $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( pub unsafe fn $name(fd: $crate::libc::c_int, data: *mut $ty) |