diff --git a/.travis.yml b/.travis.yml
index 3c6cc9429eaf483b256f705ea4bf0341c54585ec..d5ba4dac6ba2fa6acc3744a3557fc72abdeb91f4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,7 +22,8 @@ matrix:
       install: true
       script:
         - shellcheck --version
-        - shellcheck ci/*.sh
+        # FIXME: https://github.com/koalaman/shellcheck/issues/1591
+        - shellcheck -e SC2103 ci/*.sh
       stage: tools-and-build-and-tier1
     - name: "Style"
       install: true
diff --git a/ci/docker/aarch64-unknown-linux-musl/Dockerfile b/ci/docker/aarch64-unknown-linux-musl/Dockerfile
index ea73657429b069c156485d799690a9fca91f0316..e9634bf3741db26399a70cec1616033d4aceb040 100644
--- a/ci/docker/aarch64-unknown-linux-musl/Dockerfile
+++ b/ci/docker/aarch64-unknown-linux-musl/Dockerfile
@@ -3,21 +3,9 @@ FROM ubuntu:19.04
 RUN apt-get update && apt-get install -y --no-install-recommends \
   gcc make libc6-dev git curl ca-certificates \
   gcc-aarch64-linux-gnu qemu-user
-RUN curl --retry 5 https://www.musl-libc.org/releases/musl-1.1.22.tar.gz | \
-    tar xzf - && \
-    cd musl-1.1.22 && \
-    CC=aarch64-linux-gnu-gcc \
-    ./configure --prefix=/musl-aarch64 --enable-wrapper=yes && \
-    make install -j4 && \
-    cd .. && \
-    rm -rf musl-1.1.22
-# Install linux kernel headers sanitized for use with musl
-RUN curl --retry 5 -L https://github.com/sabotage-linux/kernel-headers/archive/v3.12.6-6.tar.gz | \
-    tar xzf - && \
-    cd kernel-headers-3.12.6-6 && \
-    make ARCH=arm64 prefix=/musl-aarch64 install -j4 && \
-    cd .. && \
-    rm -rf kernel-headers-3.12.6-6
+
+COPY install-musl.sh /
+RUN sh /install-musl.sh aarch64
 
 # FIXME: shouldn't need the `-lgcc` here, shouldn't that be in libstd?
 ENV PATH=$PATH:/musl-aarch64/bin:/rust/bin \
diff --git a/ci/docker/arm-unknown-linux-musleabihf/Dockerfile b/ci/docker/arm-unknown-linux-musleabihf/Dockerfile
index b001fd2c36da1fedab134beeb8c1f218b30a4866..639b141d4b3d38a4f86e61fe3a68aa05e911918e 100644
--- a/ci/docker/arm-unknown-linux-musleabihf/Dockerfile
+++ b/ci/docker/arm-unknown-linux-musleabihf/Dockerfile
@@ -4,20 +4,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   gcc make libc6-dev git curl ca-certificates \
   gcc-arm-linux-gnueabihf qemu-user
 
-RUN curl --retry 5 https://www.musl-libc.org/releases/musl-1.1.22.tar.gz | tar xzf -
-WORKDIR /musl-1.1.22
-RUN CC=arm-linux-gnueabihf-gcc \
-    CFLAGS="-march=armv6 -marm -mfpu=vfp" \
-    ./configure --prefix=/musl-arm --enable-wrapper=yes
-RUN make install -j4
-
-# Install linux kernel headers sanitized for use with musl
-RUN curl --retry 5 -L https://github.com/sabotage-linux/kernel-headers/archive/v3.12.6-6.tar.gz | \
-    tar xzf - && \
-    cd kernel-headers-3.12.6-6 && \
-    make ARCH=arm prefix=/musl-arm install -j4 && \
-    cd .. && \
-    rm -rf kernel-headers-3.12.6-6
+COPY install-musl.sh /
+RUN sh /install-musl.sh arm
 
 ENV PATH=$PATH:/musl-arm/bin:/rust/bin \
     CC_arm_unknown_linux_musleabihf=musl-gcc \
diff --git a/ci/docker/i686-unknown-linux-musl/Dockerfile b/ci/docker/i686-unknown-linux-musl/Dockerfile
index 9dd44e08369ac4dfa4617db6624291f4237db7e9..ac76a3269a5467ef680801cdf30495b4abc9d41f 100644
--- a/ci/docker/i686-unknown-linux-musl/Dockerfile
+++ b/ci/docker/i686-unknown-linux-musl/Dockerfile
@@ -4,28 +4,9 @@ RUN dpkg --add-architecture i386
 RUN apt-get update
 RUN apt-get install -y --no-install-recommends \
   gcc-multilib make libc6-dev git curl ca-certificates libc6:i386
-# Below we're cross-compiling musl for i686 using the system compiler on an
-# x86_64 system. This is an awkward thing to be doing and so we have to jump
-# through a couple hoops to get musl to be happy. In particular:
-#
-# * We specifically pass -m32 in CFLAGS and override CC when running ./configure,
-#   since otherwise the script will fail to find a compiler.
-# * We manually unset CROSS_COMPILE when running make; otherwise the makefile
-#   will call the non-existent binary 'i686-ar'.
-RUN curl --retry 5 https://www.musl-libc.org/releases/musl-1.1.22.tar.gz | \
-    tar xzf - && \
-    cd musl-1.1.22 && \
-    CC=gcc CFLAGS=-m32 ./configure --prefix=/musl-i686 --disable-shared --target=i686 && \
-    make CROSS_COMPILE= install -j4 && \
-    cd .. && \
-    rm -rf musl-1.1.22
-# Install linux kernel headers sanitized for use with musl
-RUN curl --retry 5 -L https://github.com/sabotage-linux/kernel-headers/archive/v3.12.6-6.tar.gz | \
-    tar xzf - && \
-    cd kernel-headers-3.12.6-6 && \
-    make ARCH=i386 prefix=/musl-i686 install -j4 && \
-    cd .. && \
-    rm -rf kernel-headers-3.12.6-6
+
+COPY install-musl.sh /
+RUN sh /install-musl.sh i686
 
 ENV PATH=$PATH:/musl-i686/bin:/rust/bin \
     CC_i686_unknown_linux_musl=musl-gcc
diff --git a/ci/docker/mips-unknown-linux-gnu/Dockerfile b/ci/docker/mips-unknown-linux-gnu/Dockerfile
index 9f1bcaf7a34d649c2f13eba8ab9e80bae8254143..c8623a56bb3a8b06ebd066d5b296ae2ee5c1284c 100644
--- a/ci/docker/mips-unknown-linux-gnu/Dockerfile
+++ b/ci/docker/mips-unknown-linux-gnu/Dockerfile
@@ -3,7 +3,7 @@ FROM ubuntu:19.04
 RUN apt-get update && apt-get install -y --no-install-recommends \
         gcc libc6-dev qemu-user ca-certificates \
         gcc-mips-linux-gnu libc6-dev-mips-cross \
-        qemu-system-mips
+        qemu-system-mips linux-headers-generic
 
 ENV CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_LINKER=mips-linux-gnu-gcc \
     CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_RUNNER="qemu-mips -L /usr/mips-linux-gnu" \
diff --git a/ci/docker/mips-unknown-linux-musl/Dockerfile b/ci/docker/mips-unknown-linux-musl/Dockerfile
index 7f2764cf78217d3dac034154cd7d50a1c2428007..23aecd17693043158cec9146de94bbe8e783d7ce 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/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
+# 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 - -C /toolchain --strip-components=1
 
-ENV PATH=$PATH:/rust/bin:/toolchain/staging_dir/toolchain-mips_34kc_gcc-5.3.0_musl-1.1.15/bin \
+ENV PATH=$PATH:/rust/bin:/toolchain/staging_dir/toolchain-mips_34kc_gcc-7.4.0_musl.Linux-x86_64/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-5.3.0_musl-1.1.15"
+    CARGO_TARGET_MIPS_UNKNOWN_LINUX_MUSL_RUNNER="qemu-mips -L /toolchain/staging_dir/toolchain-mips_34kc_gcc-7.4.0_musl.Linux-x86_64"
diff --git a/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile b/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile
index b97cdb4ce47e71f57bd21167e2725ad95148fcd1..d4b972d3ef28e6b76b6c280506a160cc5cb17a66 100644
--- a/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile
+++ b/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile
@@ -3,7 +3,7 @@ FROM ubuntu:19.04
 RUN apt-get update && apt-get install -y --no-install-recommends \
         gcc libc6-dev qemu-user ca-certificates \
         gcc-mips64-linux-gnuabi64 libc6-dev-mips64-cross \
-        qemu-system-mips64
+        qemu-system-mips64 linux-headers-generic
 
 ENV CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_LINKER=mips64-linux-gnuabi64-gcc \
     CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_RUNNER="qemu-mips64 -L /usr/mips64-linux-gnuabi64" \
diff --git a/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile b/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile
index 7f794525d9197295e9b3d37428e67991d7d0ee29..d0303dadcb261a940da153a10a23675f28626c8e 100644
--- a/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile
+++ b/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile
@@ -3,7 +3,7 @@ FROM ubuntu:19.04
 RUN apt-get update && apt-get install -y --no-install-recommends \
         gcc libc6-dev qemu-user ca-certificates \
         gcc-mips64el-linux-gnuabi64 libc6-dev-mips64el-cross \
-        qemu-system-mips64el
+        qemu-system-mips64el linux-headers-generic
 
 ENV CARGO_TARGET_MIPS64EL_UNKNOWN_LINUX_GNUABI64_LINKER=mips64el-linux-gnuabi64-gcc \
     CARGO_TARGET_MIPS64EL_UNKNOWN_LINUX_GNUABI64_RUNNER="qemu-mips64el -L /usr/mips64el-linux-gnuabi64" \
diff --git a/ci/docker/x86_64-unknown-linux-gnu/Dockerfile b/ci/docker/x86_64-unknown-linux-gnu/Dockerfile
index 0dbb191fbd9404e74a57b64ebd1a443c4144724f..bfa2b170adea0585e5ef3066d8eefe60360375cf 100644
--- a/ci/docker/x86_64-unknown-linux-gnu/Dockerfile
+++ b/ci/docker/x86_64-unknown-linux-gnu/Dockerfile
@@ -1,5 +1,9 @@
 FROM ubuntu:19.04
 RUN apt-get update
 RUN apt-get install -y --no-install-recommends \
-  gcc libc6-dev ca-certificates
+  gcc libc6-dev ca-certificates linux-headers-generic
+
+RUN apt search linux-headers
+RUN ls /usr/src
+
 ENV PATH=$PATH:/rust/bin
diff --git a/ci/docker/x86_64-unknown-linux-musl/Dockerfile b/ci/docker/x86_64-unknown-linux-musl/Dockerfile
index e99764fdf7ef719b3d752f94279d0d204bf69f07..06a081b751a6ba2b4f2d0bbcbdee60301f0e8b3b 100644
--- a/ci/docker/x86_64-unknown-linux-musl/Dockerfile
+++ b/ci/docker/x86_64-unknown-linux-musl/Dockerfile
@@ -3,18 +3,8 @@ FROM ubuntu:19.04
 RUN apt-get update
 RUN apt-get install -y --no-install-recommends \
   gcc make libc6-dev git curl ca-certificates
-RUN curl --retry 5 https://www.musl-libc.org/releases/musl-1.1.22.tar.gz | \
-    tar xzf - && \
-    cd musl-1.1.22 && \
-    ./configure --prefix=/musl-x86_64 && \
-    make install -j4 && \
-    cd .. && \
-    rm -rf musl-1.1.22
-# Install linux kernel headers sanitized for use with musl
-RUN curl --retry 5 -L https://github.com/sabotage-linux/kernel-headers/archive/v3.12.6-6.tar.gz | \
-    tar xzf - && \
-    cd kernel-headers-3.12.6-6 && \
-    make ARCH=x86_64 prefix=/musl-x86_64 install -j4 && \
-    cd .. && \
-    rm -rf kernel-headers-3.12.6-6
+
+COPY install-musl.sh /
+RUN sh /install-musl.sh x86_64
+
 ENV PATH=$PATH:/musl-x86_64/bin:/rust/bin
diff --git a/ci/install-musl.sh b/ci/install-musl.sh
new file mode 100644
index 0000000000000000000000000000000000000000..0a2fc5529b43ab11efe6af8b437c86a0a18689be
--- /dev/null
+++ b/ci/install-musl.sh
@@ -0,0 +1,68 @@
+#!/usr/bin/env sh
+#
+# Install musl and musl-sanitized linux kernel headers
+# to musl-{$1} directory
+
+set -ex
+
+MUSL_VERSION=1.1.22
+MUSL="musl-${MUSL_VERSION}"
+
+# Download, configure, build, and install musl:
+curl --retry 5 https://www.musl-libc.org/releases/${MUSL}.tar.gz | tar xzf -
+
+cd $MUSL
+case ${1} in
+    aarch64)
+        musl_arch=aarch64
+        kernel_arch=arm64
+        CC=aarch64-linux-gnu-gcc \
+          ./configure --prefix="/musl-${musl_arch}" --enable-wrapper=yes
+        make install -j4
+        ;;
+    arm)
+        musl_arch=arm
+        kernel_arch=arm
+        CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv6 -marm -mfpu=vfp" \
+          ./configure --prefix="/musl-${musl_arch}" --enable-wrapper=yes
+        make install -j4
+        ;;
+    i686)
+        # cross-compile musl for i686 using the system compiler on an x86_64
+        # system.
+        musl_arch=i686
+        kernel_arch=i386
+        # Specifically pass -m32 in CFLAGS and override CC when running
+        # ./configure, since otherwise the script will fail to find a compiler.
+        CC=gcc CFLAGS="-m32" \
+          ./configure --prefix="/musl-${musl_arch}" --disable-shared --target=i686
+        # unset CROSS_COMPILE when running make; otherwise the makefile will
+        # call the non-existent binary 'i686-ar'.
+        make CROSS_COMPILE= install -j4
+        ;;
+    x86_64)
+        musl_arch=x86_64
+        kernel_arch=x86_64
+        ./configure --prefix="/musl-${musl_arch}"
+        make install -j4
+        ;;
+    *)
+        echo "Unknown target arch: \"${1}\""
+        exit 1
+        ;;
+esac
+
+
+# shellcheck disable=SC2103
+cd ..
+rm -rf $MUSL
+
+# Download, configure, build, and install musl-sanitized kernel headers:
+curl --retry 5 -L \
+     https://github.com/sabotage-linux/kernel-headers/archive/v4.4.2-1.tar.gz | \
+    tar xzf -
+(
+    cd kernel-headers-4.4.2-1
+    make ARCH="${kernel_arch}" prefix="/musl-${musl_arch}" install -j4
+)
+rm -rf kernel-headers-4.4.2-1
diff --git a/libc-test/Cargo.toml b/libc-test/Cargo.toml
index 0d2eee1a91cb2ca338b184ed896fe1180280a875..8d2d9033308b7fb0ff42b0fec5b81e92877f0791 100644
--- a/libc-test/Cargo.toml
+++ b/libc-test/Cargo.toml
@@ -28,6 +28,26 @@ name = "linux-fcntl"
 path = "test/linux_fcntl.rs"
 harness = false
 
+[[test]]
+name = "linux-ipv6"
+path = "test/linux_ipv6.rs"
+harness = false
+
+[[test]]
+name = "linux-elf"
+path = "test/linux_elf.rs"
+harness = false
+
+[[test]]
+name = "linux-strerror_r"
+path = "test/linux_strerror_r.rs"
+harness = false
+
+[[test]]
+name = "linux-termios"
+path = "test/linux_termios.rs"
+harness = false
+
 [[test]]
 name = "cmsg"
 path = "test/cmsg.rs"
diff --git a/libc-test/build.rs b/libc-test/build.rs
index 61895b51cb3f1087505a507c5c4ae594a783ac93..9600c72742deb0ed41a1a496a29ad366beb22773 100644
--- a/libc-test/build.rs
+++ b/libc-test/build.rs
@@ -850,7 +850,6 @@ fn test_netbsd(target: &str) {
     cfg.skip_signededness(move |c| {
         match c {
             "LARGE_INTEGER" | "float" | "double" => true,
-            // uuid_t is a struct, not an integer.
             n if n.starts_with("pthread") => true,
             // sem_t is a struct or pointer
             "sem_t" => true,
@@ -1434,12 +1433,7 @@ fn test_android(target: &str) {
 
     cfg.generate("../src/lib.rs", "main.rs");
 
-    // On Android also generate another script for testing linux/fcntl
-    // declarations. These cannot be tested normally because including both
-    // `linux/fcntl.h` and `fcntl.h` fails.
-    //
-    // This also tests strerror_r.
-    test_linux_termios2(target);
+    test_linux_incompatible_apis(target);
 }
 
 fn test_freebsd(target: &str) {
@@ -2002,21 +1996,15 @@ fn test_linux(target: &str) {
     }
 
     let mips = target.contains("mips");
-    let i686 = target.contains("i686");
-    let x86_64 = target.contains("x86_64");
-    let x32 = target.ends_with("gnux32");
+    let mips32 = mips && !target.contains("64");
 
     let mut cfg = ctest::TestGenerator::new();
-    // FIXME: still necessary?
     cfg.define("_GNU_SOURCE", None);
     // This macro re-deifnes fscanf,scanf,sscanf to link to the symbols that are
     // deprecated since glibc >= 2.29. This allows Rust binaries to link against
     // glibc versions older than 2.29.
     cfg.define("__GLIBC_USE_DEPRECATED_SCANF", None);
 
-    // FIXME: still necessary?
-    cfg.flag("-Wno-deprecated-declarations");
-
     headers! { cfg:
                "ctype.h",
                "dirent.h",
@@ -2058,6 +2046,7 @@ fn test_linux(target: &str) {
                "stdio.h",
                "stdlib.h",
                "string.h",
+               "sys/sysctl.h",
                "sys/epoll.h",
                "sys/eventfd.h",
                "sys/file.h",
@@ -2072,6 +2061,7 @@ fn test_linux(target: &str) {
                "sys/prctl.h",
                "sys/ptrace.h",
                "sys/quota.h",
+               "sys/random.h",
                "sys/reboot.h",
                "sys/resource.h",
                "sys/sem.h",
@@ -2100,88 +2090,59 @@ fn test_linux(target: &str) {
                "unistd.h",
                "utime.h",
                "utmp.h",
+               "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 target.contains("x86") || target.contains("arm") {
+        headers! { cfg: "sys/io.h" }
+    }
+
+    // `sys/reg.h` is only available on x86 and x86_64
+    if target.contains("x86") {
+        headers! { cfg: "sys/reg.h" }
+    }
+
     // Include linux headers at the end:
     headers! {
         cfg:
+        "asm/mman.h",
+        "linux/dccp.h",
         "linux/falloc.h",
-        "linux/futex.h",
         "linux/fs.h",
+        "linux/futex.h",
         "linux/genetlink.h",
+        "linux/if.h",
         "linux/if_addr.h",
         "linux/if_alg.h",
         "linux/if_ether.h",
         "linux/if_tun.h",
         "linux/input.h",
+        "linux/magic.h",
+        "linux/memfd.h",
         "linux/module.h",
         "linux/net_tstamp.h",
+        "linux/netfilter/nf_tables.h",
         "linux/netfilter_ipv4.h",
         "linux/netfilter_ipv6.h",
         "linux/netlink.h",
+        "linux/quota.h",
         "linux/random.h",
+        "linux/reboot.h",
         "linux/rtnetlink.h",
         "linux/seccomp.h",
         "linux/sockios.h",
-    }
-
-    if x86_64 {
-        headers! { cfg: "sys/io.h" };
-    }
-    if i686 || x86_64 {
-        headers! { cfg: "sys/reg.h" };
-    }
-
-    if !musl {
-        assert!(uclibc || gnu);
-        headers! { cfg:
-                   "asm/mman.h",
-                   "linux/if.h",
-                   "linux/magic.h",
-                   "linux/netfilter/nf_tables.h",
-                   "linux/reboot.h",
-                   "sys/auxv.h",
-        };
-
-        if !x32 {
-            assert!((gnu || uclibc) && !x32);
-            headers! { cfg: "sys/sysctl.h", }
-        }
-        if !uclibc {
-            assert!(gnu);
-            headers! { cfg:
-                       "execinfo.h",
-                       "utmpx.h",
-            }
-        }
-        if !mips {
-            assert!((gnu || uclibc) && !mips);
-            headers! { cfg: "linux/quota.h" };
-        }
-    }
-
-    // DCCP support
-    if !uclibc && !musl {
-        assert!(gnu);
-        headers! { cfg: "linux/dccp.h" };
-    }
-
-    if !musl || mips {
-        assert!(gnu || uclibc || (mips && musl));
-        headers! { cfg:  "linux/memfd.h" };
+        "sys/auxv.h",
     }
 
     // note: aio.h must be included before sys/mount.h
-    if !uclibc {
-        assert!(gnu || musl);
-        // optionally included in uclibc
-        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| {
@@ -2210,7 +2171,9 @@ fn test_linux(target: &str) {
             s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
                 s.replace("e_nsec", ".tv_nsec")
             }
-            // FIXME: is this necessary?
+            // FIXME: epoll_event.data is actuall a union in C, but in Rust
+            // it is only a u64 because we only expose one field
+            // http://man7.org/linux/man-pages/man2/epoll_wait.2.html
             "u64" if struct_ == "epoll_event" => "data.u64".to_string(),
             // The following structs have a field called `type` in C,
             // but `type` is a Rust keyword, so these fields are translated
@@ -2222,31 +2185,34 @@ fn test_linux(target: &str) {
             {
                 "type".to_string()
             }
+
             s => s.to_string(),
         }
     });
 
     cfg.skip_type(move |ty| {
         match ty {
-            // sighandler_t is crazy across platforms
-            // FIXME: is this necessary?
+            // FIXME: `sighandler_t` type is incorrect, see:
+            // https://github.com/rust-lang/libc/issues/1359
             "sighandler_t" => true,
 
             // These cannot be tested when "resolv.h" is included and are tested
-            // below.
+            // in the `linux_elf.rs` file.
             "Elf64_Phdr" | "Elf32_Phdr" => true,
 
+            // This type is private on Linux. It is implemented as a C `enum`
+            // (`c_uint`) and this clashes with the type of the `rlimit` APIs
+            // which expect a `c_int` even though both are ABI compatible.
+            "__rlimit_resource_t" => true,
+
             _ => false,
         }
     });
 
     cfg.skip_struct(move |ty| {
         match ty {
-            // FIXME: is this necessary?
-            "sockaddr_nl" if musl => true,
-
             // These cannot be tested when "resolv.h" is included and are tested
-            // below.
+            // in the `linux_elf.rs` file.
             "Elf64_Phdr" | "Elf32_Phdr" => true,
 
             // On Linux, the type of `ut_tv` field of `struct utmpx`
@@ -2254,185 +2220,72 @@ fn test_linux(target: &str) {
             // which is absent in glibc, has to be defined.
             "__timeval" => true,
 
-            // This is actually a union, not a struct
+            // FIXME: This is actually a union, not a struct
             "sigval" => true,
 
-            // Linux kernel headers used on musl are too old to have this
-            // definition. Because it's tested on other Linux targets, skip it.
-            // FIXME: is this necessary?
-            "input_mask" if musl => 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: is this necessary?
+            // This type is tested in the `linux_termios.rs` file since there
+            // are header conflicts when including them with all the other
+            // structs.
             "termios2" => true,
 
             _ => false,
         }
     });
 
-    cfg.skip_signededness(move |c| match c {
-        // FIXME: is this necessary?
-        "LARGE_INTEGER" | "float" | "double" => true,
-        // FIXME: is this necessary?
-        n if n.starts_with("pthread") => true,
-        _ => false,
-    });
-
     cfg.skip_const(move |name| {
         match name {
-            // FIXME: is this necessary?
-            "SIG_DFL" | "SIG_ERR" | "SIG_IGN" => true, // sighandler_t weirdness
-            // FIXME: is this necessary?
-            "SIGUNUSED" => true,                       // removed in glibc 2.26
-
-            // types on musl are defined a little differently
-            // FIXME: is this necessary?
-            n if musl && n.contains("__SIZEOF_PTHREAD") => true,
-
-            // Skip constants not defined in MUSL but just passed down to the
-            // kernel regardless
-            // FIXME: is this necessary?
-            "RLIMIT_NLIMITS"
-            | "TCP_COOKIE_TRANSACTIONS"
-            | "RLIMIT_RTTIME"
-            | "MSG_COPY"
-                if musl =>
-            {
-                true
-            }
-            // work around super old mips toolchain
-            // FIXME: is this necessary?
-            "SCHED_IDLE" | "SHM_NORESERVE" => mips,
-
-            // weird signed extension or something like that?
-            // FIXME: is this necessary?
-            "MS_NOUSER" => true,
-            // FIXME: is this necessary?
-            "MS_RMT_MASK" => true, // updated in glibc 2.22 and musl 1.1.13
-
-            // These are either unimplemented or optionally built into uClibc
-            // FIXME: is this necessary?
-            "LC_CTYPE_MASK"
-            | "LC_NUMERIC_MASK"
-            | "LC_TIME_MASK"
-            | "LC_COLLATE_MASK"
-            | "LC_MONETARY_MASK"
-            | "LC_MESSAGES_MASK"
-            | "MADV_MERGEABLE"
-            | "MADV_UNMERGEABLE"
-            | "MADV_HWPOISON"
-            | "IPV6_ADD_MEMBERSHIP"
-            | "IPV6_DROP_MEMBERSHIP"
-            | "IPV6_MULTICAST_LOOP"
-            | "IPV6_V6ONLY"
-            | "MAP_STACK"
-            | "RTLD_DEEPBIND"
-            | "SOL_IPV6"
-            | "SOL_ICMPV6"
-                if uclibc =>
-            {
-                true
-            }
+            // These are not available in the MUSL version used by the
+            // 32-bit mips build jobs:
+            | "AF_XDP"
+            | "PF_XDP" if musl && mips32 => true,
 
-            // Musl uses old, patched kernel headers
-            // FIXME: is this necessary?
-            "FALLOC_FL_COLLAPSE_RANGE"
-            | "FALLOC_FL_ZERO_RANGE"
-            | "FALLOC_FL_INSERT_RANGE"
+            // These constants are not available if gnu headers have been included
+            // and can therefore not be tested here
+            //
+            // The IPV6 constants are tested in the `linux_ipv6.rs` tests:
+            | "IPV6_FLOWINFO"
+            | "IPV6_FLOWLABEL_MGR"
+            | "IPV6_FLOWINFO_SEND"
+            | "IPV6_FLOWINFO_FLOWLABEL"
+            | "IPV6_FLOWINFO_PRIORITY"
+            // The F_ fnctl constants are tested in the `linux_fnctl.rs` tests:
+            | "F_CANCELLK"
+            | "F_ADD_SEALS"
+            | "F_GET_SEALS"
+            | "F_SEAL_SEAL"
+            | "F_SEAL_SHRINK"
+            | "F_SEAL_GROW"
+            | "F_SEAL_WRITE" => true,
+
+            // The musl-sanitized kernel headers used in CI
+            // target the Linux kernel 4.4 and do not contain the
+            // following constants:
+            //
+            // Requires Linux kernel 4.9
             | "FALLOC_FL_UNSHARE_RANGE"
-            | "RENAME_NOREPLACE"
-            | "RENAME_EXCHANGE"
-            | "RENAME_WHITEOUT"
-            // ALG_SET_AEAD_* constants are available starting from kernel 3.19
-            | "ALG_SET_AEAD_ASSOCLEN"
-            | "ALG_SET_AEAD_AUTHSIZE"
-                if musl =>
-            {
-                true
-            }
+            //
+            // Require Linux kernel 5.x:
+            | "MSG_COPY"
+                => true,
 
-            // musl uses old kernel headers
-            // These are constants used in getrandom syscall
-            // FIXME: is this necessary?
-            "GRND_NONBLOCK" | "GRND_RANDOM" if musl => true,
+            // The musl version 1.0.22 used in CI does not
+            // contain these glibc constants yet:
+            | "RLIMIT_RTTIME" // should be in `resource.h`
+            | "TCP_COOKIE_TRANSACTIONS"  // should be in the `netinet/tcp.h` header
+                if musl => true,
 
-            // Defined by libattr not libc on linux (hard to test).
-            // See constant definition for more details.
-            // FIXME: is this necessary?
+            // FIXME: deprecated: not available in any header
+            // See: https://github.com/rust-lang/libc/issues/1356
             "ENOATTR" => true,
 
-            // On mips*-unknown-linux-gnu* CMSPAR cannot be included with the set of headers we
-            // want to use here for testing. It's originally defined in asm/termbits.h, which is
-            // also included by asm/termios.h, but not the standard termios.h. There's no way to
-            // include both asm/termbits.h and termios.h and there's no way to include both
-            // asm/termios.h and ioctl.h (+ some other headers) because of redeclared types.
-            // FIXME: is this necessary?
-            "CMSPAR" if mips && !musl => true,
-
-            // On mips Linux targets, MADV_SOFT_OFFLINE is currently missing, though it's been added but CI has too old
-            // of a Linux version. Since it exists on all other Linux targets, just ignore this for now and remove once
-            // it's been fixed in CI.
-            // FIXME: is this necessary?
-            "MADV_SOFT_OFFLINE" if mips => true,
+            // FIXME: SIGUNUSED was removed in glibc 2.26
+            // Users should use SIGSYS instead.
+            "SIGUNUSED" => 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: is this necessary?
-            "F_CANCELLK" | "F_ADD_SEALS" | "F_GET_SEALS" => true,
-            // FIXME: is this necessary?
-            "F_SEAL_SEAL" | "F_SEAL_SHRINK" | "F_SEAL_GROW"
-                | "F_SEAL_WRITE" => true,
-            // FIXME: is this necessary?
-            "QFMT_VFS_OLD" | "QFMT_VFS_V0" | "QFMT_VFS_V1"
-                if mips =>
-            {
-                true
-            } // Only on MIPS
-            // FIXME: is this necessary?
+            // FIXME: conflicts with glibc headers and is tested in
+            // `linux_termios.rs` below:
             "BOTHER" => true,
 
-            // FIXME: is this necessary?
-            "MFD_CLOEXEC" | "MFD_ALLOW_SEALING" if !mips && musl => 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: is this necessary?
-            "MFD_HUGETLB"
-                if !(x86_64 || i686) || musl =>
-            {
-                true
-            }
-
-            // These are defined for Solaris 11, but the crate is tested on
-            // illumos, where they are currently not defined
-            // FIXME: is this necessary?
-            "EADI"
-            | "PORT_SOURCE_POSTWAIT"
-            | "PORT_SOURCE_SIGNAL"
-            | "PTHREAD_STACK_MIN" => 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: is this necessary?
-            "AF_MAX" | "PF_MAX" => true,
-
-            // These are not in a glibc release yet, only in kernel headers.
-            // FIXME: is this necessary?
-            "AF_XDP"
-            | "PF_XDP"
-            | "SOL_XDP"
-            | "IPV6_FLOWINFO"
-            | "IPV6_FLOWLABEL_MGR"
-            | "IPV6_FLOWINFO_SEND"
-            | "IPV6_FLOWINFO_FLOWLABEL"
-            | "IPV6_FLOWINFO_PRIORITY"
-                 =>
-            {
-                true
-            }
-
             _ => false,
         }
     });
@@ -2440,60 +2293,25 @@ fn test_linux(target: &str) {
     cfg.skip_fn(move |name| {
         // skip those that are manually verified
         match name {
-            "execv" |       // crazy stuff with const/mut
-            "execve" |
-            "execvp" |
-            "execvpe" |
-            "fexecve" => true,
-
-            "getrlimit" | "getrlimit64" |    // non-int in 1st arg
-            "setrlimit" | "setrlimit64" |    // non-int in 1st arg
-            "prlimit" | "prlimit64"          // non-int in 2nd arg
-                => true,
-
-            // int vs uint. Sorry musl, your prototype declarations are "correct" in the sense that
-            // they match the interface defined by Linux verbatim, but they conflict with other
-            // send*/recv* syscalls
-            // FIXME: is this necessary?
-            "sendmmsg" | "recvmmsg" if musl => true,
-
-            // FIXME: is this necessary?
-            "dladdr" if musl => true, // const-ness only added recently
+            // FIXME: https://github.com/rust-lang/libc/issues/1272
+            "execv" | "execve" | "execvp" | "execvpe" | "fexecve" => true,
 
