xref: /rust-libc-0.2.174/libc-test/test/cmsg.rs (revision c04c92ed)
1 //! Compare libc's CMSG(3) family of functions against the actual C macros, for
2 //! various inputs.
3 
4 #[cfg(unix)]
5 mod t {
6 
7     use std::mem;
8 
9     use libc::{self, c_uchar, c_uint, c_void, cmsghdr, msghdr};
10 
11     extern "C" {
cmsg_firsthdr(msgh: *const msghdr) -> *mut cmsghdr12         pub fn cmsg_firsthdr(msgh: *const msghdr) -> *mut cmsghdr;
13         // see below
14         #[cfg(not(target_arch = "sparc64"))]
cmsg_nxthdr(mhdr: *const msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr15         pub fn cmsg_nxthdr(mhdr: *const msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr;
cmsg_space(length: c_uint) -> usize16         pub fn cmsg_space(length: c_uint) -> usize;
cmsg_len(length: c_uint) -> usize17         pub fn cmsg_len(length: c_uint) -> usize;
cmsg_data(cmsg: *const cmsghdr) -> *mut c_uchar18         pub fn cmsg_data(cmsg: *const cmsghdr) -> *mut c_uchar;
19     }
20 
21     #[test]
test_cmsg_data()22     fn test_cmsg_data() {
23         for l in 0..128 {
24             let pcmsghdr = l as *const cmsghdr;
25             unsafe {
26                 assert_eq!(libc::CMSG_DATA(pcmsghdr), cmsg_data(pcmsghdr));
27             }
28         }
29     }
30 
31     #[test]
test_cmsg_firsthdr()32     fn test_cmsg_firsthdr() {
33         let mut mhdr: msghdr = unsafe { mem::zeroed() };
34         mhdr.msg_control = 0xdeadbeef as *mut c_void;
35         let pmhdr = &mhdr as *const msghdr;
36         for l in 0..128 {
37             mhdr.msg_controllen = l;
38             unsafe {
39                 assert_eq!(libc::CMSG_FIRSTHDR(pmhdr), cmsg_firsthdr(pmhdr));
40             }
41         }
42     }
43 
44     #[test]
test_cmsg_len()45     fn test_cmsg_len() {
46         for l in 0..128 {
47             unsafe {
48                 assert_eq!(libc::CMSG_LEN(l) as usize, cmsg_len(l));
49             }
50         }
51     }
52 
53     // Skip on sparc64
54     // https://github.com/rust-lang/libc/issues/1239
55     #[cfg(not(target_arch = "sparc64"))]
56     #[test]
test_cmsg_nxthdr()57     fn test_cmsg_nxthdr() {
58         use std::ptr;
59         // Helps to align the buffer on the stack.
60         #[repr(align(8))]
61         struct Align8<T>(T);
62 
63         const CAPACITY: usize = 512;
64         let mut buffer = Align8([0_u8; CAPACITY]);
65         let mut mhdr: msghdr = unsafe { mem::zeroed() };
66         for start_ofs in 0..64 {
67             let pcmsghdr = buffer.0.as_mut_ptr().cast::<cmsghdr>();
68             mhdr.msg_control = pcmsghdr as *mut c_void;
69             mhdr.msg_controllen = (160 - start_ofs) as _;
70             for cmsg_len in 0..64 {
71                 // Address must be a multiple of 0x4 for testing on AIX.
72                 if cfg!(target_os = "aix") && cmsg_len % std::mem::size_of::<cmsghdr>() != 0 {
73                     continue;
74                 }
75                 for next_cmsg_len in 0..32 {
76                     unsafe {
77                         pcmsghdr.cast::<u8>().write_bytes(0, CAPACITY);
78                         (*pcmsghdr).cmsg_len = cmsg_len as _;
79                         let libc_next = libc::CMSG_NXTHDR(&mhdr, pcmsghdr);
80                         let next = cmsg_nxthdr(&mhdr, pcmsghdr);
81                         assert_eq!(libc_next, next);
82 
83                         if libc_next != ptr::null_mut() {
84                             (*libc_next).cmsg_len = next_cmsg_len;
85                             let libc_next = libc::CMSG_NXTHDR(&mhdr, pcmsghdr);
86                             let next = cmsg_nxthdr(&mhdr, pcmsghdr);
87                             assert_eq!(libc_next, next);
88                         }
89                     }
90                 }
91             }
92         }
93     }
94 
95     #[test]
test_cmsg_space()96     fn test_cmsg_space() {
97         unsafe {
98             for l in 0..128 {
99                 assert_eq!(libc::CMSG_SPACE(l) as usize, cmsg_space(l));
100             }
101         }
102     }
103 }
104