xref: /rust-libc-0.2.174/libc-test/test/cmsg.rs (revision bd00c8ea)
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 libc::{self, c_uchar, c_uint, c_void, cmsghdr, msghdr};
8     use std::mem;
9 
10     extern "C" {
11         pub fn cmsg_firsthdr(msgh: *const msghdr) -> *mut cmsghdr;
12         // see below
13         #[cfg(not(target_arch = "sparc64"))]
14         pub fn cmsg_nxthdr(mhdr: *const msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr;
15         pub fn cmsg_space(length: c_uint) -> usize;
16         pub fn cmsg_len(length: c_uint) -> usize;
17         pub fn cmsg_data(cmsg: *const cmsghdr) -> *mut c_uchar;
18     }
19 
20     #[test]
21     fn test_cmsg_data() {
22         for l in 0..128 {
23             let pcmsghdr = l as *const cmsghdr;
24             unsafe {
25                 assert_eq!(libc::CMSG_DATA(pcmsghdr), cmsg_data(pcmsghdr));
26             }
27         }
28     }
29 
30     #[test]
31     fn test_cmsg_firsthdr() {
32         let mut mhdr: msghdr = unsafe { mem::zeroed() };
33         mhdr.msg_control = 0xdeadbeef as *mut c_void;
34         let pmhdr = &mhdr as *const msghdr;
35         for l in 0..128 {
36             mhdr.msg_controllen = l;
37             unsafe {
38                 assert_eq!(libc::CMSG_FIRSTHDR(pmhdr), cmsg_firsthdr(pmhdr));
39             }
40         }
41     }
42 
43     #[test]
44     fn test_cmsg_len() {
45         for l in 0..128 {
46             unsafe {
47                 assert_eq!(libc::CMSG_LEN(l) as usize, cmsg_len(l));
48             }
49         }
50     }
51 
52     // Skip on sparc64
53     // https://github.com/rust-lang/libc/issues/1239
54     #[cfg(not(target_arch = "sparc64"))]
55     #[test]
56     fn test_cmsg_nxthdr() {
57         use std::ptr;
58         // Helps to align the buffer on the stack.
59         #[repr(align(8))]
60         struct Align8<T>(T);
61 
62         const CAPACITY: usize = 512;
63         let mut buffer = Align8([0_u8; CAPACITY]);
64         let mut mhdr: msghdr = unsafe { mem::zeroed() };
65         for start_ofs in 0..64 {
66             let pcmsghdr = buffer.0.as_mut_ptr().cast::<cmsghdr>();
67             mhdr.msg_control = pcmsghdr as *mut c_void;
68             mhdr.msg_controllen = (160 - start_ofs) as _;
69             for cmsg_len in 0..64 {
70                 for next_cmsg_len in 0..32 {
71                     unsafe {
72                         pcmsghdr.cast::<u8>().write_bytes(0, CAPACITY);
73                         (*pcmsghdr).cmsg_len = cmsg_len;
74                         let libc_next = libc::CMSG_NXTHDR(&mhdr, pcmsghdr);
75                         let next = cmsg_nxthdr(&mhdr, pcmsghdr);
76                         assert_eq!(libc_next, next);
77 
78                         if libc_next != ptr::null_mut() {
79                             (*libc_next).cmsg_len = next_cmsg_len;
80                             let libc_next = libc::CMSG_NXTHDR(&mhdr, pcmsghdr);
81                             let next = cmsg_nxthdr(&mhdr, pcmsghdr);
82                             assert_eq!(libc_next, next);
83                         }
84                     }
85                 }
86             }
87         }
88     }
89 
90     #[test]
91     fn test_cmsg_space() {
92         unsafe {
93             for l in 0..128 {
94                 assert_eq!(libc::CMSG_SPACE(l) as usize, cmsg_space(l));
95             }
96         }
97     }
98 }
99