13da5c369Sopenharmony_ci//! Provide helpers for making ioctl system calls. 23da5c369Sopenharmony_ci//! 33da5c369Sopenharmony_ci//! This library is pretty low-level and messy. `ioctl` is not fun. 43da5c369Sopenharmony_ci//! 53da5c369Sopenharmony_ci//! What is an `ioctl`? 63da5c369Sopenharmony_ci//! =================== 73da5c369Sopenharmony_ci//! 83da5c369Sopenharmony_ci//! The `ioctl` syscall is the grab-bag syscall on POSIX systems. Don't want to add a new 93da5c369Sopenharmony_ci//! syscall? Make it an `ioctl`! `ioctl` refers to both the syscall, and the commands that can be 103da5c369Sopenharmony_ci//! sent with it. `ioctl` stands for "IO control", and the commands are always sent to a file 113da5c369Sopenharmony_ci//! descriptor. 123da5c369Sopenharmony_ci//! 133da5c369Sopenharmony_ci//! It is common to see `ioctl`s used for the following purposes: 143da5c369Sopenharmony_ci//! 153da5c369Sopenharmony_ci//! * Provide read/write access to out-of-band data related to a device such as configuration 163da5c369Sopenharmony_ci//! (for instance, setting serial port options) 173da5c369Sopenharmony_ci//! * Provide a mechanism for performing full-duplex data transfers (for instance, xfer on SPI 183da5c369Sopenharmony_ci//! devices). 193da5c369Sopenharmony_ci//! * Provide access to control functions on a device (for example, on Linux you can send 203da5c369Sopenharmony_ci//! commands like pause, resume, and eject to the CDROM device. 213da5c369Sopenharmony_ci//! * Do whatever else the device driver creator thought made most sense. 223da5c369Sopenharmony_ci//! 233da5c369Sopenharmony_ci//! `ioctl`s are synchronous system calls and are similar to read and write calls in that regard. 243da5c369Sopenharmony_ci//! They operate on file descriptors and have an identifier that specifies what the ioctl is. 253da5c369Sopenharmony_ci//! Additionally they may read or write data and therefore need to pass along a data pointer. 263da5c369Sopenharmony_ci//! Besides the semantics of the ioctls being confusing, the generation of this identifer can also 273da5c369Sopenharmony_ci//! be difficult. 283da5c369Sopenharmony_ci//! 293da5c369Sopenharmony_ci//! Historically `ioctl` numbers were arbitrary hard-coded values. In Linux (before 2.6) and some 303da5c369Sopenharmony_ci//! unices this has changed to a more-ordered system where the ioctl numbers are partitioned into 313da5c369Sopenharmony_ci//! subcomponents (For linux this is documented in 323da5c369Sopenharmony_ci//! [`Documentation/ioctl/ioctl-number.rst`](https://elixir.bootlin.com/linux/latest/source/Documentation/userspace-api/ioctl/ioctl-number.rst)): 333da5c369Sopenharmony_ci//! 343da5c369Sopenharmony_ci//! * Number: The actual ioctl ID 353da5c369Sopenharmony_ci//! * Type: A grouping of ioctls for a common purpose or driver 363da5c369Sopenharmony_ci//! * Size: The size in bytes of the data that will be transferred 373da5c369Sopenharmony_ci//! * Direction: Whether there is any data and if it's read, write, or both 383da5c369Sopenharmony_ci//! 393da5c369Sopenharmony_ci//! Newer drivers should not generate complete integer identifiers for their `ioctl`s instead 403da5c369Sopenharmony_ci//! preferring to use the 4 components above to generate the final ioctl identifier. Because of 413da5c369Sopenharmony_ci//! how old `ioctl`s are, however, there are many hard-coded `ioctl` identifiers. These are 423da5c369Sopenharmony_ci//! commonly referred to as "bad" in `ioctl` documentation. 433da5c369Sopenharmony_ci//! 443da5c369Sopenharmony_ci//! Defining `ioctl`s 453da5c369Sopenharmony_ci//! ================= 463da5c369Sopenharmony_ci//! 473da5c369Sopenharmony_ci//! This library provides several `ioctl_*!` macros for binding `ioctl`s. These generate public 483da5c369Sopenharmony_ci//! unsafe functions that can then be used for calling the ioctl. This macro has a few different 493da5c369Sopenharmony_ci//! ways it can be used depending on the specific ioctl you're working with. 503da5c369Sopenharmony_ci//! 513da5c369Sopenharmony_ci//! A simple `ioctl` is `SPI_IOC_RD_MODE`. This ioctl works with the SPI interface on Linux. This 523da5c369Sopenharmony_ci//! specific `ioctl` reads the mode of the SPI device as a `u8`. It's declared in 533da5c369Sopenharmony_ci//! `/include/uapi/linux/spi/spidev.h` as `_IOR(SPI_IOC_MAGIC, 1, __u8)`. Since it uses the `_IOR` 543da5c369Sopenharmony_ci//! macro, we know it's a `read` ioctl and can use the `ioctl_read!` macro as follows: 553da5c369Sopenharmony_ci//! 563da5c369Sopenharmony_ci//! ``` 573da5c369Sopenharmony_ci//! # #[macro_use] extern crate nix; 583da5c369Sopenharmony_ci//! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h 593da5c369Sopenharmony_ci//! const SPI_IOC_TYPE_MODE: u8 = 1; 603da5c369Sopenharmony_ci//! ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8); 613da5c369Sopenharmony_ci//! # fn main() {} 623da5c369Sopenharmony_ci//! ``` 633da5c369Sopenharmony_ci//! 643da5c369Sopenharmony_ci//! This generates the function: 653da5c369Sopenharmony_ci//! 663da5c369Sopenharmony_ci//! ``` 673da5c369Sopenharmony_ci//! # #[macro_use] extern crate nix; 683da5c369Sopenharmony_ci//! # use std::mem; 693da5c369Sopenharmony_ci//! # use nix::{libc, Result}; 703da5c369Sopenharmony_ci//! # use nix::errno::Errno; 713da5c369Sopenharmony_ci//! # use nix::libc::c_int as c_int; 723da5c369Sopenharmony_ci//! # const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h 733da5c369Sopenharmony_ci//! # const SPI_IOC_TYPE_MODE: u8 = 1; 743da5c369Sopenharmony_ci//! pub unsafe fn spi_read_mode(fd: c_int, data: *mut u8) -> Result<c_int> { 753da5c369Sopenharmony_ci//! let res = libc::ioctl(fd, request_code_read!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, mem::size_of::<u8>()), data); 763da5c369Sopenharmony_ci//! Errno::result(res) 773da5c369Sopenharmony_ci//! } 783da5c369Sopenharmony_ci//! # fn main() {} 793da5c369Sopenharmony_ci//! ``` 803da5c369Sopenharmony_ci//! 813da5c369Sopenharmony_ci//! The return value for the wrapper functions generated by the `ioctl_*!` macros are `nix::Error`s. 823da5c369Sopenharmony_ci//! These are generated by assuming the return value of the ioctl is `-1` on error and everything 833da5c369Sopenharmony_ci//! else is a valid return value. If this is not the case, `Result::map` can be used to map some 843da5c369Sopenharmony_ci//! of the range of "good" values (-Inf..-2, 0..Inf) into a smaller range in a helper function. 853da5c369Sopenharmony_ci//! 863da5c369Sopenharmony_ci//! Writing `ioctl`s generally use pointers as their data source and these should use the 873da5c369Sopenharmony_ci//! `ioctl_write_ptr!`. But in some cases an `int` is passed directly. For these `ioctl`s use the 883da5c369Sopenharmony_ci//! `ioctl_write_int!` macro. This variant does not take a type as the last argument: 893da5c369Sopenharmony_ci//! 903da5c369Sopenharmony_ci//! ``` 913da5c369Sopenharmony_ci//! # #[macro_use] extern crate nix; 923da5c369Sopenharmony_ci//! const HCI_IOC_MAGIC: u8 = b'k'; 933da5c369Sopenharmony_ci//! const HCI_IOC_HCIDEVUP: u8 = 1; 943da5c369Sopenharmony_ci//! ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP); 953da5c369Sopenharmony_ci//! # fn main() {} 963da5c369Sopenharmony_ci//! ``` 973da5c369Sopenharmony_ci//! 983da5c369Sopenharmony_ci//! Some `ioctl`s don't transfer any data, and those should use `ioctl_none!`. This macro 993da5c369Sopenharmony_ci//! doesn't take a type and so it is declared similar to the `write_int` variant shown above. 1003da5c369Sopenharmony_ci//! 1013da5c369Sopenharmony_ci//! The mode for a given `ioctl` should be clear from the documentation if it has good 1023da5c369Sopenharmony_ci//! documentation. Otherwise it will be clear based on the macro used to generate the `ioctl` 1033da5c369Sopenharmony_ci//! number where `_IO`, `_IOR`, `_IOW`, and `_IOWR` map to "none", "read", "write_*", and "readwrite" 1043da5c369Sopenharmony_ci//! respectively. To determine the specific `write_` variant to use you'll need to find 1053da5c369Sopenharmony_ci//! what the argument type is supposed to be. If it's an `int`, then `write_int` should be used, 1063da5c369Sopenharmony_ci//! otherwise it should be a pointer and `write_ptr` should be used. On Linux the 1073da5c369Sopenharmony_ci//! [`ioctl_list` man page](https://man7.org/linux/man-pages/man2/ioctl_list.2.html) describes a 1083da5c369Sopenharmony_ci//! large number of `ioctl`s and describes their argument data type. 1093da5c369Sopenharmony_ci//! 1103da5c369Sopenharmony_ci//! Using "bad" `ioctl`s 1113da5c369Sopenharmony_ci//! -------------------- 1123da5c369Sopenharmony_ci//! 1133da5c369Sopenharmony_ci//! As mentioned earlier, there are many old `ioctl`s that do not use the newer method of 1143da5c369Sopenharmony_ci//! generating `ioctl` numbers and instead use hardcoded values. These can be used with the 1153da5c369Sopenharmony_ci//! `ioctl_*_bad!` macros. This naming comes from the Linux kernel which refers to these 1163da5c369Sopenharmony_ci//! `ioctl`s as "bad". These are a different variant as they bypass calling the macro that generates 1173da5c369Sopenharmony_ci//! the ioctl number and instead use the defined value directly. 1183da5c369Sopenharmony_ci//! 1193da5c369Sopenharmony_ci//! For example the `TCGETS` `ioctl` reads a `termios` data structure for a given file descriptor. 1203da5c369Sopenharmony_ci//! It's defined as `0x5401` in `ioctls.h` on Linux and can be implemented as: 1213da5c369Sopenharmony_ci//! 1223da5c369Sopenharmony_ci//! ``` 1233da5c369Sopenharmony_ci//! # #[macro_use] extern crate nix; 1243da5c369Sopenharmony_ci//! # #[cfg(any(target_os = "android", target_os = "linux"))] 1253da5c369Sopenharmony_ci//! # use nix::libc::TCGETS as TCGETS; 1263da5c369Sopenharmony_ci//! # #[cfg(any(target_os = "android", target_os = "linux"))] 1273da5c369Sopenharmony_ci//! # use nix::libc::termios as termios; 1283da5c369Sopenharmony_ci//! # #[cfg(any(target_os = "android", target_os = "linux"))] 1293da5c369Sopenharmony_ci//! ioctl_read_bad!(tcgets, TCGETS, termios); 1303da5c369Sopenharmony_ci//! # fn main() {} 1313da5c369Sopenharmony_ci//! ``` 1323da5c369Sopenharmony_ci//! 1333da5c369Sopenharmony_ci//! The generated function has the same form as that generated by `ioctl_read!`: 1343da5c369Sopenharmony_ci//! 1353da5c369Sopenharmony_ci//! ```text 1363da5c369Sopenharmony_ci//! pub unsafe fn tcgets(fd: c_int, data: *mut termios) -> Result<c_int>; 1373da5c369Sopenharmony_ci//! ``` 1383da5c369Sopenharmony_ci//! 1393da5c369Sopenharmony_ci//! Working with Arrays 1403da5c369Sopenharmony_ci//! ------------------- 1413da5c369Sopenharmony_ci//! 1423da5c369Sopenharmony_ci//! Some `ioctl`s work with entire arrays of elements. These are supported by the `ioctl_*_buf` 1433da5c369Sopenharmony_ci//! family of macros: `ioctl_read_buf`, `ioctl_write_buf`, and `ioctl_readwrite_buf`. Note that 1443da5c369Sopenharmony_ci//! there are no "bad" versions for working with buffers. The generated functions include a `len` 1453da5c369Sopenharmony_ci//! argument to specify the number of elements (where the type of each element is specified in the 1463da5c369Sopenharmony_ci//! macro). 1473da5c369Sopenharmony_ci//! 1483da5c369Sopenharmony_ci//! Again looking to the SPI `ioctl`s on Linux for an example, there is a `SPI_IOC_MESSAGE` `ioctl` 1493da5c369Sopenharmony_ci//! that queues up multiple SPI messages by writing an entire array of `spi_ioc_transfer` structs. 1503da5c369Sopenharmony_ci//! `linux/spi/spidev.h` defines a macro to calculate the `ioctl` number like: 1513da5c369Sopenharmony_ci//! 1523da5c369Sopenharmony_ci//! ```C 1533da5c369Sopenharmony_ci//! #define SPI_IOC_MAGIC 'k' 1543da5c369Sopenharmony_ci//! #define SPI_MSGSIZE(N) ... 1553da5c369Sopenharmony_ci//! #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)]) 1563da5c369Sopenharmony_ci//! ``` 1573da5c369Sopenharmony_ci//! 1583da5c369Sopenharmony_ci//! The `SPI_MSGSIZE(N)` calculation is already handled by the `ioctl_*!` macros, so all that's 1593da5c369Sopenharmony_ci//! needed to define this `ioctl` is: 1603da5c369Sopenharmony_ci//! 1613da5c369Sopenharmony_ci//! ``` 1623da5c369Sopenharmony_ci//! # #[macro_use] extern crate nix; 1633da5c369Sopenharmony_ci//! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h 1643da5c369Sopenharmony_ci//! const SPI_IOC_TYPE_MESSAGE: u8 = 0; 1653da5c369Sopenharmony_ci//! # pub struct spi_ioc_transfer(u64); 1663da5c369Sopenharmony_ci//! ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer); 1673da5c369Sopenharmony_ci//! # fn main() {} 1683da5c369Sopenharmony_ci//! ``` 1693da5c369Sopenharmony_ci//! 1703da5c369Sopenharmony_ci//! This generates a function like: 1713da5c369Sopenharmony_ci//! 1723da5c369Sopenharmony_ci//! ``` 1733da5c369Sopenharmony_ci//! # #[macro_use] extern crate nix; 1743da5c369Sopenharmony_ci//! # use std::mem; 1753da5c369Sopenharmony_ci//! # use nix::{libc, Result}; 1763da5c369Sopenharmony_ci//! # use nix::errno::Errno; 1773da5c369Sopenharmony_ci//! # use nix::libc::c_int as c_int; 1783da5c369Sopenharmony_ci//! # const SPI_IOC_MAGIC: u8 = b'k'; 1793da5c369Sopenharmony_ci//! # const SPI_IOC_TYPE_MESSAGE: u8 = 0; 1803da5c369Sopenharmony_ci//! # pub struct spi_ioc_transfer(u64); 1813da5c369Sopenharmony_ci//! pub unsafe fn spi_message(fd: c_int, data: &mut [spi_ioc_transfer]) -> Result<c_int> { 1823da5c369Sopenharmony_ci//! let res = libc::ioctl(fd, 1833da5c369Sopenharmony_ci//! request_code_write!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, data.len() * mem::size_of::<spi_ioc_transfer>()), 1843da5c369Sopenharmony_ci//! data); 1853da5c369Sopenharmony_ci//! Errno::result(res) 1863da5c369Sopenharmony_ci//! } 1873da5c369Sopenharmony_ci//! # fn main() {} 1883da5c369Sopenharmony_ci//! ``` 1893da5c369Sopenharmony_ci//! 1903da5c369Sopenharmony_ci//! Finding `ioctl` Documentation 1913da5c369Sopenharmony_ci//! ----------------------------- 1923da5c369Sopenharmony_ci//! 1933da5c369Sopenharmony_ci//! For Linux, look at your system's headers. For example, `/usr/include/linux/input.h` has a lot 1943da5c369Sopenharmony_ci//! of lines defining macros which use `_IO`, `_IOR`, `_IOW`, `_IOC`, and `_IOWR`. Some `ioctl`s are 1953da5c369Sopenharmony_ci//! documented directly in the headers defining their constants, but others have more extensive 1963da5c369Sopenharmony_ci//! documentation in man pages (like termios' `ioctl`s which are in `tty_ioctl(4)`). 1973da5c369Sopenharmony_ci//! 1983da5c369Sopenharmony_ci//! Documenting the Generated Functions 1993da5c369Sopenharmony_ci//! =================================== 2003da5c369Sopenharmony_ci//! 2013da5c369Sopenharmony_ci//! In many cases, users will wish for the functions generated by the `ioctl` 2023da5c369Sopenharmony_ci//! macro to be public and documented. For this reason, the generated functions 2033da5c369Sopenharmony_ci//! are public by default. If you wish to hide the ioctl, you will need to put 2043da5c369Sopenharmony_ci//! them in a private module. 2053da5c369Sopenharmony_ci//! 2063da5c369Sopenharmony_ci//! For documentation, it is possible to use doc comments inside the `ioctl_*!` macros. Here is an 2073da5c369Sopenharmony_ci//! example : 2083da5c369Sopenharmony_ci//! 2093da5c369Sopenharmony_ci//! ``` 2103da5c369Sopenharmony_ci//! # #[macro_use] extern crate nix; 2113da5c369Sopenharmony_ci//! # use nix::libc::c_int; 2123da5c369Sopenharmony_ci//! ioctl_read! { 2133da5c369Sopenharmony_ci//! /// Make the given terminal the controlling terminal of the calling process. The calling 2143da5c369Sopenharmony_ci//! /// process must be a session leader and not have a controlling terminal already. If the 2153da5c369Sopenharmony_ci//! /// terminal is already the controlling terminal of a different session group then the 2163da5c369Sopenharmony_ci//! /// ioctl will fail with **EPERM**, unless the caller is root (more precisely: has the 2173da5c369Sopenharmony_ci//! /// **CAP_SYS_ADMIN** capability) and arg equals 1, in which case the terminal is stolen 2183da5c369Sopenharmony_ci//! /// and all processes that had it as controlling terminal lose it. 2193da5c369Sopenharmony_ci//! tiocsctty, b't', 19, c_int 2203da5c369Sopenharmony_ci//! } 2213da5c369Sopenharmony_ci//! 2223da5c369Sopenharmony_ci//! # fn main() {} 2233da5c369Sopenharmony_ci//! ``` 2243da5c369Sopenharmony_ciuse cfg_if::cfg_if; 2253da5c369Sopenharmony_ci 2263da5c369Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))] 2273da5c369Sopenharmony_ci#[macro_use] 2283da5c369Sopenharmony_cimod linux; 2293da5c369Sopenharmony_ci 2303da5c369Sopenharmony_ci#[cfg(any( 2313da5c369Sopenharmony_ci target_os = "android", 2323da5c369Sopenharmony_ci target_os = "linux", 2333da5c369Sopenharmony_ci target_os = "redox" 2343da5c369Sopenharmony_ci))] 2353da5c369Sopenharmony_cipub use self::linux::*; 2363da5c369Sopenharmony_ci 2373da5c369Sopenharmony_ci#[cfg(any( 2383da5c369Sopenharmony_ci target_os = "dragonfly", 2393da5c369Sopenharmony_ci target_os = "freebsd", 2403da5c369Sopenharmony_ci target_os = "illumos", 2413da5c369Sopenharmony_ci target_os = "ios", 2423da5c369Sopenharmony_ci target_os = "macos", 2433da5c369Sopenharmony_ci target_os = "netbsd", 2443da5c369Sopenharmony_ci target_os = "haiku", 2453da5c369Sopenharmony_ci target_os = "openbsd" 2463da5c369Sopenharmony_ci))] 2473da5c369Sopenharmony_ci#[macro_use] 2483da5c369Sopenharmony_cimod bsd; 2493da5c369Sopenharmony_ci 2503da5c369Sopenharmony_ci#[cfg(any( 2513da5c369Sopenharmony_ci target_os = "dragonfly", 2523da5c369Sopenharmony_ci target_os = "freebsd", 2533da5c369Sopenharmony_ci target_os = "illumos", 2543da5c369Sopenharmony_ci target_os = "ios", 2553da5c369Sopenharmony_ci target_os = "macos", 2563da5c369Sopenharmony_ci target_os = "netbsd", 2573da5c369Sopenharmony_ci target_os = "haiku", 2583da5c369Sopenharmony_ci target_os = "openbsd" 2593da5c369Sopenharmony_ci))] 2603da5c369Sopenharmony_cipub use self::bsd::*; 2613da5c369Sopenharmony_ci 2623da5c369Sopenharmony_ci/// Convert raw ioctl return value to a Nix result 2633da5c369Sopenharmony_ci#[macro_export] 2643da5c369Sopenharmony_ci#[doc(hidden)] 2653da5c369Sopenharmony_cimacro_rules! convert_ioctl_res { 2663da5c369Sopenharmony_ci ($w:expr) => {{ 2673da5c369Sopenharmony_ci $crate::errno::Errno::result($w) 2683da5c369Sopenharmony_ci }}; 2693da5c369Sopenharmony_ci} 2703da5c369Sopenharmony_ci 2713da5c369Sopenharmony_ci/// Generates a wrapper function for an ioctl that passes no data to the kernel. 2723da5c369Sopenharmony_ci/// 2733da5c369Sopenharmony_ci/// The arguments to this macro are: 2743da5c369Sopenharmony_ci/// 2753da5c369Sopenharmony_ci/// * The function name 2763da5c369Sopenharmony_ci/// * The ioctl identifier 2773da5c369Sopenharmony_ci/// * The ioctl sequence number 2783da5c369Sopenharmony_ci/// 2793da5c369Sopenharmony_ci/// The generated function has the following signature: 2803da5c369Sopenharmony_ci/// 2813da5c369Sopenharmony_ci/// ```rust,ignore 2823da5c369Sopenharmony_ci/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int> 2833da5c369Sopenharmony_ci/// ``` 2843da5c369Sopenharmony_ci/// 2853da5c369Sopenharmony_ci/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 2863da5c369Sopenharmony_ci/// 2873da5c369Sopenharmony_ci/// # Example 2883da5c369Sopenharmony_ci/// 2893da5c369Sopenharmony_ci/// The `videodev2` driver on Linux defines the `log_status` `ioctl` as: 2903da5c369Sopenharmony_ci/// 2913da5c369Sopenharmony_ci/// ```C 2923da5c369Sopenharmony_ci/// #define VIDIOC_LOG_STATUS _IO('V', 70) 2933da5c369Sopenharmony_ci/// ``` 2943da5c369Sopenharmony_ci/// 2953da5c369Sopenharmony_ci/// This can be implemented in Rust like: 2963da5c369Sopenharmony_ci/// 2973da5c369Sopenharmony_ci/// ```no_run 2983da5c369Sopenharmony_ci/// # #[macro_use] extern crate nix; 2993da5c369Sopenharmony_ci/// ioctl_none!(log_status, b'V', 70); 3003da5c369Sopenharmony_ci/// fn main() {} 3013da5c369Sopenharmony_ci/// ``` 3023da5c369Sopenharmony_ci#[macro_export(local_inner_macros)] 3033da5c369Sopenharmony_cimacro_rules! ioctl_none { 3043da5c369Sopenharmony_ci ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => ( 3053da5c369Sopenharmony_ci $(#[$attr])* 3063da5c369Sopenharmony_ci pub unsafe fn $name(fd: $crate::libc::c_int) 3073da5c369Sopenharmony_ci -> $crate::Result<$crate::libc::c_int> { 3083da5c369Sopenharmony_ci convert_ioctl_res!($crate::libc::ioctl(fd, request_code_none!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type)) 3093da5c369Sopenharmony_ci } 3103da5c369Sopenharmony_ci ) 3113da5c369Sopenharmony_ci} 3123da5c369Sopenharmony_ci 3133da5c369Sopenharmony_ci/// Generates a wrapper function for a "bad" ioctl that passes no data to the kernel. 3143da5c369Sopenharmony_ci/// 3153da5c369Sopenharmony_ci/// The arguments to this macro are: 3163da5c369Sopenharmony_ci/// 3173da5c369Sopenharmony_ci/// * The function name 3183da5c369Sopenharmony_ci/// * The ioctl request code 3193da5c369Sopenharmony_ci/// 3203da5c369Sopenharmony_ci/// The generated function has the following signature: 3213da5c369Sopenharmony_ci/// 3223da5c369Sopenharmony_ci/// ```rust,ignore 3233da5c369Sopenharmony_ci/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int> 3243da5c369Sopenharmony_ci/// ``` 3253da5c369Sopenharmony_ci/// 3263da5c369Sopenharmony_ci/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 3273da5c369Sopenharmony_ci/// 3283da5c369Sopenharmony_ci/// # Example 3293da5c369Sopenharmony_ci/// 3303da5c369Sopenharmony_ci/// ```no_run 3313da5c369Sopenharmony_ci/// # #[macro_use] extern crate nix; 3323da5c369Sopenharmony_ci/// # use libc::TIOCNXCL; 3333da5c369Sopenharmony_ci/// # use std::fs::File; 3343da5c369Sopenharmony_ci/// # use std::os::unix::io::AsRawFd; 3353da5c369Sopenharmony_ci/// ioctl_none_bad!(tiocnxcl, TIOCNXCL); 3363da5c369Sopenharmony_ci/// fn main() { 3373da5c369Sopenharmony_ci/// let file = File::open("/dev/ttyUSB0").unwrap(); 3383da5c369Sopenharmony_ci/// unsafe { tiocnxcl(file.as_raw_fd()) }.unwrap(); 3393da5c369Sopenharmony_ci/// } 3403da5c369Sopenharmony_ci/// ``` 3413da5c369Sopenharmony_ci// TODO: add an example using request_code_*!() 3423da5c369Sopenharmony_ci#[macro_export(local_inner_macros)] 3433da5c369Sopenharmony_cimacro_rules! ioctl_none_bad { 3443da5c369Sopenharmony_ci ($(#[$attr:meta])* $name:ident, $nr:expr) => ( 3453da5c369Sopenharmony_ci $(#[$attr])* 3463da5c369Sopenharmony_ci pub unsafe fn $name(fd: $crate::libc::c_int) 3473da5c369Sopenharmony_ci -> $crate::Result<$crate::libc::c_int> { 3483da5c369Sopenharmony_ci convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type)) 3493da5c369Sopenharmony_ci } 3503da5c369Sopenharmony_ci ) 3513da5c369Sopenharmony_ci} 3523da5c369Sopenharmony_ci 3533da5c369Sopenharmony_ci/// Generates a wrapper function for an ioctl that reads data from the kernel. 3543da5c369Sopenharmony_ci/// 3553da5c369Sopenharmony_ci/// The arguments to this macro are: 3563da5c369Sopenharmony_ci/// 3573da5c369Sopenharmony_ci/// * The function name 3583da5c369Sopenharmony_ci/// * The ioctl identifier 3593da5c369Sopenharmony_ci/// * The ioctl sequence number 3603da5c369Sopenharmony_ci/// * The data type passed by this ioctl 3613da5c369Sopenharmony_ci/// 3623da5c369Sopenharmony_ci/// The generated function has the following signature: 3633da5c369Sopenharmony_ci/// 3643da5c369Sopenharmony_ci/// ```rust,ignore 3653da5c369Sopenharmony_ci/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int> 3663da5c369Sopenharmony_ci/// ``` 3673da5c369Sopenharmony_ci/// 3683da5c369Sopenharmony_ci/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 3693da5c369Sopenharmony_ci/// 3703da5c369Sopenharmony_ci/// # Example 3713da5c369Sopenharmony_ci/// 3723da5c369Sopenharmony_ci/// ``` 3733da5c369Sopenharmony_ci/// # #[macro_use] extern crate nix; 3743da5c369Sopenharmony_ci/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h 3753da5c369Sopenharmony_ci/// const SPI_IOC_TYPE_MODE: u8 = 1; 3763da5c369Sopenharmony_ci/// ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8); 3773da5c369Sopenharmony_ci/// # fn main() {} 3783da5c369Sopenharmony_ci/// ``` 3793da5c369Sopenharmony_ci#[macro_export(local_inner_macros)] 3803da5c369Sopenharmony_cimacro_rules! ioctl_read { 3813da5c369Sopenharmony_ci ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 3823da5c369Sopenharmony_ci $(#[$attr])* 3833da5c369Sopenharmony_ci pub unsafe fn $name(fd: $crate::libc::c_int, 3843da5c369Sopenharmony_ci data: *mut $ty) 3853da5c369Sopenharmony_ci -> $crate::Result<$crate::libc::c_int> { 3863da5c369Sopenharmony_ci convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) 3873da5c369Sopenharmony_ci } 3883da5c369Sopenharmony_ci ) 3893da5c369Sopenharmony_ci} 3903da5c369Sopenharmony_ci 3913da5c369Sopenharmony_ci/// Generates a wrapper function for a "bad" ioctl that reads data from the kernel. 3923da5c369Sopenharmony_ci/// 3933da5c369Sopenharmony_ci/// The arguments to this macro are: 3943da5c369Sopenharmony_ci/// 3953da5c369Sopenharmony_ci/// * The function name 3963da5c369Sopenharmony_ci/// * The ioctl request code 3973da5c369Sopenharmony_ci/// * The data type passed by this ioctl 3983da5c369Sopenharmony_ci/// 3993da5c369Sopenharmony_ci/// The generated function has the following signature: 4003da5c369Sopenharmony_ci/// 4013da5c369Sopenharmony_ci/// ```rust,ignore 4023da5c369Sopenharmony_ci/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int> 4033da5c369Sopenharmony_ci/// ``` 4043da5c369Sopenharmony_ci/// 4053da5c369Sopenharmony_ci/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 4063da5c369Sopenharmony_ci/// 4073da5c369Sopenharmony_ci/// # Example 4083da5c369Sopenharmony_ci/// 4093da5c369Sopenharmony_ci/// ``` 4103da5c369Sopenharmony_ci/// # #[macro_use] extern crate nix; 4113da5c369Sopenharmony_ci/// # #[cfg(any(target_os = "android", target_os = "linux"))] 4123da5c369Sopenharmony_ci/// ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios); 4133da5c369Sopenharmony_ci/// # fn main() {} 4143da5c369Sopenharmony_ci/// ``` 4153da5c369Sopenharmony_ci#[macro_export(local_inner_macros)] 4163da5c369Sopenharmony_cimacro_rules! ioctl_read_bad { 4173da5c369Sopenharmony_ci ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => ( 4183da5c369Sopenharmony_ci $(#[$attr])* 4193da5c369Sopenharmony_ci pub unsafe fn $name(fd: $crate::libc::c_int, 4203da5c369Sopenharmony_ci data: *mut $ty) 4213da5c369Sopenharmony_ci -> $crate::Result<$crate::libc::c_int> { 4223da5c369Sopenharmony_ci convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) 4233da5c369Sopenharmony_ci } 4243da5c369Sopenharmony_ci ) 4253da5c369Sopenharmony_ci} 4263da5c369Sopenharmony_ci 4273da5c369Sopenharmony_ci/// Generates a wrapper function for an ioctl that writes data through a pointer to the kernel. 4283da5c369Sopenharmony_ci/// 4293da5c369Sopenharmony_ci/// The arguments to this macro are: 4303da5c369Sopenharmony_ci/// 4313da5c369Sopenharmony_ci/// * The function name 4323da5c369Sopenharmony_ci/// * The ioctl identifier 4333da5c369Sopenharmony_ci/// * The ioctl sequence number 4343da5c369Sopenharmony_ci/// * The data type passed by this ioctl 4353da5c369Sopenharmony_ci/// 4363da5c369Sopenharmony_ci/// The generated function has the following signature: 4373da5c369Sopenharmony_ci/// 4383da5c369Sopenharmony_ci/// ```rust,ignore 4393da5c369Sopenharmony_ci/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int> 4403da5c369Sopenharmony_ci/// ``` 4413da5c369Sopenharmony_ci/// 4423da5c369Sopenharmony_ci/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 4433da5c369Sopenharmony_ci/// 4443da5c369Sopenharmony_ci/// # Example 4453da5c369Sopenharmony_ci/// 4463da5c369Sopenharmony_ci/// ``` 4473da5c369Sopenharmony_ci/// # #[macro_use] extern crate nix; 4483da5c369Sopenharmony_ci/// # pub struct v4l2_audio {} 4493da5c369Sopenharmony_ci/// ioctl_write_ptr!(s_audio, b'V', 34, v4l2_audio); 4503da5c369Sopenharmony_ci/// # fn main() {} 4513da5c369Sopenharmony_ci/// ``` 4523da5c369Sopenharmony_ci#[macro_export(local_inner_macros)] 4533da5c369Sopenharmony_cimacro_rules! ioctl_write_ptr { 4543da5c369Sopenharmony_ci ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 4553da5c369Sopenharmony_ci $(#[$attr])* 4563da5c369Sopenharmony_ci pub unsafe fn $name(fd: $crate::libc::c_int, 4573da5c369Sopenharmony_ci data: *const $ty) 4583da5c369Sopenharmony_ci -> $crate::Result<$crate::libc::c_int> { 4593da5c369Sopenharmony_ci convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) 4603da5c369Sopenharmony_ci } 4613da5c369Sopenharmony_ci ) 4623da5c369Sopenharmony_ci} 4633da5c369Sopenharmony_ci 4643da5c369Sopenharmony_ci/// Generates a wrapper function for a "bad" ioctl that writes data through a pointer to the kernel. 4653da5c369Sopenharmony_ci/// 4663da5c369Sopenharmony_ci/// The arguments to this macro are: 4673da5c369Sopenharmony_ci/// 4683da5c369Sopenharmony_ci/// * The function name 4693da5c369Sopenharmony_ci/// * The ioctl request code 4703da5c369Sopenharmony_ci/// * The data type passed by this ioctl 4713da5c369Sopenharmony_ci/// 4723da5c369Sopenharmony_ci/// The generated function has the following signature: 4733da5c369Sopenharmony_ci/// 4743da5c369Sopenharmony_ci/// ```rust,ignore 4753da5c369Sopenharmony_ci/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int> 4763da5c369Sopenharmony_ci/// ``` 4773da5c369Sopenharmony_ci/// 4783da5c369Sopenharmony_ci/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 4793da5c369Sopenharmony_ci/// 4803da5c369Sopenharmony_ci/// # Example 4813da5c369Sopenharmony_ci/// 4823da5c369Sopenharmony_ci/// ``` 4833da5c369Sopenharmony_ci/// # #[macro_use] extern crate nix; 4843da5c369Sopenharmony_ci/// # #[cfg(any(target_os = "android", target_os = "linux"))] 4853da5c369Sopenharmony_ci/// ioctl_write_ptr_bad!(tcsets, libc::TCSETS, libc::termios); 4863da5c369Sopenharmony_ci/// # fn main() {} 4873da5c369Sopenharmony_ci/// ``` 4883da5c369Sopenharmony_ci#[macro_export(local_inner_macros)] 4893da5c369Sopenharmony_cimacro_rules! ioctl_write_ptr_bad { 4903da5c369Sopenharmony_ci ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => ( 4913da5c369Sopenharmony_ci $(#[$attr])* 4923da5c369Sopenharmony_ci pub unsafe fn $name(fd: $crate::libc::c_int, 4933da5c369Sopenharmony_ci data: *const $ty) 4943da5c369Sopenharmony_ci -> $crate::Result<$crate::libc::c_int> { 4953da5c369Sopenharmony_ci convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) 4963da5c369Sopenharmony_ci } 4973da5c369Sopenharmony_ci ) 4983da5c369Sopenharmony_ci} 4993da5c369Sopenharmony_ci 5003da5c369Sopenharmony_cicfg_if! { 5013da5c369Sopenharmony_ci if #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] { 5023da5c369Sopenharmony_ci /// Generates a wrapper function for a ioctl that writes an integer to the kernel. 5033da5c369Sopenharmony_ci /// 5043da5c369Sopenharmony_ci /// The arguments to this macro are: 5053da5c369Sopenharmony_ci /// 5063da5c369Sopenharmony_ci /// * The function name 5073da5c369Sopenharmony_ci /// * The ioctl identifier 5083da5c369Sopenharmony_ci /// * The ioctl sequence number 5093da5c369Sopenharmony_ci /// 5103da5c369Sopenharmony_ci /// The generated function has the following signature: 5113da5c369Sopenharmony_ci /// 5123da5c369Sopenharmony_ci /// ```rust,ignore 5133da5c369Sopenharmony_ci /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int> 5143da5c369Sopenharmony_ci /// ``` 5153da5c369Sopenharmony_ci /// 5163da5c369Sopenharmony_ci /// `nix::sys::ioctl::ioctl_param_type` depends on the OS: 5173da5c369Sopenharmony_ci /// * BSD - `libc::c_int` 5183da5c369Sopenharmony_ci /// * Linux - `libc::c_ulong` 5193da5c369Sopenharmony_ci /// 5203da5c369Sopenharmony_ci /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 5213da5c369Sopenharmony_ci /// 5223da5c369Sopenharmony_ci /// # Example 5233da5c369Sopenharmony_ci /// 5243da5c369Sopenharmony_ci /// ``` 5253da5c369Sopenharmony_ci /// # #[macro_use] extern crate nix; 5263da5c369Sopenharmony_ci /// ioctl_write_int!(vt_activate, b'v', 4); 5273da5c369Sopenharmony_ci /// # fn main() {} 5283da5c369Sopenharmony_ci /// ``` 5293da5c369Sopenharmony_ci #[macro_export(local_inner_macros)] 5303da5c369Sopenharmony_ci macro_rules! ioctl_write_int { 5313da5c369Sopenharmony_ci ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => ( 5323da5c369Sopenharmony_ci $(#[$attr])* 5333da5c369Sopenharmony_ci pub unsafe fn $name(fd: $crate::libc::c_int, 5343da5c369Sopenharmony_ci data: $crate::sys::ioctl::ioctl_param_type) 5353da5c369Sopenharmony_ci -> $crate::Result<$crate::libc::c_int> { 5363da5c369Sopenharmony_ci convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write_int!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type, data)) 5373da5c369Sopenharmony_ci } 5383da5c369Sopenharmony_ci ) 5393da5c369Sopenharmony_ci } 5403da5c369Sopenharmony_ci } else { 5413da5c369Sopenharmony_ci /// Generates a wrapper function for a ioctl that writes an integer to the kernel. 5423da5c369Sopenharmony_ci /// 5433da5c369Sopenharmony_ci /// The arguments to this macro are: 5443da5c369Sopenharmony_ci /// 5453da5c369Sopenharmony_ci /// * The function name 5463da5c369Sopenharmony_ci /// * The ioctl identifier 5473da5c369Sopenharmony_ci /// * The ioctl sequence number 5483da5c369Sopenharmony_ci /// 5493da5c369Sopenharmony_ci /// The generated function has the following signature: 5503da5c369Sopenharmony_ci /// 5513da5c369Sopenharmony_ci /// ```rust,ignore 5523da5c369Sopenharmony_ci /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int> 5533da5c369Sopenharmony_ci /// ``` 5543da5c369Sopenharmony_ci /// 5553da5c369Sopenharmony_ci /// `nix::sys::ioctl::ioctl_param_type` depends on the OS: 5563da5c369Sopenharmony_ci /// * BSD - `libc::c_int` 5573da5c369Sopenharmony_ci /// * Linux - `libc::c_ulong` 5583da5c369Sopenharmony_ci /// 5593da5c369Sopenharmony_ci /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 5603da5c369Sopenharmony_ci /// 5613da5c369Sopenharmony_ci /// # Example 5623da5c369Sopenharmony_ci /// 5633da5c369Sopenharmony_ci /// ``` 5643da5c369Sopenharmony_ci /// # #[macro_use] extern crate nix; 5653da5c369Sopenharmony_ci /// const HCI_IOC_MAGIC: u8 = b'k'; 5663da5c369Sopenharmony_ci /// const HCI_IOC_HCIDEVUP: u8 = 1; 5673da5c369Sopenharmony_ci /// ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP); 5683da5c369Sopenharmony_ci /// # fn main() {} 5693da5c369Sopenharmony_ci /// ``` 5703da5c369Sopenharmony_ci #[macro_export(local_inner_macros)] 5713da5c369Sopenharmony_ci macro_rules! ioctl_write_int { 5723da5c369Sopenharmony_ci ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => ( 5733da5c369Sopenharmony_ci $(#[$attr])* 5743da5c369Sopenharmony_ci pub unsafe fn $name(fd: $crate::libc::c_int, 5753da5c369Sopenharmony_ci data: $crate::sys::ioctl::ioctl_param_type) 5763da5c369Sopenharmony_ci -> $crate::Result<$crate::libc::c_int> { 5773da5c369Sopenharmony_ci convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of::<$crate::libc::c_int>()) as $crate::sys::ioctl::ioctl_num_type, data)) 5783da5c369Sopenharmony_ci } 5793da5c369Sopenharmony_ci ) 5803da5c369Sopenharmony_ci } 5813da5c369Sopenharmony_ci } 5823da5c369Sopenharmony_ci} 5833da5c369Sopenharmony_ci 5843da5c369Sopenharmony_ci/// Generates a wrapper function for a "bad" ioctl that writes an integer to the kernel. 5853da5c369Sopenharmony_ci/// 5863da5c369Sopenharmony_ci/// The arguments to this macro are: 5873da5c369Sopenharmony_ci/// 5883da5c369Sopenharmony_ci/// * The function name 5893da5c369Sopenharmony_ci/// * The ioctl request code 5903da5c369Sopenharmony_ci/// 5913da5c369Sopenharmony_ci/// The generated function has the following signature: 5923da5c369Sopenharmony_ci/// 5933da5c369Sopenharmony_ci/// ```rust,ignore 5943da5c369Sopenharmony_ci/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: libc::c_int) -> Result<libc::c_int> 5953da5c369Sopenharmony_ci/// ``` 5963da5c369Sopenharmony_ci/// 5973da5c369Sopenharmony_ci/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 5983da5c369Sopenharmony_ci/// 5993da5c369Sopenharmony_ci/// # Examples 6003da5c369Sopenharmony_ci/// 6013da5c369Sopenharmony_ci/// ``` 6023da5c369Sopenharmony_ci/// # #[macro_use] extern crate nix; 6033da5c369Sopenharmony_ci/// # #[cfg(any(target_os = "android", target_os = "linux"))] 6043da5c369Sopenharmony_ci/// ioctl_write_int_bad!(tcsbrk, libc::TCSBRK); 6053da5c369Sopenharmony_ci/// # fn main() {} 6063da5c369Sopenharmony_ci/// ``` 6073da5c369Sopenharmony_ci/// 6083da5c369Sopenharmony_ci/// ```rust 6093da5c369Sopenharmony_ci/// # #[macro_use] extern crate nix; 6103da5c369Sopenharmony_ci/// const KVMIO: u8 = 0xAE; 6113da5c369Sopenharmony_ci/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03)); 6123da5c369Sopenharmony_ci/// # fn main() {} 6133da5c369Sopenharmony_ci/// ``` 6143da5c369Sopenharmony_ci#[macro_export(local_inner_macros)] 6153da5c369Sopenharmony_cimacro_rules! ioctl_write_int_bad { 6163da5c369Sopenharmony_ci ($(#[$attr:meta])* $name:ident, $nr:expr) => ( 6173da5c369Sopenharmony_ci $(#[$attr])* 6183da5c369Sopenharmony_ci pub unsafe fn $name(fd: $crate::libc::c_int, 6193da5c369Sopenharmony_ci data: $crate::libc::c_int) 6203da5c369Sopenharmony_ci -> $crate::Result<$crate::libc::c_int> { 6213da5c369Sopenharmony_ci convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) 6223da5c369Sopenharmony_ci } 6233da5c369Sopenharmony_ci ) 6243da5c369Sopenharmony_ci} 6253da5c369Sopenharmony_ci 6263da5c369Sopenharmony_ci/// Generates a wrapper function for an ioctl that reads and writes data to the kernel. 6273da5c369Sopenharmony_ci/// 6283da5c369Sopenharmony_ci/// The arguments to this macro are: 6293da5c369Sopenharmony_ci/// 6303da5c369Sopenharmony_ci/// * The function name 6313da5c369Sopenharmony_ci/// * The ioctl identifier 6323da5c369Sopenharmony_ci/// * The ioctl sequence number 6333da5c369Sopenharmony_ci/// * The data type passed by this ioctl 6343da5c369Sopenharmony_ci/// 6353da5c369Sopenharmony_ci/// The generated function has the following signature: 6363da5c369Sopenharmony_ci/// 6373da5c369Sopenharmony_ci/// ```rust,ignore 6383da5c369Sopenharmony_ci/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int> 6393da5c369Sopenharmony_ci/// ``` 6403da5c369Sopenharmony_ci/// 6413da5c369Sopenharmony_ci/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 6423da5c369Sopenharmony_ci/// 6433da5c369Sopenharmony_ci/// # Example 6443da5c369Sopenharmony_ci/// 6453da5c369Sopenharmony_ci/// ``` 6463da5c369Sopenharmony_ci/// # #[macro_use] extern crate nix; 6473da5c369Sopenharmony_ci/// # pub struct v4l2_audio {} 6483da5c369Sopenharmony_ci/// ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio); 6493da5c369Sopenharmony_ci/// # fn main() {} 6503da5c369Sopenharmony_ci/// ``` 6513da5c369Sopenharmony_ci#[macro_export(local_inner_macros)] 6523da5c369Sopenharmony_cimacro_rules! ioctl_readwrite { 6533da5c369Sopenharmony_ci ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 6543da5c369Sopenharmony_ci $(#[$attr])* 6553da5c369Sopenharmony_ci pub unsafe fn $name(fd: $crate::libc::c_int, 6563da5c369Sopenharmony_ci data: *mut $ty) 6573da5c369Sopenharmony_ci -> $crate::Result<$crate::libc::c_int> { 6583da5c369Sopenharmony_ci convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) 6593da5c369Sopenharmony_ci } 6603da5c369Sopenharmony_ci ) 6613da5c369Sopenharmony_ci} 6623da5c369Sopenharmony_ci 6633da5c369Sopenharmony_ci/// Generates a wrapper function for a "bad" ioctl that reads and writes data to the kernel. 6643da5c369Sopenharmony_ci/// 6653da5c369Sopenharmony_ci/// The arguments to this macro are: 6663da5c369Sopenharmony_ci/// 6673da5c369Sopenharmony_ci/// * The function name 6683da5c369Sopenharmony_ci/// * The ioctl request code 6693da5c369Sopenharmony_ci/// * The data type passed by this ioctl 6703da5c369Sopenharmony_ci/// 6713da5c369Sopenharmony_ci/// The generated function has the following signature: 6723da5c369Sopenharmony_ci/// 6733da5c369Sopenharmony_ci/// ```rust,ignore 6743da5c369Sopenharmony_ci/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int> 6753da5c369Sopenharmony_ci/// ``` 6763da5c369Sopenharmony_ci/// 6773da5c369Sopenharmony_ci/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 6783da5c369Sopenharmony_ci// TODO: Find an example for ioctl_readwrite_bad 6793da5c369Sopenharmony_ci#[macro_export(local_inner_macros)] 6803da5c369Sopenharmony_cimacro_rules! ioctl_readwrite_bad { 6813da5c369Sopenharmony_ci ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => ( 6823da5c369Sopenharmony_ci $(#[$attr])* 6833da5c369Sopenharmony_ci pub unsafe fn $name(fd: $crate::libc::c_int, 6843da5c369Sopenharmony_ci data: *mut $ty) 6853da5c369Sopenharmony_ci -> $crate::Result<$crate::libc::c_int> { 6863da5c369Sopenharmony_ci convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) 6873da5c369Sopenharmony_ci } 6883da5c369Sopenharmony_ci ) 6893da5c369Sopenharmony_ci} 6903da5c369Sopenharmony_ci 6913da5c369Sopenharmony_ci/// Generates a wrapper function for an ioctl that reads an array of elements from the kernel. 6923da5c369Sopenharmony_ci/// 6933da5c369Sopenharmony_ci/// The arguments to this macro are: 6943da5c369Sopenharmony_ci/// 6953da5c369Sopenharmony_ci/// * The function name 6963da5c369Sopenharmony_ci/// * The ioctl identifier 6973da5c369Sopenharmony_ci/// * The ioctl sequence number 6983da5c369Sopenharmony_ci/// * The data type passed by this ioctl 6993da5c369Sopenharmony_ci/// 7003da5c369Sopenharmony_ci/// The generated function has the following signature: 7013da5c369Sopenharmony_ci/// 7023da5c369Sopenharmony_ci/// ```rust,ignore 7033da5c369Sopenharmony_ci/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int> 7043da5c369Sopenharmony_ci/// ``` 7053da5c369Sopenharmony_ci/// 7063da5c369Sopenharmony_ci/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 7073da5c369Sopenharmony_ci// TODO: Find an example for ioctl_read_buf 7083da5c369Sopenharmony_ci#[macro_export(local_inner_macros)] 7093da5c369Sopenharmony_cimacro_rules! ioctl_read_buf { 7103da5c369Sopenharmony_ci ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 7113da5c369Sopenharmony_ci $(#[$attr])* 7123da5c369Sopenharmony_ci pub unsafe fn $name(fd: $crate::libc::c_int, 7133da5c369Sopenharmony_ci data: &mut [$ty]) 7143da5c369Sopenharmony_ci -> $crate::Result<$crate::libc::c_int> { 7153da5c369Sopenharmony_ci convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) 7163da5c369Sopenharmony_ci } 7173da5c369Sopenharmony_ci ) 7183da5c369Sopenharmony_ci} 7193da5c369Sopenharmony_ci 7203da5c369Sopenharmony_ci/// Generates a wrapper function for an ioctl that writes an array of elements to the kernel. 7213da5c369Sopenharmony_ci/// 7223da5c369Sopenharmony_ci/// The arguments to this macro are: 7233da5c369Sopenharmony_ci/// 7243da5c369Sopenharmony_ci/// * The function name 7253da5c369Sopenharmony_ci/// * The ioctl identifier 7263da5c369Sopenharmony_ci/// * The ioctl sequence number 7273da5c369Sopenharmony_ci/// * The data type passed by this ioctl 7283da5c369Sopenharmony_ci/// 7293da5c369Sopenharmony_ci/// The generated function has the following signature: 7303da5c369Sopenharmony_ci/// 7313da5c369Sopenharmony_ci/// ```rust,ignore 7323da5c369Sopenharmony_ci/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &[DATA_TYPE]) -> Result<libc::c_int> 7333da5c369Sopenharmony_ci/// ``` 7343da5c369Sopenharmony_ci/// 7353da5c369Sopenharmony_ci/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 7363da5c369Sopenharmony_ci/// 7373da5c369Sopenharmony_ci/// # Examples 7383da5c369Sopenharmony_ci/// 7393da5c369Sopenharmony_ci/// ``` 7403da5c369Sopenharmony_ci/// # #[macro_use] extern crate nix; 7413da5c369Sopenharmony_ci/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h 7423da5c369Sopenharmony_ci/// const SPI_IOC_TYPE_MESSAGE: u8 = 0; 7433da5c369Sopenharmony_ci/// # pub struct spi_ioc_transfer(u64); 7443da5c369Sopenharmony_ci/// ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer); 7453da5c369Sopenharmony_ci/// # fn main() {} 7463da5c369Sopenharmony_ci/// ``` 7473da5c369Sopenharmony_ci#[macro_export(local_inner_macros)] 7483da5c369Sopenharmony_cimacro_rules! ioctl_write_buf { 7493da5c369Sopenharmony_ci ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 7503da5c369Sopenharmony_ci $(#[$attr])* 7513da5c369Sopenharmony_ci pub unsafe fn $name(fd: $crate::libc::c_int, 7523da5c369Sopenharmony_ci data: &[$ty]) 7533da5c369Sopenharmony_ci -> $crate::Result<$crate::libc::c_int> { 7543da5c369Sopenharmony_ci convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) 7553da5c369Sopenharmony_ci } 7563da5c369Sopenharmony_ci ) 7573da5c369Sopenharmony_ci} 7583da5c369Sopenharmony_ci 7593da5c369Sopenharmony_ci/// Generates a wrapper function for an ioctl that reads and writes an array of elements to the kernel. 7603da5c369Sopenharmony_ci/// 7613da5c369Sopenharmony_ci/// The arguments to this macro are: 7623da5c369Sopenharmony_ci/// 7633da5c369Sopenharmony_ci/// * The function name 7643da5c369Sopenharmony_ci/// * The ioctl identifier 7653da5c369Sopenharmony_ci/// * The ioctl sequence number 7663da5c369Sopenharmony_ci/// * The data type passed by this ioctl 7673da5c369Sopenharmony_ci/// 7683da5c369Sopenharmony_ci/// The generated function has the following signature: 7693da5c369Sopenharmony_ci/// 7703da5c369Sopenharmony_ci/// ```rust,ignore 7713da5c369Sopenharmony_ci/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int> 7723da5c369Sopenharmony_ci/// ``` 7733da5c369Sopenharmony_ci/// 7743da5c369Sopenharmony_ci/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 7753da5c369Sopenharmony_ci// TODO: Find an example for readwrite_buf 7763da5c369Sopenharmony_ci#[macro_export(local_inner_macros)] 7773da5c369Sopenharmony_cimacro_rules! ioctl_readwrite_buf { 7783da5c369Sopenharmony_ci ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 7793da5c369Sopenharmony_ci $(#[$attr])* 7803da5c369Sopenharmony_ci pub unsafe fn $name(fd: $crate::libc::c_int, 7813da5c369Sopenharmony_ci data: &mut [$ty]) 7823da5c369Sopenharmony_ci -> $crate::Result<$crate::libc::c_int> { 7833da5c369Sopenharmony_ci convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) 7843da5c369Sopenharmony_ci } 7853da5c369Sopenharmony_ci ) 7863da5c369Sopenharmony_ci} 787