diff --git a/build.rs b/build.rs new file mode 100644 index 0000000000000..0a07d8ce6ba64 --- /dev/null +++ b/build.rs @@ -0,0 +1,41 @@ +use std::process::Command; + +#[cfg(not(target_os = "freebsd"))] +fn detect_freebsd_abi_changes() {} + +#[cfg(target_os = "freebsd")] +fn detect_freebsd_abi_changes() { + // We use freebsd-version(1). We could use `uname -k` to get the + // version of the kernel, but it wouldn't reflect the version of the + // userland (in case we are in a jail). + // + // freebsd-version(1) appeared in FreeBSD 10.0, so it's good enough. + + let _ = Command::new("freebsd-version").arg("-u") + .output() + .and_then( + |output| { + assert!(output.status.success()); + + let full_version_string = String::from_utf8_lossy(&output.stdout); + let split_version: Vec<&str> = full_version_string + .trim() + .splitn(2, '.').collect(); + + assert!(split_version.len() >= 1); + + let version: u32 = split_version[0] + .parse().unwrap(); + + // FreeBSD kernel versions are published in the following document: + // https://www.freebsd.org/doc/en/books/porters-handbook/versions.html + + if version >= 12 { println!("cargo:rustc-cfg=freebsd12_abi"); } + + Ok(()) + }); +} + +fn main() { + detect_freebsd_abi_changes(); +} diff --git a/src/unix/bsd/freebsdlike/dragonfly/mod.rs b/src/unix/bsd/freebsdlike/dragonfly/mod.rs index 38204c2272528..29b239213abf4 100644 --- a/src/unix/bsd/freebsdlike/dragonfly/mod.rs +++ b/src/unix/bsd/freebsdlike/dragonfly/mod.rs @@ -1,4 +1,5 @@ pub type clock_t = u64; +pub type dev_t = u32; pub type ino_t = u64; pub type nlink_t = u32; pub type blksize_t = i64; @@ -168,6 +169,15 @@ s! { pub ifm_index: ::c_ushort, pub ifm_data: if_data, } + + pub struct kevent { + pub ident: ::uintptr_t, + pub filter: ::c_short, + pub flags: ::c_ushort, + pub fflags: ::c_uint, + pub data: ::intptr_t, + pub udata: *mut ::c_void, + } } pub const RAND_MAX: ::c_int = 0x7fff_ffff; diff --git a/src/unix/bsd/freebsdlike/freebsd/aarch64.rs b/src/unix/bsd/freebsdlike/freebsd/aarch64.rs index a2da8452c4d34..48a590eb377de 100644 --- a/src/unix/bsd/freebsdlike/freebsd/aarch64.rs +++ b/src/unix/bsd/freebsdlike/freebsd/aarch64.rs @@ -2,29 +2,3 @@ pub type c_long = i64; pub type c_ulong = u64; pub type time_t = i64; pub type suseconds_t = i64; - -s! { - pub struct stat { - pub st_dev: ::dev_t, - pub st_ino: ::ino_t, - pub st_mode: ::mode_t, - pub st_nlink: ::nlink_t, - pub st_uid: ::uid_t, - pub st_gid: ::gid_t, - pub st_rdev: ::dev_t, - pub st_atime: ::time_t, - pub st_atime_nsec: ::c_long, - pub st_mtime: ::time_t, - pub st_mtime_nsec: ::c_long, - pub st_ctime: ::time_t, - pub st_ctime_nsec: ::c_long, - pub st_size: ::off_t, - pub st_blocks: ::blkcnt_t, - pub st_blksize: ::blksize_t, - pub st_flags: ::fflags_t, - pub st_gen: ::uint32_t, - pub st_lspare: ::int32_t, - pub st_birthtime: ::time_t, - pub st_birthtime_nsec: ::c_long, - } -} diff --git a/src/unix/bsd/freebsdlike/freebsd/freebsd11.rs b/src/unix/bsd/freebsdlike/freebsd/freebsd11.rs new file mode 100644 index 0000000000000..b201835e6307a --- /dev/null +++ b/src/unix/bsd/freebsdlike/freebsd/freebsd11.rs @@ -0,0 +1,52 @@ +pub type dev_t = u32; +pub type ino_t = u32; +pub type nlink_t = u16; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_size: ::off_t, + pub st_blocks: ::blkcnt_t, + pub st_blksize: ::blksize_t, + pub st_flags: ::fflags_t, + pub st_gen: ::uint32_t, + pub st_lspare: ::int32_t, + pub st_birthtime: ::time_t, + pub st_birthtime_nsec: ::c_long, + + #[cfg(target_arch = "x86")] + __unused: [u8; 8], + } + + pub struct dirent { + pub d_fileno: u32, + pub d_reclen: u16, + pub d_type: u8, + pub d_namlen: u8, + pub d_name: [::c_char; 256], + } + + pub struct kevent { + pub ident: ::uintptr_t, + pub filter: ::c_short, + pub flags: ::c_ushort, + pub fflags: ::c_uint, + pub data: ::intptr_t, + pub udata: *mut ::c_void, + pub ext: [::uint64_t; 0], + } +} + +pub const KEVENT_EXT_ZEROED: [::uint64_t; 0] = [0; 0]; diff --git a/src/unix/bsd/freebsdlike/freebsd/freebsd12.rs b/src/unix/bsd/freebsdlike/freebsd/freebsd12.rs new file mode 100644 index 0000000000000..2a59e0ad0465b --- /dev/null +++ b/src/unix/bsd/freebsdlike/freebsd/freebsd12.rs @@ -0,0 +1,70 @@ +pub type dev_t = u64; +pub type ino_t = u64; +pub type nlink_t = u64; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_pad0: ::uint16_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_pad1: ::uint32_t, + pub st_rdev: ::dev_t, + + #[cfg(target_arch = "x86")] + pub st_atime_ext: ::int32_t, + + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + + #[cfg(target_arch = "x86")] + pub st_mtime_ext: i32, + + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + + #[cfg(target_arch = "x86")] + pub st_ctime_ext: ::int32_t, + + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + + #[cfg(target_arch = "x86")] + pub st_birthtime_ext: ::int32_t, + + pub st_birthtime: ::time_t, + pub st_birthtime_nsec: ::c_long, + pub st_size: ::off_t, + pub st_blocks: ::blkcnt_t, + pub st_blksize: ::blksize_t, + pub st_flags: ::fflags_t, + pub st_gen: ::uint64_t, + pub st_spare: [::uint64_t; 10], + } + + pub struct dirent { + pub d_fileno: u64, + pub d_off: u64, + pub d_reclen: u16, + pub d_type: u8, + pub d_pad0: u8, + pub d_namlen: u16, + pub d_pad1: u16, + pub d_name: [::c_char; 256], + } + + pub struct kevent { + pub ident: ::uintptr_t, + pub filter: ::c_short, + pub flags: ::c_ushort, + pub fflags: ::c_uint, + pub data: ::int64_t, + pub udata: *mut ::c_void, + pub ext: [::uint64_t; 4], + } +} + +pub const KEVENT_EXT_ZEROED: [::uint64_t; 4] = [0; 4]; diff --git a/src/unix/bsd/freebsdlike/freebsd/mod.rs b/src/unix/bsd/freebsdlike/freebsd/mod.rs index 2c950f4c2520d..671f4fc8c18ff 100644 --- a/src/unix/bsd/freebsdlike/freebsd/mod.rs +++ b/src/unix/bsd/freebsdlike/freebsd/mod.rs @@ -1,8 +1,6 @@ pub type fflags_t = u32; pub type clock_t = i32; -pub type ino_t = u32; pub type lwpid_t = i32; -pub type nlink_t = u16; pub type blksize_t = u32; pub type clockid_t = ::c_int; pub type sem_t = _sem; @@ -43,14 +41,6 @@ s! { pub aio_sigevent: sigevent } - pub struct dirent { - pub d_fileno: u32, - pub d_reclen: u16, - pub d_type: u8, - pub d_namlen: u8, - pub d_name: [::c_char; 256], - } - pub struct jail { pub version: u32, pub path: *mut ::c_char, @@ -595,3 +585,16 @@ cfg_if! { // Unknown target_arch } } + +cfg_if! { + if #[cfg(freebsd12_abi)] { + // Starting with FreeBSD 12.0-RELEASE, the kernel uses 64-bit + // ino_t. This affects `struct stat` and `struct dirent_t` as + // well as a few types above. + mod freebsd12; + pub use self::freebsd12::*; + } else { + mod freebsd11; + pub use self::freebsd11::*; + } +} diff --git a/src/unix/bsd/freebsdlike/freebsd/x86.rs b/src/unix/bsd/freebsdlike/freebsd/x86.rs index 8a5e5f9fb8d28..619cbbd9751e2 100644 --- a/src/unix/bsd/freebsdlike/freebsd/x86.rs +++ b/src/unix/bsd/freebsdlike/freebsd/x86.rs @@ -2,30 +2,3 @@ pub type c_long = i32; pub type c_ulong = u32; pub type time_t = i32; pub type suseconds_t = i32; - -s! { - pub struct stat { - pub st_dev: ::dev_t, - pub st_ino: ::ino_t, - pub st_mode: ::mode_t, - pub st_nlink: ::nlink_t, - pub st_uid: ::uid_t, - pub st_gid: ::gid_t, - pub st_rdev: ::dev_t, - pub st_atime: ::time_t, - pub st_atime_nsec: ::c_long, - pub st_mtime: ::time_t, - pub st_mtime_nsec: ::c_long, - pub st_ctime: ::time_t, - pub st_ctime_nsec: ::c_long, - pub st_size: ::off_t, - pub st_blocks: ::blkcnt_t, - pub st_blksize: ::blksize_t, - pub st_flags: ::fflags_t, - pub st_gen: ::uint32_t, - pub st_lspare: ::int32_t, - pub st_birthtime: ::time_t, - pub st_birthtime_nsec: ::c_long, - __unused: [u8; 8], - } -} diff --git a/src/unix/bsd/freebsdlike/freebsd/x86_64.rs b/src/unix/bsd/freebsdlike/freebsd/x86_64.rs index a2da8452c4d34..48a590eb377de 100644 --- a/src/unix/bsd/freebsdlike/freebsd/x86_64.rs +++ b/src/unix/bsd/freebsdlike/freebsd/x86_64.rs @@ -2,29 +2,3 @@ pub type c_long = i64; pub type c_ulong = u64; pub type time_t = i64; pub type suseconds_t = i64; - -s! { - pub struct stat { - pub st_dev: ::dev_t, - pub st_ino: ::ino_t, - pub st_mode: ::mode_t, - pub st_nlink: ::nlink_t, - pub st_uid: ::uid_t, - pub st_gid: ::gid_t, - pub st_rdev: ::dev_t, - pub st_atime: ::time_t, - pub st_atime_nsec: ::c_long, - pub st_mtime: ::time_t, - pub st_mtime_nsec: ::c_long, - pub st_ctime: ::time_t, - pub st_ctime_nsec: ::c_long, - pub st_size: ::off_t, - pub st_blocks: ::blkcnt_t, - pub st_blksize: ::blksize_t, - pub st_flags: ::fflags_t, - pub st_gen: ::uint32_t, - pub st_lspare: ::int32_t, - pub st_birthtime: ::time_t, - pub st_birthtime_nsec: ::c_long, - } -} diff --git a/src/unix/bsd/freebsdlike/mod.rs b/src/unix/bsd/freebsdlike/mod.rs index c69998516df08..9ab2505266034 100644 --- a/src/unix/bsd/freebsdlike/mod.rs +++ b/src/unix/bsd/freebsdlike/mod.rs @@ -1,4 +1,3 @@ -pub type dev_t = u32; pub type mode_t = u16; pub type pthread_attr_t = *mut ::c_void; pub type rlim_t = i64; @@ -31,15 +30,6 @@ s! { __unused8: *mut ::c_void, } - pub struct kevent { - pub ident: ::uintptr_t, - pub filter: ::c_short, - pub flags: ::c_ushort, - pub fflags: ::c_uint, - pub data: ::intptr_t, - pub udata: *mut ::c_void, - } - pub struct sockaddr_storage { pub ss_len: u8, pub ss_family: ::sa_family_t,