Skip to content

Commit 43b8a4a

Browse files
notgullsunfishcode
authored andcommitted
feat: Add Ioctl helper for integer arg (#1172)
Fixing low-hanging-fruit issue #1051. Signed-off-by: John Nunley <dev@notgull.net>
1 parent f9f84f6 commit 43b8a4a

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

src/ioctl/patterns.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,51 @@ unsafe impl<'a, Opcode: CompileTimeOpcode, T> Ioctl for Updater<'a, Opcode, T> {
197197
}
198198
}
199199

200+
/// Implements an `ioctl` that passes an integer into the `ioctl`.
201+
pub struct IntegerSetter<Opcode> {
202+
/// The value to pass in.
203+
value: usize,
204+
205+
/// The opcode.
206+
_opcode: PhantomData<Opcode>,
207+
}
208+
209+
impl<Opcode: CompileTimeOpcode> IntegerSetter<Opcode> {
210+
/// Create a new integer `Ioctl` helper.
211+
///
212+
/// # Safety
213+
///
214+
/// - `Opcode` must provide a valid opcode.
215+
/// - For this opcode, it must expect an integer.
216+
/// - The integer is in the valid range for this opcode.
217+
#[inline]
218+
pub unsafe fn new(value: usize) -> Self {
219+
Self {
220+
value,
221+
_opcode: PhantomData,
222+
}
223+
}
224+
}
225+
226+
unsafe impl<Opcode: CompileTimeOpcode> Ioctl for IntegerSetter<Opcode> {
227+
type Output = ();
228+
229+
const IS_MUTATING: bool = false;
230+
const OPCODE: self::Opcode = Opcode::OPCODE;
231+
232+
fn as_ptr(&mut self) -> *mut c::c_void {
233+
// TODO: strict provenance
234+
self.value as *mut c::c_void
235+
}
236+
237+
unsafe fn output_from_ptr(
238+
_out: IoctlOutput,
239+
_extract_output: *mut c::c_void,
240+
) -> Result<Self::Output> {
241+
Ok(())
242+
}
243+
}
244+
200245
/// Trait for something that provides an `ioctl` opcode at compile time.
201246
pub trait CompileTimeOpcode {
202247
/// The opcode.

tests/io/ioctl.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,20 @@ fn test_ioctls() {
1313
file.metadata().unwrap().len()
1414
);
1515
}
16+
17+
#[cfg(all(target_os = "linux", feature = "fs"))]
18+
#[test]
19+
fn test_int_setter() {
20+
use rustix::fs::{open, Mode, OFlags};
21+
use rustix::ioctl::{ioctl, BadOpcode, IntegerSetter, RawOpcode};
22+
23+
const TUNSETOFFLOAD: RawOpcode = 0x400454D0;
24+
25+
let tun = open("/dev/net/tun", OFlags::RDWR, Mode::empty()).unwrap();
26+
27+
// SAFETY: TUNSETOFFLOAD is defined for TUN.
28+
unsafe {
29+
let code = IntegerSetter::<BadOpcode<{ TUNSETOFFLOAD }>>::new(0);
30+
assert!(ioctl(&tun, code).is_err());
31+
}
32+
}

0 commit comments

Comments
 (0)