Add a FreeBSD 12 build job and test FreeBSD12 APIs

This commits adds a second FreeBSD 12 build job,
and splits the implementation of the FreeBSD module
into two modules, one for FreeBSD 11, and one for FreeBSD 12.

The FreeBSD 11 module is compiled always by default, and is
mostly forward compatible with FreeBSD 12 systems.

The FreeBSD 12 module is only built for now in libc's CI,
and uses FreeBSD 12 data types and APIs, linking to symbols
that are only available in FreeBSD 12.

Basically, when LIBC_CI env variable is defined, and the host
system is a FreeBSD 12 system, then the FreeBSD 12 module is
automatically built and tested. Conditional compilation is done
using a `cfg(freebsd12)` flag.

This commit also re-enables many tests, and documents why
some remain disabled.
This commit is contained in:
gnzlbg 2019-05-16 14:53:51 +02:00
parent 5653a6014f
commit 7437d0a6f1
17 changed files with 698 additions and 421 deletions

View File

@ -1,8 +1,7 @@
freebsd_instance:
image: freebsd-11-1-release-amd64
task:
name: stable x86_64-unknown-freebsd
name: stable x86_64-unknown-freebsd-11
freebsd_instance:
image: freebsd-11-2-release-amd64
setup_script:
- pkg install -y curl
- curl https://sh.rustup.rs -sSf --output rustup.sh
@ -12,13 +11,15 @@ task:
test_script:
- . $HOME/.cargo/env
- sh ci/run.sh x86_64-unknown-freebsd
task:
name: nightly x86_64-unknown-freebsd
name: nightly x86_64-unknown-freebsd-12
freebsd_instance:
image: freebsd-12-0-release-amd64
setup_script:
- pkg install -y curl
- curl https://sh.rustup.rs -sSf --output rustup.sh
- sh rustup.sh -y
- sh rustup.sh --default-toolchain nightly -y
- . $HOME/.cargo/env
- rustup default nightly
test_script:

View File

