Skip to content

Commit 4525567

Browse files
committed
Add tests of actual ioctl usage
1 parent aeec797 commit 4525567

File tree

1 file changed

+179
-0
lines changed

1 file changed

+179
-0
lines changed

test/sys/test_ioctl.rs

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,182 @@ mod bsd {
146146
assert_eq!(iorw!(b'z', 10, (1 as u64) << 32), 0xC0007A0A);
147147
}
148148
}
149+
150+
#[cfg(any(target_os = "android", target_os = "linux"))]
151+
mod linux_ioctls {
152+
use std::mem;
153+
use std::os::unix::io::AsRawFd;
154+
155+
use tempfile::tempfile;
156+
use libc::{TCGETS, TCSBRK, TCSETS, TIOCNXCL, termios};
157+
158+
use nix::Error::Sys;
159+
use nix::errno::{ENOTTY, ENOSYS};
160+
161+
ioctl!(bad none tiocnxcl with TIOCNXCL);
162+
#[test]
163+
fn test_ioctl_bad_none() {
164+
let file = tempfile().unwrap();
165+
let res = unsafe { tiocnxcl(file.as_raw_fd()) };
166+
assert_eq!(res, Err(Sys(ENOTTY)));
167+
}
168+
169+
ioctl!(bad read tcgets with TCGETS; termios);
170+
#[test]
171+
fn test_ioctl_bad_read() {
172+
let file = tempfile().unwrap();
173+
let mut termios = unsafe { mem::uninitialized() };
174+
let res = unsafe { tcgets(file.as_raw_fd(), &mut termios) };
175+
assert_eq!(res, Err(Sys(ENOTTY)));
176+
}
177+
178+
ioctl!(bad write_int tcsbrk with TCSBRK);
179+
#[test]
180+
fn test_ioctl_bad_write_int() {
181+
let file = tempfile().unwrap();
182+
let res = unsafe { tcsbrk(file.as_raw_fd(), 0) };
183+
assert_eq!(res, Err(Sys(ENOTTY)));
184+
}
185+
186+
ioctl!(bad write_ptr tcsets with TCSETS; termios);
187+
#[test]
188+
fn test_ioctl_bad_write_ptr() {
189+
let file = tempfile().unwrap();
190+
let termios: termios = unsafe { mem::uninitialized() };
191+
let res = unsafe { tcsets(file.as_raw_fd(), &termios) };
192+
assert_eq!(res, Err(Sys(ENOTTY)));
193+
}
194+
195+
// FIXME: Find a suitable example for "bad readwrite".
196+
197+
// From linux/videodev2.h
198+
ioctl!(none log_status with b'V', 70);
199+
#[test]
200+
fn test_ioctl_none() {
201+
let file = tempfile().unwrap();
202+
let res = unsafe { log_status(file.as_raw_fd()) };
203+
assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
204+
}
205+
206+
#[repr(C)]
207+
pub struct v4l2_audio {
208+
index: u32,
209+
name: [u8; 32],
210+
capability: u32,
211+
mode: u32,
212+
reserved: [u32; 2],
213+
}
214+
215+
// From linux/videodev2.h
216+
ioctl!(write_ptr s_audio with b'V', 34; v4l2_audio);
217+
#[test]
218+
fn test_ioctl_read() {
219+
let file = tempfile().unwrap();
220+
let data: v4l2_audio = unsafe { mem::uninitialized() };
221+
let res = unsafe { g_audio(file.as_raw_fd(), &data) };
222+
assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
223+
}
224+
225+
// From linux/net/bluetooth/hci_sock.h
226+
const HCI_IOC_MAGIC: u8 = b'H';
227+
const HCI_IOC_HCIDEVUP: u8 = 201;
228+
ioctl!(write_int hcidevup with HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
229+
#[test]
230+
fn test_ioctl_write_int() {
231+
let file = tempfile().unwrap();
232+
let res = unsafe { hcidevup(file.as_raw_fd(), 0) };
233+
assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
234+
}
235+
236+
// From linux/videodev2.h
237+
ioctl!(write_ptr g_audio with b'V', 33; v4l2_audio);
238+
#[test]
239+
fn test_ioctl_write_ptr() {
240+
let file = tempfile().unwrap();
241+
let mut data: v4l2_audio = unsafe { mem::uninitialized() };
242+
let res = unsafe { g_audio(file.as_raw_fd(), &mut data) };
243+
assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
244+
}
245+
246+
// From linux/videodev2.h
247+
ioctl!(readwrite enum_audio with b'V', 65; v4l2_audio);
248+
#[test]
249+
fn test_ioctl_readwrite() {
250+
let file = tempfile().unwrap();
251+
let mut data: v4l2_audio = unsafe { mem::uninitialized() };
252+
let res = unsafe { enum_audio(file.as_raw_fd(), &mut data) };
253+
assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
254+
}
255+
256+
// FIXME: Find a suitable example for read_buf.
257+
258+
#[repr(C)]
259+
pub struct spi_ioc_transfer {
260+
tx_buf: u64,
261+
rx_buf: u64,
262+
len: u32,
263+
speed_hz: u32,
264+
delay_usecs: u16,
265+
bits_per_word: u8,
266+
cs_change: u8,
267+
tx_nbits: u8,
268+
rx_nbits: u8,
269+
pad: u16,
270+
}
271+
272+
// From linux/spi/spidev.h
273+
ioctl!(write_buf spi_ioc_message with super::SPI_IOC_MAGIC, super::SPI_IOC_MESSAGE; spi_ioc_transfer);
274+
#[test]
275+
fn test_ioctl_write_buf() {
276+
let file = tempfile().unwrap();
277+
let mut data: [spi_ioc_transfer; 4] = unsafe { mem::uninitialized() };
278+
let res = unsafe { spi_ioc_message(file.as_raw_fd(), &mut data[..]) };
279+
assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
280+
}
281+
282+
// FIXME: Find a suitable example for readwrite_buf.
283+
}
284+
285+
#[cfg(target_os = "freebsd")]
286+
mod freebsd_ioctls {
287+
use std::mem;
288+
use std::os::unix::io::AsRawFd;
289+
290+
use tempfile::tempfile;
291+
use libc::termios;
292+
293+
use nix::Error::Sys;
294+
use nix::errno::ENOTTY;
295+
296+
// From sys/sys/ttycom.h
297+
const TTY_IOC_MAGIC: u8 = b't';
298+
const TTY_IOC_TYPE_NXCL: u8 = 14;
299+
const TTY_IOC_TYPE_GETA: u8 = 19;
300+
const TTY_IOC_TYPE_SETA: u8 = 20;
301+
302+
ioctl!(none tiocnxcl with TTY_IOC_MAGIC, TTY_IOC_TYPE_NXCL);
303+
#[test]
304+
fn test_ioctl_none() {
305+
let file = tempfile().unwrap();
306+
let res = unsafe { tiocnxcl(file.as_raw_fd()) };
307+
assert_eq!(res, Err(Sys(ENOTTY)));
308+
}
309+
310+
ioctl!(read tiocgeta with TTY_IOC_MAGIC, TTY_IOC_TYPE_GETA; termios);
311+
#[test]
312+
fn test_ioctl_read() {
313+
let file = tempfile().unwrap();
314+
let mut termios = unsafe { mem::uninitialized() };
315+
let res = unsafe { tiocgeta(file.as_raw_fd(), &mut termios) };
316+
assert_eq!(res, Err(Sys(ENOTTY)));
317+
}
318+
319+
ioctl!(write_ptr tiocseta with TTY_IOC_MAGIC, TTY_IOC_TYPE_SETA; termios);
320+
#[test]
321+
fn test_ioctl_write_ptr() {
322+
let file = tempfile().unwrap();
323+
let termios: termios = unsafe { mem::uninitialized() };
324+
let res = unsafe { tiocseta(file.as_raw_fd(), &termios) };
325+
assert_eq!(res, Err(Sys(ENOTTY)));
326+
}
327+
}

0 commit comments

Comments
 (0)