-            // There seems to be a small error in EGLIBC's eventfd.h header. The
-            // [underlying system call][1] always takes its first `count`
-            // argument as an `unsigned int`, but [EGLIBC's <sys/eventfd.h>
-            // header][2] declares it to take an `int`. [GLIBC's header][3]
-            // matches the kernel.
+            // There are two versions of the sterror_r function, see
             //
-            // EGLIBC is no longer actively developed, and Debian, the largest
-            // distribution that had been using it, switched back to GLIBC in
-            // April 2015. So effectively all Linux <sys/eventfd.h> headers will
-            // be using `unsigned int` soon.
+            // https://linux.die.net/man/3/strerror_r
             //
-            // [1]: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/fs/eventfd.c?id=refs/tags/v3.12.51#n397
-            // [2]: http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/trusty/eglibc/trusty/view/head:/sysdeps/unix/sysv/linux/sys/eventfd.h
-            // [3]: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/sys/eventfd.h;h=6295f32e937e779e74318eb9d3bdbe76aef8a8f3;hb=4e42b5b8f89f0e288e68be7ad70f9525aebc2cff#l34
-            // FIXME: is this necessary?
-            "eventfd" => true,
-
-            "lio_listio" if musl => true,
-
-            // These are either unimplemented or optionally built into uClibc
-            // or "sysinfo", where it's defined but the structs in linux/sysinfo.h and sys/sysinfo.h
-            // clash so it can't be tested
-            "getxattr" | "lgetxattr" | "fgetxattr" | "setxattr" | "lsetxattr" | "fsetxattr" |
-            "listxattr" | "llistxattr" | "flistxattr" | "removexattr" | "lremovexattr" |
-            "fremovexattr" |
-            "backtrace" |
-            "sysinfo" | "newlocale" | "duplocale" | "freelocale" | "uselocale" |
-            "nl_langinfo_l" | "wcslen" | "wcstombs" if uclibc => 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
-            "strerror_r" | "madvise" | "msync" | "mprotect" | "recvfrom" | "getpriority"  => true,
+            // An XSI-compliant version provided if:
+            //
+            // (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
+            //
+            // and a GNU specific version provided if _GNU_SOURCE is defined.
+            //
+            // libc provides bindings for the XSI-compliant version, which is
+            // preferred for portable applications.
+            //
+            // We skip the test here since here _GNU_SOURCE is defined, and
+            // test the XSI version below.
+            "strerror_r" => true,
 
             _ => false,
         }
