diff --git a/.travis.yml b/.travis.yml
index 7f3fb55a385a60a7d488428db969ed2f07bc7c6f..d56112a3380297f4a9f8f6795bbc6cd8aa230440 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,7 +14,9 @@ matrix:
     - name: "Documentation"
       env: TARGET=x86_64-unknown-linux-gnu
       script: sh ci/dox.sh
-      install: true
+      install:
+        - travis_retry rustup component add rust-src
+        - travis_retry cargo install xargo
       stage: tools-and-build-and-tier1
     - name: "Shellcheck"
       install: true
@@ -23,11 +25,24 @@ matrix:
         - shellcheck ci/*.sh
       stage: tools-and-build-and-tier1
     - name: "Style"
-      install: rustup component add rustfmt-preview
+      install: true
       script:
         - rustc ci/style.rs && ./style src
         # Disabled due to rust-lang/rustfmt#3341
-        # - cargo fmt --all -- --check
+        #- |
+        #  if rustup component add rustfmt-preview ; then
+        #      cargo fmt --all -- --check
+        #  fi
+      stage: tools-and-build-and-tier1
+    - name: "Semver Linux"
+      install: travis_retry cargo +nightly install semverver
+      script: sh ci/semver.sh
+      stage: tools-and-build-and-tier1
+    - name: "Semver MacOSX"
+      install: travis_retry cargo +nightly install semverver
+      script: sh ci/semver.sh
+      os: osx
+      osx_image: xcode10
       stage: tools-and-build-and-tier1
 
     # BUILD stable, beta, nightly
@@ -45,7 +60,9 @@ matrix:
       script: sh ci/build.sh
       stage: tools-and-build-and-tier1
       rust: nightly
-      install: true
+      install:
+        - travis_retry rustup component add rust-src
+        - travis_retry cargo install xargo
     - name: "Build Stable Rust"
       script: sh ci/build.sh
       stage: tools-and-build-and-tier1
@@ -189,9 +206,14 @@ matrix:
       stage: tier2
 
   allow_failures:
+      # FIXME: android build bots time out irregularly
+      - env: TARGET=aarch64-linux-android
+      - env: TARGET=arm-linux-androideabi
       # FIXME: https://github.com/rust-lang/libc/issues/1226
       - env: TARGET=asmjs-unknown-emscripten
       - env: TARGET=wasm32-unknown-emscripten
+      - name: "Semver Linux"
+      - name: "Semver MacOSX"
 
 install: travis_retry rustup target add $TARGET
 
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000000000000000000000000000000000000..0e5d0c68b8a80359e3dfe4239219390941add8de
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,66 @@
+# Contributing to `libc`
+
+Welcome! If you are reading this document, it means you are interested in contributing
+to the `libc` crate.
+
+## Adding an API
+
+Want to use an API which currently isn't bound in `libc`? It's quite easy to add
+one!
+
+The internal structure of this crate is designed to minimize the number of
+`#[cfg]` attributes in order to easily be able to add new items which apply
+to all platforms in the future. As a result, the crate is organized
+hierarchically based on platform. Each module has a number of `#[cfg]`'d
+children, but only one is ever actually compiled. Each module then reexports all
+the contents of its children.
+
+This means that for each platform that libc supports, the path from a
+leaf module to the root will contain all bindings for the platform in question.
+Consequently, this indicates where an API should be added! Adding an API at a
+particular level in the hierarchy means that it is supported on all the child
+platforms of that level. For example, when adding a Unix API it should be added
+to `src/unix/mod.rs`, but when adding a Linux-only API it should be added to
+`src/unix/notbsd/linux/mod.rs`.
+
+If you're not 100% sure at what level of the hierarchy an API should be added
+at, fear not! This crate has CI support which tests any binding against all
+platforms supported, so you'll see failures if an API is added at the wrong
+level or has different signatures across platforms.
+
+With that in mind, the steps for adding a new API are:
+
+1. Determine where in the module hierarchy your API should be added.
+2. Add the API.
+3. Send a PR to this repo.
+4. Wait for CI to pass, fixing errors.
+5. Wait for a merge!
+
+### Test before you commit
+
+We have two automated tests running on [Travis](https://travis-ci.org/rust-lang/libc):
+
+1. [`libc-test`](https://github.com/alexcrichton/ctest)
+  - `cd libc-test && cargo test`
+  - Use the `skip_*()` functions in `build.rs` if you really need a workaround.
+2. Style checker
+  - `rustc ci/style.rs && ./style src`
+
+### Releasing your change to crates.io
+
+Now that you've done the amazing job of landing your new API or your new
+platform in this crate, the next step is to get that sweet, sweet usage from
+crates.io! The only next step is to bump the version of libc and then publish
+it. If you'd like to get a release out ASAP you can follow these steps:
+
+1. Update the version number in `Cargo.toml`, you'll just be bumping the patch
+   version number.
+2. Run `cargo update` to regenerate the lockfile to encode your version bump in
+   the lock file. You may pull in some other updated dependencies, that's ok.
+3. Send a PR to this repository. It should [look like this][example], but it'd
+   also be nice to fill out the description with a small rationale for the
+   release (any rationale is ok though!)
+4. Once merged the release will be tagged and published by one of the libc crate
+   maintainers.
+
+[example]: https://github.com/rust-lang/libc/pull/583
diff --git a/Cargo.toml b/Cargo.toml
index d72aa8c97dfcde4857e972d5808d7c046e857398..56a0181cb4857270f78c28be1051512267def5ad 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "libc"
-version = "0.2.48"
+version = "0.2.49"
 authors = ["The Rust Project Developers"]
 license = "MIT OR Apache-2.0"
 readme = "README.md"
diff --git a/README.md b/README.md
index 746bce82e7606aba455e5b91cf62fece06a8d145..a974ccd414c1589ad0d4d54c7e2fc608a2a29669 100644
--- a/README.md
+++ b/README.md
@@ -1,195 +1,103 @@
-libc
-====
+[![Travis-CI Status]][Travis-CI] [![Appveyor Status]][Appveyor] [![Cirrus-CI Status]][Cirrus-CI] [![Latest Version]][crates.io] [![Documentation]][docs.rs] ![License]
 
-Raw FFI bindings to platform libraries like `libc`.
+libc - Raw FFI bindings to platforms' system libraries
+====
 
-[![Build Status](https://travis-ci.org/rust-lang/libc.svg?branch=master)](https://travis-ci.org/rust-lang/libc)
-[![Build status](https://ci.appveyor.com/api/projects/status/github/rust-lang/libc?svg=true)](https://ci.appveyor.com/project/rust-lang-libs/libc)
-[![Build Status](https://api.cirrus-ci.com/github/rust-lang/libc.svg)](https://cirrus-ci.com/github/rust-lang/libc)
-[![Latest version](https://img.shields.io/crates/v/libc.svg)](https://crates.io/crates/libc)
-[![Documentation](https://docs.rs/libc/badge.svg)](https://docs.rs/libc)
-[![License](https://img.shields.io/crates/l/libc.svg)]
+`libc` provides all of the definitions necessary to easily interoperate with C
+code (or "C-like" code) on each of the platforms that Rust supports. This
+includes type definitions (e.g. `c_int`), constants (e.g. `EINVAL`) as well as
+function headers (e.g. `malloc`).
 
-**NOTE:** The minimum supported Rust version is **Rust 1.13.0** . APIs requiring
-newer Rust features are only available on newer Rust versions:
+This crate exports all underlying platform types, functions, and constants under
+the crate root, so all items are accessible as `libc::foo`. The types and values
+of all the exported APIs match the platform that libc is compiled for.
 
-| Feature              | Version |
-|----------------------|---------|
-| `union`              |  1.19.0 |
-| `const mem::size_of` |  1.24.0 |
-| `repr(align)`        |  1.25.0 |
-| `core::ffi::c_void`  |  1.30.0 |
+More detailed information about the design of this library can be found in its
+[associated RFC][rfc].
 
-To use `libc` at its fullest, Rust 1.30.0 is required.
+[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1291-promote-libc.md
 
 ## Usage
 
-First, add the following to your `Cargo.toml`:
+Add the following to your `Cargo.toml`:
 
 ```toml
 [dependencies]
 libc = "0.2"
 ```
 
-Next, add this to your crate root:
+## Features
 
-```rust
-extern crate libc;
-```
+* `use_std`: by default `libc` links to the standard library. Disable this
+  feature remove this dependency and be able to use `libc` in `#![no_std]`
+  crates.
 
-Currently libc by default links to the standard library, but if you would
-instead like to use libc in a `#![no_std]` situation or crate you can request
-this via:
+* `extra_traits`: all `struct`s implemented in `libc` are `Copy` and `Clone`.
+  This feature derives `Debug`, `Eq`, `Hash`, and `PartialEq`.
 
-```toml
-[dependencies]
-libc = { version = "0.2", default-features = false }
-```
+## Rust version support
 
-By default libc uses private fields in structs in order to enforce a certain
-memory alignment on them. These structs can be hard to instantiate outside of
-libc. To make libc use `#[repr(align(x))]`, instead of the private fields,
-activate the *align* feature. This requires Rust 1.25 or newer:
+The minimum supported Rust toolchain version is **Rust 1.13.0** . APIs requiring
+newer Rust features are only available on newer Rust toolchains:
 
-```toml
-[dependencies]
-libc = { version = "0.2", features = ["align"] }
-```
+| Feature              | Version |
+|----------------------|---------|
+| `union`              |  1.19.0 |
+| `const mem::size_of` |  1.24.0 |
+| `repr(align)`        |  1.25.0 |
+| `extra_traits`      |  1.25.0 |
+| `core::ffi::c_void`  |  1.30.0 |
+| `repr(packed(N))` |  1.33.0 |
 
-All structs implemented by the libc crate have the `Copy` and `Clone` traits
-implemented for them. The additional traits of `Debug, `Eq`, `Hash`, and
-`PartialEq` can be enabled with the *extra_traits* feature (requires Rust 1.25
-or newer):
+## Platform support
 
-```toml
-[dependencies]
-libc = { version = "0.2", features = ["extra_traits"] }
-```
+[Platform-specific documentation (master branch)][docs.master].
 
-## What is libc?
+See
+[`ci/build.sh`](https://github.com/rust-lang/libc/blob/master/libc-test/build.rs)
+for the platforms on which `libc` is guaranteed to build for each Rust
+toolchain. The test-matrix at [Travis-CI], [Appveyor], and [Cirrus-CI] show the
+platforms in which `libc` tests are run.
 
-The primary purpose of this crate is to provide all of the definitions necessary
-to easily interoperate with C code (or "C-like" code) on each of the platforms
-that Rust supports. This includes type definitions (e.g. `c_int`), constants
-(e.g. `EINVAL`) as well as function headers (e.g. `malloc`).
+<div class="platform_docs"></div>
 
-This crate does not strive to have any form of compatibility across platforms,
-but rather it is simply a straight binding to the system libraries on the
-platform in question.
+## License
 
-## Public API
+This project is licensed under either of
 
-This crate exports all underlying platform types, functions, and constants under
-the crate root, so all items are accessible as `libc::foo`. The types and values
-of all the exported APIs match the platform that libc is compiled for.
+* [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+  ([LICENSE-APACHE](LICENSE-APACHE))
 
-More detailed information about the design of this library can be found in its
-[associated RFC][rfc].
+* [MIT License](http://opensource.org/licenses/MIT)
+  ([LICENSE-MIT](LICENSE-MIT))
 
-[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1291-promote-libc.md
+at your option.
+
+## Contributing
+
+We welcome all people who want to contribute. Please see the [contributing
+instructions] for more information.
+
+[contributing instructions]: CONTRIBUTING.md
+
+Contributions in any form (issues, pull requests, etc.) to this project
+must adhere to Rust's [Code of Conduct].
+
+[Code of Conduct]: https://www.rust-lang.org/en-US/conduct.html
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in `libc` by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
 
-## Adding an API
-
-Want to use an API which currently isn't bound in `libc`? It's quite easy to add
-one!
-
-The internal structure of this crate is designed to minimize the number of
-`#[cfg]` attributes in order to easily be able to add new items which apply
-to all platforms in the future. As a result, the crate is organized
-hierarchically based on platform. Each module has a number of `#[cfg]`'d
-children, but only one is ever actually compiled. Each module then reexports all
-the contents of its children.
-
-This means that for each platform that libc supports, the path from a
-leaf module to the root will contain all bindings for the platform in question.
-Consequently, this indicates where an API should be added! Adding an API at a
-particular level in the hierarchy means that it is supported on all the child
-platforms of that level. For example, when adding a Unix API it should be added
-to `src/unix/mod.rs`, but when adding a Linux-only API it should be added to
-`src/unix/notbsd/linux/mod.rs`.
-
-If you're not 100% sure at what level of the hierarchy an API should be added
-at, fear not! This crate has CI support which tests any binding against all
-platforms supported, so you'll see failures if an API is added at the wrong
-level or has different signatures across platforms.
-
-With that in mind, the steps for adding a new API are:
-
-1. Determine where in the module hierarchy your API should be added.
-2. Add the API.
-3. Send a PR to this repo.
-4. Wait for CI to pass, fixing errors.
-5. Wait for a merge!
-
-### Test before you commit
-
-We have two automated tests running on [Travis](https://travis-ci.org/rust-lang/libc):
-
-1. [`libc-test`](https://github.com/alexcrichton/ctest)
-  - `cd libc-test && cargo test`
-  - Use the `skip_*()` functions in `build.rs` if you really need a workaround.
-2. Style checker
-  - `rustc ci/style.rs && ./style src`
-
-### Releasing your change to crates.io
-
-Now that you've done the amazing job of landing your new API or your new
-platform in this crate, the next step is to get that sweet, sweet usage from
-crates.io! The only next step is to bump the version of libc and then publish
-it. If you'd like to get a release out ASAP you can follow these steps:
-
-1. Update the version number in `Cargo.toml`, you'll just be bumping the patch
-   version number.
-2. Run `cargo update` to regenerate the lockfile to encode your version bump in
-   the lock file. You may pull in some other updated dependencies, that's ok.
-3. Send a PR to this repository. It should [look like this][example], but it'd
-   also be nice to fill out the description with a small rationale for the
-   release (any rationale is ok though!)
-4. Once merged the release will be tagged and published by one of the libc crate
-   maintainers.
-
-[example]: https://github.com/rust-lang/libc/pull/583
-
-## Platforms and Documentation
-
-The following platforms are currently tested and have documentation available:
-
-Tested:
-  * [`i686-pc-windows-msvc`](https://rust-lang.github.io/libc/i686-pc-windows-msvc/libc/)
-  * [`x86_64-pc-windows-msvc`](https://rust-lang.github.io/libc/x86_64-pc-windows-msvc/libc/)
-    (Windows)
-  * [`i686-pc-windows-gnu`](https://rust-lang.github.io/libc/i686-pc-windows-gnu/libc/)
-  * [`x86_64-pc-windows-gnu`](https://rust-lang.github.io/libc/x86_64-pc-windows-gnu/libc/)
-  * [`i686-apple-darwin`](https://rust-lang.github.io/libc/i686-apple-darwin/libc/)
-  * [`x86_64-apple-darwin`](https://rust-lang.github.io/libc/x86_64-apple-darwin/libc/)
-    (OSX)
-  * `i386-apple-ios`
-  * `x86_64-apple-ios`
-  * [`i686-unknown-linux-gnu`](https://rust-lang.github.io/libc/i686-unknown-linux-gnu/libc/)
-  * [`x86_64-unknown-linux-gnu`](https://rust-lang.github.io/libc/x86_64-unknown-linux-gnu/libc/)
-    (Linux)
-  * [`x86_64-unknown-linux-musl`](https://rust-lang.github.io/libc/x86_64-unknown-linux-musl/libc/)
-    (Linux MUSL)
-  * [`aarch64-unknown-linux-gnu`](https://rust-lang.github.io/libc/aarch64-unknown-linux-gnu/libc/)
-    (Linux)
-  * `aarch64-unknown-linux-musl`
-    (Linux MUSL)
-  * [`sparc64-unknown-linux-gnu`](https://rust-lang.github.io/libc/sparc64-unknown-linux-gnu/libc/)
-    (Linux)
-  * [`mips-unknown-linux-gnu`](https://rust-lang.github.io/libc/mips-unknown-linux-gnu/libc/)
-  * [`arm-unknown-linux-gnueabihf`](https://rust-lang.github.io/libc/arm-unknown-linux-gnueabihf/libc/)
-  * [`arm-linux-androideabi`](https://rust-lang.github.io/libc/arm-linux-androideabi/libc/)
-    (Android)
-  * [`x86_64-unknown-freebsd`](https://rust-lang.github.io/libc/x86_64-unknown-freebsd/libc/)
-  * [`x86_64-unknown-openbsd`](https://rust-lang.github.io/libc/x86_64-unknown-openbsd/libc/)
-  * [`x86_64-rumprun-netbsd`](https://rust-lang.github.io/libc/x86_64-unknown-netbsd/libc/)
-
-The following may be supported, but are not guaranteed to always work:
-
-  * `i686-unknown-freebsd`
-  * [`x86_64-unknown-bitrig`](https://rust-lang.github.io/libc/x86_64-unknown-bitrig/libc/)
-  * [`x86_64-unknown-dragonfly`](https://rust-lang.github.io/libc/x86_64-unknown-dragonfly/libc/)
-  * `i686-unknown-haiku`
-  * `x86_64-unknown-haiku`
-  * [`x86_64-unknown-netbsd`](https://rust-lang.github.io/libc/x86_64-unknown-netbsd/libc/)
-  * [`x86_64-sun-solaris`](https://rust-lang.github.io/libc/x86_64-sun-solaris/libc/)
+[Travis-CI]: https://travis-ci.com/rust-lang/libc
+[Travis-CI Status]: https://travis-ci.com/rust-lang/libc.svg?branch=master
+[Appveyor]: https://ci.appveyor.com/project/rust-lang-libs/libc
+[Appveyor Status]: https://ci.appveyor.com/api/projects/status/github/rust-lang/libc?svg=true
+[Cirrus-CI]: https://cirrus-ci.com/github/rust-lang/libc
+[Cirrus-CI Status]: https://api.cirrus-ci.com/github/rust-lang/libc.svg
+[crates.io]: https://crates.io/crates/libc
+[Latest Version]: https://img.shields.io/crates/v/libc.svg
+[Documentation]: https://docs.rs/libc/badge.svg
+[docs.rs]: https://docs.rs/libc
+[License]: https://img.shields.io/crates/l/libc.svg
+[docs.master]: https://rust-lang.github.io/libc/#platform-specific-documentation
diff --git a/appveyor.yml b/appveyor.yml
index 9fd4b26f0ab608dfb67422736f0f179639ff8366..b14230a0555f35c4608632cb8c853f30920f9381 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -23,6 +23,6 @@ install:
 build: false
 
 test_script:
-  - cargo test --target %TARGET%
-  - cargo test --no-default-features --target %TARGET%
-  - cargo test --manifest-path libc-test/Cargo.toml --target %TARGET%
+  - cargo -vv test --target %TARGET%
+  - cargo -vv test --no-default-features --target %TARGET%
+  - cargo -vv test --manifest-path libc-test/Cargo.toml --target %TARGET%
diff --git a/ci/build.sh b/ci/build.sh
index 69805fcbc281d5875ef4a371774fb924f0198303..74727a3313a1f2ec553b355d19ed44c85b4e60c4 100644
--- a/ci/build.sh
+++ b/ci/build.sh
@@ -11,7 +11,9 @@ OS=${TRAVIS_OS_NAME}
 echo "Testing Rust ${RUST} on ${OS}"
 
 test_target() {
-    TARGET="${1}"
+    CARGO="${1}"
+    TARGET="${2}"
+    NO_STD="${3}"
 
     opt=
     if [ "${TARGET}" = "x86_64-unknown-linux-gnux32" ]; then
@@ -22,31 +24,38 @@ test_target() {
         opt="--release"
     fi
 
-    NO_STD=
-    case ${TARGET} in
-        thumbv*)
-            NO_STD=1
-            ;;
-    esac
-
-    rustup target add "${TARGET}" --toolchain "${RUST}" || true
+    # If there is a std component, fetch it:
+    if [ "${NO_STD}" != "1" ]; then
+        # FIXME: rustup often fails to download some artifacts due to network
+        # issues, so we retry this N times.
+        N=5
+        n=0
+        until [ $n -ge $N ]
+        do
+            if rustup target add "${TARGET}" --toolchain "${RUST}" ; then
+                break
+            fi
+            n=$((n+1))
+            sleep 1
+        done
+    fi
 
     # Test that libc builds without any default features (no libstd)
-    cargo "+${RUST}" build -vv $opt --no-default-features --target "${TARGET}"
+    "$CARGO" "+${RUST}" build -vv $opt --no-default-features --target "${TARGET}"
 
     # Test that libc builds with default features (e.g. libstd)
     # if the target supports libstd
     if [ "$NO_STD" != "1" ]; then
-        cargo "+${RUST}" build -vv $opt --target "${TARGET}"
+        "$CARGO" "+${RUST}" build -vv $opt --target "${TARGET}"
     fi
 
     # Test that libc builds with the `extra_traits` feature
-    cargo "+${RUST}" build -vv $opt --no-default-features --target "${TARGET}" \
+    "$CARGO" "+${RUST}" build -vv $opt --no-default-features --target "${TARGET}" \
           --features extra_traits
 
     # Also test that it builds with `extra_traits` and default features:
     if [ "$NO_STD" != "1" ]; then
-        cargo "+${RUST}" build -vv $opt --target "${TARGET}" \
+        "$CARGO" "+${RUST}" build -vv $opt --target "${TARGET}" \
               --features extra_traits
     fi
 }
@@ -103,24 +112,15 @@ x86_64-unknown-cloudabi \
 
 RUST_NIGHTLY_LINUX_TARGETS="\
 aarch64-fuchsia \
-thumbv6m-none-eabi \
-thumbv7em-none-eabi \
-thumbv7em-none-eabihf \
-thumbv7m-none-eabi \
-thumbv7neon-linux-androideabi \
-thumbv7neon-unknown-linux-gnueabihf \
+armv5te-unknown-linux-gnueabi \
+armv5te-unknown-linux-musleabi \
+i686-pc-windows-gnu \
 x86_64-fortanix-unknown-sgx \
 x86_64-fuchsia \
+x86_64-pc-windows-gnu \
 x86_64-unknown-linux-gnux32 \
 x86_64-unknown-redox \
 "
-# FIXME: these do not have a rust-std component available
-# aarch64-unknown-cloudabi armv7-unknown-cloudabi-eabihf
-# i686-unknown-cloudabi powerpc-unknown-linux-gnuspe
-# sparc-unknown-linux-gnu mips-unknown-linux-uclib
-# i686-unknown-haiku mipsel-unknown-unknown-linux-uclib
-# sparc64-unknown-netbsd x86_64-unknown-bitrig x86_64-unknown-haiku
-# x86_64-unknown-openbsd i686-unknown-netbsd
 
 RUST_OSX_TARGETS="\
 aarch64-apple-ios \
@@ -161,5 +161,45 @@ case "${OS}" in
 esac
 
 for TARGET in $TARGETS; do
-    test_target "$TARGET"
+    test_target cargo "$TARGET"
 done
+
+# FIXME: https://github.com/rust-lang/rust/issues/58564
+# sparc-unknown-linux-gnu
+RUST_LINUX_NO_CORE_TARGETS="\
+x86_64-unknown-dragonfly \
+aarch64-pc-windows-msvc \
+aarch64-unknown-cloudabi \
+armebv7r-none-eabi \
+armebv7r-none-eabihf \
+armv7-unknown-cloudabi-eabihf \
+armv7r-none-eabi \
+armv7r-none-eabihf \
+i586-pc-windows-msvc \
+i686-pc-windows-msvc \
+i686-unknown-cloudabi \
+i686-unknown-haiku \
+i686-unknown-netbsd \
+nvptx64-nvidia-cuda \
+powerpc-unknown-linux-gnuspe \
+riscv32imac-unknown-none-elf \
+riscv32imc-unknown-none-elf \
+sparc64-unknown-netbsd \
+thumbv6m-none-eabi \
+thumbv7em-none-eabi \
+thumbv7em-none-eabihf \
+thumbv7m-none-eabi \
+thumbv7neon-linux-androideabi \
+thumbv7neon-unknown-linux-gnueabihf \
+thumbv8m.main-none-eabi \
+x86_64-pc-windows-msvc
+x86_64-unknown-bitrig \
+x86_64-unknown-haiku \
+x86_64-unknown-openbsd
+"
+
+if [ "${RUST}" = "nightly" ] && [ "${OS}" = "linux" ]; then
+    for TARGET in $RUST_LINUX_NO_CORE_TARGETS; do
+        test_target xargo "$TARGET" 1
+    done
+fi
diff --git a/ci/dox.sh b/ci/dox.sh
index 521743e39946bca5a4a18b3eee1c3be043c5b91f..ce5508147647cdae5e590a06d35233ddba0ebb60 100644
--- a/ci/dox.sh
+++ b/ci/dox.sh
@@ -6,28 +6,65 @@
 
 set -ex
 
-TARGETS=$(grep html_root_url src/lib.rs | sed 's/.*".*\/\(.*\)"/\1/'| sed 's/)//')
+TARGET_DOC_DIR=target/doc
+README=README.md
+PLATFORM_SUPPORT=platform-support.md
 
-rm -rf target/doc
-mkdir -p target/doc
+rm -rf $TARGET_DOC_DIR
+mkdir -p $TARGET_DOC_DIR
 
-cp ci/landing-page-head.html target/doc/index.html
+# List all targets that do currently build successfully:
+# shellcheck disable=SC1003
+grep '[\d|\w|-]* \\' ci/build.sh > targets
+sed -i.bak 's/ \\//g' targets
+grep '^[_a-zA-Z0-9-]*$' targets > tmp && mv tmp targets
 
-for target in $TARGETS; do
-  echo "documenting ${target}"
+# Create a markdown list of supported platforms in $PLATFORM_SUPPORT
+rm $PLATFORM_SUPPORT || true
 
-  rustdoc -o "target/doc/${target}" --target "${target}" src/lib.rs --cfg cross_platform_docs \
-    --crate-name libc
+printf '### Platform-specific documentation\n' >> $PLATFORM_SUPPORT
 
-  echo "<li><a href=\"/libc/${target}/libc/index.html\">${target}</a></li>" \
-    >> target/doc/index.html
-done
+while read -r target; do
+    echo "documenting ${target}"
 
-cat ci/landing-page-footer.html >> target/doc/index.html
+    case "${target}" in
+        *apple*)
+            # FIXME:
+            # We can't build docs of apple targets from Linux yet.
+            continue
+            ;;
+        *)
+            ;;
+    esac
+
+    rustup target add "${target}" || true
+
+    # If cargo doc fails, then try xargo:
+    if ! cargo doc --target "${target}" \
+             --no-default-features  --features extra_traits ; then
+        xargo doc --target "${target}" \
+              --no-default-features  --features extra_traits
+    fi
+
+    cp -r "target/${target}/doc" "${TARGET_DOC_DIR}/${target}"
+
+    echo "* [${target}](${target}/libc/index.html)" >> $PLATFORM_SUPPORT
+done < targets
+
+# Replace <div class="platform_support"></div> with the contents of $PLATFORM_SUPPORT
+cp $README $TARGET_DOC_DIR
+line=$(grep -n '<div class="platform_docs"></div>' $README | cut -d ":" -f 1)
+
+set +x
+{ head -n "$((line-1))" $README; cat $PLATFORM_SUPPORT; tail -n "+$((line+1))" $README; } > $TARGET_DOC_DIR/$README
+set -x
+
+# Copy the licenses
+cp LICENSE-* $TARGET_DOC_DIR/
 
 # If we're on travis, not a PR, and on the right branch, publish!
 if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_BRANCH" = "master" ]; then
   pip install ghp_import --install-option="--prefix=$HOME/.local"
-  "${HOME}/.local/bin/ghp-import" -n target/doc
+  "${HOME}/.local/bin/ghp-import" $TARGET_DOC_DIR
   git push -qf "https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git" gh-pages
 fi
diff --git a/ci/landing-page-footer.html b/ci/landing-page-footer.html
deleted file mode 100644
index 941cc8d2b40307cc0a5911984505cf6b48cd82aa..0000000000000000000000000000000000000000
--- a/ci/landing-page-footer.html
+++ /dev/null
@@ -1,3 +0,0 @@
-    </ul>
-  </body>
-</html>
diff --git a/ci/landing-page-head.html b/ci/landing-page-head.html
deleted file mode 100644
index fc69fa88eb5ce6fc8724ac195827278df5cdcdbd..0000000000000000000000000000000000000000
--- a/ci/landing-page-head.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-  </head>
-  <body>
-    <ul>
diff --git a/ci/runtest-android.rs b/ci/runtest-android.rs
index 18d39bfdfe89c06d5033f5bd9f46c3189d890326..b8030c41a7f6fde9803bc99d1dda9947d6e1dbb8 100644
--- a/ci/runtest-android.rs
+++ b/ci/runtest-android.rs
@@ -38,7 +38,7 @@ fn main() {
              String::from_utf8_lossy(&output.stderr));
 
     let stdout = String::from_utf8_lossy(&output.stdout);
-    let passed = stdout.lines().find(|l|
+    stdout.lines().find(|l|
         (l.starts_with("PASSED ") && l.contains(" tests")) ||
         l.starts_with("test result: ok")
     ).unwrap_or_else(|| {
diff --git a/ci/semver.sh b/ci/semver.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ac6be36f3f18e46fec078bef94e539dafd2daa29
--- /dev/null
+++ b/ci/semver.sh
@@ -0,0 +1,70 @@
+#!/usr/bin/env sh
+
+# Checks that libc does not contain breaking changes for the following targets.
+
+set -ex
+
+OS=${TRAVIS_OS_NAME}
+
+echo "Testing Semver on ${OS}"
+
+TARGETS=
+case "${OS}" in
+    *linux*)
+        TARGETS="\
+aarch64-fuchsia \
+aarch64-linux-android \
+aarch64-unknown-linux-gnu \
+aarch64-unknown-linux-musl \
+armv7-linux-androideabi \
+armv7-unknown-linux-gnueabihf \
+i586-unknown-linux-gnu \
+i586-unknown-linux-musl \
+i686-linux-android \
+i686-unknown-freebsd \
+i686-unknown-linux-gnu \
+i686-unknown-linux-musl \
+i686-pc-windows-gnu \
+x86_64-unknown-freebsd \
+x86_64-unknown-linux-gnu \
+x86_64-unknown-linux-musl \
+x86_64-unknown-netbsd \
+x86_64-unknown-cloudabi \
+x86_64-sun-solaris \
+x86_64-fuchsia \
+x86_64-pc-windows-gnu \
+x86_64-unknown-linux-gnux32 \
+x86_64-unknown-redox \
+x86_64-fortanix-unknown-sgx \
+wasm32-unknown-unknown \
+"
+    ;;
+    *osx*)
+        TARGETS="\
+aarch64-apple-ios \
+armv7-apple-ios \
+armv7s-apple-ios \
+i386-apple-ios \
+i686-apple-darwin \
+x86_64-apple-darwin \
+x86_64-apple-ios \
+"
+    ;;
+esac
+
+for TARGET in $TARGETS; do
+    # FIXME: rustup often fails to download some artifacts due to network
+    # issues, so we retry this N times.
+    N=5
+    n=0
+    until [ $n -ge $N ]
+    do
+        if rustup target add "${TARGET}" ; then
+            break
+        fi
+        n=$((n+1))
+        sleep 1
+    done
+
+    cargo +nightly semver --api-guidelines --target="${TARGET}"
+done
diff --git a/libc-test/Cargo.toml b/libc-test/Cargo.toml
index 7eecc4994cabe7427545704b487a1c66472cf1cc..9862d3a569534fdba61e4d06622cfe39048c8141 100644
--- a/libc-test/Cargo.toml
+++ b/libc-test/Cargo.toml
@@ -10,7 +10,7 @@ default-features = false
 
 [build-dependencies]
 cc = "1.0"
-ctest = "0.2.8"
+ctest = "0.2"
 
 [features]
 default = [ "use_std" ]
diff --git a/libc-test/build.rs b/libc-test/build.rs
index e0bd795bb0e52ff0f9d4e51b7a3ed0bab61220e3..89ca488a9440591f1ce3f0c193468fb0866bd76b 100644
--- a/libc-test/build.rs
+++ b/libc-test/build.rs
@@ -18,40 +18,32 @@ fn do_ctest() {
     let i686 = target.contains("i686");
     let x86_64 = target.contains("x86_64");
     let x32 = target.ends_with("gnux32");
-    let windows = target.contains("windows");
-    let mingw = target.contains("windows-gnu");
     let linux = target.contains("unknown-linux");
     let android = target.contains("android");
-    let apple = target.contains("apple");
-    let ios = target.contains("apple-ios");
     let emscripten = target.contains("asm");
     let musl = target.contains("musl") || emscripten;
     let uclibc = target.contains("uclibc");
     let freebsd = target.contains("freebsd");
-    let dragonfly = target.contains("dragonfly");
     let mips = target.contains("mips");
-    let netbsd = target.contains("netbsd");
     let openbsd = target.contains("openbsd");
-    let rumprun = target.contains("rumprun");
-    let solaris = target.contains("solaris");
-    let cloudabi = target.contains("cloudabi");
-    let redox = target.contains("redox");
-    let bsdlike = freebsd || apple || netbsd || openbsd || dragonfly;
+    let bsdlike = freebsd || openbsd;
     let mut cfg = ctest::TestGenerator::new();
 
+    match &target {
+        t if t.contains("apple") => return test_apple(t),
+        t if t.contains("openbsd") => return test_openbsd(t),
+        t if t.contains("windows") => return test_windows(t),
+        t if t.contains("redox") => return test_redox(t),
+        t if t.contains("cloudabi") => return test_cloudabi(t),
+        t if t.contains("solaris") => return test_solaris(t),
+        t if t.contains("netbsd") => return test_netbsd(t),
+        t if t.contains("dragonfly") => return test_dragonflybsd(t),
+        _ => (),
+    }
+
     // Pull in extra goodies
     if linux || android || emscripten {
         cfg.define("_GNU_SOURCE", None);
-    } else if netbsd {
-        cfg.define("_NETBSD_SOURCE", Some("1"));
-    } else if apple {
-        cfg.define("__APPLE_USE_RFC_3542", None);
-    } else if windows {
-        cfg.define("_WIN32_WINNT", Some("0x8000"));
-    } else if solaris {
-        cfg.define("_XOPEN_SOURCE", Some("700"));
-        cfg.define("__EXTENSIONS__", None);
-        cfg.define("_LCONV_C99", None);
     } else if freebsd {
         cfg.define("_WITH_GETLINE", None);
     }
@@ -75,73 +67,53 @@ fn do_ctest() {
         .header("time.h")
         .header("wchar.h");
 
-    if windows {
-        cfg.header("winsock2.h"); // must be before windows.h
-
-        cfg.header("direct.h");
-        cfg.header("io.h");
-        cfg.header("sys/utime.h");
-        cfg.header("windows.h");
-        cfg.header("process.h");
-        cfg.header("ws2ipdef.h");
-        cfg.header("signal.h");
+    cfg.flag("-Wno-deprecated-declarations");
 
-        if target.contains("gnu") {
-            cfg.header("ws2tcpip.h");
-        }
-    } else {
-        cfg.flag("-Wno-deprecated-declarations");
-
-        cfg.header("ctype.h");
-        cfg.header("dirent.h");
-        if openbsd {
-            cfg.header("sys/socket.h");
-        }
-        cfg.header("net/if.h");
-        if !ios {
-            cfg.header("net/route.h");
-            cfg.header("net/if_arp.h");
-        }
-        cfg.header("netdb.h");
-        cfg.header("netinet/in.h");
-        cfg.header("netinet/ip.h");
-        cfg.header("netinet/tcp.h");
-        cfg.header("netinet/udp.h");
-        cfg.header("resolv.h");
-        cfg.header("pthread.h");
-        cfg.header("dlfcn.h");
-        cfg.header("signal.h");
-        cfg.header("string.h");
-        cfg.header("sys/file.h");
-        cfg.header("sys/ioctl.h");
-        cfg.header("sys/mman.h");
-        cfg.header("sys/resource.h");
-        cfg.header("sys/socket.h");
-        if linux && !musl {
-            cfg.header("linux/if.h");
-            cfg.header("sys/auxv.h");
-        }
-        cfg.header("sys/time.h");
-        cfg.header("sys/un.h");
-        cfg.header("sys/wait.h");
-        cfg.header("unistd.h");
-        cfg.header("utime.h");
-        cfg.header("pwd.h");
-        cfg.header("grp.h");
-        cfg.header("sys/utsname.h");
-        if !solaris && !ios {
-            cfg.header("sys/ptrace.h");
-        }
-        cfg.header("sys/mount.h");
-        cfg.header("sys/uio.h");
-        cfg.header("sched.h");
-        cfg.header("termios.h");
-        cfg.header("poll.h");
-        cfg.header("syslog.h");
-        cfg.header("semaphore.h");
-        cfg.header("sys/statvfs.h");
-        cfg.header("sys/times.h");
+    cfg.header("ctype.h");
+    cfg.header("dirent.h");
+    cfg.header("net/if.h");
+    cfg.header("net/route.h");
+    cfg.header("net/if_arp.h");
+    if linux || android {
+        cfg.header("linux/if_alg.h");
+    }
+    cfg.header("netdb.h");
+    cfg.header("netinet/in.h");
+    cfg.header("netinet/ip.h");
+    cfg.header("netinet/tcp.h");
+    cfg.header("netinet/udp.h");
+    cfg.header("resolv.h");
+    cfg.header("pthread.h");
+    cfg.header("dlfcn.h");
+    cfg.header("signal.h");
+    cfg.header("string.h");
+    cfg.header("sys/file.h");
+    cfg.header("sys/ioctl.h");
+    cfg.header("sys/mman.h");
+    cfg.header("sys/resource.h");
+    cfg.header("sys/socket.h");
+    if linux && !musl {
+        cfg.header("linux/if.h");
+        cfg.header("sys/auxv.h");
     }
+    cfg.header("sys/time.h");
+    cfg.header("sys/un.h");
+    cfg.header("sys/wait.h");
+    cfg.header("unistd.h");
+    cfg.header("utime.h");
+    cfg.header("pwd.h");
+    cfg.header("grp.h");
+    cfg.header("sys/utsname.h");
+    cfg.header("sys/ptrace.h");
+    cfg.header("sys/mount.h");
+    cfg.header("sys/uio.h");
+    cfg.header("sched.h");
+    cfg.header("termios.h");
+    cfg.header("poll.h");
+    cfg.header("syslog.h");
+    cfg.header("semaphore.h");
+    cfg.header("sys/statvfs.h");
+    cfg.header("sys/times.h");
 
     if android {
         if !aarch64 && !x86_64 {
@@ -156,21 +128,21 @@ fn do_ctest() {
         if i686 || x86_64 {
             cfg.header("sys/reg.h");
         }
-    } else if !windows {
+    } else {
         cfg.header("glob.h");
         cfg.header("ifaddrs.h");
         cfg.header("langinfo.h");
 
-        if !openbsd && !freebsd && !dragonfly && !solaris {
+        if !openbsd && !freebsd {
             cfg.header("sys/quota.h");
         }
 
-        if !musl && !x32 && !solaris {
+        if !musl && !x32 {
             cfg.header("sys/sysctl.h");
         }
 
         if !musl && !uclibc {
-            if !netbsd && !openbsd && !uclibc {
+            if !openbsd && !uclibc {
                 cfg.header("execinfo.h");
             }
 
@@ -182,33 +154,6 @@ fn do_ctest() {
         }
     }
 
-    if apple {
-        cfg.header("spawn.h");
-        cfg.header("mach-o/dyld.h");
-        cfg.header("mach/mach_time.h");
-        cfg.header("malloc/malloc.h");
-        cfg.header("util.h");
-        cfg.header("xlocale.h");
-        cfg.header("sys/xattr.h");
-        if target.starts_with("x86") && !ios {
-            cfg.header("crt_externs.h");
-        }
-        cfg.header("netinet/in.h");
-        cfg.header("sys/ipc.h");
-        cfg.header("sys/sem.h");
-        cfg.header("sys/shm.h");
-
-        if !ios {
-            cfg.header("sys/sys_domain.h");
-            cfg.header("net/if_utun.h");
-            cfg.header("net/bpf.h");
-            cfg.header("net/route.h");
-            cfg.header("netinet/if_ether.h");
-            cfg.header("sys/proc_info.h");
-            cfg.header("sys/kern_control.h");
-        }
-    }
-
     if bsdlike {
         cfg.header("sys/event.h");
         cfg.header("net/if_dl.h");
@@ -285,9 +230,6 @@ fn do_ctest() {
             }
         }
     }
-    if solaris {
-        cfg.header("sys/epoll.h");
-    }
 
     if linux || android {
         cfg.header("sys/fsuid.h");
@@ -330,47 +272,18 @@ fn do_ctest() {
         cfg.header("spawn.h");
     }
 
-    if netbsd {
-        cfg.header("mqueue.h");
-        cfg.header("ufs/ufs/quota.h");
-        cfg.header("ufs/ufs/quota1.h");
-        cfg.header("sys/extattr.h");
-        cfg.header("sys/ioctl_compat.h");
-
-        // DCCP support
-        cfg.header("netinet/dccp.h");
-    }
-
     if openbsd {
         cfg.header("ufs/ufs/quota.h");
         cfg.header("pthread_np.h");
         cfg.header("sys/syscall.h");
     }
 
-    if dragonfly {
-        cfg.header("mqueue.h");
-        cfg.header("ufs/ufs/quota.h");
-        cfg.header("pthread_np.h");
-        cfg.header("sys/rtprio.h");
-    }
-
-    if solaris {
-        cfg.header("port.h");
-        cfg.header("ucontext.h");
-        cfg.header("sys/filio.h");
-        cfg.header("sys/loadavg.h");
-    }
-
-    if linux || freebsd || dragonfly || netbsd || apple || emscripten {
+    if linux || freebsd || emscripten {
         if !uclibc {
             cfg.header("aio.h");
         }
     }
 
-    if cloudabi || redox {
-        cfg.header("strings.h");
-    }
-
     cfg.type_name(move |ty, is_struct, is_union| {
         match ty {
             // Just pass all these through, no need for a "struct" prefix
@@ -379,12 +292,6 @@ fn do_ctest() {
             | "Elf64_Sym" | "Elf32_Ehdr" | "Elf64_Ehdr" | "Elf32_Chdr"
             | "Elf64_Chdr" => ty.to_string(),
 
-            // Fixup a few types on windows that don't actually exist.
-            "time64_t" if windows => "__time64_t".to_string(),
-            "ssize_t" if windows => "SSIZE_T".to_string(),
-            // windows
-            "sighandler_t" if windows && !mingw => "_crt_signal_t".to_string(),
-            "sighandler_t" if windows && mingw => "__p_sig_fn_t".to_string(),
             // OSX calls this something else
             "sighandler_t" if bsdlike => "sig_t".to_string(),
 
@@ -392,20 +299,8 @@ fn do_ctest() {
 
             t if t.ends_with("_t") => t.to_string(),
 
-            // Windows uppercase structs don't have `struct` in front, there's a
-            // few special cases for windows, and then otherwise put `struct` in
-            // front of everything.
-            t if is_struct => {
-                if windows && ty.chars().next().unwrap().is_uppercase() {
-                    t.to_string()
-                } else if windows && t == "stat" {
-                    "struct __stat64".to_string()
-                } else if windows && t == "utimbuf" {
-                    "struct __utimbuf64".to_string()
-                } else {
-                    format!("struct {}", t)
-                }
-            }
+            // put `struct` in front of all structs:.
+            t if is_struct => format!("struct {}", t),
 
             t => t.to_string(),
         }
@@ -423,9 +318,7 @@ fn do_ctest() {
             // Our stat *_nsec fields normally don't actually exist but are part
             // of a timeval struct
             s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
-                if target2.contains("apple") {
-                    s.replace("_nsec", "spec.tv_nsec")
-                } else if target2.contains("android") {
+                if target2.contains("android") {
                     s.to_string()
                 } else {
                     s.replace("e_nsec", ".tv_nsec")
@@ -433,7 +326,7 @@ fn do_ctest() {
             }
             "u64" if struct_ == "epoll_event" => "data.u64".to_string(),
             "type_"
-                if (linux || freebsd || dragonfly)
+                if (linux || freebsd)
                     && (struct_ == "input_event"
                         || struct_ == "input_mask"
                         || struct_ == "ff_effect"
@@ -463,11 +356,6 @@ fn do_ctest() {
             // which is absent in glibc, has to be defined.
             "__timeval" if linux => true,
 
-            // Fixed on feature=align with repr(packed(4))
-            // Once repr_packed stabilizes we can fix this unconditionally
-            // and remove this check.
-            "kevent" | "shmid_ds" | "semid_ds" if apple && x86_64 => true,
-
             // This is actually a union, not a struct
             "sigval" => true,
 
@@ -484,58 +372,25 @@ fn do_ctest() {
             // header conflicts when including them with all the other structs.
             "termios2" => true,
 
-            // Present on historical versions of iOS but missing in more recent
-            // SDKs
-            "bpf_hdr" | "proc_taskinfo" | "proc_taskallinfo"
-            | "proc_bsdinfo" | "proc_threadinfo" | "sockaddr_inarp"
-            | "sockaddr_ctl" | "arphdr"
-                if ios =>
-            {
-                true
-            }
-
             _ => false,
         }
     });
 
     cfg.skip_signededness(move |c| {
         match c {
-            "LARGE_INTEGER"
-            | "mach_timebase_info_data_t"
-            | "float"
-            | "double" => true,
-            // uuid_t is a struct, not an integer.
-            "uuid_t" if dragonfly => true,
+            "LARGE_INTEGER" | "float" | "double" => true,
             n if n.starts_with("pthread") => true,
             // sem_t is a struct or pointer
-            "sem_t" if openbsd || freebsd || dragonfly || netbsd => true,
-            // mqd_t is a pointer on FreeBSD and DragonFly
-            "mqd_t" if freebsd || dragonfly => true,
-
-            // Just some typedefs on osx, no need to check their sign
-            "posix_spawnattr_t" | "posix_spawn_file_actions_t" => true,
+            "sem_t" if openbsd || freebsd => true,
+            // mqd_t is a pointer on FreeBSD
+            "mqd_t" if freebsd => true,
 
-            // windows-isms
-            n if n.starts_with("P") => true,
-            n if n.starts_with("H") => true,
-            n if n.starts_with("LP") => true,
-            "__p_sig_fn_t" if mingw => true,
             _ => false,
         }
     });
 
     cfg.skip_const(move |name| {
         match name {
-            // Apparently these don't exist in mingw headers?
-            "MEM_RESET_UNDO"
-            | "FILE_ATTRIBUTE_NO_SCRUB_DATA"
-            | "FILE_ATTRIBUTE_INTEGRITY_STREAM"
-            | "ERROR_NOTHING_TO_TERMINATE"
-                if mingw =>
-            {
-                true
-            }
-
             "SIG_DFL" | "SIG_ERR" | "SIG_IGN" => true, // sighandler_t weirdness
             "SIGUNUSED" => true,                       // removed in glibc 2.26
 
@@ -559,9 +414,6 @@ fn do_ctest() {
             "MS_NOUSER" => true,
             "MS_RMT_MASK" => true, // updated in glibc 2.22 and musl 1.1.13
 
-            // These OSX constants are flagged as deprecated
-            "NOTE_EXIT_REPARENTED" | "NOTE_REAP" if apple => true,
-
             // These constants were removed in FreeBSD 11 (svn r273250) but will
             // still be accepted and ignored at runtime.
             "MAP_RENAME" | "MAP_NORESERVE" if freebsd => true,
@@ -587,11 +439,6 @@ fn do_ctest() {
             // These constants were added in FreeBSD 12
             "SF_USER_READAHEAD" | "SO_REUSEPORT_LB" if freebsd => true,
 
-            // These OSX constants are removed in Sierra.
-            // https://developer.apple.com/library/content/releasenotes/General/APIDiffsMacOS10_12/Swift/Darwin.html
-            "KERN_KDENABLE_BG_TRACE" if apple => true,
-            "KERN_KDDISABLE_BG_TRACE" if apple => true,
-
             // These constants were removed in OpenBSD 6 (https://git.io/v7gBO
             // https://git.io/v7gBq)
             "KERN_USERMOUNT" | "KERN_ARND" if openbsd => true,
@@ -627,6 +474,9 @@ fn do_ctest() {
             | "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
@@ -674,16 +524,8 @@ fn do_ctest() {
                 true
             }
 
-            "DT_FIFO" | "DT_CHR" | "DT_DIR" | "DT_BLK" | "DT_REG"
-            | "DT_LNK" | "DT_SOCK"
-                if solaris =>
-            {
-                true
-            }
-            "USRQUOTA" | "GRPQUOTA" if solaris => true,
-            "PRIO_MIN" | "PRIO_MAX" if solaris => true,
-
-            // These are defined for Solaris 11, but the crate is tested on illumos, where they are currently not defined
+            // These are defined for Solaris 11, but the crate is tested on
+            // illumos, where they are currently not defined
             "EADI"
             | "PORT_SOURCE_POSTWAIT"
             | "PORT_SOURCE_SIGNAL"
@@ -695,35 +537,28 @@ fn do_ctest() {
             "AF_MAX" | "PF_MAX" => true,
 
             // These are not in a glibc release yet, only in kernel headers.
-            "AF_XDP" | "PF_XDP" | "SOL_XDP" if linux => true,
-
-            // Present on historical versions of iOS, but now removed in more
-            // recent SDKs
-            "ARPOP_REQUEST"
-            | "ARPOP_REPLY"
-            | "ATF_COM"
-            | "ATF_PERM"
-            | "ATF_PUBL"
-            | "ATF_USETRAILERS"
-            | "AF_SYS_CONTROL"
-            | "SYSPROTO_EVENT"
-            | "PROC_PIDTASKALLINFO"
-            | "PROC_PIDTASKINFO"
-            | "PROC_PIDTHREADINFO"
-            | "UTUN_OPT_FLAGS"
-            | "UTUN_OPT_IFNAME"
-            | "BPF_ALIGNMENT"
-            | "SYSPROTO_CONTROL"
-                if ios =>
+            "AF_XDP"
+            | "PF_XDP"
+            | "SOL_XDP"
+            | "IPV6_FLOWINFO"
+            | "IPV6_FLOWLABEL_MGR"
+            | "IPV6_FLOWINFO_SEND"
+            | "IPV6_FLOWINFO_FLOWLABEL"
+            | "IPV6_FLOWINFO_PRIORITY"
+                if linux =>
+            {
+                true
+            }
+
+            | "IP_ORIGDSTADDR"
+            | "IP_RECVORIGDSTADDR"
+            | "IPV6_ORIGDSTADDR"
+            | "IPV6_RECVORIGDSTADDR"
+                if freebsd =>
             {
+                // FreeBSD 12 required, but CI has FreeBSD 11.
                 true
             }
-            s if ios && s.starts_with("RTF_") => true,
-            s if ios && s.starts_with("RTM_") => true,
-            s if ios && s.starts_with("RTA_") => true,
-            s if ios && s.starts_with("RTAX_") => true,
-            s if ios && s.starts_with("RTV_") => true,
-            s if ios && s.starts_with("DLT_") => true,
 
             _ => false,
         }
@@ -749,45 +584,13 @@ fn do_ctest() {
             "sendmmsg" | "recvmmsg" if musl => true,
 
             // typed 2nd arg on linux and android
-            "gettimeofday" if linux || android || freebsd || openbsd || dragonfly => true,
+            "gettimeofday" if linux || android || freebsd || openbsd => true,
 
             // not declared in newer android toolchains
             "getdtablesize" if android => true,
 
             "dlerror" if android => true, // const-ness is added
-            "dladdr" if musl || solaris => true, // const-ness only added recently
-
-            // OSX has 'struct tm *const' which we can't actually represent in
-            // Rust, but is close enough to *mut
-            "timegm" if apple => true,
-
-            // OSX's daemon is deprecated in 10.5 so we'll get a warning (which
-            // we turn into an error) so just ignore it.
-            "daemon" if apple => true,
-
-            // Deprecated on OSX
-            "sem_destroy" if apple => true,
-            "sem_init" if apple => true,
-
-            // These functions presumably exist on netbsd but don't look like
-            // they're implemented on rumprun yet, just let them slide for now.
-            // Some of them look like they have headers but then don't have
-            // corresponding actual definitions either...
-            "shm_open" |
-            "shm_unlink" |
-            "syscall" |
-            "mq_open" |
-            "mq_close" |
-            "mq_getattr" |
-            "mq_notify" |
-            "mq_receive" |
-            "mq_send" |
-            "mq_setattr" |
-            "mq_timedreceive" |
-            "mq_timedsend" |
-            "mq_unlink" |
-            "ptrace" |
-            "sigaltstack" if rumprun => true,
+            "dladdr" if musl => true, // const-ness only added recently
 
             // There seems to be a small error in EGLIBC's eventfd.h header. The
             // [underlying system call][1] always takes its first `count`
@@ -825,7 +628,6 @@ fn do_ctest() {
             // it's in a header file?
             "endpwent" if android => 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
@@ -840,37 +642,16 @@ fn do_ctest() {
             // https://mail.gnome.org/archives/commits-list/2013-May/msg01329.html
             "res_init" if android => true,
 
-            // On macOS and iOS, res_init is available, but requires linking with libresolv:
-            // http://blog.achernya.com/2013/03/os-x-has-silly-libsystem.html
-            // See discussion for skipping here:
-            // https://github.com/rust-lang/libc/pull/585#discussion_r114561460
-            "res_init" if apple => true,
-
-            // On Mac we don't use the default `close()`, instead using their $NOCANCEL variants.
-            "close" if apple => 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" |
-            "setpriority" | "personality" if android || solaris => true,
+            "setpriority" | "personality" if android  => true,
             // In Android 64 bits, these functions have been fixed since unified headers.
             // Ignore these until next major version.
             "bind" | "writev" | "readv" | "sendmsg" | "recvmsg" if android && (aarch64 || x86_64) => true,
 
-            // signal is defined with sighandler_t, so ignore
-            "signal" if solaris => true,
-
-            "cfmakeraw" | "cfsetspeed" if solaris => true,
-
-            // FIXME: mincore is defined with caddr_t on Solaris.
-            "mincore" if solaris => true,
-
-            // These were all included in historical versions of iOS but appear
-            // to be removed now
-            "system" | "ptrace" if ios => true,
-
             // Removed in OpenBSD 6.5
             // https://marc.info/?l=openbsd-cvs&m=154723400730318
             "mincore" if openbsd => true,
@@ -887,15 +668,6 @@ fn do_ctest() {
         }
     });
 
-    cfg.skip_fn_ptrcheck(move |name| {
-        match name {
-            // dllimport weirdness?
-            _ if windows => true,
-
-            _ => false,
-        }
-    });
-
     cfg.skip_field_type(move |struct_, field| {
         // This is a weird union, don't check the type.
         (struct_ == "ifaddrs" && field == "ifa_ifu") ||
@@ -933,13 +705,8 @@ fn do_ctest() {
                                            field == "ssi_arch"))
     });
 
-    cfg.fn_cname(move |name, cname| {
-        if windows {
-            cname.unwrap_or(name).to_string()
-        } else {
-            name.to_string()
-        }
-    });
+    // FIXME: remove
+    cfg.fn_cname(move |name, _cname| name.to_string());
 
     cfg.generate("../src/lib.rs", "main.rs");
 
@@ -992,3 +759,1114 @@ fn main() {
     do_cc();
     do_ctest();
 }
+
+macro_rules! headers {
+    ($cfg:ident: $header:expr) => {
+        $cfg.header($header);
+    };
+    ($cfg:ident: $($header:expr),*) => {
+        $(headers!($cfg: $header);)*
+    };
+    ($cfg:ident: $($header:expr,)*) => {
+        $(headers!($cfg: $header);)*
+    };
+}
+
+fn test_apple(target: &str) {
+    assert!(target.contains("apple"));
+    let x86_64 = target.contains("x86_64");
+
+    let mut cfg = ctest::TestGenerator::new();
+    cfg.flag("-Wno-deprecated-declarations");
+    cfg.define("__APPLE_USE_RFC_3542", None);
+
+    headers! { cfg:
+        "aio.h",
+        "ctype.h",
+        "dirent.h",
+        "dlfcn.h",
+        "errno.h",
+        "execinfo.h",
+        "fcntl.h",
+        "glob.h",
+        "grp.h",
+        "ifaddrs.h",
+        "langinfo.h",
+        "limits.h",
+        "locale.h",
+        "mach-o/dyld.h",
+        "mach/mach_time.h",
+        "malloc/malloc.h",
+        "net/bpf.h",
+        "net/if.h",
+        "net/if_arp.h",
+        "net/if_dl.h",
+        "net/if_utun.h",
+        "net/route.h",
+        "net/route.h",
+        "netdb.h",
+        "netinet/if_ether.h",
+        "netinet/in.h",
+        "netinet/in.h",
+        "netinet/ip.h",
+        "netinet/tcp.h",
+        "netinet/udp.h",
+        "poll.h",
+        "pthread.h",
+        "pwd.h",
+        "resolv.h",
+        "sched.h",
+        "semaphore.h",
+        "signal.h",
+        "spawn.h",
+        "stddef.h",
+        "stdint.h",
+        "stdio.h",
+        "stdlib.h",
+        "string.h",
+        "sys/event.h",
+        "sys/file.h",
+        "sys/ioctl.h",
+        "sys/ipc.h",
+        "sys/kern_control.h",
+        "sys/mman.h",
+        "sys/mount.h",
+        "sys/proc_info.h",
+        "sys/ptrace.h",
+        "sys/quota.h",
+        "sys/resource.h",
+        "sys/sem.h",
+        "sys/shm.h",
+        "sys/socket.h",
+        "sys/stat.h",
+        "sys/statvfs.h",
+        "sys/sys_domain.h",
+        "sys/sysctl.h",
+        "sys/time.h",
+        "sys/times.h",
+        "sys/types.h",
+        "sys/uio.h",
+        "sys/un.h",
+        "sys/utsname.h",
+        "sys/wait.h",
+        "sys/xattr.h",
+        "syslog.h",
+        "termios.h",
+        "time.h",
+        "unistd.h",
+        "util.h",
+        "utime.h",
+        "utmpx.h",
+        "wchar.h",
+        "xlocale.h",
+    }
+
+    if x86_64 {
+        headers! { cfg: "crt_externs.h" }
+    }
+
+    cfg.skip_struct(move |ty| {
+        match ty {
+            // FIXME: actually a union
+            "sigval" => true,
+
+            _ => false,
+        }
+    });
+
+    cfg.skip_const(move |name| {
+        match name {
+            // These OSX constants are removed in Sierra.
+            // https://developer.apple.com/library/content/releasenotes/General/APIDiffsMacOS10_12/Swift/Darwin.html
+            "KERN_KDENABLE_BG_TRACE" | "KERN_KDDISABLE_BG_TRACE" => 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" => true,
+
+            // close calls the close_nocancel system call
+            "close" => true,
+
+            _ => false,
+        }
+    });
+
+    cfg.skip_field_type(move |struct_, field| {
+        match (struct_, field) {
+            // FIXME: actually a union
+            ("sigevent", "sigev_value") => true,
+            _ => false,
+        }
+    });
+
+    cfg.volatile_item(|i| {
+        use ctest::VolatileItemKind::*;
+        match i {
+            StructField(ref n, ref f) if n == "aiocb" && f == "aio_buf" => {
+                true
+            }
+            _ => false,
+        }
+    });
+
+    cfg.type_name(move |ty, is_struct, is_union| {
+        match ty {
+            // Just pass all these through, no need for a "struct" prefix
+            "FILE" | "DIR" | "Dl_info" => ty.to_string(),
+
+            // OSX calls this something else
+            "sighandler_t" => "sig_t".to_string(),
+
+            t if is_union => format!("union {}", t),
+            t if t.ends_with("_t") => t.to_string(),
+            t if is_struct => format!("struct {}", t),
+            t => t.to_string(),
+        }
+    });
+
+    cfg.field_name(move |struct_, field| {
+        match field {
+            s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
+                s.replace("e_nsec", "espec.tv_nsec")
+            }
+            // FIXME: sigaction actually contains a union with two variants:
+            // a sa_sigaction with type: (*)(int, struct __siginfo *, void *)
+            // a sa_handler with type sig_t
+            "sa_sigaction" if struct_ == "sigaction" => {
+                "sa_handler".to_string()
+            }
+            s => s.to_string(),
+        }
+    });
+
+    cfg.generate("../src/lib.rs", "main.rs");
+}
+
+fn test_openbsd(target: &str) {
+    assert!(target.contains("openbsd"));
+
+    let mut cfg = ctest::TestGenerator::new();
+    cfg.flag("-Wno-deprecated-declarations");
+
+    headers! { cfg:
+        "errno.h",
+        "fcntl.h",
+        "limits.h",
+        "locale.h",
+        "stddef.h",
+        "stdint.h",
+        "stdio.h",
+        "stdlib.h",
+        "sys/stat.h",
+        "sys/types.h",
+        "time.h",
+        "wchar.h",
+        "ctype.h",
+        "dirent.h",
+        "sys/socket.h",
+        "net/if.h",
+        "net/route.h",
+        "net/if_arp.h",
+        "netdb.h",
+        "netinet/in.h",
+        "netinet/ip.h",
+        "netinet/tcp.h",
+        "netinet/udp.h",
+        "resolv.h",
+        "pthread.h",
+        "dlfcn.h",
+        "signal.h",
+        "string.h",
+        "sys/file.h",
+        "sys/ioctl.h",
+        "sys/mman.h",
+        "sys/resource.h",
+        "sys/socket.h",
+        "sys/time.h",
+        "sys/un.h",
+        "sys/wait.h",
+        "unistd.h",
+        "utime.h",
+        "pwd.h",
+        "grp.h",
+        "sys/utsname.h",
+        "sys/ptrace.h",
+        "sys/mount.h",
+        "sys/uio.h",
+        "sched.h",
+        "termios.h",
+        "poll.h",
+        "syslog.h",
+        "semaphore.h",
+        "sys/statvfs.h",
+        "sys/times.h",
+        "glob.h",
+        "ifaddrs.h",
+        "langinfo.h",
+        "sys/sysctl.h",
+        "utmp.h",
+        "sys/event.h",
+        "net/if_dl.h",
+        "util.h",
+        "ufs/ufs/quota.h",
+        "pthread_np.h",
+        "sys/syscall.h",
+    }
+
+    cfg.skip_struct(move |ty| {
+        match ty {
+            // FIXME: actually a union
+            "sigval" => true,
+
+            _ => false,
+        }
+    });
+
+    cfg.skip_const(move |name| {
+        match name {
+            // Removed in OpenBSD 6.0
+            "KERN_USERMOUNT" | "KERN_ARND" => true,
+            _ => false,
+        }
+    });
+
+    cfg.skip_fn(move |name| {
+        match name {
+            "execv" | "execve" | "execvp" | "execvpe" => true,
+
+            // typed 2nd arg
+            "gettimeofday" => true,
+
+            // Removed in OpenBSD 6.5
+            // https://marc.info/?l=openbsd-cvs&m=154723400730318
+            "mincore" => true,
+
+            _ => false,
+        }
+    });
+
+    cfg.type_name(move |ty, is_struct, is_union| {
+        match ty {
+            // Just pass all these through, no need for a "struct" prefix
+            "FILE" | "DIR" | "Dl_info" => ty.to_string(),
+
+            // OSX calls this something else
+            "sighandler_t" => "sig_t".to_string(),
+
+            t if is_union => format!("union {}", t),
+            t if t.ends_with("_t") => t.to_string(),
+            t if is_struct => format!("struct {}", t),
+            t => t.to_string(),
+        }
+    });
+
+    cfg.field_name(move |struct_, field| {
+        match field {
+            "st_birthtime" if struct_.starts_with("stat") => {
+                "__st_birthtime".to_string()
+            }
+            "st_birthtime_nsec" if struct_.starts_with("stat") => {
+                "__st_birthtimensec".to_string()
+            }
+            s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
+                s.replace("e_nsec", ".tv_nsec")
+            }
+            "sa_sigaction" if struct_ == "sigaction" => {
+                "sa_handler".to_string()
+            }
+            s => s.to_string(),
+        }
+    });
+
+    cfg.skip_field_type(move |struct_, field| {
+        // type siginfo_t.si_addr changed from OpenBSD 6.0 to 6.1
+        (struct_ == "siginfo_t" && field == "si_addr")
+    });
+
+    cfg.generate("../src/lib.rs", "linux_fcntl.rs");
+}
+
+fn test_windows(target: &str) {
+    assert!(target.contains("windows"));
+    let gnu = target.contains("gnu");
+
+    let mut cfg = ctest::TestGenerator::new();
+    cfg.define("_WIN32_WINNT", Some("0x8000"));
+
+    headers! { cfg:
+        "direct.h",
+        "errno.h",
+        "fcntl.h",
+        "io.h",
+        "limits.h",
+        "locale.h",
+        "process.h",
+        "signal.h",
+        "stddef.h",
+        "stdint.h",
+        "stdio.h",
+        "stdlib.h",
+        "sys/stat.h",
+        "sys/types.h",
+        "sys/utime.h",
+        "time.h",
+        "wchar.h",
+    }
+
+    if gnu {
+        headers! { cfg: "ws2tcpip.h" }
+    } else {
+        headers! { cfg: "Winsock2.h" };
+    }
+
+    cfg.type_name(move |ty, is_struct, is_union| {
+        match ty {
+            // Just pass all these through, no need for a "struct" prefix
+            "FILE" | "DIR" | "Dl_info" => ty.to_string(),
+
+            // FIXME: these don't exist:
+            "time64_t" => "__time64_t".to_string(),
+            "ssize_t" => "SSIZE_T".to_string(),
+
+            "sighandler_t" if !gnu => "_crt_signal_t".to_string(),
+            "sighandler_t" if gnu => "__p_sig_fn_t".to_string(),
+
+            t if is_union => format!("union {}", t),
+            t if t.ends_with("_t") => t.to_string(),
+
+            // Windows uppercase structs don't have `struct` in front:
+            t if is_struct => {
+                if ty.clone().chars().next().unwrap().is_uppercase() {
+                    t.to_string()
+                } else if t == "stat" {
+                    "struct __stat64".to_string()
+                } else if t == "utimbuf" {
+                    "struct __utimbuf64".to_string()
+                } else {
+                    // put `struct` in front of all structs:
+                    format!("struct {}", t)
+                }
+            }
+            t => t.to_string(),
+        }
+    });
+
+    cfg.fn_cname(move |name, cname| cname.unwrap_or(name).to_string());
+
+    cfg.skip_type(move |name| match name {
+        "SSIZE_T" if !gnu => true,
+        "ssize_t" if !gnu => true,
+        _ => false,
+    });
+
+    cfg.skip_const(move |name| {
+        match name {
+            // FIXME: API error:
+            // SIG_ERR type is "void (*)(int)", not "int"
+            "SIG_ERR" => true,
+            _ => false,
+        }
+    });
+
+    // FIXME: All functions point to the wrong addresses?
+    cfg.skip_fn_ptrcheck(|_| true);
+
+    cfg.skip_signededness(move |c| {
+        match c {
+            // windows-isms
+            n if n.starts_with("P") => true,
+            n if n.starts_with("H") => true,
+            n if n.starts_with("LP") => true,
+            "sighandler_t" if gnu => true,
+            _ => false,
+        }
+    });
+
+    cfg.skip_fn(move |name| {
+        match name {
+            // FIXME: API error:
+            "execv" | "execve" | "execvp" | "execvpe" => true,
+
+            _ => false,
+        }
+    });
+
+    cfg.generate("../src/lib.rs", "main.rs");
+}
+
+fn test_redox(target: &str) {
+    assert!(target.contains("redox"));
+
+    let mut cfg = ctest::TestGenerator::new();
+    cfg.flag("-Wno-deprecated-declarations");
+
+    headers! {
+        cfg:
+        "ctype.h",
+        "dirent.h",
+        "dlfcn.h",
+        "errno.h",
+        "execinfo.h",
+        "fcntl.h",
+        "glob.h",
+        "grp.h",
+        "ifaddrs.h",
+        "langinfo.h",
+        "limits.h",
+        "locale.h",
+        "net/if.h",
+        "net/if_arp.h",
+        "net/route.h",
+        "netdb.h",
+        "netinet/in.h",
+        "netinet/ip.h",
+        "netinet/tcp.h",
+        "netinet/udp.h",
+        "poll.h",
+        "pthread.h",
+        "pwd.h",
+        "resolv.h",
+        "sched.h",
+        "semaphore.h",
+        "string.h",
+        "strings.h",
+        "sys/file.h",
+        "sys/ioctl.h",
+        "sys/mman.h",
+        "sys/mount.h",
+        "sys/ptrace.h",
+        "sys/quota.h",
+        "sys/resource.h",
+        "sys/socket.h",
+        "sys/stat.h",
+        "sys/statvfs.h",
+        "sys/sysctl.h",
+        "sys/time.h",
+        "sys/times.h",
+        "sys/types.h",
+        "sys/uio.h",
+        "sys/un.h",
+        "sys/utsname.h",
+        "sys/wait.h",
+        "syslog.h",
+        "termios.h",
+        "time.h",
+        "unistd.h",
+        "utime.h",
+        "utmpx.h",
+        "wchar.h",
+    }
+
+    cfg.generate("../src/lib.rs", "main.rs");
+}
+
+fn test_cloudabi(target: &str) {
+    assert!(target.contains("cloudabi"));
+
+    let mut cfg = ctest::TestGenerator::new();
+    cfg.flag("-Wno-deprecated-declarations");
+
+    headers! {
+        cfg:
+        "execinfo.h",
+        "glob.h",
+        "ifaddrs.h",
+        "langinfo.h",
+        "sys/ptrace.h",
+        "sys/quota.h",
+        "sys/sysctl.h",
+        "utmpx.h",
+        "ctype.h",
+        "dirent.h",
+        "dlfcn.h",
+        "errno.h",
+        "fcntl.h",
+        "grp.h",
+        "limits.h",
+        "locale.h",
+        "net/if.h",
+        "net/if_arp.h",
+        "net/route.h",
+        "netdb.h",
+        "netinet/in.h",
+        "netinet/ip.h",
+        "netinet/tcp.h",
+        "netinet/udp.h",
+        "poll.h",
+        "pthread.h",
+        "pwd.h",
+        "resolv.h",
+        "sched.h",
+        "semaphore.h",
+        "signal.h",
+        "stddef.h",
+        "stdint.h",
+        "stdio.h",
+        "stdlib.h",
+        "string.h",
+        "strings.h",
+        "sys/file.h",
+        "sys/ioctl.h",
+        "sys/mman.h",
+        "sys/mount.h",
+        "sys/resource.h",
+        "sys/socket.h",
+        "sys/stat.h",
+        "sys/statvfs.h",
+        "sys/time.h",
+        "sys/times.h",
+        "sys/types.h",
+        "sys/uio.h",
+        "sys/un.h",
+        "sys/utsname.h",
+        "sys/wait.h",
+        "syslog.h",
+        "termios.h",
+        "time.h",
+        "unistd.h",
+        "utime.h",
+        "wchar.h",
+    }
+
+    cfg.generate("../src/lib.rs", "main.rs");
+}
+
+fn test_solaris(target: &str) {
+    assert!(target.contains("solaris"));
+
+    let mut cfg = ctest::TestGenerator::new();
+    cfg.flag("-Wno-deprecated-declarations");
+
+    cfg.define("_XOPEN_SOURCE", Some("700"));
+    cfg.define("__EXTENSIONS__", None);
+    cfg.define("_LCONV_C99", None);
+
+    headers! {
+        cfg:
+        "ctype.h",
+        "dirent.h",
+        "dlfcn.h",
+        "errno.h",
+        "execinfo.h",
+        "fcntl.h",
+        "glob.h",
+        "grp.h",
+        "ifaddrs.h",
+        "langinfo.h",
+        "limits.h",
+        "locale.h",
+        "net/if.h",
+        "net/if_arp.h",
+        "net/route.h",
+        "netdb.h",
+        "netinet/in.h",
+        "netinet/ip.h",
+        "netinet/tcp.h",
+        "netinet/udp.h",
+        "poll.h",
+        "port.h",
+        "pthread.h",
+        "pwd.h",
+        "resolv.h",
+        "sched.h",
+        "semaphore.h",
+        "signal.h",
+        "stddef.h",
+        "stdint.h",
+        "stdio.h",
+        "stdlib.h",
+        "string.h",
+        "sys/epoll.h",
+        "sys/file.h",
+        "sys/filio.h",
+        "sys/ioctl.h",
+        "sys/loadavg.h",
+        "sys/mman.h",
+        "sys/mount.h",
+        "sys/resource.h",
+        "sys/socket.h",
+        "sys/stat.h",
+        "sys/statvfs.h",
+        "sys/time.h",
+        "sys/times.h",
+        "sys/types.h",
+        "sys/uio.h",
+        "sys/un.h",
+        "sys/utsname.h",
+        "sys/wait.h",
+        "syslog.h",
+        "termios.h",
+        "time.h",
+        "ucontext.h",
+        "unistd.h",
+        "utime.h",
+        "utmpx.h",
+        "wchar.h",
+    }
+
+    cfg.skip_const(move |name| match name {
+        "DT_FIFO" | "DT_CHR" | "DT_DIR" | "DT_BLK" | "DT_REG" | "DT_LNK"
+        | "DT_SOCK" | "USRQUOTA" | "GRPQUOTA" | "PRIO_MIN" | "PRIO_MAX" => {
+            true
+        }
+
+        _ => false,
+    });
+
+    cfg.skip_fn(move |name| {
+        // skip those that are manually verified
+        match name {
+            // const-ness only added recently
+            "dladdr" => 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
+            "setpriority" | "personality" => true,
+
+            // signal is defined with sighandler_t, so ignore
+            "signal" => true,
+
+            "cfmakeraw" | "cfsetspeed" => true,
+
+            // FIXME: mincore is defined with caddr_t on Solaris.
+            "mincore" => true,
+
+            _ => false,
+        }
+    });
+
+    cfg.generate("../src/lib.rs", "main.rs");
+}
+
+fn test_netbsd(target: &str) {
+    assert!(target.contains("netbsd"));
+    let rumprun = target.contains("rumprun");
+    let mut cfg = ctest::TestGenerator::new();
+
+    cfg.flag("-Wno-deprecated-declarations");
+    cfg.define("_NETBSD_SOURCE", Some("1"));
+
+    headers! {
+        cfg:
+        "errno.h",
+        "fcntl.h",
+        "limits.h",
+        "locale.h",
+        "stddef.h",
+        "stdint.h",
+        "stdio.h",
+        "stdlib.h",
+        "sys/stat.h",
+        "sys/types.h",
+        "time.h",
+        "wchar.h",
+        "aio.h",
+        "ctype.h",
+        "dirent.h",
+        "dlfcn.h",
+        "glob.h",
+        "grp.h",
+        "ifaddrs.h",
+        "langinfo.h",
+        "net/if.h",
+        "net/if_arp.h",
+        "net/if_dl.h",
+        "net/route.h",
+        "netdb.h",
+        "netinet/in.h",
+        "netinet/ip.h",
+        "netinet/tcp.h",
+        "netinet/udp.h",
+        "poll.h",
+        "pthread.h",
+        "pwd.h",
+        "resolv.h",
+        "sched.h",
+        "semaphore.h",
+        "signal.h",
+        "string.h",
+        "sys/extattr.h",
+        "sys/file.h",
+        "sys/ioctl.h",
+        "sys/ioctl_compat.h",
+        "sys/mman.h",
+        "sys/mount.h",
+        "sys/ptrace.h",
+        "sys/resource.h",
+        "sys/socket.h",
+        "sys/statvfs.h",
+        "sys/sysctl.h",
+        "sys/time.h",
+        "sys/times.h",
+        "sys/uio.h",
+        "sys/un.h",
+        "sys/utsname.h",
+        "sys/wait.h",
+        "syslog.h",
+        "termios.h",
+        "ufs/ufs/quota.h",
+        "ufs/ufs/quota1.h",
+        "unistd.h",
+        "util.h",
+        "utime.h",
+        "mqueue.h",
+        "netinet/dccp.h",
+        "sys/event.h",
+        "sys/quota.h",
+    }
+
+    cfg.type_name(move |ty, is_struct, is_union| {
+        match ty {
+            // Just pass all these through, no need for a "struct" prefix
+            "FILE" | "fd_set" | "Dl_info" | "DIR" | "Elf32_Phdr"
+            | "Elf64_Phdr" | "Elf32_Shdr" | "Elf64_Shdr" | "Elf32_Sym"
+            | "Elf64_Sym" | "Elf32_Ehdr" | "Elf64_Ehdr" | "Elf32_Chdr"
+            | "Elf64_Chdr" => ty.to_string(),
+
+            // OSX calls this something else
+            "sighandler_t" => "sig_t".to_string(),
+
+            t if is_union => format!("union {}", t),
+
+            t if t.ends_with("_t") => t.to_string(),
+
+            // put `struct` in front of all structs:.
+            t if is_struct => format!("struct {}", t),
+
+            t => t.to_string(),
+        }
+    });
+
+    cfg.field_name(move |struct_, field| {
+        match field {
+            // Our stat *_nsec fields normally don't actually exist but are part
+            // of a timeval struct
+            s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
+                s.replace("e_nsec", ".tv_nsec")
+            }
+            "u64" if struct_ == "epoll_event" => "data.u64".to_string(),
+            s => s.to_string(),
+        }
+    });
+
+    cfg.skip_type(move |ty| {
+        match ty {
+            // FIXME: sighandler_t is crazy across platforms
+            "sighandler_t" => true,
+            _ => false,
+        }
+    });
+
+    cfg.skip_struct(move |ty| {
+        match ty {
+            // This is actually a union, not a struct
+            "sigval" => true,
+            // These are tested as part of the linux_fcntl tests since there are
+            // header conflicts when including them with all the other structs.
+            "termios2" => true,
+            _ => false,
+        }
+    });
+
+    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,
+            _ => false,
+        }
+    });
+
+    cfg.skip_const(move |name| {
+        match name {
+            "SIG_DFL" | "SIG_ERR" | "SIG_IGN" => true, // sighandler_t weirdness
+            "SIGUNUSED" => true,                       // removed in glibc 2.26
+
+            // weird signed extension or something like that?
+            "MS_NOUSER" => true,
+            "MS_RMT_MASK" => true, // updated in glibc 2.22 and musl 1.1.13
+            "BOTHER" => true,
+
+            _ => false,
+        }
+    });
+
+    cfg.skip_fn(move |name| {
+        match name {
+            // FIXME: incorrect API
+            "execv" |
+            "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
+
+            // These functions presumably exist on netbsd but don't look like
+            // they're implemented on rumprun yet, just let them slide for now.
+            // Some of them look like they have headers but then don't have
+            // corresponding actual definitions either...
+            "shm_open" |
+            "shm_unlink" |
+            "syscall" |
+            "mq_open" |
+            "mq_close" |
+            "mq_getattr" |
+            "mq_notify" |
+            "mq_receive" |
+            "mq_send" |
+            "mq_setattr" |
+            "mq_timedreceive" |
+            "mq_timedsend" |
+            "mq_unlink" |
+            "ptrace" |
+            "sigaltstack" if rumprun => true,
+
+            _ => false,
+        }
+    });
+
+    cfg.skip_field_type(move |struct_, field| {
+        // This is a weird union, don't check the type.
+        (struct_ == "ifaddrs" && field == "ifa_ifu") ||
+        // sighandler_t type is super weird
+        (struct_ == "sigaction" && field == "sa_sigaction") ||
+        // 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")
+    });
+
+    cfg.generate("../src/lib.rs", "main.rs");
+}
+
+fn test_dragonflybsd(target: &str) {
+    assert!(target.contains("dragonfly"));
+    let mut cfg = ctest::TestGenerator::new();
+    cfg.flag("-Wno-deprecated-declarations");
+
+    headers! {
+        cfg:
+        "aio.h",
+        "ctype.h",
+        "dirent.h",
+        "dlfcn.h",
+        "errno.h",
+        "execinfo.h",
+        "fcntl.h",
+        "glob.h",
+        "grp.h",
+        "ifaddrs.h",
+        "langinfo.h",
+        "limits.h",
+        "locale.h",
+        "mqueue.h",
+        "net/if.h",
+        "net/if_arp.h",
+        "net/if_dl.h",
+        "net/route.h",
+        "netdb.h",
+        "netinet/in.h",
+        "netinet/ip.h",
+        "netinet/tcp.h",
+        "netinet/udp.h",
+        "poll.h",
+        "pthread.h",
+        "pthread_np.h",
+        "pwd.h",
+        "resolv.h",
+        "sched.h",
+        "semaphore.h",
+        "signal.h",
+        "stddef.h",
+        "stdint.h",
+        "stdio.h",
+        "stdlib.h",
+        "string.h",
+        "sys/event.h",
+        "sys/file.h",
+        "sys/ioctl.h",
+        "sys/mman.h",
+        "sys/mount.h",
+        "sys/ptrace.h",
+        "sys/resource.h",
+        "sys/rtprio.h",
+        "sys/socket.h",
+        "sys/stat.h",
+        "sys/statvfs.h",
+        "sys/sysctl.h",
+        "sys/time.h",
+        "sys/times.h",
+        "sys/types.h",
+        "sys/uio.h",
+        "sys/un.h",
+        "sys/utsname.h",
+        "sys/wait.h",
+        "syslog.h",
+        "termios.h",
+        "time.h",
+        "ufs/ufs/quota.h",
+        "unistd.h",
+        "util.h",
+        "utime.h",
+        "utmpx.h",
+        "wchar.h",
+    }
+
+    cfg.type_name(move |ty, is_struct, is_union| {
+        match ty {
+            // Just pass all these through, no need for a "struct" prefix
+            "FILE" | "fd_set" | "Dl_info" | "DIR" | "Elf32_Phdr"
+            | "Elf64_Phdr" | "Elf32_Shdr" | "Elf64_Shdr" | "Elf32_Sym"
+            | "Elf64_Sym" | "Elf32_Ehdr" | "Elf64_Ehdr" | "Elf32_Chdr"
+            | "Elf64_Chdr" => ty.to_string(),
+
+            // FIXME: OSX calls this something else
+            "sighandler_t" => "sig_t".to_string(),
+
+            t if is_union => format!("union {}", t),
+
+            t if t.ends_with("_t") => t.to_string(),
+
+            // put `struct` in front of all structs:.
+            t if is_struct => format!("struct {}", t),
+
+            t => t.to_string(),
+        }
+    });
+
+    cfg.field_name(move |struct_, field| {
+        match field {
+            // Our stat *_nsec fields normally don't actually exist but are part
+            // of a timeval struct
+            s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
+                s.replace("e_nsec", ".tv_nsec")
+            }
+            "u64" if struct_ == "epoll_event" => "data.u64".to_string(),
+            "type_"
+                if struct_ == "input_event"
+                    || struct_ == "input_mask"
+                    || struct_ == "ff_effect"
+                    || struct_ == "rtprio" =>
+            {
+                "type".to_string()
+            }
+            s => s.to_string(),
+        }
+    });
+
+    cfg.skip_type(move |ty| {
+        match ty {
+            // sighandler_t is crazy across platforms
+            "sighandler_t" => true,
+
+            _ => false,
+        }
+    });
+
+    cfg.skip_struct(move |ty| {
+        match ty {
+            // This is actually a union, not a struct
+            "sigval" => true,
+
+            // FIXME: These are tested as part of the linux_fcntl tests since
+            // there are header conflicts when including them with all the other
+            // structs.
+            "termios2" => true,
+
+            _ => false,
+        }
+    });
+
+    cfg.skip_signededness(move |c| {
+        match c {
+            "LARGE_INTEGER" | "float" | "double" => true,
+            // uuid_t is a struct, not an integer.
+            "uuid_t" => true,
+            n if n.starts_with("pthread") => true,
+            // sem_t is a struct or pointer
+            "sem_t" => true,
+            // mqd_t is a pointer on DragonFly
+            "mqd_t" => true,
+
+            _ => false,
+        }
+    });
+
+    cfg.skip_const(move |name| {
+        match name {
+            "SIG_DFL" | "SIG_ERR" | "SIG_IGN" => true, // sighandler_t weirdness
+
+            // weird signed extension or something like that?
+            "MS_NOUSER" => true,
+            "MS_RMT_MASK" => true, // updated in glibc 2.22 and musl 1.1.13
+
+            // These are defined for Solaris 11, but the crate is tested on
+            // illumos, where they are currently not defined
+            "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...
+            "AF_MAX" | "PF_MAX" => true,
+
+            _ => false,
+        }
+    });
+
+    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
+            // typed 2nd arg on linux and android
+            "gettimeofday" => true,
+
+            _ => false,
+        }
+    });
+
+    cfg.skip_field_type(move |struct_, field| {
+        // This is a weird union, don't check the type.
+        (struct_ == "ifaddrs" && field == "ifa_ifu") ||
+        // sighandler_t type is super weird
+        (struct_ == "sigaction" && field == "sa_sigaction") ||
+        // 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")
+    });
+
+    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.
+        (struct_ == "siginfo_t" && field == "_pad") ||
+        // sigev_notify_thread_id is actually part of a sigev_un union
+        (struct_ == "sigevent" && field == "sigev_notify_thread_id")
+    });
+
+    cfg.generate("../src/lib.rs", "main.rs");
+}
diff --git a/libc-test/test/linux_fcntl.rs b/libc-test/test/linux_fcntl.rs
index 4c8ad52a91e86975e89ed0c1dc2f47c74cae56b4..a54636c6f706fbab6dd7afcbd17a8067c09b6a80 100644
--- a/libc-test/test/linux_fcntl.rs
+++ b/libc-test/test/linux_fcntl.rs
@@ -1,7 +1,10 @@
-#![allow(bad_style, improper_ctypes, unused)]
+#![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_fcntl.rs"));
+
+#[cfg(not(any(target_os = "linux", target_os = "android")))]
+fn main() {}
diff --git a/libc-test/test/main.rs b/libc-test/test/main.rs
index 3d336102bba45426123bda63733e0c5e9adbce84..62a587cf5868fa7120c3d69b7bdc6e516015afa7 100644
--- a/libc-test/test/main.rs
+++ b/libc-test/test/main.rs
@@ -1,4 +1,4 @@
-#![allow(bad_style, improper_ctypes)]
+#![allow(bad_style, improper_ctypes, deprecated)]
 extern crate libc;
 
 use libc::*;
diff --git a/src/cloudabi/mod.rs b/src/cloudabi/mod.rs
index e5027b935b1c9de5fc4bca6961adbb2899771985..81919675581fbfc6d9196c6ac599332d89683d31 100644
--- a/src/cloudabi/mod.rs
+++ b/src/cloudabi/mod.rs
@@ -1,5 +1,3 @@
-use dox::Option;
-
 pub type int8_t = i8;
 pub type int16_t = i16;
 pub type int32_t = i32;
@@ -124,14 +122,14 @@ pub const SOCK_STREAM: ::c_int = 130;
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum FILE {}
-impl ::dox::Copy for FILE {}
-impl ::dox::Clone for FILE {
+impl ::Copy for FILE {}
+impl ::Clone for FILE {
     fn clone(&self) -> FILE { *self }
 }
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum fpos_t {} // TODO: fill this out with a struct
-impl ::dox::Copy for fpos_t {}
-impl ::dox::Clone for fpos_t {
+impl ::Copy for fpos_t {}
+impl ::Clone for fpos_t {
     fn clone(&self) -> fpos_t { *self }
 }
 
@@ -281,7 +279,7 @@ extern {
     ) -> ::c_int;
     pub fn pthread_key_create(
         key: *mut pthread_key_t,
-        dtor: Option<unsafe extern fn(*mut ::c_void)>,
+        dtor: ::Option<unsafe extern fn(*mut ::c_void)>,
     ) -> ::c_int;
     pub fn pthread_key_delete(key: pthread_key_t) -> ::c_int;
     pub fn pthread_setspecific(
diff --git a/src/dox.rs b/src/dox.rs
deleted file mode 100644
index 6296c6c0257f6930b063e475b5186b9c3788438d..0000000000000000000000000000000000000000
--- a/src/dox.rs
+++ /dev/null
@@ -1,224 +0,0 @@
-pub use self::imp::*;
-
-#[cfg(not(cross_platform_docs))]
-mod imp {
-    pub use core::clone::Clone;
-    pub use core::marker::Copy;
-    pub use core::mem;
-    pub use core::option::Option;
-}
-
-#[cfg(cross_platform_docs)]
-mod imp {
-    pub enum Option<T> {
-        Some(T),
-        None,
-    }
-    impl<T: Copy> Copy for Option<T> {}
-    impl<T: Clone> Clone for Option<T> {
-        fn clone(&self) -> Option<T> {
-            loop {}
-        }
-    }
-
-    impl<T> Copy for *mut T {}
-    impl<T> Clone for *mut T {
-        fn clone(&self) -> *mut T {
-            loop {}
-        }
-    }
-
-    impl<T> Copy for *const T {}
-    impl<T> Clone for *const T {
-        fn clone(&self) -> *const T {
-            loop {}
-        }
-    }
-
-    pub trait Clone {
-        fn clone(&self) -> Self;
-    }
-
-    #[lang = "copy"]
-    pub trait Copy {}
-
-    #[lang = "freeze"]
-    pub trait Freeze {}
-
-    #[lang = "sync"]
-    pub trait Sync {}
-    impl<T> Sync for T {}
-
-    #[lang = "sized"]
-    pub trait Sized {}
-
-    #[lang = "receiver"]
-    pub trait Receiver {}
-    impl<T: ?Sized> Receiver for &T {}
-    impl<T: ?Sized> Receiver for &mut T {}
-
-    macro_rules! each_int {
-        ($mac:ident) => {
-            $mac!(u8);
-            $mac!(u16);
-            $mac!(u32);
-            $mac!(u64);
-            $mac!(usize);
-            each_signed_int!($mac);
-        };
-    }
-
-    macro_rules! each_signed_int {
-        ($mac:ident) => {
-            $mac!(i8);
-            $mac!(i16);
-            $mac!(i32);
-            $mac!(i64);
-            $mac!(isize);
-        };
-    }
-
-    #[lang = "div"]
-    pub trait Div<RHS = Self> {
-        type Output;
-        fn div(self, rhs: RHS) -> Self::Output;
-    }
-
-    #[lang = "shl"]
-    pub trait Shl<RHS = Self> {
-        type Output;
-        fn shl(self, rhs: RHS) -> Self::Output;
-    }
-
-    #[lang = "mul"]
-    pub trait Mul<RHS = Self> {
-        type Output;
-        fn mul(self, rhs: RHS) -> Self::Output;
-    }
-
-    #[lang = "sub"]
-    pub trait Sub<RHS = Self> {
-        type Output;
-        fn sub(self, rhs: RHS) -> Self::Output;
-    }
-
-    #[lang = "bitand"]
-    pub trait BitAnd<RHS = Self> {
-        type Output;
-        fn bitand(self, rhs: RHS) -> Self::Output;
-    }
-
-    #[lang = "bitand_assign"]
-    pub trait BitAndAssign<RHS = Self> {
-        fn bitand_assign(&mut self, rhs: RHS);
-    }
-
-    #[lang = "bitor"]
-    pub trait BitOr<RHS = Self> {
-        type Output;
-        fn bitor(self, rhs: RHS) -> Self::Output;
-    }
-
-    #[lang = "bitor_assign"]
-    pub trait BitOrAssign<RHS = Self> {
-        fn bitor_assign(&mut self, rhs: RHS);
-    }
-
-    #[lang = "bitxor"]
-    pub trait BitXor<RHS = Self> {
-        type Output;
-        fn bitxor(self, rhs: RHS) -> Self::Output;
-    }
-
-    #[lang = "bitxor_assign"]
-    pub trait BitXorAssign<RHS = Self> {
-        fn bitxor_assign(&mut self, rhs: RHS);
-    }
-
-    #[lang = "neg"]
-    pub trait Neg {
-        type Output;
-        fn neg(self) -> Self::Output;
-    }
-
-    #[lang = "not"]
-    pub trait Not {
-        type Output;
-        fn not(self) -> Self::Output;
-    }
-
-    #[lang = "add"]
-    pub trait Add<RHS = Self> {
-        type Output;
-        fn add(self, r: RHS) -> Self::Output;
-    }
-
-    macro_rules! impl_traits {
-        ($($i:ident)*) => ($(
-            impl Div<$i> for $i {
-                type Output = $i;
-                fn div(self, rhs: $i) -> $i { self / rhs }
-            }
-            impl Shl<$i> for $i {
-                type Output = $i;
-                fn shl(self, rhs: $i) -> $i { self << rhs }
-            }
-            impl Mul for $i {
-                type Output = $i;
-                fn mul(self, rhs: $i) -> $i { self * rhs }
-            }
-
-            impl Sub for $i {
-                type Output = $i;
-                fn sub(self, rhs: $i) -> $i { self - rhs }
-            }
-            impl BitAnd for $i {
-                type Output = $i;
-                fn bitand(self, rhs: $i) -> $i { self & rhs }
-            }
-            impl BitAndAssign for $i {
-                fn bitand_assign(&mut self, rhs: $i) { *self &= rhs; }
-            }
-            impl BitOr for $i {
-                type Output = $i;
-                fn bitor(self, rhs: $i) -> $i { self | rhs }
-            }
-            impl BitOrAssign for $i {
-                fn bitor_assign(&mut self, rhs: $i) { *self |= rhs; }
-            }
-            impl BitXor for $i {
-                type Output = $i;
-                fn bitxor(self, rhs: $i) -> $i { self ^ rhs }
-            }
-            impl BitXorAssign for $i {
-                fn bitxor_assign(&mut self, rhs: $i) { *self ^= rhs; }
-            }
-            impl Neg for $i {
-                type Output = $i;
-                fn neg(self) -> $i { -self }
-            }
-            impl Not for $i {
-                type Output = $i;
-                fn not(self) -> $i { !self }
-            }
-            impl Add<$i> for $i {
-                type Output = $i;
-                fn add(self, other: $i) -> $i { self + other }
-            }
-            impl Copy for $i {}
-            impl Clone for $i {
-                fn clone(&self) -> $i { loop {} }
-            }
-        )*)
-    }
-    each_int!(impl_traits);
-
-    pub mod mem {
-        pub fn size_of_val<T>(_: &T) -> usize {
-            4
-        }
-        pub const fn size_of<T>() -> usize {
-            4
-        }
-    }
-}
diff --git a/src/fuchsia/align.rs b/src/fuchsia/align.rs
index 8d4040d003df2139e6459d6ce91d715338f7f599..bc972751926f1aeb0c0a44d1c79012dd799cf2eb 100644
--- a/src/fuchsia/align.rs
+++ b/src/fuchsia/align.rs
@@ -32,7 +32,6 @@ macro_rules! expand_align {
         }
 
         s_no_extra_traits! {
-            #[allow(missing_debug_implementations)]
             #[cfg_attr(all(target_pointer_width = "32",
                            any(target_arch = "arm",
                                target_arch = "x86_64")),
@@ -45,7 +44,6 @@ macro_rules! expand_align {
                 size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T],
             }
 
-            #[allow(missing_debug_implementations)]
             #[cfg_attr(all(target_pointer_width = "32",
                            any(target_arch = "arm",
                                target_arch = "x86_64")),
@@ -58,7 +56,6 @@ macro_rules! expand_align {
                 size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T],
             }
 
-            #[allow(missing_debug_implementations)]
             #[cfg_attr(target_pointer_width = "32",
                        repr(align(4)))]
             #[cfg_attr(target_pointer_width = "64",
@@ -71,5 +68,75 @@ macro_rules! expand_align {
                 size: [u8; ::__SIZEOF_PTHREAD_COND_T],
             }
         }
+
+        cfg_if! {
+            if #[cfg(feature = "extra_traits")] {
+                impl PartialEq for pthread_cond_t {
+                    fn eq(&self, other: &pthread_cond_t) -> bool {
+                        self.size
+                            .iter()
+                            .zip(other.size.iter())
+                            .all(|(a,b)| a == b)
+                    }
+                }
+                impl Eq for pthread_cond_t {}
+                impl ::fmt::Debug for pthread_cond_t {
+                    fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                        f.debug_struct("pthread_cond_t")
+                            // FIXME: .field("size", &self.size)
+                            .finish()
+                    }
+                }
+                impl ::hash::Hash for pthread_cond_t {
+                    fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                        self.size.hash(state);
+                    }
+                }
+
+                impl PartialEq for pthread_mutex_t {
+                    fn eq(&self, other: &pthread_mutex_t) -> bool {
+                        self.size
+                            .iter()
+                            .zip(other.size.iter())
+                            .all(|(a,b)| a == b)
+                    }
+                }
+                impl Eq for pthread_mutex_t {}
+                impl ::fmt::Debug for pthread_mutex_t {
+                    fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                        f.debug_struct("pthread_mutex_t")
+                            // FIXME: .field("size", &self.size)
+                            .finish()
+                    }
+                }
+                impl ::hash::Hash for pthread_mutex_t {
+                    fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                        self.size.hash(state);
+                    }
+                }
+
+                impl PartialEq for pthread_rwlock_t {
+                    fn eq(&self, other: &pthread_rwlock_t) -> bool {
+                        self.size
+                            .iter()
+                            .zip(other.size.iter())
+                            .all(|(a,b)| a == b)
+                    }
+                }
+                impl Eq for pthread_rwlock_t {}
+                impl ::fmt::Debug for pthread_rwlock_t {
+                    fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                        f.debug_struct("pthread_rwlock_t")
+                            // FIXME: .field("size", &self.size)
+                            .finish()
+                    }
+                }
+                impl ::hash::Hash for pthread_rwlock_t {
+                    fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                        self.size.hash(state);
+                    }
+                }
+            }
+        }
     }
 }
diff --git a/src/fuchsia/mod.rs b/src/fuchsia/mod.rs
index 6f45cc19176ef9f8675ea0ddf2a3c6905c1781c7..01317e30a4609ff9d534cb9842d9a4b5e7fa2ca3 100644
--- a/src/fuchsia/mod.rs
+++ b/src/fuchsia/mod.rs
@@ -3,8 +3,6 @@
 //! More functions and definitions can be found in the more specific modules
 //! according to the platform in question.
 
-use dox::{mem, Option};
-
 // PUB_TYPE
 
 pub type int8_t = i8;
@@ -102,26 +100,26 @@ pub type c_ulong = u64;
 // Presumably these should be `()` or an `extern type` (when that stabilizes).
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum timezone {}
-impl ::dox::Copy for timezone {}
-impl ::dox::Clone for timezone {
+impl ::Copy for timezone {}
+impl ::Clone for timezone {
     fn clone(&self) -> timezone { *self }
 }
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum DIR {}
-impl ::dox::Copy for DIR {}
-impl ::dox::Clone for DIR {
+impl ::Copy for DIR {}
+impl ::Clone for DIR {
     fn clone(&self) -> DIR { *self }
 }
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum locale_t {}
-impl ::dox::Copy for locale_t {}
-impl ::dox::Clone for locale_t {
+impl ::Copy for locale_t {}
+impl ::Clone for locale_t {
     fn clone(&self) -> locale_t { *self }
 }
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum fpos64_t {} // TODO: fill this out with a struct
-impl ::dox::Copy for fpos64_t {}
-impl ::dox::Clone for fpos64_t {
+impl ::Copy for fpos64_t {}
+impl ::Clone for fpos64_t {
     fn clone(&self) -> fpos64_t { *self }
 }
 
@@ -309,7 +307,7 @@ s! {
         pub sa_sigaction: ::sighandler_t,
         pub sa_mask: ::sigset_t,
         pub sa_flags: ::c_int,
-        pub sa_restorer: ::dox::Option<extern fn()>,
+        pub sa_restorer: ::Option<extern fn()>,
     }
 
     pub struct termios {
@@ -924,7 +922,6 @@ s! {
 }
 
 s_no_extra_traits! {
-    #[allow(missing_debug_implementations)]
     pub struct sysinfo {
         pub uptime: ::c_ulong,
         pub loads: [::c_ulong; 3],
@@ -942,20 +939,17 @@ s_no_extra_traits! {
         pub __reserved: [::c_char; 256],
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct sockaddr_un {
         pub sun_family: sa_family_t,
         pub sun_path: [::c_char; 108]
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct sockaddr_storage {
         pub ss_family: sa_family_t,
         __ss_align: ::size_t,
         __ss_pad2: [u8; 128 - 2 * 8],
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct utsname {
         pub sysname: [::c_char; 65],
         pub nodename: [::c_char; 65],
@@ -965,7 +959,6 @@ s_no_extra_traits! {
         pub domainname: [::c_char; 65]
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct dirent {
         pub d_ino: ::ino_t,
         pub d_off: ::off_t,
@@ -974,7 +967,6 @@ s_no_extra_traits! {
         pub d_name: [::c_char; 256],
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct dirent64 {
         pub d_ino: ::ino64_t,
         pub d_off: ::off64_t,
@@ -984,6 +976,247 @@ s_no_extra_traits! {
     }
 }
 
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for sysinfo {
+            fn eq(&self, other: &sysinfo) -> bool {
+                self.uptime == other.uptime
+                    && self.loads == other.loads
+                    && self.totalram == other.totalram
+                    && self.freeram == other.freeram
+                    && self.sharedram == other.sharedram
+                    && self.bufferram == other.bufferram
+                    && self.totalswap == other.totalswap
+                    && self.freeswap == other.freeswap
+                    && self.procs == other.procs
+                    && self.pad == other.pad
+                    && self.totalhigh == other.totalhigh
+                    && self.freehigh == other.freehigh
+                    && self.mem_unit == other.mem_unit
+                    && self
+                        .__reserved
+                        .iter()
+                        .zip(other.__reserved.iter())
+                        .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for sysinfo {}
+        impl ::fmt::Debug for sysinfo {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sysinfo")
+                    .field("uptime", &self.uptime)
+                    .field("loads", &self.loads)
+                    .field("totalram", &self.totalram)
+                    .field("freeram", &self.freeram)
+                    .field("sharedram", &self.sharedram)
+                    .field("bufferram", &self.bufferram)
+                    .field("totalswap", &self.totalswap)
+                    .field("freeswap", &self.freeswap)
+                    .field("procs", &self.procs)
+                    .field("pad", &self.pad)
+                    .field("totalhigh", &self.totalhigh)
+                    .field("freehigh", &self.freehigh)
+                    .field("mem_unit", &self.mem_unit)
+                    // FIXME: .field("__reserved", &self.__reserved)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for sysinfo {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.uptime.hash(state);
+                self.loads.hash(state);
+                self.totalram.hash(state);
+                self.freeram.hash(state);
+                self.sharedram.hash(state);
+                self.bufferram.hash(state);
+                self.totalswap.hash(state);
+                self.freeswap.hash(state);
+                self.procs.hash(state);
+                self.pad.hash(state);
+                self.totalhigh.hash(state);
+                self.freehigh.hash(state);
+                self.mem_unit.hash(state);
+                self.__reserved.hash(state);
+            }
+        }
+
+        impl PartialEq for sockaddr_un {
+            fn eq(&self, other: &sockaddr_un) -> bool {
+                self.sun_family == other.sun_family
+                    && self
+                    .sun_path
+                    .iter()
+                    .zip(other.sun_path.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for sockaddr_un {}
+        impl ::fmt::Debug for sockaddr_un {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sockaddr_un")
+                    .field("sun_family", &self.sun_family)
+                    // FIXME: .field("sun_path", &self.sun_path)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for sockaddr_un {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.sun_family.hash(state);
+                self.sun_path.hash(state);
+            }
+        }
+
+        impl PartialEq for sockaddr_storage {
+            fn eq(&self, other: &sockaddr_storage) -> bool {
+                self.ss_family == other.ss_family
+                    && self.__ss_align == other.__ss_align
+                    && self
+                    .__ss_pad2
+                    .iter()
+                    .zip(other.__ss_pad2.iter())
+                    .all(|(a, b)| a == b)
+            }
+        }
+        impl Eq for sockaddr_storage {}
+        impl ::fmt::Debug for sockaddr_storage {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sockaddr_storage")
+                    .field("ss_family", &self.ss_family)
+                    .field("__ss_align", &self.__ss_align)
+                    // FIXME: .field("__ss_pad2", &self.__ss_pad2)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for sockaddr_storage {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.ss_family.hash(state);
+                self.__ss_align.hash(state);
+                self.__ss_pad2.hash(state);
+            }
+        }
+
+        impl PartialEq for utsname {
+            fn eq(&self, other: &utsname) -> bool {
+                self.sysname
+                    .iter()
+                    .zip(other.sysname.iter())
+                    .all(|(a,b)| a == b)
+                    && self
+                    .nodename
+                    .iter()
+                    .zip(other.nodename.iter())
+                    .all(|(a,b)| a == b)
+                    && self
+                    .release
+                    .iter()
+                    .zip(other.release.iter())
+                    .all(|(a,b)| a == b)
+                    && self
+                    .version
+                    .iter()
+                    .zip(other.version.iter())
+                    .all(|(a,b)| a == b)
+                    && self
+                    .machine
+                    .iter()
+                    .zip(other.machine.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for utsname {}
+        impl ::fmt::Debug for utsname {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("utsname")
+                    // FIXME: .field("sysname", &self.sysname)
+                    // FIXME: .field("nodename", &self.nodename)
+                    // FIXME: .field("release", &self.release)
+                    // FIXME: .field("version", &self.version)
+                    // FIXME: .field("machine", &self.machine)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for utsname {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.sysname.hash(state);
+                self.nodename.hash(state);
+                self.release.hash(state);
+                self.version.hash(state);
+                self.machine.hash(state);
+            }
+        }
+
+        impl PartialEq for dirent {
+            fn eq(&self, other: &dirent) -> bool {
+                self.d_ino == other.d_ino
+                    && self.d_off == other.d_off
+                    && self.d_reclen == other.d_reclen
+                    && self.d_type == other.d_type
+                    && self
+                    .d_name
+                    .iter()
+                    .zip(other.d_name.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for dirent {}
+        impl ::fmt::Debug for dirent {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("dirent")
+                    .field("d_ino", &self.d_ino)
+                    .field("d_off", &self.d_off)
+                    .field("d_reclen", &self.d_reclen)
+                    .field("d_type", &self.d_type)
+                    // FIXME: .field("d_name", &self.d_name)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for dirent {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.d_ino.hash(state);
+                self.d_off.hash(state);
+                self.d_reclen.hash(state);
+                self.d_type.hash(state);
+                self.d_name.hash(state);
+            }
+        }
+
+        impl PartialEq for dirent64 {
+            fn eq(&self, other: &dirent64) -> bool {
+                self.d_ino == other.d_ino
+                    && self.d_off == other.d_off
+                    && self.d_reclen == other.d_reclen
+                    && self.d_type == other.d_type
+                    && self
+                    .d_name
+                    .iter()
+                    .zip(other.d_name.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for dirent64 {}
+        impl ::fmt::Debug for dirent64 {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("dirent64")
+                    .field("d_ino", &self.d_ino)
+                    .field("d_off", &self.d_off)
+                    .field("d_reclen", &self.d_reclen)
+                    .field("d_type", &self.d_type)
+                    // FIXME: .field("d_name", &self.d_name)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for dirent64 {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.d_ino.hash(state);
+                self.d_off.hash(state);
+                self.d_reclen.hash(state);
+                self.d_type.hash(state);
+                self.d_name.hash(state);
+            }
+        }
+    }
+}
+
 // PUB_CONST
 
 pub const INT_MIN: c_int = -2147483648;
@@ -1610,7 +1843,7 @@ pub const WEXITED: ::c_int = 0x00000004;
 pub const WCONTINUED: ::c_int = 0x00000008;
 pub const WNOWAIT: ::c_int = 0x01000000;
 
-// Options set using PTRACE_SETOPTIONS.
+// ::Options set using PTRACE_SETOPTIONS.
 pub const PTRACE_O_TRACESYSGOOD: ::c_int = 0x00000001;
 pub const PTRACE_O_TRACEFORK: ::c_int = 0x00000002;
 pub const PTRACE_O_TRACEVFORK: ::c_int = 0x00000004;
@@ -2829,20 +3062,20 @@ cfg_if! {
 f! {
     pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () {
         let fd = fd as usize;
-        let size = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         (*set).fds_bits[fd / size] &= !(1 << (fd % size));
         return
     }
 
     pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool {
         let fd = fd as usize;
-        let size = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0
     }
 
     pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () {
         let fd = fd as usize;
-        let size = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         (*set).fds_bits[fd / size] |= 1 << (fd % size);
         return
     }
@@ -2896,21 +3129,23 @@ f! {
     }
 
     pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () {
-        let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
+        let size_in_bits
+            = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
         let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits);
         cpuset.bits[idx] |= 1 << offset;
         ()
     }
 
     pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () {
-        let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
+        let size_in_bits
+            = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
         let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits);
         cpuset.bits[idx] &= !(1 << offset);
         ()
     }
 
     pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool {
-        let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]);
+        let size_in_bits = 8 * ::mem::size_of_val(&cpuset.bits[0]);
         let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits);
         0 != (cpuset.bits[idx] & (1 << offset))
     }
@@ -2953,14 +3188,14 @@ extern {}
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum FILE {}
-impl ::dox::Copy for FILE {}
-impl ::dox::Clone for FILE {
+impl ::Copy for FILE {}
+impl ::Clone for FILE {
     fn clone(&self) -> FILE { *self }
 }
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum fpos_t {} // TODO: fill this out with a struct
-impl ::dox::Copy for fpos_t {}
-impl ::dox::Clone for fpos_t {
+impl ::Copy for fpos_t {}
+impl ::Clone for fpos_t {
     fn clone(&self) -> fpos_t { *self }
 }
 
@@ -3290,7 +3525,7 @@ extern {
     pub fn pthread_detach(thread: ::pthread_t) -> ::c_int;
     pub fn sched_yield() -> ::c_int;
     pub fn pthread_key_create(key: *mut pthread_key_t,
-                              dtor: Option<unsafe extern fn(*mut ::c_void)>)
+                              dtor: ::Option<unsafe extern fn(*mut ::c_void)>)
                               -> ::c_int;
     pub fn pthread_key_delete(key: pthread_key_t) -> ::c_int;
     pub fn pthread_getspecific(key: pthread_key_t) -> *mut ::c_void;
@@ -3795,7 +4030,7 @@ extern {
 
     pub fn glob(pattern: *const c_char,
                 flags: ::c_int,
-                errfunc: Option<extern fn(epath: *const c_char,
+                errfunc: ::Option<extern fn(epath: *const c_char,
                                           errno: ::c_int) -> ::c_int>,
                 pglob: *mut ::glob_t) -> ::c_int;
     pub fn globfree(pglob: *mut ::glob_t);
@@ -3968,9 +4203,9 @@ extern {
                       result: *mut *mut passwd) -> ::c_int;
     pub fn sigwait(set: *const sigset_t,
                    sig: *mut ::c_int) -> ::c_int;
-    pub fn pthread_atfork(prepare: Option<unsafe extern fn()>,
-                          parent: Option<unsafe extern fn()>,
-                          child: Option<unsafe extern fn()>) -> ::c_int;
+    pub fn pthread_atfork(prepare: ::Option<unsafe extern fn()>,
+                          parent: ::Option<unsafe extern fn()>,
+                          child: ::Option<unsafe extern fn()>) -> ::c_int;
     pub fn getgrgid(gid: ::gid_t) -> *mut ::group;
     pub fn getgrouplist(user: *const ::c_char,
                         group: ::gid_t,
@@ -3987,7 +4222,7 @@ extern {
                           f: extern fn(*mut ::c_void) -> *mut ::c_void,
                           value: *mut ::c_void) -> ::c_int;
     pub fn dl_iterate_phdr(
-        callback: Option<unsafe extern fn(
+        callback: ::Option<unsafe extern fn(
             info: *mut ::dl_phdr_info,
             size: ::size_t,
             data: *mut ::c_void
diff --git a/src/fuchsia/no_align.rs b/src/fuchsia/no_align.rs
index 1b8db5354eb8b8558858f7cb22a44f9e2fc12407..437da97ee0626382ff5ed06322bf90b725034bd0 100644
--- a/src/fuchsia/no_align.rs
+++ b/src/fuchsia/no_align.rs
@@ -21,7 +21,6 @@ macro_rules! expand_align {
         }
 
         s_no_extra_traits! {
-            #[allow(missing_debug_implementations)]
             pub struct pthread_mutex_t {
                 #[cfg(any(target_arch = "arm",
                           all(target_arch = "x86_64",
@@ -34,14 +33,12 @@ macro_rules! expand_align {
                 size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T],
             }
 
-            #[allow(missing_debug_implementations)]
             pub struct pthread_rwlock_t {
                 __align: [::c_long; 0],
                 __align: [::c_longlong; 0],
                 size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T],
             }
 
-            #[allow(missing_debug_implementations)]
             pub struct pthread_cond_t {
                 __align: [*const ::c_void; 0],
                 #[cfg(not(target_env = "musl"))]
@@ -49,5 +46,84 @@ macro_rules! expand_align {
                 size: [u8; ::__SIZEOF_PTHREAD_COND_T],
             }
         }
+
+        cfg_if! {
+            if #[cfg(feature = "extra_traits")] {
+                impl PartialEq for pthread_cond_t {
+                    fn eq(&self, other: &pthread_cond_t) -> bool {
+                        // Ignore __align field
+                        self.size
+                            .iter()
+                            .zip(other.size.iter())
+                            .all(|(a,b)| a == b)
+                    }
+                }
+                impl Eq for pthread_cond_t {}
+                impl ::fmt::Debug for pthread_cond_t {
+                    fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                        f.debug_struct("pthread_cond_t")
+                            // Ignore __align field
+                            // FIXME: .field("size", &self.size)
+                            .finish()
+                    }
+                }
+                impl ::hash::Hash for pthread_cond_t {
+                    fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                        // Ignore __align field
+                        self.size.hash(state);
+                    }
+                }
+
+                impl PartialEq for pthread_mutex_t {
+                    fn eq(&self, other: &pthread_mutex_t) -> bool {
+                        // Ignore __align field
+                        self.size
+                            .iter()
+                            .zip(other.size.iter())
+                            .all(|(a,b)| a == b)
+                    }
+                }
+                impl Eq for pthread_mutex_t {}
+                impl ::fmt::Debug for pthread_mutex_t {
+                    fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                        f.debug_struct("pthread_mutex_t")
+                            // Ignore __align field
+                            // FIXME: .field("size", &self.size)
+                            .finish()
+                    }
+                }
+                impl ::hash::Hash for pthread_mutex_t {
+                    fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                        // Ignore __align field
+                        self.size.hash(state);
+                    }
+                }
+
+                impl PartialEq for pthread_rwlock_t {
+                    fn eq(&self, other: &pthread_rwlock_t) -> bool {
+                        // Ignore __align field
+                        self.size
+                            .iter()
+                            .zip(other.size.iter())
+                            .all(|(a,b)| a == b)
+                    }
+                }
+                impl Eq for pthread_rwlock_t {}
+                impl ::fmt::Debug for pthread_rwlock_t {
+                    fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                        f.debug_struct("pthread_rwlock_t")
+                            // Ignore __align field
+                            // FIXME: .field("size", &self.size)
+                            .finish()
+                    }
+                }
+                impl ::hash::Hash for pthread_rwlock_t {
+                    fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                        // Ignore __align field
+                        self.size.hash(state);
+                    }
+                }
+            }
+        }
     }
 }
diff --git a/src/fuchsia/x86_64.rs b/src/fuchsia/x86_64.rs
index 8c0dc55ac2b8faaefda30e7ce1ce636f2f5500a1..eb220998e870a5b1637c9a339a738b53054d8c87 100644
--- a/src/fuchsia/x86_64.rs
+++ b/src/fuchsia/x86_64.rs
@@ -65,7 +65,6 @@ s! {
 }
 
 s_no_extra_traits! {
-    #[allow(missing_debug_implementations)]
     pub struct ucontext_t {
         pub uc_flags: ::c_ulong,
         pub uc_link: *mut ucontext_t,
@@ -76,6 +75,48 @@ s_no_extra_traits! {
     }
 }
 
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for ucontext_t {
+            fn eq(&self, other: &ucontext_t) -> bool {
+                self.uc_flags == other.uc_flags
+                    && self.uc_link == other.uc_link
+                    && self.uc_stack == other.uc_stack
+                    && self.uc_mcontext == other.uc_mcontext
+                    && self.uc_sigmask == other.uc_sigmask
+                    && self
+                    .__private
+                    .iter()
+                    .zip(other.__private.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for ucontext_t {}
+        impl ::fmt::Debug for ucontext_t {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("ucontext_t")
+                    .field("uc_flags", &self.uc_flags)
+                    .field("uc_link", &self.uc_link)
+                    .field("uc_stack", &self.uc_stack)
+                    .field("uc_mcontext", &self.uc_mcontext)
+                    .field("uc_sigmask", &self.uc_sigmask)
+                    // FIXME: .field("__private", &self.__private)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for ucontext_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.uc_flags.hash(state);
+                self.uc_link.hash(state);
+                self.uc_stack.hash(state);
+                self.uc_mcontext.hash(state);
+                self.uc_sigmask.hash(state);
+                self.__private.hash(state);
+            }
+        }
+    }
+}
+
 // Syscall table
 
 pub const SYS_read: ::c_long = 0;
diff --git a/src/lib.rs b/src/lib.rs
index b2e8eb0dc9103e20d73714c077ef5d7f75862818..6969d350d7235ee0941efbf898d4b88269619fbc 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -7,163 +7,25 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-
-//! Crate docs
-
-#![allow(bad_style, overflowing_literals, improper_ctypes, unknown_lints)]
-#![crate_type = "rlib"]
+//! libc - Raw FFI bindings to platforms' system libraries
+//!
+//! [Documentation for other platforms][pd].
+//!
+//! [pd]: https://rust-lang.github.io/libc/#platform-specific-documentation
 #![crate_name = "libc"]
-#![cfg_attr(cross_platform_docs, feature(no_core, lang_items, const_fn))]
-#![cfg_attr(cross_platform_docs, no_core)]
-#![doc(
-    html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
-    html_favicon_url = "https://doc.rust-lang.org/favicon.ico"
-)]
-#![cfg_attr(
-    all(target_os = "linux", target_arch = "x86_64"),
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/x86_64-unknown-linux-gnu"
-    )
-)]
-#![cfg_attr(
-    all(target_os = "linux", target_arch = "x86"),
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/i686-unknown-linux-gnu"
-    )
-)]
-#![cfg_attr(
-    all(target_os = "linux", target_arch = "arm"),
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/arm-unknown-linux-gnueabihf"
-    )
-)]
-#![cfg_attr(
-    all(target_os = "linux", target_arch = "mips"),
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/mips-unknown-linux-gnu"
-    )
-)]
-#![cfg_attr(
-    all(target_os = "linux", target_arch = "aarch64"),
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/aarch64-unknown-linux-gnu"
-    )
-)]
-#![cfg_attr(
-    all(target_os = "linux", target_env = "musl"),
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/x86_64-unknown-linux-musl"
-    )
-)]
-#![cfg_attr(
-    all(target_os = "macos", target_arch = "x86_64"),
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/x86_64-apple-darwin"
-    )
-)]
-#![cfg_attr(
-    all(target_os = "macos", target_arch = "x86"),
-    doc(html_root_url = "https://rust-lang.github.io/libc/i686-apple-darwin")
-)]
-#![cfg_attr(
-    all(windows, target_arch = "x86_64", target_env = "gnu"),
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/x86_64-pc-windows-gnu"
-    )
-)]
-#![cfg_attr(
-    all(windows, target_arch = "x86", target_env = "gnu"),
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/i686-pc-windows-gnu"
-    )
-)]
-#![cfg_attr(
-    all(windows, target_arch = "x86_64", target_env = "msvc"),
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/x86_64-pc-windows-msvc"
-    )
-)]
-#![cfg_attr(
-    all(windows, target_arch = "x86", target_env = "msvc"),
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/i686-pc-windows-msvc"
-    )
-)]
-#![cfg_attr(
-    target_os = "android",
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/arm-linux-androideabi"
-    )
-)]
-#![cfg_attr(
-    target_os = "freebsd",
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/x86_64-unknown-freebsd"
-    )
-)]
-#![cfg_attr(
-    target_os = "openbsd",
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/x86_64-unknown-openbsd"
-    )
-)]
-#![cfg_attr(
-    target_os = "bitrig",
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/x86_64-unknown-bitrig"
-    )
-)]
-#![cfg_attr(
-    target_os = "netbsd",
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/x86_64-unknown-netbsd"
-    )
-)]
-#![cfg_attr(
-    target_os = "dragonfly",
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/x86_64-unknown-dragonfly"
-    )
-)]
-#![cfg_attr(
-    target_os = "solaris",
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/x86_64-sun-solaris"
-    )
-)]
-#![cfg_attr(
-    all(target_os = "emscripten", target_arch = "asmjs"),
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/asmjs-unknown-emscripten"
-    )
-)]
-#![cfg_attr(
-    all(target_os = "emscripten", target_arch = "wasm32"),
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/wasm32-unknown-emscripten"
-    )
-)]
-#![cfg_attr(
-    all(target_os = "linux", target_arch = "sparc64"),
-    doc(
-        html_root_url = "https://rust-lang.github.io/libc/sparc64-unknown-linux-gnu"
-    )
-)]
+#![crate_type = "rlib"]
+#![cfg_attr(not(feature = "rustc-dep-of-std"), deny(warnings))]
+#![allow(bad_style, overflowing_literals, improper_ctypes, unknown_lints)]
 // Attributes needed when building as part of the standard library
-#![cfg_attr(feature = "rustc-dep-of-std", feature(cfg_target_vendor))]
-#![cfg_attr(feature = "rustc-dep-of-std", feature(link_cfg))]
-#![cfg_attr(feature = "rustc-dep-of-std", feature(no_core))]
-#![cfg_attr(feature = "rustc-dep-of-std", no_core)]
-#![cfg_attr(feature = "rustc-dep-of-std", allow(warnings))]
 #![cfg_attr(
-    not(any(feature = "use_std", feature = "rustc-dep-of-std")),
-    no_std
+    feature = "rustc-dep-of-std",
+    feature(cfg_target_vendor, link_cfg, no_core)
 )]
-// Enable lints
+// Enable extra lints:
 #![cfg_attr(feature = "extra_traits", deny(missing_debug_implementations))]
 #![deny(missing_copy_implementations, safe_packed_borrows)]
-#[cfg(all(not(cross_platform_docs), feature = "use_std"))]
-extern crate std as core;
+#![no_std]
+#![cfg_attr(feature = "rustc-dep-of-std", no_core)]
 
 #[macro_use]
 mod macros;
@@ -179,40 +41,52 @@ cfg_if! {
 }
 
 cfg_if! {
-    if #[cfg(not(cross_platform_docs))] {
-        cfg_if! {
-            if #[cfg(libc_priv_mod_use)] {
-                #[cfg(libc_core_cvoid)]
-                #[allow(unused_imports)]
-                use core::ffi;
-                #[allow(unused_imports)]
-                use core::fmt;
-                #[allow(unused_imports)]
-                use core::hash;
-                #[allow(unused_imports)]
-                use core::num;
-                #[allow(unused_imports)]
-                use core::mem;
-            } else {
-                #[doc(hidden)]
-                #[allow(unused_imports)]
-                pub use core::fmt;
-                #[doc(hidden)]
-                #[allow(unused_imports)]
-                pub use core::hash;
-                #[doc(hidden)]
-                #[allow(unused_imports)]
-                pub use core::num;
-                #[doc(hidden)]
-                #[allow(unused_imports)]
-                pub use core::mem;
-            }
-        }
+    if #[cfg(libc_priv_mod_use)] {
+        #[cfg(libc_core_cvoid)]
+        #[allow(unused_imports)]
+        use core::ffi;
+        #[allow(unused_imports)]
+        use core::fmt;
+        #[allow(unused_imports)]
+        use core::hash;
+        #[allow(unused_imports)]
+        use core::num;
+        #[allow(unused_imports)]
+        use core::mem;
+        #[doc(hidden)]
+        #[allow(unused_imports)]
+        use core::clone::Clone;
+        #[doc(hidden)]
+        #[allow(unused_imports)]
+        use core::marker::Copy;
+        #[doc(hidden)]
+        #[allow(unused_imports)]
+        use core::option::Option;
+    } else {
+        #[doc(hidden)]
+        #[allow(unused_imports)]
+        pub use core::fmt;
+        #[doc(hidden)]
+        #[allow(unused_imports)]
+        pub use core::hash;
+        #[doc(hidden)]
+        #[allow(unused_imports)]
+        pub use core::num;
+        #[doc(hidden)]
+        #[allow(unused_imports)]
+        pub use core::mem;
+        #[doc(hidden)]
+        #[allow(unused_imports)]
+        pub use core::clone::Clone;
+        #[doc(hidden)]
+        #[allow(unused_imports)]
+        pub use core::marker::Copy;
+        #[doc(hidden)]
+        #[allow(unused_imports)]
+        pub use core::option::Option;
     }
 }
 
-mod dox;
-
 cfg_if! {
     if #[cfg(windows)] {
         mod windows;
diff --git a/src/macros.rs b/src/macros.rs
index 89eaeb5e0315712f3f8ef6b7ff02ae89b1ae1d5d..c48ae8bc40b416a99a8b30dadb02bc0d54f044a6 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -77,8 +77,8 @@ macro_rules! s {
             $(#[$attr])*
             pub struct $i { $($field)* }
         }
-        impl ::dox::Copy for $i {}
-        impl ::dox::Clone for $i {
+        impl ::Copy for $i {}
+        impl ::Clone for $i {
             fn clone(&self) -> $i { *self }
         }
     );
@@ -98,8 +98,8 @@ macro_rules! s_no_extra_traits {
                     pub union $i { $($field)* }
                 }
 
-                impl ::dox::Copy for $i {}
-                impl ::dox::Clone for $i {
+                impl ::Copy for $i {}
+                impl ::Clone for $i {
                     fn clone(&self) -> $i { *self }
                 }
             }
@@ -111,8 +111,8 @@ macro_rules! s_no_extra_traits {
             $(#[$attr])*
             pub struct $i { $($field)* }
         }
-        impl ::dox::Copy for $i {}
-        impl ::dox::Clone for $i {
+        impl ::Copy for $i {}
+        impl ::Clone for $i {
             fn clone(&self) -> $i { *self }
         }
     );
@@ -124,16 +124,9 @@ macro_rules! f {
         $($body:stmt);*
     })*) => ($(
         #[inline]
-        #[cfg(not(cross_platform_docs))]
         pub unsafe extern fn $i($($arg: $argty),*) -> $ret {
             $($body);*
         }
-
-        #[cfg(cross_platform_docs)]
-        #[allow(dead_code)]
-        pub unsafe extern fn $i($($arg: $argty),*) -> $ret {
-            loop {}
-        }
     )*)
 }
 
diff --git a/src/redox/mod.rs b/src/redox/mod.rs
index cde619e98726e250a60f2036235c514e26cef504..ac0ae00bce10d63936fcc5ab42b307df9a6ad27f 100644
--- a/src/redox/mod.rs
+++ b/src/redox/mod.rs
@@ -221,14 +221,14 @@ pub const SIGSYS:    ::c_int = 31;
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum FILE {}
-impl ::dox::Copy for FILE {}
-impl ::dox::Clone for FILE {
+impl ::Copy for FILE {}
+impl ::Clone for FILE {
     fn clone(&self) -> FILE { *self }
 }
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum fpos_t {} // TODO: fill this out with a struct
-impl ::dox::Copy for fpos_t {}
-impl ::dox::Clone for fpos_t {
+impl ::Copy for fpos_t {}
+impl ::Clone for fpos_t {
     fn clone(&self) -> fpos_t { *self }
 }
 
diff --git a/src/unix/bsd/apple/mod.rs b/src/unix/bsd/apple/mod.rs
index 670ef568b64351c6ec80a33b5edd6dc5f224c30c..8ae593779cdefdec3321c12a80f0fe62cf98f72a 100644
--- a/src/unix/bsd/apple/mod.rs
+++ b/src/unix/bsd/apple/mod.rs
@@ -1,8 +1,6 @@
 //! Apple (ios/darwin)-specific definitions
 //!
 //! This covers *-apple-* triples currently
-use dox::mem;
-
 pub type c_char = i8;
 pub type clock_t = c_ulong;
 pub type time_t = c_long;
@@ -36,8 +34,8 @@ pub type shmatt_t = ::c_ushort;
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum timezone {}
-impl ::dox::Copy for timezone {}
-impl ::dox::Clone for timezone {
+impl ::Copy for timezone {}
+impl ::Clone for timezone {
     fn clone(&self) -> timezone { *self }
 }
 
@@ -141,6 +139,7 @@ s! {
     }
 
     pub struct sigaction {
+        // FIXME: this field is actually a union
         pub sa_sigaction: ::sighandler_t,
         pub sa_mask: sigset_t,
         pub sa_flags: ::c_int,
@@ -484,8 +483,6 @@ s! {
 }
 
 s_no_extra_traits!{
-    // FIXME: https://github.com/rust-lang/libc/issues/1243
-    #[allow(missing_debug_implementations)]
     #[cfg_attr(libc_packedN, repr(packed(4)))]
     pub struct kevent {
         pub ident: ::uintptr_t,
@@ -496,8 +493,6 @@ s_no_extra_traits!{
         pub udata: *mut ::c_void,
     }
 
-    // FIXME: https://github.com/rust-lang/libc/issues/1243
-    #[allow(missing_debug_implementations)]
     #[cfg_attr(libc_packedN, repr(packed(4)))]
     pub struct semid_ds {
         // Note the manpage shows different types than the system header.
@@ -511,8 +506,6 @@ s_no_extra_traits!{
         pub sem_pad3: [::int32_t; 4],
     }
 
-    // FIXME: https://github.com/rust-lang/libc/issues/1243
-    #[allow(missing_debug_implementations)]
     #[cfg_attr(libc_packedN, repr(packed(4)))]
     pub struct shmid_ds {
         pub shm_perm: ipc_perm,
@@ -642,6 +635,175 @@ cfg_if! {
 
 cfg_if! {
     if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for kevent {
+            fn eq(&self, other: &kevent) -> bool {
+                self.ident == other.ident
+                    && self.filter == other.filter
+                    && self.flags == other.flags
+                    && self.fflags == other.fflags
+                    && self.data == other.data
+                    && self.udata == other.udata
+            }
+        }
+        impl Eq for kevent {}
+        impl ::fmt::Debug for kevent {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                let ident = self.ident;
+                let filter = self.filter;
+                let flags = self.flags;
+                let fflags = self.fflags;
+                let data = self.data;
+                let udata = self.udata;
+                f.debug_struct("kevent")
+                    .field("ident", &ident)
+                    .field("filter", &filter)
+                    .field("flags", &flags)
+                    .field("fflags", &fflags)
+                    .field("data", &data)
+                    .field("udata", &udata)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for kevent {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                let ident = self.ident;
+                let filter = self.filter;
+                let flags = self.flags;
+                let fflags = self.fflags;
+                let data = self.data;
+                let udata = self.udata;
+                ident.hash(state);
+                filter.hash(state);
+                flags.hash(state);
+                fflags.hash(state);
+                data.hash(state);
+                udata.hash(state);
+            }
+        }
+
+        impl PartialEq for semid_ds {
+            fn eq(&self, other: &semid_ds) -> bool {
+                let sem_perm = self.sem_perm;
+                let sem_pad3 = self.sem_pad3;
+                let other_sem_perm = other.sem_perm;
+                let other_sem_pad3 = other.sem_pad3;
+                sem_perm == other_sem_perm
+                    && self.sem_base == other.sem_base
+                    && self.sem_nsems == other.sem_nsems
+                    && self.sem_otime == other.sem_otime
+                    && self.sem_pad1 == other.sem_pad1
+                    && self.sem_ctime == other.sem_ctime
+                    && self.sem_pad2 == other.sem_pad2
+                    && sem_pad3 == other_sem_pad3
+            }
+        }
+        impl Eq for semid_ds {}
+        impl ::fmt::Debug for semid_ds {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                let sem_perm = self.sem_perm;
+                let sem_base = self.sem_base;
+                let sem_nsems = self.sem_nsems;
+                let sem_otime = self.sem_otime;
+                let sem_pad1 = self.sem_pad1;
+                let sem_ctime = self.sem_ctime;
+                let sem_pad2 = self.sem_pad2;
+                let sem_pad3 = self.sem_pad3;
+                f.debug_struct("semid_ds")
+                    .field("sem_perm", &sem_perm)
+                    .field("sem_base", &sem_base)
+                    .field("sem_nsems", &sem_nsems)
+                    .field("sem_otime", &sem_otime)
+                    .field("sem_pad1", &sem_pad1)
+                    .field("sem_ctime", &sem_ctime)
+                    .field("sem_pad2", &sem_pad2)
+                    .field("sem_pad3", &sem_pad3)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for semid_ds {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                let sem_perm = self.sem_perm;
+                let sem_base = self.sem_base;
+                let sem_nsems = self.sem_nsems;
+                let sem_otime = self.sem_otime;
+                let sem_pad1 = self.sem_pad1;
+                let sem_ctime = self.sem_ctime;
+                let sem_pad2 = self.sem_pad2;
+                let sem_pad3 = self.sem_pad3;
+                sem_perm.hash(state);
+                sem_base.hash(state);
+                sem_nsems.hash(state);
+                sem_otime.hash(state);
+                sem_pad1.hash(state);
+                sem_ctime.hash(state);
+                sem_pad2.hash(state);
+                sem_pad3.hash(state);
+            }
+        }
+
+        impl PartialEq for shmid_ds {
+            fn eq(&self, other: &shmid_ds) -> bool {
+                let shm_perm = self.shm_perm;
+                let other_shm_perm = other.shm_perm;
+                shm_perm == other_shm_perm
+                    && self.shm_segsz == other.shm_segsz
+                    && self.shm_lpid == other.shm_lpid
+                    && self.shm_cpid == other.shm_cpid
+                    && self.shm_nattch == other.shm_nattch
+                    && self.shm_atime == other.shm_atime
+                    && self.shm_dtime == other.shm_dtime
+                    && self.shm_ctime == other.shm_ctime
+                    && self.shm_internal == other.shm_internal
+            }
+        }
+        impl Eq for shmid_ds {}
+        impl ::fmt::Debug for shmid_ds {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                let shm_perm = self.shm_perm;
+                let shm_segsz = self.shm_segsz;
+                let shm_lpid = self.shm_lpid;
+                let shm_cpid = self.shm_cpid;
+                let shm_nattch = self.shm_nattch;
+                let shm_atime = self.shm_atime;
+                let shm_dtime = self.shm_dtime;
+                let shm_ctime = self.shm_ctime;
+                let shm_internal = self.shm_internal;
+                f.debug_struct("shmid_ds")
+                    .field("shm_perm", &shm_perm)
+                    .field("shm_segsz", &shm_segsz)
+                    .field("shm_lpid", &shm_lpid)
+                    .field("shm_cpid", &shm_cpid)
+                    .field("shm_nattch", &shm_nattch)
+                    .field("shm_atime", &shm_atime)
+                    .field("shm_dtime", &shm_dtime)
+                    .field("shm_ctime", &shm_ctime)
+                    .field("shm_internal", &shm_internal)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for shmid_ds {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                let shm_perm = self.shm_perm;
+                let shm_segsz = self.shm_segsz;
+                let shm_lpid = self.shm_lpid;
+                let shm_cpid = self.shm_cpid;
+                let shm_nattch = self.shm_nattch;
+                let shm_atime = self.shm_atime;
+                let shm_dtime = self.shm_dtime;
+                let shm_ctime = self.shm_ctime;
+                let shm_internal = self.shm_internal;
+                shm_perm.hash(state);
+                shm_segsz.hash(state);
+                shm_lpid.hash(state);
+                shm_cpid.hash(state);
+                shm_nattch.hash(state);
+                shm_atime.hash(state);
+                shm_dtime.hash(state);
+                shm_ctime.hash(state);
+                shm_internal.hash(state);
+            }
+        }
+
         impl PartialEq for proc_threadinfo {
             fn eq(&self, other: &proc_threadinfo) -> bool {
                 self.pth_user_time == other.pth_user_time
@@ -678,7 +840,6 @@ cfg_if! {
                     .finish()
             }
         }
-
         impl ::hash::Hash for proc_threadinfo {
             fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
                 self.pth_user_time.hash(state);
@@ -2257,12 +2418,14 @@ pub const NOTE_NONE: ::uint32_t = 0x00000080;
 pub const NOTE_EXIT: ::uint32_t = 0x80000000;
 pub const NOTE_FORK: ::uint32_t = 0x40000000;
 pub const NOTE_EXEC: ::uint32_t = 0x20000000;
+#[deprecated(since="0.2.49", note="Deprecated since MacOSX 10.9")]
 pub const NOTE_REAP: ::uint32_t = 0x10000000;
 pub const NOTE_SIGNAL: ::uint32_t = 0x08000000;
 pub const NOTE_EXITSTATUS: ::uint32_t = 0x04000000;
 pub const NOTE_EXIT_DETAIL: ::uint32_t = 0x02000000;
 pub const NOTE_PDATAMASK: ::uint32_t = 0x000fffff;
 pub const NOTE_PCTRLMASK: ::uint32_t = 0xfff00000;
+#[deprecated(since="0.2.49", note="Deprecated since MacOSX 10.9")]
 pub const NOTE_EXIT_REPARENTED: ::uint32_t = 0x00080000;
 pub const NOTE_EXIT_DETAIL_MASK: ::uint32_t = 0x00070000;
 pub const NOTE_EXIT_DECRYPTFAIL: ::uint32_t = 0x00010000;
@@ -2468,7 +2631,9 @@ pub const KERN_KDSETRTCDEC: ::c_int = 15;
 pub const KERN_KDGETENTROPY: ::c_int = 16;
 pub const KERN_KDWRITETR: ::c_int = 17;
 pub const KERN_KDWRITEMAP: ::c_int = 18;
+#[deprecated(since = "0.2.49", note ="Removed in MacOSX 10.12")]
 pub const KERN_KDENABLE_BG_TRACE: ::c_int = 19;
+#[deprecated(since = "0.2.49", note ="Removed in MacOSX 10.12")]
 pub const KERN_KDDISABLE_BG_TRACE: ::c_int = 20;
 pub const KERN_KDREADCURTHRMAP: ::c_int = 21;
 pub const KERN_KDSET_TYPEFILTER: ::c_int = 22;
@@ -2782,12 +2947,12 @@ pub const UF_HIDDEN:        ::c_uint = 0x00008000;
 cfg_if! {
     if #[cfg(libc_const_size_of)] {
         fn __DARWIN_ALIGN32(p: usize) -> usize {
-            const __DARWIN_ALIGNBYTES32: usize = mem::size_of::<u32>() - 1;
+            const __DARWIN_ALIGNBYTES32: usize = ::mem::size_of::<u32>() - 1;
             p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32
         }
     } else {
         fn __DARWIN_ALIGN32(p: usize) -> usize {
-            let __DARWIN_ALIGNBYTES32: usize = mem::size_of::<u32>() - 1;
+            let __DARWIN_ALIGNBYTES32: usize = ::mem::size_of::<u32>() - 1;
             p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32
         }
     }
@@ -2803,7 +2968,7 @@ f! {
         let next = cmsg as usize + __DARWIN_ALIGN32(cmsg_len as usize);
         let max = (*mhdr).msg_control as usize
                    + (*mhdr).msg_controllen as usize;
-        if next + __DARWIN_ALIGN32(mem::size_of::<::cmsghdr>()) > max {
+        if next + __DARWIN_ALIGN32(::mem::size_of::<::cmsghdr>()) > max {
             0 as *mut ::cmsghdr
         } else {
             next as *mut ::cmsghdr
@@ -2812,17 +2977,17 @@ f! {
 
     pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar {
         (cmsg as *mut ::c_uchar)
-            .offset(__DARWIN_ALIGN32(mem::size_of::<::cmsghdr>()) as isize)
+            .offset(__DARWIN_ALIGN32(::mem::size_of::<::cmsghdr>()) as isize)
     }
 
     pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
-        (__DARWIN_ALIGN32(mem::size_of::<::cmsghdr>())
+        (__DARWIN_ALIGN32(::mem::size_of::<::cmsghdr>())
             + __DARWIN_ALIGN32(length as usize))
             as ::c_uint
     }
 
     pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
-        (__DARWIN_ALIGN32(mem::size_of::<::cmsghdr>()) + length as usize)
+        (__DARWIN_ALIGN32(::mem::size_of::<::cmsghdr>()) + length as usize)
             as ::c_uint
     }
 
@@ -2848,6 +3013,16 @@ f! {
 }
 
 extern {
+    #[deprecated(since="0.2.49", note="Deprecated in MacOSX 10.5")]
+    #[link_name = "daemon$1050"]
+    pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int;
+    #[deprecated(since="0.2.49", note="Deprecated in MacOSX 10.10")]
+    pub fn sem_destroy(sem: *mut sem_t) -> ::c_int;
+    #[deprecated(since="0.2.49", note="Deprecated in MacOSX 10.10")]
+    pub fn sem_init(sem: *mut sem_t,
+                    pshared: ::c_int,
+                    value: ::c_uint)
+                    -> ::c_int;
     pub fn aio_read(aiocbp: *mut aiocb) -> ::c_int;
     pub fn aio_write(aiocbp: *mut aiocb) -> ::c_int;
     pub fn aio_fsync(op: ::c_int, aiocbp: *mut aiocb) -> ::c_int;
diff --git a/src/unix/bsd/freebsdlike/dragonfly/mod.rs b/src/unix/bsd/freebsdlike/dragonfly/mod.rs
index 5656a26be67198384d6e596bb78e6c478b10a285..f0cbef9ce2d3a6f9328e1794a0fa77757f577a98 100644
--- a/src/unix/bsd/freebsdlike/dragonfly/mod.rs
+++ b/src/unix/bsd/freebsdlike/dragonfly/mod.rs
@@ -20,35 +20,17 @@ pub type sem_t = *mut sem;
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum sem {}
-impl ::dox::Copy for sem {}
-impl ::dox::Clone for sem {
+impl ::Copy for sem {}
+impl ::Clone for sem {
     fn clone(&self) -> sem { *self }
 }
 
 s! {
-
     pub struct exit_status {
         pub e_termination: u16,
         pub e_exit: u16
     }
 
-    pub struct utmpx {
-        pub ut_name: [::c_char; 32],
-        pub ut_id: [::c_char; 4],
-
-        pub ut_line: [::c_char; 32],
-        pub ut_host: [::c_char; 256],
-
-        pub ut_unused: [u8; 16],
-        pub ut_session: u16,
-        pub ut_type: u16,
-        pub ut_pid: ::pid_t,
-        ut_exit: exit_status,
-        ut_ss: ::sockaddr_storage,
-        pub ut_tv: ::timeval,
-        pub ut_unused2: [u8; 16],
-    }
-
     pub struct aiocb {
         pub aio_fildes: ::c_int,
         pub aio_offset: ::off_t,
@@ -61,15 +43,6 @@ s! {
         _aio_err: ::c_int
     }
 
-    pub struct dirent {
-        pub d_fileno: ::ino_t,
-        pub d_namlen: u16,
-        pub d_type: u8,
-        __unused1: u8,
-        __unused2: u32,
-        pub d_name: [::c_char; 256],
-    }
-
     pub struct uuid {
         pub time_low: u32,
         pub time_mid: u16,
@@ -121,27 +94,6 @@ s! {
         pub f_uid_uuid: ::uuid_t,
     }
 
-    pub struct statfs {
-        pub f_bsize: ::c_long,
-        pub f_iosize: ::c_long,
-        pub f_blocks: ::c_long,
-        pub f_bfree: ::c_long,
-        pub f_bavail: ::c_long,
-        pub f_files: ::c_long,
-        pub f_ffree: ::c_long,
-        pub f_fsid: ::fsid_t,
-        pub f_owner: ::uid_t,
-        pub f_type: ::int32_t,
-        pub f_flags: ::int32_t,
-        pub f_syncwrites: ::c_long,
-        pub f_asyncwrites: ::c_long,
-        pub f_fstypename: [::c_char; 16],
-        pub f_mntonname: [::c_char; 90],
-        pub f_syncreads: ::c_long,
-        pub f_asyncreads: ::c_long,
-        pub f_mntfromname: [::c_char; 90],
-    }
-
     pub struct stat {
         pub st_ino: ::ino_t,
         pub st_nlink: ::nlink_t,
@@ -224,6 +176,230 @@ s! {
     }
 }
 
+s_no_extra_traits! {
+    pub struct utmpx {
+        pub ut_name: [::c_char; 32],
+        pub ut_id: [::c_char; 4],
+
+        pub ut_line: [::c_char; 32],
+        pub ut_host: [::c_char; 256],
+
+        pub ut_unused: [u8; 16],
+        pub ut_session: u16,
+        pub ut_type: u16,
+        pub ut_pid: ::pid_t,
+        ut_exit: exit_status,
+        ut_ss: ::sockaddr_storage,
+        pub ut_tv: ::timeval,
+        pub ut_unused2: [u8; 16],
+    }
+
+    pub struct dirent {
+        pub d_fileno: ::ino_t,
+        pub d_namlen: u16,
+        pub d_type: u8,
+        __unused1: u8,
+        __unused2: u32,
+        pub d_name: [::c_char; 256],
+    }
+
+    pub struct statfs {
+        pub f_bsize: ::c_long,
+        pub f_iosize: ::c_long,
+        pub f_blocks: ::c_long,
+        pub f_bfree: ::c_long,
+        pub f_bavail: ::c_long,
+        pub f_files: ::c_long,
+        pub f_ffree: ::c_long,
+        pub f_fsid: ::fsid_t,
+        pub f_owner: ::uid_t,
+        pub f_type: ::int32_t,
+        pub f_flags: ::int32_t,
+        pub f_syncwrites: ::c_long,
+        pub f_asyncwrites: ::c_long,
+        pub f_fstypename: [::c_char; 16],
+        pub f_mntonname: [::c_char; 90],
+        pub f_syncreads: ::c_long,
+        pub f_asyncreads: ::c_long,
+        pub f_mntfromname: [::c_char; 90],
+    }
+}
+
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for utmpx {
+            fn eq(&self, other: &utmpx) -> bool {
+                self.ut_name == other.ut_name
+                    && self.ut_id == other.ut_id
+                    && self.ut_line == other.ut_line
+                    && self
+                    .ut_host
+                    .iter()
+                    .zip(other.ut_host.iter())
+                    .all(|(a,b)| a == b)
+                    && self.ut_unused == other.ut_unused
+                    && self.ut_session == other.ut_session
+                    && self.ut_type == other.ut_type
+                    && self.ut_pid == other.ut_pid
+                    && self.ut_exit == other.ut_exit
+                    && self.ut_ss == other.ut_ss
+                    && self.ut_tv == other.ut_tv
+                    && self.ut_unused2 == other.ut_unused2
+            }
+        }
+        impl Eq for utmpx {}
+        impl ::fmt::Debug for utmpx {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("utmpx")
+                    .field("ut_name", &self.ut_name)
+                    .field("ut_id", &self.ut_id)
+                    .field("ut_line", &self.ut_line)
+                    // FIXME: .field("ut_host", &self.ut_host)
+                    .field("ut_unused", &self.ut_unused)
+                    .field("ut_session", &self.ut_session)
+                    .field("ut_type", &self.ut_type)
+                    .field("ut_pid", &self.ut_pid)
+                    .field("ut_exit", &self.ut_exit)
+                    .field("ut_ss", &self.ut_ss)
+                    .field("ut_tv", &self.ut_tv)
+                    .field("ut_unused2", &self.ut_unused2)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for utmpx {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.ut_name.hash(state);
+                self.ut_id.hash(state);
+                self.ut_line.hash(state);
+                self.ut_host.hash(state);
+                self.ut_unused.hash(state);
+                self.ut_session.hash(state);
+                self.ut_type.hash(state);
+                self.ut_pid.hash(state);
+                self.ut_exit.hash(state);
+                self.ut_ss.hash(state);
+                self.ut_tv.hash(state);
+                self.ut_unused2.hash(state);
+            }
+        }
+
+        impl PartialEq for dirent {
+            fn eq(&self, other: &dirent) -> bool {
+                self.d_fileno == other.d_fileno
+                    && self.d_namlen == other.d_namlen
+                    && self.d_type == other.d_type
+                    // Ignore __unused1
+                    // Ignore __unused2
+                    && self
+                    .d_name
+                    .iter()
+                    .zip(other.d_name.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for dirent {}
+        impl ::fmt::Debug for dirent {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("dirent")
+                    .field("d_fileno", &self.d_fileno)
+                    .field("d_namlen", &self.d_namlen)
+                    .field("d_type", &self.d_type)
+                    // Ignore __unused1
+                    // Ignore __unused2
+                    // FIXME: .field("d_name", &self.d_name)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for dirent {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.d_fileno.hash(state);
+                self.d_namlen.hash(state);
+                self.d_type.hash(state);
+                    // Ignore __unused1
+                    // Ignore __unused2
+                self.d_name.hash(state);
+            }
+        }
+
+        impl PartialEq for statfs {
+            fn eq(&self, other: &statfs) -> bool {
+                self.f_bsize == other.f_bsize
+                    && self.f_iosize == other.f_iosize
+                    && self.f_blocks == other.f_blocks
+                    && self.f_bfree == other.f_bfree
+                    && self.f_bavail == other.f_bavail
+                    && self.f_files == other.f_files
+                    && self.f_ffree == other.f_ffree
+                    && self.f_fsid == other.f_fsid
+                    && self.f_owner == other.f_owner
+                    && self.f_type == other.f_type
+                    && self.f_flags == other.f_flags
+                    && self.f_syncwrites == other.f_syncwrites
+                    && self.f_asyncwrites == other.f_asyncwrites
+                    && self.f_fstypename == other.f_fstypename
+                    && self
+                    .f_mntonname
+                    .iter()
+                    .zip(other.f_mntonname.iter())
+                    .all(|(a,b)| a == b)
+                    && self.f_syncreads == other.f_syncreads
+                    && self.f_asyncreads == other.f_asyncreads
+                    && self
+                    .f_mntfromname
+                    .iter()
+                    .zip(other.f_mntfromname.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for statfs {}
+        impl ::fmt::Debug for statfs {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("statfs")
+                    .field("f_bsize", &self.f_bsize)
+                    .field("f_iosize", &self.f_iosize)
+                    .field("f_blocks", &self.f_blocks)
+                    .field("f_bfree", &self.f_bfree)
+                    .field("f_bavail", &self.f_bavail)
+                    .field("f_files", &self.f_files)
+                    .field("f_ffree", &self.f_ffree)
+                    .field("f_fsid", &self.f_fsid)
+                    .field("f_owner", &self.f_owner)
+                    .field("f_type", &self.f_type)
+                    .field("f_flags", &self.f_flags)
+                    .field("f_syncwrites", &self.f_syncwrites)
+                    .field("f_asyncwrites", &self.f_asyncwrites)
+                    // FIXME: .field("f_mntonname", &self.f_mntonname)
+                    .field("f_syncreads", &self.f_syncreads)
+                    .field("f_asyncreads", &self.f_asyncreads)
+                    // FIXME: .field("f_mntfromname", &self.f_mntfromname)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for statfs {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.f_bsize.hash(state);
+                self.f_iosize.hash(state);
+                self.f_blocks.hash(state);
+                self.f_bfree.hash(state);
+                self.f_bavail.hash(state);
+                self.f_files.hash(state);
+                self.f_ffree.hash(state);
+                self.f_fsid.hash(state);
+                self.f_owner.hash(state);
+                self.f_type.hash(state);
+                self.f_flags.hash(state);
+                self.f_syncwrites.hash(state);
+                self.f_asyncwrites.hash(state);
+                self.f_fstypename.hash(state);
+                self.f_mntonname.hash(state);
+                self.f_syncreads.hash(state);
+                self.f_asyncreads.hash(state);
+                self.f_mntfromname.hash(state);
+            }
+        }
+    }
+}
+
 pub const RAND_MAX: ::c_int = 0x7fff_ffff;
 pub const PTHREAD_STACK_MIN: ::size_t = 16384;
 pub const SIGSTKSZ: ::size_t = 40960;
@@ -801,29 +977,32 @@ fn _CMSG_ALIGN(n: usize) -> usize {
 f! {
     pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar {
         (cmsg as *mut ::c_uchar)
-            .offset(_CMSG_ALIGN(mem::size_of::<::cmsghdr>()) as isize)
+            .offset(_CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) as isize)
     }
 
     pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
-        _CMSG_ALIGN(mem::size_of::<::cmsghdr>()) + length as usize
+        (_CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) + length as usize)
+            as ::c_uint
     }
 
     pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr)
         -> *mut ::cmsghdr
     {
-        let next = cmsg as usize + _CMSG_ALIGN((*cmsg).cmsg_len)
-            + _CMSG_ALIGN(mem::size_of::<::cmsghdr>());
+        let next = cmsg as usize + _CMSG_ALIGN((*cmsg).cmsg_len as usize)
+            + _CMSG_ALIGN(::mem::size_of::<::cmsghdr>());
         let max = (*mhdr).msg_control as usize
             + (*mhdr).msg_controllen as usize;
         if next <= max {
-            (cmsg as usize + _CMSG_ALIGN((*cmsg).cmsg_len)) as *mut ::cmsghdr
+            (cmsg as usize + _CMSG_ALIGN((*cmsg).cmsg_len as usize))
+                as *mut ::cmsghdr
         } else {
             0 as *mut ::cmsghdr
         }
     }
 
     pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
-        _CMSG_ALIGN(mem::size_of::<::cmsghdr>()) + _CMSG_ALIGN(length as usize)
+        (_CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) +
+            _CMSG_ALIGN(length as usize)) as ::c_uint
     }
 }
 
diff --git a/src/unix/bsd/freebsdlike/freebsd/aarch64.rs b/src/unix/bsd/freebsdlike/freebsd/aarch64.rs
index dac614fd0a1cef594ab5df74b8d7c87b9720ad14..996abc5e3ad31807f3a2d64789e1f0c613c4ff6b 100644
--- a/src/unix/bsd/freebsdlike/freebsd/aarch64.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/aarch64.rs
@@ -1,5 +1,3 @@
-use dox::mem;
-
 pub type c_char = u8;
 pub type c_long = i64;
 pub type c_ulong = u64;
@@ -36,7 +34,7 @@ s! {
 cfg_if! {
     if #[cfg(libc_const_size_of)] {
         #[doc(hidden)]
-        pub const _ALIGNBYTES: usize = mem::size_of::<::c_longlong>() - 1;
+        pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_longlong>() - 1;
     } else {
         #[doc(hidden)]
         pub const _ALIGNBYTES: usize = 8 - 1;
diff --git a/src/unix/bsd/freebsdlike/freebsd/arm.rs b/src/unix/bsd/freebsdlike/freebsd/arm.rs
index 99a761eeef5287bd498e2d9cd8ed5a264c25ce6b..945aca98cff2df3b1a24c297ab382305b6a9096b 100644
--- a/src/unix/bsd/freebsdlike/freebsd/arm.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/arm.rs
@@ -38,7 +38,7 @@ s! {
 cfg_if! {
     if #[cfg(libc_const_size_of)] {
         #[doc(hidden)]
-        pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;
+        pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_int>() - 1;
     } else {
         #[doc(hidden)]
         pub const _ALIGNBYTES: usize = 4 - 1;
diff --git a/src/unix/bsd/freebsdlike/freebsd/mod.rs b/src/unix/bsd/freebsdlike/freebsd/mod.rs
index 0d0eb3f3b0ff5e674b9d4690d7c01aae1c3ccd7f..85816e97c387725051193e5153f21a218837192e 100644
--- a/src/unix/bsd/freebsdlike/freebsd/mod.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/mod.rs
@@ -1,5 +1,3 @@
-use dox::mem;
-
 pub type fflags_t = u32;
 pub type clock_t = i32;
 pub type ino_t = u32;
@@ -135,10 +133,14 @@ s! {
         pub ss_size: ::size_t,
         pub ss_flags: ::c_int,
     }
+
+    pub struct mmsghdr {
+        pub msg_hdr: ::msghdr,
+        pub msg_len: ::ssize_t,
+    }
 }
 
 s_no_extra_traits! {
-    #[allow(missing_debug_implementations)]
     pub struct utmpx {
         pub ut_type: ::c_short,
         pub ut_tv: ::timeval,
@@ -150,7 +152,6 @@ s_no_extra_traits! {
         pub __ut_spare: [::c_char; 64],
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct dirent {
         pub d_fileno: u32,
         pub d_reclen: u16,
@@ -159,7 +160,6 @@ s_no_extra_traits! {
         pub d_name: [::c_char; 256],
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct statfs {
         pub f_version: ::uint32_t,
         pub f_type: ::uint32_t,
@@ -185,7 +185,6 @@ s_no_extra_traits! {
         pub f_mntonname: [::c_char; 88],
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct sockaddr_dl {
         pub sdl_len: ::c_uchar,
         pub sdl_family: ::c_uchar,
@@ -198,6 +197,228 @@ s_no_extra_traits! {
     }
 }
 
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for utmpx {
+            fn eq(&self, other: &utmpx) -> bool {
+                self.ut_type == other.ut_type
+                    && self.ut_tv == other.ut_tv
+                    && self.ut_id == other.ut_id
+                    && self.ut_pid == other.ut_pid
+                    && self.ut_user == other.ut_user
+                    && self.ut_line == other.ut_line
+                    && self
+                    .ut_host
+                    .iter()
+                    .zip(other.ut_host.iter())
+                    .all(|(a,b)| a == b)
+                    && self
+                    .__ut_spare
+                    .iter()
+                    .zip(other.__ut_spare.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for utmpx {}
+        impl ::fmt::Debug for utmpx {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("utmpx")
+                    .field("ut_type", &self.ut_type)
+                    .field("ut_tv", &self.ut_tv)
+                    .field("ut_id", &self.ut_id)
+                    .field("ut_pid", &self.ut_pid)
+                    .field("ut_user", &self.ut_user)
+                    .field("ut_line", &self.ut_line)
+                    // FIXME: .field("ut_host", &self.ut_host)
+                    // FIXME: .field("__ut_spare", &self.__ut_spare)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for utmpx {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.ut_type.hash(state);
+                self.ut_tv.hash(state);
+                self.ut_id.hash(state);
+                self.ut_pid.hash(state);
+                self.ut_user.hash(state);
+                self.ut_line.hash(state);
+                self.ut_host.hash(state);
+                self.__ut_spare.hash(state);
+            }
+        }
+
+        impl PartialEq for dirent {
+            fn eq(&self, other: &dirent) -> bool {
+                self.d_fileno == other.d_fileno
+                    && self.d_reclen == other.d_reclen
+                    && self.d_type == other.d_type
+                    && self.d_namlen == other.d_namlen
+                    && self
+                    .d_name
+                    .iter()
+                    .zip(other.d_name.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for dirent {}
+        impl ::fmt::Debug for dirent {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("dirent")
+                    .field("d_fileno", &self.d_fileno)
+                    .field("d_reclen", &self.d_reclen)
+                    .field("d_type", &self.d_type)
+                    .field("d_namlen", &self.d_namlen)
+                    // FIXME: .field("d_name", &self.d_name)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for dirent {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.d_fileno.hash(state);
+                self.d_reclen.hash(state);
+                self.d_type.hash(state);
+                self.d_namlen.hash(state);
+                self.d_name.hash(state);
+            }
+        }
+
+        impl PartialEq for statfs {
+            fn eq(&self, other: &statfs) -> bool {
+                self.f_version == other.f_version
+                    && self.f_type == other.f_type
+                    && self.f_flags == other.f_flags
+                    && self.f_bsize == other.f_bsize
+                    && self.f_iosize == other.f_iosize
+                    && self.f_blocks == other.f_blocks
+                    && self.f_bfree == other.f_bfree
+                    && self.f_bavail == other.f_bavail
+                    && self.f_files == other.f_files
+                    && self.f_ffree == other.f_ffree
+                    && self.f_syncwrites == other.f_syncwrites
+                    && self.f_asyncwrites == other.f_asyncwrites
+                    && self.f_syncreads == other.f_syncreads
+                    && self.f_asyncreads == other.f_asyncreads
+                    && self.f_spare == other.f_spare
+                    && self.f_namemax == other.f_namemax
+                    && self.f_owner == other.f_owner
+                    && self.f_fsid == other.f_fsid
+                    && self
+                    .f_charspare
+                    .iter()
+                    .zip(other.f_charspare.iter())
+                    .all(|(a,b)| a == b)
+                    && self.f_fstypename == other.f_fstypename
+                    && self
+                    .f_mntfromname
+                    .iter()
+                    .zip(other.f_mntfromname.iter())
+                    .all(|(a,b)| a == b)
+                    && self
+                    .f_mntonname
+                    .iter()
+                    .zip(other.f_mntonname.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for statfs {}
+        impl ::fmt::Debug for statfs {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("statfs")
+                    .field("f_bsize", &self.f_bsize)
+                    .field("f_iosize", &self.f_iosize)
+                    .field("f_blocks", &self.f_blocks)
+                    .field("f_bfree", &self.f_bfree)
+                    .field("f_bavail", &self.f_bavail)
+                    .field("f_files", &self.f_files)
+                    .field("f_ffree", &self.f_ffree)
+                    .field("f_syncwrites", &self.f_syncwrites)
+                    .field("f_asyncwrites", &self.f_asyncwrites)
+                    .field("f_syncreads", &self.f_syncreads)
+                    .field("f_asyncreads", &self.f_asyncreads)
+                    .field("f_spare", &self.f_spare)
+                    .field("f_namemax", &self.f_namemax)
+                    .field("f_owner", &self.f_owner)
+                    .field("f_fsid", &self.f_fsid)
+                    // FIXME: .field("f_charspare", &self.f_charspare)
+                    .field("f_fstypename", &self.f_fstypename)
+                    // FIXME: .field("f_mntfromname", &self.f_mntfromname)
+                    // FIXME: .field("f_mntonname", &self.f_mntonname)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for statfs {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.f_version.hash(state);
+                self.f_type.hash(state);
+                self.f_flags.hash(state);
+                self.f_bsize.hash(state);
+                self.f_iosize.hash(state);
+                self.f_blocks.hash(state);
+                self.f_bfree.hash(state);
+                self.f_bavail.hash(state);
+                self.f_files.hash(state);
+                self.f_ffree.hash(state);
+                self.f_syncwrites.hash(state);
+                self.f_asyncwrites.hash(state);
+                self.f_syncreads.hash(state);
+                self.f_asyncreads.hash(state);
+                self.f_spare.hash(state);
+                self.f_namemax.hash(state);
+                self.f_owner.hash(state);
+                self.f_fsid.hash(state);
+                self.f_charspare.hash(state);
+                self.f_fstypename.hash(state);
+                self.f_mntfromname.hash(state);
+                self.f_mntonname.hash(state);
+            }
+        }
+
+        impl PartialEq for sockaddr_dl {
+            fn eq(&self, other: &sockaddr_dl) -> bool {
+                self.sdl_len == other.sdl_len
+                    && self.sdl_family == other.sdl_family
+                    && self.sdl_index == other.sdl_index
+                    && self.sdl_type == other.sdl_type
+                    && self.sdl_nlen == other.sdl_nlen
+                    && self.sdl_alen == other.sdl_alen
+                    && self.sdl_slen == other.sdl_slen
+                    && self
+                    .sdl_data
+                    .iter()
+                    .zip(other.sdl_data.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for sockaddr_dl {}
+        impl ::fmt::Debug for sockaddr_dl {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sockaddr_dl")
+                    .field("sdl_len", &self.sdl_len)
+                    .field("sdl_family", &self.sdl_family)
+                    .field("sdl_index", &self.sdl_index)
+                    .field("sdl_type", &self.sdl_type)
+                    .field("sdl_nlen", &self.sdl_nlen)
+                    .field("sdl_alen", &self.sdl_alen)
+                    .field("sdl_slen", &self.sdl_slen)
+                    // FIXME: .field("sdl_data", &self.sdl_data)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for sockaddr_dl {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.sdl_len.hash(state);
+                self.sdl_family.hash(state);
+                self.sdl_index.hash(state);
+                self.sdl_type.hash(state);
+                self.sdl_nlen.hash(state);
+                self.sdl_alen.hash(state);
+                self.sdl_slen.hash(state);
+                self.sdl_data.hash(state);
+            }
+        }
+    }
+}
+
 pub const SIGEV_THREAD_ID: ::c_int = 4;
 
 pub const EXTATTR_NAMESPACE_EMPTY: ::c_int = 0;
@@ -830,8 +1051,16 @@ 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;
@@ -983,11 +1212,11 @@ fn _ALIGN(p: usize) -> usize {
 f! {
     pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar {
         (cmsg as *mut ::c_uchar)
-            .offset(_ALIGN(mem::size_of::<::cmsghdr>()) as isize)
+            .offset(_ALIGN(::mem::size_of::<::cmsghdr>()) as isize)
     }
 
     pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
-        _ALIGN(mem::size_of::<::cmsghdr>()) as ::c_uint + length
+        _ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length
     }
 
     pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr)
@@ -997,7 +1226,7 @@ f! {
             return ::CMSG_FIRSTHDR(mhdr);
         };
         let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)
-            + _ALIGN(mem::size_of::<::cmsghdr>());
+            + _ALIGN(::mem::size_of::<::cmsghdr>());
         let max = (*mhdr).msg_control as usize
             + (*mhdr).msg_controllen as usize;
         if next > max {
@@ -1009,7 +1238,7 @@ f! {
     }
 
     pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
-        (_ALIGN(mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize))
+        (_ALIGN(::mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize))
             as ::c_uint
     }
 
@@ -1205,6 +1434,11 @@ 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;
+
+    pub fn sendmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::size_t,
+                    flags: ::c_int) -> ::ssize_t;
+    pub fn recvmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::size_t,
+                    flags: ::c_int, timeout: *const ::timespec) -> ::ssize_t;
 }
 
 #[link(name = "util")]
diff --git a/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs b/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs
index 517f2960240b8493cb0660b27fc3332f12868c12..9d893b69a34cf469402ea42d67a70ac4e615f7ce 100644
--- a/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs
@@ -34,7 +34,7 @@ s! {
 cfg_if! {
     if #[cfg(libc_const_size_of)] {
         #[doc(hidden)]
-        pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+        pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1;
     } else {
         #[doc(hidden)]
         pub const _ALIGNBYTES: usize = 8 - 1;
diff --git a/src/unix/bsd/freebsdlike/freebsd/x86.rs b/src/unix/bsd/freebsdlike/freebsd/x86.rs
index b31e3353618540705e18853760585783eec2cb27..845124d0422b5bc12c9b439e002b5ba020736e6b 100644
--- a/src/unix/bsd/freebsdlike/freebsd/x86.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/x86.rs
@@ -1,5 +1,3 @@
-use dox::mem;
-
 pub type c_char = i8;
 pub type c_long = i32;
 pub type c_ulong = u32;
@@ -37,7 +35,7 @@ s! {
 cfg_if! {
     if #[cfg(libc_const_size_of)] {
         #[doc(hidden)]
-        pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+        pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1;
     } else {
         #[doc(hidden)]
         pub const _ALIGNBYTES: usize = 8 - 1;
diff --git a/src/unix/bsd/freebsdlike/freebsd/x86_64.rs b/src/unix/bsd/freebsdlike/freebsd/x86_64.rs
index 89819fde3c8aa19dd6477e18ba250a35b2accac2..323d1ab7b31488edaecd2472a5708120c33341e4 100644
--- a/src/unix/bsd/freebsdlike/freebsd/x86_64.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/x86_64.rs
@@ -1,5 +1,3 @@
-use dox::mem;
-
 pub type c_char = i8;
 pub type c_long = i64;
 pub type c_ulong = u64;
@@ -36,7 +34,7 @@ s! {
 cfg_if! {
     if #[cfg(libc_const_size_of)] {
         #[doc(hidden)]
-        pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+        pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1;
     } else {
         #[doc(hidden)]
         pub const _ALIGNBYTES: usize = 8 - 1;
diff --git a/src/unix/bsd/freebsdlike/mod.rs b/src/unix/bsd/freebsdlike/mod.rs
index ca9ed982be5faad4210e7c1bf81bfa196895e4f3..1f4d3dd489349ce5c907dd1b6ad04bbadfc14840 100644
--- a/src/unix/bsd/freebsdlike/mod.rs
+++ b/src/unix/bsd/freebsdlike/mod.rs
@@ -17,8 +17,8 @@ pub type id_t = i64;
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum timezone {}
-impl ::dox::Copy for timezone {}
-impl ::dox::Clone for timezone {
+impl ::Copy for timezone {}
+impl ::Clone for timezone {
     fn clone(&self) -> timezone { *self }
 }
 
@@ -189,7 +189,6 @@ s! {
 }
 
 s_no_extra_traits! {
-    #[allow(missing_debug_implementations)]
     pub struct sockaddr_storage {
         pub ss_len: u8,
         pub ss_family: ::sa_family_t,
@@ -199,6 +198,45 @@ s_no_extra_traits! {
     }
 }
 
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for sockaddr_storage {
+            fn eq(&self, other: &sockaddr_storage) -> bool {
+                self.ss_len == other.ss_len
+                    && self.ss_family == other.ss_family
+                    && self.__ss_pad1 == other.__ss_pad1
+                    && self.__ss_align == other.__ss_align
+                    && self
+                    .__ss_pad2
+                    .iter()
+                    .zip(other.__ss_pad2.iter())
+                    .all(|(a, b)| a == b)
+            }
+        }
+        impl Eq for sockaddr_storage {}
+        impl ::fmt::Debug for sockaddr_storage {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sockaddr_storage")
+                    .field("ss_len", &self.ss_len)
+                    .field("ss_family", &self.ss_family)
+                    .field("__ss_pad1", &self.__ss_pad1)
+                    .field("__ss_align", &self.__ss_align)
+                    // FIXME: .field("__ss_pad2", &self.__ss_pad2)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for sockaddr_storage {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.ss_len.hash(state);
+                self.ss_family.hash(state);
+                self.__ss_pad1.hash(state);
+                self.__ss_align.hash(state);
+                self.__ss_pad2.hash(state);
+            }
+        }
+    }
+}
+
 pub const AIO_LISTIO_MAX: ::c_int = 16;
 pub const AIO_CANCELED: ::c_int = 1;
 pub const AIO_NOTCANCELED: ::c_int = 2;
@@ -1050,6 +1088,14 @@ f! {
 }
 
 extern {
+    pub fn sem_destroy(sem: *mut sem_t) -> ::c_int;
+    pub fn sem_init(sem: *mut sem_t,
+                    pshared: ::c_int,
+                    value: ::c_uint)
+                    -> ::c_int;
+
+    pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int;
+
     pub fn accept4(s: ::c_int, addr: *mut ::sockaddr,
                    addrlen: *mut ::socklen_t, flags: ::c_int) -> ::c_int;
     pub fn aio_read(aiocbp: *mut aiocb) -> ::c_int;
diff --git a/src/unix/bsd/mod.rs b/src/unix/bsd/mod.rs
index 8b5ec8c54d766b75a92339b12417026c8b9511f9..e1a2f416fdfc3e1a42b3c142ddc89d17a09a2b0f 100644
--- a/src/unix/bsd/mod.rs
+++ b/src/unix/bsd/mod.rs
@@ -1,5 +1,3 @@
-use dox::{mem, Option};
-
 pub type wchar_t = i32;
 pub type off_t = i64;
 pub type useconds_t = u32;
@@ -435,7 +433,7 @@ pub const POLLWRBAND: ::c_short = 0x100;
 
 f! {
     pub fn CMSG_FIRSTHDR(mhdr: *const ::msghdr) -> *mut ::cmsghdr {
-        if (*mhdr).msg_controllen as usize >= mem::size_of::<::cmsghdr>() {
+        if (*mhdr).msg_controllen as usize >= ::mem::size_of::<::cmsghdr>() {
             (*mhdr).msg_control as *mut ::cmsghdr
         } else {
             0 as *mut ::cmsghdr
@@ -443,20 +441,20 @@ f! {
     }
 
     pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () {
-        let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         let fd = fd as usize;
         (*set).fds_bits[fd / bits] &= !(1 << (fd % bits));
         return
     }
 
     pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool {
-        let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         let fd = fd as usize;
         return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0
     }
 
     pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () {
-        let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         let fd = fd as usize;
         (*set).fds_bits[fd / bits] |= 1 << (fd % bits);
         return
@@ -527,7 +525,7 @@ extern {
     #[cfg_attr(target_os = "freebsd", link_name = "glob@FBSD_1.0")]
     pub fn glob(pattern: *const ::c_char,
                 flags: ::c_int,
-                errfunc: Option<extern fn(epath: *const ::c_char,
+                errfunc: ::Option<extern fn(epath: *const ::c_char,
                                           errno: ::c_int) -> ::c_int>,
                 pglob: *mut ::glob_t) -> ::c_int;
     #[cfg_attr(target_os = "netbsd", link_name = "__globfree30")]
@@ -625,7 +623,6 @@ extern {
     pub fn pthread_cancel(thread: ::pthread_t) -> ::c_int;
     pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int;
     pub fn sem_unlink(name: *const ::c_char) -> ::c_int;
-    pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int;
     #[cfg_attr(target_os = "netbsd", link_name = "__getpwnam_r50")]
     #[cfg_attr(target_os = "solaris", link_name = "__posix_getpwnam_r")]
     pub fn getpwnam_r(name: *const ::c_char,
@@ -645,9 +642,9 @@ extern {
     #[cfg_attr(target_os = "solaris", link_name = "__posix_sigwait")]
     pub fn sigwait(set: *const sigset_t,
                    sig: *mut ::c_int) -> ::c_int;
-    pub fn pthread_atfork(prepare: Option<unsafe extern fn()>,
-                          parent: Option<unsafe extern fn()>,
-                          child: Option<unsafe extern fn()>) -> ::c_int;
+    pub fn pthread_atfork(prepare: ::Option<unsafe extern fn()>,
+                          parent: ::Option<unsafe extern fn()>,
+                          child: ::Option<unsafe extern fn()>) -> ::c_int;
     pub fn getgrgid(gid: ::gid_t) -> *mut ::group;
     #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
                link_name = "popen$UNIX2003")]
diff --git a/src/unix/bsd/netbsdlike/mod.rs b/src/unix/bsd/netbsdlike/mod.rs
index d03529662faa41c96a6bef6707def8986a181d44..3ef2e09e42510b23e05cb852c034ae1544764cc7 100644
--- a/src/unix/bsd/netbsdlike/mod.rs
+++ b/src/unix/bsd/netbsdlike/mod.rs
@@ -1,5 +1,3 @@
-use dox::mem;
-
 pub type time_t = i64;
 pub type mode_t = u32;
 pub type nlink_t = ::uint32_t;
@@ -15,14 +13,14 @@ pub type sem_t = *mut sem;
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum timezone {}
-impl ::dox::Copy for timezone {}
-impl ::dox::Clone for timezone {
+impl ::Copy for timezone {}
+impl ::Clone for timezone {
     fn clone(&self) -> timezone { *self }
 }
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum sem {}
-impl ::dox::Copy for sem {}
-impl ::dox::Clone for sem {
+impl ::Copy for sem {}
+impl ::Clone for sem {
     fn clone(&self) -> sem { *self }
 }
 
@@ -597,58 +595,15 @@ pub const SF_APPEND:        ::c_ulong = 0x00040000;
 
 pub const TIMER_ABSTIME: ::c_int = 1;
 
-fn _ALIGN(p: usize) -> usize {
-    (p + _ALIGNBYTES) & !_ALIGNBYTES
-}
-
-f! {
-    pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar {
-        (cmsg as *mut ::c_uchar)
-            .offset(_ALIGN(mem::size_of::<::cmsghdr>()) as isize)
-    }
-
-    pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
-        _ALIGN(mem::size_of::<::cmsghdr>()) as ::c_uint + length
-    }
-
-    pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr)
-        -> *mut ::cmsghdr
-    {
-        if cmsg.is_null() {
-            return ::CMSG_FIRSTHDR(mhdr);
-        };
-        let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)
-            + _ALIGN(mem::size_of::<::cmsghdr>());
-        let max = (*mhdr).msg_control as usize
-            + (*mhdr).msg_controllen as usize;
-        if next > max {
-            0 as *mut ::cmsghdr
-        } else {
-            (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize))
-                as *mut ::cmsghdr
-        }
-    }
-
-    pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
-        (_ALIGN(mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize))
-            as ::c_uint
-    }
-
-    pub fn WSTOPSIG(status: ::c_int) -> ::c_int {
-        status >> 8
-    }
-
-    pub fn WIFSIGNALED(status: ::c_int) -> bool {
-        (status & 0o177) != 0o177 && (status & 0o177) != 0
-    }
-
-    pub fn WIFSTOPPED(status: ::c_int) -> bool {
-        (status & 0o177) == 0o177
-    }
-}
-
 #[link(name = "util")]
 extern {
+    pub fn sem_destroy(sem: *mut sem_t) -> ::c_int;
+    pub fn sem_init(sem: *mut sem_t,
+                    pshared: ::c_int,
+                    value: ::c_uint)
+                    -> ::c_int;
+
+    pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int;
     pub fn mincore(addr: *mut ::c_void, len: ::size_t,
                    vec: *mut ::c_char) -> ::c_int;
     #[cfg_attr(target_os = "netbsd", link_name = "__clock_getres50")]
diff --git a/src/unix/bsd/netbsdlike/netbsd/aarch64.rs b/src/unix/bsd/netbsdlike/netbsd/aarch64.rs
index e30d731bbf3cac2c84669fdb2cf4e7d079bb29fe..58c4cf7c4552639f2e6defc6a00e510f13be308c 100644
--- a/src/unix/bsd/netbsdlike/netbsd/aarch64.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/aarch64.rs
@@ -1,5 +1,3 @@
-use dox::mem;
-
 use PT_FIRSTMACH;
 
 pub type c_long = i64;
@@ -11,7 +9,7 @@ pub type __cpu_simple_lock_nv_t = ::c_uchar;
 cfg_if! {
     if #[cfg(libc_const_size_of)] {
         #[doc(hidden)]
-        pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;
+        pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_int>() - 1;
     } else {
         #[doc(hidden)]
         pub const _ALIGNBYTES: usize = 4 - 1;
diff --git a/src/unix/bsd/netbsdlike/netbsd/arm.rs b/src/unix/bsd/netbsdlike/netbsd/arm.rs
index cfcc1396472915a3e52922db8feaa1e60a5e1813..4bf3ccd02b2c4cdc091f4238df920cfa37c1c78d 100644
--- a/src/unix/bsd/netbsdlike/netbsd/arm.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/arm.rs
@@ -1,5 +1,3 @@
-use dox::mem;
-
 use PT_FIRSTMACH;
 
 pub type c_long = i32;
@@ -11,7 +9,7 @@ pub type __cpu_simple_lock_nv_t = ::c_int;
 cfg_if! {
     if #[cfg(libc_const_size_of)] {
         #[doc(hidden)]
-        pub const _ALIGNBYTES: usize = mem::size_of::<::c_longlong>() - 1;
+        pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_longlong>() - 1;
     } else {
         #[doc(hidden)]
         pub const _ALIGNBYTES: usize = 8 - 1;
diff --git a/src/unix/bsd/netbsdlike/netbsd/mod.rs b/src/unix/bsd/netbsdlike/netbsd/mod.rs
index 36a5366e6824c429212d1a9aa3f30e0840337dc6..caf4922d4d6154f0f67cfb0a181f359e77110fae 100644
--- a/src/unix/bsd/netbsdlike/netbsd/mod.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/mod.rs
@@ -1,5 +1,3 @@
-use dox::mem;
-
 pub type clock_t = ::c_uint;
 pub type suseconds_t = ::c_int;
 pub type dev_t = u64;
@@ -268,17 +266,20 @@ s! {
         pub sdl_slen: ::uint8_t,
         pub sdl_data: [::c_char; 12],
     }
+
+    pub struct mmsghdr {
+        pub msg_hdr: ::msghdr,
+        pub msg_len: ::c_uint,
+    }
 }
 
 s_no_extra_traits! {
-    #[allow(missing_debug_implementations)]
     pub struct in_pktinfo {
         pub ipi_addr: ::in_addr,
         pub ipi_ifindex: ::c_uint,
     }
 
     #[repr(packed)]
-    #[allow(missing_debug_implementations)]
     pub struct arphdr {
         pub ar_hrd: u16,
         pub ar_pro: u16,
@@ -288,18 +289,15 @@ s_no_extra_traits! {
     }
 
     #[repr(packed)]
-    #[allow(missing_debug_implementations)]
     pub struct in_addr {
         pub s_addr: ::in_addr_t,
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct ip_mreq {
         pub imr_multiaddr: in_addr,
         pub imr_interface: in_addr,
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct sockaddr_in {
         pub sin_len: u8,
         pub sin_family: ::sa_family_t,
@@ -308,7 +306,6 @@ s_no_extra_traits! {
         pub sin_zero: [::int8_t; 8],
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct dirent {
         pub d_fileno: ::ino_t,
         pub d_reclen: u16,
@@ -317,7 +314,6 @@ s_no_extra_traits! {
         pub d_name: [::c_char; 512],
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct statvfs {
         pub f_flag: ::c_ulong,
         pub f_bsize: ::c_ulong,
@@ -352,7 +348,6 @@ s_no_extra_traits! {
         pub f_mntfromname: [::c_char; 1024],
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct sockaddr_storage {
         pub ss_len: u8,
         pub ss_family: ::sa_family_t,
@@ -362,6 +357,309 @@ s_no_extra_traits! {
     }
 }
 
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for in_pktinfo {
+            fn eq(&self, other: &in_pktinfo) -> bool {
+                self.ipi_addr == other.ipi_addr
+                    && self.ipi_ifindex == other.ipi_ifindex
+            }
+        }
+        impl Eq for in_pktinfo {}
+        impl ::fmt::Debug for in_pktinfo {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("in_pktinfo")
+                    .field("ipi_addr", &self.ipi_addr)
+                    .field("ipi_ifindex", &self.ipi_ifindex)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for in_pktinfo {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.ipi_addr.hash(state);
+                self.ipi_ifindex.hash(state);
+            }
+        }
+
+        impl PartialEq for arphdr {
+            fn eq(&self, other: &arphdr) -> bool {
+                self.ar_hrd == other.ar_hrd
+                    && self.ar_pro == other.ar_pro
+                    && self.ar_hln == other.ar_hln
+                    && self.ar_pln == other.ar_pln
+                    && self.ar_op == other.ar_op
+            }
+        }
+        impl Eq for arphdr {}
+        impl ::fmt::Debug for arphdr {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                let ar_hrd = self.ar_hrd;
+                let ar_pro = self.ar_pro;
+                let ar_op = self.ar_op;
+                f.debug_struct("arphdr")
+                    .field("ar_hrd", &ar_hrd)
+                    .field("ar_pro", &ar_pro)
+                    .field("ar_hln", &self.ar_hln)
+                    .field("ar_pln", &self.ar_pln)
+                    .field("ar_op", &ar_op)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for arphdr {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                let ar_hrd = self.ar_hrd;
+                let ar_pro = self.ar_pro;
+                let ar_op = self.ar_op;
+                ar_hrd.hash(state);
+                ar_pro.hash(state);
+                self.ar_hln.hash(state);
+                self.ar_pln.hash(state);
+                ar_op.hash(state);
+            }
+        }
+
+        impl PartialEq for in_addr {
+            fn eq(&self, other: &in_addr) -> bool {
+                self.s_addr == other.s_addr
+            }
+        }
+        impl Eq for in_addr {}
+        impl ::fmt::Debug for in_addr {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                let s_addr = self.s_addr;
+                f.debug_struct("in_addr")
+                    .field("s_addr", &s_addr)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for in_addr {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                let s_addr = self.s_addr;
+                s_addr.hash(state);
+            }
+        }
+
+        impl PartialEq for ip_mreq {
+            fn eq(&self, other: &ip_mreq) -> bool {
+                self.imr_multiaddr == other.imr_multiaddr
+                    && self.imr_interface == other.imr_interface
+            }
+        }
+        impl Eq for ip_mreq {}
+        impl ::fmt::Debug for ip_mreq {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("ip_mreq")
+                    .field("imr_multiaddr", &self.imr_multiaddr)
+                    .field("imr_interface", &self.imr_interface)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for ip_mreq {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.imr_multiaddr.hash(state);
+                self.imr_interface.hash(state);
+            }
+        }
+
+        impl PartialEq for sockaddr_in {
+            fn eq(&self, other: &sockaddr_in) -> bool {
+                self.sin_len == other.sin_len
+                    && self.sin_family == other.sin_family
+                    && self.sin_port == other.sin_port
+                    && self.sin_addr == other.sin_addr
+                    && self.sin_zero == other.sin_zero
+            }
+        }
+        impl Eq for sockaddr_in {}
+        impl ::fmt::Debug for sockaddr_in {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sockaddr_in")
+                    .field("sin_len", &self.sin_len)
+                    .field("sin_family", &self.sin_family)
+                    .field("sin_port", &self.sin_port)
+                    .field("sin_addr", &self.sin_addr)
+                    .field("sin_zero", &self.sin_zero)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for sockaddr_in {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.sin_len.hash(state);
+                self.sin_family.hash(state);
+                self.sin_port.hash(state);
+                self.sin_addr.hash(state);
+                self.sin_zero.hash(state);
+            }
+        }
+
+        impl PartialEq for dirent {
+            fn eq(&self, other: &dirent) -> bool {
+                self.d_fileno == other.d_fileno
+                    && self.d_reclen == other.d_reclen
+                    && self.d_namlen == other.d_namlen
+                    && self.d_type == other.d_type
+                    && self
+                    .d_name
+                    .iter()
+                    .zip(other.d_name.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for dirent {}
+        impl ::fmt::Debug for dirent {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("dirent")
+                    .field("d_fileno", &self.d_fileno)
+                    .field("d_reclen", &self.d_reclen)
+                    .field("d_namlen", &self.d_namlen)
+                    .field("d_type", &self.d_type)
+                    // FIXME: .field("d_name", &self.d_name)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for dirent {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.d_fileno.hash(state);
+                self.d_reclen.hash(state);
+                self.d_namlen.hash(state);
+                self.d_type.hash(state);
+                self.d_name.hash(state);
+            }
+        }
+
+        impl PartialEq for statvfs {
+            fn eq(&self, other: &statvfs) -> bool {
+                self.f_flag == other.f_flag
+                    && self.f_bsize == other.f_bsize
+                    && self.f_frsize == other.f_frsize
+                    && self.f_iosize == other.f_iosize
+                    && self.f_blocks == other.f_blocks
+                    && self.f_bfree == other.f_bfree
+                    && self.f_bavail == other.f_bavail
+                    && self.f_bresvd == other.f_bresvd
+                    && self.f_files == other.f_files
+                    && self.f_ffree == other.f_ffree
+                    && self.f_favail == other.f_favail
+                    && self.f_fresvd == other.f_fresvd
+                    && self.f_syncreads == other.f_syncreads
+                    && self.f_syncwrites == other.f_syncwrites
+                    && self.f_asyncreads == other.f_asyncreads
+                    && self.f_asyncwrites == other.f_asyncwrites
+                    && self.f_fsidx == other.f_fsidx
+                    && self.f_fsid == other.f_fsid
+                    && self.f_namemax == other.f_namemax
+                    && self.f_owner == other.f_owner
+                    && self.f_spare == other.f_spare
+                    && self.f_fstypename == other.f_fstypename
+                    && self
+                    .f_mntonname
+                    .iter()
+                    .zip(other.f_mntonname.iter())
+                    .all(|(a,b)| a == b)
+                    && self
+                    .f_mntfromname
+                    .iter()
+                    .zip(other.f_mntfromname.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for statvfs {}
+        impl ::fmt::Debug for statvfs {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("statvfs")
+                    .field("f_flag", &self.f_flag)
+                    .field("f_bsize", &self.f_bsize)
+                    .field("f_frsize", &self.f_frsize)
+                    .field("f_iosize", &self.f_iosize)
+                    .field("f_blocks", &self.f_blocks)
+                    .field("f_bfree", &self.f_bfree)
+                    .field("f_bavail", &self.f_bavail)
+                    .field("f_bresvd", &self.f_bresvd)
+                    .field("f_files", &self.f_files)
+                    .field("f_ffree", &self.f_ffree)
+                    .field("f_favail", &self.f_favail)
+                    .field("f_fresvd", &self.f_fresvd)
+                    .field("f_syncreads", &self.f_syncreads)
+                    .field("f_syncwrites", &self.f_syncwrites)
+                    .field("f_asyncreads", &self.f_asyncreads)
+                    .field("f_asyncwrites", &self.f_asyncwrites)
+                    .field("f_fsidx", &self.f_fsidx)
+                    .field("f_fsid", &self.f_fsid)
+                    .field("f_namemax", &self.f_namemax)
+                    .field("f_owner", &self.f_owner)
+                    .field("f_spare", &self.f_spare)
+                    .field("f_fstypename", &self.f_fstypename)
+                    // FIXME: .field("f_mntonname", &self.f_mntonname)
+                    // FIXME: .field("f_mntfromname", &self.f_mntfromname)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for statvfs {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.f_flag.hash(state);
+                self.f_bsize.hash(state);
+                self.f_frsize.hash(state);
+                self.f_iosize.hash(state);
+                self.f_blocks.hash(state);
+                self.f_bfree.hash(state);
+                self.f_bavail.hash(state);
+                self.f_bresvd.hash(state);
+                self.f_files.hash(state);
+                self.f_ffree.hash(state);
+                self.f_favail.hash(state);
+                self.f_fresvd.hash(state);
+                self.f_syncreads.hash(state);
+                self.f_syncwrites.hash(state);
+                self.f_asyncreads.hash(state);
+                self.f_asyncwrites.hash(state);
+                self.f_fsidx.hash(state);
+                self.f_fsid.hash(state);
+                self.f_namemax.hash(state);
+                self.f_owner.hash(state);
+                self.f_spare.hash(state);
+                self.f_fstypename.hash(state);
+                self.f_mntonname.hash(state);
+                self.f_mntfromname.hash(state);
+            }
+        }
+
+        impl PartialEq for sockaddr_storage {
+            fn eq(&self, other: &sockaddr_storage) -> bool {
+                self.ss_len == other.ss_len
+                    && self.ss_family == other.ss_family
+                    && self.__ss_pad1 == other.__ss_pad1
+                    && self.__ss_pad2 == other.__ss_pad2
+                    && self
+                    .__ss_pad3
+                    .iter()
+                    .zip(other.__ss_pad3.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for sockaddr_storage {}
+        impl ::fmt::Debug for sockaddr_storage {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sockaddr_storage")
+                    .field("ss_len", &self.ss_len)
+                    .field("ss_family", &self.ss_family)
+                    .field("__ss_pad1", &self.__ss_pad1)
+                    .field("__ss_pad2", &self.__ss_pad2)
+                    // FIXME: .field("__ss_pad3", &self.__ss_pad3)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for sockaddr_storage {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.ss_len.hash(state);
+                self.ss_family.hash(state);
+                self.__ss_pad1.hash(state);
+                self.__ss_pad2.hash(state);
+                self.__ss_pad3.hash(state);
+            }
+        }
+    }
+}
+
 pub const AT_FDCWD: ::c_int = -100;
 pub const AT_EACCESS: ::c_int = 0x100;
 pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x200;
@@ -1057,10 +1355,58 @@ pub const SF_SNAPSHOT:  ::c_ulong = 0x00200000;
 pub const SF_LOG:       ::c_ulong = 0x00400000;
 pub const SF_SNAPINVAL: ::c_ulong = 0x00800000;
 
-// dirfd() is a macro on netbsd to access
-// the first field of the struct where dirp points to:
-// http://cvsweb.netbsd.org/bsdweb.cgi/src/include/dirent.h?rev=1.36
+fn _ALIGN(p: usize) -> usize {
+    (p + _ALIGNBYTES) & !_ALIGNBYTES
+}
+
 f! {
+    pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar {
+        (cmsg as *mut ::c_uchar)
+            .offset(_ALIGN(::mem::size_of::<::cmsghdr>()) as isize)
+    }
+
+    pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
+        _ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length
+    }
+
+    pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr)
+        -> *mut ::cmsghdr
+    {
+        if cmsg.is_null() {
+            return ::CMSG_FIRSTHDR(mhdr);
+        };
+        let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)
+            + _ALIGN(::mem::size_of::<::cmsghdr>());
+        let max = (*mhdr).msg_control as usize
+            + (*mhdr).msg_controllen as usize;
+        if next > max {
+            0 as *mut ::cmsghdr
+        } else {
+            (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize))
+                as *mut ::cmsghdr
+        }
+    }
+
+    pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
+        (_ALIGN(::mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize))
+            as ::c_uint
+    }
+
+    pub fn WSTOPSIG(status: ::c_int) -> ::c_int {
+        status >> 8
+    }
+
+    pub fn WIFSIGNALED(status: ::c_int) -> bool {
+        (status & 0o177) != 0o177 && (status & 0o177) != 0
+    }
+
+    pub fn WIFSTOPPED(status: ::c_int) -> bool {
+        (status & 0o177) == 0o177
+    }
+
+    // dirfd() is a macro on netbsd to access
+    // the first field of the struct where dirp points to:
+    // http://cvsweb.netbsd.org/bsdweb.cgi/src/include/dirent.h?rev=1.36
     pub fn dirfd(dirp: *mut ::DIR) -> ::c_int {
         *(dirp as *const ::c_int)
     }
@@ -1075,7 +1421,7 @@ f! {
         } else {
             0
         };
-        mem::size_of::<sockcred>() + mem::size_of::<::gid_t>() * ngrps
+        ::mem::size_of::<sockcred>() + ::mem::size_of::<::gid_t>() * ngrps
     }
 }
 
@@ -1238,6 +1584,11 @@ extern {
     pub fn settimeofday(tv: *const ::timeval, tz: *const ::c_void) -> ::c_int;
 
     pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::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;
 }
 
 #[link(name = "util")]
diff --git a/src/unix/bsd/netbsdlike/netbsd/powerpc.rs b/src/unix/bsd/netbsdlike/netbsd/powerpc.rs
index 10cdc73c8142a36466422483eac91cc2b43e646f..e12fd5e11233279d7cec5debf4f939ea859b353e 100644
--- a/src/unix/bsd/netbsdlike/netbsd/powerpc.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/powerpc.rs
@@ -1,5 +1,3 @@
-use dox::mem;
-
 use PT_FIRSTMACH;
 
 pub type c_long = i32;
@@ -11,7 +9,7 @@ pub type __cpu_simple_lock_nv_t = ::c_int;
 cfg_if! {
     if #[cfg(libc_const_size_of)] {
         #[doc(hidden)]
-        pub const _ALIGNBYTES: usize = mem::size_of::<::c_double>() - 1;
+        pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_double>() - 1;
     } else {
         #[doc(hidden)]
         pub const _ALIGNBYTES: usize = 8 - 1;
diff --git a/src/unix/bsd/netbsdlike/netbsd/x86.rs b/src/unix/bsd/netbsdlike/netbsd/x86.rs
index 895e7f8908dd6cb056b251380b1f9c3d2e5db657..daa89a11a67cbc9c6fa363c0bc5055faa46cd8ed 100644
--- a/src/unix/bsd/netbsdlike/netbsd/x86.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/x86.rs
@@ -1,5 +1,3 @@
-use dox::mem;
-
 pub type c_long = i32;
 pub type c_ulong = u32;
 pub type c_char = i8;
@@ -9,7 +7,7 @@ pub type __cpu_simple_lock_nv_t = ::c_uchar;
 cfg_if! {
     if #[cfg(libc_const_size_of)] {
         #[doc(hidden)]
-        pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;
+        pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_int>() - 1;
     } else {
         #[doc(hidden)]
         pub const _ALIGNBYTES: usize = 4 - 1;
diff --git a/src/unix/bsd/netbsdlike/netbsd/x86_64.rs b/src/unix/bsd/netbsdlike/netbsd/x86_64.rs
index e71a82c99bb57a7fc3ac9a32294005d4b6fb3011..0860d4f6c7b57e3f0e073cc4d2a23fdb7ceab723 100644
--- a/src/unix/bsd/netbsdlike/netbsd/x86_64.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/x86_64.rs
@@ -1,5 +1,3 @@
-use dox::mem;
-
 use PT_FIRSTMACH;
 
 pub type c_long = i64;
@@ -11,7 +9,7 @@ pub type __cpu_simple_lock_nv_t = ::c_uchar;
 cfg_if! {
     if #[cfg(libc_const_size_of)] {
         #[doc(hidden)]
-        pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+        pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1;
     } else {
         #[doc(hidden)]
         pub const _ALIGNBYTES: usize = 8 - 1;
diff --git a/src/unix/bsd/netbsdlike/openbsdlike/bitrig/mod.rs b/src/unix/bsd/netbsdlike/openbsdlike/bitrig/mod.rs
index e5f0219e032cf030b76e4aec95d433de6b9d89a3..5cabac5499c4a23967388ebc50cf0139aea1d83f 100644
--- a/src/unix/bsd/netbsdlike/openbsdlike/bitrig/mod.rs
+++ b/src/unix/bsd/netbsdlike/openbsdlike/bitrig/mod.rs
@@ -1,6 +1,21 @@
 pub type c_char = i8;
 
 s! {
+    pub struct glob_t {
+        pub gl_pathc:   ::c_int,
+        pub gl_matchc:  ::c_int,
+        pub gl_offs:    ::c_int,
+        pub gl_flags:   ::c_int,
+        pub gl_pathv:   *mut *mut ::c_char,
+        __unused1: *mut ::c_void,
+        __unused2: *mut ::c_void,
+        __unused3: *mut ::c_void,
+        __unused4: *mut ::c_void,
+        __unused5: *mut ::c_void,
+        __unused6: *mut ::c_void,
+        __unused7: *mut ::c_void,
+    }
+
     pub struct lconv {
         pub decimal_point: *mut ::c_char,
         pub thousands_sep: *mut ::c_char,
diff --git a/src/unix/bsd/netbsdlike/openbsdlike/mod.rs b/src/unix/bsd/netbsdlike/openbsdlike/mod.rs
index cf67747113507fe33209cab506c3e2d107ba961d..c94ad15a8d50d1e0eb1fe379514a0e1361074b24 100644
--- a/src/unix/bsd/netbsdlike/openbsdlike/mod.rs
+++ b/src/unix/bsd/netbsdlike/openbsdlike/mod.rs
@@ -34,21 +34,6 @@ s! {
         pub sin_zero: [::int8_t; 8],
     }
 
-    pub struct glob_t {
-        pub gl_pathc:   ::c_int,
-        pub gl_matchc:  ::c_int,
-        pub gl_offs:    ::c_int,
-        pub gl_flags:   ::c_int,
-        pub gl_pathv:   *mut *mut ::c_char,
-        __unused1: *mut ::c_void,
-        __unused2: *mut ::c_void,
-        __unused3: *mut ::c_void,
-        __unused4: *mut ::c_void,
-        __unused5: *mut ::c_void,
-        __unused6: *mut ::c_void,
-        __unused7: *mut ::c_void,
-    }
-
     pub struct kevent {
         pub ident: ::uintptr_t,
         pub filter: ::c_short,
@@ -223,184 +208,183 @@ s_no_extra_traits! {
     }
 }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for dirent {
-    fn eq(&self, other: &dirent) -> bool {
-        self.d_fileno == other.d_fileno
-            && self.d_off == other.d_off
-            && self.d_reclen == other.d_reclen
-            && self.d_type == other.d_type
-            && self.d_namlen == other.d_namlen
-            && self
-                .d_name
-                .iter()
-                .zip(other.d_name.iter())
-                .all(|(a,b)| a == b)
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for dirent {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for dirent {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("dirent")
-         .field("d_fileno", &self.d_fileno)
-         .field("d_off", &self.d_off)
-         .field("d_reclen", &self.d_reclen)
-         .field("d_type", &self.d_type)
-         .field("d_namlen", &self.d_namlen)
-         // FIXME: .field("d_name", &self.d_name)
-         .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for dirent {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.d_fileno.hash(state);
-        self.d_off.hash(state);
-        self.d_reclen.hash(state);
-        self.d_type.hash(state);
-        self.d_namlen.hash(state);
-        self.d_name.hash(state);
-    }
-}
-
-#[cfg(feature = "extra_traits")]
-impl PartialEq for sockaddr_storage {
-    fn eq(&self, other: &sockaddr_storage) -> bool {
-        self.ss_len == other.ss_len
-            && self.ss_family == other.ss_family
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for sockaddr_storage {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for sockaddr_storage {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("sockaddr_storage")
-         .field("ss_len", &self.ss_len)
-         .field("ss_family", &self.ss_family)
-         .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for sockaddr_storage {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.ss_len.hash(state);
-        self.ss_family.hash(state);
-    }
-}
-
-#[cfg(feature = "extra_traits")]
-impl PartialEq for siginfo_t {
-    fn eq(&self, other: &siginfo_t) -> bool {
-        self.si_signo == other.si_signo
-            && self.si_code == other.si_code
-            && self.si_errno == other.si_errno
-            && self.si_addr == other.si_addr
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for siginfo_t {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for siginfo_t {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("siginfo_t")
-            .field("si_signo", &self.si_signo)
-            .field("si_code", &self.si_code)
-            .field("si_errno", &self.si_errno)
-            .field("si_addr", &self.si_addr)
-            .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for siginfo_t {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.si_signo.hash(state);
-        self.si_code.hash(state);
-        self.si_errno.hash(state);
-        self.si_addr.hash(state);
-    }
-}
-
-#[cfg(feature = "extra_traits")]
-impl PartialEq for lastlog {
-    fn eq(&self, other: &lastlog) -> bool {
-        self.ll_time == other.ll_time
-            && self
-                .ll_line
-                .iter()
-                .zip(other.ll_line.iter())
-                .all(|(a,b)| a == b)
-            && self
-                .ll_host
-                .iter()
-                .zip(other.ll_host.iter())
-                .all(|(a,b)| a == b)
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for lastlog {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for lastlog {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("lastlog")
-         .field("ll_time", &self.ll_time)
-         // FIXME: .field("ll_line", &self.ll_line)
-         // FIXME: .field("ll_host", &self.ll_host)
-         .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for lastlog {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.ll_time.hash(state);
-        self.ll_line.hash(state);
-        self.ll_host.hash(state);
-    }
-}
-
-#[cfg(feature = "extra_traits")]
-impl PartialEq for utmp {
-    fn eq(&self, other: &utmp) -> bool {
-        self.ut_time == other.ut_time
-            && self
-                .ut_line
-                .iter()
-                .zip(other.ut_line.iter())
-                .all(|(a,b)| a == b)
-            && self
-                .ut_name
-                .iter()
-                .zip(other.ut_name.iter())
-                .all(|(a,b)| a == b)
-            && self
-                .ut_host
-                .iter()
-                .zip(other.ut_host.iter())
-                .all(|(a,b)| a == b)
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for utmp {}
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for utmp {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("utmp")
-         // FIXME: .field("ut_line", &self.ut_line)
-         // FIXME: .field("ut_name", &self.ut_name)
-         // FIXME: .field("ut_host", &self.ut_host)
-         .field("ut_time", &self.ut_time)
-         .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for utmp {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        self.ut_line.hash(state);
-        self.ut_name.hash(state);
-        self.ut_host.hash(state);
-        self.ut_time.hash(state);
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for dirent {
+            fn eq(&self, other: &dirent) -> bool {
+                self.d_fileno == other.d_fileno
+                    && self.d_off == other.d_off
+                    && self.d_reclen == other.d_reclen
+                    && self.d_type == other.d_type
+                    && self.d_namlen == other.d_namlen
+                    && self
+                    .d_name
+                    .iter()
+                    .zip(other.d_name.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+
+        impl Eq for dirent {}
+
+        impl ::fmt::Debug for dirent {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("dirent")
+                    .field("d_fileno", &self.d_fileno)
+                    .field("d_off", &self.d_off)
+                    .field("d_reclen", &self.d_reclen)
+                    .field("d_type", &self.d_type)
+                    .field("d_namlen", &self.d_namlen)
+                // FIXME: .field("d_name", &self.d_name)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for dirent {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.d_fileno.hash(state);
+                self.d_off.hash(state);
+                self.d_reclen.hash(state);
+                self.d_type.hash(state);
+                self.d_namlen.hash(state);
+                self.d_name.hash(state);
+            }
+        }
+
+        impl PartialEq for sockaddr_storage {
+            fn eq(&self, other: &sockaddr_storage) -> bool {
+                self.ss_len == other.ss_len
+                    && self.ss_family == other.ss_family
+            }
+        }
+
+        impl Eq for sockaddr_storage {}
+
+        impl ::fmt::Debug for sockaddr_storage {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sockaddr_storage")
+                    .field("ss_len", &self.ss_len)
+                    .field("ss_family", &self.ss_family)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for sockaddr_storage {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.ss_len.hash(state);
+                self.ss_family.hash(state);
+            }
+        }
+
+        impl PartialEq for siginfo_t {
+            fn eq(&self, other: &siginfo_t) -> bool {
+                self.si_signo == other.si_signo
+                    && self.si_code == other.si_code
+                    && self.si_errno == other.si_errno
+                    && self.si_addr == other.si_addr
+            }
+        }
+
+        impl Eq for siginfo_t {}
+
+        impl ::fmt::Debug for siginfo_t {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("siginfo_t")
+                    .field("si_signo", &self.si_signo)
+                    .field("si_code", &self.si_code)
+                    .field("si_errno", &self.si_errno)
+                    .field("si_addr", &self.si_addr)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for siginfo_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.si_signo.hash(state);
+                self.si_code.hash(state);
+                self.si_errno.hash(state);
+                self.si_addr.hash(state);
+            }
+        }
+
+        impl PartialEq for lastlog {
+            fn eq(&self, other: &lastlog) -> bool {
+                self.ll_time == other.ll_time
+                    && self
+                    .ll_line
+                    .iter()
+                    .zip(other.ll_line.iter())
+                    .all(|(a,b)| a == b)
+                    && self
+                    .ll_host
+                    .iter()
+                    .zip(other.ll_host.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+
+        impl Eq for lastlog {}
+
+        impl ::fmt::Debug for lastlog {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("lastlog")
+                    .field("ll_time", &self.ll_time)
+                // FIXME: .field("ll_line", &self.ll_line)
+                // FIXME: .field("ll_host", &self.ll_host)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for lastlog {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.ll_time.hash(state);
+                self.ll_line.hash(state);
+                self.ll_host.hash(state);
+            }
+        }
+
+        impl PartialEq for utmp {
+            fn eq(&self, other: &utmp) -> bool {
+                self.ut_time == other.ut_time
+                    && self
+                    .ut_line
+                    .iter()
+                    .zip(other.ut_line.iter())
+                    .all(|(a,b)| a == b)
+                    && self
+                    .ut_name
+                    .iter()
+                    .zip(other.ut_name.iter())
+                    .all(|(a,b)| a == b)
+                    && self
+                    .ut_host
+                    .iter()
+                    .zip(other.ut_host.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+
+        impl Eq for utmp {}
+
+        impl ::fmt::Debug for utmp {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("utmp")
+                // FIXME: .field("ut_line", &self.ut_line)
+                // FIXME: .field("ut_name", &self.ut_name)
+                // FIXME: .field("ut_host", &self.ut_host)
+                    .field("ut_time", &self.ut_time)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for utmp {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.ut_line.hash(state);
+                self.ut_name.hash(state);
+                self.ut_host.hash(state);
+                self.ut_time.hash(state);
+            }
+        }
     }
 }
 
diff --git a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/aarch64.rs b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/aarch64.rs
index 268e5af4f8d11a1c696d103f02132a4a0a49a20f..6a8cbb5c4f7ea7ba0449a8eafa42d42b782146bc 100644
--- a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/aarch64.rs
+++ b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/aarch64.rs
@@ -1,5 +1,3 @@
-use dox::mem;
-
 pub type c_long = i64;
 pub type c_ulong = u64;
 pub type c_char = u8;
@@ -8,7 +6,7 @@ pub type c_char = u8;
 cfg_if! {
     if #[cfg(libc_const_size_of)] {
         #[doc(hidden)]
-        pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+        pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1;
     } else {
         #[doc(hidden)]
         pub const _ALIGNBYTES: usize = 8 - 1;
diff --git a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/mod.rs b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/mod.rs
index 661f1f435709203962fbf32439bbd93bfad0a96a..435523f10984b697d0733b90634d84598a405ba6 100644
--- a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/mod.rs
+++ b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/mod.rs
@@ -1,4 +1,19 @@
 s! {
+    pub struct glob_t {
+        pub gl_pathc:   ::size_t,
+        pub gl_matchc:  ::size_t,
+        pub gl_offs:    ::size_t,
+        pub gl_flags:   ::c_int,
+        pub gl_pathv:   *mut *mut ::c_char,
+        __unused1: *mut ::c_void,
+        __unused2: *mut ::c_void,
+        __unused3: *mut ::c_void,
+        __unused4: *mut ::c_void,
+        __unused5: *mut ::c_void,
+        __unused6: *mut ::c_void,
+        __unused7: *mut ::c_void,
+    }
+
     pub struct lconv {
         pub decimal_point: *mut ::c_char,
         pub thousands_sep: *mut ::c_char,
@@ -142,31 +157,34 @@ s_no_extra_traits! {
     }
 }
 
-#[cfg(feature = "extra_traits")]
-impl PartialEq for mount_info {
-    fn eq(&self, other: &mount_info) -> bool {
-        unsafe {
-            self.align
-                .iter()
-                .zip(other.align.iter())
-                .all(|(a,b)| a == b)
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for mount_info {
+            fn eq(&self, other: &mount_info) -> bool {
+                unsafe {
+                    self.align
+                        .iter()
+                        .zip(other.align.iter())
+                        .all(|(a,b)| a == b)
+                }
+            }
+        }
+
+        impl Eq for mount_info { }
+
+        impl ::fmt::Debug for mount_info {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("mount_info")
+                // FIXME: .field("align", &self.align)
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for mount_info {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                unsafe { self.align.hash(state) };
+            }
         }
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl Eq for mount_info { }
-#[cfg(feature = "extra_traits")]
-impl std::fmt::Debug for mount_info {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.debug_struct("mount_info")
-         // FIXME: .field("align", &self.align)
-         .finish()
-    }
-}
-#[cfg(feature = "extra_traits")]
-impl std::hash::Hash for mount_info {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        unsafe { self.align.hash(state) };
     }
 }
 
@@ -200,101 +218,105 @@ cfg_if! {
             }
         }
 
-        #[cfg(feature = "extra_traits")]
-        impl PartialEq for statfs {
-            fn eq(&self, other: &statfs) -> bool {
-                self.f_flags == other.f_flags
-                    && self.f_bsize == other.f_bsize
-                    && self.f_iosize == other.f_iosize
-                    && self.f_blocks == other.f_blocks
-                    && self.f_bfree == other.f_bfree
-                    && self.f_bavail == other.f_bavail
-                    && self.f_files == other.f_files
-                    && self.f_ffree == other.f_ffree
-                    && self.f_favail == other.f_favail
-                    && self.f_syncwrites == other.f_syncwrites
-                    && self.f_syncreads == other.f_syncreads
-                    && self.f_asyncwrites == other.f_asyncwrites
-                    && self.f_asyncreads == other.f_asyncreads
-                    && self.f_fsid == other.f_fsid
-                    && self.f_namemax == other.f_namemax
-                    && self.f_owner == other.f_owner
-                    && self.f_ctime == other.f_ctime
-                    && self.f_fstypename
-                           .iter()
-                           .zip(other.f_fstypename.iter())
-                           .all(|(a,b)| a == b)
-                    && self.f_mntonname
-                           .iter()
-                           .zip(other.f_mntonname.iter())
-                           .all(|(a,b)| a == b)
-                    && self.f_mntfromname
-                           .iter()
-                           .zip(other.f_mntfromname.iter())
-                           .all(|(a,b)| a == b)
-                    && self.f_mntfromspec
-                           .iter()
-                           .zip(other.f_mntfromspec.iter())
-                           .all(|(a,b)| a == b)
-                    && self.mount_info == other.mount_info
-            }
-        }
-        #[cfg(feature = "extra_traits")]
-        impl Eq for statfs { }
-        #[cfg(feature = "extra_traits")]
-        impl std::fmt::Debug for statfs {
-            fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-                f.debug_struct("statfs")
-                 .field("f_flags", &self.f_flags)
-                 .field("f_bsize", &self.f_bsize)
-                 .field("f_iosize", &self.f_iosize)
-                 .field("f_blocks", &self.f_blocks)
-                 .field("f_bfree", &self.f_bfree)
-                 .field("f_bavail", &self.f_bavail)
-                 .field("f_files", &self.f_files)
-                 .field("f_ffree", &self.f_ffree)
-                 .field("f_favail", &self.f_favail)
-                 .field("f_syncwrites", &self.f_syncwrites)
-                 .field("f_syncreads", &self.f_syncreads)
-                 .field("f_asyncwrites", &self.f_asyncwrites)
-                 .field("f_asyncreads", &self.f_asyncreads)
-                 .field("f_fsid", &self.f_fsid)
-                 .field("f_namemax", &self.f_namemax)
-                 .field("f_owner", &self.f_owner)
-                 .field("f_ctime", &self.f_ctime)
-                 // FIXME: .field("f_fstypename", &self.f_fstypename)
-                 // FIXME: .field("f_mntonname", &self.f_mntonname)
-                 // FIXME: .field("f_mntfromname", &self.f_mntfromname)
-                 // FIXME: .field("f_mntfromspec", &self.f_mntfromspec)
-                 .field("mount_info", &self.mount_info)
-                 .finish()
-            }
-        }
-        #[cfg(feature = "extra_traits")]
-        impl std::hash::Hash for statfs {
-            fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-                self.f_flags.hash(state);
-                self.f_bsize.hash(state);
-                self.f_iosize.hash(state);
-                self.f_blocks.hash(state);
-                self.f_bfree.hash(state);
-                self.f_bavail.hash(state);
-                self.f_files.hash(state);
-                self.f_ffree.hash(state);
-                self.f_favail.hash(state);
-                self.f_syncwrites.hash(state);
-                self.f_syncreads.hash(state);
-                self.f_asyncwrites.hash(state);
-                self.f_asyncreads.hash(state);
-                self.f_fsid.hash(state);
-                self.f_namemax.hash(state);
-                self.f_owner.hash(state);
-                self.f_ctime.hash(state);
-                self.f_fstypename.hash(state);
-                self.f_mntonname.hash(state);
-                self.f_mntfromname.hash(state);
-                self.f_mntfromspec.hash(state);
-                self.mount_info.hash(state);
+        cfg_if! {
+            if #[cfg(feature = "extra_traits")] {
+                impl PartialEq for statfs {
+                    fn eq(&self, other: &statfs) -> bool {
+                        self.f_flags == other.f_flags
+                            && self.f_bsize == other.f_bsize
+                            && self.f_iosize == other.f_iosize
+                            && self.f_blocks == other.f_blocks
+                            && self.f_bfree == other.f_bfree
+                            && self.f_bavail == other.f_bavail
+                            && self.f_files == other.f_files
+                            && self.f_ffree == other.f_ffree
+                            && self.f_favail == other.f_favail
+                            && self.f_syncwrites == other.f_syncwrites
+                            && self.f_syncreads == other.f_syncreads
+                            && self.f_asyncwrites == other.f_asyncwrites
+                            && self.f_asyncreads == other.f_asyncreads
+                            && self.f_fsid == other.f_fsid
+                            && self.f_namemax == other.f_namemax
+                            && self.f_owner == other.f_owner
+                            && self.f_ctime == other.f_ctime
+                            && self.f_fstypename
+                            .iter()
+                            .zip(other.f_fstypename.iter())
+                            .all(|(a,b)| a == b)
+                            && self.f_mntonname
+                            .iter()
+                            .zip(other.f_mntonname.iter())
+                            .all(|(a,b)| a == b)
+                            && self.f_mntfromname
+                            .iter()
+                            .zip(other.f_mntfromname.iter())
+                            .all(|(a,b)| a == b)
+                            && self.f_mntfromspec
+                            .iter()
+                            .zip(other.f_mntfromspec.iter())
+                            .all(|(a,b)| a == b)
+                            && self.mount_info == other.mount_info
+                    }
+                }
+
+                impl Eq for statfs { }
+
+                impl ::fmt::Debug for statfs {
+                    fn fmt(&self, f: &mut ::fmt::Formatter)
+                           -> ::fmt::Result {
+                        f.debug_struct("statfs")
+                            .field("f_flags", &self.f_flags)
+                            .field("f_bsize", &self.f_bsize)
+                            .field("f_iosize", &self.f_iosize)
+                            .field("f_blocks", &self.f_blocks)
+                            .field("f_bfree", &self.f_bfree)
+                            .field("f_bavail", &self.f_bavail)
+                            .field("f_files", &self.f_files)
+                            .field("f_ffree", &self.f_ffree)
+                            .field("f_favail", &self.f_favail)
+                            .field("f_syncwrites", &self.f_syncwrites)
+                            .field("f_syncreads", &self.f_syncreads)
+                            .field("f_asyncwrites", &self.f_asyncwrites)
+                            .field("f_asyncreads", &self.f_asyncreads)
+                            .field("f_fsid", &self.f_fsid)
+                            .field("f_namemax", &self.f_namemax)
+                            .field("f_owner", &self.f_owner)
+                            .field("f_ctime", &self.f_ctime)
+                        // FIXME: .field("f_fstypename", &self.f_fstypename)
+                        // FIXME: .field("f_mntonname", &self.f_mntonname)
+                        // FIXME: .field("f_mntfromname", &self.f_mntfromname)
+                        // FIXME: .field("f_mntfromspec", &self.f_mntfromspec)
+                            .field("mount_info", &self.mount_info)
+                            .finish()
+                    }
+                }
+
+                impl ::hash::Hash for statfs {
+                    fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                        self.f_flags.hash(state);
+                        self.f_bsize.hash(state);
+                        self.f_iosize.hash(state);
+                        self.f_blocks.hash(state);
+                        self.f_bfree.hash(state);
+                        self.f_bavail.hash(state);
+                        self.f_files.hash(state);
+                        self.f_ffree.hash(state);
+                        self.f_favail.hash(state);
+                        self.f_syncwrites.hash(state);
+                        self.f_syncreads.hash(state);
+                        self.f_asyncwrites.hash(state);
+                        self.f_asyncreads.hash(state);
+                        self.f_fsid.hash(state);
+                        self.f_namemax.hash(state);
+                        self.f_owner.hash(state);
+                        self.f_ctime.hash(state);
+                        self.f_fstypename.hash(state);
+                        self.f_mntonname.hash(state);
+                        self.f_mntfromname.hash(state);
+                        self.f_mntfromspec.hash(state);
+                        self.mount_info.hash(state);
+                    }
+                }
             }
         }
     }
@@ -385,6 +407,56 @@ pub const SIGSTKSZ : ::size_t = 28672;
 
 pub const PT_FIRSTMACH: ::c_int = 32;
 
+fn _ALIGN(p: usize) -> usize {
+    (p + _ALIGNBYTES) & !_ALIGNBYTES
+}
+
+f! {
+    pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar {
+        (cmsg as *mut ::c_uchar)
+            .offset(_ALIGN(::mem::size_of::<::cmsghdr>()) as isize)
+    }
+
+    pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
+        _ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length
+    }
+
+    pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr)
+        -> *mut ::cmsghdr
+    {
+        if cmsg.is_null() {
+            return ::CMSG_FIRSTHDR(mhdr);
+        };
+        let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)
+            + _ALIGN(::mem::size_of::<::cmsghdr>());
+        let max = (*mhdr).msg_control as usize
+            + (*mhdr).msg_controllen as usize;
+        if next > max {
+            0 as *mut ::cmsghdr
+        } else {
+            (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize))
+                as *mut ::cmsghdr
+        }
+    }
+
+    pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
+        (_ALIGN(::mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize))
+            as ::c_uint
+    }
+
+    pub fn WSTOPSIG(status: ::c_int) -> ::c_int {
+        status >> 8
+    }
+
+    pub fn WIFSIGNALED(status: ::c_int) -> bool {
+        (status & 0o177) != 0o177 && (status & 0o177) != 0
+    }
+
+    pub fn WIFSTOPPED(status: ::c_int) -> bool {
+        (status & 0o177) == 0o177
+    }
+}
+
 extern {
     pub fn accept4(s: ::c_int, addr: *mut ::sockaddr,
                    addrlen: *mut ::socklen_t, flags: ::c_int) -> ::c_int;
diff --git a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs
index 959c87b42792fbc11fc44b72251f2755937835ef..05538cd0a9e814600400ee50949da7adec8717eb 100644
--- a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs
+++ b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs
@@ -1,5 +1,3 @@
-use dox::mem;
-
 pub type c_long = i32;
 pub type c_ulong = u32;
 pub type c_char = i8;
@@ -8,7 +6,7 @@ pub type c_char = i8;
 cfg_if! {
     if #[cfg(libc_const_size_of)] {
         #[doc(hidden)]
-        pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;
+        pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_int>() - 1;
     } else {
         #[doc(hidden)]
         pub const _ALIGNBYTES: usize = 4 - 1;
diff --git a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86_64.rs b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86_64.rs
index b2025a8a9c06b0439a0c35d8fa21249103929eda..7daa9d83664aae6b11fd8e6892f00e35a0cdd0ec 100644
--- a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86_64.rs
+++ b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86_64.rs
@@ -1,5 +1,3 @@
-use dox::mem;
-
 use PT_FIRSTMACH;
 
 pub type c_long = i64;
@@ -10,7 +8,7 @@ pub type c_char = i8;
 cfg_if! {
     if #[cfg(libc_const_size_of)] {
         #[doc(hidden)]
-        pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+        pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1;
     } else {
         #[doc(hidden)]
         pub const _ALIGNBYTES: usize = 8 - 1;
diff --git a/src/unix/haiku/mod.rs b/src/unix/haiku/mod.rs
index e0365d913ce8c4e1fd53b51ebaff0ae2e4d3ce4b..bcf4613ddc39689830a0c16708115e7a2ef99a31 100644
--- a/src/unix/haiku/mod.rs
+++ b/src/unix/haiku/mod.rs
@@ -1,5 +1,3 @@
-use dox::{mem, Option};
-
 pub type rlim_t = ::uintptr_t;
 pub type sa_family_t = u8;
 pub type pthread_key_t = ::c_int;
@@ -33,8 +31,8 @@ pub type idtype_t = ::c_uint;
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum timezone {}
-impl ::dox::Copy for timezone {}
-impl ::dox::Clone for timezone {
+impl ::Copy for timezone {}
+impl ::Clone for timezone {
     fn clone(&self) -> timezone { *self }
 }
 
@@ -71,20 +69,6 @@ s! {
         pub sin6_scope_id: u32,
     }
 
-    pub struct sockaddr_un {
-        pub sun_len: u8,
-        pub sun_family: sa_family_t,
-        pub sun_path: [::c_char; 126]
-    }
-
-    pub struct sockaddr_storage {
-        pub ss_len: u8,
-        pub ss_family: sa_family_t,
-        __ss_pad1: [u8; 6],
-        __ss_pad2: u64,
-        __ss_pad3: [u8; 112],
-    }
-
     pub struct addrinfo {
         pub ai_flags: ::c_int,
         pub ai_family: ::c_int,
@@ -213,15 +197,6 @@ s! {
         pub st_blocks: blkcnt_t,
     }
 
-    pub struct dirent {
-        pub d_dev: dev_t,
-        pub d_pdev: dev_t,
-        pub d_ino: ino_t,
-        pub d_pino: i64,
-        pub d_reclen: ::c_ushort,
-        pub d_name: [::c_char; 1024], // Max length is _POSIX_PATH_MAX
-    }
-
     pub struct glob_t {
         pub gl_pathc: ::size_t,
         __unused1: ::size_t,
@@ -333,6 +308,139 @@ s! {
     }
 }
 
+s_no_extra_traits! {
+    pub struct sockaddr_un {
+        pub sun_len: u8,
+        pub sun_family: sa_family_t,
+        pub sun_path: [::c_char; 126]
+    }
+    pub struct sockaddr_storage {
+        pub ss_len: u8,
+        pub ss_family: sa_family_t,
+        __ss_pad1: [u8; 6],
+        __ss_pad2: u64,
+        __ss_pad3: [u8; 112],
+    }
+    pub struct dirent {
+        pub d_dev: dev_t,
+        pub d_pdev: dev_t,
+        pub d_ino: ino_t,
+        pub d_pino: i64,
+        pub d_reclen: ::c_ushort,
+        pub d_name: [::c_char; 1024], // Max length is _POSIX_PATH_MAX
+    }
+}
+
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for sockaddr_un {
+            fn eq(&self, other: &sockaddr_un) -> bool {
+                self.sun_len == other.sun_len
+                    && self.sun_family == other.sun_family
+                    && self
+                    .sun_path
+                    .iter()
+                    .zip(other.sun_path.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for sockaddr_un {}
+        impl ::fmt::Debug for sockaddr_un {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sockaddr_un")
+                    .field("sun_len", &self.sun_len)
+                    .field("sun_family", &self.sun_family)
+                    // FIXME: .field("sun_path", &self.sun_path)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for sockaddr_un {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.sun_len.hash(state);
+                self.sun_family.hash(state);
+                self.sun_path.hash(state);
+            }
+        }
+
+        impl PartialEq for sockaddr_storage {
+            fn eq(&self, other: &sockaddr_storage) -> bool {
+                self.ss_len == other.ss_len
+                    && self.ss_family == other.ss_family
+                    && self
+                    .__ss_pad1
+                    .iter()
+                    .zip(other.__ss_pad1.iter())
+                    .all(|(a, b)| a == b)
+                    && self.__ss_pad2 == other.__ss_pad2
+                    && self
+                    .__ss_pad3
+                    .iter()
+                    .zip(other.__ss_pad3.iter())
+                    .all(|(a, b)| a == b)
+            }
+        }
+        impl Eq for sockaddr_storage {}
+        impl ::fmt::Debug for sockaddr_storage {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sockaddr_storage")
+                    .field("ss_len", &self.ss_len)
+                    .field("ss_family", &self.ss_family)
+                    .field("__ss_pad1", &self.__ss_pad1)
+                    .field("__ss_pad2", &self.__ss_pad2)
+                    // FIXME: .field("__ss_pad3", &self.__ss_pad3)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for sockaddr_storage {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.ss_len.hash(state);
+                self.ss_family.hash(state);
+                self.__ss_pad1.hash(state);
+                self.__ss_pad2.hash(state);
+                self.__ss_pad3.hash(state);
+            }
+        }
+
+        impl PartialEq for dirent {
+            fn eq(&self, other: &dirent) -> bool {
+                self.d_dev == other.d_dev
+                    && self.d_pdev == other.d_pdev
+                    && self.d_ino == other.d_ino
+                    && self.d_pino == other.d_pino
+                    && self.d_reclen == other.d_reclen
+                    && self
+                    .d_name
+                    .iter()
+                    .zip(other.d_name.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for dirent {}
+        impl ::fmt::Debug for dirent {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("dirent")
+                    .field("d_dev", &self.d_dev)
+                    .field("d_pdev", &self.d_pdev)
+                    .field("d_ino", &self.d_ino)
+                    .field("d_pino", &self.d_pino)
+                    .field("d_reclen", &self.d_reclen)
+                    // FIXME: .field("d_name", &self.d_name)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for dirent {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.d_dev.hash(state);
+                self.d_pdev.hash(state);
+                self.d_ino.hash(state);
+                self.d_pino.hash(state);
+                self.d_reclen.hash(state);
+                self.d_name.hash(state);
+            }
+        }
+    }
+}
+
 // intentionally not public, only used for fd_set
 cfg_if! {
     if #[cfg(target_pointer_width = "32")] {
@@ -1042,20 +1150,20 @@ pub const TCIOFLUSH: ::c_int = 0x03;
 f! {
     pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () {
         let fd = fd as usize;
-        let size = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         (*set).fds_bits[fd / size] &= !(1 << (fd % size));
         return
     }
 
     pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool {
         let fd = fd as usize;
-        let size = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0
     }
 
     pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () {
         let fd = fd as usize;
-        let size = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         (*set).fds_bits[fd / size] |= 1 << (fd % size);
         return
     }
@@ -1110,6 +1218,12 @@ extern {
 
 #[link(name = "bsd")]
 extern {
+    pub fn sem_destroy(sem: *mut sem_t) -> ::c_int;
+    pub fn sem_init(sem: *mut sem_t,
+                    pshared: ::c_int,
+                    value: ::c_uint)
+                    -> ::c_int;
+
     pub fn clock_gettime(clk_id: ::c_int, tp: *mut ::timespec) -> ::c_int;
     pub fn clock_settime(clk_id: ::c_int, tp: *const ::timespec) -> ::c_int;
     pub fn pthread_create(thread: *mut ::pthread_t,
@@ -1146,7 +1260,7 @@ extern {
 
     pub fn glob(pattern: *const ::c_char,
                 flags: ::c_int,
-                errfunc: Option<extern fn(epath: *const ::c_char,
+                errfunc: ::Option<extern fn(epath: *const ::c_char,
                                           errno: ::c_int) -> ::c_int>,
                 pglob: *mut ::glob_t) -> ::c_int;
     pub fn globfree(pglob: *mut ::glob_t);
@@ -1238,9 +1352,9 @@ extern {
     #[cfg_attr(target_os = "solaris", link_name = "__posix_sigwait")]
     pub fn sigwait(set: *const sigset_t,
                    sig: *mut ::c_int) -> ::c_int;
-    pub fn pthread_atfork(prepare: Option<unsafe extern fn()>,
-                          parent: Option<unsafe extern fn()>,
-                          child: Option<unsafe extern fn()>) -> ::c_int;
+    pub fn pthread_atfork(prepare: ::Option<unsafe extern fn()>,
+                          parent: ::Option<unsafe extern fn()>,
+                          child: ::Option<unsafe extern fn()>) -> ::c_int;
     pub fn getgrgid(gid: ::gid_t) -> *mut ::group;
     #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
                link_name = "popen$UNIX2003")]
diff --git a/src/unix/hermit/mod.rs b/src/unix/hermit/mod.rs
index ca389f06c1e128604b1616114c4a97f0f9b38a77..0c372f12128e6835ff32bb5dd461cfb9d2fb6000 100644
--- a/src/unix/hermit/mod.rs
+++ b/src/unix/hermit/mod.rs
@@ -705,6 +705,12 @@ f! {
 }
 
 extern {
+    pub fn sem_destroy(sem: *mut sem_t) -> ::c_int;
+    pub fn sem_init(sem: *mut sem_t,
+                    pshared: ::c_int,
+                    value: ::c_uint)
+                    -> ::c_int;
+
     pub fn abs(i: ::c_int) -> ::c_int;
     pub fn atof(s: *const ::c_char) -> ::c_double;
     pub fn labs(i: ::c_long) -> ::c_long;
diff --git a/src/unix/mod.rs b/src/unix/mod.rs
index 972c2c0dae89d022591e8b4b2500e6d2777b989e..15f7c7f2eab8534a1cf2b98bb5417d146ac15983 100644
--- a/src/unix/mod.rs
+++ b/src/unix/mod.rs
@@ -3,8 +3,6 @@
 //! More functions and definitions can be found in the more specific modules
 //! according to the platform in question.
 
-use dox::Option;
-
 pub type int8_t = i8;
 pub type int16_t = i16;
 pub type int32_t = i32;
@@ -43,14 +41,14 @@ pub type cc_t = ::c_uchar;
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum DIR {}
-impl ::dox::Copy for DIR {}
-impl ::dox::Clone for DIR {
+impl ::Copy for DIR {}
+impl ::Clone for DIR {
     fn clone(&self) -> DIR { *self }
 }
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum locale_t {}
-impl ::dox::Copy for locale_t {}
-impl ::dox::Clone for locale_t {
+impl ::Copy for locale_t {}
+impl ::Clone for locale_t {
     fn clone(&self) -> locale_t { *self }
 }
 
@@ -303,9 +301,7 @@ pub const ATF_PUBL: ::c_int = 0x08;
 pub const ATF_USETRAILERS: ::c_int = 0x10;
 
 cfg_if! {
-    if #[cfg(cross_platform_docs)] {
-        // on dox builds don't pull in anything
-    } else if #[cfg(target_os = "l4re")] {
+    if #[cfg(target_os = "l4re")] {
         // required libraries for L4Re are linked externally, ATM
     } else if #[cfg(feature = "use_std")] {
         // cargo build, don't pull in anything extra as the libstd dep
@@ -364,14 +360,14 @@ cfg_if! {
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum FILE {}
-impl ::dox::Copy for FILE {}
-impl ::dox::Clone for FILE {
+impl ::Copy for FILE {}
+impl ::Clone for FILE {
     fn clone(&self) -> FILE { *self }
 }
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum fpos_t {} // TODO: fill this out with a struct
-impl ::dox::Copy for fpos_t {}
-impl ::dox::Clone for fpos_t {
+impl ::Copy for fpos_t {}
+impl ::Clone for fpos_t {
     fn clone(&self) -> fpos_t { *self }
 }
 
@@ -858,7 +854,7 @@ extern {
     #[cfg_attr(target_os = "netbsd", link_name = "__libc_thr_yield")]
     pub fn sched_yield() -> ::c_int;
     pub fn pthread_key_create(key: *mut pthread_key_t,
-                              dtor: Option<unsafe extern fn(*mut ::c_void)>)
+                              dtor: ::Option<unsafe extern fn(*mut ::c_void)>)
                               -> ::c_int;
     pub fn pthread_key_delete(key: pthread_key_t) -> ::c_int;
     pub fn pthread_getspecific(key: pthread_key_t) -> *mut ::c_void;
@@ -1025,16 +1021,11 @@ extern {
                      locale: *const ::c_char) -> *mut ::c_char;
     pub fn localeconv() -> *mut lconv;
 
-    pub fn sem_destroy(sem: *mut sem_t) -> ::c_int;
     #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
                link_name = "sem_wait$UNIX2003")]
     pub fn sem_wait(sem: *mut sem_t) -> ::c_int;
     pub fn sem_trywait(sem: *mut sem_t) -> ::c_int;
     pub fn sem_post(sem: *mut sem_t) -> ::c_int;
-    pub fn sem_init(sem: *mut sem_t,
-                    pshared: ::c_int,
-                    value: ::c_uint)
-                    -> ::c_int;
     pub fn statvfs(path: *const c_char, buf: *mut statvfs) -> ::c_int;
     pub fn fstatvfs(fd: ::c_int, buf: *mut statvfs) -> ::c_int;
 
diff --git a/src/unix/newlib/mod.rs b/src/unix/newlib/mod.rs
index 94bce1e12f467c0c318247e0821a90633d41d33d..e2c7fca07692618dc33fe209e10af63807d1f5fd 100644
--- a/src/unix/newlib/mod.rs
+++ b/src/unix/newlib/mod.rs
@@ -1,5 +1,3 @@
-use dox::mem;
-
 pub type blkcnt_t = i32;
 pub type blksize_t = i32;
 pub type clock_t = i32;
@@ -27,15 +25,6 @@ pub type time_t = i32;
 pub type useconds_t = u32;
 
 s! {
-    pub struct in_addr {
-        pub s_addr: ::in_addr_t,
-    }
-
-    pub struct ip_mreq {
-        pub imr_multiaddr: in_addr,
-        pub imr_interface: in_addr,
-    }
-
     pub struct sockaddr {
         pub sa_family: sa_family_t,
         pub sa_data: [::c_char; 14],
@@ -502,10 +491,6 @@ pub const IFF_LINK2: ::c_int = 0x4000; // per link layer defined bit
 pub const IFF_ALTPHYS: ::c_int = IFF_LINK2; // use alternate physical connection
 pub const IFF_MULTICAST: ::c_int = 0x8000; // supports multicast
 
-pub const IPPROTO_IP: ::c_int = 0;
-pub const IPPROTO_UDP: ::c_int = 17;
-pub const IPPROTO_TCP: ::c_int = 6;
-
 pub const TCP_NODELAY: ::c_int = 8193;
 pub const TCP_MAXSEG: ::c_int = 8194;
 
@@ -543,20 +528,20 @@ pub const EAI_SOCKTYPE: ::c_int = -307;
 
 f! {
     pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () {
-        let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         let fd = fd as usize;
         (*set).fds_bits[fd / bits] &= !(1 << (fd % bits));
         return
     }
 
     pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool {
-        let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         let fd = fd as usize;
         return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0
     }
 
     pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () {
-        let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         let fd = fd as usize;
         (*set).fds_bits[fd / bits] |= 1 << (fd % bits);
         return
@@ -570,6 +555,12 @@ f! {
 }
 
 extern {
+    pub fn sem_destroy(sem: *mut sem_t) -> ::c_int;
+    pub fn sem_init(sem: *mut sem_t,
+                    pshared: ::c_int,
+                    value: ::c_uint)
+                    -> ::c_int;
+
     pub fn abs(i: ::c_int) -> ::c_int;
     pub fn atof(s: *const ::c_char) -> ::c_double;
     pub fn labs(i: ::c_long) -> ::c_long;
@@ -636,9 +627,9 @@ extern {
     #[cfg_attr(target_os = "solaris", link_name = "__posix_sigwait")]
     pub fn sigwait(set: *const sigset_t,
                    sig: *mut ::c_int) -> ::c_int;
-    pub fn pthread_atfork(prepare: Option<unsafe extern fn()>,
-                          parent: Option<unsafe extern fn()>,
-                          child: Option<unsafe extern fn()>) -> ::c_int;
+    pub fn pthread_atfork(prepare: ::Option<unsafe extern fn()>,
+                          parent: ::Option<unsafe extern fn()>,
+                          child: ::Option<unsafe extern fn()>) -> ::c_int;
     pub fn getgrgid(gid: ::gid_t) -> *mut ::group;
     #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
                link_name = "popen$UNIX2003")]
diff --git a/src/unix/notbsd/android/b32/mod.rs b/src/unix/notbsd/android/b32/mod.rs
index 394abe8fe24c774ea32704d53cd35af5be7441d8..a8cc51b2215c8a29edb8e375e2edfb217e70ae9a 100644
--- a/src/unix/notbsd/android/b32/mod.rs
+++ b/src/unix/notbsd/android/b32/mod.rs
@@ -14,7 +14,7 @@ s! {
         pub sa_sigaction: ::sighandler_t,
         pub sa_mask: ::sigset_t,
         pub sa_flags: ::c_ulong,
-        pub sa_restorer: ::dox::Option<extern fn()>,
+        pub sa_restorer: ::Option<extern fn()>,
     }
 
     pub struct rlimit64 {
diff --git a/src/unix/notbsd/android/b64/mod.rs b/src/unix/notbsd/android/b64/mod.rs
index fce9965b0017a71d6092cae06ff272772798865f..46becc53d4d383a098718f5cc5e0ebe4fe8eba7c 100644
--- a/src/unix/notbsd/android/b64/mod.rs
+++ b/src/unix/notbsd/android/b64/mod.rs
@@ -16,7 +16,7 @@ s! {
         pub sa_flags: ::c_uint,
         pub sa_sigaction: ::sighandler_t,
         pub sa_mask: ::sigset_t,
-        pub sa_restorer: ::dox::Option<extern fn()>,
+        pub sa_restorer: ::Option<extern fn()>,
     }
 
     pub struct rlimit64 {
diff --git a/src/unix/notbsd/android/mod.rs b/src/unix/notbsd/android/mod.rs
index 2213b75b663ed4164bcd192842e92f202b931b1c..2f62a0930da2d201fa59957ec47b1253297374f6 100644
--- a/src/unix/notbsd/android/mod.rs
+++ b/src/unix/notbsd/android/mod.rs
@@ -1,7 +1,5 @@
 //! Android-specific definitions for linux-like values
 
-use dox::{mem, Option};
-
 pub type clock_t = ::c_long;
 pub type time_t = ::c_long;
 pub type suseconds_t = ::c_long;
@@ -238,6 +236,19 @@ s_no_extra_traits!{
         pub ut_addr_v6: [::int32_t; 4],
         unused: [::c_char; 20],
     }
+
+    pub struct sockaddr_alg {
+        pub salg_family: ::sa_family_t,
+        pub salg_type: [::c_uchar; 14],
+        pub salg_feat: u32,
+        pub salg_mask: u32,
+        pub salg_name: [::c_uchar; 64],
+    }
+
+    pub struct af_alg_iv {
+        pub ivlen: u32,
+        pub iv: [::c_uchar; 0],
+    }
 }
 
 cfg_if! {
@@ -451,6 +462,81 @@ cfg_if! {
                 self.unused.hash(state);
             }
         }
+
+        impl PartialEq for sockaddr_alg {
+            fn eq(&self, other: &sockaddr_alg) -> bool {
+                self.salg_family == other.salg_family
+                    && self
+                    .salg_type
+                    .iter()
+                    .zip(other.salg_type.iter())
+                    .all(|(a, b)| a == b)
+                    && self.salg_feat == other.salg_feat
+                    && self.salg_mask == other.salg_mask
+                    && self
+                    .salg_name
+                    .iter()
+                    .zip(other.salg_name.iter())
+                    .all(|(a, b)| a == b)
+           }
+        }
+
+        impl Eq for sockaddr_alg {}
+
+        impl ::fmt::Debug for sockaddr_alg {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sockaddr_alg")
+                    .field("salg_family", &self.salg_family)
+                    .field("salg_type", &self.salg_type)
+                    .field("salg_feat", &self.salg_feat)
+                    .field("salg_mask", &self.salg_mask)
+                    .field("salg_name", &&self.salg_name[..])
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for sockaddr_alg {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.salg_family.hash(state);
+                self.salg_type.hash(state);
+                self.salg_feat.hash(state);
+                self.salg_mask.hash(state);
+                self.salg_name.hash(state);
+            }
+        }
+
+        impl af_alg_iv {
+            fn as_slice(&self) -> &[u8] {
+                unsafe {
+                    ::core::slice::from_raw_parts(
+                        self.iv.as_ptr(),
+                        self.ivlen as usize
+                    )
+                }
+            }
+        }
+
+        impl PartialEq for af_alg_iv {
+            fn eq(&self, other: &af_alg_iv) -> bool {
+                *self.as_slice() == *other.as_slice()
+           }
+        }
+
+        impl Eq for af_alg_iv {}
+
+        impl ::fmt::Debug for af_alg_iv {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("af_alg_iv")
+                    .field("iv", &self.as_slice())
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for af_alg_iv {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.as_slice().hash(state);
+            }
+        }
     }
 }
 
@@ -1266,6 +1352,10 @@ pub const SFD_NONBLOCK: ::c_int = O_NONBLOCK;
 pub const SOCK_NONBLOCK: ::c_int = O_NONBLOCK;
 
 pub const SO_ORIGINAL_DST: ::c_int = 80;
+pub const IP_ORIGDSTADDR : ::c_int = 20;
+pub const IP_RECVORIGDSTADDR : ::c_int = IP_ORIGDSTADDR;
+pub const IPV6_ORIGDSTADDR : ::c_int = 74;
+pub const IPV6_RECVORIGDSTADDR : ::c_int = IPV6_ORIGDSTADDR;
 pub const IUTF8: ::tcflag_t = 0x00004000;
 pub const CMSPAR: ::tcflag_t = 0o10000000000;
 pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY;
@@ -1690,6 +1780,16 @@ pub const MODULE_INIT_IGNORE_VERMAGIC: ::c_uint = 0x0002;
 // Similarity to Linux it's not used but defined for compatibility.
 pub const ENOATTR: ::c_int = ::ENODATA;
 
+// linux/if_alg.h
+pub const ALG_SET_KEY: ::c_int = 1;
+pub const ALG_SET_IV: ::c_int = 2;
+pub const ALG_SET_OP: ::c_int = 3;
+pub const ALG_SET_AEAD_ASSOCLEN: ::c_int = 4;
+pub const ALG_SET_AEAD_AUTHSIZE: ::c_int = 5;
+
+pub const ALG_OP_DECRYPT: ::c_int = 0;
+pub const ALG_OP_ENCRYPT: ::c_int = 1;
+
 f! {
     pub fn CMSG_NXTHDR(mhdr: *const msghdr,
                        cmsg: *const cmsghdr) -> *mut cmsghdr {
@@ -1712,21 +1812,21 @@ f! {
     }
 
     pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () {
-        let size_in___bits = 8 * mem::size_of_val(&cpuset.__bits[0]);
+        let size_in___bits = 8 * ::mem::size_of_val(&cpuset.__bits[0]);
         let (idx, offset) = (cpu / size_in___bits, cpu % size_in___bits);
         cpuset.__bits[idx] |= 1 << offset;
         ()
     }
 
     pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () {
-        let size_in___bits = 8 * mem::size_of_val(&cpuset.__bits[0]);
+        let size_in___bits = 8 * ::mem::size_of_val(&cpuset.__bits[0]);
         let (idx, offset) = (cpu / size_in___bits, cpu % size_in___bits);
         cpuset.__bits[idx] &= !(1 << offset);
         ()
     }
 
     pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool {
-        let size_in___bits = 8 * mem::size_of_val(&cpuset.__bits[0]);
+        let size_in___bits = 8 * ::mem::size_of_val(&cpuset.__bits[0]);
         let (idx, offset) = (cpu / size_in___bits, cpu % size_in___bits);
         0 != (cpuset.__bits[idx] & (1 << offset))
     }
@@ -1928,9 +2028,9 @@ extern {
     #[cfg_attr(target_os = "solaris", link_name = "__posix_sigwait")]
     pub fn sigwait(set: *const sigset_t,
                    sig: *mut ::c_int) -> ::c_int;
-    pub fn pthread_atfork(prepare: Option<unsafe extern fn()>,
-                          parent: Option<unsafe extern fn()>,
-                          child: Option<unsafe extern fn()>) -> ::c_int;
+    pub fn pthread_atfork(prepare: ::Option<unsafe extern fn()>,
+                          parent: ::Option<unsafe extern fn()>,
+                          child: ::Option<unsafe extern fn()>) -> ::c_int;
     pub fn getgrgid(gid: ::gid_t) -> *mut ::group;
     pub fn getgrouplist(user: *const ::c_char,
                         group: ::gid_t,
@@ -1950,6 +2050,11 @@ extern {
                           f: extern fn(*mut ::c_void) -> *mut ::c_void,
                           value: *mut ::c_void) -> ::c_int;
     pub fn __errno() -> *mut ::c_int;
+    pub fn inotify_rm_watch(fd: ::c_int, wd: ::uint32_t) -> ::c_int;
+    pub fn sendmmsg(sockfd: ::c_int, msgvec: *const ::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: *const ::timespec) -> ::c_int;
 }
 
 cfg_if! {
diff --git a/src/unix/notbsd/emscripten/align.rs b/src/unix/notbsd/emscripten/align.rs
index 3f36d45d6d71fb60114f8adcd9c3f682c583e902..26a49b234b99c34cdb26ffe68cc8e6db919fafc8 100644
--- a/src/unix/notbsd/emscripten/align.rs
+++ b/src/unix/notbsd/emscripten/align.rs
@@ -32,10 +32,35 @@ macro_rules! expand_align {
                        repr(align(4)))]
             #[cfg_attr(target_pointer_width = "64",
                        repr(align(8)))]
-            #[allow(missing_debug_implementations)]
             pub struct pthread_cond_t {
                 size: [u8; ::__SIZEOF_PTHREAD_COND_T],
             }
         }
+
+        cfg_if! {
+            if #[cfg(feature = "extra_traits")] {
+                impl PartialEq for pthread_cond_t {
+                    fn eq(&self, other: &pthread_cond_t) -> bool {
+                        self.size
+                            .iter()
+                            .zip(other.size.iter())
+                            .all(|(a,b)| a == b)
+                    }
+                }
+                impl Eq for pthread_cond_t {}
+                impl ::fmt::Debug for pthread_cond_t {
+                    fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                        f.debug_struct("pthread_cond_t")
+                            // FIXME: .field("size", &self.size)
+                            .finish()
+                    }
+                }
+                impl ::hash::Hash for pthread_cond_t {
+                    fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                        self.size.hash(state);
+                    }
+                }
+            }
+        }
     }
 }
diff --git a/src/unix/notbsd/emscripten/mod.rs b/src/unix/notbsd/emscripten/mod.rs
index 5de7b5ac57608600db55424e1fab668adff5eb2a..0f8c76e3ab6d0f40d40932bda0ce03c7ebedf4ed 100644
--- a/src/unix/notbsd/emscripten/mod.rs
+++ b/src/unix/notbsd/emscripten/mod.rs
@@ -1,5 +1,3 @@
-use dox::{mem, Option};
-
 pub type c_char = i8;
 pub type wchar_t = i32;
 pub type useconds_t = u32;
@@ -37,8 +35,8 @@ pub type nlink_t = u32;
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum fpos64_t {} // TODO: fill this out with a struct
-impl ::dox::Copy for fpos64_t {}
-impl ::dox::Clone for fpos64_t {
+impl ::Copy for fpos64_t {}
+impl ::Clone for fpos64_t {
     fn clone(&self) -> fpos64_t { *self }
 }
 
@@ -169,11 +167,6 @@ s! {
         pub msgseg: ::c_ushort,
     }
 
-    pub struct mmsghdr {
-        pub msg_hdr: ::msghdr,
-        pub msg_len: ::c_uint,
-    }
-
     pub struct sembuf {
         pub sem_num: ::c_ushort,
         pub sem_op: ::c_short,
@@ -201,7 +194,7 @@ s! {
         pub sa_sigaction: ::sighandler_t,
         pub sa_mask: ::sigset_t,
         pub sa_flags: ::c_int,
-        pub sa_restorer: ::dox::Option<extern fn()>,
+        pub sa_restorer: ::Option<extern fn()>,
     }
 
     pub struct ipc_perm {
@@ -410,7 +403,6 @@ s! {
 }
 
 s_no_extra_traits! {
-    #[allow(missing_debug_implementations)]
     pub struct dirent {
         pub d_ino: ::ino_t,
         pub d_off: ::off_t,
@@ -419,7 +411,6 @@ s_no_extra_traits! {
         pub d_name: [::c_char; 256],
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct dirent64 {
         pub d_ino: ::ino64_t,
         pub d_off: ::off64_t,
@@ -428,7 +419,6 @@ s_no_extra_traits! {
         pub d_name: [::c_char; 256],
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct sysinfo {
         pub uptime: ::c_ulong,
         pub loads: [::c_ulong; 3],
@@ -447,6 +437,142 @@ s_no_extra_traits! {
     }
 }
 
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for dirent {
+            fn eq(&self, other: &dirent) -> bool {
+                self.d_ino == other.d_ino
+                    && self.d_off == other.d_off
+                    && self.d_reclen == other.d_reclen
+                    && self.d_type == other.d_type
+                    && self
+                    .d_name
+                    .iter()
+                    .zip(other.d_name.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for dirent {}
+        impl ::fmt::Debug for dirent {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("dirent")
+                    .field("d_ino", &self.d_ino)
+                    .field("d_off", &self.d_off)
+                    .field("d_reclen", &self.d_reclen)
+                    .field("d_type", &self.d_type)
+                    // FIXME: .field("d_name", &self.d_name)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for dirent {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.d_ino.hash(state);
+                self.d_off.hash(state);
+                self.d_reclen.hash(state);
+                self.d_type.hash(state);
+                self.d_name.hash(state);
+            }
+        }
+
+        impl PartialEq for dirent64 {
+            fn eq(&self, other: &dirent64) -> bool {
+                self.d_ino == other.d_ino
+                    && self.d_off == other.d_off
+                    && self.d_reclen == other.d_reclen
+                    && self.d_type == other.d_type
+                    && self
+                    .d_name
+                    .iter()
+                    .zip(other.d_name.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for dirent64 {}
+        impl ::fmt::Debug for dirent64 {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("dirent64")
+                    .field("d_ino", &self.d_ino)
+                    .field("d_off", &self.d_off)
+                    .field("d_reclen", &self.d_reclen)
+                    .field("d_type", &self.d_type)
+                    // FIXME: .field("d_name", &self.d_name)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for dirent64 {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.d_ino.hash(state);
+                self.d_off.hash(state);
+                self.d_reclen.hash(state);
+                self.d_type.hash(state);
+                self.d_name.hash(state);
+            }
+        }
+
+        impl PartialEq for sysinfo {
+            fn eq(&self, other: &sysinfo) -> bool {
+                self.uptime == other.uptime
+                    && self.loads == other.loads
+                    && self.totalram == other.totalram
+                    && self.freeram == other.freeram
+                    && self.sharedram == other.sharedram
+                    && self.bufferram == other.bufferram
+                    && self.totalswap == other.totalswap
+                    && self.freeswap == other.freeswap
+                    && self.procs == other.procs
+                    && self.pad == other.pad
+                    && self.totalhigh == other.totalhigh
+                    && self.freehigh == other.freehigh
+                    && self.mem_unit == other.mem_unit
+                    && self
+                    .__reserved
+                    .iter()
+                    .zip(other.__reserved.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for sysinfo {}
+        impl ::fmt::Debug for sysinfo {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sysinfo")
+                    .field("uptime", &self.uptime)
+                    .field("loads", &self.loads)
+                    .field("totalram", &self.totalram)
+                    .field("freeram", &self.freeram)
+                    .field("sharedram", &self.sharedram)
+                    .field("bufferram", &self.bufferram)
+                    .field("totalswap", &self.totalswap)
+                    .field("freeswap", &self.freeswap)
+                    .field("procs", &self.procs)
+                    .field("pad", &self.pad)
+                    .field("totalhigh", &self.totalhigh)
+                    .field("freehigh", &self.freehigh)
+                    .field("mem_unit", &self.mem_unit)
+                    // FIXME: .field("__reserved", &self.__reserved)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for sysinfo {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.uptime.hash(state);
+                self.loads.hash(state);
+                self.totalram.hash(state);
+                self.freeram.hash(state);
+                self.sharedram.hash(state);
+                self.bufferram.hash(state);
+                self.totalswap.hash(state);
+                self.freeswap.hash(state);
+                self.procs.hash(state);
+                self.pad.hash(state);
+                self.totalhigh.hash(state);
+                self.freehigh.hash(state);
+                self.mem_unit.hash(state);
+                self.__reserved.hash(state);
+            }
+        }
+    }
+}
+
 pub const ABDAY_1: ::nl_item = 0x20000;
 pub const ABDAY_2: ::nl_item = 0x20001;
 pub const ABDAY_3: ::nl_item = 0x20002;
@@ -1477,7 +1603,7 @@ pub const ATF_MAGIC: ::c_int = 0x80;
 f! {
     pub fn CMSG_NXTHDR(mhdr: *const msghdr,
                        cmsg: *const cmsghdr) -> *mut cmsghdr {
-        if ((*cmsg).cmsg_len as usize) < mem::size_of::<cmsghdr>() {
+        if ((*cmsg).cmsg_len as usize) < ::mem::size_of::<cmsghdr>() {
             return 0 as *mut cmsghdr;
         };
         let next = (cmsg as usize +
@@ -1499,21 +1625,23 @@ f! {
     }
 
     pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () {
-        let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
+        let size_in_bits
+            = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
         let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits);
         cpuset.bits[idx] |= 1 << offset;
         ()
     }
 
     pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () {
-        let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
+        let size_in_bits
+            = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
         let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits);
         cpuset.bits[idx] &= !(1 << offset);
         ()
     }
 
     pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool {
-        let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]);
+        let size_in_bits = 8 * ::mem::size_of_val(&cpuset.bits[0]);
         let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits);
         0 != (cpuset.bits[idx] & (1 << offset))
     }
@@ -1622,7 +1750,7 @@ extern {
 
     pub fn glob(pattern: *const c_char,
                 flags: ::c_int,
-                errfunc: Option<extern fn(epath: *const c_char,
+                errfunc: ::Option<extern fn(epath: *const c_char,
                                           errno: ::c_int) -> ::c_int>,
                 pglob: *mut ::glob_t) -> ::c_int;
     pub fn globfree(pglob: *mut ::glob_t);
@@ -1648,9 +1776,9 @@ 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 sendmmsg(sockfd: ::c_int, msgvec: *mut mmsghdr, vlen: ::c_uint,
+    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,
+    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 ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int;
diff --git a/src/unix/notbsd/emscripten/no_align.rs b/src/unix/notbsd/emscripten/no_align.rs
index cf8880794c16842a687ed275ff50089fdbc8c6c1..ece4dff17c665dda2aaed70bc6b5291ca56ddeeb 100644
--- a/src/unix/notbsd/emscripten/no_align.rs
+++ b/src/unix/notbsd/emscripten/no_align.rs
@@ -28,11 +28,36 @@ macro_rules! expand_align {
         }
 
         s_no_extra_traits! {
-            #[allow(missing_debug_implementations)]
             pub struct pthread_cond_t {
                 __align: [*const ::c_void; 0],
                 size: [u8; ::__SIZEOF_PTHREAD_COND_T],
             }
         }
+
+        cfg_if! {
+            if #[cfg(feature = "extra_traits")] {
+                impl PartialEq for pthread_cond_t {
+                    fn eq(&self, other: &pthread_cond_t) -> bool {
+                        self.size
+                            .iter()
+                            .zip(other.size.iter())
+                            .all(|(a,b)| a == b)
+                    }
+                }
+                impl Eq for pthread_cond_t {}
+                impl ::fmt::Debug for pthread_cond_t {
+                    fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                        f.debug_struct("pthread_cond_t")
+                            // FIXME: .field("size", &self.size)
+                            .finish()
+                    }
+                }
+                impl ::hash::Hash for pthread_cond_t {
+                    fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                        self.size.hash(state);
+                    }
+                }
+            }
+        }
     }
 }
diff --git a/src/unix/notbsd/linux/mips/mips32.rs b/src/unix/notbsd/linux/mips/mips32.rs
index a6c08a5ad71b8af4aeb0a4f74b0a4e068da52fc9..991161395444ab7b2aaccdfe00eeee748d1286fd 100644
--- a/src/unix/notbsd/linux/mips/mips32.rs
+++ b/src/unix/notbsd/linux/mips/mips32.rs
@@ -133,7 +133,7 @@ s! {
         pub sa_flags: ::c_int,
         pub sa_sigaction: ::sighandler_t,
         pub sa_mask: sigset_t,
-        pub sa_restorer: ::dox::Option<extern fn()>,
+        pub sa_restorer: ::Option<extern fn()>,
         _resv: [::c_int; 1],
     }
 
diff --git a/src/unix/notbsd/linux/mips/mips64.rs b/src/unix/notbsd/linux/mips/mips64.rs
index e8b02a36b0e718b9296c8ff3a6c9d3a4be2921ad..c4247c976c9bd74684f62725e5414c3dea640c5f 100644
--- a/src/unix/notbsd/linux/mips/mips64.rs
+++ b/src/unix/notbsd/linux/mips/mips64.rs
@@ -131,7 +131,7 @@ s! {
         pub sa_flags: ::c_int,
         pub sa_sigaction: ::sighandler_t,
         pub sa_mask: sigset_t,
-        pub sa_restorer: ::dox::Option<extern fn()>,
+        pub sa_restorer: ::Option<extern fn()>,
     }
 
     pub struct stack_t {
diff --git a/src/unix/notbsd/linux/mips/mod.rs b/src/unix/notbsd/linux/mips/mod.rs
index 5d4dec79bf5e7ac57f4e33145bd13b48c97c7b2b..b7001866eba3aaf405db40da6764e27a3683e716 100644
--- a/src/unix/notbsd/linux/mips/mod.rs
+++ b/src/unix/notbsd/linux/mips/mod.rs
@@ -913,7 +913,7 @@ extern {
                      sz: ::c_int) -> ::c_int;
     pub fn glob64(pattern: *const ::c_char,
                   flags: ::c_int,
-                  errfunc: ::dox::Option<extern fn(epath: *const ::c_char,
+                  errfunc: ::Option<extern fn(epath: *const ::c_char,
                                                    errno: ::c_int)
                                                    -> ::c_int>,
                   pglob: *mut glob64_t) -> ::c_int;
diff --git a/src/unix/notbsd/linux/mod.rs b/src/unix/notbsd/linux/mod.rs
index 03192e6278e3d0e45f19206753809ee514633931..b9ecc9de9f4393ff5e00bac10fe50bc18e307269 100644
--- a/src/unix/notbsd/linux/mod.rs
+++ b/src/unix/notbsd/linux/mod.rs
@@ -1,7 +1,5 @@
 //! Linux-specific definitions for linux-like values
 
-use dox::{mem, Option};
-
 pub type useconds_t = u32;
 pub type dev_t = u64;
 pub type socklen_t = u32;
@@ -40,8 +38,8 @@ pub type Elf64_Section = u16;
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum fpos64_t {} // TODO: fill this out with a struct
-impl ::dox::Copy for fpos64_t {}
-impl ::dox::Clone for fpos64_t {
+impl ::Copy for fpos64_t {}
+impl ::Clone for fpos64_t {
     fn clone(&self) -> fpos64_t { *self }
 }
 
@@ -191,11 +189,6 @@ s! {
         pub msgseg: ::c_ushort,
     }
 
-    pub struct mmsghdr {
-        pub msg_hdr: ::msghdr,
-        pub msg_len: ::c_uint,
-    }
-
     pub struct sembuf {
         pub sem_num: ::c_ushort,
         pub sem_op: ::c_short,
@@ -500,13 +493,6 @@ s! {
         pub updated: ::c_ulong,
         pub ha: [::c_uchar; ::MAX_ADDR_LEN],
     }
-
-    pub struct inotify_event {
-        pub wd: ::c_int,
-        pub mask: ::uint32_t,
-        pub cookie: ::uint32_t,
-        pub len: ::uint32_t
-    }
 }
 
 s_no_extra_traits!{
@@ -525,6 +511,19 @@ s_no_extra_traits!{
         pub d_type: ::c_uchar,
         pub d_name: [::c_char; 256],
     }
+
+    pub struct sockaddr_alg {
+        pub salg_family: ::sa_family_t,
+        pub salg_type: [::c_uchar; 14],
+        pub salg_feat: u32,
+        pub salg_mask: u32,
+        pub salg_name: [::c_uchar; 64],
+    }
+
+    pub struct af_alg_iv {
+        pub ivlen: u32,
+        pub iv: [::c_uchar; 0],
+    }
 }
 
 cfg_if! {
@@ -670,6 +669,81 @@ cfg_if! {
                 self.size.hash(state);
             }
         }
+
+        impl PartialEq for sockaddr_alg {
+            fn eq(&self, other: &sockaddr_alg) -> bool {
+                self.salg_family == other.salg_family
+                    && self
+                    .salg_type
+                    .iter()
+                    .zip(other.salg_type.iter())
+                    .all(|(a, b)| a == b)
+                    && self.salg_feat == other.salg_feat
+                    && self.salg_mask == other.salg_mask
+                    && self
+                    .salg_name
+                    .iter()
+                    .zip(other.salg_name.iter())
+                    .all(|(a, b)| a == b)
+           }
+        }
+
+        impl Eq for sockaddr_alg {}
+
+        impl ::fmt::Debug for sockaddr_alg {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sockaddr_alg")
+                    .field("salg_family", &self.salg_family)
+                    .field("salg_type", &self.salg_type)
+                    .field("salg_feat", &self.salg_feat)
+                    .field("salg_mask", &self.salg_mask)
+                    .field("salg_name", &&self.salg_name[..])
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for sockaddr_alg {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.salg_family.hash(state);
+                self.salg_type.hash(state);
+                self.salg_feat.hash(state);
+                self.salg_mask.hash(state);
+                self.salg_name.hash(state);
+            }
+        }
+
+        impl af_alg_iv {
+            fn as_slice(&self) -> &[u8] {
+                unsafe {
+                    ::core::slice::from_raw_parts(
+                        self.iv.as_ptr(),
+                        self.ivlen as usize
+                    )
+                }
+            }
+        }
+
+        impl PartialEq for af_alg_iv {
+            fn eq(&self, other: &af_alg_iv) -> bool {
+                *self.as_slice() == *other.as_slice()
+           }
+        }
+
+        impl Eq for af_alg_iv {}
+
+        impl ::fmt::Debug for af_alg_iv {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("af_alg_iv")
+                    .field("iv", &self.as_slice())
+                    .finish()
+            }
+        }
+
+        impl ::hash::Hash for af_alg_iv {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.as_slice().hash(state);
+            }
+        }
     }
 }
 
@@ -1331,6 +1405,10 @@ pub const FALLOC_FL_UNSHARE_RANGE: ::c_int = 0x40;
 pub const ENOATTR: ::c_int = ::ENODATA;
 
 pub const SO_ORIGINAL_DST: ::c_int = 80;
+pub const IP_ORIGDSTADDR : ::c_int = 20;
+pub const IP_RECVORIGDSTADDR : ::c_int = IP_ORIGDSTADDR;
+pub const IPV6_ORIGDSTADDR : ::c_int = 74;
+pub const IPV6_RECVORIGDSTADDR : ::c_int = IPV6_ORIGDSTADDR;
 pub const IUTF8: ::tcflag_t = 0x00004000;
 pub const CMSPAR: ::tcflag_t = 0o10000000000;
 
@@ -1693,45 +1771,6 @@ pub const ARPD_LOOKUP: ::c_ushort = 0x02;
 pub const ARPD_FLUSH: ::c_ushort = 0x03;
 pub const ATF_MAGIC: ::c_int = 0x80;
 
-// uapi/linux/inotify.h
-pub const IN_ACCESS:        ::uint32_t = 0x0000_0001;
-pub const IN_MODIFY:        ::uint32_t = 0x0000_0002;
-pub const IN_ATTRIB:        ::uint32_t = 0x0000_0004;
-pub const IN_CLOSE_WRITE:   ::uint32_t = 0x0000_0008;
-pub const IN_CLOSE_NOWRITE: ::uint32_t = 0x0000_0010;
-pub const IN_CLOSE:         ::uint32_t = (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE);
-pub const IN_OPEN:          ::uint32_t = 0x0000_0020;
-pub const IN_MOVED_FROM:    ::uint32_t = 0x0000_0040;
-pub const IN_MOVED_TO:      ::uint32_t = 0x0000_0080;
-pub const IN_MOVE:          ::uint32_t = (IN_MOVED_FROM | IN_MOVED_TO);
-pub const IN_CREATE:        ::uint32_t = 0x0000_0100;
-pub const IN_DELETE:        ::uint32_t = 0x0000_0200;
-pub const IN_DELETE_SELF:   ::uint32_t = 0x0000_0400;
-pub const IN_MOVE_SELF:     ::uint32_t = 0x0000_0800;
-
-pub const IN_UNMOUNT:       ::uint32_t = 0x0000_2000;
-pub const IN_Q_OVERFLOW:    ::uint32_t = 0x0000_4000;
-pub const IN_IGNORED:       ::uint32_t = 0x0000_8000;
-
-pub const IN_ONLYDIR:       ::uint32_t = 0x0100_0000;
-pub const IN_DONT_FOLLOW:   ::uint32_t = 0x0200_0000;
-// pub const IN_EXCL_UNLINK:   ::uint32_t = 0x0400_0000;
-
-// pub const IN_MASK_CREATE:   ::uint32_t = 0x1000_0000;
-// pub const IN_MASK_ADD:      ::uint32_t = 0x2000_0000;
-pub const IN_ISDIR:         ::uint32_t = 0x4000_0000;
-pub const IN_ONESHOT:       ::uint32_t = 0x8000_0000;
-
-pub const IN_ALL_EVENTS:    ::uint32_t = (
-  IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE |
-  IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM |
-  IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF |
-  IN_MOVE_SELF
-);
-
-pub const IN_CLOEXEC: ::c_int = O_CLOEXEC;
-pub const IN_NONBLOCK: ::c_int = O_NONBLOCK;
-
 #[cfg(not(target_arch = "sparc64"))]
 pub const SO_TIMESTAMPING: ::c_int = 37;
 #[cfg(target_arch = "sparc64")]
@@ -1751,10 +1790,20 @@ pub const SOF_TIMESTAMPING_SOFTWARE: ::c_uint = 1 << 4;
 pub const SOF_TIMESTAMPING_SYS_HARDWARE: ::c_uint = 1 << 5;
 pub const SOF_TIMESTAMPING_RAW_HARDWARE: ::c_uint = 1 << 6;
 
+// linux/if_alg.h
+pub const ALG_SET_KEY: ::c_int = 1;
+pub const ALG_SET_IV: ::c_int = 2;
+pub const ALG_SET_OP: ::c_int = 3;
+pub const ALG_SET_AEAD_ASSOCLEN: ::c_int = 4;
+pub const ALG_SET_AEAD_AUTHSIZE: ::c_int = 5;
+
+pub const ALG_OP_DECRYPT: ::c_int = 0;
+pub const ALG_OP_ENCRYPT: ::c_int = 1;
+
 f! {
     pub fn CMSG_NXTHDR(mhdr: *const msghdr,
                        cmsg: *const cmsghdr) -> *mut cmsghdr {
-        if ((*cmsg).cmsg_len as usize) < mem::size_of::<cmsghdr>() {
+        if ((*cmsg).cmsg_len as usize) < ::mem::size_of::<cmsghdr>() {
             return 0 as *mut cmsghdr;
         };
         let next = (cmsg as usize +
@@ -1778,21 +1827,23 @@ f! {
     }
 
     pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () {
-        let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
+        let size_in_bits
+            = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
         let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits);
         cpuset.bits[idx] |= 1 << offset;
         ()
     }
 
     pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () {
-        let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
+        let size_in_bits
+            = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
         let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits);
         cpuset.bits[idx] &= !(1 << offset);
         ()
     }
 
     pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool {
-        let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]);
+        let size_in_bits = 8 * ::mem::size_of_val(&cpuset.bits[0]);
         let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits);
         0 != (cpuset.bits[idx] & (1 << offset))
     }
@@ -2053,7 +2104,7 @@ extern {
 
     pub fn glob(pattern: *const c_char,
                 flags: ::c_int,
-                errfunc: Option<extern fn(epath: *const c_char,
+                errfunc: ::Option<extern fn(epath: *const c_char,
                                           errno: ::c_int) -> ::c_int>,
                 pglob: *mut ::glob_t) -> ::c_int;
     pub fn globfree(pglob: *mut ::glob_t);
@@ -2082,9 +2133,9 @@ 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,
+    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,
+    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;
@@ -2226,9 +2277,9 @@ extern {
     #[cfg_attr(target_os = "solaris", link_name = "__posix_sigwait")]
     pub fn sigwait(set: *const sigset_t,
                    sig: *mut ::c_int) -> ::c_int;
-    pub fn pthread_atfork(prepare: Option<unsafe extern fn()>,
-                          parent: Option<unsafe extern fn()>,
-                          child: Option<unsafe extern fn()>) -> ::c_int;
+    pub fn pthread_atfork(prepare: ::Option<unsafe extern fn()>,
+                          parent: ::Option<unsafe extern fn()>,
+                          child: ::Option<unsafe extern fn()>) -> ::c_int;
     pub fn getgrgid(gid: ::gid_t) -> *mut ::group;
     pub fn getgrouplist(user: *const ::c_char,
                         group: ::gid_t,
@@ -2247,7 +2298,7 @@ extern {
                           f: extern fn(*mut ::c_void) -> *mut ::c_void,
                           value: *mut ::c_void) -> ::c_int;
     pub fn dl_iterate_phdr(
-        callback: Option<unsafe extern fn(
+        callback: ::Option<unsafe extern fn(
             info: *mut ::dl_phdr_info,
             size: ::size_t,
             data: *mut ::c_void
@@ -2333,11 +2384,6 @@ extern {
         nobj: ::size_t,
         stream: *mut ::FILE
     ) -> ::size_t;
-    pub fn inotify_init() -> ::c_int;
-    pub fn inotify_init1(flags: ::c_int) -> ::c_int;
-    pub fn inotify_add_watch(fd: ::c_int,
-                             path: *const ::c_char,
-                             mask: ::uint32_t) -> ::c_int;
     pub fn inotify_rm_watch(fd: ::c_int, wd: ::c_int) -> ::c_int;
 }
 
diff --git a/src/unix/notbsd/linux/musl/mod.rs b/src/unix/notbsd/linux/musl/mod.rs
index d5351d624bea6fd358e3799539f78b14f700d02c..4f4a3d868af0bf6c4956d3a18316b281b1111d25 100644
--- a/src/unix/notbsd/linux/musl/mod.rs
+++ b/src/unix/notbsd/linux/musl/mod.rs
@@ -37,7 +37,7 @@ s! {
         pub sa_sigaction: ::sighandler_t,
         pub sa_mask: ::sigset_t,
         pub sa_flags: ::c_int,
-        pub sa_restorer: ::dox::Option<extern fn()>,
+        pub sa_restorer: ::Option<extern fn()>,
     }
 
     pub struct statvfs {
@@ -116,7 +116,11 @@ cfg_if! {
                     && self.totalhigh == other.totalhigh
                     && self.freehigh == other.freehigh
                     && self.mem_unit == other.mem_unit
-                // Ignore __reserved field
+                    && self
+                        .__reserved
+                        .iter()
+                        .zip(other.__reserved.iter())
+                        .all(|(a,b)| a == b)
             }
         }
 
@@ -138,7 +142,7 @@ cfg_if! {
                     .field("totalhigh", &self.totalhigh)
                     .field("freehigh", &self.freehigh)
                     .field("mem_unit", &self.mem_unit)
-                // FIXME: .field("__reserved", &self.__reserved)
+                    // FIXME: .field("__reserved", &self.__reserved)
                     .finish()
             }
         }
diff --git a/src/unix/notbsd/linux/other/mod.rs b/src/unix/notbsd/linux/other/mod.rs
index 497ea6d70a93dc594ba814ffd5be91d717de270c..d289f05385a6a90a98045944cf3ddbc98f5d4983 100644
--- a/src/unix/notbsd/linux/other/mod.rs
+++ b/src/unix/notbsd/linux/other/mod.rs
@@ -35,7 +35,7 @@ s! {
         #[cfg(target_arch = "sparc64")]
         __reserved0: ::c_int,
         pub sa_flags: ::c_int,
-        pub sa_restorer: ::dox::Option<extern fn()>,
+        pub sa_restorer: ::Option<extern fn()>,
     }
 
     pub struct stack_t {
@@ -321,7 +321,6 @@ pub const SOL_PNPIPE: ::c_int = 275;
 pub const SOL_RDS: ::c_int = 276;
 pub const SOL_IUCV: ::c_int = 277;
 pub const SOL_CAIF: ::c_int = 278;
-pub const SOL_ALG: ::c_int = 279;
 pub const SOL_NFC: ::c_int = 280;
 pub const SOL_XDP: ::c_int = 283;
 
@@ -927,7 +926,7 @@ extern {
                      sz: ::c_int) -> ::c_int;
     pub fn glob64(pattern: *const ::c_char,
                   flags: ::c_int,
-                  errfunc: ::dox::Option<extern fn(epath: *const ::c_char,
+                  errfunc: ::Option<extern fn(epath: *const ::c_char,
                                                    errno: ::c_int)
                                                    -> ::c_int>,
                   pglob: *mut glob64_t) -> ::c_int;
diff --git a/src/unix/notbsd/linux/s390x/mod.rs b/src/unix/notbsd/linux/s390x/mod.rs
index d4bc9bd2f4a102267d60b49dcd379bae162c89b2..ebe9d41710e629d05f4ec71079d2a983d03ae63d 100644
--- a/src/unix/notbsd/linux/s390x/mod.rs
+++ b/src/unix/notbsd/linux/s390x/mod.rs
@@ -1,4 +1,4 @@
-use pthread_mutex_t;
+use ::pthread_mutex_t;
 
 pub type blkcnt_t = i64;
 pub type blksize_t = i64;
@@ -92,7 +92,7 @@ s! {
         pub sa_sigaction: ::sighandler_t,
         __glibc_reserved0: ::c_int,
         pub sa_flags: ::c_int,
-        pub sa_restorer: ::dox::Option<extern fn()>,
+        pub sa_restorer: ::Option<extern fn()>,
         pub sa_mask: sigset_t,
     }
 
@@ -1322,7 +1322,7 @@ extern {
                      sz: ::c_int) -> ::c_int;
     pub fn glob64(pattern: *const ::c_char,
                   flags: ::c_int,
-                  errfunc: ::dox::Option<extern fn(epath: *const ::c_char,
+                  errfunc: ::Option<extern fn(epath: *const ::c_char,
                                                    errno: ::c_int)
                                                    -> ::c_int>,
                   pglob: *mut glob64_t) -> ::c_int;
diff --git a/src/unix/notbsd/mod.rs b/src/unix/notbsd/mod.rs
index baabd6e84dadda46684f0bfea9ac523549e20293..13ddb292d3fb3500c4e15d20f1c1cee3a9b5121d 100644
--- a/src/unix/notbsd/mod.rs
+++ b/src/unix/notbsd/mod.rs
@@ -1,5 +1,3 @@
-use dox::mem;
-
 pub type sa_family_t = u16;
 pub type pthread_key_t = ::c_uint;
 pub type speed_t = ::c_uint;
@@ -10,8 +8,8 @@ pub type id_t = ::c_uint;
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum timezone {}
-impl ::dox::Copy for timezone {}
-impl ::dox::Clone for timezone {
+impl ::Copy for timezone {}
+impl ::Clone for timezone {
     fn clone(&self) -> timezone { *self }
 }
 
@@ -209,6 +207,18 @@ s! {
         pub ar_pln: u8,
         pub ar_op: u16,
     }
+
+    pub struct inotify_event {
+        pub wd: ::c_int,
+        pub mask: ::uint32_t,
+        pub cookie: ::uint32_t,
+        pub len: ::uint32_t
+    }
+
+    pub struct mmsghdr {
+        pub msg_hdr: ::msghdr,
+        pub msg_len: ::c_uint,
+    }
 }
 
 s_no_extra_traits!{
@@ -220,7 +230,6 @@ s_no_extra_traits!{
                 not(target_os = "android")),
             target_arch = "x86_64"),
         repr(packed))]
-    #[allow(missing_debug_implementations)]
     pub struct epoll_event {
         pub events: ::uint32_t,
         pub u64: ::uint64_t,
@@ -252,6 +261,32 @@ s_no_extra_traits!{
 
 cfg_if! {
     if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for epoll_event {
+            fn eq(&self, other: &epoll_event) -> bool {
+                self.events == other.events
+                    && self.u64 == other.u64
+            }
+        }
+        impl Eq for epoll_event {}
+        impl ::fmt::Debug for epoll_event {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                let events = self.events;
+                let u64 = self.u64;
+                f.debug_struct("epoll_event")
+                    .field("events", &events)
+                    .field("u64", &u64)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for epoll_event {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                let events = self.events;
+                let u64 = self.u64;
+                events.hash(state);
+                u64.hash(state);
+            }
+        }
+
         impl PartialEq for sockaddr_un {
             fn eq(&self, other: &sockaddr_un) -> bool {
                 self.sun_family == other.sun_family
@@ -262,9 +297,7 @@ cfg_if! {
                     .all(|(a, b)| a == b)
             }
         }
-
         impl Eq for sockaddr_un {}
-
         impl ::fmt::Debug for sockaddr_un {
             fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
                 f.debug_struct("sockaddr_un")
@@ -273,7 +306,6 @@ cfg_if! {
                     .finish()
             }
         }
-
         impl ::hash::Hash for sockaddr_un {
             fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
                 self.sun_family.hash(state);
@@ -657,6 +689,7 @@ pub const SOL_DCCP: ::c_int = 269;
 pub const SOL_NETLINK: ::c_int = 270;
 pub const SOL_TIPC: ::c_int = 271;
 pub const SOL_BLUETOOTH: ::c_int = 274;
+pub const SOL_ALG: ::c_int = 279;
 
 pub const AF_UNSPEC: ::c_int = 0;
 pub const AF_UNIX: ::c_int = 1;
@@ -774,6 +807,7 @@ pub const IP_RECVTOS: ::c_int = 13;
 pub const IP_ADD_MEMBERSHIP: ::c_int = 35;
 pub const IP_DROP_MEMBERSHIP: ::c_int = 36;
 pub const IP_TRANSPARENT: ::c_int = 19;
+pub const IPV6_FLOWINFO: ::c_int = 11;
 pub const IPV6_UNICAST_HOPS: ::c_int = 16;
 pub const IPV6_MULTICAST_IF: ::c_int = 17;
 pub const IPV6_MULTICAST_HOPS: ::c_int = 18;
@@ -781,11 +815,16 @@ pub const IPV6_MULTICAST_LOOP: ::c_int = 19;
 pub const IPV6_ADD_MEMBERSHIP: ::c_int = 20;
 pub const IPV6_DROP_MEMBERSHIP: ::c_int = 21;
 pub const IPV6_V6ONLY: ::c_int = 26;
+pub const IPV6_FLOWLABEL_MGR: ::c_int = 32;
+pub const IPV6_FLOWINFO_SEND: ::c_int = 33;
 pub const IPV6_RECVPKTINFO: ::c_int = 49;
 pub const IPV6_PKTINFO: ::c_int = 50;
 pub const IPV6_RECVTCLASS: ::c_int = 66;
 pub const IPV6_TCLASS: ::c_int = 67;
 
+pub const IPV6_FLOWINFO_FLOWLABEL: ::c_int = 0x000fffff;
+pub const IPV6_FLOWINFO_PRIORITY: ::c_int = 0x0ff00000;
+
 pub const TCP_NODELAY: ::c_int = 1;
 pub const TCP_MAXSEG: ::c_int = 2;
 pub const TCP_CORK: ::c_int = 3;
@@ -1128,13 +1167,52 @@ pub const ARPHRD_IEEE802154: u16 = 804;
 pub const ARPHRD_VOID: u16 = 0xFFFF;
 pub const ARPHRD_NONE: u16 = 0xFFFE;
 
+// uapi/linux/inotify.h
+pub const IN_ACCESS:        ::uint32_t = 0x0000_0001;
+pub const IN_MODIFY:        ::uint32_t = 0x0000_0002;
+pub const IN_ATTRIB:        ::uint32_t = 0x0000_0004;
+pub const IN_CLOSE_WRITE:   ::uint32_t = 0x0000_0008;
+pub const IN_CLOSE_NOWRITE: ::uint32_t = 0x0000_0010;
+pub const IN_CLOSE:         ::uint32_t = (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE);
+pub const IN_OPEN:          ::uint32_t = 0x0000_0020;
+pub const IN_MOVED_FROM:    ::uint32_t = 0x0000_0040;
+pub const IN_MOVED_TO:      ::uint32_t = 0x0000_0080;
+pub const IN_MOVE:          ::uint32_t = (IN_MOVED_FROM | IN_MOVED_TO);
+pub const IN_CREATE:        ::uint32_t = 0x0000_0100;
+pub const IN_DELETE:        ::uint32_t = 0x0000_0200;
+pub const IN_DELETE_SELF:   ::uint32_t = 0x0000_0400;
+pub const IN_MOVE_SELF:     ::uint32_t = 0x0000_0800;
+
+pub const IN_UNMOUNT:       ::uint32_t = 0x0000_2000;
+pub const IN_Q_OVERFLOW:    ::uint32_t = 0x0000_4000;
+pub const IN_IGNORED:       ::uint32_t = 0x0000_8000;
+
+pub const IN_ONLYDIR:       ::uint32_t = 0x0100_0000;
+pub const IN_DONT_FOLLOW:   ::uint32_t = 0x0200_0000;
+// pub const IN_EXCL_UNLINK:   ::uint32_t = 0x0400_0000;
+
+// pub const IN_MASK_CREATE:   ::uint32_t = 0x1000_0000;
+// pub const IN_MASK_ADD:      ::uint32_t = 0x2000_0000;
+pub const IN_ISDIR:         ::uint32_t = 0x4000_0000;
+pub const IN_ONESHOT:       ::uint32_t = 0x8000_0000;
+
+pub const IN_ALL_EVENTS:    ::uint32_t = (
+  IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE |
+  IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM |
+  IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF |
+  IN_MOVE_SELF
+);
+
+pub const IN_CLOEXEC: ::c_int = O_CLOEXEC;
+pub const IN_NONBLOCK: ::c_int = O_NONBLOCK;
+
 fn CMSG_ALIGN(len: usize) -> usize {
-    len + mem::size_of::<usize>() - 1 & !(mem::size_of::<usize>() - 1)
+    len + ::mem::size_of::<usize>() - 1 & !(::mem::size_of::<usize>() - 1)
 }
 
 f! {
     pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr {
-        if (*mhdr).msg_controllen as usize >= mem::size_of::<cmsghdr>() {
+        if (*mhdr).msg_controllen as usize >= ::mem::size_of::<cmsghdr>() {
             (*mhdr).msg_control as *mut cmsghdr
         } else {
             0 as *mut cmsghdr
@@ -1146,30 +1224,30 @@ f! {
     }
 
     pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
-        (CMSG_ALIGN(length as usize) + CMSG_ALIGN(mem::size_of::<cmsghdr>()))
+        (CMSG_ALIGN(length as usize) + CMSG_ALIGN(::mem::size_of::<cmsghdr>()))
             as ::c_uint
     }
 
     pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
-        CMSG_ALIGN(mem::size_of::<cmsghdr>()) as ::c_uint + length
+        CMSG_ALIGN(::mem::size_of::<cmsghdr>()) as ::c_uint + length
     }
 
     pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () {
         let fd = fd as usize;
-        let size = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         (*set).fds_bits[fd / size] &= !(1 << (fd % size));
         return
     }
 
     pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool {
         let fd = fd as usize;
-        let size = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0
     }
 
     pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () {
         let fd = fd as usize;
-        let size = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         (*set).fds_bits[fd / size] |= 1 << (fd % size);
         return
     }
@@ -1234,6 +1312,12 @@ f! {
 }
 
 extern {
+    pub fn sem_destroy(sem: *mut sem_t) -> ::c_int;
+    pub fn sem_init(sem: *mut sem_t,
+                    pshared: ::c_int,
+                    value: ::c_uint)
+                    -> ::c_int;
+
     pub fn fdatasync(fd: ::c_int) -> ::c_int;
     pub fn mincore(addr: *mut ::c_void, len: ::size_t,
                    vec: *mut ::c_uchar) -> ::c_int;
@@ -1374,6 +1458,11 @@ extern {
     pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int)
                    -> ::ssize_t;
     pub fn uname(buf: *mut ::utsname) -> ::c_int;
+    pub fn inotify_init() -> ::c_int;
+    pub fn inotify_init1(flags: ::c_int) -> ::c_int;
+    pub fn inotify_add_watch(fd: ::c_int,
+                             path: *const ::c_char,
+                             mask: ::uint32_t) -> ::c_int;
 }
 
 cfg_if! {
diff --git a/src/unix/solarish/mod.rs b/src/unix/solarish/mod.rs
index 8954fd242cf7a572e0d12690935fca2c9e3a0923..ab36e5730f00f203946709402abf1d8c467e9f97 100644
--- a/src/unix/solarish/mod.rs
+++ b/src/unix/solarish/mod.rs
@@ -1,5 +1,3 @@
-use dox::{mem, Option};
-
 pub type c_char = i8;
 pub type c_long = i64;
 pub type c_ulong = u64;
@@ -38,8 +36,8 @@ pub type idtype_t = ::c_uint;
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum timezone {}
-impl ::dox::Copy for timezone {}
-impl ::dox::Clone for timezone {
+impl ::Copy for timezone {}
+impl ::Clone for timezone {
     fn clone(&self) -> timezone { *self }
 }
 
@@ -344,19 +342,16 @@ s! {
 
 s_no_extra_traits! {
     #[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), repr(packed))]
-    #[allow(missing_debug_implementations)]
     pub struct epoll_event {
         pub events: ::uint32_t,
         pub u64: ::uint64_t,
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct sockaddr_un {
         pub sun_family: sa_family_t,
         pub sun_path: [c_char; 108]
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct utsname {
         pub sysname: [::c_char; 257],
         pub nodename: [::c_char; 257],
@@ -365,7 +360,6 @@ s_no_extra_traits! {
         pub machine: [::c_char; 257],
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct fd_set {
         #[cfg(target_pointer_width = "64")]
         fds_bits: [i64; FD_SETSIZE / 64],
@@ -373,7 +367,6 @@ s_no_extra_traits! {
         fds_bits: [i32; FD_SETSIZE / 32],
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct sockaddr_storage {
         pub ss_family: ::sa_family_t,
         __ss_pad1: [u8; 6],
@@ -381,7 +374,6 @@ s_no_extra_traits! {
         __ss_pad2: [u8; 240],
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct siginfo_t {
         pub si_signo: ::c_int,
         pub si_code: ::c_int,
@@ -391,7 +383,6 @@ s_no_extra_traits! {
         __pad: [u8; 232],
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct sockaddr_dl {
         pub sdl_family: ::c_ushort,
         pub sdl_index: ::c_ushort,
@@ -403,6 +394,242 @@ s_no_extra_traits! {
     }
 }
 
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for epoll_event {
+            fn eq(&self, other: &epoll_event) -> bool {
+                self.events == other.events
+                    && self.u64 == other.u64
+            }
+        }
+        impl Eq for epoll_event {}
+        impl ::fmt::Debug for epoll_event {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                let events = self.events;
+                let u64 = self.u64;
+                f.debug_struct("epoll_event")
+                    .field("events", &events)
+                    .field("u64", &u64)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for epoll_event {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                let events = self.events;
+                let u64 = self.u64;
+                events.hash(state);
+                u64.hash(state);
+            }
+        }
+
+        impl PartialEq for sockaddr_un {
+            fn eq(&self, other: &sockaddr_un) -> bool {
+                self.sun_family == other.sun_family
+                    && self
+                    .sun_path
+                    .iter()
+                    .zip(other.sun_path.iter())
+                    .all(|(a, b)| a == b)
+            }
+        }
+        impl Eq for sockaddr_un {}
+        impl ::fmt::Debug for sockaddr_un {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sockaddr_un")
+                    .field("sun_family", &self.sun_family)
+                    // FIXME: .field("sun_path", &self.sun_path)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for sockaddr_un {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.sun_family.hash(state);
+                self.sun_path.hash(state);
+            }
+        }
+
+        impl PartialEq for utsname {
+            fn eq(&self, other: &utsname) -> bool {
+                self.sysname
+                    .iter()
+                    .zip(other.sysname.iter())
+                    .all(|(a, b)| a == b)
+                    && self
+                    .nodename
+                    .iter()
+                    .zip(other.nodename.iter())
+                    .all(|(a, b)| a == b)
+                    && self
+                    .release
+                    .iter()
+                    .zip(other.release.iter())
+                    .all(|(a, b)| a == b)
+                    && self
+                    .version
+                    .iter()
+                    .zip(other.version.iter())
+                    .all(|(a, b)| a == b)
+                    && self
+                    .machine
+                    .iter()
+                    .zip(other.machine.iter())
+                    .all(|(a, b)| a == b)
+            }
+        }
+        impl Eq for utsname {}
+        impl ::fmt::Debug for utsname {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("utsname")
+                    // FIXME: .field("sysname", &self.sysname)
+                    // FIXME: .field("nodename", &self.nodename)
+                    // FIXME: .field("release", &self.release)
+                    // FIXME: .field("version", &self.version)
+                    // FIXME: .field("machine", &self.machine)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for utsname {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.sysname.hash(state);
+                self.nodename.hash(state);
+                self.release.hash(state);
+                self.version.hash(state);
+                self.machine.hash(state);
+            }
+        }
+
+        impl PartialEq for fd_set {
+            fn eq(&self, other: &fd_set) -> bool {
+                self.fds_bits
+                    .iter()
+                    .zip(other.fds_bits.iter())
+                    .all(|(a, b)| a == b)
+            }
+        }
+        impl Eq for fd_set {}
+        impl ::fmt::Debug for fd_set {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("fd_set")
+                    // FIXME: .field("fds_bits", &self.fds_bits)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for fd_set {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.fds_bits.hash(state);
+            }
+        }
+
+        impl PartialEq for sockaddr_storage {
+            fn eq(&self, other: &sockaddr_storage) -> bool {
+                self.ss_family == other.ss_family
+                    && self.__ss_pad1 == other.__ss_pad1
+                    && self.__ss_align == other.__ss_align
+                    && self
+                    .__ss_pad2
+                    .iter()
+                    .zip(other.__ss_pad2.iter())
+                    .all(|(a, b)| a == b)
+            }
+        }
+        impl Eq for sockaddr_storage {}
+        impl ::fmt::Debug for sockaddr_storage {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sockaddr_storage")
+                    .field("ss_family", &self.ss_family)
+                    .field("__ss_pad1", &self.__ss_pad1)
+                    .field("__ss_align", &self.__ss_align)
+                    // FIXME: .field("__ss_pad2", &self.__ss_pad2)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for sockaddr_storage {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.ss_family.hash(state);
+                self.__ss_pad1.hash(state);
+                self.__ss_align.hash(state);
+                self.__ss_pad2.hash(state);
+            }
+        }
+
+        impl PartialEq for siginfo_t {
+            fn eq(&self, other: &siginfo_t) -> bool {
+                self.si_signo == other.si_signo
+                    && self.si_code == other.si_code
+                    && self.si_errno == other.si_errno
+                    && self.si_addr == other.si_addr
+                    && self
+                    .__pad
+                    .iter()
+                    .zip(other.__pad.iter())
+                    .all(|(a, b)| a == b)
+            }
+        }
+        impl Eq for siginfo_t {}
+        impl ::fmt::Debug for siginfo_t {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("siginfo_t")
+                    .field("si_signo", &self.si_signo)
+                    .field("si_code", &self.si_code)
+                    .field("si_errno", &self.si_errno)
+                    .field("si_addr", &self.si_addr)
+                    // FIXME: .field("__pad", &self.__pad)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for siginfo_t {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.si_signo.hash(state);
+                self.si_code.hash(state);
+                self.si_errno.hash(state);
+                self.si_addr.hash(state);
+                self.__pad.hash(state);
+            }
+        }
+
+        impl PartialEq for sockaddr_dl {
+            fn eq(&self, other: &sockaddr_dl) -> bool {
+                self.sdl_family == other.sdl_family
+                    && self.sdl_index == other.sdl_index
+                    && self.sdl_type == other.sdl_type
+                    && self.sdl_nlen == other.sdl_nlen
+                    && self.sdl_alen == other.sdl_alen
+                    && self.sdl_slen == other.sdl_slen
+                    && self
+                    .sdl_data
+                    .iter()
+                    .zip(other.sdl_data.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for sockaddr_dl {}
+        impl ::fmt::Debug for sockaddr_dl {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("sockaddr_dl")
+                    .field("sdl_family", &self.sdl_family)
+                    .field("sdl_index", &self.sdl_index)
+                    .field("sdl_type", &self.sdl_type)
+                    .field("sdl_nlen", &self.sdl_nlen)
+                    .field("sdl_alen", &self.sdl_alen)
+                    .field("sdl_slen", &self.sdl_slen)
+                    // FIXME: .field("sdl_data", &self.sdl_data)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for sockaddr_dl {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.sdl_family.hash(state);
+                self.sdl_index.hash(state);
+                self.sdl_type.hash(state);
+                self.sdl_nlen.hash(state);
+                self.sdl_alen.hash(state);
+                self.sdl_slen.hash(state);
+                self.sdl_data.hash(state);
+            }
+        }
+    }
+}
+
 pub const LC_CTYPE: ::c_int = 0;
 pub const LC_NUMERIC: ::c_int = 1;
 pub const LC_TIME: ::c_int = 2;
@@ -1500,20 +1727,20 @@ pub const VERASE2: usize = 17;
 
 f! {
     pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () {
-        let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         let fd = fd as usize;
         (*set).fds_bits[fd / bits] &= !(1 << (fd % bits));
         return
     }
 
     pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool {
-        let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         let fd = fd as usize;
         return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0
     }
 
     pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () {
-        let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         let fd = fd as usize;
         (*set).fds_bits[fd / bits] |= 1 << (fd % bits);
         return
@@ -1559,6 +1786,12 @@ f! {
 }
 
 extern {
+    pub fn sem_destroy(sem: *mut sem_t) -> ::c_int;
+    pub fn sem_init(sem: *mut sem_t,
+                    pshared: ::c_int,
+                    value: ::c_uint)
+                    -> ::c_int;
+
     pub fn abs(i: ::c_int) -> ::c_int;
     pub fn acct(filename: *const ::c_char) -> ::c_int;
     pub fn atof(s: *const ::c_char) -> ::c_double;
@@ -1637,7 +1870,7 @@ extern {
 
     pub fn glob(pattern: *const ::c_char,
                 flags: ::c_int,
-                errfunc: Option<extern fn(epath: *const ::c_char,
+                errfunc: ::Option<extern fn(epath: *const ::c_char,
                                           errno: ::c_int) -> ::c_int>,
                 pglob: *mut ::glob_t) -> ::c_int;
 
@@ -1779,10 +2012,13 @@ extern {
                link_name = "__posix_sigwait")]
     pub fn sigwait(set: *const sigset_t,
                    sig: *mut ::c_int) -> ::c_int;
-    pub fn pthread_atfork(prepare: Option<unsafe extern fn()>,
-                          parent: Option<unsafe extern fn()>,
-                          child: Option<unsafe extern fn()>) -> ::c_int;
+    pub fn pthread_atfork(prepare: ::Option<unsafe extern fn()>,
+                          parent: ::Option<unsafe extern fn()>,
+                          child: ::Option<unsafe extern fn()>) -> ::c_int;
     pub fn getgrgid(gid: ::gid_t) -> *mut ::group;
+    pub fn setgrent();
+    pub fn endgrent();
+    pub fn getgrent() -> *mut ::group;
     pub fn popen(command: *const c_char,
                  mode: *const c_char) -> *mut ::FILE;
 
diff --git a/src/unix/uclibc/arm/align.rs b/src/unix/uclibc/arm/align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4a0e07460ebb10fe101ee84406726a5a2ac065a1
--- /dev/null
+++ b/src/unix/uclibc/arm/align.rs
@@ -0,0 +1,13 @@
+s! {
+    // FIXME this is actually a union
+    #[cfg_attr(target_pointer_width = "32",
+               repr(align(4)))]
+    #[cfg_attr(target_pointer_width = "64",
+               repr(align(8)))]
+    pub struct sem_t {
+        #[cfg(target_pointer_width = "32")]
+        __size: [::c_char; 16],
+        #[cfg(target_pointer_width = "64")]
+        __size: [::c_char; 32],
+    }
+}
diff --git a/src/unix/uclibc/arm/mod.rs b/src/unix/uclibc/arm/mod.rs
new file mode 100644
index 0000000000000000000000000000000000000000..b250fb5391f0241c8b10cbd37661d24fae87f5c1
--- /dev/null
+++ b/src/unix/uclibc/arm/mod.rs
@@ -0,0 +1,687 @@
+pub type c_char = u8;
+pub type wchar_t = ::c_uint;
+pub type c_long = i32;
+pub type c_ulong = u32;
+pub type time_t = ::c_long;
+
+pub type clock_t = ::c_long;
+pub type fsblkcnt_t = ::c_ulong;
+pub type fsfilcnt_t = ::c_ulong;
+pub type ino_t = ::c_ulong;
+pub type off_t = ::c_long;
+pub type pthread_t = ::c_ulong;
+pub type rlim_t = ::c_ulong;
+pub type suseconds_t = ::c_long;
+
+pub type nlink_t = ::c_uint;
+pub type blksize_t = ::c_long;
+pub type blkcnt_t = ::c_long;
+
+s! {
+    pub struct cmsghdr {
+        pub cmsg_len: ::size_t,
+        pub cmsg_level: ::c_int,
+        pub cmsg_type: ::c_int,
+    }
+
+    pub struct msghdr {
+        pub msg_name: *mut ::c_void,
+        pub msg_namelen: ::socklen_t,
+        pub msg_iov: *mut ::iovec,
+        pub msg_iovlen: ::c_int,
+        pub msg_control: *mut ::c_void,
+        pub msg_controllen: ::socklen_t,
+        pub msg_flags: ::c_int,
+    }
+
+    pub struct pthread_attr_t {
+        __size: [::c_long; 9],
+    }
+
+    pub struct stat {
+        pub st_dev: ::c_ulonglong,
+        pub __pad1: ::c_ushort,
+        pub st_ino: ::ino_t,
+        pub st_mode: ::mode_t,
+        pub st_nlink: ::nlink_t,
+        pub st_uid: ::uid_t,
+        pub st_gid: ::gid_t,
+        pub st_rdev: ::c_ulonglong,
+        pub __pad2: ::c_ushort,
+        pub st_size: ::off_t,
+        pub st_blksize: ::blksize_t,
+        pub st_blocks: ::blkcnt_t,
+        pub st_atim: ::timespec,
+        pub st_mtim: ::timespec,
+        pub st_ctim: ::timespec,
+        pub __unused4: ::c_ulong,
+        pub __unused5: ::c_ulong,
+    }
+
+    pub struct stat64
+    {
+        pub st_dev: ::c_ulonglong,
+        pub __pad1: ::c_uint,
+        pub __st_ino: ::ino_t,
+        pub st_mode: ::mode_t,
+        pub st_nlink: ::nlink_t,
+        pub st_uid: ::uid_t,
+        pub st_gid: ::gid_t,
+        pub st_rdev: ::c_ulonglong,
+        pub __pad2: ::c_uint,
+        pub st_size: ::off64_t,
+        pub st_blksize: ::blksize_t,
+        pub st_blocks: ::blkcnt64_t,
+        pub st_atim: ::timespec,
+        pub st_mtim: ::timespec,
+        pub st_ctim: ::timespec,
+        pub st_ino: ::ino64_t,
+    }
+
+    pub struct flock {
+        pub l_type: ::c_short,
+        pub l_whence: ::c_short,
+        pub l_start: ::off_t,
+        pub l_len: ::off_t,
+        pub l_pid: ::pid_t,
+    }
+
+    pub struct statfs {
+        pub f_type: ::c_int,
+        pub f_bsize: ::c_int,
+        pub f_blocks: ::fsblkcnt_t,
+        pub f_bfree: ::fsblkcnt_t,
+        pub f_bavail: ::fsblkcnt_t,
+        pub f_files: ::fsfilcnt_t,
+        pub f_ffree: ::fsfilcnt_t,
+
+        pub f_fsid: ::fsid_t,
+        pub f_namelen: ::c_int,
+        pub f_frsize: ::c_int,
+        pub f_spare: [::c_int; 5],
+    }
+
+    pub struct sigset_t {
+        __val: [::c_ulong; 2],
+    }
+
+    pub struct sigaction {
+        pub sa_sigaction: ::sighandler_t,
+        // uClibc defines sa_flags as `unsigned long int`,
+        // but nix crate expects `int`
+        pub sa_flags: ::c_int,
+        pub sa_restorer: *mut ::c_void,
+        pub sa_mask: sigset_t,
+    }
+
+    pub struct termios {
+        pub c_iflag: ::tcflag_t,
+        pub c_oflag: ::tcflag_t,
+        pub c_cflag: ::tcflag_t,
+        pub c_lflag: ::tcflag_t,
+        pub c_line: ::cc_t,
+        pub c_cc: [::cc_t; ::NCCS],
+        pub c_ispeed: ::speed_t,
+        pub c_ospeed: ::speed_t,
+    }
+
+    pub struct siginfo_t {
+        pub si_signo: ::c_int,
+        pub si_errno: ::c_int,
+        pub si_code: ::c_int,
+        pub _pad: [::c_int; 29],
+    }
+
+    pub struct stack_t {
+        pub ss_sp: *mut ::c_void,
+        ss_flags: ::c_int,
+        ss_size: ::size_t,
+    }
+
+    pub struct ipc_perm {
+        pub __key: ::key_t,
+        pub uid: ::uid_t,
+        pub gid: ::gid_t,
+        pub cuid: ::uid_t,
+        pub cgid: ::gid_t,
+        pub mode: ::c_ushort,
+        pub __pad1: ::c_ushort,
+        pub __seq: ::c_ushort,
+        pub __pad2: ::c_ushort,
+        pub __unused1: ::c_ulong,
+        pub __unused2: ::c_ulong,
+    }
+
+    pub struct msqid_ds {
+        pub msg_perm: ::ipc_perm,
+        pub msg_stime: ::time_t,
+        pub __unused1: ::c_ulong,
+        pub msg_rtime: ::time_t,
+        pub __unused2: ::c_ulong,
+        pub msg_ctime: ::time_t,
+        pub __unused3: ::c_ulong,
+        pub __msg_cbytes: ::c_ulong,
+        pub msg_qnum: ::msgqnum_t,
+        pub msg_qbytes: ::msglen_t,
+        pub msg_lspid: ::pid_t,
+        pub msg_lrpid: ::pid_t,
+        pub __unused4: ::c_ulong,
+        pub __unused5: ::c_ulong,
+    }
+
+    pub struct shmid_ds {
+        pub shm_perm: ::ipc_perm,
+        pub shm_segsz: ::size_t,
+        pub shm_atime: ::time_t,
+        pub __unused1: ::c_ulong,
+        pub shm_dtime: ::time_t,
+        pub __unused2: ::c_ulong,
+        pub shm_ctime: ::time_t,
+        pub __unused3: ::c_ulong,
+        pub shm_cpid: ::pid_t,
+        pub shm_lpid: ::pid_t,
+        pub shm_nattch: ::shmatt_t,
+        pub __unused4: ::c_ulong,
+        pub __unused5: ::c_ulong,
+    }
+
+    pub struct ucred {
+        pub pid: ::pid_t,
+        pub uid: ::uid_t,
+        pub gid: ::gid_t,
+    }
+
+}
+
+pub const O_CLOEXEC: ::c_int = 0o2000000;
+pub const RLIM_INFINITY: rlim_t = !0;
+pub const __SIZEOF_PTHREAD_ATTR_T: usize = 36;
+pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 24;
+pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4;
+pub const __SIZEOF_PTHREAD_COND_COMPAT_T: usize = 12;
+pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4;
+pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32;
+pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8;
+pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 20;
+pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4;
+pub const NCCS: usize = 32;
+
+// I wasn't able to find those constants
+// in uclibc build environment for armv7
+pub const AIO_ALLDONE: ::c_int = 2; // from linux/mod.rs
+pub const AIO_CANCELED: ::c_int = 0; // from linux/mod.rs
+pub const AIO_NOTCANCELED: ::c_int = 1; // from linux/mod.rs
+pub const CLONE_NEWCGROUP: ::c_int = 0x02000000; // from linux/mod.rs
+pub const EPOLLEXCLUSIVE: ::c_int = 0x10000000; // from linux/mod.rs
+pub const EPOLLWAKEUP: ::c_int = 0x20000000; // from linux/other/mod.rs
+pub const EXTPROC: ::tcflag_t = 0o200000; // from asm-generic/termbits.h
+pub const F_GETPIPE_SZ: ::c_int = 1032; // from notbsd/mod.rs
+pub const F_SETPIPE_SZ: ::c_int = 1031; // from notbsd/mod.rs
+pub const LIO_NOP: ::c_int = 2; // from linux/mod.rs
+pub const LIO_NOWAIT: ::c_int = 1; // from linux/mod.rs
+pub const LIO_READ: ::c_int = 0; // from linux/mod.rs
+pub const LIO_WAIT: ::c_int = 0; // from linux/mod.rs
+pub const LIO_WRITE: ::c_int = 1; // from linux/mod.rs
+pub const MAP_HUGETLB: ::c_int = 0x040000; // from linux/other/mod.rs
+pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY;
+pub const RB_KEXEC: ::c_int = 0x45584543u32 as i32; // from linux/mod.rs
+pub const RB_SW_SUSPEND: ::c_int = 0xd000fce2u32 as i32; // from linux/mod.rs
+pub const SO_BUSY_POLL: ::c_int = 46; // from src/unix/notbsd/mod.rs
+pub const SO_PEEK_OFF: ::c_int = 42; // from src/unix/notbsd/mod.rs
+pub const SO_REUSEPORT: ::c_int = 15; // from src/unix/notbsd/mod.rs
+pub const SOL_NETLINK: ::c_int = 270; // from src/unix/notbsd/mod.rs
+pub const _POSIX_VDISABLE: ::cc_t = 0; // from linux/mod.rs
+pub const AT_EMPTY_PATH: ::c_int = 0x1000; // from notbsd/mod.rs
+
+// autogenerated constants with hand tuned types
+pub const AT_NO_AUTOMOUNT: ::c_int = 0x800;
+pub const B0: ::speed_t = 0;
+pub const B1000000: ::speed_t = 0x1008;
+pub const B110: ::speed_t = 0x3;
+pub const B115200: ::speed_t = 0x1002;
+pub const B1152000: ::speed_t = 0x1009;
+pub const B1200: ::speed_t = 0x9;
+pub const B134: ::speed_t = 0x4;
+pub const B150: ::speed_t = 0x5;
+pub const B1500000: ::speed_t = 0x100a;
+pub const B1800: ::speed_t = 0xa;
+pub const B19200: ::speed_t = 0xe;
+pub const B200: ::speed_t = 0x6;
+pub const B2000000: ::speed_t = 0x100b;
+pub const B230400: ::speed_t = 0x1003;
+pub const B2400: ::speed_t = 0xb;
+pub const B2500000: ::speed_t = 0x100c;
+pub const B300: ::speed_t = 0x7;
+pub const B3000000: ::speed_t = 0x100d;
+pub const B3500000: ::speed_t = 0x100e;
+pub const B38400: ::speed_t = 0xf;
+pub const B4000000: ::speed_t = 0x100f;
+pub const B460800: ::speed_t = 0x1004;
+pub const B4800: ::speed_t = 0xc;
+pub const B50: ::speed_t = 0x1;
+pub const B500000: ::speed_t = 0x1005;
+pub const B57600: ::speed_t = 0x1001;
+pub const B576000: ::speed_t = 0x1006;
+pub const B600: ::speed_t = 0x8;
+pub const B75: ::speed_t = 0x2;
+pub const B921600: ::speed_t = 0x1007;
+pub const B9600: ::speed_t = 0xd;
+pub const BS1: ::c_int = 0x2000;
+pub const BSDLY: ::c_int = 0x2000;
+pub const CBAUD: ::tcflag_t = 0x100f;
+pub const CBAUDEX: ::tcflag_t = 0x1000;
+pub const CIBAUD: ::tcflag_t = 0x100f0000;
+pub const CLOCAL: ::tcflag_t = 0x800;
+pub const CMSPAR: ::tcflag_t = 0x40000000;
+pub const CPU_SETSIZE: ::c_int = 0x400;
+pub const CR1: ::c_int = 0x200;
+pub const CR2: ::c_int = 0x400;
+pub const CR3: ::c_int = 0x600;
+pub const CRDLY: ::c_int = 0x600;
+pub const CREAD: ::tcflag_t = 0x80;
+pub const CS6: ::tcflag_t = 0x10;
+pub const CS7: ::tcflag_t = 0x20;
+pub const CS8: ::tcflag_t = 0x30;
+pub const CSIZE: ::tcflag_t = 0x30;
+pub const CSTOPB: ::tcflag_t = 0x40;
+pub const EADDRINUSE: ::c_int = 0x62;
+pub const EADDRNOTAVAIL: ::c_int = 0x63;
+pub const EADV: ::c_int = 0x44;
+pub const EAFNOSUPPORT: ::c_int = 0x61;
+pub const EALREADY: ::c_int = 0x72;
+pub const EBADE: ::c_int = 0x34;
+pub const EBADFD: ::c_int = 0x4d;
+pub const EBADMSG: ::c_int = 0x4a;
+pub const EBADR: ::c_int = 0x35;
+pub const EBADRQC: ::c_int = 0x38;
+pub const EBADSLT: ::c_int = 0x39;
+pub const EBFONT: ::c_int = 0x3b;
+pub const ECANCELED: ::c_int = 0x7d;
+pub const ECHOCTL: ::tcflag_t = 0x200;
+pub const ECHOE: ::tcflag_t = 0x10;
+pub const ECHOK: ::tcflag_t = 0x20;
+pub const ECHOKE: ::tcflag_t = 0x800;
+pub const ECHONL: ::tcflag_t = 0x40;
+pub const ECHOPRT: ::tcflag_t = 0x400;
+pub const ECHRNG: ::c_int = 0x2c;
+pub const ECOMM: ::c_int = 0x46;
+pub const ECONNABORTED: ::c_int = 0x67;
+pub const ECONNREFUSED: ::c_int = 0x6f;
+pub const ECONNRESET: ::c_int = 0x68;
+pub const EDEADLK: ::c_int = 0x23;
+pub const EDESTADDRREQ: ::c_int = 0x59;
+pub const EDOTDOT: ::c_int = 0x49;
+pub const EDQUOT: ::c_int = 0x7a;
+pub const EFD_CLOEXEC: ::c_int = 0x80000;
+pub const EFD_NONBLOCK: ::c_int = 0x800;
+pub const EHOSTDOWN: ::c_int = 0x70;
+pub const EHOSTUNREACH: ::c_int = 0x71;
+pub const EHWPOISON: ::c_int = 0x85;
+pub const EIDRM: ::c_int = 0x2b;
+pub const EILSEQ: ::c_int = 0x54;
+pub const EINPROGRESS: ::c_int = 0x73;
+pub const EISCONN: ::c_int = 0x6a;
+pub const EISNAM: ::c_int = 0x78;
+pub const EKEYEXPIRED: ::c_int = 0x7f;
+pub const EKEYREJECTED: ::c_int = 0x81;
+pub const EKEYREVOKED: ::c_int = 0x80;
+pub const EL2HLT: ::c_int = 0x33;
+pub const EL2NSYNC: ::c_int = 0x2d;
+pub const EL3HLT: ::c_int = 0x2e;
+pub const EL3RST: ::c_int = 0x2f;
+pub const ELIBACC: ::c_int = 0x4f;
+pub const ELIBBAD: ::c_int = 0x50;
+pub const ELIBEXEC: ::c_int = 0x53;
+pub const ELIBMAX: ::c_int = 0x52;
+pub const ELIBSCN: ::c_int = 0x51;
+pub const ELNRNG: ::c_int = 0x30;
+pub const ELOOP: ::c_int = 0x28;
+pub const EMEDIUMTYPE: ::c_int = 0x7c;
+pub const EMSGSIZE: ::c_int = 0x5a;
+pub const EMULTIHOP: ::c_int = 0x48;
+pub const ENAMETOOLONG: ::c_int = 0x24;
+pub const ENAVAIL: ::c_int = 0x77;
+pub const ENETDOWN: ::c_int = 0x64;
+pub const ENETRESET: ::c_int = 0x66;
+pub const ENETUNREACH: ::c_int = 0x65;
+pub const ENOANO: ::c_int = 0x37;
+pub const ENOBUFS: ::c_int = 0x69;
+pub const ENOCSI: ::c_int = 0x32;
+pub const ENODATA: ::c_int = 0x3d;
+pub const ENOKEY: ::c_int = 0x7e;
+pub const ENOLCK: ::c_int = 0x25;
+pub const ENOLINK: ::c_int = 0x43;
+pub const ENOMEDIUM: ::c_int = 0x7b;
+pub const ENOMSG: ::c_int = 0x2a;
+pub const ENONET: ::c_int = 0x40;
+pub const ENOPKG: ::c_int = 0x41;
+pub const ENOPROTOOPT: ::c_int = 0x5c;
+pub const ENOSR: ::c_int = 0x3f;
+pub const ENOSTR: ::c_int = 0x3c;
+pub const ENOSYS: ::c_int = 0x26;
+pub const ENOTCONN: ::c_int = 0x6b;
+pub const ENOTEMPTY: ::c_int = 0x27;
+pub const ENOTNAM: ::c_int = 0x76;
+pub const ENOTRECOVERABLE: ::c_int = 0x83;
+pub const ENOTSOCK: ::c_int = 0x58;
+pub const ENOTUNIQ: ::c_int = 0x4c;
+pub const EOPNOTSUPP: ::c_int = 0x5f;
+pub const EOVERFLOW: ::c_int = 0x4b;
+pub const EOWNERDEAD: ::c_int = 0x82;
+pub const EPFNOSUPPORT: ::c_int = 0x60;
+pub const EPOLL_CLOEXEC: ::c_int = 0x80000;
+pub const EPROTO: ::c_int = 0x47;
+pub const EPROTONOSUPPORT: ::c_int = 0x5d;
+pub const EPROTOTYPE: ::c_int = 0x5b;
+pub const EREMCHG: ::c_int = 0x4e;
+pub const EREMOTE: ::c_int = 0x42;
+pub const EREMOTEIO: ::c_int = 0x79;
+pub const ERESTART: ::c_int = 0x55;
+pub const ERFKILL: ::c_int = 0x84;
+pub const ESHUTDOWN: ::c_int = 0x6c;
+pub const ESOCKTNOSUPPORT: ::c_int = 0x5e;
+pub const ESRMNT: ::c_int = 0x45;
+pub const ESTALE: ::c_int = 0x74;
+pub const ESTRPIPE: ::c_int = 0x56;
+pub const ETIME: ::c_int = 0x3e;
+pub const ETIMEDOUT: ::c_int = 0x6e;
+pub const ETOOMANYREFS: ::c_int = 0x6d;
+pub const EUCLEAN: ::c_int = 0x75;
+pub const EUNATCH: ::c_int = 0x31;
+pub const EUSERS: ::c_int = 0x57;
+pub const EXFULL: ::c_int = 0x36;
+pub const FF1: ::c_int = 0x8000;
+pub const FFDLY: ::c_int = 0x8000;
+pub const FIONBIO: ::c_ulong = 0x5421;
+pub const FIOCLEX: ::c_ulong = 0x5451;
+pub const FLUSHO: ::tcflag_t = 0x1000;
+pub const F_GETLK: ::c_int = 0x5;
+pub const F_SETLK: ::c_int = 0x6;
+pub const F_SETLKW: ::c_int = 0x7;
+pub const HUPCL: ::tcflag_t = 0x400;
+pub const ICANON: ::tcflag_t = 0x2;
+pub const IEXTEN: ::tcflag_t = 0x8000;
+pub const IPV6_MULTICAST_HOPS: ::c_int = 0x12;
+pub const IPV6_MULTICAST_IF: ::c_int = 0x11;
+pub const IPV6_UNICAST_HOPS: ::c_int = 0x10;
+pub const IP_MULTICAST_IF: ::c_int = 0x20;
+pub const ISIG: ::tcflag_t = 0x1;
+pub const IUTF8: ::tcflag_t = 0x4000;
+pub const IXOFF: ::tcflag_t = 0x1000;
+pub const IXON: ::tcflag_t = 0x400;
+pub const MAP_ANON: ::c_int = 0x20;
+pub const MAP_ANONYMOUS: ::c_int = 0x20;
+pub const MAP_DENYWRITE: ::c_int = 0x800;
+pub const MAP_EXECUTABLE: ::c_int = 0x1000;
+pub const MAP_GROWSDOWN: ::c_int = 0x100;
+pub const MAP_LOCKED: ::c_int = 0x2000;
+pub const MAP_NONBLOCK: ::c_int = 0x10000;
+pub const MAP_NORESERVE: ::c_int = 0x4000;
+pub const MAP_POPULATE: ::c_int = 0x8000;
+pub const MAP_STACK: ::c_int = 0x20000;
+pub const MS_ACTIVE: u32 = 0x40000000;
+pub const MS_DIRSYNC: u32 = 0x80;
+pub const MS_I_VERSION: u32 = 0x800000;
+pub const MS_KERNMOUNT: u32 = 0x400000;
+pub const MS_MOVE: u32 = 0x2000;
+pub const MS_POSIXACL: u32 = 0x10000;
+pub const MS_PRIVATE: u32 = 0x40000;
+pub const MS_REC: u32 = 0x4000;
+pub const MS_RELATIME: u32 = 0x200000;
+pub const MS_SHARED: u32 = 0x100000;
+pub const MS_SILENT: u32 = 0x8000;
+pub const MS_SLAVE: u32 = 0x80000;
+pub const MS_STRICTATIME: u32 = 0x1000000;
+pub const MS_UNBINDABLE: u32 = 0x20000;
+pub const NLDLY: ::tcflag_t = 0x100;
+pub const NOFLSH: ::tcflag_t = 0x80;
+pub const OCRNL: ::c_int = 0x8;
+pub const OFDEL: ::c_int = 0x80;
+pub const OFILL: ::c_int = 0x40;
+pub const OLCUC: ::tcflag_t = 0x2;
+pub const ONLCR: ::tcflag_t = 0x4;
+pub const ONLRET: ::tcflag_t = 0x20;
+pub const ONOCR: ::tcflag_t = 0x10;
+pub const O_ACCMODE: ::c_int = 0x3;
+pub const O_APPEND: ::c_int = 0x400;
+pub const O_CREAT: ::c_int = 0x40;
+pub const O_DIRECT: ::c_int = 0x10000;
+pub const O_DIRECTORY: ::c_int = 0x4000;
+pub const O_DSYNC: ::c_int = 0x1000;
+pub const O_EXCL: ::c_int = 0x80;
+pub const O_NDELAY: ::c_int = 0x800;
+pub const O_NOCTTY: ::c_int = 0x100;
+pub const O_NOFOLLOW: ::c_int = 0x8000;
+pub const O_NONBLOCK: ::c_int = 0x800;
+pub const O_SYNC: ::c_int = 0o10000;
+pub const O_TRUNC: ::c_int = 0x200;
+pub const PARENB: ::tcflag_t = 0x100;
+pub const PARODD: ::tcflag_t = 0x200;
+pub const PENDIN: ::tcflag_t = 0x4000;
+pub const POLLRDBAND: ::c_short = 0x80;
+pub const POLLRDNORM: ::c_short = 0x40;
+pub const POLLWRBAND: ::c_short = 0x200;
+pub const POLLWRNORM: ::c_short = 0x100;
+pub const QIF_ALL: ::uint32_t = 0x3f;
+pub const QIF_BLIMITS: ::uint32_t = 0x1;
+pub const QIF_BTIME: ::uint32_t = 0x10;
+pub const QIF_ILIMITS: ::uint32_t = 0x4;
+pub const QIF_INODES: ::uint32_t = 0x8;
+pub const QIF_ITIME: ::uint32_t = 0x20;
+pub const QIF_LIMITS: ::uint32_t = 0x5;
+pub const QIF_SPACE: ::uint32_t = 0x2;
+pub const QIF_TIMES: ::uint32_t = 0x30;
+pub const QIF_USAGE: ::uint32_t = 0xa;
+pub const SA_NOCLDSTOP: ::c_int = 0x1;
+pub const SA_NOCLDWAIT: ::c_int = 0x2;
+pub const SA_NODEFER: ::c_int = 0x40000000;
+pub const SA_ONSTACK: ::c_int = 0x8000000;
+pub const SA_RESETHAND: ::c_int = 0x80000000;
+pub const SA_RESTART: ::c_int = 0x10000000;
+pub const SA_SIGINFO: ::c_int = 0x4;
+pub const SFD_CLOEXEC: ::c_int = 0x80000;
+pub const SFD_NONBLOCK: ::c_int = 0x800;
+pub const SIGBUS: ::c_int = 0x7;
+pub const SIGCHLD: ::c_int = 0x11;
+pub const SIGCONT: ::c_int = 0x12;
+pub const SIGIO: ::c_int = 0x1d;
+pub const SIGPROF: ::c_int = 0x1b;
+pub const SIGPWR: ::c_int = 0x1e;
+pub const SIGSTKFLT: ::c_int = 0x10;
+pub const SIGSTOP: ::c_int = 0x13;
+pub const SIGSYS: ::c_int = 0x1f;
+pub const SIGTSTP: ::c_int = 0x14;
+pub const SIGTTIN: ::c_int = 0x15;
+pub const SIGTTOU: ::c_int = 0x16;
+pub const SIGURG: ::c_int = 0x17;
+pub const SIGUSR1: ::c_int = 0xa;
+pub const SIGUSR2: ::c_int = 0xc;
+pub const SIGVTALRM: ::c_int = 0x1a;
+pub const SIGWINCH: ::c_int = 0x1c;
+pub const SIGXCPU: ::c_int = 0x18;
+pub const SIGXFSZ: ::c_int = 0x19;
+pub const SIG_BLOCK: ::c_int = 0;
+pub const SIG_SETMASK: ::c_int = 0x2;
+pub const SIG_UNBLOCK: ::c_int = 0x1;
+pub const SOCK_DGRAM: ::c_int = 0x2;
+pub const SOCK_NONBLOCK: ::c_int = 0o0004000;
+pub const SOCK_SEQPACKET: ::c_int = 0x5;
+pub const SOCK_STREAM: ::c_int = 0x1;
+pub const SOL_SOCKET: ::c_int = 0x1;
+pub const SO_ACCEPTCONN: ::c_int = 0x1e;
+pub const SO_BINDTODEVICE: ::c_int = 0x19;
+pub const SO_BROADCAST: ::c_int = 0x6;
+pub const SO_BSDCOMPAT: ::c_int = 0xe;
+pub const SO_DOMAIN: ::c_int = 0x27;
+pub const SO_DONTROUTE: ::c_int = 0x5;
+pub const SO_ERROR: ::c_int = 0x4;
+pub const SO_KEEPALIVE: ::c_int = 0x9;
+pub const SO_LINGER: ::c_int = 0xd;
+pub const SO_MARK: ::c_int = 0x24;
+pub const SO_OOBINLINE: ::c_int = 0xa;
+pub const SO_PASSCRED: ::c_int = 0x10;
+pub const SO_PEERCRED: ::c_int = 0x11;
+pub const SO_PRIORITY: ::c_int = 0xc;
+pub const SO_PROTOCOL: ::c_int = 0x26;
+pub const SO_RCVBUF: ::c_int = 0x8;
+pub const SO_RCVLOWAT: ::c_int = 0x12;
+pub const SO_RCVTIMEO: ::c_int = 0x14;
+pub const SO_REUSEADDR: ::c_int = 0x2;
+pub const SO_RXQ_OVFL: ::c_int = 0x28;
+pub const SO_SNDBUF: ::c_int = 0x7;
+pub const SO_SNDBUFFORCE: ::c_int = 0x20;
+pub const SO_SNDLOWAT: ::c_int = 0x13;
+pub const SO_SNDTIMEO: ::c_int = 0x15;
+pub const SO_TIMESTAMP: ::c_int = 0x1d;
+pub const SO_TYPE: ::c_int = 0x3;
+pub const SYS_gettid: ::c_int = 0xe0;
+pub const TAB1: ::c_int = 0x800;
+pub const TAB2: ::c_int = 0x1000;
+pub const TAB3: ::c_int = 0x1800;
+pub const TABDLY: ::c_int = 0x1800;
+pub const TCSADRAIN: ::c_int = 0x1;
+pub const TCSAFLUSH: ::c_int = 0x2;
+pub const TCSANOW: ::c_int = 0;
+pub const TOSTOP: ::tcflag_t = 0x100;
+pub const VDISCARD: usize = 0xd;
+pub const VEOF: usize = 0x4;
+pub const VEOL: usize = 0xb;
+pub const VEOL2: usize = 0x10;
+pub const VMIN: usize = 0x6;
+pub const VREPRINT: usize = 0xc;
+pub const VSTART: usize = 0x8;
+pub const VSTOP: usize = 0x9;
+pub const VSUSP: usize = 0xa;
+pub const VSWTC: usize = 0x7;
+pub const VT1: ::c_int = 0x4000;
+pub const VTDLY: ::c_int = 0x4000;
+pub const VTIME: usize = 0x5;
+pub const VWERASE: usize = 0xe;
+pub const XTABS: ::tcflag_t = 0x1800;
+pub const _PC_2_SYMLINKS: ::c_int = 0x14;
+pub const _PC_ALLOC_SIZE_MIN: ::c_int = 0x12;
+pub const _PC_ASYNC_IO: ::c_int = 0xa;
+pub const _PC_FILESIZEBITS: ::c_int = 0xd;
+pub const _PC_PRIO_IO: ::c_int = 0xb;
+pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 0xe;
+pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 0xf;
+pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 0x10;
+pub const _PC_REC_XFER_ALIGN: ::c_int = 0x11;
+pub const _PC_SYMLINK_MAX: ::c_int = 0x13;
+pub const _PC_SYNC_IO: ::c_int = 0x9;
+pub const _SC_2_PBS: ::c_int = 0xa8;
+pub const _SC_2_PBS_ACCOUNTING: ::c_int = 0xa9;
+pub const _SC_2_PBS_CHECKPOINT: ::c_int = 0xaf;
+pub const _SC_2_PBS_LOCATE: ::c_int = 0xaa;
+pub const _SC_2_PBS_MESSAGE: ::c_int = 0xab;
+pub const _SC_2_PBS_TRACK: ::c_int = 0xac;
+pub const _SC_ADVISORY_INFO: ::c_int = 0x84;
+pub const _SC_BARRIERS: ::c_int = 0x85;
+pub const _SC_CLOCK_SELECTION: ::c_int = 0x89;
+pub const _SC_CPUTIME: ::c_int = 0x8a;
+pub const _SC_IPV6: ::c_int = 0xeb;
+pub const _SC_MONOTONIC_CLOCK: ::c_int = 0x95;
+pub const _SC_RAW_SOCKETS: ::c_int = 0xec;
+pub const _SC_READER_WRITER_LOCKS: ::c_int = 0x99;
+pub const _SC_REGEXP: ::c_int = 0x9b;
+pub const _SC_SHELL: ::c_int = 0x9d;
+pub const _SC_SPAWN: ::c_int = 0x9f;
+pub const _SC_SPIN_LOCKS: ::c_int = 0x9a;
+pub const _SC_SPORADIC_SERVER: ::c_int = 0xa0;
+pub const _SC_SS_REPL_MAX: ::c_int = 0xf1;
+pub const _SC_SYMLOOP_MAX: ::c_int = 0xad;
+pub const _SC_THREAD_CPUTIME: ::c_int = 0x8b;
+pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 0x52;
+pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 0xf7;
+pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 0xf8;
+pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 0xa1;
+pub const _SC_TIMEOUTS: ::c_int = 0xa4;
+pub const _SC_TRACE: ::c_int = 0xb5;
+pub const _SC_TRACE_EVENT_FILTER: ::c_int = 0xb6;
+pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 0xf2;
+pub const _SC_TRACE_INHERIT: ::c_int = 0xb7;
+pub const _SC_TRACE_LOG: ::c_int = 0xb8;
+pub const _SC_TRACE_NAME_MAX: ::c_int = 0xf3;
+pub const _SC_TRACE_SYS_MAX: ::c_int = 0xf4;
+pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 0xf5;
+pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 0xa5;
+pub const _SC_V6_ILP32_OFF32: ::c_int = 0xb0;
+pub const _SC_V6_ILP32_OFFBIG: ::c_int = 0xb1;
+pub const _SC_V6_LP64_OFF64: ::c_int = 0xb2;
+pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 0xb3;
+pub const _SC_XOPEN_STREAMS: ::c_int = 0xf6;
+
+fn CMSG_ALIGN(len: usize) -> usize {
+    len + ::mem::size_of::<usize>() - 1 & !(::mem::size_of::<usize>() - 1)
+}
+
+f! {
+    pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr {
+        if (*mhdr).msg_controllen as usize >= ::mem::size_of::<cmsghdr>() {
+            (*mhdr).msg_control as *mut cmsghdr
+        } else {
+            0 as *mut cmsghdr
+        }
+    }
+
+    pub fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut ::c_uchar {
+        cmsg.offset(1) as *mut ::c_uchar
+    }
+
+    pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
+        (CMSG_ALIGN(length as usize) + CMSG_ALIGN(::mem::size_of::<cmsghdr>()))
+            as ::c_uint
+    }
+
+    pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
+        CMSG_ALIGN(::mem::size_of::<cmsghdr>()) as ::c_uint + length
+    }
+
+    pub fn CMSG_NXTHDR(mhdr: *const msghdr,
+                       cmsg: *const cmsghdr) -> *mut cmsghdr {
+        if ((*cmsg).cmsg_len as usize) < ::mem::size_of::<cmsghdr>() {
+            return 0 as *mut cmsghdr;
+        };
+        let next = (cmsg as usize +
+                    CMSG_ALIGN((*cmsg).cmsg_len as usize))
+            as *mut cmsghdr;
+        let max = (*mhdr).msg_control as usize
+            + (*mhdr).msg_controllen as usize;
+        if (next.offset(1)) as usize > max ||
+            next as usize + CMSG_ALIGN((*next).cmsg_len as usize) > max
+        {
+            0 as *mut cmsghdr
+        } else {
+            next as *mut cmsghdr
+        }
+    }
+
+}
+
+extern {
+    pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int;
+    pub fn openpty(amaster: *mut ::c_int,
+                aslave: *mut ::c_int,
+                name: *mut ::c_char,
+                termp: *mut termios,
+                winp: *mut ::winsize) -> ::c_int;
+    pub fn setns(fd: ::c_int, nstype: ::c_int) -> ::c_int;
+    pub fn pwritev(fd: ::c_int,
+                   iov: *const ::iovec,
+                   iovcnt: ::c_int,
+                   offset: ::off_t) -> ::ssize_t;
+    pub fn preadv(fd: ::c_int,
+                  iov: *const ::iovec,
+                  iovcnt: ::c_int,
+                  offset: ::off_t) -> ::ssize_t;
+}
+
+cfg_if! {
+    if #[cfg(libc_align)] {
+        mod align;
+        pub use self::align::*;
+    } else {
+        mod no_align;
+        pub use self::no_align::*;
+    }
+}
diff --git a/src/unix/uclibc/arm/no_align.rs b/src/unix/uclibc/arm/no_align.rs
new file mode 100644
index 0000000000000000000000000000000000000000..e32bf673d140e27b412196ccc9b9554b594e2ea8
--- /dev/null
+++ b/src/unix/uclibc/arm/no_align.rs
@@ -0,0 +1,10 @@
+s! {
+    // FIXME this is actually a union
+    pub struct sem_t {
+        #[cfg(target_pointer_width = "32")]
+        __size: [::c_char; 16],
+        #[cfg(target_pointer_width = "64")]
+        __size: [::c_char; 32],
+        __align: [::c_long; 0],
+    }
+}
diff --git a/src/unix/uclibc/mips/mips32/align.rs b/src/unix/uclibc/mips/mips32/align.rs
index 965c9c3cc44981c627e95456dd20c3d290fffcb6..4a0e07460ebb10fe101ee84406726a5a2ac065a1 100644
--- a/src/unix/uclibc/mips/mips32/align.rs
+++ b/src/unix/uclibc/mips/mips32/align.rs
@@ -1,6 +1,6 @@
 s! {
     // FIXME this is actually a union
-    #[cfg_attr(arget_pointer_width = "32",
+    #[cfg_attr(target_pointer_width = "32",
                repr(align(4)))]
     #[cfg_attr(target_pointer_width = "64",
                repr(align(8)))]
diff --git a/src/unix/uclibc/mips/mips32/mod.rs b/src/unix/uclibc/mips/mips32/mod.rs
index 8dc9429e60c1c24e50ed7d9811cf007b51646e0f..23b385424487e7932f843f556fd506844e168f19 100644
--- a/src/unix/uclibc/mips/mips32/mod.rs
+++ b/src/unix/uclibc/mips/mips32/mod.rs
@@ -610,7 +610,7 @@ extern {
                      sz: ::c_int) -> ::c_int;
     pub fn glob64(pattern: *const ::c_char,
                   flags: ::c_int,
-                  errfunc: ::dox::Option<extern fn(epath: *const ::c_char,
+                  errfunc: ::Option<extern fn(epath: *const ::c_char,
                                                    errno: ::c_int)
                                                    -> ::c_int>,
                   pglob: *mut glob64_t) -> ::c_int;
diff --git a/src/unix/uclibc/mod.rs b/src/unix/uclibc/mod.rs
index cfaef3bd736d8b138babc4ff33125f11e6ed6ad5..d2735dba8d8810a828b4e95900ee3742857f806f 100644
--- a/src/unix/uclibc/mod.rs
+++ b/src/unix/uclibc/mod.rs
@@ -1,5 +1,3 @@
-use dox::{mem, Option};
-
 pub type sa_family_t = u16;
 pub type pthread_key_t = ::c_uint;
 pub type speed_t = ::c_uint;
@@ -26,15 +24,15 @@ pub type idtype_t = ::c_uint;
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum fpos64_t {} // TODO: fill this out with a struct
-impl ::dox::Copy for fpos64_t {}
-impl ::dox::Clone for fpos64_t {
+impl ::Copy for fpos64_t {}
+impl ::Clone for fpos64_t {
     fn clone(&self) -> fpos64_t { *self }
 }
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum timezone {}
-impl ::dox::Copy for timezone {}
-impl ::dox::Clone for timezone {
+impl ::Copy for timezone {}
+impl ::Clone for timezone {
     fn clone(&self) -> timezone { *self }
 }
 
@@ -1389,20 +1387,20 @@ pub const AF_MAX: ::c_int = 39;
 f! {
     pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () {
         let fd = fd as usize;
-        let size = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         (*set).fds_bits[fd / size] &= !(1 << (fd % size));
         return
     }
 
     pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool {
         let fd = fd as usize;
-        let size = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0
     }
 
     pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () {
         let fd = fd as usize;
-        let size = mem::size_of_val(&(*set).fds_bits[0]) * 8;
+        let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
         (*set).fds_bits[fd / size] |= 1 << (fd % size);
         return
     }
@@ -1452,21 +1450,23 @@ f! {
     }
 
     pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () {
-        let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
+        let size_in_bits
+            = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
         let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits);
         cpuset.bits[idx] |= 1 << offset;
         ()
     }
 
     pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () {
-        let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
+        let size_in_bits
+            = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
         let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits);
         cpuset.bits[idx] &= !(1 << offset);
         ()
     }
 
     pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool {
-        let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]);
+        let size_in_bits = 8 * ::mem::size_of_val(&cpuset.bits[0]);
         let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits);
         0 != (cpuset.bits[idx] & (1 << offset))
     }
@@ -1481,6 +1481,12 @@ f! {
 }
 
 extern {
+    pub fn sem_destroy(sem: *mut sem_t) -> ::c_int;
+    pub fn sem_init(sem: *mut sem_t,
+                    pshared: ::c_int,
+                    value: ::c_uint)
+                    -> ::c_int;
+
     pub fn abs(i: ::c_int) -> ::c_int;
     pub fn atof(s: *const ::c_char) -> ::c_double;
     pub fn labs(i: ::c_long) -> ::c_long;
@@ -1787,7 +1793,7 @@ extern {
 
     pub fn glob(pattern: *const c_char,
                 flags: ::c_int,
-                errfunc: Option<extern fn(epath: *const c_char,
+                errfunc: ::Option<extern fn(epath: *const c_char,
                                           errno: ::c_int) -> ::c_int>,
                 pglob: *mut ::glob_t) -> ::c_int;
     pub fn globfree(pglob: *mut ::glob_t);
@@ -1871,9 +1877,9 @@ extern {
     #[cfg_attr(target_os = "solaris", link_name = "__posix_sigwait")]
     pub fn sigwait(set: *const sigset_t,
                    sig: *mut ::c_int) -> ::c_int;
-    pub fn pthread_atfork(prepare: Option<unsafe extern fn()>,
-                          parent: Option<unsafe extern fn()>,
-                          child: Option<unsafe extern fn()>) -> ::c_int;
+    pub fn pthread_atfork(prepare: ::Option<unsafe extern fn()>,
+                          parent: ::Option<unsafe extern fn()>,
+                          child: ::Option<unsafe extern fn()>) -> ::c_int;
     pub fn pthread_create(native: *mut ::pthread_t,
                           attr: *const ::pthread_attr_t,
                           f: extern fn(*mut ::c_void) -> *mut ::c_void,
@@ -1893,6 +1899,9 @@ cfg_if! {
     } else if #[cfg(target_arch = "x86_64")] {
         mod x86_64;
         pub use self::x86_64::*;
+    } else if #[cfg(target_arch = "arm")] {
+        mod arm;
+        pub use self::arm::*;
     } else {
         pub use unsupported_target;
     }
diff --git a/src/windows/mod.rs b/src/windows/mod.rs
index acde2e9ee2261efa55e6ca9231cd27576f3c6a9d..70ca675bd6c18bba8cc3b899edd962afa406d5fc 100644
--- a/src/windows/mod.rs
+++ b/src/windows/mod.rs
@@ -49,8 +49,8 @@ pub type dev_t = u32;
 pub type ino_t = u16;
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum timezone {}
-impl ::dox::Copy for timezone {}
-impl ::dox::Clone for timezone {
+impl ::Copy for timezone {}
+impl ::Clone for timezone {
     fn clone(&self) -> timezone { *self }
 }
 pub type time64_t = i64;
@@ -208,14 +208,14 @@ extern {}
 
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum FILE {}
-impl ::dox::Copy for FILE {}
-impl ::dox::Clone for FILE {
+impl ::Copy for FILE {}
+impl ::Clone for FILE {
     fn clone(&self) -> FILE { *self }
 }
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum fpos_t {} // TODO: fill this out with a struct
-impl ::dox::Copy for fpos_t {}
-impl ::dox::Clone for fpos_t {
+impl ::Copy for fpos_t {}
+impl ::Clone for fpos_t {
     fn clone(&self) -> fpos_t { *self }
 }