Skip to content

Commit 8067378

Browse files
committed
Fix CMSG_DATA(3) and friends on BSD
PR #1098 added the CMSG_DATA(3) family of functions into libc. Because they're defined as macros in C, they had to be rewritten as Rust functions for libc. Also, they can't be tested in CI for the same reason. But that PR erroneously used the same definitions in BSD as in Linux. This commit corrects the definitions for OSX, FreeBSD, DragonflyBSD, OpenBSD, and NetBSD. I renamed a few variables and collapsed a few macros in order to combine the definitions where possible. Fixes #1210
1 parent ce1dfcb commit 8067378

File tree

17 files changed

+220
-33
lines changed

17 files changed

+220
-33
lines changed

src/unix/bsd/apple/mod.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Apple (ios/darwin)-specific definitions
22
//!
33
//! This covers *-apple-* triples currently
4+
use dox::mem;
45

56
pub type c_char = i8;
67
pub type clock_t = c_ulong;
@@ -2383,7 +2384,45 @@ pub const SF_IMMUTABLE: ::c_uint = 0x00020000;
23832384
pub const SF_APPEND: ::c_uint = 0x00040000;
23842385
pub const UF_HIDDEN: ::c_uint = 0x00008000;
23852386

2387+
fn __DARWIN_ALIGN32(p: usize) -> usize {
2388+
const __DARWIN_ALIGNBYTES32: usize = mem::size_of::<u32>() - 1;
2389+
p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32
2390+
}
2391+
23862392
f! {
2393+
pub fn CMSG_NXTHDR(mhdr: *const ::msghdr,
2394+
cmsg: *const ::cmsghdr) -> *mut ::cmsghdr {
2395+
if cmsg.is_null() {
2396+
return ::CMSG_FIRSTHDR(mhdr);
2397+
};
2398+
let cmsg_len = (*cmsg).cmsg_len as usize;
2399+
let next = cmsg as usize + __DARWIN_ALIGN32(cmsg_len as usize)
2400+
+ __DARWIN_ALIGN32(mem::size_of::<::cmsghdr>());
2401+
let max = (*mhdr).msg_control as usize
2402+
+ (*mhdr).msg_controllen as usize;
2403+
if next > max {
2404+
0 as *mut ::cmsghdr
2405+
} else {
2406+
next as *mut ::cmsghdr
2407+
}
2408+
}
2409+
2410+
pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar {
2411+
(cmsg as *mut ::c_uchar)
2412+
.offset(__DARWIN_ALIGN32(mem::size_of::<::cmsghdr>()) as isize)
2413+
}
2414+
2415+
pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
2416+
(__DARWIN_ALIGN32(mem::size_of::<::cmsghdr>())
2417+
+ __DARWIN_ALIGN32(length as usize))
2418+
as ::c_uint
2419+
}
2420+
2421+
pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
2422+
__DARWIN_ALIGN32(mem::size_of::<::cmsghdr>() + length as usize)
2423+
as ::c_uint
2424+
}
2425+
23872426
pub fn WSTOPSIG(status: ::c_int) -> ::c_int {
23882427
status >> 8
23892428
}

src/unix/bsd/freebsdlike/dragonfly/mod.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,39 @@ pub const SF_NOHISTORY: ::c_ulong = 0x00400000;
782782
pub const SF_CACHE: ::c_ulong = 0x00800000;
783783
pub const SF_XLINK: ::c_ulong = 0x01000000;
784784

