1//! Provide helpers for making ioctl system calls. 2//! 3//! This library is pretty low-level and messy. `ioctl` is not fun. 4//! 5//! What is an `ioctl`? 6//! =================== 7//! 8//! The `ioctl` syscall is the grab-bag syscall on POSIX systems. Don't want to add a new 9//! syscall? Make it an `ioctl`! `ioctl` refers to both the syscall, and the commands that can be 10//! sent with it. `ioctl` stands for "IO control", and the commands are always sent to a file 11//! descriptor. 12//! 13//! It is common to see `ioctl`s used for the following purposes: 14//! 15//! * Provide read/write access to out-of-band data related to a device such as configuration 16//! (for instance, setting serial port options) 17//! * Provide a mechanism for performing full-duplex data transfers (for instance, xfer on SPI 18//! devices). 19//! * Provide access to control functions on a device (for example, on Linux you can send 20//! commands like pause, resume, and eject to the CDROM device. 21//! * Do whatever else the device driver creator thought made most sense. 22//! 23//! `ioctl`s are synchronous system calls and are similar to read and write calls in that regard. 24//! They operate on file descriptors and have an identifier that specifies what the ioctl is. 25//! Additionally they may read or write data and therefore need to pass along a data pointer. 26//! Besides the semantics of the ioctls being confusing, the generation of this identifer can also 27//! be difficult. 28//! 29//! Historically `ioctl` numbers were arbitrary hard-coded values. In Linux (before 2.6) and some 30//! unices this has changed to a more-ordered system where the ioctl numbers are partitioned into 31//! subcomponents (For linux this is documented in 32//! [`Documentation/ioctl/ioctl-number.rst`](https://elixir.bootlin.com/linux/latest/source/Documentation/userspace-api/ioctl/ioctl-number.rst)): 33//! 34//! * Number: The actual ioctl ID 35//! * Type: A grouping of ioctls for a common purpose or driver 36//! * Size: The size in bytes of the data that will be transferred 37//! * Direction: Whether there is any data and if it's read, write, or both 38//! 39//! Newer drivers should not generate complete integer identifiers for their `ioctl`s instead 40//! preferring to use the 4 components above to generate the final ioctl identifier. Because of 41//! how old `ioctl`s are, however, there are many hard-coded `ioctl` identifiers. These are 42//! commonly referred to as "bad" in `ioctl` documentation. 43//! 44//! Defining `ioctl`s 45//! ================= 46//! 47//! This library provides several `ioctl_*!` macros for binding `ioctl`s. These generate public 48//! unsafe functions that can then be used for calling the ioctl. This macro has a few different 49//! ways it can be used depending on the specific ioctl you're working with. 50//! 51//! A simple `ioctl` is `SPI_IOC_RD_MODE`. This ioctl works with the SPI interface on Linux. This 52//! specific `ioctl` reads the mode of the SPI device as a `u8`. It's declared in 53//! `/include/uapi/linux/spi/spidev.h` as `_IOR(SPI_IOC_MAGIC, 1, __u8)`. Since it uses the `_IOR` 54//! macro, we know it's a `read` ioctl and can use the `ioctl_read!` macro as follows: 55//! 56//! ``` 57//! # #[macro_use] extern crate nix; 58//! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h 59//! const SPI_IOC_TYPE_MODE: u8 = 1; 60//! ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8); 61//! # fn main() {} 62//! ``` 63//! 64//! This generates the function: 65//! 66//! ``` 67//! # #[macro_use] extern crate nix; 68//! # use std::mem; 69//! # use nix::{libc, Result}; 70//! # use nix::errno::Errno; 71//! # use nix::libc::c_int as c_int; 72//! # const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h 73//! # const SPI_IOC_TYPE_MODE: u8 = 1; 74//! pub unsafe fn spi_read_mode(fd: c_int, data: *mut u8) -> Result<c_int> { 75//! let res = libc::ioctl(fd, request_code_read!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, mem::size_of::<u8>()), data); 76//! Errno::result(res) 77//! } 78//! # fn main() {} 79//! ``` 80//! 81//! The return value for the wrapper functions generated by the `ioctl_*!` macros are `nix::Error`s. 82//! These are generated by assuming the return value of the ioctl is `-1` on error and everything 83//! else is a valid return value. If this is not the case, `Result::map` can be used to map some 84//! of the range of "good" values (-Inf..-2, 0..Inf) into a smaller range in a helper function. 85//! 86//! Writing `ioctl`s generally use pointers as their data source and these should use the 87//! `ioctl_write_ptr!`. But in some cases an `int` is passed directly. For these `ioctl`s use the 88//! `ioctl_write_int!` macro. This variant does not take a type as the last argument: 89//! 90//! ``` 91//! # #[macro_use] extern crate nix; 92//! const HCI_IOC_MAGIC: u8 = b'k'; 93//! const HCI_IOC_HCIDEVUP: u8 = 1; 94//! ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP); 95//! # fn main() {} 96//! ``` 97//! 98//! Some `ioctl`s don't transfer any data, and those should use `ioctl_none!`. This macro 99//! doesn't take a type and so it is declared similar to the `write_int` variant shown above. 100//! 101//! The mode for a given `ioctl` should be clear from the documentation if it has good 102//! documentation. Otherwise it will be clear based on the macro used to generate the `ioctl` 103//! number where `_IO`, `_IOR`, `_IOW`, and `_IOWR` map to "none", "read", "write_*", and "readwrite" 104//! respectively. To determine the specific `write_` variant to use you'll need to find 105//! what the argument type is supposed to be. If it's an `int`, then `write_int` should be used, 106//! otherwise it should be a pointer and `write_ptr` should be used. On Linux the 107//! [`ioctl_list` man page](https://man7.org/linux/man-pages/man2/ioctl_list.2.html) describes a 108//! large number of `ioctl`s and describes their argument data type. 109//! 110//! Using "bad" `ioctl`s 111//! -------------------- 112//! 113//! As mentioned earlier, there are many old `ioctl`s that do not use the newer method of 114//! generating `ioctl` numbers and instead use hardcoded values. These can be used with the 115//! `ioctl_*_bad!` macros. This naming comes from the Linux kernel which refers to these 116//! `ioctl`s as "bad". These are a different variant as they bypass calling the macro that generates 117//! the ioctl number and instead use the defined value directly. 118//! 119//! For example the `TCGETS` `ioctl` reads a `termios` data structure for a given file descriptor. 120//! It's defined as `0x5401` in `ioctls.h` on Linux and can be implemented as: 121//! 122//! ``` 123//! # #[macro_use] extern crate nix; 124//! # #[cfg(any(target_os = "android", target_os = "linux"))] 125//! # use nix::libc::TCGETS as TCGETS; 126//! # #[cfg(any(target_os = "android", target_os = "linux"))] 127//! # use nix::libc::termios as termios; 128//! # #[cfg(any(target_os = "android", target_os = "linux"))] 129//! ioctl_read_bad!(tcgets, TCGETS, termios); 130//! # fn main() {} 131//! ``` 132//! 133//! The generated function has the same form as that generated by `ioctl_read!`: 134//! 135//! ```text 136//! pub unsafe fn tcgets(fd: c_int, data: *mut termios) -> Result<c_int>; 137//! ``` 138//! 139//! Working with Arrays 140//! ------------------- 141//! 142//! Some `ioctl`s work with entire arrays of elements. These are supported by the `ioctl_*_buf` 143//! family of macros: `ioctl_read_buf`, `ioctl_write_buf`, and `ioctl_readwrite_buf`. Note that 144//! there are no "bad" versions for working with buffers. The generated functions include a `len` 145//! argument to specify the number of elements (where the type of each element is specified in the 146//! macro). 147//! 148//! Again looking to the SPI `ioctl`s on Linux for an example, there is a `SPI_IOC_MESSAGE` `ioctl` 149//! that queues up multiple SPI messages by writing an entire array of `spi_ioc_transfer` structs. 150//! `linux/spi/spidev.h` defines a macro to calculate the `ioctl` number like: 151//! 152//! ```C 153//! #define SPI_IOC_MAGIC 'k' 154//! #define SPI_MSGSIZE(N) ... 155//! #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)]) 156//! ``` 157//! 158//! The `SPI_MSGSIZE(N)` calculation is already handled by the `ioctl_*!` macros, so all that's 159//! needed to define this `ioctl` is: 160//! 161//! ``` 162//! # #[macro_use] extern crate nix; 163//! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h 164//! const SPI_IOC_TYPE_MESSAGE: u8 = 0; 165//! # pub struct spi_ioc_transfer(u64); 166//! ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer); 167//! # fn main() {} 168//! ``` 169//! 170//! This generates a function like: 171//! 172//! ``` 173//! # #[macro_use] extern crate nix; 174//! # use std::mem; 175//! # use nix::{libc, Result}; 176//! # use nix::errno::Errno; 177//! # use nix::libc::c_int as c_int; 178//! # const SPI_IOC_MAGIC: u8 = b'k'; 179//! # const SPI_IOC_TYPE_MESSAGE: u8 = 0; 180//! # pub struct spi_ioc_transfer(u64); 181//! pub unsafe fn spi_message(fd: c_int, data: &mut [spi_ioc_transfer]) -> Result<c_int> { 182//! let res = libc::ioctl(fd, 183//! request_code_write!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, data.len() * mem::size_of::<spi_ioc_transfer>()), 184//! data); 185//! Errno::result(res) 186//! } 187//! # fn main() {} 188//! ``` 189//! 190//! Finding `ioctl` Documentation 191//! ----------------------------- 192//! 193//! For Linux, look at your system's headers. For example, `/usr/include/linux/input.h` has a lot 194//! of lines defining macros which use `_IO`, `_IOR`, `_IOW`, `_IOC`, and `_IOWR`. Some `ioctl`s are 195//! documented directly in the headers defining their constants, but others have more extensive 196//! documentation in man pages (like termios' `ioctl`s which are in `tty_ioctl(4)`). 197//! 198//! Documenting the Generated Functions 199//! =================================== 200//! 201//! In many cases, users will wish for the functions generated by the `ioctl` 202//! macro to be public and documented. For this reason, the generated functions 203//! are public by default. If you wish to hide the ioctl, you will need to put 204//! them in a private module. 205//! 206//! For documentation, it is possible to use doc comments inside the `ioctl_*!` macros. Here is an 207//! example : 208//! 209//! ``` 210//! # #[macro_use] extern crate nix; 211//! # use nix::libc::c_int; 212//! ioctl_read! { 213//! /// Make the given terminal the controlling terminal of the calling process. The calling 214//! /// process must be a session leader and not have a controlling terminal already. If the 215//! /// terminal is already the controlling terminal of a different session group then the 216//! /// ioctl will fail with **EPERM**, unless the caller is root (more precisely: has the 217//! /// **CAP_SYS_ADMIN** capability) and arg equals 1, in which case the terminal is stolen 218//! /// and all processes that had it as controlling terminal lose it. 219//! tiocsctty, b't', 19, c_int 220//! } 221//! 222//! # fn main() {} 223//! ``` 224use cfg_if::cfg_if; 225 226#[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))] 227#[macro_use] 228mod linux; 229 230#[cfg(any( 231 target_os = "android", 232 target_os = "linux", 233 target_os = "redox" 234))] 235pub use self::linux::*; 236 237#[cfg(any( 238 target_os = "dragonfly", 239 target_os = "freebsd", 240 target_os = "illumos", 241 target_os = "ios", 242 target_os = "macos", 243 target_os = "netbsd", 244 target_os = "haiku", 245 target_os = "openbsd" 246))] 247#[macro_use] 248mod bsd; 249 250#[cfg(any( 251 target_os = "dragonfly", 252 target_os = "freebsd", 253 target_os = "illumos", 254 target_os = "ios", 255 target_os = "macos", 256 target_os = "netbsd", 257 target_os = "haiku", 258 target_os = "openbsd" 259))] 260pub use self::bsd::*; 261 262/// Convert raw ioctl return value to a Nix result 263#[macro_export] 264#[doc(hidden)] 265macro_rules! convert_ioctl_res { 266 ($w:expr) => {{ 267 $crate::errno::Errno::result($w) 268 }}; 269} 270 271/// Generates a wrapper function for an ioctl that passes no data to the kernel. 272/// 273/// The arguments to this macro are: 274/// 275/// * The function name 276/// * The ioctl identifier 277/// * The ioctl sequence number 278/// 279/// The generated function has the following signature: 280/// 281/// ```rust,ignore 282/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int> 283/// ``` 284/// 285/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 286/// 287/// # Example 288/// 289/// The `videodev2` driver on Linux defines the `log_status` `ioctl` as: 290/// 291/// ```C 292/// #define VIDIOC_LOG_STATUS _IO('V', 70) 293/// ``` 294/// 295/// This can be implemented in Rust like: 296/// 297/// ```no_run 298/// # #[macro_use] extern crate nix; 299/// ioctl_none!(log_status, b'V', 70); 300/// fn main() {} 301/// ``` 302#[macro_export(local_inner_macros)] 303macro_rules! ioctl_none { 304 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => ( 305 $(#[$attr])* 306 pub unsafe fn $name(fd: $crate::libc::c_int) 307 -> $crate::Result<$crate::libc::c_int> { 308 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_none!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type)) 309 } 310 ) 311} 312 313/// Generates a wrapper function for a "bad" ioctl that passes no data to the kernel. 314/// 315/// The arguments to this macro are: 316/// 317/// * The function name 318/// * The ioctl request code 319/// 320/// The generated function has the following signature: 321/// 322/// ```rust,ignore 323/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int> 324/// ``` 325/// 326/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 327/// 328/// # Example 329/// 330/// ```no_run 331/// # #[macro_use] extern crate nix; 332/// # use libc::TIOCNXCL; 333/// # use std::fs::File; 334/// # use std::os::unix::io::AsRawFd; 335/// ioctl_none_bad!(tiocnxcl, TIOCNXCL); 336/// fn main() { 337/// let file = File::open("/dev/ttyUSB0").unwrap(); 338/// unsafe { tiocnxcl(file.as_raw_fd()) }.unwrap(); 339/// } 340/// ``` 341// TODO: add an example using request_code_*!() 342#[macro_export(local_inner_macros)] 343macro_rules! ioctl_none_bad { 344 ($(#[$attr:meta])* $name:ident, $nr:expr) => ( 345 $(#[$attr])* 346 pub unsafe fn $name(fd: $crate::libc::c_int) 347 -> $crate::Result<$crate::libc::c_int> { 348 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type)) 349 } 350 ) 351} 352 353/// Generates a wrapper function for an ioctl that reads data from the kernel. 354/// 355/// The arguments to this macro are: 356/// 357/// * The function name 358/// * The ioctl identifier 359/// * The ioctl sequence number 360/// * The data type passed by this ioctl 361/// 362/// The generated function has the following signature: 363/// 364/// ```rust,ignore 365/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int> 366/// ``` 367/// 368/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 369/// 370/// # Example 371/// 372/// ``` 373/// # #[macro_use] extern crate nix; 374/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h 375/// const SPI_IOC_TYPE_MODE: u8 = 1; 376/// ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8); 377/// # fn main() {} 378/// ``` 379#[macro_export(local_inner_macros)] 380macro_rules! ioctl_read { 381 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 382 $(#[$attr])* 383 pub unsafe fn $name(fd: $crate::libc::c_int, 384 data: *mut $ty) 385 -> $crate::Result<$crate::libc::c_int> { 386 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)) 387 } 388 ) 389} 390 391/// Generates a wrapper function for a "bad" ioctl that reads data from the kernel. 392/// 393/// The arguments to this macro are: 394/// 395/// * The function name 396/// * The ioctl request code 397/// * The data type passed by this ioctl 398/// 399/// The generated function has the following signature: 400/// 401/// ```rust,ignore 402/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int> 403/// ``` 404/// 405/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 406/// 407/// # Example 408/// 409/// ``` 410/// # #[macro_use] extern crate nix; 411/// # #[cfg(any(target_os = "android", target_os = "linux"))] 412/// ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios); 413/// # fn main() {} 414/// ``` 415#[macro_export(local_inner_macros)] 416macro_rules! ioctl_read_bad { 417 ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => ( 418 $(#[$attr])* 419 pub unsafe fn $name(fd: $crate::libc::c_int, 420 data: *mut $ty) 421 -> $crate::Result<$crate::libc::c_int> { 422 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) 423 } 424 ) 425} 426 427/// Generates a wrapper function for an ioctl that writes data through a pointer to the kernel. 428/// 429/// The arguments to this macro are: 430/// 431/// * The function name 432/// * The ioctl identifier 433/// * The ioctl sequence number 434/// * The data type passed by this ioctl 435/// 436/// The generated function has the following signature: 437/// 438/// ```rust,ignore 439/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int> 440/// ``` 441/// 442/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 443/// 444/// # Example 445/// 446/// ``` 447/// # #[macro_use] extern crate nix; 448/// # pub struct v4l2_audio {} 449/// ioctl_write_ptr!(s_audio, b'V', 34, v4l2_audio); 450/// # fn main() {} 451/// ``` 452#[macro_export(local_inner_macros)] 453macro_rules! ioctl_write_ptr { 454 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 455 $(#[$attr])* 456 pub unsafe fn $name(fd: $crate::libc::c_int, 457 data: *const $ty) 458 -> $crate::Result<$crate::libc::c_int> { 459 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)) 460 } 461 ) 462} 463 464/// Generates a wrapper function for a "bad" ioctl that writes data through a pointer to the kernel. 465/// 466/// The arguments to this macro are: 467/// 468/// * The function name 469/// * The ioctl request code 470/// * The data type passed by this ioctl 471/// 472/// The generated function has the following signature: 473/// 474/// ```rust,ignore 475/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int> 476/// ``` 477/// 478/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 479/// 480/// # Example 481/// 482/// ``` 483/// # #[macro_use] extern crate nix; 484/// # #[cfg(any(target_os = "android", target_os = "linux"))] 485/// ioctl_write_ptr_bad!(tcsets, libc::TCSETS, libc::termios); 486/// # fn main() {} 487/// ``` 488#[macro_export(local_inner_macros)] 489macro_rules! ioctl_write_ptr_bad { 490 ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => ( 491 $(#[$attr])* 492 pub unsafe fn $name(fd: $crate::libc::c_int, 493 data: *const $ty) 494 -> $crate::Result<$crate::libc::c_int> { 495 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) 496 } 497 ) 498} 499 500cfg_if! { 501 if #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] { 502 /// Generates a wrapper function for a ioctl that writes an integer to the kernel. 503 /// 504 /// The arguments to this macro are: 505 /// 506 /// * The function name 507 /// * The ioctl identifier 508 /// * The ioctl sequence number 509 /// 510 /// The generated function has the following signature: 511 /// 512 /// ```rust,ignore 513 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int> 514 /// ``` 515 /// 516 /// `nix::sys::ioctl::ioctl_param_type` depends on the OS: 517 /// * BSD - `libc::c_int` 518 /// * Linux - `libc::c_ulong` 519 /// 520 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 521 /// 522 /// # Example 523 /// 524 /// ``` 525 /// # #[macro_use] extern crate nix; 526 /// ioctl_write_int!(vt_activate, b'v', 4); 527 /// # fn main() {} 528 /// ``` 529 #[macro_export(local_inner_macros)] 530 macro_rules! ioctl_write_int { 531 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => ( 532 $(#[$attr])* 533 pub unsafe fn $name(fd: $crate::libc::c_int, 534 data: $crate::sys::ioctl::ioctl_param_type) 535 -> $crate::Result<$crate::libc::c_int> { 536 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write_int!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type, data)) 537 } 538 ) 539 } 540 } else { 541 /// Generates a wrapper function for a ioctl that writes an integer to the kernel. 542 /// 543 /// The arguments to this macro are: 544 /// 545 /// * The function name 546 /// * The ioctl identifier 547 /// * The ioctl sequence number 548 /// 549 /// The generated function has the following signature: 550 /// 551 /// ```rust,ignore 552 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int> 553 /// ``` 554 /// 555 /// `nix::sys::ioctl::ioctl_param_type` depends on the OS: 556 /// * BSD - `libc::c_int` 557 /// * Linux - `libc::c_ulong` 558 /// 559 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 560 /// 561 /// # Example 562 /// 563 /// ``` 564 /// # #[macro_use] extern crate nix; 565 /// const HCI_IOC_MAGIC: u8 = b'k'; 566 /// const HCI_IOC_HCIDEVUP: u8 = 1; 567 /// ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP); 568 /// # fn main() {} 569 /// ``` 570 #[macro_export(local_inner_macros)] 571 macro_rules! ioctl_write_int { 572 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => ( 573 $(#[$attr])* 574 pub unsafe fn $name(fd: $crate::libc::c_int, 575 data: $crate::sys::ioctl::ioctl_param_type) 576 -> $crate::Result<$crate::libc::c_int> { 577 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)) 578 } 579 ) 580 } 581 } 582} 583 584/// Generates a wrapper function for a "bad" ioctl that writes an integer to the kernel. 585/// 586/// The arguments to this macro are: 587/// 588/// * The function name 589/// * The ioctl request code 590/// 591/// The generated function has the following signature: 592/// 593/// ```rust,ignore 594/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: libc::c_int) -> Result<libc::c_int> 595/// ``` 596/// 597/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 598/// 599/// # Examples 600/// 601/// ``` 602/// # #[macro_use] extern crate nix; 603/// # #[cfg(any(target_os = "android", target_os = "linux"))] 604/// ioctl_write_int_bad!(tcsbrk, libc::TCSBRK); 605/// # fn main() {} 606/// ``` 607/// 608/// ```rust 609/// # #[macro_use] extern crate nix; 610/// const KVMIO: u8 = 0xAE; 611/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03)); 612/// # fn main() {} 613/// ``` 614#[macro_export(local_inner_macros)] 615macro_rules! ioctl_write_int_bad { 616 ($(#[$attr:meta])* $name:ident, $nr:expr) => ( 617 $(#[$attr])* 618 pub unsafe fn $name(fd: $crate::libc::c_int, 619 data: $crate::libc::c_int) 620 -> $crate::Result<$crate::libc::c_int> { 621 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) 622 } 623 ) 624} 625 626/// Generates a wrapper function for an ioctl that reads and writes data to the kernel. 627/// 628/// The arguments to this macro are: 629/// 630/// * The function name 631/// * The ioctl identifier 632/// * The ioctl sequence number 633/// * The data type passed by this ioctl 634/// 635/// The generated function has the following signature: 636/// 637/// ```rust,ignore 638/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int> 639/// ``` 640/// 641/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 642/// 643/// # Example 644/// 645/// ``` 646/// # #[macro_use] extern crate nix; 647/// # pub struct v4l2_audio {} 648/// ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio); 649/// # fn main() {} 650/// ``` 651#[macro_export(local_inner_macros)] 652macro_rules! ioctl_readwrite { 653 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 654 $(#[$attr])* 655 pub unsafe fn $name(fd: $crate::libc::c_int, 656 data: *mut $ty) 657 -> $crate::Result<$crate::libc::c_int> { 658 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)) 659 } 660 ) 661} 662 663/// Generates a wrapper function for a "bad" ioctl that reads and writes data to the kernel. 664/// 665/// The arguments to this macro are: 666/// 667/// * The function name 668/// * The ioctl request code 669/// * The data type passed by this ioctl 670/// 671/// The generated function has the following signature: 672/// 673/// ```rust,ignore 674/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int> 675/// ``` 676/// 677/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 678// TODO: Find an example for ioctl_readwrite_bad 679#[macro_export(local_inner_macros)] 680macro_rules! ioctl_readwrite_bad { 681 ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => ( 682 $(#[$attr])* 683 pub unsafe fn $name(fd: $crate::libc::c_int, 684 data: *mut $ty) 685 -> $crate::Result<$crate::libc::c_int> { 686 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) 687 } 688 ) 689} 690 691/// Generates a wrapper function for an ioctl that reads an array of elements from the kernel. 692/// 693/// The arguments to this macro are: 694/// 695/// * The function name 696/// * The ioctl identifier 697/// * The ioctl sequence number 698/// * The data type passed by this ioctl 699/// 700/// The generated function has the following signature: 701/// 702/// ```rust,ignore 703/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int> 704/// ``` 705/// 706/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 707// TODO: Find an example for ioctl_read_buf 708#[macro_export(local_inner_macros)] 709macro_rules! ioctl_read_buf { 710 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 711 $(#[$attr])* 712 pub unsafe fn $name(fd: $crate::libc::c_int, 713 data: &mut [$ty]) 714 -> $crate::Result<$crate::libc::c_int> { 715 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)) 716 } 717 ) 718} 719 720/// Generates a wrapper function for an ioctl that writes an array of elements to the kernel. 721/// 722/// The arguments to this macro are: 723/// 724/// * The function name 725/// * The ioctl identifier 726/// * The ioctl sequence number 727/// * The data type passed by this ioctl 728/// 729/// The generated function has the following signature: 730/// 731/// ```rust,ignore 732/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &[DATA_TYPE]) -> Result<libc::c_int> 733/// ``` 734/// 735/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 736/// 737/// # Examples 738/// 739/// ``` 740/// # #[macro_use] extern crate nix; 741/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h 742/// const SPI_IOC_TYPE_MESSAGE: u8 = 0; 743/// # pub struct spi_ioc_transfer(u64); 744/// ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer); 745/// # fn main() {} 746/// ``` 747#[macro_export(local_inner_macros)] 748macro_rules! ioctl_write_buf { 749 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 750 $(#[$attr])* 751 pub unsafe fn $name(fd: $crate::libc::c_int, 752 data: &[$ty]) 753 -> $crate::Result<$crate::libc::c_int> { 754 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)) 755 } 756 ) 757} 758 759/// Generates a wrapper function for an ioctl that reads and writes an array of elements to the kernel. 760/// 761/// The arguments to this macro are: 762/// 763/// * The function name 764/// * The ioctl identifier 765/// * The ioctl sequence number 766/// * The data type passed by this ioctl 767/// 768/// The generated function has the following signature: 769/// 770/// ```rust,ignore 771/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int> 772/// ``` 773/// 774/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 775// TODO: Find an example for readwrite_buf 776#[macro_export(local_inner_macros)] 777macro_rules! ioctl_readwrite_buf { 778 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 779 $(#[$attr])* 780 pub unsafe fn $name(fd: $crate::libc::c_int, 781 data: &mut [$ty]) 782 -> $crate::Result<$crate::libc::c_int> { 783 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)) 784 } 785 ) 786} 787