diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
commit | 9835e2ae736235810b4ea1c162ca5e65c547e770 (patch) | |
tree | 3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/nix/src/sys/ioctl | |
parent | Releasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff) | |
download | rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip |
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/nix/src/sys/ioctl')
-rw-r--r-- | vendor/nix/src/sys/ioctl/bsd.rs | 129 | ||||
-rw-r--r-- | vendor/nix/src/sys/ioctl/linux.rs | 172 | ||||
-rw-r--r-- | vendor/nix/src/sys/ioctl/mod.rs | 786 |
3 files changed, 0 insertions, 1087 deletions
diff --git a/vendor/nix/src/sys/ioctl/bsd.rs b/vendor/nix/src/sys/ioctl/bsd.rs deleted file mode 100644 index 307994cb9..000000000 --- a/vendor/nix/src/sys/ioctl/bsd.rs +++ /dev/null @@ -1,129 +0,0 @@ -/// The datatype used for the ioctl number -#[doc(hidden)] -#[cfg(not(target_os = "illumos"))] -pub type ioctl_num_type = ::libc::c_ulong; - -#[doc(hidden)] -#[cfg(target_os = "illumos")] -pub type ioctl_num_type = ::libc::c_int; - -/// The datatype used for the 3rd argument -#[doc(hidden)] -pub type ioctl_param_type = ::libc::c_int; - -mod consts { - use crate::sys::ioctl::ioctl_num_type; - #[doc(hidden)] - pub const VOID: ioctl_num_type = 0x2000_0000; - #[doc(hidden)] - pub const OUT: ioctl_num_type = 0x4000_0000; - #[doc(hidden)] - #[allow(overflowing_literals)] - pub const IN: ioctl_num_type = 0x8000_0000; - #[doc(hidden)] - pub const INOUT: ioctl_num_type = IN | OUT; - #[doc(hidden)] - pub const IOCPARM_MASK: ioctl_num_type = 0x1fff; -} - -pub use self::consts::*; - -#[macro_export] -#[doc(hidden)] -macro_rules! ioc { - ($inout:expr, $group:expr, $num:expr, $len:expr) => { - $inout - | (($len as $crate::sys::ioctl::ioctl_num_type - & $crate::sys::ioctl::IOCPARM_MASK) - << 16) - | (($group as $crate::sys::ioctl::ioctl_num_type) << 8) - | ($num as $crate::sys::ioctl::ioctl_num_type) - }; -} - -/// Generate an ioctl request code for a command that passes no data. -/// -/// This is equivalent to the `_IO()` macro exposed by the C ioctl API. -/// -/// You should only use this macro directly if the `ioctl` you're working -/// with is "bad" and you cannot use `ioctl_none!()` directly. -/// -/// # Example -/// -/// ``` -/// # #[macro_use] extern crate nix; -/// const KVMIO: u8 = 0xAE; -/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03)); -/// # fn main() {} -/// ``` -#[macro_export(local_inner_macros)] -macro_rules! request_code_none { - ($g:expr, $n:expr) => { - ioc!($crate::sys::ioctl::VOID, $g, $n, 0) - }; -} - -/// Generate an ioctl request code for a command that passes an integer -/// -/// This is equivalent to the `_IOWINT()` macro exposed by the C ioctl API. -/// -/// You should only use this macro directly if the `ioctl` you're working -/// with is "bad" and you cannot use `ioctl_write_int!()` directly. -#[macro_export(local_inner_macros)] -macro_rules! request_code_write_int { - ($g:expr, $n:expr) => { - ioc!( - $crate::sys::ioctl::VOID, - $g, - $n, - ::std::mem::size_of::<$crate::libc::c_int>() - ) - }; -} - -/// Generate an ioctl request code for a command that reads. -/// -/// This is equivalent to the `_IOR()` macro exposed by the C ioctl API. -/// -/// You should only use this macro directly if the `ioctl` you're working -/// with is "bad" and you cannot use `ioctl_read!()` directly. -/// -/// The read/write direction is relative to userland, so this -/// command would be userland is reading and the kernel is -/// writing. -#[macro_export(local_inner_macros)] -macro_rules! request_code_read { - ($g:expr, $n:expr, $len:expr) => { - ioc!($crate::sys::ioctl::OUT, $g, $n, $len) - }; -} - -/// Generate an ioctl request code for a command that writes. -/// -/// This is equivalent to the `_IOW()` macro exposed by the C ioctl API. -/// -/// You should only use this macro directly if the `ioctl` you're working -/// with is "bad" and you cannot use `ioctl_write!()` directly. -/// -/// The read/write direction is relative to userland, so this -/// command would be userland is writing and the kernel is -/// reading. -#[macro_export(local_inner_macros)] -macro_rules! request_code_write { - ($g:expr, $n:expr, $len:expr) => { - ioc!($crate::sys::ioctl::IN, $g, $n, $len) - }; -} - -/// Generate an ioctl request code for a command that reads and writes. -/// -/// This is equivalent to the `_IOWR()` macro exposed by the C ioctl API. -/// -/// You should only use this macro directly if the `ioctl` you're working -/// with is "bad" and you cannot use `ioctl_readwrite!()` directly. -#[macro_export(local_inner_macros)] -macro_rules! request_code_readwrite { - ($g:expr, $n:expr, $len:expr) => { - ioc!($crate::sys::ioctl::INOUT, $g, $n, $len) - }; -} diff --git a/vendor/nix/src/sys/ioctl/linux.rs b/vendor/nix/src/sys/ioctl/linux.rs deleted file mode 100644 index 0c0a20905..000000000 --- a/vendor/nix/src/sys/ioctl/linux.rs +++ /dev/null @@ -1,172 +0,0 @@ -/// The datatype used for the ioctl number -#[cfg(any(target_os = "android", target_env = "musl"))] -#[doc(hidden)] -pub type ioctl_num_type = ::libc::c_int; -#[cfg(not(any(target_os = "android", target_env = "musl")))] -#[doc(hidden)] -pub type ioctl_num_type = ::libc::c_ulong; -/// The datatype used for the 3rd argument -#[doc(hidden)] -pub type ioctl_param_type = ::libc::c_ulong; - -#[doc(hidden)] -pub const NRBITS: ioctl_num_type = 8; -#[doc(hidden)] -pub const TYPEBITS: ioctl_num_type = 8; - -#[cfg(any( - target_arch = "mips", - target_arch = "mips64", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "sparc64" -))] -mod consts { - #[doc(hidden)] - pub const NONE: u8 = 1; - #[doc(hidden)] - pub const READ: u8 = 2; - #[doc(hidden)] - pub const WRITE: u8 = 4; - #[doc(hidden)] - pub const SIZEBITS: u8 = 13; - #[doc(hidden)] - pub const DIRBITS: u8 = 3; -} - -// "Generic" ioctl protocol -#[cfg(any( - target_arch = "x86", - target_arch = "arm", - target_arch = "s390x", - target_arch = "x86_64", - target_arch = "aarch64", - target_arch = "riscv32", - target_arch = "riscv64" -))] -mod consts { - #[doc(hidden)] - pub const NONE: u8 = 0; - #[doc(hidden)] - pub const READ: u8 = 2; - #[doc(hidden)] - pub const WRITE: u8 = 1; - #[doc(hidden)] - pub const SIZEBITS: u8 = 14; - #[doc(hidden)] - pub const DIRBITS: u8 = 2; -} - -pub use self::consts::*; - -#[doc(hidden)] -pub const NRSHIFT: ioctl_num_type = 0; -#[doc(hidden)] -pub const TYPESHIFT: ioctl_num_type = NRSHIFT + NRBITS as ioctl_num_type; -#[doc(hidden)] -pub const SIZESHIFT: ioctl_num_type = TYPESHIFT + TYPEBITS as ioctl_num_type; -#[doc(hidden)] -pub const DIRSHIFT: ioctl_num_type = SIZESHIFT + SIZEBITS as ioctl_num_type; - -#[doc(hidden)] -pub const NRMASK: ioctl_num_type = (1 << NRBITS) - 1; -#[doc(hidden)] -pub const TYPEMASK: ioctl_num_type = (1 << TYPEBITS) - 1; -#[doc(hidden)] -pub const SIZEMASK: ioctl_num_type = (1 << SIZEBITS) - 1; -#[doc(hidden)] -pub const DIRMASK: ioctl_num_type = (1 << DIRBITS) - 1; - -/// Encode an ioctl command. -#[macro_export] -#[doc(hidden)] -macro_rules! ioc { - ($dir:expr, $ty:expr, $nr:expr, $sz:expr) => { - (($dir as $crate::sys::ioctl::ioctl_num_type - & $crate::sys::ioctl::DIRMASK) - << $crate::sys::ioctl::DIRSHIFT) - | (($ty as $crate::sys::ioctl::ioctl_num_type - & $crate::sys::ioctl::TYPEMASK) - << $crate::sys::ioctl::TYPESHIFT) - | (($nr as $crate::sys::ioctl::ioctl_num_type - & $crate::sys::ioctl::NRMASK) - << $crate::sys::ioctl::NRSHIFT) - | (($sz as $crate::sys::ioctl::ioctl_num_type - & $crate::sys::ioctl::SIZEMASK) - << $crate::sys::ioctl::SIZESHIFT) - }; -} - -/// Generate an ioctl request code for a command that passes no data. -/// -/// This is equivalent to the `_IO()` macro exposed by the C ioctl API. -/// -/// You should only use this macro directly if the `ioctl` you're working -/// with is "bad" and you cannot use `ioctl_none!()` directly. -/// -/// # Example -/// -/// ``` -/// # #[macro_use] extern crate nix; -/// const KVMIO: u8 = 0xAE; -/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03)); -/// # fn main() {} -/// ``` -#[macro_export(local_inner_macros)] -macro_rules! request_code_none { - ($ty:expr, $nr:expr) => { - ioc!($crate::sys::ioctl::NONE, $ty, $nr, 0) - }; -} - -/// Generate an ioctl request code for a command that reads. -/// -/// This is equivalent to the `_IOR()` macro exposed by the C ioctl API. -/// -/// You should only use this macro directly if the `ioctl` you're working -/// with is "bad" and you cannot use `ioctl_read!()` directly. -/// -/// The read/write direction is relative to userland, so this -/// command would be userland is reading and the kernel is -/// writing. -#[macro_export(local_inner_macros)] -macro_rules! request_code_read { - ($ty:expr, $nr:expr, $sz:expr) => { - ioc!($crate::sys::ioctl::READ, $ty, $nr, $sz) - }; -} - -/// Generate an ioctl request code for a command that writes. -/// -/// This is equivalent to the `_IOW()` macro exposed by the C ioctl API. -/// -/// You should only use this macro directly if the `ioctl` you're working -/// with is "bad" and you cannot use `ioctl_write!()` directly. -/// -/// The read/write direction is relative to userland, so this -/// command would be userland is writing and the kernel is -/// reading. -#[macro_export(local_inner_macros)] -macro_rules! request_code_write { - ($ty:expr, $nr:expr, $sz:expr) => { - ioc!($crate::sys::ioctl::WRITE, $ty, $nr, $sz) - }; -} - -/// Generate an ioctl request code for a command that reads and writes. -/// -/// This is equivalent to the `_IOWR()` macro exposed by the C ioctl API. -/// -/// You should only use this macro directly if the `ioctl` you're working -/// with is "bad" and you cannot use `ioctl_readwrite!()` directly. -#[macro_export(local_inner_macros)] -macro_rules! request_code_readwrite { - ($ty:expr, $nr:expr, $sz:expr) => { - ioc!( - $crate::sys::ioctl::READ | $crate::sys::ioctl::WRITE, - $ty, - $nr, - $sz - ) - }; -} diff --git a/vendor/nix/src/sys/ioctl/mod.rs b/vendor/nix/src/sys/ioctl/mod.rs deleted file mode 100644 index 98d6b5c99..000000000 --- a/vendor/nix/src/sys/ioctl/mod.rs +++ /dev/null @@ -1,786 +0,0 @@ -//! Provide helpers for making ioctl system calls. -//! -//! This library is pretty low-level and messy. `ioctl` is not fun. -//! -//! What is an `ioctl`? -//! =================== -//! -//! The `ioctl` syscall is the grab-bag syscall on POSIX systems. Don't want to add a new -//! syscall? Make it an `ioctl`! `ioctl` refers to both the syscall, and the commands that can be -//! sent with it. `ioctl` stands for "IO control", and the commands are always sent to a file -//! descriptor. -//! -//! It is common to see `ioctl`s used for the following purposes: -//! -//! * Provide read/write access to out-of-band data related to a device such as configuration -//! (for instance, setting serial port options) -//! * Provide a mechanism for performing full-duplex data transfers (for instance, xfer on SPI -//! devices). -//! * Provide access to control functions on a device (for example, on Linux you can send -//! commands like pause, resume, and eject to the CDROM device. -//! * Do whatever else the device driver creator thought made most sense. -//! -//! `ioctl`s are synchronous system calls and are similar to read and write calls in that regard. -//! They operate on file descriptors and have an identifier that specifies what the ioctl is. -//! Additionally they may read or write data and therefore need to pass along a data pointer. -//! Besides the semantics of the ioctls being confusing, the generation of this identifer can also -//! be difficult. -//! -//! Historically `ioctl` numbers were arbitrary hard-coded values. In Linux (before 2.6) and some -//! unices this has changed to a more-ordered system where the ioctl numbers are partitioned into -//! subcomponents (For linux this is documented in -//! [`Documentation/ioctl/ioctl-number.rst`](https://elixir.bootlin.com/linux/latest/source/Documentation/userspace-api/ioctl/ioctl-number.rst)): -//! -//! * Number: The actual ioctl ID -//! * Type: A grouping of ioctls for a common purpose or driver -//! * Size: The size in bytes of the data that will be transferred -//! * Direction: Whether there is any data and if it's read, write, or both -//! -//! Newer drivers should not generate complete integer identifiers for their `ioctl`s instead -//! preferring to use the 4 components above to generate the final ioctl identifier. Because of -//! how old `ioctl`s are, however, there are many hard-coded `ioctl` identifiers. These are -//! commonly referred to as "bad" in `ioctl` documentation. -//! -//! Defining `ioctl`s -//! ================= -//! -//! This library provides several `ioctl_*!` macros for binding `ioctl`s. These generate public -//! unsafe functions that can then be used for calling the ioctl. This macro has a few different -//! ways it can be used depending on the specific ioctl you're working with. -//! -//! A simple `ioctl` is `SPI_IOC_RD_MODE`. This ioctl works with the SPI interface on Linux. This -//! specific `ioctl` reads the mode of the SPI device as a `u8`. It's declared in -//! `/include/uapi/linux/spi/spidev.h` as `_IOR(SPI_IOC_MAGIC, 1, __u8)`. Since it uses the `_IOR` -//! macro, we know it's a `read` ioctl and can use the `ioctl_read!` macro as follows: -//! -//! ``` -//! # #[macro_use] extern crate nix; -//! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h -//! const SPI_IOC_TYPE_MODE: u8 = 1; -//! ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8); -//! # fn main() {} -//! ``` -//! -//! This generates the function: -//! -//! ``` -//! # #[macro_use] extern crate nix; -//! # use std::mem; -//! # use nix::{libc, Result}; -//! # use nix::errno::Errno; -//! # use nix::libc::c_int as c_int; -//! # const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h -//! # const SPI_IOC_TYPE_MODE: u8 = 1; -//! pub unsafe fn spi_read_mode(fd: c_int, data: *mut u8) -> Result<c_int> { -//! let res = libc::ioctl(fd, request_code_read!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, mem::size_of::<u8>()), data); -//! Errno::result(res) -//! } -//! # fn main() {} -//! ``` -//! -//! The return value for the wrapper functions generated by the `ioctl_*!` macros are `nix::Error`s. -//! These are generated by assuming the return value of the ioctl is `-1` on error and everything -//! else is a valid return value. If this is not the case, `Result::map` can be used to map some -//! of the range of "good" values (-Inf..-2, 0..Inf) into a smaller range in a helper function. -//! -//! Writing `ioctl`s generally use pointers as their data source and these should use the -//! `ioctl_write_ptr!`. But in some cases an `int` is passed directly. For these `ioctl`s use the -//! `ioctl_write_int!` macro. This variant does not take a type as the last argument: -//! -//! ``` -//! # #[macro_use] extern crate nix; -//! const HCI_IOC_MAGIC: u8 = b'k'; -//! const HCI_IOC_HCIDEVUP: u8 = 1; -//! ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP); -//! # fn main() {} -//! ``` -//! -//! Some `ioctl`s don't transfer any data, and those should use `ioctl_none!`. This macro -//! doesn't take a type and so it is declared similar to the `write_int` variant shown above. -//! -//! The mode for a given `ioctl` should be clear from the documentation if it has good -//! documentation. Otherwise it will be clear based on the macro used to generate the `ioctl` -//! number where `_IO`, `_IOR`, `_IOW`, and `_IOWR` map to "none", "read", "write_*", and "readwrite" -//! respectively. To determine the specific `write_` variant to use you'll need to find -//! what the argument type is supposed to be. If it's an `int`, then `write_int` should be used, -//! otherwise it should be a pointer and `write_ptr` should be used. On Linux the -//! [`ioctl_list` man page](https://man7.org/linux/man-pages/man2/ioctl_list.2.html) describes a -//! large number of `ioctl`s and describes their argument data type. -//! -//! Using "bad" `ioctl`s -//! -------------------- -//! -//! As mentioned earlier, there are many old `ioctl`s that do not use the newer method of -//! generating `ioctl` numbers and instead use hardcoded values. These can be used with the -//! `ioctl_*_bad!` macros. This naming comes from the Linux kernel which refers to these -//! `ioctl`s as "bad". These are a different variant as they bypass calling the macro that generates -//! the ioctl number and instead use the defined value directly. -//! -//! For example the `TCGETS` `ioctl` reads a `termios` data structure for a given file descriptor. -//! It's defined as `0x5401` in `ioctls.h` on Linux and can be implemented as: -//! -//! ``` -//! # #[macro_use] extern crate nix; -//! # #[cfg(any(target_os = "android", target_os = "linux"))] -//! # use nix::libc::TCGETS as TCGETS; -//! # #[cfg(any(target_os = "android", target_os = "linux"))] -//! # use nix::libc::termios as termios; -//! # #[cfg(any(target_os = "android", target_os = "linux"))] -//! ioctl_read_bad!(tcgets, TCGETS, termios); -//! # fn main() {} -//! ``` -//! -//! The generated function has the same form as that generated by `ioctl_read!`: -//! -//! ```text -//! pub unsafe fn tcgets(fd: c_int, data: *mut termios) -> Result<c_int>; -//! ``` -//! -//! Working with Arrays -//! ------------------- -//! -//! Some `ioctl`s work with entire arrays of elements. These are supported by the `ioctl_*_buf` -//! family of macros: `ioctl_read_buf`, `ioctl_write_buf`, and `ioctl_readwrite_buf`. Note that -//! there are no "bad" versions for working with buffers. The generated functions include a `len` -//! argument to specify the number of elements (where the type of each element is specified in the -//! macro). -//! -//! Again looking to the SPI `ioctl`s on Linux for an example, there is a `SPI_IOC_MESSAGE` `ioctl` -//! that queues up multiple SPI messages by writing an entire array of `spi_ioc_transfer` structs. -//! `linux/spi/spidev.h` defines a macro to calculate the `ioctl` number like: -//! -//! ```C -//! #define SPI_IOC_MAGIC 'k' -//! #define SPI_MSGSIZE(N) ... -//! #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)]) -//! ``` -//! -//! The `SPI_MSGSIZE(N)` calculation is already handled by the `ioctl_*!` macros, so all that's -//! needed to define this `ioctl` is: -//! -//! ``` -//! # #[macro_use] extern crate nix; -//! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h -//! const SPI_IOC_TYPE_MESSAGE: u8 = 0; -//! # pub struct spi_ioc_transfer(u64); -//! ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer); -//! # fn main() {} -//! ``` -//! -//! This generates a function like: -//! -//! ``` -//! # #[macro_use] extern crate nix; -//! # use std::mem; -//! # use nix::{libc, Result}; -//! # use nix::errno::Errno; -//! # use nix::libc::c_int as c_int; -//! # const SPI_IOC_MAGIC: u8 = b'k'; -//! # const SPI_IOC_TYPE_MESSAGE: u8 = 0; -//! # pub struct spi_ioc_transfer(u64); -//! pub unsafe fn spi_message(fd: c_int, data: &mut [spi_ioc_transfer]) -> Result<c_int> { -//! let res = libc::ioctl(fd, -//! request_code_write!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, data.len() * mem::size_of::<spi_ioc_transfer>()), -//! data); -//! Errno::result(res) -//! } -//! # fn main() {} -//! ``` -//! -//! Finding `ioctl` Documentation -//! ----------------------------- -//! -//! For Linux, look at your system's headers. For example, `/usr/include/linux/input.h` has a lot -//! of lines defining macros which use `_IO`, `_IOR`, `_IOW`, `_IOC`, and `_IOWR`. Some `ioctl`s are -//! documented directly in the headers defining their constants, but others have more extensive -//! documentation in man pages (like termios' `ioctl`s which are in `tty_ioctl(4)`). -//! -//! Documenting the Generated Functions -//! =================================== -//! -//! In many cases, users will wish for the functions generated by the `ioctl` -//! macro to be public and documented. For this reason, the generated functions -//! are public by default. If you wish to hide the ioctl, you will need to put -//! them in a private module. -//! -//! For documentation, it is possible to use doc comments inside the `ioctl_*!` macros. Here is an -//! example : -//! -//! ``` -//! # #[macro_use] extern crate nix; -//! # use nix::libc::c_int; -//! ioctl_read! { -//! /// Make the given terminal the controlling terminal of the calling process. The calling -//! /// process must be a session leader and not have a controlling terminal already. If the -//! /// terminal is already the controlling terminal of a different session group then the -//! /// ioctl will fail with **EPERM**, unless the caller is root (more precisely: has the -//! /// **CAP_SYS_ADMIN** capability) and arg equals 1, in which case the terminal is stolen -//! /// and all processes that had it as controlling terminal lose it. -//! tiocsctty, b't', 19, c_int -//! } -//! -//! # fn main() {} -//! ``` -use cfg_if::cfg_if; - -#[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))] -#[macro_use] -mod linux; - -#[cfg(any( - target_os = "android", - target_os = "linux", - target_os = "redox" -))] -pub use self::linux::*; - -#[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "haiku", - target_os = "openbsd" -))] -#[macro_use] -mod bsd; - -#[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "haiku", - target_os = "openbsd" -))] -pub use self::bsd::*; - -/// Convert raw ioctl return value to a Nix result -#[macro_export] -#[doc(hidden)] -macro_rules! convert_ioctl_res { - ($w:expr) => {{ - $crate::errno::Errno::result($w) - }}; -} - -/// Generates a wrapper function for an ioctl that passes no data to the kernel. -/// -/// The arguments to this macro are: -/// -/// * The function name -/// * The ioctl identifier -/// * The ioctl sequence number -/// -/// The generated function has the following signature: -/// -/// ```rust,ignore -/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int> -/// ``` -/// -/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). -/// -/// # Example -/// -/// The `videodev2` driver on Linux defines the `log_status` `ioctl` as: -/// -/// ```C -/// #define VIDIOC_LOG_STATUS _IO('V', 70) -/// ``` -/// -/// This can be implemented in Rust like: -/// -/// ```no_run -/// # #[macro_use] extern crate nix; -/// ioctl_none!(log_status, b'V', 70); -/// fn main() {} -/// ``` -#[macro_export(local_inner_macros)] -macro_rules! ioctl_none { - ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => ( - $(#[$attr])* - pub unsafe fn $name(fd: $crate::libc::c_int) - -> $crate::Result<$crate::libc::c_int> { - convert_ioctl_res!($crate::libc::ioctl(fd, request_code_none!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type)) - } - ) -} - -/// Generates a wrapper function for a "bad" ioctl that passes no data to the kernel. -/// -/// The arguments to this macro are: -/// -/// * The function name -/// * The ioctl request code -/// -/// The generated function has the following signature: -/// -/// ```rust,ignore -/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int> -/// ``` -/// -/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). -/// -/// # Example -/// -/// ```no_run -/// # #[macro_use] extern crate nix; -/// # use libc::TIOCNXCL; -/// # use std::fs::File; -/// # use std::os::unix::io::AsRawFd; -/// ioctl_none_bad!(tiocnxcl, TIOCNXCL); -/// fn main() { -/// let file = File::open("/dev/ttyUSB0").unwrap(); -/// unsafe { tiocnxcl(file.as_raw_fd()) }.unwrap(); -/// } -/// ``` -// TODO: add an example using request_code_*!() -#[macro_export(local_inner_macros)] -macro_rules! ioctl_none_bad { - ($(#[$attr:meta])* $name:ident, $nr:expr) => ( - $(#[$attr])* - pub unsafe fn $name(fd: $crate::libc::c_int) - -> $crate::Result<$crate::libc::c_int> { - convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type)) - } - ) -} - -/// Generates a wrapper function for an ioctl that reads data from the kernel. -/// -/// The arguments to this macro are: -/// -/// * The function name -/// * The ioctl identifier -/// * The ioctl sequence number -/// * The data type passed by this ioctl -/// -/// The generated function has the following signature: -/// -/// ```rust,ignore -/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int> -/// ``` -/// -/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). -/// -/// # Example -/// -/// ``` -/// # #[macro_use] extern crate nix; -/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h -/// const SPI_IOC_TYPE_MODE: u8 = 1; -/// ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8); -/// # fn main() {} -/// ``` -#[macro_export(local_inner_macros)] -macro_rules! ioctl_read { - ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( - $(#[$attr])* - pub unsafe fn $name(fd: $crate::libc::c_int, - data: *mut $ty) - -> $crate::Result<$crate::libc::c_int> { - convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) - } - ) -} - -/// Generates a wrapper function for a "bad" ioctl that reads data from the kernel. -/// -/// The arguments to this macro are: -/// -/// * The function name -/// * The ioctl request code -/// * The data type passed by this ioctl -/// -/// The generated function has the following signature: -/// -/// ```rust,ignore -/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int> -/// ``` -/// -/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). -/// -/// # Example -/// -/// ``` -/// # #[macro_use] extern crate nix; -/// # #[cfg(any(target_os = "android", target_os = "linux"))] -/// ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios); -/// # fn main() {} -/// ``` -#[macro_export(local_inner_macros)] -macro_rules! ioctl_read_bad { - ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => ( - $(#[$attr])* - pub unsafe fn $name(fd: $crate::libc::c_int, - data: *mut $ty) - -> $crate::Result<$crate::libc::c_int> { - convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) - } - ) -} - -/// Generates a wrapper function for an ioctl that writes data through a pointer to the kernel. -/// -/// The arguments to this macro are: -/// -/// * The function name -/// * The ioctl identifier -/// * The ioctl sequence number -/// * The data type passed by this ioctl -/// -/// The generated function has the following signature: -/// -/// ```rust,ignore -/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int> -/// ``` -/// -/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). -/// -/// # Example -/// -/// ``` -/// # #[macro_use] extern crate nix; -/// # pub struct v4l2_audio {} -/// ioctl_write_ptr!(s_audio, b'V', 34, v4l2_audio); -/// # fn main() {} -/// ``` -#[macro_export(local_inner_macros)] -macro_rules! ioctl_write_ptr { - ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( - $(#[$attr])* - pub unsafe fn $name(fd: $crate::libc::c_int, - data: *const $ty) - -> $crate::Result<$crate::libc::c_int> { - convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) - } - ) -} - -/// Generates a wrapper function for a "bad" ioctl that writes data through a pointer to the kernel. -/// -/// The arguments to this macro are: -/// -/// * The function name -/// * The ioctl request code -/// * The data type passed by this ioctl -/// -/// The generated function has the following signature: -/// -/// ```rust,ignore -/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int> -/// ``` -/// -/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). -/// -/// # Example -/// -/// ``` -/// # #[macro_use] extern crate nix; -/// # #[cfg(any(target_os = "android", target_os = "linux"))] -/// ioctl_write_ptr_bad!(tcsets, libc::TCSETS, libc::termios); -/// # fn main() {} -/// ``` -#[macro_export(local_inner_macros)] -macro_rules! ioctl_write_ptr_bad { - ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => ( - $(#[$attr])* - pub unsafe fn $name(fd: $crate::libc::c_int, - data: *const $ty) - -> $crate::Result<$crate::libc::c_int> { - convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) - } - ) -} - -cfg_if! { - if #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] { - /// Generates a wrapper function for a ioctl that writes an integer to the kernel. - /// - /// The arguments to this macro are: - /// - /// * The function name - /// * The ioctl identifier - /// * The ioctl sequence number - /// - /// The generated function has the following signature: - /// - /// ```rust,ignore - /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int> - /// ``` - /// - /// `nix::sys::ioctl::ioctl_param_type` depends on the OS: - /// * BSD - `libc::c_int` - /// * Linux - `libc::c_ulong` - /// - /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). - /// - /// # Example - /// - /// ``` - /// # #[macro_use] extern crate nix; - /// ioctl_write_int!(vt_activate, b'v', 4); - /// # fn main() {} - /// ``` - #[macro_export(local_inner_macros)] - macro_rules! ioctl_write_int { - ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => ( - $(#[$attr])* - pub unsafe fn $name(fd: $crate::libc::c_int, - data: $crate::sys::ioctl::ioctl_param_type) - -> $crate::Result<$crate::libc::c_int> { - convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write_int!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type, data)) - } - ) - } - } else { - /// Generates a wrapper function for a ioctl that writes an integer to the kernel. - /// - /// The arguments to this macro are: - /// - /// * The function name - /// * The ioctl identifier - /// * The ioctl sequence number - /// - /// The generated function has the following signature: - /// - /// ```rust,ignore - /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int> - /// ``` - /// - /// `nix::sys::ioctl::ioctl_param_type` depends on the OS: - /// * BSD - `libc::c_int` - /// * Linux - `libc::c_ulong` - /// - /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). - /// - /// # Example - /// - /// ``` - /// # #[macro_use] extern crate nix; - /// const HCI_IOC_MAGIC: u8 = b'k'; - /// const HCI_IOC_HCIDEVUP: u8 = 1; - /// ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP); - /// # fn main() {} - /// ``` - #[macro_export(local_inner_macros)] - macro_rules! ioctl_write_int { - ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => ( - $(#[$attr])* - pub unsafe fn $name(fd: $crate::libc::c_int, - data: $crate::sys::ioctl::ioctl_param_type) - -> $crate::Result<$crate::libc::c_int> { - 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)) - } - ) - } - } -} - -/// Generates a wrapper function for a "bad" ioctl that writes an integer to the kernel. -/// -/// The arguments to this macro are: -/// -/// * The function name -/// * The ioctl request code -/// -/// The generated function has the following signature: -/// -/// ```rust,ignore -/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: libc::c_int) -> Result<libc::c_int> -/// ``` -/// -/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). -/// -/// # Examples -/// -/// ``` -/// # #[macro_use] extern crate nix; -/// # #[cfg(any(target_os = "android", target_os = "linux"))] -/// ioctl_write_int_bad!(tcsbrk, libc::TCSBRK); -/// # fn main() {} -/// ``` -/// -/// ```rust -/// # #[macro_use] extern crate nix; -/// const KVMIO: u8 = 0xAE; -/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03)); -/// # fn main() {} -/// ``` -#[macro_export(local_inner_macros)] -macro_rules! ioctl_write_int_bad { - ($(#[$attr:meta])* $name:ident, $nr:expr) => ( - $(#[$attr])* - pub unsafe fn $name(fd: $crate::libc::c_int, - data: $crate::libc::c_int) - -> $crate::Result<$crate::libc::c_int> { - convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) - } - ) -} - -/// Generates a wrapper function for an ioctl that reads and writes data to the kernel. -/// -/// The arguments to this macro are: -/// -/// * The function name -/// * The ioctl identifier -/// * The ioctl sequence number -/// * The data type passed by this ioctl -/// -/// The generated function has the following signature: -/// -/// ```rust,ignore -/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int> -/// ``` -/// -/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). -/// -/// # Example -/// -/// ``` -/// # #[macro_use] extern crate nix; -/// # pub struct v4l2_audio {} -/// ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio); -/// # fn main() {} -/// ``` -#[macro_export(local_inner_macros)] -macro_rules! ioctl_readwrite { - ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( - $(#[$attr])* - pub unsafe fn $name(fd: $crate::libc::c_int, - data: *mut $ty) - -> $crate::Result<$crate::libc::c_int> { - convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) - } - ) -} - -/// Generates a wrapper function for a "bad" ioctl that reads and writes data to the kernel. -/// -/// The arguments to this macro are: -/// -/// * The function name -/// * The ioctl request code -/// * The data type passed by this ioctl -/// -/// The generated function has the following signature: -/// -/// ```rust,ignore -/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int> -/// ``` -/// -/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). -// TODO: Find an example for ioctl_readwrite_bad -#[macro_export(local_inner_macros)] -macro_rules! ioctl_readwrite_bad { - ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => ( - $(#[$attr])* - pub unsafe fn $name(fd: $crate::libc::c_int, - data: *mut $ty) - -> $crate::Result<$crate::libc::c_int> { - convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data)) - } - ) -} - -/// Generates a wrapper function for an ioctl that reads an array of elements from the kernel. -/// -/// The arguments to this macro are: -/// -/// * The function name -/// * The ioctl identifier -/// * The ioctl sequence number -/// * The data type passed by this ioctl -/// -/// The generated function has the following signature: -/// -/// ```rust,ignore -/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int> -/// ``` -/// -/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). -// TODO: Find an example for ioctl_read_buf -#[macro_export(local_inner_macros)] -macro_rules! ioctl_read_buf { - ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( - $(#[$attr])* - pub unsafe fn $name(fd: $crate::libc::c_int, - data: &mut [$ty]) - -> $crate::Result<$crate::libc::c_int> { - convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) - } - ) -} - -/// Generates a wrapper function for an ioctl that writes an array of elements to the kernel. -/// -/// The arguments to this macro are: -/// -/// * The function name -/// * The ioctl identifier -/// * The ioctl sequence number -/// * The data type passed by this ioctl -/// -/// The generated function has the following signature: -/// -/// ```rust,ignore -/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &[DATA_TYPE]) -> Result<libc::c_int> -/// ``` -/// -/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). -/// -/// # Examples -/// -/// ``` -/// # #[macro_use] extern crate nix; -/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h -/// const SPI_IOC_TYPE_MESSAGE: u8 = 0; -/// # pub struct spi_ioc_transfer(u64); -/// ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer); -/// # fn main() {} -/// ``` -#[macro_export(local_inner_macros)] -macro_rules! ioctl_write_buf { - ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( - $(#[$attr])* - pub unsafe fn $name(fd: $crate::libc::c_int, - data: &[$ty]) - -> $crate::Result<$crate::libc::c_int> { - convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) - } - ) -} - -/// Generates a wrapper function for an ioctl that reads and writes an array of elements to the kernel. -/// -/// The arguments to this macro are: -/// -/// * The function name -/// * The ioctl identifier -/// * The ioctl sequence number -/// * The data type passed by this ioctl -/// -/// The generated function has the following signature: -/// -/// ```rust,ignore -/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int> -/// ``` -/// -/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html). -// TODO: Find an example for readwrite_buf -#[macro_export(local_inner_macros)] -macro_rules! ioctl_readwrite_buf { - ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => ( - $(#[$attr])* - pub unsafe fn $name(fd: $crate::libc::c_int, - data: &mut [$ty]) - -> $crate::Result<$crate::libc::c_int> { - convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data)) - } - ) -} |