@@ -2525,7 +2343,8 @@ fn test_linux(target: &str) {
         (musl && struct_ == "statvfs" && field == "__f_unused") ||
         // sigev_notify_thread_id is actually part of a sigev_un union
         (struct_ == "sigevent" && field == "sigev_notify_thread_id") ||
-        // signalfd had SIGSYS fields added in Linux 4.18, but no libc release has them yet.
+        // signalfd had SIGSYS fields added in Linux 4.18, but no libc release
+        // has them yet.
         (struct_ == "signalfd_siginfo" && (field == "ssi_addr_lsb" ||
                                            field == "_pad2" ||
                                            field == "ssi_syscall" ||
@@ -2533,77 +2352,133 @@ fn test_linux(target: &str) {
                                            field == "ssi_arch"))
     });
 
-    // FIXME: remove
-    cfg.fn_cname(move |name, _cname| name.to_string());
-
     cfg.generate("../src/lib.rs", "main.rs");
 
-    // On Linux also generate another script for testing linux/fcntl declarations.
-    // These cannot be tested normally because including both `linux/fcntl.h` and `fcntl.h`
-    // fails on a lot of platforms.
-    test_linux_termios2(target);
-
-    // Test Elf64_Phdr and Elf32_Phdr
-    // These types have a field called `p_type`, but including
-    // "resolve.h" defines a `p_type` macro that expands to `__p_type`
-    // making the tests for these fails when both are included.
-    let mut cfg = ctest::TestGenerator::new();
-    cfg.skip_fn(|_| true)
-        .skip_const(|_| true)
-        .skip_static(|_| true)
-        .type_name(move |ty, _is_struct, _is_union| ty.to_string());
-    cfg.skip_struct(move |ty| match ty {
-        "Elf64_Phdr" | "Elf32_Phdr" => false,
-        _ => true,
-    });
-    cfg.skip_type(move |ty| match ty {
-        "Elf64_Phdr" | "Elf32_Phdr" => false,
-        _ => true,
-    });
-    cfg.header("elf.h");
-    cfg.generate("../src/lib.rs", "linux_elf.rs");
+    test_linux_incompatible_apis(target);
 }
 
