Skip to content

Commit

Permalink
Use ioctl numbers from C libs
Browse files Browse the repository at this point in the history
Generate the desired ioctl numbers are compile time using
the native macros and compare to the ones generated by
our own macros.
  • Loading branch information
Susurrus committed Jul 20, 2017
1 parent 44ed4c0 commit f8d2e37
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 125 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ bitflags = "0.9"
cfg-if = "0.1.0"
void = "1.0.2"

[build-dependencies]
gcc = "0.3"

[dev-dependencies]
lazy_static = "0.2"
rand = "0.3.8"
Expand Down
7 changes: 7 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
extern crate gcc;

fn main() {
gcc::Config::new()
.file("ioctls.c")
.compile("libioctls.a");
}
10 changes: 10 additions & 0 deletions ioctls.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include <sys/ioctl.h>
#include <stdint.h>

uint64_t io_a_255() {
return _IO('a', 255);
}

uint64_t io_q_10() {
return _IO('q', 10);
}
117 changes: 117 additions & 0 deletions src/sys/ioctl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,3 +318,120 @@ macro_rules! ioctl {
}
);
}

mod test {
pub use super::ioctl_num_type as ioctl_num_type;

extern {
fn io_q_10() -> u64();
fn io_a_255() -> u64();
}

#[test]
fn test_io() {
assert_eq!(io!(b'q', 10), unsafe { io_q_10() } as ioctl_num_type);
assert_eq!(io!(b'a', 255), unsafe { io_a_255() } as ioctl_num_type);
}
}

#[cfg(any(target_os = "linux", target_os = "android"))]
mod linux {
#[test]
fn test_op_write() {
if cfg!(any(target_arch = "mips", target_arch="powerpc", target_arch="powerpc64")){
assert_eq!(iow!(b'z', 10, 1), 0x80017A0A);
assert_eq!(iow!(b'z', 10, 512), 0x82007A0A);
} else {
assert_eq!(iow!(b'z', 10, 1), 0x40017A0A);
assert_eq!(iow!(b'z', 10, 512), 0x42007A0A);
}
}

#[cfg(target_pointer_width = "64")]
#[test]
fn test_op_write_64() {
if cfg!(any(target_arch="powerpc64")){
assert_eq!(iow!(b'z', 10, (1 as u64) << 32), 0x80007A0A);
} else {
assert_eq!(iow!(b'z', 10, (1 as u64) << 32), 0x40007A0A);
}

}

#[test]
fn test_op_read() {
if cfg!(any(target_arch = "mips", target_arch="powerpc", target_arch="powerpc64")){
assert_eq!(ior!(b'z', 10, 1), 0x40017A0A);
assert_eq!(ior!(b'z', 10, 512), 0x42007A0A);
} else {
assert_eq!(ior!(b'z', 10, 1), 0x80017A0A);
assert_eq!(ior!(b'z', 10, 512), 0x82007A0A);
}
}

#[cfg(target_pointer_width = "64")]
#[test]
fn test_op_read_64() {
if cfg!(any(target_arch="powerpc64")){
assert_eq!(ior!(b'z', 10, (1 as u64) << 32), 0x40007A0A);
} else {
assert_eq!(ior!(b'z', 10, (1 as u64) << 32), 0x80007A0A);
}
}

#[test]
fn test_op_read_write() {
assert_eq!(iorw!(b'z', 10, 1), 0xC0017A0A);
assert_eq!(iorw!(b'z', 10, 512), 0xC2007A0A);
}

#[cfg(target_pointer_width = "64")]
#[test]
fn test_op_read_write_64() {
assert_eq!(iorw!(b'z', 10, (1 as u64) << 32), 0xC0007A0A);
}
}

