From 1a3d1525da37e295f659424258df4566a1755abf Mon Sep 17 00:00:00 2001
From: gnzlbg <gonzalobg88@gmail.com>
Date: Mon, 27 May 2019 17:31:32 +0200
Subject: [PATCH] [breaking change] sendmmsg/recvmmsg flag argument is an
 unsigned integer on MUSL

---
 ci/docker/mips-unknown-linux-musl/Dockerfile |  10 +-
 libc-test/build.rs                           | 129 +++++++++----------
 libc-test/test/linux_elf.rs                  |   2 +-
 libc-test/test/linux_fcntl.rs                |   2 +-
 libc-test/test/linux_ipv6.rs                 |   2 +-
 libc-test/test/linux_strerror_r.rs           |   2 +-
 libc-test/test/linux_termios.rs              |   2 +-
 src/unix/notbsd/linux/mips/mod.rs            |   5 +
 src/unix/notbsd/linux/mod.rs                 |   4 -
 src/unix/notbsd/linux/musl/b32/mips.rs       |   2 +-
 src/unix/notbsd/linux/musl/mod.rs            |   5 +
 src/unix/notbsd/linux/other/mod.rs           |   5 +
 src/unix/notbsd/linux/s390x/mod.rs           |   5 +
 13 files changed, 95 insertions(+), 80 deletions(-)

diff --git a/ci/docker/mips-unknown-linux-musl/Dockerfile b/ci/docker/mips-unknown-linux-musl/Dockerfile
index fe2ea85c..aee73bea 100644
--- a/ci/docker/mips-unknown-linux-musl/Dockerfile
+++ b/ci/docker/mips-unknown-linux-musl/Dockerfile
@@ -7,11 +7,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
 RUN mkdir /toolchain
 
 # Note that this originally came from:
-# https://downloads.openwrt.org/snapshots/targets/ar71xx/generic/openwrt-sdk-ar71xx-generic_gcc-7.4.0_musl.Linux-x86_64.tar.xz
-RUN curl --retry 5 -L https://downloads.openwrt.org/snapshots/targets/ar71xx/generic/openwrt-sdk-ar71xx-generic_gcc-7.4.0_musl.Linux-x86_64.tar.xz | \
-      tar xf -J - -C /toolchain --strip-components=1
+# https://downloads.openwrt.org/snapshots/trunk/ar71xx/generic/OpenWrt-SDK-ar71xx-generic_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2
+RUN curl --retry 5 -L https://s3-us-west-1.amazonaws.com/rust-lang-ci2/libc/OpenWrt-SDK-ar71xx-generic_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2 | \
+    tar xjf - -C /toolchain --strip-components=1
 
-ENV PATH=$PATH:/rust/bin:/toolchain/staging_dir/toolchain-mips_34kc_gcc-7.4.0_musl.Linux-x86_64/bin \
+ENV PATH=$PATH:/rust/bin:/toolchain/staging_dir/toolchain-mips_34kc_gcc-5.3.0_musl-1.1.15/bin \
     CC_mips_unknown_linux_musl=mips-openwrt-linux-gcc \
     CARGO_TARGET_MIPS_UNKNOWN_LINUX_MUSL_LINKER=mips-openwrt-linux-gcc \