@ -16,6 +16,12 @@ fn main() {
);
}
if std::env::var("LIBC_CI").is_ok() {
if let Some(12) = which_freebsd() {
println!("cargo:rustc-cfg=freebsd12");
}
}
// Rust >= 1.15 supports private module use:
if rustc_minor_ver >= 15 || rustc_dep_of_std {
println!("cargo:rustc-cfg=libc_priv_mod_use");
@ -70,3 +76,26 @@ fn rustc_minor_version() -> Option<u32> {
otry!(pieces.next()).parse().ok()
}
fn which_freebsd() -> Option<i32> {
let output = std::process::Command::new("freebsd-version").output().ok();
if output.is_none() {
return None;
}
let output = output.unwrap();
if !output.status.success() {
return None;
}
let stdout = String::from_utf8(output.stdout).ok();
if stdout.is_none() {
return None;
}
let stdout = stdout.unwrap();
match &stdout {
s if s.starts_with("11") => Some(11),
s if s.starts_with("12") => Some(12),
_ => None,
}
}

View File

@ -87,10 +87,12 @@ if [ "$TARGET" = "x86_64-unknown-linux-gnux32" ]; then
opt="--release"
fi
cargo test $opt --no-default-features --manifest-path libc-test/Cargo.toml \
export LIBC_CI=1
cargo test -vv $opt --no-default-features --manifest-path libc-test/Cargo.toml \
--target "${TARGET}"
cargo test $opt --manifest-path libc-test/Cargo.toml --target "${TARGET}"
cargo test -vv $opt --manifest-path libc-test/Cargo.toml --target "${TARGET}"
cargo test $opt --features extra_traits --manifest-path libc-test/Cargo.toml \
cargo test -vv $opt --features extra_traits --manifest-path libc-test/Cargo.toml \
--target "${TARGET}"

View File

@ -1022,14 +1022,9 @@ fn test_dragonflybsd(target: &str) {
s.replace("e_nsec", ".tv_nsec")
}
"u64" if struct_ == "epoll_event" => "data.u64".to_string(),
"type_"
if struct_ == "input_event"
|| struct_ == "input_mask"
|| struct_ == "ff_effect"
|| struct_ == "rtprio" =>
{
"type".to_string()
}
// Field is named `type` in C but that is a Rust keyword,
// so these fields are translated to `type_` in the bindings.
"type_" if struct_ == "rtprio" => "type".to_string(),
s => s.to_string(),
}
});
@ -1449,11 +1444,19 @@ fn test_android(target: &str) {
fn test_freebsd(target: &str) {
assert!(target.contains("freebsd"));
let x86 = target.contains("i686") || target.contains("x86_64");
let mut cfg = ctest::TestGenerator::new();
let freebsd_ver = which_freebsd();
if let Some(12) = freebsd_ver {
// If the host is FreeBSD 12, run FreeBSD 12 tests
cfg.cfg("freebsd12", None);
}
// Required for `getline`:
cfg.define("_WITH_GETLINE", None);
// Required for making freebsd11_stat available in the headers
cfg.define("_WANT_FREEBSD11_STAT", None);
headers! { cfg:
"aio.h",
@ -1533,19 +1536,18 @@ fn test_freebsd(target: &str) {
cfg.type_name(move |ty, is_struct, is_union| {
match ty {
// Just pass all these through, no need for a "struct" prefix
// FIXME: still required?
"FILE" | "fd_set" | "Dl_info" | "DIR" | "Elf32_Phdr"
| "Elf64_Phdr" | "Elf32_Shdr" | "Elf64_Shdr" | "Elf32_Sym"
| "Elf64_Sym" | "Elf32_Ehdr" | "Elf64_Ehdr" | "Elf32_Chdr"
| "Elf64_Chdr" => ty.to_string(),
"FILE" | "fd_set" | "Dl_info" | "DIR" => ty.to_string(),
// FIXME: still required?
// FIXME: https://github.com/rust-lang/libc/issues/1273
"sighandler_t" => "sig_t".to_string(),
t if is_union => format!("union {}", t),
t if t.ends_with("_t") => t.to_string(),
// sigval is a struct in Rust, but a union in C:
"sigval" => format!("union sigval"),
// put `struct` in front of all structs:.
t if is_struct => format!("struct {}", t),
@ -1560,125 +1562,40 @@ fn test_freebsd(target: &str) {
s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
s.replace("e_nsec", ".tv_nsec")
}
// FIXME: still required?
"u64" if struct_ == "epoll_event" => "data.u64".to_string(),
// FIXME: still required?
"type_"
if struct_ == "input_event"
|| struct_ == "input_mask"
|| struct_ == "ff_effect"
|| struct_ == "rtprio" =>
{
"type".to_string()
}
// Field is named `type` in C but that is a Rust keyword,
// so these fields are translated to `type_` in the bindings.
"type_" if struct_ == "rtprio" => "type".to_string(),
s => s.to_string(),
}
});
cfg.skip_type(move |ty| {
match ty {
// sighandler_t is crazy across platforms
// FIXME: still required?
"sighandler_t" => true,
_ => false,
}
});
cfg.skip_struct(move |ty| {
match ty {
// This is actually a union, not a struct
// FIXME: still required?
"sigval" => true,
// These are tested as part of the linux_fcntl tests since there are
// header conflicts when including them with all the other structs.
// FIXME: still required?
"termios2" => true,
_ => false,
}
});
cfg.skip_signededness(move |c| {
match c {
// FIXME: still required?
"LARGE_INTEGER" | "float" | "double" => true,
// FIXME: still required?
n if n.starts_with("pthread") => true,
// sem_t is a struct or pointer
// FIXME: still required?
"sem_t" => true,
// mqd_t is a pointer on FreeBSD
// FIXME: still required?
"mqd_t" => true,
_ => false,
}
});
cfg.skip_const(move |name| {
match name {
// FIXME: still required?
"SIG_DFL" | "SIG_ERR" | "SIG_IGN" => true, // sighandler_t weirdness
// FIXME: still required?
"SIGUNUSED" => true, // removed in glibc 2.26
// weird signed extension or something like that?
// FIXME: still required?
"MS_NOUSER" => true,
// FIXME: still required?
"MS_RMT_MASK" => true, // updated in glibc 2.22 and musl 1.1.13
// These constants were introduced in FreeBSD 12:
"SF_USER_READAHEAD"
| "EVFILT_EMPTY"
| "SO_REUSEPORT_LB"
| "IP_ORIGDSTADDR"
| "IP_RECVORIGDSTADDR"
| "IPV6_ORIGDSTADDR"
| "IPV6_RECVORIGDSTADDR"
if Some(12) != freebsd_ver =>
{
true
}
// FIXME: There are deprecated - remove in a couple of releases.
// These constants were removed in FreeBSD 11 (svn r273250) but will
// still be accepted and ignored at runtime.
"MAP_RENAME" | "MAP_NORESERVE" => true,
"MAP_RENAME" | "MAP_NORESERVE" if Some(10) != freebsd_ver => true,
// FIXME: There are deprecated - remove in a couple of releases.
// These constants were removed in FreeBSD 11 (svn r262489),
// and they've never had any legitimate use outside of the
// base system anyway.
"CTL_MAXID" | "KERN_MAXID" | "HW_MAXID" | "NET_MAXID"
| "USER_MAXID" => true,
// These constants were added in FreeBSD 11
// FIXME: still required?
"EVFILT_PROCDESC" | "EVFILT_SENDFILE" | "EVFILT_EMPTY"
| "PD_CLOEXEC" | "PD_ALLOWED_AT_FORK" => true,
// These constants were added in FreeBSD 12
// FIXME: still required?
"SF_USER_READAHEAD" | "SO_REUSEPORT_LB" => true,
// These constants are tested in a separate test program generated
// below because there are header conflicts if we try to include the
// headers that define them here.
// FIXME: still required?
"F_CANCELLK" | "F_ADD_SEALS" | "F_GET_SEALS" => true,
// FIXME: still required?
"F_SEAL_SEAL" | "F_SEAL_SHRINK" | "F_SEAL_GROW"
| "F_SEAL_WRITE" => true,
// FIXME: still required?
"BOTHER" => true,
// MFD_HUGETLB is not available in some older libc versions on the
// CI builders. On the x86_64 and i686 builders it seems to be
// available for all targets, so at least test it there.
// FIXME: still required?
"MFD_HUGETLB" if !x86 => true,
// These change all the time from release to release of linux
// distros, let's just not bother trying to verify them. They
// shouldn't be used in code anyway...
// FIXME: still required?
"AF_MAX" | "PF_MAX" => true,
// FreeBSD 12 required, but CI has FreeBSD 11.
// FIXME: still required?
"IP_ORIGDSTADDR"
| "IP_RECVORIGDSTADDR"
| "IPV6_ORIGDSTADDR"
| "IPV6_RECVORIGDSTADDR" => true,
_ => false,
}
});
@ -1686,81 +1603,42 @@ fn test_freebsd(target: &str) {
cfg.skip_fn(move |name| {
// skip those that are manually verified
match name {
// FIXME: still required?
"execv" | // crazy stuff with const/mut
"execve" |
"execvp" |
"execvpe" |
"fexecve" => true,
// FIXME: https://github.com/rust-lang/libc/issues/1272
"execv" | "execve" | "execvp" | "execvpe" | "fexecve" => true,
// The `uname` function in freebsd is now an inline wrapper that
// delegates to another, but the symbol still exists, so don't check
// the symbol.
// FIXME: still required?
// The `uname` function in the `utsname.h` FreeBSD header is a C
// inline function (has no symbol) that calls the `__xuname` symbol.
// Therefore the function pointer comparison does not make sense for it.
"uname" => true,
// FIXME: need to upgrade FreeBSD version; see https://github.com/rust-lang/libc/issues/938
// FIXME: still required?
"setgrent" => true,
// aio_waitcomplete's return type changed between FreeBSD 10 and 11.
// FIXME: still required?
"aio_waitcomplete" => true,
// lio_listio confuses the checker, probably because one of its
// arguments is an array
// FIXME: still required?
// FIXME: Our API is unsound. The Rust API allows aliasing
// pointers, but the C API requires pointers not to alias.
// We should probably be at least using `&`/`&mut` here, see:
// https://github.com/gnzlbg/ctest/issues/68
"lio_listio" => true,
// Definition of those functions as changed since unified headers from NDK r14b
// These changes imply some API breaking changes but are still ABI compatible.
// We can wait for the next major release to be compliant with the new API.
// FIXME: unskip these for next major release
// FIXME: still required ?
"strerror_r" | "madvise" | "msync" | "mprotect" | "recvfrom" | "getpriority" |
_ => false,
}
});
cfg.skip_field_type(move |struct_, field| {
// This is a weird union, don't check the type.
// FIXME: still required?
(struct_ == "ifaddrs" && field == "ifa_ifu") ||
// FIXME: still required?
// sighandler_t type is super weird
(struct_ == "sigaction" && field == "sa_sigaction") ||
// FIXME: still required?
// sigval is actually a union, but we pretend it's a struct
(struct_ == "sigevent" && field == "sigev_value") ||
// aio_buf is "volatile void*" and Rust doesn't understand volatile
// FIXME: still required?
(struct_ == "aiocb" && field == "aio_buf") ||
// stack_t.ss_sp's type changed from FreeBSD 10 to 11 in svn r294930
// FIXME: still required?
(struct_ == "stack_t" && field == "ss_sp")
cfg.volatile_item(|i| {
use ctest::VolatileItemKind::*;
match i {
// aio_buf is a volatile void** but since we cannot express that in
// Rust types, we have to explicitly tell the checker about it here:
StructField(ref n, ref f) if n == "aiocb" && f == "aio_buf" => {
true
}
_ => false,
}
});
cfg.skip_field(move |struct_, field| {
// this is actually a union on linux, so we can't represent it well and
// just insert some padding.
// FIXME: still required?
(struct_ == "siginfo_t" && field == "_pad") ||
// sigev_notify_thread_id is actually part of a sigev_un union
// FIXME: still required?
(struct_ == "sigevent" && field == "sigev_notify_thread_id") ||
// signalfd had SIGSYS fields added in Linux 4.18, but no libc release has them yet.
// FIXME: still required?
(struct_ == "signalfd_siginfo" && (field == "ssi_addr_lsb" ||
field == "_pad2" ||
field == "ssi_syscall" ||
field == "ssi_call_addr" ||
field == "ssi_arch"))
// FIXME: `sa_sigaction` has type `sighandler_t` but that type is
// incorrect, see: https://github.com/rust-lang/libc/issues/1359
(struct_ == "sigaction" && field == "sa_sigaction")
});
// FIXME: remove
cfg.fn_cname(move |name, _cname| name.to_string());
cfg.generate("../src/lib.rs", "main.rs");
}
@ -2334,12 +2212,13 @@ fn test_linux(target: &str) {
}
// FIXME: is this necessary?
"u64" if struct_ == "epoll_event" => "data.u64".to_string(),
// FIXME: is this necessary?
// The following structs have a field called `type` in C,
// but `type` is a Rust keyword, so these fields are translated
// to `type_` in Rust.
"type_"
if struct_ == "input_event"
|| struct_ == "input_mask"
|| struct_ == "ff_effect"
|| struct_ == "rtprio" =>
|| struct_ == "ff_effect" =>
{
"type".to_string()
}
@ -2726,3 +2605,20 @@ fn test_linux_termios2(target: &str) {
});
cfg.generate("../src/lib.rs", "linux_fcntl.rs");
}
fn which_freebsd() -> Option<i32> {
let output = std::process::Command::new("freebsd-version")
.output()
.ok()?;
if !output.status.success() {
return None;
}
let stdout = String::from_utf8(output.stdout).ok()?;
match &stdout {
s if s.starts_with("11") => Some(11),
s if s.starts_with("12") => Some(12),
_ => None,
}
}

View File

@ -2419,6 +2419,7 @@ pub const NOTE_NONE: ::uint32_t = 0x00000080;
pub const NOTE_EXIT: ::uint32_t = 0x80000000;
pub const NOTE_FORK: ::uint32_t = 0x40000000;
pub const NOTE_EXEC: ::uint32_t = 0x20000000;
#[doc(hidden)]
#[deprecated(since="0.2.49", note="Deprecated since MacOSX 10.9")]
pub const NOTE_REAP: ::uint32_t = 0x10000000;
pub const NOTE_SIGNAL: ::uint32_t = 0x08000000;
@ -2426,6 +2427,7 @@ pub const NOTE_EXITSTATUS: ::uint32_t = 0x04000000;
pub const NOTE_EXIT_DETAIL: ::uint32_t = 0x02000000;
pub const NOTE_PDATAMASK: ::uint32_t = 0x000fffff;
pub const NOTE_PCTRLMASK: ::uint32_t = 0xfff00000;
#[doc(hidden)]
#[deprecated(since="0.2.49", note="Deprecated since MacOSX 10.9")]
pub const NOTE_EXIT_REPARENTED: ::uint32_t = 0x00080000;
pub const NOTE_EXIT_DETAIL_MASK: ::uint32_t = 0x00070000;
@ -2632,8 +2634,10 @@ pub const KERN_KDSETRTCDEC: ::c_int = 15;
pub const KERN_KDGETENTROPY: ::c_int = 16;
pub const KERN_KDWRITETR: ::c_int = 17;
pub const KERN_KDWRITEMAP: ::c_int = 18;
#[doc(hidden)]
#[deprecated(since = "0.2.49", note ="Removed in MacOSX 10.12")]
pub const KERN_KDENABLE_BG_TRACE: ::c_int = 19;
#[doc(hidden)]
#[deprecated(since = "0.2.49", note ="Removed in MacOSX 10.12")]
pub const KERN_KDDISABLE_BG_TRACE: ::c_int = 20;
pub const KERN_KDREADCURTHRMAP: ::c_int = 21;
@ -3014,11 +3018,15 @@ f! {
}
extern {
pub fn setgrent();
#[doc(hidden)]
#[deprecated(since="0.2.49", note="Deprecated in MacOSX 10.5")]
#[link_name = "daemon$1050"]
pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int;
#[doc(hidden)]
#[deprecated(since="0.2.49", note="Deprecated in MacOSX 10.10")]
pub fn sem_destroy(sem: *mut sem_t) -> ::c_int;
#[doc(hidden)]
#[deprecated(since="0.2.49", note="Deprecated in MacOSX 10.10")]
pub fn sem_init(sem: *mut sem_t,
pshared: ::c_int,

View File

@ -1,3 +1,4 @@
pub type dev_t = u32;
pub type c_char = i8;
pub type clock_t = u64;
pub type ino_t = u64;
@ -27,6 +28,15 @@ impl ::Clone for sem {
}
s! {
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 exit_status {
pub e_termination: u16,
pub e_exit: u16
@ -1008,6 +1018,7 @@ f! {
}
extern {
pub fn setgrent();
pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int)
-> ::c_int;
pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int;

View File

@ -0,0 +1,214 @@
// APIs that had breaking changes after FreeBSD 11
// The type of `nlink_t` changed from `u16` to `uint64_t` in FreeBSD 12:
pub type nlink_t = u16;
// Type of `dev_t` changed from `u32` to `uint64_t` in FreeBSD 12:
pub type dev_t = u32;
// Type of `ino_t` changed from `unsigned int` to `unsigned long` in FreeBSD 12:
pub type ino_t = u32;
s! {
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 shmid_ds {
pub shm_perm: ::ipc_perm,
pub shm_segsz: ::size_t,
pub shm_lpid: ::pid_t,
pub shm_cpid: ::pid_t,
// Type of shm_nattc changed from `int` to `shmatt_t` (aka `unsigned
// int`) in FreeBSD 12:
pub shm_nattch: ::c_int,
pub shm_atime: ::time_t,
pub shm_dtime: ::time_t,
pub shm_ctime: ::time_t,
}
}
s_no_extra_traits! {
pub struct dirent {
pub d_fileno: ::ino_t,
pub d_reclen: u16,
pub d_type: u8,
// Type of `d_namlen` changed from `char` to `uint16_t` in FreeBSD 12:
pub d_namlen: u8,
pub d_name: [::c_char; 256],
}
pub struct statfs {
pub f_version: ::uint32_t,
pub f_type: ::uint32_t,
pub f_flags: ::uint64_t,
pub f_bsize: ::uint64_t,
pub f_iosize: ::uint64_t,
pub f_blocks: ::uint64_t,
pub f_bfree: ::uint64_t,
pub f_bavail: ::int64_t,
pub f_files: ::uint64_t,
pub f_ffree: ::int64_t,
pub f_syncwrites: ::uint64_t,
pub f_asyncwrites: ::uint64_t,
pub f_syncreads: ::uint64_t,
pub f_asyncreads: ::uint64_t,
f_spare: [::uint64_t; 10],
pub f_namemax: ::uint32_t,
pub f_owner: ::uid_t,
pub f_fsid: ::fsid_t,
f_charspare: [::c_char; 80],
pub f_fstypename: [::c_char; 16],
// Array length changed from 88 to 1024 in FreeBSD 12:
pub f_mntfromname: [::c_char; 88],
// Array length changed from 88 to 1024 in FreeBSD 12:
pub f_mntonname: [::c_char; 88],
}
}
cfg_if! {
if #[cfg(feature = "extra_traits")] {
impl PartialEq for statfs {
fn eq(&self, other: &statfs) -> bool {
self.f_version == other.f_version
&& self.f_type == other.f_type
&& self.f_flags == other.f_flags
&& self.f_bsize == other.f_bsize
&& self.f_iosize == other.f_iosize
&& self.f_blocks == other.f_blocks
&& self.f_bfree == other.f_bfree
&& self.f_bavail == other.f_bavail
&& self.f_files == other.f_files
&& self.f_ffree == other.f_ffree
&& self.f_syncwrites == other.f_syncwrites
&& self.f_asyncwrites == other.f_asyncwrites
&& self.f_syncreads == other.f_syncreads
&& self.f_asyncreads == other.f_asyncreads
&& self.f_namemax == other.f_namemax
&& self.f_owner == other.f_owner
&& self.f_fsid == other.f_fsid
&& self.f_fstypename == other.f_fstypename
&& self
.f_mntfromname
.iter()
.zip(other.f_mntfromname.iter())
.all(|(a,b)| a == b)
&& self
.f_mntonname
.iter()
.zip(other.f_mntonname.iter())
.all(|(a,b)| a == b)
}
}
impl Eq for statfs {}
impl ::fmt::Debug for statfs {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("statfs")
.field("f_bsize", &self.f_bsize)
.field("f_iosize", &self.f_iosize)
.field("f_blocks", &self.f_blocks)
.field("f_bfree", &self.f_bfree)
.field("f_bavail", &self.f_bavail)
.field("f_files", &self.f_files)
.field("f_ffree", &self.f_ffree)
.field("f_syncwrites", &self.f_syncwrites)
.field("f_asyncwrites", &self.f_asyncwrites)
.field("f_syncreads", &self.f_syncreads)
.field("f_asyncreads", &self.f_asyncreads)
.field("f_namemax", &self.f_namemax)
.field("f_owner", &self.f_owner)
.field("f_fsid", &self.f_fsid)
.field("f_fstypename", &self.f_fstypename)
.field("f_mntfromname", &&self.f_mntfromname[..])
.field("f_mntonname", &&self.f_mntonname[..])
.finish()
}
}
impl ::hash::Hash for statfs {
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
self.f_version.hash(state);
self.f_type.hash(state);
self.f_flags.hash(state);
self.f_bsize.hash(state);
self.f_iosize.hash(state);
self.f_blocks.hash(state);
self.f_bfree.hash(state);
self.f_bavail.hash(state);
self.f_files.hash(state);
self.f_ffree.hash(state);
self.f_syncwrites.hash(state);
self.f_asyncwrites.hash(state);
self.f_syncreads.hash(state);
self.f_asyncreads.hash(state);
self.f_namemax.hash(state);
self.f_owner.hash(state);
self.f_fsid.hash(state);
self.f_fstypename.hash(state);
self.f_mntfromname.hash(state);
self.f_mntonname.hash(state);
}
}
impl PartialEq for dirent {
fn eq(&self, other: &dirent) -> bool {
self.d_fileno == other.d_fileno
&& self.d_reclen == other.d_reclen
&& self.d_type == other.d_type
&& self.d_namlen == other.d_namlen
&& self
.d_name[..self.d_namlen as _]
.iter()
.zip(other.d_name.iter())
.all(|(a,b)| a == b)
}
}
impl Eq for dirent {}
impl ::fmt::Debug for dirent {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("dirent")
.field("d_fileno", &self.d_fileno)
.field("d_reclen", &self.d_reclen)
.field("d_type", &self.d_type)
.field("d_namlen", &self.d_namlen)
.field("d_name", &&self.d_name[..self.d_namlen as _])
.finish()
}
}
impl ::hash::Hash for dirent {
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
self.d_fileno.hash(state);
self.d_reclen.hash(state);
self.d_type.hash(state);
self.d_namlen.hash(state);
self.d_name[..self.d_namlen as _].hash(state);
}
}
}
}
extern {
// Return type ::c_int was removed in FreeBSD 12
pub fn setgrent() -> ::c_int;
// Type of `addr` argument changed from `const void*` to `void*`
// in FreeBSD 12
pub fn mprotect(addr: *const ::c_void, len: ::size_t, prot: ::c_int)
-> ::c_int;
// Return type ::c_int was removed in FreeBSD 12
pub fn freelocale(loc: ::locale_t) -> ::c_int;
// Return type ::c_int changed to ::ssize_t in FreeBSD 12:
pub fn msgrcv(msqid: ::c_int, msgp: *mut ::c_void, msgsz: ::size_t,
msgtyp: ::c_long, msgflg: ::c_int) -> ::c_int;
}
cfg_if! {
if #[cfg(target_arch = "x86_64")] {
mod x86_64;
pub use self::x86_64::*;
}
}

View File

@ -0,0 +1,30 @@
#[repr(C)]
#[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))]
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: u32,
pub st_lspare: i32,
pub st_birthtime: ::time_t,
pub st_birthtime_nsec: ::c_long,
}
impl ::Copy for ::stat {}
impl ::Clone for ::stat {
fn clone(&self) -> ::stat { *self }
}

View File

@ -0,0 +1,207 @@
// APIs that changed in FreeBSD12
pub type nlink_t = u64;
pub type dev_t = u64;
pub type ino_t = ::c_ulong;
pub type shmatt_t = ::c_uint;
s! {
pub struct shmid_ds {
pub shm_perm: ::ipc_perm,
pub shm_segsz: ::size_t,
pub shm_lpid: ::pid_t,
pub shm_cpid: ::pid_t,
pub shm_nattch: ::shmatt_t,
pub shm_atime: ::time_t,
pub shm_dtime: ::time_t,
pub shm_ctime: ::time_t,
}
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: [u64; 4],
}
}
s_no_extra_traits! {
pub struct dirent {
pub d_fileno: ::ino_t,
pub d_off: ::off_t,
pub d_reclen: u16,
pub d_type: u8,
d_pad0: u8,
pub d_namlen: u16,
d_pad1: u16,
pub d_name: [::c_char; 256],
}
pub struct statfs {
pub f_version: ::uint32_t,
pub f_type: ::uint32_t,
pub f_flags: ::uint64_t,
pub f_bsize: ::uint64_t,
pub f_iosize: ::uint64_t,
pub f_blocks: ::uint64_t,
pub f_bfree: ::uint64_t,
pub f_bavail: ::int64_t,
pub f_files: ::uint64_t,
pub f_ffree: ::int64_t,
pub f_syncwrites: ::uint64_t,
pub f_asyncwrites: ::uint64_t,
pub f_syncreads: ::uint64_t,
pub f_asyncreads: ::uint64_t,
f_spare: [::uint64_t; 10],
pub f_namemax: ::uint32_t,
pub f_owner: ::uid_t,
pub f_fsid: ::fsid_t,
f_charspare: [::c_char; 80],
pub f_fstypename: [::c_char; 16],
pub f_mntfromname: [::c_char; 1024],
pub f_mntonname: [::c_char; 1024],
}
}
cfg_if! {
if #[cfg(feature = "extra_traits")] {
impl PartialEq for statfs {
fn eq(&self, other: &statfs) -> bool {
self.f_version == other.f_version
&& self.f_type == other.f_type
&& self.f_flags == other.f_flags
&& self.f_bsize == other.f_bsize
&& self.f_iosize == other.f_iosize
&& self.f_blocks == other.f_blocks
&& self.f_bfree == other.f_bfree
&& self.f_bavail == other.f_bavail
&& self.f_files == other.f_files
&& self.f_ffree == other.f_ffree
&& self.f_syncwrites == other.f_syncwrites
&& self.f_asyncwrites == other.f_asyncwrites
&& self.f_syncreads == other.f_syncreads
&& self.f_asyncreads == other.f_asyncreads
&& self.f_namemax == other.f_namemax
&& self.f_owner == other.f_owner
&& self.f_fsid == other.f_fsid
&& self.f_fstypename == other.f_fstypename
&& self
.f_mntfromname
.iter()
.zip(other.f_mntfromname.iter())
.all(|(a,b)| a == b)
&& self
.f_mntonname
.iter()
.zip(other.f_mntonname.iter())
.all(|(a,b)| a == b)
}
}
impl Eq for statfs {}
impl ::fmt::Debug for statfs {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("statfs")
.field("f_bsize", &self.f_bsize)
.field("f_iosize", &self.f_iosize)
.field("f_blocks", &self.f_blocks)
.field("f_bfree", &self.f_bfree)
.field("f_bavail", &self.f_bavail)
.field("f_files", &self.f_files)
.field("f_ffree", &self.f_ffree)
.field("f_syncwrites", &self.f_syncwrites)
.field("f_asyncwrites", &self.f_asyncwrites)
.field("f_syncreads", &self.f_syncreads)
.field("f_asyncreads", &self.f_asyncreads)
.field("f_namemax", &self.f_namemax)
.field("f_owner", &self.f_owner)
.field("f_fsid", &self.f_fsid)
.field("f_fstypename", &self.f_fstypename)
.field("f_mntfromname", &&self.f_mntfromname[..])
.field("f_mntonname", &&self.f_mntonname[..])
.finish()
}
}
impl ::hash::Hash for statfs {
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
self.f_version.hash(state);
self.f_type.hash(state);
self.f_flags.hash(state);
self.f_bsize.hash(state);
self.f_iosize.hash(state);
self.f_blocks.hash(state);
self.f_bfree.hash(state);
self.f_bavail.hash(state);
self.f_files.hash(state);
self.f_ffree.hash(state);
self.f_syncwrites.hash(state);
self.f_asyncwrites.hash(state);
self.f_syncreads.hash(state);
self.f_asyncreads.hash(state);
self.f_namemax.hash(state);
self.f_owner.hash(state);
self.f_fsid.hash(state);
self.f_charspare.hash(state);
self.f_fstypename.hash(state);
self.f_mntfromname.hash(state);
self.f_mntonname.hash(state);
}
}
impl PartialEq for dirent {
fn eq(&self, other: &dirent) -> bool {
self.d_fileno == other.d_fileno
&& self.d_off == other.d_off
&& self.d_reclen == other.d_reclen
&& self.d_type == other.d_type
&& self.d_namlen == other.d_namlen
&& self
.d_name[..self.d_namlen as _]
.iter()
.zip(other.d_name.iter())
.all(|(a,b)| a == b)
}
}
impl Eq for dirent {}
impl ::fmt::Debug for dirent {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("dirent")
.field("d_fileno", &self.d_fileno)
.field("d_off", &self.d_off)
.field("d_reclen", &self.d_reclen)
.field("d_type", &self.d_type)
.field("d_namlen", &self.d_namlen)
.field("d_name", &&self.d_name[..self.d_namlen as _])
.finish()
}
}
impl ::hash::Hash for dirent {
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
self.d_fileno.hash(state);
self.d_off.hash(state);
self.d_reclen.hash(state);
self.d_type.hash(state);
self.d_namlen.hash(state);
self.d_name[..self.d_namlen as _].hash(state);
}
}
}
}
extern {
pub fn setgrent();
pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int)
-> ::c_int;
pub fn freelocale(loc: ::locale_t);
pub fn msgrcv(msqid: ::c_int, msgp: *mut ::c_void, msgsz: ::size_t,
msgtyp: ::c_long, msgflg: ::c_int) -> ::ssize_t;
}
cfg_if! {
if #[cfg(target_arch = "x86_64")] {
mod x86_64;
pub use self::x86_64::*;
}
}