#[cfg(any(target_os = "macos",
target_os = "ios",
target_os = "netbsd",
target_os = "openbsd",
target_os = "freebsd",
target_os = "dragonfly"))]
mod bsd {
#[test]
fn test_op_write() {
assert_eq!(iow!(b'z', 10, 1), 0x80017A0A);
assert_eq!(iow!(b'z', 10, 512), 0x82007A0A);
}

#[cfg(target_pointer_width = "64")]
#[test]
fn test_op_write_64() {
assert_eq!(iow!(b'z', 10, (1 as u64) << 32), 0x80007A0A);
}

#[test]
fn test_op_read() {
assert_eq!(ior!(b'z', 10, 1), 0x40017A0A);
assert_eq!(ior!(b'z', 10, 512), 0x42007A0A);
}

#[cfg(target_pointer_width = "64")]
#[test]
fn test_op_read_64() {
assert_eq!(ior!(b'z', 10, (1 as u64) << 32), 0x40007A0A);
}

#[test]
fn test_op_read_write() {
assert_eq!(iorw!(b'z', 10, 1), 0xC0017A0A);
assert_eq!(iorw!(b'z', 10, 512), 0xC2007A0A);
}

#[cfg(target_pointer_width = "64")]
#[test]
fn test_op_read_write_64() {
assert_eq!(iorw!(b'z', 10, (1 as u64) << 32), 0xC0007A0A);
}
}
125 changes: 0 additions & 125 deletions test/sys/test_ioctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,128 +160,3 @@ mod linux_ioctls {

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

// See C code for source of values for op calculations (does NOT work for mips/powerpc):
// https://gist.github.com/posborne/83ea6880770a1aef332e
//
// TODO: Need a way to compute these constants at test time. Using precomputed
// values is fragile and needs to be maintained.

#[cfg(any(target_os = "linux", target_os = "android"))]
mod linux {
#[test]
fn test_op_none() {
if cfg!(any(target_arch = "mips", target_arch="powerpc", target_arch="powerpc64")){
assert_eq!(io!(b'q', 10), 0x2000710A);
assert_eq!(io!(b'a', 255), 0x200061FF);
} else {
assert_eq!(io!(b'q', 10), 0x0000710A);
assert_eq!(io!(b'a', 255), 0x000061FF);
}
}

#[test]
fn test_op_write() {
if cfg!(any(target_arch = "mips", target_arch="powerpc", target_arch="powerpc64")){
assert_eq!(iow!(b'z', 10, 1), 0x80017A0A);
assert_eq!(iow!(b'z', 10, 512), 0x82007A0A);
} else {
assert_eq!(iow!(b'z', 10, 1), 0x40017A0A);
assert_eq!(iow!(b'z', 10, 512), 0x42007A0A);
}
}

#[cfg(target_pointer_width = "64")]
#[test]
fn test_op_write_64() {
if cfg!(any(target_arch="powerpc64")){
assert_eq!(iow!(b'z', 10, (1 as u64) << 32), 0x80007A0A);
} else {
assert_eq!(iow!(b'z', 10, (1 as u64) << 32), 0x40007A0A);
}

}

#[test]
fn test_op_read() {
if cfg!(any(target_arch = "mips", target_arch="powerpc", target_arch="powerpc64")){
assert_eq!(ior!(b'z', 10, 1), 0x40017A0A);
assert_eq!(ior!(b'z', 10, 512), 0x42007A0A);
} else {
assert_eq!(ior!(b'z', 10, 1), 0x80017A0A);
assert_eq!(ior!(b'z', 10, 512), 0x82007A0A);
}
}

#[cfg(target_pointer_width = "64")]
#[test]
fn test_op_read_64() {
if cfg!(any(target_arch="powerpc64")){
assert_eq!(ior!(b'z', 10, (1 as u64) << 32), 0x40007A0A);
} else {
assert_eq!(ior!(b'z', 10, (1 as u64) << 32), 0x80007A0A);
}
}

#[test]
fn test_op_read_write() {
assert_eq!(iorw!(b'z', 10, 1), 0xC0017A0A);
assert_eq!(iorw!(b'z', 10, 512), 0xC2007A0A);
}

#[cfg(target_pointer_width = "64")]
#[test]
fn test_op_read_write_64() {
assert_eq!(iorw!(b'z', 10, (1 as u64) << 32), 0xC0007A0A);
}
}

#[cfg(any(target_os = "macos",
target_os = "ios",
target_os = "netbsd",
target_os = "openbsd",
target_os = "freebsd",
target_os = "dragonfly"))]
mod bsd {
#[test]
fn test_op_none() {
assert_eq!(io!(b'q', 10), 0x2000710A);
assert_eq!(io!(b'a', 255), 0x200061FF);
}

#[test]
fn test_op_write() {
assert_eq!(iow!(b'z', 10, 1), 0x80017A0A);
assert_eq!(iow!(b'z', 10, 512), 0x82007A0A);
}

#[cfg(target_pointer_width = "64")]
#[test]
fn test_op_write_64() {
assert_eq!(iow!(b'z', 10, (1 as u64) << 32), 0x80007A0A);
}

#[test]
fn test_op_read() {
assert_eq!(ior!(b'z', 10, 1), 0x40017A0A);
assert_eq!(ior!(b'z', 10, 512), 0x42007A0A);
}

#[cfg(target_pointer_width = "64")]
#[test]
fn test_op_read_64() {
assert_eq!(ior!(b'z', 10, (1 as u64) << 32), 0x40007A0A);
}

#[test]
fn test_op_read_write() {
assert_eq!(iorw!(b'z', 10, 1), 0xC0017A0A);
assert_eq!(iorw!(b'z', 10, 512), 0xC2007A0A);
}

#[cfg(target_pointer_width = "64")]
#[test]
fn test_op_read_write_64() {
assert_eq!(iorw!(b'z', 10, (1 as u64) << 32), 0xC0007A0A);
}
}

0 comments on commit f8d2e37

Please sign in to comment.