-fn test_linux_termios2(target: &str) {
+// This function tests APIs that are incompatible to test when other APIs
+// are included (e.g. because including both sets of headers clashes)
+fn test_linux_incompatible_apis(target: &str) {
     assert!(target.contains("linux") || target.contains("android"));
     let musl = target.contains("musl");
-    let mut cfg = ctest::TestGenerator::new();
-    cfg.skip_type(|_| true)
-        .skip_fn(|f| match f {
+    let linux = target.contains("linux");
+
+    {
+        // test strerror_r from the `string.h` header
+        let mut cfg = ctest::TestGenerator::new();
+        cfg.skip_type(|_| true).skip_static(|_| true);
+
+        headers! { cfg: "string.h" }
+        cfg.skip_fn(|f| match f {
             "strerror_r" => false,
             _ => true,
         })
-        .skip_static(|_| true);
-    headers! {
-        cfg:
-      "linux/quota.h",
-        "asm/termbits.h",
-        "string.h"
+        .skip_const(|_| true)
+        .skip_struct(|_| true);
+        cfg.generate("../src/lib.rs", "linux_strerror_r.rs");
     }
-    if musl {
-        cfg.header("fcntl.h");
-    } else {
-        cfg.header("linux/fcntl.h");
+    {
+        // test fcntl - see:
+        // http://man7.org/linux/man-pages/man2/fcntl.2.html
+        let mut cfg = ctest::TestGenerator::new();
+
+        if musl {
+            cfg.header("fcntl.h");
+        } else {
+            cfg.header("linux/fcntl.h");
+        }
+
+        cfg.skip_type(|_| true)
+            .skip_static(|_| true)
+            .skip_struct(|_| true)
+            .skip_fn(|_| true)
+            .skip_const(move |name| match name {
+                // test fcntl constants:
+                "F_CANCELLK" | "F_ADD_SEALS" | "F_GET_SEALS"
+                | "F_SEAL_SEAL" | "F_SEAL_SHRINK" | "F_SEAL_GROW"
+                | "F_SEAL_WRITE" => false,
+                _ => true,
+            })
+            .type_name(move |ty, is_struct, is_union| match ty {
+                t if is_struct => format!("struct {}", t),
+                t if is_union => format!("union {}", t),
+                t => t.to_string(),
+            });
+
+        cfg.generate("../src/lib.rs", "linux_fcntl.rs");
     }
-    if !musl {
-        cfg.header("net/if.h");
-        cfg.header("linux/if.h");
+    {
+        // test termios
+        let mut cfg = ctest::TestGenerator::new();
+        cfg.header("asm/termbits.h");
+        cfg.skip_type(|_| true)
+            .skip_static(|_| true)
+            .skip_fn(|_| true)
+            .skip_const(|c| c != "BOTHER")
+            .skip_struct(|s| s != "termios2")
+            .type_name(move |ty, is_struct, is_union| match ty {
+                t if is_struct => format!("struct {}", t),
+                t if is_union => format!("union {}", t),
+                t => t.to_string(),
+            });
+        cfg.generate("../src/lib.rs", "linux_termios.rs");
     }
 
-    cfg.skip_const(move |name| match name {
-        "F_CANCELLK" | "F_ADD_SEALS" | "F_GET_SEALS" => false,
-        "F_SEAL_SEAL" | "F_SEAL_SHRINK" | "F_SEAL_GROW" | "F_SEAL_WRITE" => {
-            false
-        }
-        _ => true,
-    });
-    cfg.skip_struct(|s| s != "termios2");
-    cfg.type_name(move |ty, is_struct, is_union| match ty {
-        t if is_struct => format!("struct {}", t),
-        t if is_union => format!("union {}", t),
-        t => t.to_string(),
-    });
-    cfg.generate("../src/lib.rs", "linux_fcntl.rs");
+    if !linux {
+        return;
+    }
+    // linux-only tests (no android):
+
+    {
+        // test IPV6_ constants:
+        let mut cfg = ctest::TestGenerator::new();
+        headers! {
+            cfg:
+            "linux/in6.h"
+        }
+        cfg.skip_type(|_| true)
+            .skip_static(|_| true)
+            .skip_fn(|_| true)
+            .skip_const(|_| true)
+            .skip_struct(|_| true)
+            .skip_const(move |name| match name {
+                "IPV6_FLOWINFO"
+                | "IPV6_FLOWLABEL_MGR"
+                | "IPV6_FLOWINFO_SEND"
+                | "IPV6_FLOWINFO_FLOWLABEL"
+                | "IPV6_FLOWINFO_PRIORITY" => false,
+                _ => true,
+            })
+            .type_name(move |ty, is_struct, is_union| match ty {
+                t if is_struct => format!("struct {}", t),
+                t if is_union => format!("union {}", t),
+                t => t.to_string(),
+            });
+        cfg.generate("../src/lib.rs", "linux_ipv6.rs");
+    }
+    {
+        // Test Elf64_Phdr and Elf32_Phdr
+        // These types have a field called `p_type`, but including
+        // "resolve.h" defines a `p_type` macro that expands to `__p_type`
+        // making the tests for these fails when both are included.
+        let mut cfg = ctest::TestGenerator::new();
+        cfg.header("elf.h");
+        cfg.skip_fn(|_| true)
+            .skip_static(|_| true)
+            .skip_fn(|_| true)
+            .skip_const(|_| true)
+            .type_name(move |ty, _is_struct, _is_union| ty.to_string())
+            .skip_struct(move |ty| match ty {
+                "Elf64_Phdr" | "Elf32_Phdr" => false,
+                _ => true,
+            })
+            .skip_type(move |ty| match ty {
+                "Elf64_Phdr" | "Elf32_Phdr" => false,
+                _ => true,
+            });
+        cfg.generate("../src/lib.rs", "linux_elf.rs");
+    }
 }
 
 fn which_freebsd() -> Option<i32> {
diff --git a/libc-test/test/linux_elf.rs b/libc-test/test/linux_elf.rs
new file mode 100644
index 0000000000000000000000000000000000000000..e9e45da9f2cd7d5426f06306d4c5d8c864025fde
--- /dev/null
+++ b/libc-test/test/linux_elf.rs
@@ -0,0 +1,10 @@
+#![allow(bad_style, improper_ctypes, unused, deprecated)]
+
+extern crate libc;
+use libc::*;
+
+#[cfg(target_os = "linux")]
+include!(concat!(env!("OUT_DIR"), "/linux_elf.rs"));
+
+#[cfg(not(target_os = "linux"))]
+fn main() {}
diff --git a/libc-test/test/linux_ipv6.rs b/libc-test/test/linux_ipv6.rs
new file mode 100644
index 0000000000000000000000000000000000000000..2c0adb2812cad435b009fb7a285d0810d8b005d0
--- /dev/null
+++ b/libc-test/test/linux_ipv6.rs
@@ -0,0 +1,10 @@
+#![allow(bad_style, improper_ctypes, unused, deprecated)]
+
+extern crate libc;
+use libc::*;
+
+#[cfg(target_os = "linux")]
+include!(concat!(env!("OUT_DIR"), "/linux_ipv6.rs"));
+
+#[cfg(not(target_os = "linux"))]
+fn main() {}
diff --git a/libc-test/test/linux_strerror_r.rs b/libc-test/test/linux_strerror_r.rs
new file mode 100644
index 0000000000000000000000000000000000000000..c05b79494dd53232b68dee28cdb76dea8d96a369
--- /dev/null
+++ b/libc-test/test/linux_strerror_r.rs
@@ -0,0 +1,10 @@
+#![allow(bad_style, improper_ctypes, unused, deprecated)]
+
+extern crate libc;
+use libc::*;
+
+#[cfg(any(target_os = "linux", target_os = "android"))]
+include!(concat!(env!("OUT_DIR"), "/linux_strerror_r.rs"));
+
+#[cfg(not(any(target_os = "linux", target_os = "android")))]
+fn main() {}
diff --git a/libc-test/test/linux_termios.rs b/libc-test/test/linux_termios.rs
new file mode 100644
index 0000000000000000000000000000000000000000..d765f336c083f90576e6735d7a2b724cade58d9e
--- /dev/null
+++ b/libc-test/test/linux_termios.rs
@@ -0,0 +1,10 @@
+#![allow(bad_style, improper_ctypes, unused, deprecated)]
+
+extern crate libc;
+use libc::*;
+
+#[cfg(any(target_os = "linux", target_os = "android"))]
+include!(concat!(env!("OUT_DIR"), "/linux_termios.rs"));
+
+#[cfg(not(any(target_os = "linux", target_os = "android")))]
+fn main() {}
diff --git a/src/unix/bsd/mod.rs b/src/unix/bsd/mod.rs
index e69035e197132d9db152b71f64f98746ad49b7dd..250711f74cec07f91b3781ce914dc28ccb161501 100644
--- a/src/unix/bsd/mod.rs
+++ b/src/unix/bsd/mod.rs
@@ -488,6 +488,13 @@ f! {
 }
 
 extern {
+    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
+               link_name = "getrlimit$UNIX2003")]
+    pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int;
+    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
+               link_name = "setrlimit$UNIX2003")]
+    pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int;
+
     pub fn strerror_r(errnum: ::c_int, buf: *mut c_char,
                       buflen: ::size_t) -> ::c_int;
     pub fn abs(i: ::c_int) -> ::c_int;
diff --git a/src/unix/haiku/mod.rs b/src/unix/haiku/mod.rs
index 885c83991fce96f101ba79ef25cdd3c6fa2c91aa..56df0db586dc85917929b209a30db62b429d4363 100644
--- a/src/unix/haiku/mod.rs
+++ b/src/unix/haiku/mod.rs
@@ -1209,6 +1209,8 @@ f! {
 }
 
 extern {
+    pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int;
+    pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int;
     pub fn strerror_r(errnum: ::c_int, buf: *mut c_char,
                       buflen: ::size_t) -> ::c_int;
 
diff --git a/src/unix/hermit/mod.rs b/src/unix/hermit/mod.rs
index 4c5781163037c26010900e889572a79ccae74c66..4bc03ef9baa18d04e1816f1ad6bbca444c55d6ed 100644
--- a/src/unix/hermit/mod.rs
+++ b/src/unix/hermit/mod.rs
@@ -964,6 +964,8 @@ f! {
 }
 
 extern {
+    pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int;
+    pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int;
     pub fn strerror_r(errnum: ::c_int, buf: *mut c_char,
                       buflen: ::size_t) -> ::c_int;
 
diff --git a/src/unix/mod.rs b/src/unix/mod.rs
index 588426f04e4ce500a881d4cb898635cafb05681a..afb81be3774751f71146a952a62522a44b482ec2 100644
--- a/src/unix/mod.rs
+++ b/src/unix/mod.rs
@@ -846,12 +846,6 @@ extern {
 
     pub fn signal(signum: ::c_int, handler: sighandler_t) -> sighandler_t;
 
-    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
-               link_name = "getrlimit$UNIX2003")]
-    pub fn getrlimit(resource: ::c_int, rlim: *mut rlimit) -> ::c_int;
-    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
-               link_name = "setrlimit$UNIX2003")]
-    pub fn setrlimit(resource: ::c_int, rlim: *const rlimit) -> ::c_int;
     #[cfg_attr(target_os = "netbsd", link_name = "__getrusage50")]
     pub fn getrusage(resource: ::c_int, usage: *mut rusage) -> ::c_int;
 
diff --git a/src/unix/newlib/mod.rs b/src/unix/newlib/mod.rs
index 93798e58b505956cef5d731f882be2389b687394..f27874cbe5821f8687dcfc1f18532b75be8034ed 100644
--- a/src/unix/newlib/mod.rs
+++ b/src/unix/newlib/mod.rs
@@ -598,6 +598,9 @@ f! {
 }
 
 extern {
+    pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int;
+    pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int;
+
     #[cfg_attr(target_os = "linux",
                link_name = "__xpg_strerror_r")]
     pub fn strerror_r(errnum: ::c_int, buf: *mut c_char,
diff --git a/src/unix/notbsd/android/mod.rs b/src/unix/notbsd/android/mod.rs
index 252407c190a74423f4f2917c129efa5d3c12c598..05d49002c11be0e456a313c06de3bccf680fa1c1 100644
--- a/src/unix/notbsd/android/mod.rs
+++ b/src/unix/notbsd/android/mod.rs
@@ -762,6 +762,10 @@ pub const SIGURG: ::c_int = 23;
 pub const SIGIO: ::c_int = 29;
 pub const SIGSYS: ::c_int = 31;
 pub const SIGSTKFLT: ::c_int = 16;
+#[deprecated(
+    since = "0.2.55",
+    note = "Use SIGSYS instead"
+)]
 pub const SIGUNUSED: ::c_int = 31;
 pub const SIGTTIN: ::c_int = 21;
 pub const SIGTTOU: ::c_int = 22;
@@ -1919,6 +1923,8 @@ f! {
 }
 
 extern {
+    pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int;
+    pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int;
     pub fn strerror_r(errnum: ::c_int, buf: *mut c_char,
                       buflen: ::size_t) -> ::c_int;
 
diff --git a/src/unix/notbsd/emscripten/mod.rs b/src/unix/notbsd/emscripten/mod.rs
index 0a98eafb61e5c8b94f6ad5fc16d09ac07d6a9dad..f1ab424b88bb0c0e96cdb9824256770df4b5dedf 100644
--- a/src/unix/notbsd/emscripten/mod.rs
+++ b/src/unix/notbsd/emscripten/mod.rs
@@ -1687,6 +1687,8 @@ f! {
 }
 
 extern {
+    pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int;
+    pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int;
     pub fn strerror_r(errnum: ::c_int, buf: *mut c_char,
                       buflen: ::size_t) -> ::c_int;
 
diff --git a/src/unix/notbsd/linux/mips/mod.rs b/src/unix/notbsd/linux/mips/mod.rs
index c1407b6c46ad9d1731d2b1b34f3b931c44d958be..c5253accad196e64ae3c04df3af3ce1424134f77 100644
--- a/src/unix/notbsd/linux/mips/mod.rs
+++ b/src/unix/notbsd/linux/mips/mod.rs
@@ -1,3 +1,4 @@
+pub type pthread_t = c_ulong;
 pub type shmatt_t = ::c_ulong;
 pub type msgqnum_t = ::c_ulong;
 pub type msglen_t = ::c_ulong;
@@ -70,6 +71,8 @@ s! {
     }
 }
 
+pub const MS_RMT_MASK: ::c_ulong = 0x02800051;
+
 pub const SFD_CLOEXEC: ::c_int = 0x080000;
 
 pub const NCCS: usize = 32;
diff --git a/src/unix/notbsd/linux/mod.rs b/src/unix/notbsd/linux/mod.rs
index bb3638d0a4463b109b867c88a806b737947901fb..a810dc46763311c5a37bd0436ee48abc4ab0795b 100644
--- a/src/unix/notbsd/linux/mod.rs
+++ b/src/unix/notbsd/linux/mod.rs
@@ -3,7 +3,6 @@
 pub type useconds_t = u32;
 pub type dev_t = u64;
 pub type socklen_t = u32;
-pub type pthread_t = c_ulong;
 pub type mode_t = u32;
 pub type ino64_t = u64;
 pub type off64_t = i64;
@@ -850,8 +849,7 @@ pub const _PC_ALLOC_SIZE_MIN: ::c_int = 18;
 pub const _PC_SYMLINK_MAX: ::c_int = 19;
 pub const _PC_2_SYMLINKS: ::c_int = 20;
 
-pub const MS_NOUSER: ::c_ulong = 0x80000000;
-pub const MS_RMT_MASK: ::c_ulong = 0x800051;
+pub const MS_NOUSER: ::c_ulong = 0xffffffff80000000;
 
 pub const _SC_ARG_MAX: ::c_int = 0;
 pub const _SC_CHILD_MAX: ::c_int = 1;
@@ -2267,10 +2265,15 @@ extern {
                        flags: ::c_int) -> ::c_int;
     pub fn pthread_setschedprio(native: ::pthread_t,
                                 priority: ::c_int) -> ::c_int;
-    pub fn prlimit(pid: ::pid_t, resource: ::c_int, new_limit: *const ::rlimit,
+    pub fn getrlimit(resource: ::__rlimit_resource_t,
+                     rlim: *mut ::rlimit) -> ::c_int;
+    pub fn setrlimit(resource: ::__rlimit_resource_t,
+                     rlim: *const ::rlimit) -> ::c_int;
+    pub fn prlimit(pid: ::pid_t,
+                   resource: ::__rlimit_resource_t, new_limit: *const ::rlimit,
                    old_limit: *mut ::rlimit) -> ::c_int;
     pub fn prlimit64(pid: ::pid_t,
-                     resource: ::c_int,
+                     resource: ::__rlimit_resource_t,
                      new_limit: *const ::rlimit64,
                      old_limit: *mut ::rlimit64) -> ::c_int;
     pub fn getloadavg(loadavg: *mut ::c_double, nelem: ::c_int) -> ::c_int;
diff --git a/src/unix/notbsd/linux/musl/b32/arm.rs b/src/unix/notbsd/linux/musl/b32/arm.rs
index 88d8798ecaa472f8ac449b697c81969341af677a..94f1a80f557af2d24ee4802acc918324f3874454 100644
--- a/src/unix/notbsd/linux/musl/b32/arm.rs
+++ b/src/unix/notbsd/linux/musl/b32/arm.rs
@@ -180,7 +180,7 @@ pub const RLIMIT_NOFILE: ::c_int = 7;
 pub const RLIMIT_AS: ::c_int = 9;
 pub const RLIMIT_NPROC: ::c_int = 6;
 pub const RLIMIT_MEMLOCK: ::c_int = 8;
-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;
@@ -838,6 +838,6 @@ pub const SYS_pkey_alloc: ::c_long = 395;
 pub const SYS_pkey_free: ::c_long = 396;
 
 #[doc(hidden)]
-pub const AF_MAX: ::c_int = 43;
+pub const AF_MAX: ::c_int = 45;
 #[doc(hidden)]
 pub const PF_MAX: ::c_int = AF_MAX;
diff --git a/src/unix/notbsd/linux/musl/b32/x86.rs b/src/unix/notbsd/linux/musl/b32/x86.rs
index 8bfb60ba3852aaf72cad272bb7fdf7a4b94e0e6a..0f620fe5fbc581095456628be0e09249ec7ccf5b 100644
--- a/src/unix/notbsd/linux/musl/b32/x86.rs
+++ b/src/unix/notbsd/linux/musl/b32/x86.rs
@@ -240,7 +240,7 @@ pub const RLIMIT_NOFILE: ::c_int = 7;
 pub const RLIMIT_AS: ::c_int = 9;
 pub const RLIMIT_NPROC: ::c_int = 6;
 pub const RLIMIT_MEMLOCK: ::c_int = 8;
-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;
@@ -946,6 +946,6 @@ pub const UESP: ::c_int = 15;
 pub const SS: ::c_int = 16;
 
 #[doc(hidden)]
-pub const AF_MAX: ::c_int = 42;
+pub const AF_MAX: ::c_int = 45;
 #[doc(hidden)]
 pub const PF_MAX: ::c_int = AF_MAX;
diff --git a/src/unix/notbsd/linux/musl/b64/aarch64.rs b/src/unix/notbsd/linux/musl/b64/aarch64.rs
index f01a5c4374c333307157cd7192a698aacc82530b..018aaa9b501318a30da6fcfdaaf805bcc5ac6cd5 100644
--- a/src/unix/notbsd/linux/musl/b64/aarch64.rs
+++ b/src/unix/notbsd/linux/musl/b64/aarch64.rs
@@ -71,7 +71,7 @@ pub const MINSIGSTKSZ: ::size_t = 6144;
 pub const SIGSTKSZ: ::size_t = 12288;
 
 #[doc(hidden)]
-pub const PF_MAX: ::c_int = 43;
+pub const PF_MAX: ::c_int = 45;
 #[doc(hidden)]
 pub const AF_MAX: ::c_int = PF_MAX;
 
@@ -340,7 +340,7 @@ pub const SYS_pkey_mprotect: ::c_long = 288;
 pub const SYS_pkey_alloc: ::c_long = 289;
 pub const SYS_pkey_free: ::c_long = 290;
 
-pub const RLIMIT_NLIMITS: ::c_int = 16;
+pub const RLIMIT_NLIMITS: ::c_int = 15;
 pub const TIOCINQ: ::c_int = ::FIONREAD;
 pub const MCL_CURRENT: ::c_int = 0x0001;
 pub const MCL_FUTURE: ::c_int = 0x0002;
diff --git a/src/unix/notbsd/linux/musl/b64/powerpc64.rs b/src/unix/notbsd/linux/musl/b64/powerpc64.rs
index 04eba48cc418283f6af686fce818e6466eff9bed..8f16047e5d06311035ccaf25f77febd13f42642c 100644
--- a/src/unix/notbsd/linux/musl/b64/powerpc64.rs
+++ b/src/unix/notbsd/linux/musl/b64/powerpc64.rs
@@ -70,7 +70,7 @@ pub const SIGSTKSZ: ::size_t = 10240;
 pub const MINSIGSTKSZ: ::size_t = 4096;
 
 #[doc(hidden)]
-pub const AF_MAX: ::c_int = 43;
+pub const AF_MAX: ::c_int = 45;
 #[doc(hidden)]
 pub const PF_MAX: ::c_int = AF_MAX;
 
diff --git a/src/unix/notbsd/linux/musl/b64/x86_64.rs b/src/unix/notbsd/linux/musl/b64/x86_64.rs
index 94c5d88dab30611dc024d9ba6bb35610d800d88b..3a908354b586d291c64132a2099dde451f76a68e 100644
--- a/src/unix/notbsd/linux/musl/b64/x86_64.rs
+++ b/src/unix/notbsd/linux/musl/b64/x86_64.rs
@@ -493,11 +493,11 @@ pub const SIGSTKSZ: ::size_t = 8192;
 pub const MINSIGSTKSZ: ::size_t = 2048;
 
 #[doc(hidden)]
-pub const AF_MAX: ::c_int = 42;
+pub const AF_MAX: ::c_int = 45;
 #[doc(hidden)]
 pub const PF_MAX: ::c_int = AF_MAX;
 
-pub const RLIMIT_NLIMITS: ::c_int = 16;
+pub const RLIMIT_NLIMITS: ::c_int = 15;
 pub const TIOCINQ: ::c_int = ::FIONREAD;
 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 f230064c9e248aa05fb27f75f9df2ed8285908e2..95b99a26eebd9b32adb8137c36a3d0fcf6151ed4 100644
--- a/src/unix/notbsd/linux/musl/mod.rs
+++ b/src/unix/notbsd/linux/musl/mod.rs
@@ -1,3 +1,4 @@
+pub type pthread_t = *mut ::c_void;
 pub type clock_t = c_long;
 pub type time_t = c_long;
 pub type suseconds_t = c_long;
@@ -168,6 +169,8 @@ cfg_if! {
     }
 }
 
+pub const MS_RMT_MASK: ::c_ulong = 0x02800051;
+
 pub const SFD_CLOEXEC: ::c_int = 0x080000;
 
 pub const NCCS: usize = 32;
@@ -239,6 +242,10 @@ pub const TCP_REPAIR_OPTIONS: ::c_int = 22;
 pub const TCP_FASTOPEN: ::c_int = 23;
 pub const TCP_TIMESTAMP: ::c_int = 24;
 
+#[deprecated(
+    since = "0.2.55",
+    note = "Use SIGSYS instead"
+)]
 pub const SIGUNUSED: ::c_int = ::SIGSYS;
 
 pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4;