View File

@ -0,0 +1,32 @@
#[repr(C)]
#[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))]
pub struct stat {
pub st_dev: ::dev_t,
pub st_ino: ::ino_t,
pub st_nlink: ::nlink_t,
pub st_mode: ::mode_t,
st_padding0: i16,
pub st_uid: ::uid_t,
pub st_gid: ::gid_t,
st_padding1: i32,
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_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: u64,
pub st_spare: [u64; 10],
}
impl ::Copy for ::stat {}
impl ::Clone for ::stat {
fn clone(&self) -> ::stat { *self }
}

View File

@ -1,8 +1,7 @@
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 = i32;
pub type clockid_t = ::c_int;
pub type sem_t = _sem;
@ -110,17 +109,6 @@ s! {
pub msg_ctime: ::time_t,
}
pub struct shmid_ds {
pub shm_perm: ::ipc_perm,
pub shm_segsz: ::size_t,
pub shm_lpid: ::pid_t,
pub shm_cpid: ::pid_t,
pub shm_nattch: ::c_int,
pub shm_atime: ::time_t,
pub shm_dtime: ::time_t,
pub shm_ctime: ::time_t,
}
pub struct xucred {
pub cr_version: ::c_uint,
pub cr_uid: ::uid_t,
@ -153,39 +141,6 @@ s_no_extra_traits! {
pub __ut_spare: [::c_char; 64],
}
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 statfs {
pub f_version: ::uint32_t,
pub f_type: ::uint32_t,
pub f_flags: ::uint64_t,
pub f_bsize: ::uint64_t,
pub f_iosize: ::uint64_t,
pub f_blocks: ::uint64_t,
pub f_bfree: ::uint64_t,
pub f_bavail: ::int64_t,
pub f_files: ::uint64_t,
pub f_ffree: ::int64_t,
pub f_syncwrites: ::uint64_t,
pub f_asyncwrites: ::uint64_t,
pub f_syncreads: ::uint64_t,
pub f_asyncreads: ::uint64_t,
f_spare: [::uint64_t; 10],
pub f_namemax: ::uint32_t,
pub f_owner: ::uid_t,
pub f_fsid: ::fsid_t,
f_charspare: [::c_char; 80],
pub f_fstypename: [::c_char; 16],
pub f_mntfromname: [::c_char; 88],
pub f_mntonname: [::c_char; 88],
}
pub struct sockaddr_dl {
pub sdl_len: ::c_uchar,
pub sdl_family: ::c_uchar,
@ -248,132 +203,6 @@ cfg_if! {
}
}
impl PartialEq for dirent {
fn eq(&self, other: &dirent) -> bool {
self.d_fileno == other.d_fileno
&& self.d_reclen == other.d_reclen
&& self.d_type == other.d_type
&& self.d_namlen == other.d_namlen
&& self
.d_name
.iter()
.zip(other.d_name.iter())
.all(|(a,b)| a == b)
}
}
impl Eq for dirent {}
impl ::fmt::Debug for dirent {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("dirent")
.field("d_fileno", &self.d_fileno)
.field("d_reclen", &self.d_reclen)
.field("d_type", &self.d_type)
.field("d_namlen", &self.d_namlen)
// FIXME: .field("d_name", &self.d_name)
.finish()
}
}
impl ::hash::Hash for dirent {
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
self.d_fileno.hash(state);
self.d_reclen.hash(state);
self.d_type.hash(state);
self.d_namlen.hash(state);
self.d_name.hash(state);
}
}
impl PartialEq for statfs {
fn eq(&self, other: &statfs) -> bool {
self.f_version == other.f_version
&& self.f_type == other.f_type
&& self.f_flags == other.f_flags
&& self.f_bsize == other.f_bsize
&& self.f_iosize == other.f_iosize
&& self.f_blocks == other.f_blocks
&& self.f_bfree == other.f_bfree
&& self.f_bavail == other.f_bavail
&& self.f_files == other.f_files
&& self.f_ffree == other.f_ffree
&& self.f_syncwrites == other.f_syncwrites
&& self.f_asyncwrites == other.f_asyncwrites
&& self.f_syncreads == other.f_syncreads
&& self.f_asyncreads == other.f_asyncreads
&& self.f_spare == other.f_spare
&& self.f_namemax == other.f_namemax
&& self.f_owner == other.f_owner
&& self.f_fsid == other.f_fsid
&& self
.f_charspare
.iter()
.zip(other.f_charspare.iter())
.all(|(a,b)| a == b)
&& self.f_fstypename == other.f_fstypename
&& self
.f_mntfromname
.iter()
.zip(other.f_mntfromname.iter())
.all(|(a,b)| a == b)
&& self
.f_mntonname
.iter()
.zip(other.f_mntonname.iter())
.all(|(a,b)| a == b)
}
}
impl Eq for statfs {}
impl ::fmt::Debug for statfs {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("statfs")
.field("f_bsize", &self.f_bsize)
.field("f_iosize", &self.f_iosize)
.field("f_blocks", &self.f_blocks)
.field("f_bfree", &self.f_bfree)
.field("f_bavail", &self.f_bavail)
.field("f_files", &self.f_files)
.field("f_ffree", &self.f_ffree)
.field("f_syncwrites", &self.f_syncwrites)
.field("f_asyncwrites", &self.f_asyncwrites)
.field("f_syncreads", &self.f_syncreads)
.field("f_asyncreads", &self.f_asyncreads)
.field("f_spare", &self.f_spare)
.field("f_namemax", &self.f_namemax)
.field("f_owner", &self.f_owner)
.field("f_fsid", &self.f_fsid)
// FIXME: .field("f_charspare", &self.f_charspare)
.field("f_fstypename", &self.f_fstypename)
// FIXME: .field("f_mntfromname", &self.f_mntfromname)
// FIXME: .field("f_mntonname", &self.f_mntonname)
.finish()
}
}
impl ::hash::Hash for statfs {
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
self.f_version.hash(state);
self.f_type.hash(state);
self.f_flags.hash(state);
self.f_bsize.hash(state);
self.f_iosize.hash(state);
self.f_blocks.hash(state);
self.f_bfree.hash(state);
self.f_bavail.hash(state);
self.f_files.hash(state);
self.f_ffree.hash(state);
self.f_syncwrites.hash(state);
self.f_asyncwrites.hash(state);
self.f_syncreads.hash(state);
self.f_asyncreads.hash(state);
self.f_spare.hash(state);
self.f_namemax.hash(state);
self.f_owner.hash(state);
self.f_fsid.hash(state);
self.f_charspare.hash(state);
self.f_fstypename.hash(state);
self.f_mntfromname.hash(state);
self.f_mntonname.hash(state);
}
}
impl PartialEq for sockaddr_dl {
fn eq(&self, other: &sockaddr_dl) -> bool {
self.sdl_len == other.sdl_len
@ -779,14 +608,21 @@ pub const IFF_POINTOPOINT: ::c_int = 0x10; // (i) is a point-to-point link
// 0x20 was IFF_SMART
pub const IFF_RUNNING: ::c_int = 0x40; // (d) resources allocated
#[doc(hidden)]
// IFF_DRV_RUNNING is deprecated. Use the portable `IFF_RUNNING` instead
#[doc(hidden)]
#[deprecated(
since="0.2.54",
note="IFF_DRV_RUNNING is deprecated. Use the portable IFF_RUNNING instead"
)]
pub const IFF_DRV_RUNNING: ::c_int = 0x40;
pub const IFF_NOARP: ::c_int = 0x80; // (n) no address resolution protocol
pub const IFF_PROMISC: ::c_int = 0x100; // (n) receive all packets
pub const IFF_ALLMULTI: ::c_int = 0x200; // (n) receive all multicast packets
pub const IFF_OACTIVE: ::c_int = 0x400; // (d) tx hardware queue is full
#[doc(hidden)]
// IFF_DRV_OACTIVE is deprecated. Use the portable `IFF_OACTIVE` instead
#[deprecated(
since = "0.2.54",
note = "Use the portable `IFF_OACTIVE` instead",
)]
pub const IFF_DRV_OACTIVE: ::c_int = 0x400;
pub const IFF_SIMPLEX: ::c_int = 0x800; // (i) can't hear own transmissions
pub const IFF_LINK0: ::c_int = 0x1000; // per link layer defined bit
@ -1106,14 +942,19 @@ pub const SHM_ANON: *mut ::c_char = 1 as *mut ::c_char;
// they were all removed in svn r262489. They remain here for backwards
// compatibility only, and are scheduled to be removed in libc 1.0.0.
#[doc(hidden)]
#[deprecated(since="0.2.54",note="Removed in FreeBSD 11")]
pub const NET_MAXID: ::c_int = AF_MAX;
#[doc(hidden)]
#[deprecated(since="0.2.54",note="Removed in FreeBSD 11")]
pub const CTL_MAXID: ::c_int = 10;
#[doc(hidden)]
#[deprecated(since="0.2.54",note="Removed in FreeBSD 11")]
pub const KERN_MAXID: ::c_int = 38;
#[doc(hidden)]
#[deprecated(since="0.2.54",note="Removed in FreeBSD 11")]
pub const HW_MAXID: ::c_int = 13;
#[doc(hidden)]
#[deprecated(since="0.2.54",note="Removed in FreeBSD 11")]
pub const USER_MAXID: ::c_int = 21;
#[doc(hidden)]
pub const CTL_P1003_1B_MAXID: ::c_int = 26;
@ -1251,9 +1092,6 @@ f! {
extern {
pub fn __error() -> *mut ::c_int;
pub fn mprotect(addr: *const ::c_void, len: ::size_t, prot: ::c_int)
-> ::c_int;
pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int;
pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int;
pub fn clock_settime(clk_id: ::clockid_t, tp: *const ::timespec) -> ::c_int;
@ -1335,7 +1173,6 @@ extern {
timeout: *mut ::timespec) -> ::ssize_t;
pub fn mq_getfd_np(mqd: ::mqd_t) -> ::c_int;
pub fn freelocale(loc: ::locale_t) -> ::c_int;
pub fn waitid(idtype: idtype_t, id: ::id_t, infop: *mut ::siginfo_t,
options: ::c_int) -> ::c_int;
@ -1349,8 +1186,6 @@ extern {
pub fn msgctl(msqid: ::c_int, cmd: ::c_int,
buf: *mut ::msqid_ds) -> ::c_int;
pub fn msgget(key: ::key_t, msgflg: ::c_int) -> ::c_int;
pub fn msgrcv(msqid: ::c_int, msgp: *mut ::c_void, msgsz: ::size_t,
msgtyp: ::c_long, msgflg: ::c_int) -> ::c_int;
pub fn msgsnd(msqid: ::c_int, msgp: *const ::c_void, msgsz: ::size_t,
msgflg: ::c_int) -> ::c_int;
pub fn cfmakesane(termios: *mut ::termios);
@ -1451,6 +1286,16 @@ extern {
attrnamespace: *mut ::c_int) -> ::c_int;
}
cfg_if! {
if #[cfg(freebsd12)] {
mod freebsd12;
pub use self::freebsd12::*;
} else {
mod freebsd11;
pub use self::freebsd11::*;
}
}
cfg_if! {
if #[cfg(target_arch = "x86")] {
mod x86;

View File

@ -4,32 +4,6 @@ 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,
}
}
// should be pub(crate), but that requires Rust 1.18.0
cfg_if! {
if #[cfg(libc_const_size_of)] {

View File

@ -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;
@ -46,15 +45,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 addrinfo {
pub ai_flags: ::c_int,
pub ai_family: ::c_int,
@ -758,7 +748,11 @@ pub const LOCK_NB: ::c_int = 4;
pub const LOCK_UN: ::c_int = 8;
pub const MAP_COPY: ::c_int = 0x0002;
#[doc(hidden)]
#[deprecated(since="0.2.54",note="Removed in FreeBSD 11")]
pub const MAP_RENAME: ::c_int = 0x0020;
#[doc(hidden)]
#[deprecated(since="0.2.54",note="Removed in FreeBSD 11")]
pub const MAP_NORESERVE: ::c_int = 0x0040;
pub const MAP_HASSEMAPHORE: ::c_int = 0x0200;
pub const MAP_STACK: ::c_int = 0x0400;
@ -1141,7 +1135,10 @@ extern {
pub fn getutxid(ut: *const utmpx) -> *mut utmpx;
pub fn getutxline(ut: *const utmpx) -> *mut utmpx;
pub fn initgroups(name: *const ::c_char, basegid: ::gid_t) -> ::c_int;
#[cfg_attr(target_os = "freebsd", link_name = "kevent@FBSD_1.0")]
#[cfg_attr(
all(target_os = "freebsd", not(freebsd12)),
link_name = "kevent@FBSD_1.0"
)]
pub fn kevent(kq: ::c_int,
changelist: *const ::kevent,
nchanges: ::c_int,
@ -1157,7 +1154,10 @@ extern {
n: ::size_t) -> *mut ::c_void;
pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char,
mode: ::mode_t) -> ::c_int;
#[cfg_attr(target_os = "freebsd", link_name = "mknodat@FBSD_1.1")]
#[cfg_attr(
all(target_os = "freebsd", not(freebsd12)),
link_name = "mknodat@FBSD_1.1"
)]
pub fn mknodat(dirfd: ::c_int, pathname: *const ::c_char,
mode: ::mode_t, dev: dev_t) -> ::c_int;
pub fn mq_close(mqd: ::mqd_t) -> ::c_int;

