Struct Ioctl

Source
pub struct Ioctl<T: ?Sized = NoArgs> { /* private fields */ }
Expand description

An ioctl.

Ioctl can represent ioctls that take either no arguments or a single argument. If T is NoArgs, the ioctl takes no arguments. For other values of T, the ioctl takes T as its only argument. Often, the argument T is a pointer or reference to a struct that contains the actual arguments.

While Ioctl cannot handle ioctls that require passing more than one argument to the ioctl(2) function, Linux doesn’t have any ioctls that take more than one argument, and is unlikely to gain any in the future.

The Ioctl type is constructed with the free functions _IO, _IOR, _IOW, _IOWR, and _IOC. For legacy ioctls, it can also be created via Ioctl::from_raw.

Implementations§

Source§

impl<T: ?Sized> Ioctl<T>

Source

pub const fn from_raw(request: u32) -> Self

Creates an Ioctl object from a raw request code and an arbitrary argument type.

This can be used for legacy ioctls that were defined before the _IOx macros were introduced.

§Examples

From asm-generic/ioctls.h:

#define FIONREAD	0x541B

From man 2const FIONREAD:

DESCRIPTION
    FIONREAD
        Get the number of bytes in the input buffer.
    ...
SYNOPSIS
    ...
    int ioctl(int fd, FIONREAD, int *argp);
    ...
use std::io;
use std::fs::File;
use std::ffi::c_int;
use linux_ioctl::*;

const FIONREAD: Ioctl<*mut c_int> = Ioctl::from_raw(0x541B);

let file = File::open("/dev/ptmx")
    .map_err(|e| io::Error::new(e.kind(), format!("failed to open `/dev/ptmx`: {e}")))?;

let mut bytes = c_int::MAX;
unsafe { FIONREAD.ioctl(&file, &mut bytes)? };
assert_ne!(bytes, c_int::MAX);

println!("{} bytes in input buffer", bytes);
Source

pub const fn with_arg<T2>(self) -> Ioctl<T2>

Changes the ioctl argument type to T2.

This can be used for ioctls that incorrectly declare their type, or for ioctls that take a by-value argument, rather than _IOW-type ioctls that take their argument indirectly through a pointer.

Returns an Ioctl that passes an argument of type T2 to the kernel, while using the ioctl request code from self.

§Examples

The KVM_CREATE_VM ioctl is declared with _IO, but takes an int as its argument, specifying the VM type (KVM_VM_*).

From linux/kvm.h:

#define KVMIO 0xAE
...
#define KVM_CREATE_VM             _IO(KVMIO,   0x01) /* returns a VM fd */
use std::fs::File;
use std::ffi::c_int;
use linux_ioctl::*;

const KVMIO: u8 = 0xAE;
const KVM_CREATE_VM: Ioctl<c_int> = _IO(KVMIO, 0x01).with_arg::<c_int>();

// The `KVM_CREATE_VM` ioctl takes the VM type as an argument. 0 is a reasonable default on
// most architectures.
let vm_type: c_int = 0;

let file = File::open("/dev/kvm")?;

let vm_fd = unsafe { KVM_CREATE_VM.ioctl(&file, vm_type)? };
println!("created new VM with file descriptor {vm_fd}");

unsafe { libc::close(vm_fd) };
Source

pub fn request(self) -> u32

Returns the ioctl request code.

This is passed to ioctl(2) as its second argument.

Source§

impl Ioctl<NoArgs>

Source

pub unsafe fn ioctl(self, fd: &impl AsRawFd) -> Result<c_int>

Performs an ioctl that doesn’t take an argument.

On success, returns the value returned by the ioctl syscall. On error (when ioctl returns -1), returns the error from errno.

Note that the actual ioctl(2) call performed will pass 0 as a dummy argument to the ioctl. This is because some Linux ioctls are declared without an argument, but will fail unless they receive 0 as their argument (eg. KVM_GET_API_VERSION). There should be no harm in passing this argument unconditionally, as the kernel will typically just ignore excess arguments.

§Safety

This method performs an arbitrary ioctl on an arbitrary file descriptor. The caller has to ensure that any safety requirements of the ioctl are met, and that fd belongs to the driver it expects.

Source§

impl<T> Ioctl<T>

Source

pub unsafe fn ioctl(self, fd: &impl AsRawFd, arg: T) -> Result<c_int>

Performs an ioctl that takes an argument of type T.

Returns the value returned by the ioctl(2) invocation, or an I/O error if the call failed.

For many ioctls, T will be a pointer to the actual argument. The caller must ensure that it points to valid data that conforms to the requirements of the ioctl.

§Safety

This method performs an arbitrary ioctl on an arbitrary file descriptor. The caller has to ensure that any safety requirements of the ioctl are met, and that fd belongs to the driver it expects.

Trait Implementations§

Source§

impl<T: ?Sized> Clone for Ioctl<T>

Source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: ?Sized> Copy for Ioctl<T>

Auto Trait Implementations§

§

impl<T> Freeze for Ioctl<T>
where T: ?Sized,

§

impl<T> RefUnwindSafe for Ioctl<T>
where T: RefUnwindSafe + ?Sized,

§

impl<T> Send for Ioctl<T>
where T: Send + ?Sized,

§

impl<T> Sync for Ioctl<T>
where T: Sync + ?Sized,

§

impl<T> Unpin for Ioctl<T>
where T: Unpin + ?Sized,

§

impl<T> UnwindSafe for Ioctl<T>
where T: UnwindSafe + ?Sized,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.