785+
fn _CMSG_ALIGN(n: usize) -> usize {
786+
(n + 3) & !3
787+
}
788+
789+
f! {
790+
pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar {
791+
(cmsg as *mut ::c_uchar)
792+
.offset(_CMSG_ALIGN(mem::size_of::<::cmsghdr>()) as isize)
793+
}
794+
795+
pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
796+
_CMSG_ALIGN(mem::size_of::<::cmsghdr>()) + length as usize
797+
}
798+
799+
pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr)
800+
-> *mut ::cmsghdr
801+
{
802+
let next = cmsg as usize + _CMSG_ALIGN((*cmsg).cmsg_len)
803+
+ _CMSG_ALIGN(mem::size_of::<::cmsghdr>());
804+
let max = (*mhdr).msg_control as usize
805+
+ (*mhdr).msg_controllen as usize;
806+
if next <= max {
807+
(cmsg as usize + _CMSG_ALIGN((*cmsg).cmsg_len)) as *mut ::cmsghdr
808+
} else {
809+
0 as *mut ::cmsghdr
810+
}
811+
}
812+
813+
pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
814+
_CMSG_ALIGN(mem::size_of::<::cmsghdr>()) + _CMSG_ALIGN(length as usize)
815+
}
816+
}
817+
785818
extern {
786819
pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int)
787820
-> ::c_int;

src/unix/bsd/freebsdlike/freebsd/aarch64.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use dox::mem;
2+
13
pub type c_long = i64;
24
pub type c_ulong = u64;
35
pub type time_t = i64;
@@ -29,4 +31,7 @@ s! {
2931
}
3032
}
3133

34+
// should be pub(crate), but that requires Rust 1.18.0
35+
#[doc(hidden)]
36+
pub const _ALIGNBYTES: usize = mem::size_of::<::c_longlong>() - 1;
3237
pub const MAP_32BIT: ::c_int = 0x00080000;

src/unix/bsd/freebsdlike/freebsd/mod.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use dox::mem;
2+
13
pub type fflags_t = u32;
24
pub type clock_t = i32;
35
pub type ino_t = u32;
@@ -962,7 +964,43 @@ pub const UF_READONLY: ::c_ulong = 0x00001000;
962964
pub const UF_HIDDEN: ::c_ulong = 0x00008000;
963965
pub const SF_SNAPSHOT: ::c_ulong = 0x00200000;
964966

967+
fn _ALIGN(p: usize) -> usize {
968+
(p + _ALIGNBYTES) & !_ALIGNBYTES
969+
}
970+
965971
f! {
972+
pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar {
973+
(cmsg as *mut ::c_uchar)
974+
.offset(_ALIGN(mem::size_of::<::cmsghdr>()) as isize)
975+
}
976+
977+
pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
978+
_ALIGN(mem::size_of::<::cmsghdr>()) as ::c_uint + length
979+
}
980+
981+
pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr)
982+
-> *mut ::cmsghdr
983+
{
984+
if cmsg.is_null() {
985+
return ::CMSG_FIRSTHDR(mhdr);
986+
};
987+
let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)
988+
+ _ALIGN(mem::size_of::<::cmsghdr>());
989+
let max = (*mhdr).msg_control as usize
990+
+ (*mhdr).msg_controllen as usize;
991+
if next > max {
992+
0 as *mut ::cmsghdr
993+
} else {
994+
(cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize))
995+
as *mut ::cmsghdr
996+
}
997+
}
998+
999+
pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
1000+
(_ALIGN(mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize))
1001+
as ::c_uint
1002+
}
1003+
9661004
pub fn uname(buf: *mut ::utsname) -> ::c_int {
9671005
__xuname(256, buf as *mut ::c_void)
9681006
}

src/unix/bsd/freebsdlike/freebsd/x86.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use dox::mem;
2+
13
pub type c_long = i32;
24
pub type c_ulong = u32;
35
pub type time_t = i32;
@@ -29,3 +31,7 @@ s! {
2931
__unused: [u8; 8],
3032
}
3133
}
34+
35+
// should be pub(crate), but that requires Rust 1.18.0
36+
#[doc(hidden)]
37+
pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;

src/unix/bsd/freebsdlike/freebsd/x86_64.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use dox::mem;
2+
13
pub type c_long = i64;
24
pub type c_ulong = u64;
35
pub type time_t = i64;
@@ -29,4 +31,7 @@ s! {
2931
}
3032
}
3133