View File

@ -508,7 +508,6 @@ extern {
pub fn getpwent() -> *mut passwd;
pub fn setpwent();
pub fn endpwent();
pub fn setgrent();
pub fn endgrent();
pub fn getgrent() -> *mut ::group;
@ -524,14 +523,20 @@ extern {
#[cfg_attr(target_os = "macos", link_name = "glob$INODE64")]
#[cfg_attr(target_os = "netbsd", link_name = "__glob30")]
#[cfg_attr(target_os = "freebsd", link_name = "glob@FBSD_1.0")]
#[cfg_attr(
all(target_os = "freebsd", not(freebsd12)),
link_name = "glob@FBSD_1.0"
)]
pub fn glob(pattern: *const ::c_char,
flags: ::c_int,
errfunc: ::Option<extern fn(epath: *const ::c_char,
errno: ::c_int) -> ::c_int>,
pglob: *mut ::glob_t) -> ::c_int;
#[cfg_attr(target_os = "netbsd", link_name = "__globfree30")]
#[cfg_attr(target_os = "freebsd", link_name = "globfree@FBSD_1.0")]
#[cfg_attr(
all(target_os = "freebsd", not(freebsd12)),
link_name = "globfree@FBSD_1.0"
)]
pub fn globfree(pglob: *mut ::glob_t);
pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int)

