Skip to content

Commit

Permalink
Add tests of actual ioctl usage
Browse files Browse the repository at this point in the history
  • Loading branch information
Susurrus authored and marmistrz committed Jul 25, 2017
1 parent b6ad298 commit 845453b
Showing 1 changed file with 179 additions and 0 deletions.
179 changes: 179 additions & 0 deletions test/sys/test_ioctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,182 @@ mod bsd {
assert_eq!(iorw!(b'z', 10, (1 as u64) << 32), 0xC0007A0A);
}
}

#[cfg(any(target_os = "android", target_os = "linux"))]
mod linux_ioctls {
use std::mem;
use std::os::unix::io::AsRawFd;

use tempfile::tempfile;
use libc::{TCGETS, TCSBRK, TCSETS, TIOCNXCL, termios};

use nix::Error::Sys;
use nix::errno::{ENOTTY, ENOSYS};

ioctl!(bad none tiocnxcl with TIOCNXCL);
#[test]
fn test_ioctl_bad_none() {
let file = tempfile().unwrap();
let res = unsafe { tiocnxcl(file.as_raw_fd()) };
assert_eq!(res, Err(Sys(ENOTTY)));
}

ioctl!(bad read tcgets with TCGETS; termios);
#[test]
fn test_ioctl_bad_read() {
let file = tempfile().unwrap();
let mut termios = unsafe { mem::uninitialized() };
let res = unsafe { tcgets(file.as_raw_fd(), &mut termios) };
assert_eq!(res, Err(Sys(ENOTTY)));
}

ioctl!(bad write_int tcsbrk with TCSBRK);
#[test]
fn test_ioctl_bad_write_int() {
let file = tempfile().unwrap();
let res = unsafe { tcsbrk(file.as_raw_fd(), 0) };
assert_eq!(res, Err(Sys(ENOTTY)));
}

ioctl!(bad write_ptr tcsets with TCSETS; termios);
#[test]
fn test_ioctl_bad_write_ptr() {
let file = tempfile().unwrap();
let termios: termios = unsafe { mem::uninitialized() };
let res = unsafe { tcsets(file.as_raw_fd(), &termios) };
assert_eq!(res, Err(Sys(ENOTTY)));
}

// FIXME: Find a suitable example for "bad readwrite".

// From linux/videodev2.h
ioctl!(none log_status with b'V', 70);
#[test]
fn test_ioctl_none() {
let file = tempfile().unwrap();
let res = unsafe { log_status(file.as_raw_fd()) };
assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
}

#[repr(C)]
pub struct v4l2_audio {
index: u32,
name: [u8; 32],
capability: u32,
mode: u32,
reserved: [u32; 2],
}

// From linux/videodev2.h
ioctl!(write_ptr s_audio with b'V', 34; v4l2_audio);
#[test]
fn test_ioctl_read() {
let file = tempfile().unwrap();
let data: v4l2_audio = unsafe { mem::uninitialized() };
let res = unsafe { g_audio(file.as_raw_fd(), &data) };
assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
}

// From linux/net/bluetooth/hci_sock.h
const HCI_IOC_MAGIC: u8 = b'H';
const HCI_IOC_HCIDEVUP: u8 = 201;
ioctl!(write_int hcidevup with HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
#[test]
fn test_ioctl_write_int() {
let file = tempfile().unwrap();
let res = unsafe { hcidevup(file.as_raw_fd(), 0) };
assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
}

// From linux/videodev2.h
ioctl!(write_ptr g_audio with b'V', 33; v4l2_audio);
#[test]
fn test_ioctl_write_ptr() {
let file = tempfile().unwrap();
let mut data: v4l2_audio = unsafe { mem::uninitialized() };
let res = unsafe { g_audio(file.as_raw_fd(), &mut data) };
assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
}

// From linux/videodev2.h
ioctl!(readwrite enum_audio with b'V', 65; v4l2_audio);
#[test]
fn test_ioctl_readwrite() {
let file = tempfile().unwrap();
let mut data: v4l2_audio = unsafe { mem::uninitialized() };
let res = unsafe { enum_audio(file.as_raw_fd(), &mut data) };
assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
}

// FIXME: Find a suitable example for read_buf.

#[repr(C)]
pub struct spi_ioc_transfer {
tx_buf: u64,
rx_buf: u64,
len: u32,
speed_hz: u32,
delay_usecs: u16,
bits_per_word: u8,
cs_change: u8,
tx_nbits: u8,
rx_nbits: u8,
pad: u16,
}

// From linux/spi/spidev.h
ioctl!(write_buf spi_ioc_message with super::SPI_IOC_MAGIC, super::SPI_IOC_MESSAGE; spi_ioc_transfer);
#[test]
fn test_ioctl_write_buf() {
let file = tempfile().unwrap();
let mut data: [spi_ioc_transfer; 4] = unsafe { mem::uninitialized() };
let res = unsafe { spi_ioc_message(file.as_raw_fd(), &mut data[..]) };
assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
}

// FIXME: Find a suitable example for readwrite_buf.
}

#[cfg(target_os = "freebsd")]
mod freebsd_ioctls {
use std::mem;
use std::os::unix::io::AsRawFd;

use tempfile::tempfile;
use libc::termios;

use nix::Error::Sys;
use nix::errno::ENOTTY;

// From sys/sys/ttycom.h
const TTY_IOC_MAGIC: u8 = b't';
const TTY_IOC_TYPE_NXCL: u8 = 14;
const TTY_IOC_TYPE_GETA: u8 = 19;
const TTY_IOC_TYPE_SETA: u8 = 20;

ioctl!(none tiocnxcl with TTY_IOC_MAGIC, TTY_IOC_TYPE_NXCL);
#[test]
fn test_ioctl_none() {
let file = tempfile().unwrap();
let res = unsafe { tiocnxcl(file.as_raw_fd()) };
assert_eq!(res, Err(Sys(ENOTTY)));
}

ioctl!(read tiocgeta with TTY_IOC_MAGIC, TTY_IOC_TYPE_GETA; termios);
#[test]
fn test_ioctl_read() {
let file = tempfile().unwrap();
let mut termios = unsafe { mem::uninitialized() };
let res = unsafe { tiocgeta(file.as_raw_fd(), &mut termios) };
assert_eq!(res, Err(Sys(ENOTTY)));
}

ioctl!(write_ptr tiocseta with TTY_IOC_MAGIC, TTY_IOC_TYPE_SETA; termios);
#[test]
fn test_ioctl_write_ptr() {
let file = tempfile().unwrap();
let termios: termios = unsafe { mem::uninitialized() };
let res = unsafe { tiocseta(file.as_raw_fd(), &termios) };
assert_eq!(res, Err(Sys(ENOTTY)));
}
}

0 comments on commit 845453b

Please sign in to comment.