diff --git a/.cirrus.yml b/.cirrus.yml index e3f777b52907f..4fb29f518069b 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,3 +1,17 @@ +task: + name: nightly x86_64-unknown-freebsd-10 + freebsd_instance: + image: freebsd-10-4-release-amd64 + setup_script: + - pkg install -y curl + - curl https://sh.rustup.rs -sSf --output rustup.sh + - sh rustup.sh --default-toolchain nightly -y + - . $HOME/.cargo/env + - rustup default nightly + test_script: + - . $HOME/.cargo/env + - LIBC_CI=1 sh ci/run.sh x86_64-unknown-freebsd + task: name: stable x86_64-unknown-freebsd-11 freebsd_instance: diff --git a/build.rs b/build.rs index d9d23ca2ac9a8..d5bcb5253a4c8 100644 --- a/build.rs +++ b/build.rs @@ -16,11 +16,15 @@ fn main() { ); } - // The ABI of libc is backward compatible with FreeBSD 11. + // The ABI of libc used by libstd is backward compatible with FreeBSD 10. + // The ABI of libc from crates.io is backward compatible with FreeBSD 11. // // On CI, we detect the actual FreeBSD version and match its ABI exactly, // running tests to ensure that the ABI is correct. match which_freebsd() { + Some(10) if libc_ci || rustc_dep_of_std => { + println!("cargo:rustc-cfg=freebsd10") + } Some(11) if libc_ci => println!("cargo:rustc-cfg=freebsd11"), Some(12) if libc_ci => println!("cargo:rustc-cfg=freebsd12"), Some(13) if libc_ci => println!("cargo:rustc-cfg=freebsd13"), @@ -109,6 +113,7 @@ fn which_freebsd() -> Option { let stdout = stdout.unwrap(); match &stdout { + s if s.starts_with("10") => Some(10), s if s.starts_with("11") => Some(11), s if s.starts_with("12") => Some(12), s if s.starts_with("13") => Some(13), diff --git a/libc-test/build.rs b/libc-test/build.rs index 002ece011b99b..336de17995982 100644 --- a/libc-test/build.rs +++ b/libc-test/build.rs @@ -1457,6 +1457,7 @@ fn test_freebsd(target: &str) { let freebsd_ver = which_freebsd(); match freebsd_ver { + Some(10) => cfg.cfg("freebsd10", None), Some(11) => cfg.cfg("freebsd11", None), Some(12) => cfg.cfg("freebsd12", None), Some(13) => cfg.cfg("freebsd13", None), @@ -1466,7 +1467,10 @@ fn test_freebsd(target: &str) { // Required for `getline`: cfg.define("_WITH_GETLINE", None); // Required for making freebsd11_stat available in the headers - cfg.define("_WANT_FREEBSD11_STAT", None); + match freebsd_ver { + Some(10) => &mut cfg, + _ => cfg.define("_WANT_FREEBSD11_STAT", None), + }; headers! { cfg: "aio.h", @@ -1594,6 +1598,34 @@ fn test_freebsd(target: &str) { true } + // These constants were introduced in FreeBSD 11: + "SF_USER_READAHEAD" + | "SF_NOCACHE" + | "RLIMIT_KQUEUES" + | "RLIMIT_UMTXP" + | "EVFILT_PROCDESC" + | "EVFILT_SENDFILE" + | "EVFILT_EMPTY" + | "SO_REUSEPORT_LB" + | "TCP_CCALGOOPT" + | "TCP_PCAP_OUT" + | "TCP_PCAP_IN" + | "IP_BINDMULTI" + | "IP_ORIGDSTADDR" + | "IP_RECVORIGDSTADDR" + | "IPV6_ORIGDSTADDR" + | "IPV6_RECVORIGDSTADDR" + | "PD_CLOEXEC" + | "PD_ALLOWED_AT_FORK" + | "IP_RSS_LISTEN_BUCKET" + if Some(10) == freebsd_ver => + { + true + } + + // FIXME: This constant has a different value in FreeBSD 10: + "RLIM_NLIMITS" if Some(10) == 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. @@ -1609,12 +1641,28 @@ fn test_freebsd(target: &str) { } }); + cfg.skip_struct(move |ty| { + match ty { + // `mmsghdr` is not available in FreeBSD 10 + "mmsghdr" if Some(10) == freebsd_ver => true, + + _ => false, + } + }); + cfg.skip_fn(move |name| { // skip those that are manually verified match name { // FIXME: https://github.com/rust-lang/libc/issues/1272 "execv" | "execve" | "execvp" | "execvpe" | "fexecve" => true, + // These functions were added in FreeBSD 11: + "fdatasync" | "mq_getfd_np" if Some(10) == freebsd_ver => true, + + // This function changed its return type from `int` in FreeBSD10 to + // `ssize_t` in FreeBSD11: + "aio_waitcomplete" if Some(10) == freebsd_ver => true, + // 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. @@ -1630,6 +1678,14 @@ fn test_freebsd(target: &str) { } }); + cfg.skip_signededness(move |c| { + match c { + // FIXME: has a different sign in FreeBSD10 + "blksize_t" if Some(10) == freebsd_ver => true, + _ => false, + } + }); + cfg.volatile_item(|i| { use ctest::VolatileItemKind::*; match i { @@ -1643,9 +1699,17 @@ fn test_freebsd(target: &str) { }); cfg.skip_field(move |struct_, field| { - // 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") + match (struct_, field) { + // FIXME: `sa_sigaction` has type `sighandler_t` but that type is + // incorrect, see: https://github.com/rust-lang/libc/issues/1359 + ("sigaction", "sa_sigaction") => true, + + // FIXME: in FreeBSD10 this field has type `char*` instead of + // `void*`: + ("stack_t", "ss_sp") if Some(10) == freebsd_ver => true, + + _ => false, + } }); cfg.skip_roundtrip(move |s| match s { @@ -2473,6 +2537,7 @@ fn which_freebsd() -> Option { let stdout = String::from_utf8(output.stdout).ok()?; match &stdout { + s if s.starts_with("10") => Some(10), s if s.starts_with("11") => Some(11), s if s.starts_with("12") => Some(12), s if s.starts_with("13") => Some(13), diff --git a/src/unix/bsd/freebsdlike/freebsd/mod.rs b/src/unix/bsd/freebsdlike/freebsd/mod.rs index d534af9091291..8f29e4500a4f4 100644 --- a/src/unix/bsd/freebsdlike/freebsd/mod.rs +++ b/src/unix/bsd/freebsdlike/freebsd/mod.rs @@ -307,6 +307,26 @@ cfg_if! { } } +pub const SF_USER_READAHEAD: ::c_int = 0x00000008; +pub const SF_NOCACHE: ::c_int = 0x00000010; +pub const RLIMIT_KQUEUES: ::c_int = 13; +pub const RLIMIT_UMTXP: ::c_int = 14; +pub const EVFILT_PROCDESC: i16 = -8; +pub const EVFILT_SENDFILE: i16 = -12; +pub const EVFILT_EMPTY: i16 = -13; +pub const SO_REUSEPORT_LB: ::c_int = 0x10000; +pub const TCP_CCALGOOPT: ::c_int = 65; +pub const TCP_PCAP_OUT: ::c_int = 2048; +pub const TCP_PCAP_IN: ::c_int = 4096; +pub const IP_BINDMULTI: ::c_int = 25; +pub const IP_ORIGDSTADDR : ::c_int = 27; +pub const IP_RECVORIGDSTADDR : ::c_int = IP_ORIGDSTADDR; +pub const IPV6_ORIGDSTADDR: ::c_int = 72; +pub const IPV6_RECVORIGDSTADDR: ::c_int = IPV6_ORIGDSTADDR; +pub const PD_CLOEXEC: ::c_int = 0x00000002; +pub const PD_ALLOWED_AT_FORK: ::c_int = PD_DAEMON | PD_CLOEXEC; +pub const IP_RSS_LISTEN_BUCKET: ::c_int = 26; + pub const SIGEV_THREAD_ID: ::c_int = 4; pub const EXTATTR_NAMESPACE_EMPTY: ::c_int = 0; @@ -320,8 +340,6 @@ pub const SIGSTKSZ: ::size_t = 34816; pub const SF_NODISKIO: ::c_int = 0x00000001; pub const SF_MNOWAIT: ::c_int = 0x00000002; pub const SF_SYNC: ::c_int = 0x00000004; -pub const SF_USER_READAHEAD: ::c_int = 0x00000008; -pub const SF_NOCACHE: ::c_int = 0x00000010; pub const O_CLOEXEC: ::c_int = 0x00100000; pub const O_DIRECTORY: ::c_int = 0x00020000; pub const O_EXEC: ::c_int = 0x00040000; @@ -335,8 +353,6 @@ pub const ENOTRECOVERABLE: ::c_int = 95; pub const EOWNERDEAD: ::c_int = 96; pub const RLIMIT_NPTS: ::c_int = 11; pub const RLIMIT_SWAP: ::c_int = 12; -pub const RLIMIT_KQUEUES: ::c_int = 13; -pub const RLIMIT_UMTXP: ::c_int = 14; pub const RLIM_NLIMITS: ::rlim_t = 15; pub const Q_GETQUOTA: ::c_int = 0x700; @@ -358,12 +374,9 @@ pub const EVFILT_VNODE: i16 = -4; pub const EVFILT_PROC: i16 = -5; pub const EVFILT_SIGNAL: i16 = -6; pub const EVFILT_TIMER: i16 = -7; -pub const EVFILT_PROCDESC: i16 = -8; pub const EVFILT_FS: i16 = -9; pub const EVFILT_LIO: i16 = -10; pub const EVFILT_USER: i16 = -11; -pub const EVFILT_SENDFILE: i16 = -12; -pub const EVFILT_EMPTY: i16 = -13; pub const EV_ADD: u16 = 0x1; pub const EV_DELETE: u16 = 0x2; @@ -590,7 +603,6 @@ pub const JAIL_SYS_INHERIT: ::c_int = 2; pub const SO_BINTIME: ::c_int = 0x2000; pub const SO_NO_OFFLOAD: ::c_int = 0x4000; pub const SO_NO_DDP: ::c_int = 0x8000; -pub const SO_REUSEPORT_LB: ::c_int = 0x10000; pub const SO_LABEL: ::c_int = 0x1009; pub const SO_PEERLABEL: ::c_int = 0x1010; pub const SO_LISTENQLIMIT: ::c_int = 0x1011; @@ -929,23 +941,12 @@ pub const IPPROTO_SEND: ::c_int = 259; pub const TCP_MD5SIG: ::c_int = 16; pub const TCP_INFO: ::c_int = 32; pub const TCP_CONGESTION: ::c_int = 64; -pub const TCP_CCALGOOPT: ::c_int = 65; pub const TCP_KEEPINIT: ::c_int = 128; pub const TCP_FASTOPEN: ::c_int = 1025; -pub const TCP_PCAP_OUT: ::c_int = 2048; -pub const TCP_PCAP_IN: ::c_int = 4096; pub const IP_BINDANY: ::c_int = 24; -pub const IP_BINDMULTI: ::c_int = 25; -pub const IP_RSS_LISTEN_BUCKET: ::c_int = 26; -pub const IP_ORIGDSTADDR : ::c_int = 27; -pub const IP_RECVORIGDSTADDR : ::c_int = IP_ORIGDSTADDR; - pub const IP_RECVTOS: ::c_int = 68; -pub const IPV6_ORIGDSTADDR: ::c_int = 72; -pub const IPV6_RECVORIGDSTADDR: ::c_int = IPV6_ORIGDSTADDR; - pub const PF_SLOW: ::c_int = AF_SLOW; pub const PF_SCLUSTER: ::c_int = AF_SCLUSTER; pub const PF_ARP: ::c_int = AF_ARP; @@ -1068,8 +1069,6 @@ pub const XUCRED_VERSION: ::c_uint = 0; // Flags which can be passed to pdfork(2) pub const PD_DAEMON: ::c_int = 0x00000001; -pub const PD_CLOEXEC: ::c_int = 0x00000002; -pub const PD_ALLOWED_AT_FORK: ::c_int = PD_DAEMON | PD_CLOEXEC; // Values for struct rtprio (type_ field) pub const RTP_PRIO_REALTIME: ::c_ushort = 2; @@ -1136,6 +1135,11 @@ f! { } extern { + pub fn fdatasync(fd: ::c_int) -> ::c_int; + pub fn aio_waitcomplete(iocbp: *mut *mut aiocb, + timeout: *mut ::timespec) -> ::ssize_t; + pub fn mq_getfd_np(mqd: ::mqd_t) -> ::c_int; + pub fn __error() -> *mut ::c_int; pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; @@ -1202,7 +1206,6 @@ extern { pub fn jail_set(iov: *mut ::iovec, niov: ::c_uint, flags: ::c_int) -> ::c_int; - pub fn fdatasync(fd: ::c_int) -> ::c_int; pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, @@ -1215,10 +1218,6 @@ extern { pub fn getutxuser(user: *const ::c_char) -> *mut utmpx; pub fn setutxdb(_type: ::c_int, file: *const ::c_char) -> ::c_int; - pub fn aio_waitcomplete(iocbp: *mut *mut aiocb, - timeout: *mut ::timespec) -> ::ssize_t; - pub fn mq_getfd_np(mqd: ::mqd_t) -> ::c_int; - pub fn waitid(idtype: idtype_t, id: ::id_t, infop: *mut ::siginfo_t, options: ::c_int) -> ::c_int; @@ -1318,8 +1317,10 @@ extern { pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int; pub fn __xuname(nmln: ::c_int, buf: *mut ::c_void) -> ::c_int; + #[cfg(not(freebsd10))] pub fn sendmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::size_t, flags: ::c_int) -> ::ssize_t; + #[cfg(not(freebsd10))] pub fn recvmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::size_t, flags: ::c_int, timeout: *const ::timespec) -> ::ssize_t; } @@ -1339,7 +1340,7 @@ cfg_if! { } else if #[cfg(freebsd13)] { mod freebsd12; pub use self::freebsd12::*; - } else if #[cfg(freebsd11)] { + } else if #[cfg(any(freebsd10, freebsd11))] { mod freebsd11; pub use self::freebsd11::*; } else { diff --git a/src/unix/bsd/freebsdlike/mod.rs b/src/unix/bsd/freebsdlike/mod.rs index 2561e2504e630..8db13a974c6c3 100644 --- a/src/unix/bsd/freebsdlike/mod.rs +++ b/src/unix/bsd/freebsdlike/mod.rs @@ -1162,7 +1162,7 @@ extern { pub fn getutxline(ut: *const utmpx) -> *mut utmpx; pub fn initgroups(name: *const ::c_char, basegid: ::gid_t) -> ::c_int; #[cfg_attr( - all(target_os = "freebsd", freebsd11), + all(target_os = "freebsd", any(freebsd11, freebsd10)), link_name = "kevent@FBSD_1.0" )] pub fn kevent(kq: ::c_int, @@ -1181,7 +1181,7 @@ extern { pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; #[cfg_attr( - all(target_os = "freebsd", freebsd11), + all(target_os = "freebsd", any(freebsd11, freebsd10)), link_name = "mknodat@FBSD_1.1" )] pub fn mknodat(dirfd: ::c_int, pathname: *const ::c_char, diff --git a/src/unix/bsd/mod.rs b/src/unix/bsd/mod.rs index 40b18c638dafa..e1abd5840cf43 100644 --- a/src/unix/bsd/mod.rs +++ b/src/unix/bsd/mod.rs @@ -550,7 +550,7 @@ extern { #[cfg_attr(target_os = "macos", link_name = "glob$INODE64")] #[cfg_attr(target_os = "netbsd", link_name = "__glob30")] #[cfg_attr( - all(target_os = "freebsd", freebsd11), + all(target_os = "freebsd", any(freebsd11, freebsd10)), link_name = "glob@FBSD_1.0" )] pub fn glob(pattern: *const ::c_char, @@ -560,7 +560,7 @@ extern { pglob: *mut ::glob_t) -> ::c_int; #[cfg_attr(target_os = "netbsd", link_name = "__globfree30")] #[cfg_attr( - all(target_os = "freebsd", freebsd11), + all(target_os = "freebsd", any(freebsd11, freebsd10)), link_name = "globfree@FBSD_1.0" )] pub fn globfree(pglob: *mut ::glob_t); diff --git a/src/unix/mod.rs b/src/unix/mod.rs index 721d241164a1d..ee15cdf8767e9 100644 --- a/src/unix/mod.rs +++ b/src/unix/mod.rs @@ -567,7 +567,7 @@ extern { #[cfg_attr(target_os = "macos", link_name = "fstat$INODE64")] #[cfg_attr(target_os = "netbsd", link_name = "__fstat50")] #[cfg_attr( - all(target_os = "freebsd", freebsd11), + all(target_os = "freebsd", any(freebsd11, freebsd10)), link_name = "fstat@FBSD_1.0" )] pub fn fstat(fildes: ::c_int, buf: *mut stat) -> ::c_int; @@ -577,7 +577,7 @@ extern { #[cfg_attr(target_os = "macos", link_name = "stat$INODE64")] #[cfg_attr(target_os = "netbsd", link_name = "__stat50")] #[cfg_attr( - all(target_os = "freebsd", freebsd11), + all(target_os = "freebsd", any(freebsd11, freebsd10)), link_name = "stat@FBSD_1.0" )] pub fn stat(path: *const c_char, buf: *mut stat) -> ::c_int; @@ -608,7 +608,7 @@ extern { #[cfg_attr(target_os = "macos", link_name = "readdir$INODE64")] #[cfg_attr(target_os = "netbsd", link_name = "__readdir30")] #[cfg_attr( - all(target_os = "freebsd", freebsd11), + all(target_os = "freebsd", any(freebsd11, freebsd10)), link_name = "readdir@FBSD_1.0" )] pub fn readdir(dirp: *mut ::DIR) -> *mut ::dirent; @@ -631,7 +631,7 @@ extern { flags: ::c_int) -> ::c_int; #[cfg_attr(target_os = "macos", link_name = "fstatat$INODE64")] #[cfg_attr( - all(target_os = "freebsd", freebsd11), + all(target_os = "freebsd", any(freebsd11, freebsd10)), link_name = "fstatat@FBSD_1.1" )] pub fn fstatat(dirfd: ::c_int, pathname: *const ::c_char, @@ -786,7 +786,7 @@ extern { #[cfg_attr(target_os = "macos", link_name = "lstat$INODE64")] #[cfg_attr(target_os = "netbsd", link_name = "__lstat50")] #[cfg_attr( - all(target_os = "freebsd", freebsd11), + all(target_os = "freebsd", any(freebsd11, freebsd10)), link_name = "lstat@FBSD_1.0" )] pub fn lstat(path: *const c_char, buf: *mut stat) -> ::c_int; @@ -962,7 +962,7 @@ extern { #[cfg_attr(target_os = "netbsd", link_name = "__mknod50")] #[cfg_attr( - all(target_os = "freebsd", freebsd11), + all(target_os = "freebsd", any(freebsd11, freebsd10)), link_name = "mknod@FBSD_1.0" )] pub fn mknod(pathname: *const ::c_char, mode: ::mode_t, @@ -1126,7 +1126,7 @@ cfg_if! { #[cfg_attr(target_os = "macos", link_name = "readdir_r$INODE64")] #[cfg_attr(target_os = "netbsd", link_name = "__readdir_r30")] #[cfg_attr( - all(target_os = "freebsd", freebsd11), + all(target_os = "freebsd", any(freebsd11, freebsd10)), link_name = "readdir_r@FBSD_1.0" )] /// The 64-bit libc on Solaris and illumos only has readdir_r. If a