diff --git a/src/unix/notbsd/linux/other/b32/mod.rs b/src/unix/notbsd/linux/other/b32/mod.rs
index d078f753755c685f98ed7a937db80573b0281cef..32e510e3735b277c60d52a2ea6ff015ad7a56c56 100644
--- a/src/unix/notbsd/linux/other/b32/mod.rs
+++ b/src/unix/notbsd/linux/other/b32/mod.rs
@@ -228,6 +228,10 @@ pub const SIGURG: ::c_int = 23;
 pub const SIGIO: ::c_int = 29;
 pub const SIGSYS: ::c_int = 31;
 pub const SIGSTKFLT: ::c_int = 16;
+#[deprecated(
+    since = "0.2.55",
+    note = "Use SIGSYS instead"
+)]
 pub const SIGUNUSED: ::c_int = 31;
 pub const SIGPOLL: ::c_int = 29;
 pub const SIGPWR: ::c_int = 30;
diff --git a/src/unix/notbsd/linux/other/b64/aarch64.rs b/src/unix/notbsd/linux/other/b64/aarch64.rs
index 3bd2e02eebe9981bae13cfcb159ac7b670f294be..4433b775a99eaa317773f56048561b14879109ba 100644
--- a/src/unix/notbsd/linux/other/b64/aarch64.rs
+++ b/src/unix/notbsd/linux/other/b64/aarch64.rs
@@ -315,6 +315,10 @@ pub const SIGURG: ::c_int = 23;
 pub const SIGIO: ::c_int = 29;
 pub const SIGSYS: ::c_int = 31;
 pub const SIGSTKFLT: ::c_int = 16;
