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