View File

@ -597,6 +597,7 @@ pub const TIMER_ABSTIME: ::c_int = 1;
#[link(name = "util")]
extern {
pub fn setgrent();
pub fn sem_destroy(sem: *mut sem_t) -> ::c_int;
pub fn sem_init(sem: *mut sem_t,
pshared: ::c_int,

View File

@ -575,14 +575,20 @@ extern {
#[cfg_attr(target_os = "macos", link_name = "fstat$INODE64")]
#[cfg_attr(target_os = "netbsd", link_name = "__fstat50")]
#[cfg_attr(target_os = "freebsd", link_name = "fstat@FBSD_1.0")]
#[cfg_attr(
all(target_os = "freebsd", not(freebsd12)),
link_name = "fstat@FBSD_1.0"
)]
pub fn fstat(fildes: ::c_int, buf: *mut stat) -> ::c_int;
pub fn mkdir(path: *const c_char, mode: mode_t) -> ::c_int;
#[cfg_attr(target_os = "macos", link_name = "stat$INODE64")]
#[cfg_attr(target_os = "netbsd", link_name = "__stat50")]
#[cfg_attr(target_os = "freebsd", link_name = "stat@FBSD_1.0")]
#[cfg_attr(
all(target_os = "freebsd", not(freebsd12)),
link_name = "stat@FBSD_1.0"
)]
pub fn stat(path: *const c_char, buf: *mut stat) -> ::c_int;
pub fn pclose(stream: *mut ::FILE) -> ::c_int;
@ -616,11 +622,17 @@ extern {
#[cfg_attr(target_os = "macos", link_name = "readdir$INODE64")]
#[cfg_attr(target_os = "netbsd", link_name = "__readdir30")]
#[cfg_attr(target_os = "freebsd", link_name = "readdir@FBSD_1.0")]
#[cfg_attr(
all(target_os = "freebsd", not(freebsd12)),
link_name = "readdir@FBSD_1.0"
)]
pub fn readdir(dirp: *mut ::DIR) -> *mut ::dirent;
#[cfg_attr(target_os = "macos", link_name = "readdir_r$INODE64")]
#[cfg_attr(target_os = "netbsd", link_name = "__readdir_r30")]
#[cfg_attr(target_os = "freebsd", link_name = "readdir_r@FBSD_1.0")]
#[cfg_attr(
all(target_os = "freebsd", not(freebsd12)),
link_name = "readdir_r@FBSD_1.0"
)]
/// The 64-bit libc on Solaris and illumos only has readdir_r. If a
/// 32-bit Solaris or illumos target is ever created, it should use
/// __posix_readdir_r. See libc(3LIB) on Solaris or illumos:
@ -649,7 +661,10 @@ extern {
owner: ::uid_t, group: ::gid_t,
flags: ::c_int) -> ::c_int;
#[cfg_attr(target_os = "macos", link_name = "fstatat$INODE64")]
#[cfg_attr(target_os = "freebsd", link_name = "fstatat@FBSD_1.1")]
#[cfg_attr(
all(target_os = "freebsd", not(freebsd12)),
link_name = "fstatat@FBSD_1.1"
)]
pub fn fstatat(dirfd: ::c_int, pathname: *const ::c_char,
buf: *mut stat, flags: ::c_int) -> ::c_int;
pub fn linkat(olddirfd: ::c_int, oldpath: *const ::c_char,
@ -804,7 +819,10 @@ extern {
#[cfg_attr(target_os = "macos", link_name = "lstat$INODE64")]
#[cfg_attr(target_os = "netbsd", link_name = "__lstat50")]
#[cfg_attr(target_os = "freebsd", link_name = "lstat@FBSD_1.0")]
#[cfg_attr(
all(target_os = "freebsd", not(freebsd12)),
link_name = "lstat@FBSD_1.0"
)]
pub fn lstat(path: *const c_char, buf: *mut stat) -> ::c_int;
#[cfg_attr(all(target_os = "macos", target_arch = "x86"),
@ -984,7 +1002,10 @@ extern {
pub fn difftime(time1: time_t, time0: time_t) -> ::c_double;
#[cfg_attr(target_os = "netbsd", link_name = "__mknod50")]
#[cfg_attr(target_os = "freebsd", link_name = "mknod@FBSD_1.0")]
#[cfg_attr(
all(target_os = "freebsd", not(freebsd12)),
link_name = "mknod@FBSD_1.0"
)]
pub fn mknod(pathname: *const ::c_char, mode: ::mode_t,
dev: ::dev_t) -> ::c_int;
pub fn gethostname(name: *mut ::c_char, len: ::size_t) -> ::c_int;

View File

@ -48,6 +48,7 @@ s! {
pub si_signo: ::c_int,
pub si_errno: ::c_int,
pub si_code: ::c_int,
#[doc(hidden)]
#[deprecated(
since="0.2.54",
note="Please leave a comment on \