+#[deprecated(
+    since = "0.2.55",
+    note = "Use SIGSYS instead"
+)]
 pub const SIGUNUSED: ::c_int = 31;
 pub const SIGPOLL: ::c_int = 29;
 pub const SIGPWR: ::c_int = 30;
diff --git a/src/unix/notbsd/linux/other/b64/powerpc64.rs b/src/unix/notbsd/linux/other/b64/powerpc64.rs
index bc5b01c5a4c153d1091005ca2cc572ec136045da..7c02bdfec5e4fe7f9130dd4444358333fb7ed67b 100644
--- a/src/unix/notbsd/linux/other/b64/powerpc64.rs
+++ b/src/unix/notbsd/linux/other/b64/powerpc64.rs
@@ -302,6 +302,10 @@ pub const SIGURG: ::c_int = 23;
 pub const SIGIO: ::c_int = 29;
 pub const SIGSYS: ::c_int = 31;
 pub const SIGSTKFLT: ::c_int = 16;
+#[deprecated(
+    since = "0.2.55",
+    note = "Use SIGSYS instead"
+)]
 pub const SIGUNUSED: ::c_int = 31;
 pub const SIGPOLL: ::c_int = 29;
 pub const SIGPWR: ::c_int = 30;
diff --git a/src/unix/notbsd/linux/other/b64/x86_64.rs b/src/unix/notbsd/linux/other/b64/x86_64.rs
index 79f27e083f2d6fa9c8e9a3814a09707a2fa7a94c..3bd8288ad10a69549ab2be6d5658fd7745160326 100644
--- a/src/unix/notbsd/linux/other/b64/x86_64.rs
+++ b/src/unix/notbsd/linux/other/b64/x86_64.rs
@@ -500,6 +500,10 @@ pub const SIGURG: ::c_int = 23;
 pub const SIGIO: ::c_int = 29;
 pub const SIGSYS: ::c_int = 31;
 pub const SIGSTKFLT: ::c_int = 16;
