Skip to content

Commit c407d8b

Browse files
authored
Simplify the ioctl API. (#1348)
* Simplify the `ioctl` API. As suggested [here], simplify the ioctl API by renaming `RawOpcode` to `Opcode` and using const generics. [here]: #1022 (comment) * Remove `none`'s `T` parameter. * Add more comments. * Reword `ioctl`'s safety comment to be more explicit about opcode choice.
1 parent 8308034 commit c407d8b

15 files changed

Lines changed: 207 additions & 281 deletions

File tree

CHANGES.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,5 +303,23 @@ vector before calling `epoll::wait` or `kqueue`, or consuming it using
303303
[`Buffer` trait]: https://docs.rs/rustix/1.0.0/rustix/buffer/trait.Buffer.html
304304
[`spare_capacity`]: https://docs.rs/rustix/1.0.0/rustix/buffer/fn.spare_capacity.html
305305

306+
The `Opcode` type has changed from a struct to a raw integer value, and the
307+
associated utilities are change to `const` functions. In place of `ReadOpcode`,
308+
`WriteOpcode`, `ReadWriteOpcode`, and `NoneOpcode`, use the `read`, `write`,
309+
`read_write`, and `none` const functions in the [`ioctl::opcode`] module. For
310+
example, in place of this:
311+
```rust
312+
ioctl::Setter::<ioctl::ReadOpcode<b'U', 15, c_uint>, c_uint>::new(interface)
313+
```
314+
use this:
315+
```rust
316+
+ ioctl::Setter::<{ ioctl::opcode::read::<c_uint>(b'U', 15) }, c_uint>::new(interface)
317+
```
318+
.
319+
320+
In place of `BadOpcode`, use the opcode value directly.
321+
322+
[`ioctl::opcode`]: https://docs.rs/rustix/1.0.0/rustix/ioctl/opcode/index.html
323+
306324
All explicitly deprecated functions and types have been removed. Their
307325
deprecation messages will have identified alternatives.

src/backend/libc/fs/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ pub(crate) mod types;
1616

1717
// TODO: Fix linux-raw-sys to define ioctl codes for sparc.
1818
#[cfg(all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64")))]
19-
pub(crate) const EXT4_IOC_RESIZE_FS: crate::ioctl::RawOpcode = 0x8008_6610;
19+
pub(crate) const EXT4_IOC_RESIZE_FS: crate::ioctl::Opcode = 0x8008_6610;
2020

2121
#[cfg(all(linux_kernel, not(any(target_arch = "sparc", target_arch = "sparc64"))))]
22-
pub(crate) const EXT4_IOC_RESIZE_FS: crate::ioctl::RawOpcode =
23-
linux_raw_sys::ioctl::EXT4_IOC_RESIZE_FS as crate::ioctl::RawOpcode;
22+
pub(crate) const EXT4_IOC_RESIZE_FS: crate::ioctl::Opcode =
23+
linux_raw_sys::ioctl::EXT4_IOC_RESIZE_FS as crate::ioctl::Opcode;

src/backend/libc/io/syscalls.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::io::DupFlags;
1616
#[cfg(linux_kernel)]
1717
use crate::io::ReadWriteFlags;
1818
use crate::io::{self, FdFlags};
19-
use crate::ioctl::{IoctlOutput, RawOpcode};
19+
use crate::ioctl::{IoctlOutput, Opcode};
2020
use core::cmp::min;
2121
#[cfg(not(any(target_os = "espidf", target_os = "horizon")))]
2222
use {
@@ -210,7 +210,7 @@ pub(crate) unsafe fn try_close(raw_fd: RawFd) -> io::Result<()> {
210210
#[inline]
211211
pub(crate) unsafe fn ioctl(
212212
fd: BorrowedFd<'_>,
213-
request: RawOpcode,
213+
request: Opcode,
214214
arg: *mut c::c_void,
215215
) -> io::Result<IoctlOutput> {
216216
ret_c_int(c::ioctl(borrowed_fd(fd), request, arg))
@@ -219,7 +219,7 @@ pub(crate) unsafe fn ioctl(
219219
#[inline]
220220
pub(crate) unsafe fn ioctl_readonly(
221221
fd: BorrowedFd<'_>,
222-
request: RawOpcode,
222+
request: Opcode,
223223
arg: *mut c::c_void,
224224
) -> io::Result<IoctlOutput> {
225225
ioctl(fd, request, arg)

src/backend/libc/io/windows_syscalls.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::backend::conv::{borrowed_fd, ret_c_int, ret_send_recv, send_recv_len}
77
use crate::backend::fd::LibcFd;
88
use crate::fd::{BorrowedFd, RawFd};
99
use crate::io;
10-
use crate::ioctl::{IoctlOutput, RawOpcode};
10+
use crate::ioctl::{IoctlOutput, Opcode};
1111

1212
pub(crate) unsafe fn read(fd: BorrowedFd<'_>, buf: (*mut u8, usize)) -> io::Result<usize> {
1313
// `read` on a socket is equivalent to `recv` with no flags.
@@ -43,7 +43,7 @@ pub(crate) unsafe fn try_close(raw_fd: RawFd) -> io::Result<()> {
4343
#[inline]
4444
pub(crate) unsafe fn ioctl(
4545
fd: BorrowedFd<'_>,
46-
request: RawOpcode,
46+
request: Opcode,
4747
arg: *mut c::c_void,
4848
) -> io::Result<IoctlOutput> {
4949
ret_c_int(c::ioctl(borrowed_fd(fd), request, arg.cast()))
@@ -52,7 +52,7 @@ pub(crate) unsafe fn ioctl(
5252
#[inline]
5353
pub(crate) unsafe fn ioctl_readonly(
5454
fd: BorrowedFd<'_>,
55-
request: RawOpcode,
55+
request: Opcode,
5656
arg: *mut c::c_void,
5757
) -> io::Result<IoctlOutput> {
5858
ioctl(fd, request, arg)

src/backend/linux_raw/io/syscalls.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::backend::conv::{hi, lo};
2727
use crate::backend::{c, MAX_IOV};
2828
use crate::fd::{AsFd as _, BorrowedFd, OwnedFd, RawFd};
2929
use crate::io::{self, DupFlags, FdFlags, IoSlice, IoSliceMut, ReadWriteFlags};
30-
use crate::ioctl::{IoctlOutput, RawOpcode};
30+
use crate::ioctl::{IoctlOutput, Opcode};
3131
use core::cmp;
3232
use linux_raw_sys::general::{F_DUPFD_CLOEXEC, F_GETFD, F_SETFD};
3333

@@ -272,7 +272,7 @@ pub(crate) unsafe fn try_close(fd: RawFd) -> io::Result<()> {
272272
#[inline]
273273
pub(crate) unsafe fn ioctl(
274274
fd: BorrowedFd<'_>,
275-
request: RawOpcode,
275+
request: Opcode,
276276
arg: *mut c::c_void,
277277
) -> io::Result<IoctlOutput> {
278278
ret_c_int(syscall!(__NR_ioctl, fd, c_uint(request), arg))
@@ -281,7 +281,7 @@ pub(crate) unsafe fn ioctl(
281281
#[inline]
282282
pub(crate) unsafe fn ioctl_readonly(
283283
fd: BorrowedFd<'_>,
284-
request: RawOpcode,
284+
request: Opcode,
285285
arg: *mut c::c_void,
286286
) -> io::Result<IoctlOutput> {
287287
ret_c_int(syscall_readonly!(__NR_ioctl, fd, c_uint(request), arg))

src/fs/ioctl.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use crate::fd::{AsRawFd as _, BorrowedFd};
2525
pub fn ioctl_blksszget<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
2626
// SAFETY: `BLZSSZGET` is a getter opcode that gets a u32.
2727
unsafe {
28-
let ctl = ioctl::Getter::<ioctl::BadOpcode<{ c::BLKSSZGET }>, c::c_uint>::new();
28+
let ctl = ioctl::Getter::<{ c::BLKSSZGET }, c::c_uint>::new();
2929
ioctl::ioctl(fd, ctl)
3030
}
3131
}
@@ -37,7 +37,7 @@ pub fn ioctl_blksszget<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
3737
pub fn ioctl_blkpbszget<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
3838
// SAFETY: `BLKPBSZGET` is a getter opcode that gets a u32.
3939
unsafe {
40-
let ctl = ioctl::Getter::<ioctl::BadOpcode<{ c::BLKPBSZGET }>, c::c_uint>::new();
40+
let ctl = ioctl::Getter::<{ c::BLKPBSZGET }, c::c_uint>::new();
4141
ioctl::ioctl(fd, ctl)
4242
}
4343
}
@@ -64,9 +64,7 @@ pub fn ioctl_ficlone<Fd: AsFd, SrcFd: AsFd>(fd: Fd, src_fd: SrcFd) -> io::Result
6464
pub fn ext4_ioc_resize_fs<Fd: AsFd>(fd: Fd, blocks: u64) -> io::Result<()> {
6565
// SAFETY: `EXT4_IOC_RESIZE_FS` is a pointer setter opcode.
6666
unsafe {
67-
let ctl = ioctl::Setter::<ioctl::BadOpcode<{ backend::fs::EXT4_IOC_RESIZE_FS }>, u64>::new(
68-
blocks,
69-
);
67+
let ctl = ioctl::Setter::<{ backend::fs::EXT4_IOC_RESIZE_FS }, u64>::new(blocks);
7068
ioctl::ioctl(fd, ctl)
7169
}
7270
}
@@ -81,7 +79,7 @@ unsafe impl ioctl::Ioctl for Ficlone<'_> {
8179
const IS_MUTATING: bool = false;
8280

8381
fn opcode(&self) -> ioctl::Opcode {
84-
ioctl::Opcode::old(c::FICLONE as ioctl::RawOpcode)
82+
c::FICLONE as ioctl::Opcode
8583
}
8684

8785
fn as_ptr(&mut self) -> *mut c::c_void {
@@ -144,9 +142,9 @@ bitflags! {
144142
pub fn ioctl_getflags<Fd: AsFd>(fd: Fd) -> io::Result<IFlags> {
145143
unsafe {
146144
#[cfg(target_pointer_width = "32")]
147-
let ctl = ioctl::Getter::<ioctl::BadOpcode<{ c::FS_IOC32_GETFLAGS }>, u32>::new();
145+
let ctl = ioctl::Getter::<{ c::FS_IOC32_GETFLAGS }, u32>::new();
148146
#[cfg(target_pointer_width = "64")]
149-
let ctl = ioctl::Getter::<ioctl::BadOpcode<{ c::FS_IOC_GETFLAGS }>, u32>::new();
147+
let ctl = ioctl::Getter::<{ c::FS_IOC_GETFLAGS }, u32>::new();
150148

151149
ioctl::ioctl(fd, ctl).map(IFlags::from_bits_retain)
152150
}
@@ -161,11 +159,10 @@ pub fn ioctl_getflags<Fd: AsFd>(fd: Fd) -> io::Result<IFlags> {
161159
pub fn ioctl_setflags<Fd: AsFd>(fd: Fd, flags: IFlags) -> io::Result<()> {
162160
unsafe {
163161
#[cfg(target_pointer_width = "32")]
164-
let ctl =
165-
ioctl::Setter::<ioctl::BadOpcode<{ c::FS_IOC32_SETFLAGS }>, u32>::new(flags.bits());
162+
let ctl = ioctl::Setter::<{ c::FS_IOC32_SETFLAGS }, u32>::new(flags.bits());
166163

167164
#[cfg(target_pointer_width = "64")]
168-
let ctl = ioctl::Setter::<ioctl::BadOpcode<{ c::FS_IOC_SETFLAGS }>, u32>::new(flags.bits());
165+
let ctl = ioctl::Setter::<{ c::FS_IOC_SETFLAGS }, u32>::new(flags.bits());
169166

170167
ioctl::ioctl(fd, ctl)
171168
}

src/io/ioctl.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use backend::fd::AsFd;
2323
pub fn ioctl_fioclex<Fd: AsFd>(fd: Fd) -> io::Result<()> {
2424
// SAFETY: `FIOCLEX` is a no-argument setter opcode.
2525
unsafe {
26-
let ctl = ioctl::NoArg::<ioctl::BadOpcode<{ c::FIOCLEX }>>::new();
26+
let ctl = ioctl::NoArg::<{ c::FIOCLEX }>::new();
2727
ioctl::ioctl(fd, ctl)
2828
}
2929
}
@@ -43,7 +43,7 @@ pub fn ioctl_fioclex<Fd: AsFd>(fd: Fd) -> io::Result<()> {
4343
pub fn ioctl_fionbio<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
4444
// SAFETY: `FIONBIO` is a pointer setter opcode.
4545
unsafe {
46-
let ctl = ioctl::Setter::<ioctl::BadOpcode<{ c::FIONBIO }>, c::c_int>::new(value.into());
46+
let ctl = ioctl::Setter::<{ c::FIONBIO }, c::c_int>::new(value.into());
4747
ioctl::ioctl(fd, ctl)
4848
}
4949
}
@@ -71,7 +71,7 @@ pub fn ioctl_fionbio<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
7171
pub fn ioctl_fionread<Fd: AsFd>(fd: Fd) -> io::Result<u64> {
7272
// SAFETY: `FIONREAD` is a getter opcode that gets a `c_int`.
7373
unsafe {
74-
let ctl = ioctl::Getter::<ioctl::BadOpcode<{ c::FIONREAD }>, c::c_int>::new();
74+
let ctl = ioctl::Getter::<{ c::FIONREAD }, c::c_int>::new();
7575
ioctl::ioctl(fd, ctl).map(|n| n as u64)
7676
}
7777
}

src/ioctl/bsd.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
//! `ioctl` opcode behavior for BSD platforms.
22
3-
use super::{Direction, RawOpcode};
3+
use super::{Direction, Opcode};
44

55
pub(super) const fn compose_opcode(
66
dir: Direction,
7-
group: RawOpcode,
8-
num: RawOpcode,
9-
size: RawOpcode,
10-
) -> RawOpcode {
7+
group: Opcode,
8+
num: Opcode,
9+
size: Opcode,
10+
) -> Opcode {
1111
let dir = match dir {
1212
Direction::None => NONE,
1313
Direction::Read => READ,
@@ -19,9 +19,9 @@ pub(super) const fn compose_opcode(
1919
}
2020

2121
// `IOC_VOID`
22-
pub const NONE: RawOpcode = 0x2000_0000;
22+
pub const NONE: Opcode = 0x2000_0000;
2323
// `IOC_OUT` (“out” is from the perspective of the kernel)
24-
pub const READ: RawOpcode = 0x4000_0000;
24+
pub const READ: Opcode = 0x4000_0000;
2525
// `IOC_IN` (“in” is from the perspective of the kernel)
26-
pub const WRITE: RawOpcode = 0x8000_0000;
27-
pub const IOCPARAM_MASK: RawOpcode = 0x1FFF;
26+
pub const WRITE: Opcode = 0x8000_0000;
27+
pub const IOCPARAM_MASK: Opcode = 0x1FFF;

src/ioctl/linux.rs

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
//! `ioctl` opcode behavior for Linux platforms.
22
3-
use super::{Direction, RawOpcode};
3+
use super::{Direction, Opcode};
44
use consts::*;
55

66
/// Compose an opcode from its component parts.
77
pub(super) const fn compose_opcode(
88
dir: Direction,
9-
group: RawOpcode,
10-
num: RawOpcode,
11-
size: RawOpcode,
12-
) -> RawOpcode {
9+
group: Opcode,
10+
num: Opcode,
11+
size: Opcode,
12+
) -> Opcode {
1313
macro_rules! mask_and_shift {
1414
($val:expr, $shift:expr, $mask:expr) => {{
1515
($val & $mask) << $shift
@@ -29,18 +29,18 @@ pub(super) const fn compose_opcode(
2929
| mask_and_shift!(dir, DIR_SHIFT, DIR_MASK)
3030
}
3131

32-
const NUM_BITS: RawOpcode = 8;
33-
const GROUP_BITS: RawOpcode = 8;
32+
const NUM_BITS: Opcode = 8;
33+
const GROUP_BITS: Opcode = 8;
3434

35-
const NUM_SHIFT: RawOpcode = 0;
36-
const GROUP_SHIFT: RawOpcode = NUM_SHIFT + NUM_BITS;
37-
const SIZE_SHIFT: RawOpcode = GROUP_SHIFT + GROUP_BITS;
38-
const DIR_SHIFT: RawOpcode = SIZE_SHIFT + SIZE_BITS;
35+
const NUM_SHIFT: Opcode = 0;
36+
const GROUP_SHIFT: Opcode = NUM_SHIFT + NUM_BITS;
37+
const SIZE_SHIFT: Opcode = GROUP_SHIFT + GROUP_BITS;
38+
const DIR_SHIFT: Opcode = SIZE_SHIFT + SIZE_BITS;
3939

40-
const NUM_MASK: RawOpcode = (1 << NUM_BITS) - 1;
41-
const GROUP_MASK: RawOpcode = (1 << GROUP_BITS) - 1;
42-
const SIZE_MASK: RawOpcode = (1 << SIZE_BITS) - 1;
43-
const DIR_MASK: RawOpcode = (1 << DIR_BITS) - 1;
40+
const NUM_MASK: Opcode = (1 << NUM_BITS) - 1;
41+
const GROUP_MASK: Opcode = (1 << GROUP_BITS) - 1;
42+
const SIZE_MASK: Opcode = (1 << SIZE_BITS) - 1;
43+
const DIR_MASK: Opcode = (1 << DIR_BITS) - 1;
4444

4545
#[cfg(any(
4646
target_arch = "x86",
@@ -54,13 +54,13 @@ const DIR_MASK: RawOpcode = (1 << DIR_BITS) - 1;
5454
target_arch = "csky"
5555
))]
5656
mod consts {
57-
use super::RawOpcode;
57+
use super::Opcode;
5858

59-
pub(super) const NONE: RawOpcode = 0;
60-
pub(super) const READ: RawOpcode = 2;
61-
pub(super) const WRITE: RawOpcode = 1;
62-
pub(super) const SIZE_BITS: RawOpcode = 14;
63-
pub(super) const DIR_BITS: RawOpcode = 2;
59+
pub(super) const NONE: Opcode = 0;
60+
pub(super) const READ: Opcode = 2;
61+
pub(super) const WRITE: Opcode = 1;
62+
pub(super) const SIZE_BITS: Opcode = 14;
63+
pub(super) const DIR_BITS: Opcode = 2;
6464
}
6565

6666
#[cfg(any(
@@ -74,13 +74,13 @@ mod consts {
7474
target_arch = "sparc64"
7575
))]
7676
mod consts {
77-
use super::RawOpcode;
77+
use super::Opcode;
7878

79-
pub(super) const NONE: RawOpcode = 1;
80-
pub(super) const READ: RawOpcode = 2;
81-
pub(super) const WRITE: RawOpcode = 4;
82-
pub(super) const SIZE_BITS: RawOpcode = 13;
83-
pub(super) const DIR_BITS: RawOpcode = 3;
79+
pub(super) const NONE: Opcode = 1;
80+
pub(super) const READ: Opcode = 2;
81+
pub(super) const WRITE: Opcode = 4;
82+
pub(super) const SIZE_BITS: Opcode = 13;
83+
pub(super) const DIR_BITS: Opcode = 3;
8484
}
8585

8686
#[cfg(not(any(
@@ -98,11 +98,11 @@ fn check_known_opcodes() {
9898
assert_eq!(
9999
compose_opcode(
100100
Direction::Read,
101-
b'U' as RawOpcode,
101+
b'U' as Opcode,
102102
15,
103-
size_of::<c_uint>() as RawOpcode
103+
size_of::<c_uint>() as Opcode
104104
),
105-
linux_raw_sys::ioctl::USBDEVFS_CLAIMINTERFACE as RawOpcode
105+
linux_raw_sys::ioctl::USBDEVFS_CLAIMINTERFACE as Opcode
106106
);
107107

108108
// _IOW('v', 2, long)
@@ -111,10 +111,10 @@ fn check_known_opcodes() {
111111
assert_eq!(
112112
compose_opcode(
113113
Direction::Write,
114-
b'v' as RawOpcode,
114+
b'v' as Opcode,
115115
2,
116-
size_of::<c_long>() as RawOpcode
116+
size_of::<c_long>() as Opcode
117117
),
118-
linux_raw_sys::ioctl::FS_IOC_SETVERSION as RawOpcode
118+
linux_raw_sys::ioctl::FS_IOC_SETVERSION as Opcode
119119
);
120120
}

0 commit comments

Comments
 (0)