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 //! ``` 224 use cfg_if::cfg_if; 225 226 #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))] 227 #[macro_use] 228 mod linux; 229 230 #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))] 231 pub use self::linux::*; 232 233 #[cfg(any(target_os = "dragonfly", 234 target_os = "freebsd", 235 target_os = "illumos", 236 target_os = "ios", 237 target_os = "macos", 238 target_os = "netbsd", 239 target_os = "openbsd"))] 240 #[macro_use] 241 mod bsd; 242 243 #[cfg(any(target_os = "dragonfly", 244 target_os = "freebsd", 245 target_os = "illumos", 246 target_os = "ios", 247 target_os = "macos", 248 target_os = "netbsd", 249 target_os = "openbsd"))] 250 pub use self::bsd::*; 251 252 /// Convert raw ioctl return value to a Nix result 253 #[macro_export] 254 #[doc(hidden)] 255 macro_rules! convert_ioctl_res { 256 ($w:expr) => ( 257 { 258 $crate::errno::Errno::result($w) 259 } 260 ); 261 } 262 263 /// Generates a wrapper function for an ioctl that passes no data to the kernel. 264 /// 265 /// The arguments to this macro are: 266 /// 267 /// * The function name 268 /// * The ioctl identifier 269 /// * The ioctl sequence number 270 /// 271 /// The generated function has the following signature: 272 /// 273 /// ```rust,ignore 274 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int> 275 /// ``` 276 /// 277 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 278 /// 279 /// # Example 280 /// 281 /// The `videodev2` driver on Linux defines the `log_status` `ioctl` as: 282 /// 283 /// ```C 284 /// #define VIDIOC_LOG_STATUS _IO('V', 70) 285 /// ``` 286 /// 287 /// This can be implemented in Rust like: 288 /// 289 /// ```no_run 290 /// # #[macro_use] extern crate nix; 291 /// ioctl_none!(log_status, b'V', 70); 292 /// fn main() {} 293 /// ``` 294 #[macro_export(local_inner_macros)] 295 macro_rules! ioctl_none { 296 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => ( 297 $(#[$attr])* 298 pub unsafe fn $name(fd: $crate::libc::c_int) 299 -> $crate::Result<$crate::libc::c_int> { 300 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_none!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type)) 301 } 302 ) 303 } 304 305 /// Generates a wrapper function for a "bad" ioctl that passes no data to the kernel. 306 /// 307 /// The arguments to this macro are: 308 /// 309 /// * The function name 310 /// * The ioctl request code 311 /// 312 /// The generated function has the following signature: 313 /// 314 /// ```rust,ignore 315 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int> 316 /// ``` 317 /// 318 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 319 /// 320 /// # Example 321 /// 322 /// ```no_run 323 /// # #[macro_use] extern crate nix; 324 /// # use libc::TIOCNXCL; 325 /// # use std::fs::File; 326 /// # use std::os::unix::io::AsRawFd; 327 /// ioctl_none_bad!(tiocnxcl, TIOCNXCL); 328 /// fn main() { 329 /// let file = File::open("/dev/ttyUSB0").unwrap(); 330 /// unsafe { tiocnxcl(file.as_raw_fd()) }.unwrap(); 331 /// } 332 /// ``` 333 // TODO: add an example using request_code_*!() 334 #[macro_export(local_inner_macros)] 335 macro_rules! ioctl_none_bad { 336 ($(#[$attr:meta])* $name:ident, $nr:expr) => ( 337 $(#[$attr])* 338 pub unsafe fn $name(fd: $crate::libc::c_int) 339 -> $crate::Result<$crate::libc::c_int> { 340 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type)) 341 } 342 ) 343 } 344 345 /// Generates a wrapper function for an ioctl that reads data from the kernel. 346 /// 347 /// The arguments to this macro are: 348 /// 349 /// * The function name 350 /// * The ioctl identifier 351 /// * The ioctl sequence number 352 /// * The data type passed by this ioctl 353 /// 354 /// The generated function has the following signature: 355 /// 356 /// ```rust,ignore 357 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int> 358 /// ``` 359 /// 360 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 361 /// 362 /// # Example 363 /// 364 /// ``` 365 /// # #[macro_use] extern crate nix; 366 /// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h 367 /// const SPI_IOC_TYPE_MODE: u8 = 1; 368 /// ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8); 369 /// # fn main() {} 370 /// ``` 371 #[macro_export(local_inner_macros)] 372 macro_rules! ioctl_read { 373 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 374 $(#[$attr])* 375 pub unsafe fn $name(fd: $crate::libc::c_int, 376 data: *mut $ty) 377 -> $crate::Result<$crate::libc::c_int> { 378 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)) 379 } 380 ) 381 } 382 383 /// Generates a wrapper function for a "bad" ioctl that reads data from the kernel. 384 /// 385 /// The arguments to this macro are: 386 /// 387 /// * The function name 388 /// * The ioctl request code 389 /// * The data type passed by this ioctl 390 /// 391 /// The generated function has the following signature: 392 /// 393 /// ```rust,ignore 394 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int> 395 /// ``` 396 /// 397 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 398 /// 399 /// # Example 400 /// 401 /// ``` 402 /// # #[macro_use] extern crate nix; 403 /// # #[cfg(any(target_os = "android", target_os = "linux"))] 404 /// ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios); 405 /// # fn main() {} 406 /// ``` 407 #[macro_export(local_inner_macros)] 408 macro_rules! ioctl_read_bad { 409 ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => ( 410 $(#[$attr])* 411 pub unsafe fn $name(fd: $crate::libc::c_int, 412 data: *mut $ty) 413 -> $crate::Result<$crate::libc::c_int> { 414 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) 415 } 416 ) 417 } 418 419 /// Generates a wrapper function for an ioctl that writes data through a pointer to the kernel. 420 /// 421 /// The arguments to this macro are: 422 /// 423 /// * The function name 424 /// * The ioctl identifier 425 /// * The ioctl sequence number 426 /// * The data type passed by this ioctl 427 /// 428 /// The generated function has the following signature: 429 /// 430 /// ```rust,ignore 431 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int> 432 /// ``` 433 /// 434 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 435 /// 436 /// # Example 437 /// 438 /// ``` 439 /// # #[macro_use] extern crate nix; 440 /// # pub struct v4l2_audio {} 441 /// ioctl_write_ptr!(s_audio, b'V', 34, v4l2_audio); 442 /// # fn main() {} 443 /// ``` 444 #[macro_export(local_inner_macros)] 445 macro_rules! ioctl_write_ptr { 446 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 447 $(#[$attr])* 448 pub unsafe fn $name(fd: $crate::libc::c_int, 449 data: *const $ty) 450 -> $crate::Result<$crate::libc::c_int> { 451 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)) 452 } 453 ) 454 } 455 456 /// Generates a wrapper function for a "bad" ioctl that writes data through a pointer to the kernel. 457 /// 458 /// The arguments to this macro are: 459 /// 460 /// * The function name 461 /// * The ioctl request code 462 /// * The data type passed by this ioctl 463 /// 464 /// The generated function has the following signature: 465 /// 466 /// ```rust,ignore 467 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int> 468 /// ``` 469 /// 470 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 471 /// 472 /// # Example 473 /// 474 /// ``` 475 /// # #[macro_use] extern crate nix; 476 /// # #[cfg(any(target_os = "android", target_os = "linux"))] 477 /// ioctl_write_ptr_bad!(tcsets, libc::TCSETS, libc::termios); 478 /// # fn main() {} 479 /// ``` 480 #[macro_export(local_inner_macros)] 481 macro_rules! ioctl_write_ptr_bad { 482 ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => ( 483 $(#[$attr])* 484 pub unsafe fn $name(fd: $crate::libc::c_int, 485 data: *const $ty) 486 -> $crate::Result<$crate::libc::c_int> { 487 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) 488 } 489 ) 490 } 491 492 cfg_if!{ 493 if #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] { 494 /// Generates a wrapper function for a ioctl that writes an integer to the kernel. 495 /// 496 /// The arguments to this macro are: 497 /// 498 /// * The function name 499 /// * The ioctl identifier 500 /// * The ioctl sequence number 501 /// 502 /// The generated function has the following signature: 503 /// 504 /// ```rust,ignore 505 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int> 506 /// ``` 507 /// 508 /// `nix::sys::ioctl::ioctl_param_type` depends on the OS: 509 /// * BSD - `libc::c_int` 510 /// * Linux - `libc::c_ulong` 511 /// 512 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 513 /// 514 /// # Example 515 /// 516 /// ``` 517 /// # #[macro_use] extern crate nix; 518 /// ioctl_write_int!(vt_activate, b'v', 4); 519 /// # fn main() {} 520 /// ``` 521 #[macro_export(local_inner_macros)] 522 macro_rules! ioctl_write_int { 523 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => ( 524 $(#[$attr])* 525 pub unsafe fn $name(fd: $crate::libc::c_int, 526 data: $crate::sys::ioctl::ioctl_param_type) 527 -> $crate::Result<$crate::libc::c_int> { 528 convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write_int!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type, data)) 529 } 530 ) 531 } 532 } else { 533 /// Generates a wrapper function for a ioctl that writes an integer to the kernel. 534 /// 535 /// The arguments to this macro are: 536 /// 537 /// * The function name 538 /// * The ioctl identifier 539 /// * The ioctl sequence number 540 /// 541 /// The generated function has the following signature: 542 /// 543 /// ```rust,ignore 544 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int> 545 /// ``` 546 /// 547 /// `nix::sys::ioctl::ioctl_param_type` depends on the OS: 548 /// * BSD - `libc::c_int` 549 /// * Linux - `libc::c_ulong` 550 /// 551 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 552 /// 553 /// # Example 554 /// 555 /// ``` 556 /// # #[macro_use] extern crate nix; 557 /// const HCI_IOC_MAGIC: u8 = b'k'; 558 /// const HCI_IOC_HCIDEVUP: u8 = 1; 559 /// ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP); 560 /// # fn main() {} 561 /// ``` 562 #[macro_export(local_inner_macros)] 563 macro_rules! ioctl_write_int { 564 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => ( 565 $(#[$attr])* 566 pub unsafe fn $name(fd: $crate::libc::c_int, 567 data: $crate::sys::ioctl::ioctl_param_type) 568 -> $crate::Result<$crate::libc::c_int> { 569 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)) 570 } 571 ) 572 } 573 } 574 } 575 576 /// Generates a wrapper function for a "bad" ioctl that writes an integer to the kernel. 577 /// 578 /// The arguments to this macro are: 579 /// 580 /// * The function name 581 /// * The ioctl request code 582 /// 583 /// The generated function has the following signature: 584 /// 585 /// ```rust,ignore 586 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: libc::c_int) -> Result<libc::c_int> 587 /// ``` 588 /// 589 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 590 /// 591 /// # Examples 592 /// 593 /// ``` 594 /// # #[macro_use] extern crate nix; 595 /// # #[cfg(any(target_os = "android", target_os = "linux"))] 596 /// ioctl_write_int_bad!(tcsbrk, libc::TCSBRK); 597 /// # fn main() {} 598 /// ``` 599 /// 600 /// ```rust 601 /// # #[macro_use] extern crate nix; 602 /// const KVMIO: u8 = 0xAE; 603 /// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03)); 604 /// # fn main() {} 605 /// ``` 606 #[macro_export(local_inner_macros)] 607 macro_rules! ioctl_write_int_bad { 608 ($(#[$attr:meta])* $name:ident, $nr:expr) => ( 609 $(#[$attr])* 610 pub unsafe fn $name(fd: $crate::libc::c_int, 611 data: $crate::libc::c_int) 612 -> $crate::Result<$crate::libc::c_int> { 613 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) 614 } 615 ) 616 } 617 618 /// Generates a wrapper function for an ioctl that reads and writes data to the kernel. 619 /// 620 /// The arguments to this macro are: 621 /// 622 /// * The function name 623 /// * The ioctl identifier 624 /// * The ioctl sequence number 625 /// * The data type passed by this ioctl 626 /// 627 /// The generated function has the following signature: 628 /// 629 /// ```rust,ignore 630 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int> 631 /// ``` 632 /// 633 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 634 /// 635 /// # Example 636 /// 637 /// ``` 638 /// # #[macro_use] extern crate nix; 639 /// # pub struct v4l2_audio {} 640 /// ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio); 641 /// # fn main() {} 642 /// ``` 643 #[macro_export(local_inner_macros)] 644 macro_rules! ioctl_readwrite { 645 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 646 $(#[$attr])* 647 pub unsafe fn $name(fd: $crate::libc::c_int, 648 data: *mut $ty) 649 -> $crate::Result<$crate::libc::c_int> { 650 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)) 651 } 652 ) 653 } 654 655 /// Generates a wrapper function for a "bad" ioctl that reads and writes data to the kernel. 656 /// 657 /// The arguments to this macro are: 658 /// 659 /// * The function name 660 /// * The ioctl request code 661 /// * The data type passed by this ioctl 662 /// 663 /// The generated function has the following signature: 664 /// 665 /// ```rust,ignore 666 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int> 667 /// ``` 668 /// 669 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 670 // TODO: Find an example for ioctl_readwrite_bad 671 #[macro_export(local_inner_macros)] 672 macro_rules! ioctl_readwrite_bad { 673 ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => ( 674 $(#[$attr])* 675 pub unsafe fn $name(fd: $crate::libc::c_int, 676 data: *mut $ty) 677 -> $crate::Result<$crate::libc::c_int> { 678 convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) 679 } 680 ) 681 } 682 683 /// Generates a wrapper function for an ioctl that reads an array of elements from the kernel. 684 /// 685 /// The arguments to this macro are: 686 /// 687 /// * The function name 688 /// * The ioctl identifier 689 /// * The ioctl sequence number 690 /// * The data type passed by this ioctl 691 /// 692 /// The generated function has the following signature: 693 /// 694 /// ```rust,ignore 695 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int> 696 /// ``` 697 /// 698 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 699 // TODO: Find an example for ioctl_read_buf 700 #[macro_export(local_inner_macros)] 701 macro_rules! ioctl_read_buf { 702 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 703 $(#[$attr])* 704 pub unsafe fn $name(fd: $crate::libc::c_int, 705 data: &mut [$ty]) 706 -> $crate::Result<$crate::libc::c_int> { 707 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)) 708 } 709 ) 710 } 711 712 /// Generates a wrapper function for an ioctl that writes an array of elements to the kernel. 713 /// 714 /// The arguments to this macro are: 715 /// 716 /// * The function name 717 /// * The ioctl identifier 718 /// * The ioctl sequence number 719 /// * The data type passed by this ioctl 720 /// 721 /// The generated function has the following signature: 722 /// 723 /// ```rust,ignore 724 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &[DATA_TYPE]) -> Result<libc::c_int> 725 /// ``` 726 /// 727 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 728 /// 729 /// # Examples 730 /// 731 /// ``` 732 /// # #[macro_use] extern crate nix; 733 /// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h 734 /// const SPI_IOC_TYPE_MESSAGE: u8 = 0; 735 /// # pub struct spi_ioc_transfer(u64); 736 /// ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer); 737 /// # fn main() {} 738 /// ``` 739 #[macro_export(local_inner_macros)] 740 macro_rules! ioctl_write_buf { 741 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 742 $(#[$attr])* 743 pub unsafe fn $name(fd: $crate::libc::c_int, 744 data: &[$ty]) 745 -> $crate::Result<$crate::libc::c_int> { 746 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)) 747 } 748 ) 749 } 750 751 /// Generates a wrapper function for an ioctl that reads and writes an array of elements to the kernel. 752 /// 753 /// The arguments to this macro are: 754 /// 755 /// * The function name 756 /// * The ioctl identifier 757 /// * The ioctl sequence number 758 /// * The data type passed by this ioctl 759 /// 760 /// The generated function has the following signature: 761 /// 762 /// ```rust,ignore 763 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int> 764 /// ``` 765 /// 766 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). 767 // TODO: Find an example for readwrite_buf 768 #[macro_export(local_inner_macros)] 769 macro_rules! ioctl_readwrite_buf { 770 ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( 771 $(#[$attr])* 772 pub unsafe fn $name(fd: $crate::libc::c_int, 773 data: &mut [$ty]) 774 -> $crate::Result<$crate::libc::c_int> { 775 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)) 776 } 777 ) 778 } 779