+#[deprecated(
+    since = "0.2.55",
+    note = "Use SIGSYS instead"
+)]
 pub const SIGUNUSED: ::c_int = 31;
 pub const SIGPOLL: ::c_int = 29;
 pub const SIGPWR: ::c_int = 30;
diff --git a/src/unix/notbsd/linux/other/mod.rs b/src/unix/notbsd/linux/other/mod.rs
index 16daca45c3c03a67a8e97ddf25be7c0d56564553..2ebb2acb45810d28a8abd9a43013c7ea6c44a3be 100644
--- a/src/unix/notbsd/linux/other/mod.rs
+++ b/src/unix/notbsd/linux/other/mod.rs
@@ -1,3 +1,4 @@
+pub type pthread_t = c_ulong;
 pub type __priority_which_t = ::c_uint;
 
 s! {
@@ -308,6 +309,8 @@ cfg_if! {
     }
 }
 
+pub const MS_RMT_MASK: ::c_ulong = 0x02800051;
+
 pub const __UT_LINESIZE: usize = 32;
 pub const __UT_NAMESIZE: usize = 32;
 pub const __UT_HOSTSIZE: usize = 256;
@@ -922,7 +925,7 @@ pub const M_ARENA_TEST: ::c_int = -7;
 pub const M_ARENA_MAX: ::c_int = -8;
 
 #[doc(hidden)]