34+
// should be pub(crate), but that requires Rust 1.18.0
35+
#[doc(hidden)]
36+
pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
3237
pub const MAP_32BIT: ::c_int = 0x00080000;

src/unix/bsd/mod.rs

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -340,43 +340,14 @@ pub const POLLRDBAND: ::c_short = 0x080;
340340
pub const POLLWRBAND: ::c_short = 0x100;
341341

342342
f! {
343-
pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr {
344-
if (*mhdr).msg_controllen as usize >= mem::size_of::<cmsghdr>() {
345-
(*mhdr).msg_control as *mut cmsghdr
343+
pub fn CMSG_FIRSTHDR(mhdr: *const ::msghdr) -> *mut ::cmsghdr {
344+
if (*mhdr).msg_controllen as usize >= mem::size_of::<::cmsghdr>() {
345+
(*mhdr).msg_control as *mut ::cmsghdr
346346
} else {
347-
0 as *mut cmsghdr
347+
0 as *mut ::cmsghdr
348348
}
349349
}
350350

351-
pub fn CMSG_NXTHDR(mhdr: *const msghdr,
352-
cmsg: *const cmsghdr) -> *mut cmsghdr {
353-
if cmsg.is_null() {
354-
return CMSG_FIRSTHDR(mhdr);
355-
};
356-
let pad = mem::align_of::<cmsghdr>() - 1;
357-
let next = cmsg as usize + (*cmsg).cmsg_len as usize + pad & !pad;
358-
let max = (*mhdr).msg_control as usize
359-
+ (*mhdr).msg_controllen as usize;
360-
if next < max {
361-
next as *mut cmsghdr
362-
} else {
363-
0 as *mut cmsghdr
364-
}
365-
}
366-
367-
pub fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut ::c_uchar {
368-
cmsg.offset(1) as *mut ::c_uchar
369-
}
370-
371-
pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
372-
let pad = mem::align_of::<cmsghdr>() as ::c_uint - 1;
373-
mem::size_of::<cmsghdr>() as ::c_uint + ((length + pad) & !pad)
374-
}
375-
376-
pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
377-
mem::size_of::<cmsghdr>() as ::c_uint + length
378-
}
379-
380351
pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () {
381352
let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8;
382353
let fd = fd as usize;

src/unix/bsd/netbsdlike/mod.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use dox::mem;
2+
13
pub type time_t = i64;
24
pub type mode_t = u32;
35
pub type nlink_t = ::uint32_t;
@@ -593,7 +595,43 @@ pub const SF_APPEND: ::c_ulong = 0x00040000;
593595

594596
pub const TIMER_ABSTIME: ::c_int = 1;
595597

598+
fn _ALIGN(p: usize) -> usize {
599+
(p + _ALIGNBYTES) & !_ALIGNBYTES
600+
}
601+
596602
f! {
603+
pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar {
604+
(cmsg as *mut ::c_uchar)
605+
.offset(_ALIGN(mem::size_of::<::cmsghdr>()) as isize)
606+
}
607+
608+
pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
609+
_ALIGN(mem::size_of::<::cmsghdr>()) as ::c_uint + length
610+
}
611+
612+
pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr)
613+
-> *mut ::cmsghdr
614+
{
615+
if cmsg.is_null() {
616+
return ::CMSG_FIRSTHDR(mhdr);
617+
};
618+
let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)
619+
+ _ALIGN(mem::size_of::<::cmsghdr>());
620+
let max = (*mhdr).msg_control as usize
621+
+ (*mhdr).msg_controllen as usize;
622+
if next > max {
623+
0 as *mut ::cmsghdr
624+
} else {
625+
(cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize))
626+
as *mut ::cmsghdr
627+
}
628+
}
629+
630+
pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
631+
(_ALIGN(mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize))
632+
as ::c_uint
633+
}
634+
597635
pub fn WSTOPSIG(status: ::c_int) -> ::c_int {
598636
status >> 8
599637
}

