From a162ea27e593631fbc39274301f7dcba6eed06cb Mon Sep 17 00:00:00 2001 From: roblabla Date: Sun, 9 Jul 2017 00:52:20 +0200 Subject: Allow doc attributes in ioctl macro --- src/sys/ioctl/mod.rs | 67 ++++++++++++++++++++++++++++++++++++++++---------- test/sys/test_ioctl.rs | 54 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 13 deletions(-) diff --git a/src/sys/ioctl/mod.rs b/src/sys/ioctl/mod.rs index 4db3fe76..b29c8b42 100644 --- a/src/sys/ioctl/mod.rs +++ b/src/sys/ioctl/mod.rs @@ -197,6 +197,34 @@ //! of lines defining macros which use `_IO`, `_IOR`, `_IOW`, `_IOC`, and `_IORW`. Some `ioctl`s are //! documented directly in the headers defining their constants, but others have more extensive //! documentation in man pages (like termios' `ioctl`s which are in `tty_ioctl(4)`). +//! +//! Documenting the generated functions +//! =================================== +//! +//! In many cases, users will wish for the functions generated by the `ioctl` +//! macro to be public and documented. For this reason, the generated functions +//! are public by default. If you wish to hide the ioctl, you will need to put +//! them in a private module. +//! +//! For documentation, it is possible to use doc comments inside the `ioctl!` +//! macro. Here is an example : +//! +//! ``` +//! # #[macro_use] extern crate nix; +//! # use nix::libc::c_int; +//! ioctl! { +//! /// Make the given terminal the controlling terminal of the calling process. The calling +//! /// process must be a session leader and not have a controlling terminal already. If the +//! /// terminal is already the controlling terminal of a different session group then the +//! /// ioctl will fail with **EPERM**, unless the caller is root (more precisely: has the +//! /// **CAP_SYS_ADMIN** capability) and arg equals 1, in which case the terminal is stolen +//! /// and all processes that had it as controlling terminal lose it. +//! read tiocsctty with b't', 19; c_int +//! } +//! +//! # fn main() {} +//! ``` +//! #[cfg(any(target_os = "linux", target_os = "android"))] #[path = "platform/linux.rs"] #[macro_use] @@ -228,89 +256,102 @@ macro_rules! convert_ioctl_res { /// Generates ioctl functions. See [::sys::ioctl](sys/ioctl/index.html). #[macro_export] macro_rules! ioctl { - (bad none $name:ident with $nr:expr) => ( + ($(#[$attr:meta])* bad none $name:ident with $nr:expr) => ( + $(#[$attr])* pub unsafe fn $name(fd: $crate::libc::c_int) -> $crate::Result<$crate::libc::c_int> { convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type)) } ); - (bad read $name:ident with $nr:expr; $ty:ty) => ( + ($(#[$attr:meta])* bad read $name:ident with $nr:expr; $ty:ty) => ( + $(#[$attr])* pub unsafe fn $name(fd: $crate::libc::c_int, data: *mut $ty) -> $crate::Result<$crate::libc::c_int> { convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) } ); - (bad write_ptr $name:ident with $nr:expr; $ty:ty) => ( + ($(#[$attr:meta])* bad write_ptr $name:ident with $nr:expr; $ty:ty) => ( + $(#[$attr])* pub unsafe fn $name(fd: $crate::libc::c_int, data: *const $ty) -> $crate::Result<$crate::libc::c_int> { convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) } ); - (bad write_int $name:ident with $nr:expr) => ( + ($(#[$attr:meta])* bad write_int $name:ident with $nr:expr) => ( + $(#[$attr])* 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, $nr as $crate::sys::ioctl::ioctl_num_type, data)) } ); - (bad readwrite $name:ident with $nr:expr; $ty:ty) => ( + ($(#[$attr:meta])* bad readwrite $name:ident with $nr:expr; $ty:ty) => ( + $(#[$attr])* pub unsafe fn $name(fd: $crate::libc::c_int, data: *mut $ty) -> $crate::Result<$crate::libc::c_int> { convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) } ); - (none $name:ident with $ioty:expr, $nr:expr) => ( + ($(#[$attr:meta])* none $name:ident with $ioty:expr, $nr:expr) => ( + $(#[$attr])* pub unsafe fn $name(fd: $crate::libc::c_int) -> $crate::Result<$crate::libc::c_int> { convert_ioctl_res!($crate::libc::ioctl(fd, io!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type)) } ); - (read $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( + ($(#[$attr:meta])* read $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( + $(#[$attr])* pub unsafe fn $name(fd: $crate::libc::c_int, data: *mut $ty) -> $crate::Result<$crate::libc::c_int> { convert_ioctl_res!($crate::libc::ioctl(fd, ior!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) } ); - (write_ptr $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( + ($(#[$attr:meta])* write_ptr $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( + $(#[$attr])* pub unsafe fn $name(fd: $crate::libc::c_int, 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) => ( + ($(#[$attr:meta])* write_int $name:ident with $ioty:expr, $nr:expr) => ( + $(#[$attr])* 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) => ( + ($(#[$attr:meta])* readwrite $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( + $(#[$attr])* pub unsafe fn $name(fd: $crate::libc::c_int, data: *mut $ty) -> $crate::Result<$crate::libc::c_int> { convert_ioctl_res!($crate::libc::ioctl(fd, iorw!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) } ); - (read_buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( + ($(#[$attr:meta])* read_buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( + $(#[$attr])* pub unsafe fn $name(fd: $crate::libc::c_int, data: &mut [$ty]) -> $crate::Result<$crate::libc::c_int> { convert_ioctl_res!($crate::libc::ioctl(fd, ior!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) } ); - (write_buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( + ($(#[$attr:meta])* write_buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( + $(#[$attr])* pub unsafe fn $name(fd: $crate::libc::c_int, data: &[$ty]) -> $crate::Result<$crate::libc::c_int> { convert_ioctl_res!($crate::libc::ioctl(fd, iow!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) } ); - (readwrite_buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( + ($(#[$attr:meta])* readwrite_buf $name:ident with $ioty:expr, $nr:expr; $ty:ty) => ( + $(#[$attr])* pub unsafe fn $name(fd: $crate::libc::c_int, data: &mut [$ty]) -> $crate::Result<$crate::libc::c_int> { diff --git a/test/sys/test_ioctl.rs b/test/sys/test_ioctl.rs index 38ecdc99..bd275a97 100644 --- a/test/sys/test_ioctl.rs +++ b/test/sys/test_ioctl.rs @@ -22,6 +22,60 @@ ioctl!(write_buf writebuf_test_u32 with 0, 0; u32); ioctl!(write_buf writebuf_test_u64 with 0, 0; u64); ioctl!(readwrite_buf readwritebuf_test with 0, 0; u32); +// Make sure documentation works +ioctl! { + /// This documents the ioctl function + bad none do_bad_docs with 0x1234 +} +ioctl! { + /// This documents the ioctl function + bad read do_bad_read_docs with 0x1234; u16 +} +ioctl! { + /// This documents the ioctl function + bad write_int do_bad_write_int_docs with 0x1234 +} +ioctl! { + /// This documents the ioctl function + bad write_ptr do_bad_write_ptr_docs with 0x1234; u8 +} +ioctl! { + /// This documents the ioctl function + bad readwrite do_bad_readwrite_docs with 0x1234; u32 +} +ioctl! { + /// This documents the ioctl function + none do_none_docs with 0, 0 +} +ioctl! { + /// This documents the ioctl function + read do_read_docs with 0, 0; u32 +} +ioctl! { + /// This documents the ioctl function + write_int do_write_int_docs with 0, 0 +} +ioctl! { + /// This documents the ioctl function + write_ptr do_write_ptr_docs with 0, 0; u32 +} +ioctl! { + /// This documents the ioctl function + readwrite do_readwrite_docs with 0, 0; u32 +} +ioctl! { + /// This documents the ioctl function + read_buf do_read_buf_docs with 0, 0; u32 +} +ioctl! { + /// This documents the ioctl function + write_buf do_write_buf_docs with 0, 0; u32 +} +ioctl! { + /// This documents the ioctl function + readwrite_buf do_readwrite_buf_docs with 0, 0; u32 +} + // See C code for source of values for op calculations (does NOT work for mips/powerpc): // https://gist.github.com/posborne/83ea6880770a1aef332e // -- cgit v1.2.3