-pub const AF_MAX: ::c_int = 42;
+pub const AF_MAX: ::c_int = 45;
 #[doc(hidden)]
 pub const PF_MAX: ::c_int = AF_MAX;
 
diff --git a/src/unix/notbsd/linux/s390x/mod.rs b/src/unix/notbsd/linux/s390x/mod.rs
index b9059687dfafa71ab7e24cb999ae9526d1dd8436..7785f9d59aeeaea80bbd729eb9211b2cf0b7a5fd 100644
--- a/src/unix/notbsd/linux/s390x/mod.rs
+++ b/src/unix/notbsd/linux/s390x/mod.rs
@@ -1,5 +1,6 @@
 use ::pthread_mutex_t;
 
+pub type pthread_t = c_ulong;
 pub type blkcnt_t = i64;
 pub type blksize_t = i64;
 pub type c_char = u8;
@@ -352,6 +353,8 @@ cfg_if! {
     }
 }
 
+pub const MS_RMT_MASK: ::c_ulong = 0x02800051;
+
 pub const SFD_CLOEXEC: ::c_int = 0x080000;
 
 pub const NCCS: usize = 32;
@@ -638,6 +641,10 @@ pub const SIGURG: ::c_int = 23;
 pub const SIGIO: ::c_int = 29;
 pub const SIGSYS: ::c_int = 31;
 pub const SIGSTKFLT: ::c_int = 16;
+#[deprecated(
+    since = "0.2.55",
+    note = "Use SIGSYS instead"
+)]
 pub const SIGUNUSED: ::c_int = 31;
 pub const SIGTTIN: ::c_int = 21;
 pub const SIGTTOU: ::c_int = 22;
diff --git a/src/unix/notbsd/mod.rs b/src/unix/notbsd/mod.rs
index ea1e7c69bb91946a742c5f11c5aa0fc9e768b071..2b6d6637a17269834061984fb8e89c7cc6defc45 100644
--- a/src/unix/notbsd/mod.rs
+++ b/src/unix/notbsd/mod.rs
@@ -4,6 +4,7 @@ pub type tcflag_t = ::c_uint;
 pub type clockid_t = ::c_int;
 pub type key_t = ::c_int;
 pub type id_t = ::c_uint;
+pub type __rlimit_resource_t = ::c_uint;
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum timezone {}
@@ -1305,7 +1306,8 @@ extern {
     pub fn fstatat64(dirfd: ::c_int, pathname: *const c_char,
                      buf: *mut stat64, flags: ::c_int) -> ::c_int;
     pub fn ftruncate64(fd: ::c_int, length: off64_t) -> ::c_int;
-    pub fn getrlimit64(resource: ::c_int, rlim: *mut rlimit64) -> ::c_int;
+    pub fn getrlimit64(resource: ::__rlimit_resource_t,
+                       rlim: *mut rlimit64) -> ::c_int;
     pub fn lseek64(fd: ::c_int, offset: off64_t, whence: ::c_int) -> off64_t;
     pub fn lstat64(path: *const c_char, buf: *mut stat64) -> ::c_int;
     pub fn mmap64(addr: *mut ::c_void,
@@ -1334,7 +1336,8 @@ extern {
     pub fn readdir64(dirp: *mut ::DIR) -> *mut ::dirent64;
     pub fn readdir64_r(dirp: *mut ::DIR, entry: *mut ::dirent64,
                        result: *mut *mut ::dirent64) -> ::c_int;
-    pub fn setrlimit64(resource: ::c_int, rlim: *const rlimit64) -> ::c_int;
+    pub fn setrlimit64(resource: ::__rlimit_resource_t,
+                       rlim: *const rlimit64) -> ::c_int;
     pub fn stat64(path: *const c_char, buf: *mut stat64) -> ::c_int;
     pub fn truncate64(path: *const c_char, length: off64_t) -> ::c_int;
 
diff --git a/src/unix/redox/mod.rs b/src/unix/redox/mod.rs
index 4131bb9cf32b5c91c9a1c9151018891afe22f796..388918eb9b5dcf7efa6f8468feb7fc0ca842b04e 100644
--- a/src/unix/redox/mod.rs
+++ b/src/unix/redox/mod.rs
@@ -534,6 +534,9 @@ cfg_if! {
 }
 
 extern {
+    pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int;
+    pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int;
+
     pub fn strerror_r(errnum: ::c_int, buf: *mut c_char,
                       buflen: ::size_t) -> ::c_int;
 
diff --git a/src/unix/solarish/mod.rs b/src/unix/solarish/mod.rs
index 062b2837dbd70f8b007320a3604dd24ca8aa642f..de7c1cde8e58900796a91895628bc1f7d8b8c55f 100644
--- a/src/unix/solarish/mod.rs
+++ b/src/unix/solarish/mod.rs
@@ -1786,6 +1786,9 @@ f! {
 }
 
 extern {
+    pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int;
+    pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int;
+
     pub fn strerror_r(errnum: ::c_int, buf: *mut c_char,
                       buflen: ::size_t) -> ::c_int;
 
diff --git a/src/unix/uclibc/mod.rs b/src/unix/uclibc/mod.rs
index 9a430a9fa9b99ecef8969d55d7ce1fb84225ce12..f3dc379d84a4e841aa2242ac814d7b8442f91c50 100644
--- a/src/unix/uclibc/mod.rs
+++ b/src/unix/uclibc/mod.rs
@@ -1583,6 +1583,8 @@ extern {
 
     pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t,
                          advise: ::c_int) -> ::c_int;
+    pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int;
+    pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int;
     pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int;
     pub fn utimensat(dirfd: ::c_int, path: *const ::c_char,
                      times: *const ::timespec, flag: ::c_int) -> ::c_int;