13da5c369Sopenharmony_ci#![allow(dead_code)] 23da5c369Sopenharmony_ci 33da5c369Sopenharmony_ci// Simple tests to ensure macro generated fns compile 43da5c369Sopenharmony_ciioctl_none_bad!(do_bad, 0x1234); 53da5c369Sopenharmony_ciioctl_read_bad!(do_bad_read, 0x1234, u16); 63da5c369Sopenharmony_ciioctl_write_int_bad!(do_bad_write_int, 0x1234); 73da5c369Sopenharmony_ciioctl_write_ptr_bad!(do_bad_write_ptr, 0x1234, u8); 83da5c369Sopenharmony_ciioctl_readwrite_bad!(do_bad_readwrite, 0x1234, u32); 93da5c369Sopenharmony_ciioctl_none!(do_none, 0, 0); 103da5c369Sopenharmony_ciioctl_read!(read_test, 0, 0, u32); 113da5c369Sopenharmony_ciioctl_write_int!(write_ptr_int, 0, 0); 123da5c369Sopenharmony_ciioctl_write_ptr!(write_ptr_u8, 0, 0, u8); 133da5c369Sopenharmony_ciioctl_write_ptr!(write_ptr_u32, 0, 0, u32); 143da5c369Sopenharmony_ciioctl_write_ptr!(write_ptr_u64, 0, 0, u64); 153da5c369Sopenharmony_ciioctl_readwrite!(readwrite_test, 0, 0, u64); 163da5c369Sopenharmony_ciioctl_read_buf!(readbuf_test, 0, 0, u32); 173da5c369Sopenharmony_ciconst SPI_IOC_MAGIC: u8 = b'k'; 183da5c369Sopenharmony_ciconst SPI_IOC_MESSAGE: u8 = 0; 193da5c369Sopenharmony_ciioctl_write_buf!(writebuf_test_consts, SPI_IOC_MAGIC, SPI_IOC_MESSAGE, u8); 203da5c369Sopenharmony_ciioctl_write_buf!(writebuf_test_u8, 0, 0, u8); 213da5c369Sopenharmony_ciioctl_write_buf!(writebuf_test_u32, 0, 0, u32); 223da5c369Sopenharmony_ciioctl_write_buf!(writebuf_test_u64, 0, 0, u64); 233da5c369Sopenharmony_ciioctl_readwrite_buf!(readwritebuf_test, 0, 0, u32); 243da5c369Sopenharmony_ci 253da5c369Sopenharmony_ci// See C code for source of values for op calculations (does NOT work for mips/powerpc): 263da5c369Sopenharmony_ci// https://gist.github.com/posborne/83ea6880770a1aef332e 273da5c369Sopenharmony_ci// 283da5c369Sopenharmony_ci// TODO: Need a way to compute these constants at test time. Using precomputed 293da5c369Sopenharmony_ci// values is fragile and needs to be maintained. 303da5c369Sopenharmony_ci 313da5c369Sopenharmony_ci#[cfg(any(target_os = "linux", target_os = "android"))] 323da5c369Sopenharmony_cimod linux { 333da5c369Sopenharmony_ci // The cast is not unnecessary on all platforms. 343da5c369Sopenharmony_ci #[allow(clippy::unnecessary_cast)] 353da5c369Sopenharmony_ci #[test] 363da5c369Sopenharmony_ci fn test_op_none() { 373da5c369Sopenharmony_ci if cfg!(any( 383da5c369Sopenharmony_ci target_arch = "mips", 393da5c369Sopenharmony_ci target_arch = "mips64", 403da5c369Sopenharmony_ci target_arch = "powerpc", 413da5c369Sopenharmony_ci target_arch = "powerpc64" 423da5c369Sopenharmony_ci )) { 433da5c369Sopenharmony_ci assert_eq!(request_code_none!(b'q', 10) as u32, 0x2000_710A); 443da5c369Sopenharmony_ci assert_eq!(request_code_none!(b'a', 255) as u32, 0x2000_61FF); 453da5c369Sopenharmony_ci } else { 463da5c369Sopenharmony_ci assert_eq!(request_code_none!(b'q', 10) as u32, 0x0000_710A); 473da5c369Sopenharmony_ci assert_eq!(request_code_none!(b'a', 255) as u32, 0x0000_61FF); 483da5c369Sopenharmony_ci } 493da5c369Sopenharmony_ci } 503da5c369Sopenharmony_ci 513da5c369Sopenharmony_ci // The cast is not unnecessary on all platforms. 523da5c369Sopenharmony_ci #[allow(clippy::unnecessary_cast)] 533da5c369Sopenharmony_ci #[test] 543da5c369Sopenharmony_ci fn test_op_write() { 553da5c369Sopenharmony_ci if cfg!(any( 563da5c369Sopenharmony_ci target_arch = "mips", 573da5c369Sopenharmony_ci target_arch = "mips64", 583da5c369Sopenharmony_ci target_arch = "powerpc", 593da5c369Sopenharmony_ci target_arch = "powerpc64" 603da5c369Sopenharmony_ci )) { 613da5c369Sopenharmony_ci assert_eq!(request_code_write!(b'z', 10, 1) as u32, 0x8001_7A0A); 623da5c369Sopenharmony_ci assert_eq!(request_code_write!(b'z', 10, 512) as u32, 0x8200_7A0A); 633da5c369Sopenharmony_ci } else { 643da5c369Sopenharmony_ci assert_eq!(request_code_write!(b'z', 10, 1) as u32, 0x4001_7A0A); 653da5c369Sopenharmony_ci assert_eq!(request_code_write!(b'z', 10, 512) as u32, 0x4200_7A0A); 663da5c369Sopenharmony_ci } 673da5c369Sopenharmony_ci } 683da5c369Sopenharmony_ci 693da5c369Sopenharmony_ci #[cfg(target_pointer_width = "64")] 703da5c369Sopenharmony_ci #[test] 713da5c369Sopenharmony_ci fn test_op_write_64() { 723da5c369Sopenharmony_ci if cfg!(any(target_arch = "mips64", target_arch = "powerpc64")) { 733da5c369Sopenharmony_ci assert_eq!( 743da5c369Sopenharmony_ci request_code_write!(b'z', 10, 1u64 << 32) as u32, 753da5c369Sopenharmony_ci 0x8000_7A0A 763da5c369Sopenharmony_ci ); 773da5c369Sopenharmony_ci } else { 783da5c369Sopenharmony_ci assert_eq!( 793da5c369Sopenharmony_ci request_code_write!(b'z', 10, 1u64 << 32) as u32, 803da5c369Sopenharmony_ci 0x4000_7A0A 813da5c369Sopenharmony_ci ); 823da5c369Sopenharmony_ci } 833da5c369Sopenharmony_ci } 843da5c369Sopenharmony_ci 853da5c369Sopenharmony_ci // The cast is not unnecessary on all platforms. 863da5c369Sopenharmony_ci #[allow(clippy::unnecessary_cast)] 873da5c369Sopenharmony_ci #[test] 883da5c369Sopenharmony_ci fn test_op_read() { 893da5c369Sopenharmony_ci if cfg!(any( 903da5c369Sopenharmony_ci target_arch = "mips", 913da5c369Sopenharmony_ci target_arch = "mips64", 923da5c369Sopenharmony_ci target_arch = "powerpc", 933da5c369Sopenharmony_ci target_arch = "powerpc64" 943da5c369Sopenharmony_ci )) { 953da5c369Sopenharmony_ci assert_eq!(request_code_read!(b'z', 10, 1) as u32, 0x4001_7A0A); 963da5c369Sopenharmony_ci assert_eq!(request_code_read!(b'z', 10, 512) as u32, 0x4200_7A0A); 973da5c369Sopenharmony_ci } else { 983da5c369Sopenharmony_ci assert_eq!(request_code_read!(b'z', 10, 1) as u32, 0x8001_7A0A); 993da5c369Sopenharmony_ci assert_eq!(request_code_read!(b'z', 10, 512) as u32, 0x8200_7A0A); 1003da5c369Sopenharmony_ci } 1013da5c369Sopenharmony_ci } 1023da5c369Sopenharmony_ci 1033da5c369Sopenharmony_ci #[cfg(target_pointer_width = "64")] 1043da5c369Sopenharmony_ci #[test] 1053da5c369Sopenharmony_ci fn test_op_read_64() { 1063da5c369Sopenharmony_ci if cfg!(any(target_arch = "mips64", target_arch = "powerpc64")) { 1073da5c369Sopenharmony_ci assert_eq!( 1083da5c369Sopenharmony_ci request_code_read!(b'z', 10, 1u64 << 32) as u32, 1093da5c369Sopenharmony_ci 0x4000_7A0A 1103da5c369Sopenharmony_ci ); 1113da5c369Sopenharmony_ci } else { 1123da5c369Sopenharmony_ci assert_eq!( 1133da5c369Sopenharmony_ci request_code_read!(b'z', 10, 1u64 << 32) as u32, 1143da5c369Sopenharmony_ci 0x8000_7A0A 1153da5c369Sopenharmony_ci ); 1163da5c369Sopenharmony_ci } 1173da5c369Sopenharmony_ci } 1183da5c369Sopenharmony_ci 1193da5c369Sopenharmony_ci // The cast is not unnecessary on all platforms. 1203da5c369Sopenharmony_ci #[allow(clippy::unnecessary_cast)] 1213da5c369Sopenharmony_ci #[test] 1223da5c369Sopenharmony_ci fn test_op_read_write() { 1233da5c369Sopenharmony_ci assert_eq!(request_code_readwrite!(b'z', 10, 1) as u32, 0xC001_7A0A); 1243da5c369Sopenharmony_ci assert_eq!(request_code_readwrite!(b'z', 10, 512) as u32, 0xC200_7A0A); 1253da5c369Sopenharmony_ci } 1263da5c369Sopenharmony_ci 1273da5c369Sopenharmony_ci #[cfg(target_pointer_width = "64")] 1283da5c369Sopenharmony_ci #[test] 1293da5c369Sopenharmony_ci fn test_op_read_write_64() { 1303da5c369Sopenharmony_ci assert_eq!( 1313da5c369Sopenharmony_ci request_code_readwrite!(b'z', 10, 1u64 << 32) as u32, 1323da5c369Sopenharmony_ci 0xC000_7A0A 1333da5c369Sopenharmony_ci ); 1343da5c369Sopenharmony_ci } 1353da5c369Sopenharmony_ci} 1363da5c369Sopenharmony_ci 1373da5c369Sopenharmony_ci#[cfg(any( 1383da5c369Sopenharmony_ci target_os = "dragonfly", 1393da5c369Sopenharmony_ci target_os = "freebsd", 1403da5c369Sopenharmony_ci target_os = "ios", 1413da5c369Sopenharmony_ci target_os = "macos", 1423da5c369Sopenharmony_ci target_os = "netbsd", 1433da5c369Sopenharmony_ci target_os = "openbsd" 1443da5c369Sopenharmony_ci))] 1453da5c369Sopenharmony_cimod bsd { 1463da5c369Sopenharmony_ci #[test] 1473da5c369Sopenharmony_ci fn test_op_none() { 1483da5c369Sopenharmony_ci assert_eq!(request_code_none!(b'q', 10), 0x2000_710A); 1493da5c369Sopenharmony_ci assert_eq!(request_code_none!(b'a', 255), 0x2000_61FF); 1503da5c369Sopenharmony_ci } 1513da5c369Sopenharmony_ci 1523da5c369Sopenharmony_ci #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] 1533da5c369Sopenharmony_ci #[test] 1543da5c369Sopenharmony_ci fn test_op_write_int() { 1553da5c369Sopenharmony_ci assert_eq!(request_code_write_int!(b'v', 4), 0x2004_7604); 1563da5c369Sopenharmony_ci assert_eq!(request_code_write_int!(b'p', 2), 0x2004_7002); 1573da5c369Sopenharmony_ci } 1583da5c369Sopenharmony_ci 1593da5c369Sopenharmony_ci #[test] 1603da5c369Sopenharmony_ci fn test_op_write() { 1613da5c369Sopenharmony_ci assert_eq!(request_code_write!(b'z', 10, 1), 0x8001_7A0A); 1623da5c369Sopenharmony_ci assert_eq!(request_code_write!(b'z', 10, 512), 0x8200_7A0A); 1633da5c369Sopenharmony_ci } 1643da5c369Sopenharmony_ci 1653da5c369Sopenharmony_ci #[cfg(target_pointer_width = "64")] 1663da5c369Sopenharmony_ci #[test] 1673da5c369Sopenharmony_ci fn test_op_write_64() { 1683da5c369Sopenharmony_ci assert_eq!(request_code_write!(b'z', 10, 1u64 << 32), 0x8000_7A0A); 1693da5c369Sopenharmony_ci } 1703da5c369Sopenharmony_ci 1713da5c369Sopenharmony_ci #[test] 1723da5c369Sopenharmony_ci fn test_op_read() { 1733da5c369Sopenharmony_ci assert_eq!(request_code_read!(b'z', 10, 1), 0x4001_7A0A); 1743da5c369Sopenharmony_ci assert_eq!(request_code_read!(b'z', 10, 512), 0x4200_7A0A); 1753da5c369Sopenharmony_ci } 1763da5c369Sopenharmony_ci 1773da5c369Sopenharmony_ci #[cfg(target_pointer_width = "64")] 1783da5c369Sopenharmony_ci #[test] 1793da5c369Sopenharmony_ci fn test_op_read_64() { 1803da5c369Sopenharmony_ci assert_eq!(request_code_read!(b'z', 10, 1u64 << 32), 0x4000_7A0A); 1813da5c369Sopenharmony_ci } 1823da5c369Sopenharmony_ci 1833da5c369Sopenharmony_ci #[test] 1843da5c369Sopenharmony_ci fn test_op_read_write() { 1853da5c369Sopenharmony_ci assert_eq!(request_code_readwrite!(b'z', 10, 1), 0xC001_7A0A); 1863da5c369Sopenharmony_ci assert_eq!(request_code_readwrite!(b'z', 10, 512), 0xC200_7A0A); 1873da5c369Sopenharmony_ci } 1883da5c369Sopenharmony_ci 1893da5c369Sopenharmony_ci #[cfg(target_pointer_width = "64")] 1903da5c369Sopenharmony_ci #[test] 1913da5c369Sopenharmony_ci fn test_op_read_write_64() { 1923da5c369Sopenharmony_ci assert_eq!(request_code_readwrite!(b'z', 10, 1u64 << 32), 0xC000_7A0A); 1933da5c369Sopenharmony_ci } 1943da5c369Sopenharmony_ci} 1953da5c369Sopenharmony_ci 1963da5c369Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))] 1973da5c369Sopenharmony_cimod linux_ioctls { 1983da5c369Sopenharmony_ci use std::mem; 1993da5c369Sopenharmony_ci use std::os::unix::io::AsRawFd; 2003da5c369Sopenharmony_ci 2013da5c369Sopenharmony_ci use libc::{termios, TCGETS, TCSBRK, TCSETS, TIOCNXCL}; 2023da5c369Sopenharmony_ci use tempfile::tempfile; 2033da5c369Sopenharmony_ci 2043da5c369Sopenharmony_ci use nix::errno::Errno; 2053da5c369Sopenharmony_ci 2063da5c369Sopenharmony_ci ioctl_none_bad!(tiocnxcl, TIOCNXCL); 2073da5c369Sopenharmony_ci #[test] 2083da5c369Sopenharmony_ci fn test_ioctl_none_bad() { 2093da5c369Sopenharmony_ci let file = tempfile().unwrap(); 2103da5c369Sopenharmony_ci let res = unsafe { tiocnxcl(file.as_raw_fd()) }; 2113da5c369Sopenharmony_ci assert_eq!(res, Err(Errno::ENOTTY)); 2123da5c369Sopenharmony_ci } 2133da5c369Sopenharmony_ci 2143da5c369Sopenharmony_ci ioctl_read_bad!(tcgets, TCGETS, termios); 2153da5c369Sopenharmony_ci #[test] 2163da5c369Sopenharmony_ci fn test_ioctl_read_bad() { 2173da5c369Sopenharmony_ci let file = tempfile().unwrap(); 2183da5c369Sopenharmony_ci let mut termios = unsafe { mem::zeroed() }; 2193da5c369Sopenharmony_ci let res = unsafe { tcgets(file.as_raw_fd(), &mut termios) }; 2203da5c369Sopenharmony_ci assert_eq!(res, Err(Errno::ENOTTY)); 2213da5c369Sopenharmony_ci } 2223da5c369Sopenharmony_ci 2233da5c369Sopenharmony_ci ioctl_write_int_bad!(tcsbrk, TCSBRK); 2243da5c369Sopenharmony_ci #[test] 2253da5c369Sopenharmony_ci fn test_ioctl_write_int_bad() { 2263da5c369Sopenharmony_ci let file = tempfile().unwrap(); 2273da5c369Sopenharmony_ci let res = unsafe { tcsbrk(file.as_raw_fd(), 0) }; 2283da5c369Sopenharmony_ci assert_eq!(res, Err(Errno::ENOTTY)); 2293da5c369Sopenharmony_ci } 2303da5c369Sopenharmony_ci 2313da5c369Sopenharmony_ci ioctl_write_ptr_bad!(tcsets, TCSETS, termios); 2323da5c369Sopenharmony_ci #[test] 2333da5c369Sopenharmony_ci fn test_ioctl_write_ptr_bad() { 2343da5c369Sopenharmony_ci let file = tempfile().unwrap(); 2353da5c369Sopenharmony_ci let termios: termios = unsafe { mem::zeroed() }; 2363da5c369Sopenharmony_ci let res = unsafe { tcsets(file.as_raw_fd(), &termios) }; 2373da5c369Sopenharmony_ci assert_eq!(res, Err(Errno::ENOTTY)); 2383da5c369Sopenharmony_ci } 2393da5c369Sopenharmony_ci 2403da5c369Sopenharmony_ci // FIXME: Find a suitable example for `ioctl_readwrite_bad` 2413da5c369Sopenharmony_ci 2423da5c369Sopenharmony_ci // From linux/videodev2.h 2433da5c369Sopenharmony_ci ioctl_none!(log_status, b'V', 70); 2443da5c369Sopenharmony_ci #[test] 2453da5c369Sopenharmony_ci fn test_ioctl_none() { 2463da5c369Sopenharmony_ci let file = tempfile().unwrap(); 2473da5c369Sopenharmony_ci let res = unsafe { log_status(file.as_raw_fd()) }; 2483da5c369Sopenharmony_ci assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); 2493da5c369Sopenharmony_ci } 2503da5c369Sopenharmony_ci 2513da5c369Sopenharmony_ci #[repr(C)] 2523da5c369Sopenharmony_ci pub struct v4l2_audio { 2533da5c369Sopenharmony_ci index: u32, 2543da5c369Sopenharmony_ci name: [u8; 32], 2553da5c369Sopenharmony_ci capability: u32, 2563da5c369Sopenharmony_ci mode: u32, 2573da5c369Sopenharmony_ci reserved: [u32; 2], 2583da5c369Sopenharmony_ci } 2593da5c369Sopenharmony_ci 2603da5c369Sopenharmony_ci // From linux/videodev2.h 2613da5c369Sopenharmony_ci ioctl_write_ptr!(s_audio, b'V', 34, v4l2_audio); 2623da5c369Sopenharmony_ci #[test] 2633da5c369Sopenharmony_ci fn test_ioctl_write_ptr() { 2643da5c369Sopenharmony_ci let file = tempfile().unwrap(); 2653da5c369Sopenharmony_ci let data: v4l2_audio = unsafe { mem::zeroed() }; 2663da5c369Sopenharmony_ci let res = unsafe { s_audio(file.as_raw_fd(), &data) }; 2673da5c369Sopenharmony_ci assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); 2683da5c369Sopenharmony_ci } 2693da5c369Sopenharmony_ci 2703da5c369Sopenharmony_ci // From linux/net/bluetooth/hci_sock.h 2713da5c369Sopenharmony_ci const HCI_IOC_MAGIC: u8 = b'H'; 2723da5c369Sopenharmony_ci const HCI_IOC_HCIDEVUP: u8 = 201; 2733da5c369Sopenharmony_ci ioctl_write_int!(hcidevup, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP); 2743da5c369Sopenharmony_ci #[test] 2753da5c369Sopenharmony_ci fn test_ioctl_write_int() { 2763da5c369Sopenharmony_ci let file = tempfile().unwrap(); 2773da5c369Sopenharmony_ci let res = unsafe { hcidevup(file.as_raw_fd(), 0) }; 2783da5c369Sopenharmony_ci assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); 2793da5c369Sopenharmony_ci } 2803da5c369Sopenharmony_ci 2813da5c369Sopenharmony_ci // From linux/videodev2.h 2823da5c369Sopenharmony_ci ioctl_read!(g_audio, b'V', 33, v4l2_audio); 2833da5c369Sopenharmony_ci #[test] 2843da5c369Sopenharmony_ci fn test_ioctl_read() { 2853da5c369Sopenharmony_ci let file = tempfile().unwrap(); 2863da5c369Sopenharmony_ci let mut data: v4l2_audio = unsafe { mem::zeroed() }; 2873da5c369Sopenharmony_ci let res = unsafe { g_audio(file.as_raw_fd(), &mut data) }; 2883da5c369Sopenharmony_ci assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); 2893da5c369Sopenharmony_ci } 2903da5c369Sopenharmony_ci 2913da5c369Sopenharmony_ci // From linux/videodev2.h 2923da5c369Sopenharmony_ci ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio); 2933da5c369Sopenharmony_ci #[test] 2943da5c369Sopenharmony_ci fn test_ioctl_readwrite() { 2953da5c369Sopenharmony_ci let file = tempfile().unwrap(); 2963da5c369Sopenharmony_ci let mut data: v4l2_audio = unsafe { mem::zeroed() }; 2973da5c369Sopenharmony_ci let res = unsafe { enum_audio(file.as_raw_fd(), &mut data) }; 2983da5c369Sopenharmony_ci assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); 2993da5c369Sopenharmony_ci } 3003da5c369Sopenharmony_ci 3013da5c369Sopenharmony_ci // FIXME: Find a suitable example for `ioctl_read_buf`. 3023da5c369Sopenharmony_ci 3033da5c369Sopenharmony_ci #[repr(C)] 3043da5c369Sopenharmony_ci pub struct spi_ioc_transfer { 3053da5c369Sopenharmony_ci tx_buf: u64, 3063da5c369Sopenharmony_ci rx_buf: u64, 3073da5c369Sopenharmony_ci len: u32, 3083da5c369Sopenharmony_ci speed_hz: u32, 3093da5c369Sopenharmony_ci delay_usecs: u16, 3103da5c369Sopenharmony_ci bits_per_word: u8, 3113da5c369Sopenharmony_ci cs_change: u8, 3123da5c369Sopenharmony_ci tx_nbits: u8, 3133da5c369Sopenharmony_ci rx_nbits: u8, 3143da5c369Sopenharmony_ci pad: u16, 3153da5c369Sopenharmony_ci } 3163da5c369Sopenharmony_ci 3173da5c369Sopenharmony_ci // From linux/spi/spidev.h 3183da5c369Sopenharmony_ci ioctl_write_buf!( 3193da5c369Sopenharmony_ci spi_ioc_message, 3203da5c369Sopenharmony_ci super::SPI_IOC_MAGIC, 3213da5c369Sopenharmony_ci super::SPI_IOC_MESSAGE, 3223da5c369Sopenharmony_ci spi_ioc_transfer 3233da5c369Sopenharmony_ci ); 3243da5c369Sopenharmony_ci #[test] 3253da5c369Sopenharmony_ci fn test_ioctl_write_buf() { 3263da5c369Sopenharmony_ci let file = tempfile().unwrap(); 3273da5c369Sopenharmony_ci let data: [spi_ioc_transfer; 4] = unsafe { mem::zeroed() }; 3283da5c369Sopenharmony_ci let res = unsafe { spi_ioc_message(file.as_raw_fd(), &data[..]) }; 3293da5c369Sopenharmony_ci assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); 3303da5c369Sopenharmony_ci } 3313da5c369Sopenharmony_ci 3323da5c369Sopenharmony_ci // FIXME: Find a suitable example for `ioctl_readwrite_buf`. 3333da5c369Sopenharmony_ci} 3343da5c369Sopenharmony_ci 3353da5c369Sopenharmony_ci#[cfg(target_os = "freebsd")] 3363da5c369Sopenharmony_cimod freebsd_ioctls { 3373da5c369Sopenharmony_ci use std::mem; 3383da5c369Sopenharmony_ci use std::os::unix::io::AsRawFd; 3393da5c369Sopenharmony_ci 3403da5c369Sopenharmony_ci use libc::termios; 3413da5c369Sopenharmony_ci use tempfile::tempfile; 3423da5c369Sopenharmony_ci 3433da5c369Sopenharmony_ci use nix::errno::Errno; 3443da5c369Sopenharmony_ci 3453da5c369Sopenharmony_ci // From sys/sys/ttycom.h 3463da5c369Sopenharmony_ci const TTY_IOC_MAGIC: u8 = b't'; 3473da5c369Sopenharmony_ci const TTY_IOC_TYPE_NXCL: u8 = 14; 3483da5c369Sopenharmony_ci const TTY_IOC_TYPE_GETA: u8 = 19; 3493da5c369Sopenharmony_ci const TTY_IOC_TYPE_SETA: u8 = 20; 3503da5c369Sopenharmony_ci 3513da5c369Sopenharmony_ci ioctl_none!(tiocnxcl, TTY_IOC_MAGIC, TTY_IOC_TYPE_NXCL); 3523da5c369Sopenharmony_ci #[test] 3533da5c369Sopenharmony_ci fn test_ioctl_none() { 3543da5c369Sopenharmony_ci let file = tempfile().unwrap(); 3553da5c369Sopenharmony_ci let res = unsafe { tiocnxcl(file.as_raw_fd()) }; 3563da5c369Sopenharmony_ci assert_eq!(res, Err(Errno::ENOTTY)); 3573da5c369Sopenharmony_ci } 3583da5c369Sopenharmony_ci 3593da5c369Sopenharmony_ci ioctl_read!(tiocgeta, TTY_IOC_MAGIC, TTY_IOC_TYPE_GETA, termios); 3603da5c369Sopenharmony_ci #[test] 3613da5c369Sopenharmony_ci fn test_ioctl_read() { 3623da5c369Sopenharmony_ci let file = tempfile().unwrap(); 3633da5c369Sopenharmony_ci let mut termios = unsafe { mem::zeroed() }; 3643da5c369Sopenharmony_ci let res = unsafe { tiocgeta(file.as_raw_fd(), &mut termios) }; 3653da5c369Sopenharmony_ci assert_eq!(res, Err(Errno::ENOTTY)); 3663da5c369Sopenharmony_ci } 3673da5c369Sopenharmony_ci 3683da5c369Sopenharmony_ci ioctl_write_ptr!(tiocseta, TTY_IOC_MAGIC, TTY_IOC_TYPE_SETA, termios); 3693da5c369Sopenharmony_ci #[test] 3703da5c369Sopenharmony_ci fn test_ioctl_write_ptr() { 3713da5c369Sopenharmony_ci let file = tempfile().unwrap(); 3723da5c369Sopenharmony_ci let termios: termios = unsafe { mem::zeroed() }; 3733da5c369Sopenharmony_ci let res = unsafe { tiocseta(file.as_raw_fd(), &termios) }; 3743da5c369Sopenharmony_ci assert_eq!(res, Err(Errno::ENOTTY)); 3753da5c369Sopenharmony_ci } 3763da5c369Sopenharmony_ci} 377