src/unix/bsd/netbsdlike/netbsd/aarch64.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1+
use dox::mem;
2+
13
use PT_FIRSTMACH;
24

35
pub type c_long = i64;
46
pub type c_ulong = u64;
57
pub type c_char = u8;
68
pub type __cpu_simple_lock_nv_t = ::c_uchar;
79

10+
// should be pub(crate), but that requires Rust 1.18.0
11+
#[doc(hidden)]
12+
pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;
13+
814
pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 0;
915
pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 1;
1016
pub const PT_GETFPREGS: ::c_int = PT_FIRSTMACH + 2;

src/unix/bsd/netbsdlike/netbsd/arm.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1+
use dox::mem;
2+
13
use PT_FIRSTMACH;
24

35
pub type c_long = i32;
46
pub type c_ulong = u32;
57
pub type c_char = u8;
68
pub type __cpu_simple_lock_nv_t = ::c_int;
79

10+
// should be pub(crate), but that requires Rust 1.18.0
11+
#[doc(hidden)]
12+
pub const _ALIGNBYTES: usize = mem::size_of::<::c_longlong>() - 1;
13+
814
pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1;
915
pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2;
1016
pub const PT_GETFPREGS: ::c_int = PT_FIRSTMACH + 3;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1+
use dox::mem;
2+
13
use PT_FIRSTMACH;
24

35
pub type c_long = i32;
46
pub type c_ulong = u32;
57
pub type c_char = u8;
68
pub type __cpu_simple_lock_nv_t = ::c_int;
79

10+
// should be pub(crate), but that requires Rust 1.18.0
11+
#[doc(hidden)]
12+
pub const _ALIGNBYTES: usize = mem::size_of::<::c_double>() - 1;
13+
814
pub const PT_STEP: ::c_int = PT_FIRSTMACH + 0;
915
pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1;
1016
pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2;

src/unix/bsd/netbsdlike/netbsd/sparc64.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@ pub type c_long = i64;
22
pub type c_ulong = u64;
33
pub type c_char = i8;
44
pub type __cpu_simple_lock_nv_t = ::c_uchar;
5+
6+
// should be pub(crate), but that requires Rust 1.18.0
7+
#[doc(hidden)]
8+
pub const _ALIGNBYTES: usize = 0xf;

src/unix/bsd/netbsdlike/netbsd/x86.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1+
use dox::mem;
2+
13
pub type c_long = i32;
24
pub type c_ulong = u32;
35
pub type c_char = i8;
46
pub type __cpu_simple_lock_nv_t = ::c_uchar;
7+
8+
// should be pub(crate), but that requires Rust 1.18.0
9+
#[doc(hidden)]
10+
pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;

src/unix/bsd/netbsdlike/netbsd/x86_64.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1+
use dox::mem;
2+
13
use PT_FIRSTMACH;
24

35
pub type c_long = i64;
46
pub type c_ulong = u64;
57
pub type c_char = i8;
68
pub type __cpu_simple_lock_nv_t = ::c_uchar;
79

10+
// should be pub(crate), but that requires Rust 1.18.0
11+
#[doc(hidden)]
12+
pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
13+
814
pub const PT_STEP: ::c_int = PT_FIRSTMACH + 0;
915
pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1;
1016
pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
use dox::mem;
2+
13
pub type c_long = i64;
24
pub type c_ulong = u64;
35
pub type c_char = u8;
6+
7+
// should be pub(crate), but that requires Rust 1.18.0
8+
#[doc(hidden)]
9+
pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
use dox::mem;
2+
13
pub type c_long = i32;
24
pub type c_ulong = u32;
35
pub type c_char = i8;
6+
7+
// should be pub(crate), but that requires Rust 1.18.0
8+
#[doc(hidden)]
9+
pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;

0 commit comments

Comments
 (0)