pub const fn _IOW<T>(ty: u8, nr: u8) -> Ioctl<*const T>Expand description
Creates an Ioctl that writes data of type T to the kernel.
By default, a pointer to the data will be passed to ioctl(2), and the kernel will read the
argument from that location.
This is generally correct if the argument is a struct, but if the argument is a primitive type
like int, or is already a pointer like char*, many drivers expect the argument to be passed
to ioctl(2) without indirection.
To bind to those ioctls, you can call Ioctl::with_direct_arg on the Ioctl returned by
_IOW.
§Errors
This method will cause a compile-time assertion failure if the size of T exceeds the ioctl
argument size limit.
This typically means that the wrong type T was specified.
§Example
Let’s create a virtual input device with uinput.
From linux/uinput.h:
/* ioctl */
#define UINPUT_IOCTL_BASE 'U'
#define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1)
#define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2)
...
#define UI_DEV_SETUP _IOW(UINPUT_IOCTL_BASE, 3, struct uinput_setup)
...
#define UI_SET_EVBIT _IOW(UINPUT_IOCTL_BASE, 100, int)
#define UI_SET_KEYBIT _IOW(UINPUT_IOCTL_BASE, 101, int)From linux/input.h:
#define EV_KEY 0x01
...
#define KEY_A 30use std::{mem, fs::File, ffi::{c_char, c_int}};
use libc::uinput_setup;
use linux_ioctl::*;
const UINPUT_IOCTL_BASE: u8 = b'U';
const UI_DEV_CREATE: Ioctl<NoArgs> = _IO(UINPUT_IOCTL_BASE, 1);
const UI_DEV_DESTROY: Ioctl<NoArgs> = _IO(UINPUT_IOCTL_BASE, 2);
const UI_DEV_SETUP: Ioctl<*const uinput_setup> = _IOW(UINPUT_IOCTL_BASE, 3);
// These two expect their argument to be passed directly instead of behind a pointer:
const UI_SET_EVBIT: Ioctl<c_int> = _IOW(UINPUT_IOCTL_BASE, 100).with_direct_arg();
const UI_SET_KEYBIT: Ioctl<c_int> = _IOW(UINPUT_IOCTL_BASE, 101).with_direct_arg();
const EV_KEY: c_int = 0x01;
const KEY_A: c_int = 30;
let uinput = File::options().write(true).open("/dev/uinput")?;
// Enable the "A" key:
unsafe {
UI_SET_EVBIT.ioctl(&uinput, EV_KEY)?;
UI_SET_KEYBIT.ioctl(&uinput, KEY_A)?;
}
let mut setup: uinput_setup = unsafe { mem::zeroed() };
setup.name[0] = b'A' as c_char; // (must not be blank)
unsafe {
UI_DEV_SETUP.ioctl(&uinput, &setup)?;
UI_DEV_CREATE.ioctl(&uinput)?;
// ...use the device...
UI_DEV_DESTROY.ioctl(&uinput)?;
}