-    CARGO_TARGET_MIPS_UNKNOWN_LINUX_MUSL_RUNNER="qemu-mips -L /toolchain/staging_dir/toolchain-mips_34kc_gcc-7.4.0_musl.Linux-x86_64"
+    CARGO_TARGET_MIPS_UNKNOWN_LINUX_MUSL_RUNNER="qemu-mips -L /toolchain/staging_dir/toolchain-mips_34kc_gcc-5.3.0_musl-1.1.15"
diff --git a/libc-test/build.rs b/libc-test/build.rs
index a0dcd8ce..bf6529d6 100644
--- a/libc-test/build.rs
+++ b/libc-test/build.rs
@@ -37,14 +37,22 @@ fn main() {
 }
 
 macro_rules! headers {
-    ($cfg:ident: $header:expr) => {
+    ($cfg:ident: [$m:expr]: $header:literal) => {
+        if $m {
+            $cfg.header($header);
+        }
+    };
+    ($cfg:ident: $header:literal) => {
         $cfg.header($header);
     };
-    ($cfg:ident: $($header:expr),*) => {
-        $(headers!($cfg: $header);)*
+    ($($cfg:ident: $([$c:expr]:)* $header:literal,)*) => {
+        $(headers!($cfg: $([$c]:)* $header);)*
+    };
+    ($cfg:ident: $( $([$c:expr]:)* $header:literal,)*) => {
+        headers!($($cfg: $([$c]:)* $header,)*);
     };
-    ($cfg:ident: $($header:expr,)*) => {
-        $(headers!($cfg: $header);)*
+    ($cfg:ident: $( $([$c:expr]:)* $header:literal),*) => {
+        headers!($($cfg: $([$c]:)* $header,)*);
     };
 }
 
@@ -135,10 +143,7 @@ fn test_apple(target: &str) {
         "utmpx.h",
         "wchar.h",
         "xlocale.h",
-    }
-
-    if x86_64 {
-        headers! { cfg: "crt_externs.h" }
+        [x86_64]: "crt_externs.h",
     }
 
     cfg.skip_struct(move |ty| {
@@ -386,12 +391,8 @@ fn test_windows(target: &str) {
         "sys/utime.h",
         "time.h",
         "wchar.h",
-    }
-
-    if gnu {
-        headers! { cfg: "ws2tcpip.h" }
-    } else {
-        headers! { cfg: "Winsock2.h" };
+        [gnu]: "ws2tcpip.h",
+        [!gnu]: "Winsock2.h",
     }
 
     cfg.type_name(move |ty, is_struct, is_union| {
@@ -1304,16 +1305,10 @@ fn test_android(target: &str) {
                "utmp.h",
                "wchar.h",
                "xlocale.h",
-    }
-
-    if target_pointer_width == 32 {
-        // time64_t is not defined for 64-bit targets If included it will
-        // generate the error 'Your time_t is already 64-bit'
-        cfg.header("time64.h");
-    }
-
-    if x86 {
-        cfg.header("sys/reg.h");
+               // time64_t is not defined for 64-bit targets If included it will
+               // generate the error 'Your time_t is already 64-bit'
+               [target_pointer_width == 32]: "time64.h",
+               [x86]: "sys/reg.h",
     }
 
     cfg.type_name(move |ty, is_struct, is_union| {
@@ -2000,7 +1995,7 @@ fn test_linux(target: &str) {
     let x86_32 = target.contains("i686");
     let x32 = target.contains("x32");
     let mips = target.contains("mips");
-    let mips32 = mips && !target.contains("64");
+    let mips32_musl = mips && !target.contains("64") && musl;
 
     let mut cfg = ctest::TestGenerator::new();
     cfg.define("_GNU_SOURCE", None);
@@ -2064,7 +2059,8 @@ fn test_linux(target: &str) {
                "sys/prctl.h",
                "sys/ptrace.h",
                "sys/quota.h",
-               "sys/random.h",
+               // FIXME: the mips-musl CI build jobs use ancient musl 1.0.15:
+               [!mips32_musl]: "sys/random.h",
                "sys/reboot.h",
                "sys/resource.h",
                "sys/sem.h",
@@ -2096,29 +2092,17 @@ fn test_linux(target: &str) {
                "utmpx.h",
                "wchar.h",
                "errno.h",
-    }
-
-    // `sys/io.h` is only available on x86*, Alpha, IA64, and 32-bit ARM:
-    // https://bugzilla.redhat.com/show_bug.cgi?id=1116162
-    if x86_64 || x86_32 || arm {
-        headers! { cfg: "sys/io.h" }
-    }
-
-    // `sys/reg.h` is only available on x86 and x86_64
-    if x86_64 || x86_32 {
-        headers! { cfg: "sys/reg.h" }
-    }
-
-    // sysctl system call is deprecated and not available on musl
-    // It is also unsupported in x32:
-    if !(x32 || musl) {
-        headers! { cfg:  "sys/sysctl.h"}
-    }
-
-    // <execinfo.h> is not supported by musl:
-    // https://www.openwall.com/lists/musl/2015/04/09/3
-    if !musl {
-        headers! { cfg: "execinfo.h" }
+               // `sys/io.h` is only available on x86*, Alpha, IA64, and 32-bit
+               // ARM: https://bugzilla.redhat.com/show_bug.cgi?id=1116162
+               [x86_64 || x86_32 || arm]: "sys/io.h",
+               // `sys/reg.h` is only available on x86 and x86_64
+               [x86_64 || x86_32]: "sys/reg.h",
+               // sysctl system call is deprecated and not available on musl
+               // It is also unsupported in x32:
+               [!(x32 || musl)]: "sys/sysctl.h",
+               // <execinfo.h> is not supported by musl:
+               // https://www.openwall.com/lists/musl/2015/04/09/3
+               [!musl]: "execinfo.h",
     }
 
     // Include linux headers at the end:
@@ -2130,7 +2114,8 @@ fn test_linux(target: &str) {
         "linux/fs.h",
         "linux/futex.h",
         "linux/genetlink.h",
-        "linux/if.h",
+        // FIXME: musl version 1.0.15 used by mips build jobs is ancient
+        [!mips32_musl]: "linux/if.h",
         "linux/if_addr.h",
         "linux/if_alg.h",
         "linux/if_ether.h",
@@ -2154,10 +2139,11 @@ fn test_linux(target: &str) {
     }
 
     // note: aio.h must be included before sys/mount.h
-    headers! { cfg:
-               "sys/xattr.h",
-               "sys/sysinfo.h",
-               "aio.h",
+    headers! {
+        cfg:
+        "sys/xattr.h",
+        "sys/sysinfo.h",
+        "aio.h",
     }
 
     cfg.type_name(move |ty, is_struct, is_union| {
@@ -2243,17 +2229,15 @@ fn test_linux(target: &str) {
             // structs.
             "termios2" => true,
 
+            // FIXME: musl version using by mips build jobs 1.0.15 is ancient:
+            "ifmap" | "ifreq" | "ifconf" if mips32_musl => true,
+
             _ => false,
         }
     });
 
     cfg.skip_const(move |name| {
         match name {
-            // These are not available in the MUSL version used by the
-            // 32-bit mips build jobs:
-            | "AF_XDP"
-            | "PF_XDP" if musl && mips32 => true,
-
             // These constants are not available if gnu headers have been included
             // and can therefore not be tested here
             //
@@ -2281,7 +2265,7 @@ fn test_linux(target: &str) {
             //
             // Require Linux kernel 5.x:
             | "MSG_COPY"
-                => true,
+               if musl  => true,
 
             // The musl version 1.0.22 used in CI does not
             // contain these glibc constants yet:
@@ -2304,6 +2288,11 @@ fn test_linux(target: &str) {
             // FIXME: on musl the pthread types are defined a little differently
             // - these constants are used by the glibc implementation.
             n if musl && n.contains("__SIZEOF_PTHREAD") => true,
+
+            // FIXME: musl version 1.0.15 used by mips build jobs is ancient
+            t if mips32_musl && t.starts_with("IFF") => true,
+            "MFD_HUGETLB" | "AF_XDP" | "PF_XDP" if mips32_musl => true,
+
             _ => false,
         }
     });
@@ -2320,7 +2309,8 @@ fn test_linux(target: &str) {
             //
             // An XSI-compliant version provided if:
             //
-            // (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
+            // (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
+            //  && ! _GNU_SOURCE
             //
             // and a GNU specific version provided if _GNU_SOURCE is defined.
             //
@@ -2341,7 +2331,6 @@ fn test_linux(target: &str) {
         }
     });
 
-    // FIXME: is this necessary?
     cfg.skip_field_type(move |struct_, field| {
         // This is a weird union, don't check the type.
         (struct_ == "ifaddrs" && field == "ifa_ifu") ||
@@ -2351,12 +2340,22 @@ fn test_linux(target: &str) {
         (struct_ == "utmpx" && field == "ut_tv") ||
         // 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
-        (struct_ == "aiocb" && field == "aio_buf") ||
         // this one is an anonymous union
         (struct_ == "ff_effect" && field == "u")
     });
 
+    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.
diff --git a/libc-test/test/linux_elf.rs b/libc-test/test/linux_elf.rs
index e9e45da9..8744200e 100644
--- a/libc-test/test/linux_elf.rs
+++ b/libc-test/test/linux_elf.rs
@@ -7,4 +7,4 @@ use libc::*;
 include!(concat!(env!("OUT_DIR"), "/linux_elf.rs"));
 
 #[cfg(not(target_os = "linux"))]
-fn main() {}
+fn main() { println!("PASSED 0 tests"); }
diff --git a/libc-test/test/linux_fcntl.rs b/libc-test/test/linux_fcntl.rs
index a54636c6..915a87dc 100644
--- a/libc-test/test/linux_fcntl.rs
+++ b/libc-test/test/linux_fcntl.rs
@@ -7,4 +7,4 @@ use libc::*;
 include!(concat!(env!("OUT_DIR"), "/linux_fcntl.rs"));
 
 #[cfg(not(any(target_os = "linux", target_os = "android")))]
-fn main() {}
+fn main() { println!("PASSED 0 tests"); }
diff --git a/libc-test/test/linux_ipv6.rs b/libc-test/test/linux_ipv6.rs
index 2c0adb28..c4d0965a 100644
--- a/libc-test/test/linux_ipv6.rs
+++ b/libc-test/test/linux_ipv6.rs
@@ -7,4 +7,4 @@ use libc::*;
 include!(concat!(env!("OUT_DIR"), "/linux_ipv6.rs"));
 
 #[cfg(not(target_os = "linux"))]
-fn main() {}
+fn main() { println!("PASSED 0 tests"); }
diff --git a/libc-test/test/linux_strerror_r.rs b/libc-test/test/linux_strerror_r.rs
index c05b7949..5139175f 100644
--- a/libc-test/test/linux_strerror_r.rs
+++ b/libc-test/test/linux_strerror_r.rs
@@ -7,4 +7,4 @@ use libc::*;
 include!(concat!(env!("OUT_DIR"), "/linux_strerror_r.rs"));
 
 #[cfg(not(any(target_os = "linux", target_os = "android")))]
-fn main() {}
+fn main() { println!("PASSED 0 tests"); }
diff --git a/libc-test/test/linux_termios.rs b/libc-test/test/linux_termios.rs
index d765f336..9ee47631 100644
--- a/libc-test/test/linux_termios.rs
+++ b/libc-test/test/linux_termios.rs
@@ -7,4 +7,4 @@ use libc::*;
 include!(concat!(env!("OUT_DIR"), "/linux_termios.rs"));
 
 #[cfg(not(any(target_os = "linux", target_os = "android")))]
-fn main() {}
+fn main() { println!("PASSED 0 tests"); }
diff --git a/src/unix/notbsd/linux/mips/mod.rs b/src/unix/notbsd/linux/mips/mod.rs
index b1ebd15d..083572a2 100644
--- a/src/unix/notbsd/linux/mips/mod.rs
+++ b/src/unix/notbsd/linux/mips/mod.rs
@@ -907,6 +907,11 @@ f! {
 
 #[link(name = "util")]
 extern {
+    pub fn sendmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::c_uint,
+                    flags: ::c_int) -> ::c_int;
+    pub fn recvmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::c_uint,
+                    flags: ::c_int, timeout: *mut ::timespec) -> ::c_int;
+
     pub fn getrlimit64(resource: ::__rlimit_resource_t,
                        rlim: *mut ::rlimit64) -> ::c_int;
     pub fn setrlimit64(resource: ::__rlimit_resource_t,
diff --git a/src/unix/notbsd/linux/mod.rs b/src/unix/notbsd/linux/mod.rs
index 116930f3..59da339a 100644
--- a/src/unix/notbsd/linux/mod.rs
+++ b/src/unix/notbsd/linux/mod.rs
@@ -2326,10 +2326,6 @@ extern {
     pub fn getdomainname(name: *mut ::c_char, len: ::size_t) -> ::c_int;
     pub fn setdomainname(name: *const ::c_char, len: ::size_t) -> ::c_int;
     pub fn vhangup() -> ::c_int;
-    pub fn sendmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::c_uint,
-                    flags: ::c_int) -> ::c_int;
-    pub fn recvmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::c_uint,
-                    flags: ::c_int, timeout: *mut ::timespec) -> ::c_int;
     pub fn sync();
     pub fn syscall(num: ::c_long, ...) -> ::c_long;
     pub fn sched_getaffinity(pid: ::pid_t,
diff --git a/src/unix/notbsd/linux/musl/b32/mips.rs b/src/unix/notbsd/linux/musl/b32/mips.rs
index 37430af5..514c480e 100644
--- a/src/unix/notbsd/linux/musl/b32/mips.rs
+++ b/src/unix/notbsd/linux/musl/b32/mips.rs
@@ -191,7 +191,7 @@ pub const RLIMIT_NOFILE: ::c_int = 5;
 pub const RLIMIT_AS: ::c_int = 6;
 pub const RLIMIT_NPROC: ::c_int = 8;
 pub const RLIMIT_MEMLOCK: ::c_int = 9;
-pub const RLIMIT_NLIMITS: ::c_int = 16;
+pub const RLIMIT_NLIMITS: ::c_int = 15;
 
 pub const MCL_CURRENT: ::c_int = 0x0001;
 pub const MCL_FUTURE: ::c_int = 0x0002;
diff --git a/src/unix/notbsd/linux/musl/mod.rs b/src/unix/notbsd/linux/musl/mod.rs
index 37e4bd61..62eff604 100644
--- a/src/unix/notbsd/linux/musl/mod.rs
+++ b/src/unix/notbsd/linux/musl/mod.rs
@@ -332,6 +332,11 @@ pub const SO_PEEK_OFF: ::c_int = 42;
 pub const SO_BUSY_POLL: ::c_int = 46;
 
 extern {
+    pub fn sendmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::c_uint,
+                    flags: ::c_uint) -> ::c_int;
+    pub fn recvmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::c_uint,
+                    flags: ::c_uint, timeout: *mut ::timespec) -> ::c_int;
+
     pub fn getrlimit64(resource: ::c_int,
                        rlim: *mut ::rlimit64) -> ::c_int;
     pub fn setrlimit64(resource: ::c_int,
diff --git a/src/unix/notbsd/linux/other/mod.rs b/src/unix/notbsd/linux/other/mod.rs
index e33455df..26c9ad4c 100644
--- a/src/unix/notbsd/linux/other/mod.rs
+++ b/src/unix/notbsd/linux/other/mod.rs
@@ -950,6 +950,11 @@ f! {
 }
 
 extern {
+    pub fn sendmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::c_uint,
+                    flags: ::c_int) -> ::c_int;
+    pub fn recvmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::c_uint,
+                    flags: ::c_int, timeout: *mut ::timespec) -> ::c_int;
+
     pub fn getrlimit64(resource: ::__rlimit_resource_t,
                        rlim: *mut ::rlimit64) -> ::c_int;
     pub fn setrlimit64(resource: ::__rlimit_resource_t,
diff --git a/src/unix/notbsd/linux/s390x/mod.rs b/src/unix/notbsd/linux/s390x/mod.rs
index af4a3466..132e89f7 100644
--- a/src/unix/notbsd/linux/s390x/mod.rs
+++ b/src/unix/notbsd/linux/s390x/mod.rs
@@ -1317,6 +1317,11 @@ pub const SYS_newfstatat: ::c_long = 293;
 
 #[link(name = "util")]
 extern {
+    pub fn sendmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::c_uint,
+                    flags: ::c_int) -> ::c_int;
+    pub fn recvmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::c_uint,
+                    flags: ::c_int, timeout: *mut ::timespec) -> ::c_int;
+
     pub fn getrlimit64(resource: ::__rlimit_resource_t,
                        rlim: *mut ::rlimit64) -> ::c_int;
     pub fn setrlimit64(resource: ::__rlimit_resource_t,
-- 
GitLab