aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Gu <guyu2876@gmail.com>2022-04-20 21:11:25 +0800
committerYixun Lan <dlan@gentoo.org>2022-04-20 21:22:29 +0800
commit07c4b52e96d933d680ba43f71849bae09abd41f2 (patch)
tree4188501340620bfdf521812e3aa910f741d9127d
parentwww-client/firefox: import ebuild from gentoo's official tree (diff)
downloadriscv-07c4b52e96d933d680ba43f71849bae09abd41f2.tar.gz
riscv-07c4b52e96d933d680ba43f71849bae09abd41f2.tar.bz2
riscv-07c4b52e96d933d680ba43f71849bae09abd41f2.zip
www-client/firefox: bump to 98.0.2
Compared to the original ebuild, a patch was added and the sandbox was disabled because too many failures with 'enable-sanbox' enabled This feature is temporarily not supported on riscv. Some logs like: /var/tmp/portage/www-client/firefox-98.0.2/work/firefox-98.0.2/security/sandbox/linux/reporter/SandboxReporter.cpp:35:4: error: #error "unrecognized architecture" 164:47.00 /var/tmp/portage/www-client/firefox-98.0.2/work/firefox-98.0.2/security/sandbox/chromium/sandbox/linux/system_headers/linux_signal.h:65:2: error: #error "Unsupported platform" 164:47.58 /var/tmp/portage/www-client/firefox-98.0.2/work/firefox-98.0.2/security/sandbox/chromium/sandbox/linux/bpf_dsl/seccomp_macros.h:350:2: error: #error Unsupported target platform Closes: https://github.com/gentoo/riscv/pull/3 Signed-off-by: Yu Gu <guyu2876@gmail.com> Signed-off-by: Yixun Lan <dlan@gentoo.org>
-rw-r--r--www-client/firefox/files/makotokato-riscv64-support-and-zenithal-backported.patch47126
-rw-r--r--www-client/firefox/firefox-98.0.2.ebuild4
2 files changed, 47129 insertions, 1 deletions
diff --git a/www-client/firefox/files/makotokato-riscv64-support-and-zenithal-backported.patch b/www-client/firefox/files/makotokato-riscv64-support-and-zenithal-backported.patch
new file mode 100644
index 0000000..39ebd6a
--- /dev/null
+++ b/www-client/firefox/files/makotokato-riscv64-support-and-zenithal-backported.patch
@@ -0,0 +1,47126 @@
+From: Zenithal <i@zenithal.me>
+
+Some changes would be rejected/ignored when patching firefox 92 src,
+so I commented out some blocks, see these #-leading block below
+
+From be9cbd86b4c121dbdb626f8c373fd809f25bc23e Mon Sep 17 00:00:00 2001
+From: Makoto Kato <m_kato@ga2.so-net.ne.jp>
+Date: Sun, 13 Jun 2021 04:06:39 +0000
+Subject: [PATCH] Update authenticator-rs
+
+---
+ .cargo/config.in | 5 +
+ Cargo.lock | 3 +-
+ .../rust/authenticator/.cargo-checksum.json | 2 +-
+ third_party/rust/authenticator/.clippy.toml | 2 +
+ third_party/rust/authenticator/.flake8 | 4 +
+ .../authenticator/.pre-commit-config.yaml | 42 +
+ third_party/rust/authenticator/.travis.yml | 42 +
+ third_party/rust/authenticator/Cargo.lock | 1603 -----------------
+ third_party/rust/authenticator/Cargo.toml | 131 +-
+ third_party/rust/authenticator/build.rs | 2 +
+ .../authenticator/src/linux/hidwrapper.rs | 3 +
+ .../authenticator/src/linux/ioctl_riscv64.rs | 5 +
+ toolkit/library/rust/shared/Cargo.toml | 2 +-
+ 13 files changed, 154 insertions(+), 1692 deletions(-)
+ create mode 100644 third_party/rust/authenticator/.clippy.toml
+ create mode 100644 third_party/rust/authenticator/.flake8
+ create mode 100644 third_party/rust/authenticator/.pre-commit-config.yaml
+ create mode 100644 third_party/rust/authenticator/.travis.yml
+ delete mode 100644 third_party/rust/authenticator/Cargo.lock
+ create mode 100644 third_party/rust/authenticator/src/linux/ioctl_riscv64.rs
+
+diff --unified --recursive --text a/.cargo/config.in b/.cargo/config.in
+--- a/.cargo/config.in 2022-03-10 14:19:43.020478706 +0800
++++ b/.cargo/config.in 2022-03-10 14:21:21.873044017 +0800
+@@ -22,11 +22,6 @@
+ replace-with = "vendored-sources"
+ rev = "3bfc47d9a571d0842676043ba60716318e946c06"
+
+-[source."https://github.com/mozilla/midir.git"]
+-git = "https://github.com/mozilla/midir.git"
+-replace-with = "vendored-sources"
+-rev = "4c11f0ffb5d6a10de4aff40a7b81218b33b94e6f"
+-
+ [source."https://github.com/mozilla/l10nregistry-rs.git"]
+ git = "https://github.com/mozilla/l10nregistry-rs.git"
+ replace-with = "vendored-sources"
+@@ -57,6 +52,16 @@
+ replace-with = "vendored-sources"
+ rev = "a1a6ba41f0c610ebe751639f25f037474ca52941"
+
++[source."https://github.com/makotokato/midir.git"]
++git = "https://github.com/makotokato/midir.git"
++replace-with = "vendored-sources"
++rev = "6140b2825dd4dc2b40e49e154ca7596e7b9a131a"
++
++[source."https://github.com/makotokato/authenticator-rs"]
++git = "https://github.com/makotokato/authenticator-rs"
++replace-with = "vendored-sources"
++rev = "eed8919d50559f4959e2d7d2af7b4d48869b5366"
++
+ [source."https://github.com/kinetiknz/mio-named-pipes"]
+ git = "https://github.com/kinetiknz/mio-named-pipes"
+ replace-with = "vendored-sources"
+diff --git a/Cargo.lock b/Cargo.lock
+index 7e17939fad48b..8519d3d0e95a6 100644
+--- a/Cargo.lock
++++ b/Cargo.lock
+@@ -316,8 +316,7 @@ dependencies = [
+ [[package]]
+ name = "authenticator"
+ version = "0.3.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "08cee7a0952628fde958e149507c2bb321ab4fccfafd225da0b20adc956ef88a"
++source = "git+https://github.com/makotokato/authenticator-rs?rev=eed8919d50559f4959e2d7d2af7b4d48869b5366#eed8919d50559f4959e2d7d2af7b4d48869b5366"
+ dependencies = [
+ "bitflags",
+ "core-foundation",
+diff --git a/third_party/rust/authenticator/.cargo-checksum.json b/third_party/rust/authenticator/.cargo-checksum.json
+index ce451ad09df4f..9791345c9de54 100644
+--- a/third_party/rust/authenticator/.cargo-checksum.json
++++ b/third_party/rust/authenticator/.cargo-checksum.json
+@@ -1 +1 @@
+-{"files":{"Cargo.lock":"abaed4932db2206e5fdb7cb73a8c100f6c91fc84a8f33e8763677040ae8ea9bf","Cargo.toml":"9b56d5495021e7cd8ab7e019cceda45e906a2a3629a68e9019c6e5cb682dbc43","Cross.toml":"8d132da818d48492aa9f4b78a348f0df3adfae45d988d42ebd6be8a5adadb6c3","LICENSE":"e866c8f5864d4cacfe403820e722e9dc03fe3c7565efa5e4dad9051d827bb92a","README.md":"c87d9c7cc44f1dd4ef861a3a9f8cd2eb68aedd3814768871f5fb63c2070806cd","build.rs":"bc308b771ae9741d775370e3efe45e9cca166fd1d0335f4214b00497042ccc55","examples/main.rs":"d899646fa396776d0bb66efb86099ffb195566ecdb6fc4c1765ae3d54d696a8d","rustfmt.toml":"ceb6615363d6fff16426eb56f5727f98a7f7ed459ba9af735b1d8b672e2c3b9b","src/authenticatorservice.rs":"9fc5bcdd1e4f32e58ae920f96f40619a870b0a1b8d05db650803b2402a37fbf9","src/capi.rs":"1d3145ce81293bec697b0d385357fb1b0b495b0c356e2da5e6f15d028d328c70","src/consts.rs":"3dbcdfced6241822062e1aa2e6c8628af5f539ea18ee41edab51a3d33ebb77c6","src/errors.rs":"de89e57435ed1f9ff10f1f2d997a5b29d61cb215551e0ab40861a08ca52d1447","src/freebsd/device.rs":"595df4b3f66b90dd73f8df67e1a2ba9a20c0b5fd893afbadbec564aa34f89981","src/freebsd/mod.rs":"42dcb57fbeb00140003a8ad39acac9b547062b8f281a3fa5deb5f92a6169dde6","src/freebsd/monitor.rs":"c10b154632fbedc3dca27197f7fc890c3d50ac1744b927e9f1e44a9e8a13506e","src/freebsd/transaction.rs":"bfb92dcf2edeb5d620a019907fff1025eb36ef322055e78649a3055b074fa851","src/freebsd/uhid.rs":"84f564d337637c1cd107ccc536b8fce2230628e144e4031e8db4d7163c9c0cb3","src/hidproto.rs":"362fc8e24b94ba431aad5ee0002f5a3364badd937c706c0ae119a5a7a2abc7c2","src/lib.rs":"12f62285a3d33347f95236b71341462a76ea1ded67651fc96ba25d7bd1dd8298","src/linux/device.rs":"d27c5f877cf96b97668579ac5db0f2685f7c969e7a5d0ddc68043eb16bfcddb8","src/linux/hidraw.rs":"ed55caa40fd518d67bb67d5af08f9adcab34f89e0ca591142d45b87f172926dd","src/linux/hidwrapper.h":"72785db3a9b27ea72b6cf13a958fee032af54304522d002f56322473978a20f9","src/linux/hidwrapper.rs":"4be65676cf3220929700bf4906938dcbd1538ba53d40c60b08f9ba8890c910f6","src/linux/ioctl_aarch64le.rs":"2d8b265cd39a9f46816f83d5a5df0701c13eb842bc609325bad42ce50add3bf0","src/linux/ioctl_armle.rs":"2d8b265cd39a9f46816f83d5a5df0701c13eb842bc609325bad42ce50add3bf0","src/linux/ioctl_mips64le.rs":"fbda309934ad8bda689cd4fb5c0ca696fe26dedb493fe9d5a5322c3047d474fd","src/linux/ioctl_mipsbe.rs":"fbda309934ad8bda689cd4fb5c0ca696fe26dedb493fe9d5a5322c3047d474fd","src/linux/ioctl_mipsle.rs":"fbda309934ad8bda689cd4fb5c0ca696fe26dedb493fe9d5a5322c3047d474fd","src/linux/ioctl_powerpc64be.rs":"fbda309934ad8bda689cd4fb5c0ca696fe26dedb493fe9d5a5322c3047d474fd","src/linux/ioctl_powerpc64le.rs":"fbda309934ad8bda689cd4fb5c0ca696fe26dedb493fe9d5a5322c3047d474fd","src/linux/ioctl_powerpcbe.rs":"fbda309934ad8bda689cd4fb5c0ca696fe26dedb493fe9d5a5322c3047d474fd","src/linux/ioctl_s390xbe.rs":"2d8b265cd39a9f46816f83d5a5df0701c13eb842bc609325bad42ce50add3bf0","src/linux/ioctl_x86.rs":"2d8b265cd39a9f46816f83d5a5df0701c13eb842bc609325bad42ce50add3bf0","src/linux/ioctl_x86_64.rs":"2d8b265cd39a9f46816f83d5a5df0701c13eb842bc609325bad42ce50add3bf0","src/linux/mod.rs":"446e435126d2a58f167f648dd95cba28e8ac9c17f1f799e1eaeab80ea800fc57","src/linux/monitor.rs":"9ef4e22fdcf005dd5201b42595d958ea462998c75dbfc68c8a403e7be64328e4","src/linux/transaction.rs":"bfb92dcf2edeb5d620a019907fff1025eb36ef322055e78649a3055b074fa851","src/macos/device.rs":"cc97b773254a89526164987e4b8e4181910fc3decb32acf51ca86c596ad0147b","src/macos/iokit.rs":"7dc4e7bbf8e42e2fcde0cee8e48d14d6234a5a910bd5d3c4e966d8ba6b73992f","src/macos/mod.rs":"333e561554fc901d4f6092f6e4c85823e2b0c4ff31c9188d0e6d542b71a0a07c","src/macos/monitor.rs":"d059861b4739c9272fa305b6dd91ebeb08530bd0e70a013dd999565d6f06fb30","src/macos/transaction.rs":"935b4bc79b0e50a984604a1ada96a7ef723cc283b7d33ca07f3150b1752b99f7","src/manager.rs":"5a4cdc26b9fde20e1a3dc2389f15d38d9153109bfee5119c092fbfdbd19bad8d","src/netbsd/device.rs":"3a99a989a7a8411ddb9893c371644076662a3b488d40b436601c27fd92fdf159","src/netbsd/fd.rs":"260f1a8ae04896c0eb35ab0914e11ca9291e7317a086c94328aa219c0e1fc1d2","src/netbsd/mod.rs":"b1c52aa29537330cebe67427062d6c94871cab2a9b0c04b2305d686f07e88fd5","src/netbsd/monitor.rs":"dfd68e026c52271b68a3a9263837c793127e9d54ed19b748ef6d13ab4c44e09a","src/netbsd/transaction.rs":"9334a832a57e717a981c13c364ed4ee80ce9798460fc6c8954723d2fcf20585a","src/netbsd/uhid.rs":"154a4587767f151e3f846cc0b79f615d5137de67afed84f19176f27ac9097908","src/openbsd/device.rs":"ae1c8de90bb515a12d571372a30322fadb5122bc69ab71caf154452caa8a644f","src/openbsd/mod.rs":"514274d414042ff84b3667a41a736e78581e22fda87ccc97c2bc05617e381a30","src/openbsd/monitor.rs":"5eb071dd3719ea305eac21ec20596463f63790f8cd1f908a59e3f9cb0b71b5ad","src/openbsd/transaction.rs":"2380c9430f4c95a1fefaaab729d8ece0d149674708d705a71dd5d2513d9e1a4c","src/statecallback.rs":"6b16f97176db1ae3fc3851fe8394e4ffc324bc6fe59313845ac3a88132fd52f1","src/statemachine.rs":"27e2655411ebc1077c200f0aa2ba429ca656fc7dd6f90e08b51492b59ec72e61","src/stub/device.rs":"5e378147e113e20160a45d395b717bd3deecb327247c24b6735035f7d50861b7","src/stub/mod.rs":"6a7fec504a52d403b0241b18cd8b95088a31807571f4c0a67e4055afc74f4453","src/stub/transaction.rs":"4a2ccb2d72070a8bc61442254e063278c68212d5565ba5bfe4d47cacebf5bd1c","src/u2fhid-capi.h":"10f2658df774bb7f7f197a9f217b9e20d67b232b60a554e8ee3c3f71480ea1f6","src/u2fprotocol.rs":"72120773a948ffd667b5976c26ae27a4327769d97b0eef7a3b1e6b2b4bbb46a9","src/u2ftypes.rs":"a02d2c29790c5edfec9af320b1d4bcb93be0bbf02b881fa5aa403cfb687a25ae","src/util.rs":"d2042b2db4864f2b1192606c3251709361de7fb7521e1519190ef26a77de8e64","src/virtualdevices/mod.rs":"2c7df7691d5c150757304241351612aed4260d65b70ab0f483edbc1a5cfb5674","src/virtualdevices/software_u2f.rs":"1b86b94c6eadec6a22dffdd2b003c5324247c6412eeddb28a6094feb1c523f8e","src/virtualdevices/webdriver/mod.rs":"4a36e6dfa9f45f941d863b4039bfbcfa8eaca660bd6ed78aeb1a2962db64be5a","src/virtualdevices/webdriver/testtoken.rs":"7146e02f1a5dad2c8827dd11c12ee408c0e42a0706ac65f139998feffd42570f","src/virtualdevices/webdriver/virtualmanager.rs":"a55a28995c81b5affb0a74207b6dd556d272086a554676df2e675fe991d730a9","src/virtualdevices/webdriver/web_api.rs":"27206ee09c83fe25b34cad62174e42383defd8c8a5e917d30691412aacdae08f","src/windows/device.rs":"bc3f9587677c185a624c0aae7537baf9f780484ab8337929db994800b9064ba9","src/windows/mod.rs":"218e7f2fe91ecb390c12bba5a5ffdad2c1f0b22861c937f4d386262e5b3dd617","src/windows/monitor.rs":"3804dc67de46a1a6b7925c83e0df95d94ddfa1aa53a88fc845f4ff26aede57f8","src/windows/transaction.rs":"ee639f28b2dcdb7e00c922d8762fe6aa33def8c7aaeb46ec93e3a772407a9d86","src/windows/winapi.rs":"de92afb17df26216161138f18eb3b9162f3fb2cdeb74aa78173afe804ba02e00","testing/cross/powerpc64le-unknown-linux-gnu.Dockerfile":"d7463ff4376e3e0ca3fed879fab4aa975c4c0a3e7924c5b88aef9381a5d013de","testing/cross/x86_64-unknown-linux-gnu.Dockerfile":"11c79c04b07a171b0c9b63ef75fa75f33263ce76e3c1eda0879a3e723ebd0c24","testing/run_cross.sh":"cc2a7e0359f210eba2e7121f81eb8ab0125cea6e0d0f2698177b0fe2ad0c33d8","webdriver-tools/requirements.txt":"8236aa3dedad886f213c9b778fec80b037212d30e640b458984110211d546005","webdriver-tools/webdriver-driver.py":"82327c26ba271d1689acc87b612ab8436cb5475f0a3c0dba7baa06e7f6f5e19c"},"package":"08cee7a0952628fde958e149507c2bb321ab4fccfafd225da0b20adc956ef88a"}
+\ No newline at end of file
++{"files":{".clippy.toml":"86011295a6e2cea043b8002238f9c96b39f17aa8241aa079f44bb6e71eb62421",".flake8":"04f55f4a3c02b50dfa568ce4f7c6a47a9374b6483256811f8be702d1382576cd",".pre-commit-config.yaml":"b7920a17d5a378c7702f9c39bf5156bb8c4ea15d8691217e0a5a8e8f571b4cf7",".travis.yml":"883be088379477e7fa6f3d06b1c8d59dc41da61b6c15d2675c62113341e7b2d5","Cargo.toml":"e7334212220a6d8ca01996888275cc0d11d098e36db1bf4c5b7429051897bf3f","Cross.toml":"8d132da818d48492aa9f4b78a348f0df3adfae45d988d42ebd6be8a5adadb6c3","LICENSE":"e866c8f5864d4cacfe403820e722e9dc03fe3c7565efa5e4dad9051d827bb92a","README.md":"c87d9c7cc44f1dd4ef861a3a9f8cd2eb68aedd3814768871f5fb63c2070806cd","build.rs":"a459ee1ace052f9692817b15c702cb6e5a6dac7c7dfe74fa075662dbcf808dbe","examples/main.rs":"d899646fa396776d0bb66efb86099ffb195566ecdb6fc4c1765ae3d54d696a8d","rustfmt.toml":"ceb6615363d6fff16426eb56f5727f98a7f7ed459ba9af735b1d8b672e2c3b9b","src/authenticatorservice.rs":"9fc5bcdd1e4f32e58ae920f96f40619a870b0a1b8d05db650803b2402a37fbf9","src/capi.rs":"1d3145ce81293bec697b0d385357fb1b0b495b0c356e2da5e6f15d028d328c70","src/consts.rs":"3dbcdfced6241822062e1aa2e6c8628af5f539ea18ee41edab51a3d33ebb77c6","src/errors.rs":"de89e57435ed1f9ff10f1f2d997a5b29d61cb215551e0ab40861a08ca52d1447","src/freebsd/device.rs":"595df4b3f66b90dd73f8df67e1a2ba9a20c0b5fd893afbadbec564aa34f89981","src/freebsd/mod.rs":"42dcb57fbeb00140003a8ad39acac9b547062b8f281a3fa5deb5f92a6169dde6","src/freebsd/monitor.rs":"c10b154632fbedc3dca27197f7fc890c3d50ac1744b927e9f1e44a9e8a13506e","src/freebsd/transaction.rs":"bfb92dcf2edeb5d620a019907fff1025eb36ef322055e78649a3055b074fa851","src/freebsd/uhid.rs":"84f564d337637c1cd107ccc536b8fce2230628e144e4031e8db4d7163c9c0cb3","src/hidproto.rs":"362fc8e24b94ba431aad5ee0002f5a3364badd937c706c0ae119a5a7a2abc7c2","src/lib.rs":"12f62285a3d33347f95236b71341462a76ea1ded67651fc96ba25d7bd1dd8298","src/linux/device.rs":"d27c5f877cf96b97668579ac5db0f2685f7c969e7a5d0ddc68043eb16bfcddb8","src/linux/hidraw.rs":"ed55caa40fd518d67bb67d5af08f9adcab34f89e0ca591142d45b87f172926dd","src/linux/hidwrapper.h":"72785db3a9b27ea72b6cf13a958fee032af54304522d002f56322473978a20f9","src/linux/hidwrapper.rs":"753c7459dbb73befdd186b6269ac33f7a4537b4c935928f50f2b2131756e787d","src/linux/ioctl_aarch64le.rs":"2d8b265cd39a9f46816f83d5a5df0701c13eb842bc609325bad42ce50add3bf0","src/linux/ioctl_armle.rs":"2d8b265cd39a9f46816f83d5a5df0701c13eb842bc609325bad42ce50add3bf0","src/linux/ioctl_mips64le.rs":"fbda309934ad8bda689cd4fb5c0ca696fe26dedb493fe9d5a5322c3047d474fd","src/linux/ioctl_mipsbe.rs":"fbda309934ad8bda689cd4fb5c0ca696fe26dedb493fe9d5a5322c3047d474fd","src/linux/ioctl_mipsle.rs":"fbda309934ad8bda689cd4fb5c0ca696fe26dedb493fe9d5a5322c3047d474fd","src/linux/ioctl_powerpc64be.rs":"fbda309934ad8bda689cd4fb5c0ca696fe26dedb493fe9d5a5322c3047d474fd","src/linux/ioctl_powerpc64le.rs":"fbda309934ad8bda689cd4fb5c0ca696fe26dedb493fe9d5a5322c3047d474fd","src/linux/ioctl_powerpcbe.rs":"fbda309934ad8bda689cd4fb5c0ca696fe26dedb493fe9d5a5322c3047d474fd","src/linux/ioctl_riscv64.rs":"2d8b265cd39a9f46816f83d5a5df0701c13eb842bc609325bad42ce50add3bf0","src/linux/ioctl_s390xbe.rs":"2d8b265cd39a9f46816f83d5a5df0701c13eb842bc609325bad42ce50add3bf0","src/linux/ioctl_x86.rs":"2d8b265cd39a9f46816f83d5a5df0701c13eb842bc609325bad42ce50add3bf0","src/linux/ioctl_x86_64.rs":"2d8b265cd39a9f46816f83d5a5df0701c13eb842bc609325bad42ce50add3bf0","src/linux/mod.rs":"446e435126d2a58f167f648dd95cba28e8ac9c17f1f799e1eaeab80ea800fc57","src/linux/monitor.rs":"9ef4e22fdcf005dd5201b42595d958ea462998c75dbfc68c8a403e7be64328e4","src/linux/transaction.rs":"bfb92dcf2edeb5d620a019907fff1025eb36ef322055e78649a3055b074fa851","src/macos/device.rs":"cc97b773254a89526164987e4b8e4181910fc3decb32acf51ca86c596ad0147b","src/macos/iokit.rs":"7dc4e7bbf8e42e2fcde0cee8e48d14d6234a5a910bd5d3c4e966d8ba6b73992f","src/macos/mod.rs":"333e561554fc901d4f6092f6e4c85823e2b0c4ff31c9188d0e6d542b71a0a07c","src/macos/monitor.rs":"d059861b4739c9272fa305b6dd91ebeb08530bd0e70a013dd999565d6f06fb30","src/macos/transaction.rs":"935b4bc79b0e50a984604a1ada96a7ef723cc283b7d33ca07f3150b1752b99f7","src/manager.rs":"5a4cdc26b9fde20e1a3dc2389f15d38d9153109bfee5119c092fbfdbd19bad8d","src/netbsd/device.rs":"3a99a989a7a8411ddb9893c371644076662a3b488d40b436601c27fd92fdf159","src/netbsd/fd.rs":"260f1a8ae04896c0eb35ab0914e11ca9291e7317a086c94328aa219c0e1fc1d2","src/netbsd/mod.rs":"b1c52aa29537330cebe67427062d6c94871cab2a9b0c04b2305d686f07e88fd5","src/netbsd/monitor.rs":"dfd68e026c52271b68a3a9263837c793127e9d54ed19b748ef6d13ab4c44e09a","src/netbsd/transaction.rs":"9334a832a57e717a981c13c364ed4ee80ce9798460fc6c8954723d2fcf20585a","src/netbsd/uhid.rs":"154a4587767f151e3f846cc0b79f615d5137de67afed84f19176f27ac9097908","src/openbsd/device.rs":"ae1c8de90bb515a12d571372a30322fadb5122bc69ab71caf154452caa8a644f","src/openbsd/mod.rs":"514274d414042ff84b3667a41a736e78581e22fda87ccc97c2bc05617e381a30","src/openbsd/monitor.rs":"5eb071dd3719ea305eac21ec20596463f63790f8cd1f908a59e3f9cb0b71b5ad","src/openbsd/transaction.rs":"2380c9430f4c95a1fefaaab729d8ece0d149674708d705a71dd5d2513d9e1a4c","src/statecallback.rs":"6b16f97176db1ae3fc3851fe8394e4ffc324bc6fe59313845ac3a88132fd52f1","src/statemachine.rs":"27e2655411ebc1077c200f0aa2ba429ca656fc7dd6f90e08b51492b59ec72e61","src/stub/device.rs":"5e378147e113e20160a45d395b717bd3deecb327247c24b6735035f7d50861b7","src/stub/mod.rs":"6a7fec504a52d403b0241b18cd8b95088a31807571f4c0a67e4055afc74f4453","src/stub/transaction.rs":"4a2ccb2d72070a8bc61442254e063278c68212d5565ba5bfe4d47cacebf5bd1c","src/u2fhid-capi.h":"10f2658df774bb7f7f197a9f217b9e20d67b232b60a554e8ee3c3f71480ea1f6","src/u2fprotocol.rs":"72120773a948ffd667b5976c26ae27a4327769d97b0eef7a3b1e6b2b4bbb46a9","src/u2ftypes.rs":"a02d2c29790c5edfec9af320b1d4bcb93be0bbf02b881fa5aa403cfb687a25ae","src/util.rs":"d2042b2db4864f2b1192606c3251709361de7fb7521e1519190ef26a77de8e64","src/virtualdevices/mod.rs":"2c7df7691d5c150757304241351612aed4260d65b70ab0f483edbc1a5cfb5674","src/virtualdevices/software_u2f.rs":"1b86b94c6eadec6a22dffdd2b003c5324247c6412eeddb28a6094feb1c523f8e","src/virtualdevices/webdriver/mod.rs":"4a36e6dfa9f45f941d863b4039bfbcfa8eaca660bd6ed78aeb1a2962db64be5a","src/virtualdevices/webdriver/testtoken.rs":"7146e02f1a5dad2c8827dd11c12ee408c0e42a0706ac65f139998feffd42570f","src/virtualdevices/webdriver/virtualmanager.rs":"a55a28995c81b5affb0a74207b6dd556d272086a554676df2e675fe991d730a9","src/virtualdevices/webdriver/web_api.rs":"27206ee09c83fe25b34cad62174e42383defd8c8a5e917d30691412aacdae08f","src/windows/device.rs":"bc3f9587677c185a624c0aae7537baf9f780484ab8337929db994800b9064ba9","src/windows/mod.rs":"218e7f2fe91ecb390c12bba5a5ffdad2c1f0b22861c937f4d386262e5b3dd617","src/windows/monitor.rs":"3804dc67de46a1a6b7925c83e0df95d94ddfa1aa53a88fc845f4ff26aede57f8","src/windows/transaction.rs":"ee639f28b2dcdb7e00c922d8762fe6aa33def8c7aaeb46ec93e3a772407a9d86","src/windows/winapi.rs":"de92afb17df26216161138f18eb3b9162f3fb2cdeb74aa78173afe804ba02e00","testing/cross/powerpc64le-unknown-linux-gnu.Dockerfile":"d7463ff4376e3e0ca3fed879fab4aa975c4c0a3e7924c5b88aef9381a5d013de","testing/cross/x86_64-unknown-linux-gnu.Dockerfile":"11c79c04b07a171b0c9b63ef75fa75f33263ce76e3c1eda0879a3e723ebd0c24","testing/run_cross.sh":"cc2a7e0359f210eba2e7121f81eb8ab0125cea6e0d0f2698177b0fe2ad0c33d8","webdriver-tools/requirements.txt":"8236aa3dedad886f213c9b778fec80b037212d30e640b458984110211d546005","webdriver-tools/webdriver-driver.py":"82327c26ba271d1689acc87b612ab8436cb5475f0a3c0dba7baa06e7f6f5e19c"},"package":null}
+\ No newline at end of file
+diff --git a/third_party/rust/authenticator/.clippy.toml b/third_party/rust/authenticator/.clippy.toml
+new file mode 100644
+index 0000000000000..844d0757e91f4
+--- /dev/null
++++ b/third_party/rust/authenticator/.clippy.toml
+@@ -0,0 +1,2 @@
++type-complexity-threshold = 384
++too-many-arguments-threshold = 8
+diff --git a/third_party/rust/authenticator/.flake8 b/third_party/rust/authenticator/.flake8
+new file mode 100644
+index 0000000000000..5a725c9b4ce65
+--- /dev/null
++++ b/third_party/rust/authenticator/.flake8
+@@ -0,0 +1,4 @@
++[flake8]
++# See http://pep8.readthedocs.io/en/latest/intro.html#configuration
++ignore = E121, E123, E126, E129, E133, E203, E226, E241, E242, E704, W503, E402, E741
++max-line-length = 99
+diff --git a/third_party/rust/authenticator/.pre-commit-config.yaml b/third_party/rust/authenticator/.pre-commit-config.yaml
+new file mode 100644
+index 0000000000000..e0ceb8ea5473c
+--- /dev/null
++++ b/third_party/rust/authenticator/.pre-commit-config.yaml
+@@ -0,0 +1,42 @@
++- repo: git://github.com/pre-commit/pre-commit-hooks
++ rev: HEAD
++ hooks:
++ - id: flake8
++ - id: check-ast
++ - id: detect-private-key
++ - id: detect-aws-credentials
++ - id: check-merge-conflict
++ - id: end-of-file-fixer
++ - id: requirements-txt-fixer
++ - id: trailing-whitespace
++- repo: local
++ hooks:
++ - id: rustfmt
++ name: Check rustfmt
++ language: system
++ entry: cargo fmt -- --check
++ pass_filenames: false
++ files: '.rs$'
++- repo: local
++ hooks:
++ - id: tests
++ name: Run tests
++ language: system
++ entry: cargo test --all-targets --all-features
++ pass_filenames: false
++ files: '.rs$'
++- repo: local
++ hooks:
++ - id: clippy
++ name: Check clippy
++ language: system
++ entry: cargo clippy --all-targets -- -A renamed_and_removed_lints -A clippy::new-ret-no-self -D warnings
++ pass_filenames: false
++ files: '.rs$'
++- repo: local
++ hooks:
++ - id: black
++ name: Check black
++ language: system
++ entry: black
++ files: '.py$'
+diff --git a/third_party/rust/authenticator/.travis.yml b/third_party/rust/authenticator/.travis.yml
+new file mode 100644
+index 0000000000000..70ea5c5581af2
+--- /dev/null
++++ b/third_party/rust/authenticator/.travis.yml
+@@ -0,0 +1,42 @@
++os:
++ - linux
++ - windows
++
++language: rust
++rust:
++ - stable
++ - nightly
++cache: cargo
++
++jobs:
++ allow_failures:
++ - rust: nightly
++
++addons:
++ apt:
++ packages:
++ - build-essential
++ - libudev-dev
++
++install:
++ - rustup component add rustfmt
++ - rustup component add clippy
++
++script:
++- |
++ if [ "$TRAVIS_RUST_VERSION" == "nightly" ] && [ "$TRAVIS_OS_NAME" == "linux" ] ; then
++ export ASAN_OPTIONS="detect_odr_violation=1:leak_check_at_exit=0:detect_leaks=0"
++ export RUSTFLAGS="-Z sanitizer=address"
++ fi
++- |
++ if [ "$TRAVIS_RUST_VERSION" == "stable" ] && [ "$TRAVIS_OS_NAME" == "linux" ] ; then
++ echo "Running rustfmt"
++ cargo fmt --all -- --check
++ echo "Running clippy"
++ cargo clippy --all-targets --all-features -- -A renamed_and_removed_lints -A clippy::new-ret-no-self -D warnings
++
++ rustup install nightly
++ cargo install cargo-fuzz
++ cargo +nightly fuzz build
++ fi
++- cargo test --all-targets --all-features
+diff --git a/third_party/rust/authenticator/Cargo.lock b/third_party/rust/authenticator/Cargo.lock
+deleted file mode 100644
+index 9f284b468deaa..0000000000000
+--- a/third_party/rust/authenticator/Cargo.lock
++++ /dev/null
+@@ -1,1603 +0,0 @@
+-# This file is automatically @generated by Cargo.
+-# It is not intended for manual editing.
+-[[package]]
+-name = "aho-corasick"
+-version = "0.7.13"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "ansi_term"
+-version = "0.11.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "assert_matches"
+-version = "1.3.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "atty"
+-version = "0.2.14"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "authenticator"
+-version = "0.3.1"
+-dependencies = [
+- "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "bindgen 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "devd-rs 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+- "libudev 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)",
+- "serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
+- "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
+- "warp 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "autocfg"
+-version = "0.1.7"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "autocfg"
+-version = "1.0.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "base64"
+-version = "0.10.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "base64"
+-version = "0.12.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "bindgen"
+-version = "0.51.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "cexpr 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+- "clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
+- "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
+- "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
+- "regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rustc-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "which 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "bitflags"
+-version = "1.2.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "block-buffer"
+-version = "0.7.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+- "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "block-buffer"
+-version = "0.9.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "generic-array 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "block-padding"
+-version = "0.1.5"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "buf_redux"
+-version = "0.8.4"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "byte-tools"
+-version = "0.3.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "byteorder"
+-version = "1.3.4"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "bytes"
+-version = "0.5.6"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "cc"
+-version = "1.0.58"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "cexpr"
+-version = "0.3.6"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "cfg-if"
+-version = "0.1.10"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "clang-sys"
+-version = "0.28.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+- "libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "clap"
+-version = "2.33.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
+- "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+- "vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "cloudabi"
+-version = "0.0.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "core-foundation"
+-version = "0.9.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "core-foundation-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "core-foundation-sys"
+-version = "0.8.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "cpuid-bool"
+-version = "0.1.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "devd-rs"
+-version = "0.3.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+- "nom 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "digest"
+-version = "0.8.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "digest"
+-version = "0.9.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "generic-array 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "dtoa"
+-version = "0.4.6"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "env_logger"
+-version = "0.6.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
+- "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
+- "regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+- "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "fake-simd"
+-version = "0.1.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "fnv"
+-version = "1.0.7"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "fuchsia-cprng"
+-version = "0.1.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "fuchsia-zircon"
+-version = "0.3.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "fuchsia-zircon-sys"
+-version = "0.3.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "futures"
+-version = "0.3.5"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "futures-channel 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures-io 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "futures-channel"
+-version = "0.3.5"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "futures-core"
+-version = "0.3.5"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "futures-io"
+-version = "0.3.5"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "futures-sink"
+-version = "0.3.5"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "futures-task"
+-version = "0.3.5"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "once_cell 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "futures-util"
+-version = "0.3.5"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "pin-project 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
+- "pin-utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "generic-array"
+-version = "0.12.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "generic-array"
+-version = "0.14.4"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "getopts"
+-version = "0.2.21"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "getrandom"
+-version = "0.1.14"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+- "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "glob"
+-version = "0.3.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "h2"
+-version = "0.2.6"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "indexmap 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tracing 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "hashbrown"
+-version = "0.9.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "headers"
+-version = "0.3.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "headers-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
+- "sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "time 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "headers-core"
+-version = "0.2.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "hermit-abi"
+-version = "0.1.15"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "http"
+-version = "0.2.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
+- "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "http-body"
+-version = "0.3.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "httparse"
+-version = "1.3.4"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "humantime"
+-version = "1.3.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "hyper"
+-version = "0.13.7"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures-channel 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "h2 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+- "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "pin-project 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
+- "socket2 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+- "time 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tracing 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
+- "want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "idna"
+-version = "0.2.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+- "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+- "unicode-normalization 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "indexmap"
+-version = "1.6.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "hashbrown 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "input_buffer"
+-version = "0.3.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "iovec"
+-version = "0.1.4"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "itoa"
+-version = "0.4.6"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "kernel32-sys"
+-version = "0.2.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+- "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "lazy_static"
+-version = "1.4.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "libc"
+-version = "0.2.73"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "libloading"
+-version = "0.5.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
+- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "libudev"
+-version = "0.2.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+- "libudev-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "libudev-sys"
+-version = "0.1.4"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+- "pkg-config 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "log"
+-version = "0.4.11"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "matches"
+-version = "0.1.8"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "memchr"
+-version = "2.3.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "mime"
+-version = "0.3.16"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "mime_guess"
+-version = "2.0.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
+- "unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "mio"
+-version = "0.6.22"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+- "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
+- "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "net2 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
+- "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "miow"
+-version = "0.2.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "net2 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
+- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+- "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "multipart"
+-version = "0.17.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "buf_redux 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
+- "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
+- "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
+- "mime_guess 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "twoway 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "net2"
+-version = "0.2.35"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "nom"
+-version = "4.2.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "nom"
+-version = "5.1.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "once_cell"
+-version = "1.4.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "opaque-debug"
+-version = "0.2.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "opaque-debug"
+-version = "0.3.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "peeking_take_while"
+-version = "0.1.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "percent-encoding"
+-version = "2.1.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "pin-project"
+-version = "0.4.23"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "pin-project-internal 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "pin-project-internal"
+-version = "0.4.23"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
+- "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
+- "syn 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "pin-project-lite"
+-version = "0.1.7"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "pin-utils"
+-version = "0.1.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "pkg-config"
+-version = "0.3.18"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "ppv-lite86"
+-version = "0.2.8"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "proc-macro2"
+-version = "1.0.19"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "quick-error"
+-version = "1.2.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "quote"
+-version = "1.0.7"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "rand"
+-version = "0.6.5"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "rand"
+-version = "0.7.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "rand_chacha"
+-version = "0.1.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "rand_chacha"
+-version = "0.2.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "ppv-lite86 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "rand_core"
+-version = "0.3.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "rand_core"
+-version = "0.4.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "rand_core"
+-version = "0.5.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "rand_hc"
+-version = "0.1.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "rand_hc"
+-version = "0.2.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "rand_isaac"
+-version = "0.1.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "rand_jitter"
+-version = "0.1.4"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "rand_os"
+-version = "0.1.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "rand_pcg"
+-version = "0.1.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "rand_xorshift"
+-version = "0.1.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "rdrand"
+-version = "0.4.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "redox_syscall"
+-version = "0.1.57"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "regex"
+-version = "1.3.9"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "aho-corasick 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
+- "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "regex-syntax 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
+- "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "regex-syntax"
+-version = "0.6.18"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "remove_dir_all"
+-version = "0.5.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "runloop"
+-version = "0.1.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "rustc-hash"
+-version = "1.1.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "ryu"
+-version = "1.0.5"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "safemem"
+-version = "0.3.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "scoped-tls"
+-version = "1.0.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "serde"
+-version = "1.0.116"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "serde_derive 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "serde_derive"
+-version = "1.0.116"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
+- "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
+- "syn 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "serde_json"
+-version = "1.0.57"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "serde_urlencoded"
+-version = "0.6.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "dtoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)",
+- "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "sha-1"
+-version = "0.8.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "sha-1"
+-version = "0.9.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "block-buffer 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+- "cpuid-bool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "opaque-debug 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "sha2"
+-version = "0.8.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "shlex"
+-version = "0.1.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "slab"
+-version = "0.4.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "socket2"
+-version = "0.3.15"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+- "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)",
+- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "strsim"
+-version = "0.8.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "syn"
+-version = "1.0.41"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
+- "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
+- "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "tempfile"
+-version = "3.1.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)",
+- "remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "termcolor"
+-version = "1.1.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "textwrap"
+-version = "0.11.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "thread_local"
+-version = "1.0.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "time"
+-version = "0.1.44"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+- "wasi 0.10.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "tinyvec"
+-version = "0.3.4"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "tokio"
+-version = "0.2.22"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)",
+- "pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+- "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "tokio-macros"
+-version = "0.2.5"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
+- "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
+- "syn 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "tokio-tungstenite"
+-version = "0.11.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
+- "pin-project 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tungstenite 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "tokio-util"
+-version = "0.3.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
+- "pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "tower-service"
+-version = "0.3.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "tracing"
+-version = "0.1.19"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tracing-core 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "tracing-core"
+-version = "0.1.16"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "tracing-futures"
+-version = "0.2.4"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "pin-project 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tracing 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "try-lock"
+-version = "0.2.3"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "tungstenite"
+-version = "0.11.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+- "input_buffer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
+- "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "sha-1 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "utf-8 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "twoway"
+-version = "0.1.8"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "typenum"
+-version = "1.12.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "unicase"
+-version = "2.6.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "unicode-bidi"
+-version = "0.3.4"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "unicode-normalization"
+-version = "0.1.13"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "tinyvec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "unicode-width"
+-version = "0.1.8"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "unicode-xid"
+-version = "0.2.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "url"
+-version = "2.1.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+- "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "urlencoding"
+-version = "1.1.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "utf-8"
+-version = "0.7.5"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "vec_map"
+-version = "0.8.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "version_check"
+-version = "0.1.5"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "version_check"
+-version = "0.9.2"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "want"
+-version = "0.3.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
+- "try-lock 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "warp"
+-version = "0.2.5"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+- "futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+- "headers 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+- "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "hyper 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)",
+- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
+- "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
+- "mime_guess 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+- "multipart 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "pin-project 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
+- "scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)",
+- "serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
+- "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tokio-tungstenite 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tracing 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
+- "tracing-futures 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
+- "urlencoding 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "wasi"
+-version = "0.9.0+wasi-snapshot-preview1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "wasi"
+-version = "0.10.0+wasi-snapshot-preview1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "which"
+-version = "3.1.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "winapi"
+-version = "0.2.8"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "winapi"
+-version = "0.3.9"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+- "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "winapi-build"
+-version = "0.1.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "winapi-i686-pc-windows-gnu"
+-version = "0.4.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "winapi-util"
+-version = "0.1.5"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[[package]]
+-name = "winapi-x86_64-pc-windows-gnu"
+-version = "0.4.0"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-
+-[[package]]
+-name = "ws2_32-sys"
+-version = "0.2.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-dependencies = [
+- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+- "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+-]
+-
+-[metadata]
+-"checksum aho-corasick 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)" = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86"
+-"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
+-"checksum assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7deb0a829ca7bcfaf5da70b073a8d128619259a7be8216a355e23f00763059e5"
+-"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+-"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
+-"checksum autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
+-"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
+-"checksum base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
+-"checksum bindgen 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ebd71393f1ec0509b553aa012b9b58e81dadbdff7130bd3b8cba576e69b32f75"
+-"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+-"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
+-"checksum block-buffer 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
+-"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
+-"checksum buf_redux 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f"
+-"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
+-"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
+-"checksum bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
+-"checksum cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)" = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518"
+-"checksum cexpr 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d"
+-"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+-"checksum clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853"
+-"checksum clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129"
+-"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
+-"checksum core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b5ed8e7e76c45974e15e41bfa8d5b0483cd90191639e01d8f5f1e606299d3fb"
+-"checksum core-foundation-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9a21fa21941700a3cd8fcb4091f361a6a712fac632f85d9f487cc892045d55c6"
+-"checksum cpuid-bool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
+-"checksum devd-rs 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1945ccb7caedabdfb9347766ead740fb1e0582b7425598325f546adbd832cce1"
+-"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
+-"checksum digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+-"checksum dtoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
+-"checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3"
+-"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
+-"checksum fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+-"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
+-"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
+-"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
+-"checksum futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613"
+-"checksum futures-channel 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5"
+-"checksum futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399"
+-"checksum futures-io 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
+-"checksum futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc"
+-"checksum futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626"
+-"checksum futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"
+-"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
+-"checksum generic-array 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
+-"checksum getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
+-"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
+-"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
+-"checksum h2 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "993f9e0baeed60001cf565546b0d3dbe6a6ad23f2bd31644a133c641eccf6d53"
+-"checksum hashbrown 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "00d63df3d41950fb462ed38308eea019113ad1508da725bbedcd0fa5a85ef5f7"
+-"checksum headers 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ed18eb2459bf1a09ad2d6b1547840c3e5e62882fa09b9a6a20b1de8e3228848f"
+-"checksum headers-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
+-"checksum hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9"
+-"checksum http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9"
+-"checksum http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b"
+-"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
+-"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
+-"checksum hyper 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3e68a8dd9716185d9e64ea473ea6ef63529252e3e27623295a0378a19665d5eb"
+-"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
+-"checksum indexmap 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2"
+-"checksum input_buffer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "19a8a95243d5a0398cae618ec29477c6e3cb631152be5c19481f80bc71559754"
+-"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
+-"checksum itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
+-"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
+-"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+-"checksum libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)" = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9"
+-"checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
+-"checksum libudev 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea626d3bdf40a1c5aee3bcd4f40826970cae8d80a8fec934c82a63840094dcfe"
+-"checksum libudev-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324"
+-"checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
+-"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
+-"checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
+-"checksum mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
+-"checksum mime_guess 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212"
+-"checksum mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)" = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430"
+-"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
+-"checksum multipart 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8209c33c951f07387a8497841122fc6f712165e3f9bda3e6be4645b58188f676"
+-"checksum net2 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3ebc3ec692ed7c9a255596c67808dee269f64655d8baf7b4f0638e51ba1d6853"
+-"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
+-"checksum nom 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
+-"checksum once_cell 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad"
+-"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
+-"checksum opaque-debug 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+-"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
+-"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
+-"checksum pin-project 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)" = "ca4433fff2ae79342e497d9f8ee990d174071408f28f726d6d83af93e58e48aa"
+-"checksum pin-project-internal 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)" = "2c0e815c3ee9a031fdf5af21c10aa17c573c9c6a566328d99e3936c34e36461f"
+-"checksum pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715"
+-"checksum pin-utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+-"checksum pkg-config 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33"
+-"checksum ppv-lite86 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
+-"checksum proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12"
+-"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
+-"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
+-"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
+-"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
+-"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
+-"checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
+-"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
+-"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
+-"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+-"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
+-"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
+-"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
+-"checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
+-"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
+-"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
+-"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
+-"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
+-"checksum redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)" = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
+-"checksum regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
+-"checksum regex-syntax 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)" = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
+-"checksum remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
+-"checksum runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d79b4b604167921892e84afbbaad9d5ad74e091bf6c511d9dbfb0593f09fabd"
+-"checksum rustc-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+-"checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
+-"checksum safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
+-"checksum scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
+-"checksum serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)" = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5"
+-"checksum serde_derive 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)" = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8"
+-"checksum serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)" = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c"
+-"checksum serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"
+-"checksum sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
+-"checksum sha-1 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "170a36ea86c864a3f16dd2687712dd6646f7019f301e57537c7f4dc9f5916770"
+-"checksum sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
+-"checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
+-"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
+-"checksum socket2 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "b1fa70dc5c8104ec096f4fe7ede7a221d35ae13dcd19ba1ad9a81d2cab9a1c44"
+-"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
+-"checksum syn 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b"
+-"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
+-"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
+-"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
+-"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
+-"checksum time 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
+-"checksum tinyvec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117"
+-"checksum tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd"
+-"checksum tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389"
+-"checksum tokio-tungstenite 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d9e878ad426ca286e4dcae09cbd4e1973a7f8987d97570e2469703dd7f5720c"
+-"checksum tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499"
+-"checksum tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860"
+-"checksum tracing 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6d79ca061b032d6ce30c660fded31189ca0b9922bf483cd70759f13a2d86786c"
+-"checksum tracing-core 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5bcf46c1f1f06aeea2d6b81f3c863d0930a596c86ad1920d4e5bad6dd1d7119a"
+-"checksum tracing-futures 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c"
+-"checksum try-lock 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
+-"checksum tungstenite 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f0308d80d86700c5878b9ef6321f020f29b1bb9d5ff3cab25e75e23f3a492a23"
+-"checksum twoway 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1"
+-"checksum typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
+-"checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
+-"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
+-"checksum unicode-normalization 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977"
+-"checksum unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
+-"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
+-"checksum url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb"
+-"checksum urlencoding 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c9232eb53352b4442e40d7900465dfc534e8cb2dc8f18656fcb2ac16112b5593"
+-"checksum utf-8 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7"
+-"checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
+-"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
+-"checksum version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
+-"checksum want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
+-"checksum warp 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f41be6df54c97904af01aa23e613d4521eed7ab23537cede692d4058f6449407"
+-"checksum wasi 0.10.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
+-"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
+-"checksum which 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
+-"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
+-"checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+-"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
+-"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+-"checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+-"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+-"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
+diff --git a/third_party/rust/authenticator/Cargo.toml b/third_party/rust/authenticator/Cargo.toml
+index 57d24bd66b948..c49befae2178c 100644
+--- a/third_party/rust/authenticator/Cargo.toml
++++ b/third_party/rust/authenticator/Cargo.toml
+@@ -1,99 +1,60 @@
+-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+-#
+-# When uploading crates to the registry Cargo will automatically
+-# "normalize" Cargo.toml files for maximal compatibility
+-# with all versions of Cargo and also rewrite `path` dependencies
+-# to registry (e.g., crates.io) dependencies
+-#
+-# If you believe there's an error in this file please file an
+-# issue against the rust-lang/cargo repository. If you're
+-# editing this file be aware that the upstream Cargo.toml
+-# will likely look very different (and much more reasonable)
+-
+ [package]
+-edition = "2018"
+ name = "authenticator"
+ version = "0.3.1"
+ authors = ["J.C. Jones <jc@mozilla.com>", "Tim Taubert <ttaubert@mozilla.com>", "Kyle Machulis <kyle@nonpolynomial.com>"]
+-description = "Library for interacting with CTAP1/2 security keys for Web Authentication. Used by Firefox."
+ keywords = ["ctap2", "u2f", "fido", "webauthn"]
+ categories = ["cryptography", "hardware-support", "os"]
+-license = "MPL-2.0"
+ repository = "https://github.com/mozilla/authenticator-rs/"
+-[dependencies.base64]
+-version = "^0.10"
+-optional = true
+-
+-[dependencies.bitflags]
+-version = "1.0"
+-
+-[dependencies.bytes]
+-version = "0.5"
+-features = ["serde"]
+-optional = true
+-
+-[dependencies.libc]
+-version = "0.2"
+-
+-[dependencies.log]
+-version = "0.4"
+-
+-[dependencies.rand]
+-version = "0.7"
+-
+-[dependencies.runloop]
+-version = "0.1.0"
+-
+-[dependencies.serde]
+-version = "1.0"
+-features = ["derive"]
+-optional = true
+-
+-[dependencies.serde_json]
+-version = "1.0"
+-optional = true
+-
+-[dependencies.tokio]
+-version = "0.2"
+-features = ["macros"]
+-optional = true
++license = "MPL-2.0"
++description = "Library for interacting with CTAP1/2 security keys for Web Authentication. Used by Firefox."
++edition = "2018"
+
+-[dependencies.warp]
+-version = "0.2.4"
+-optional = true
+-[dev-dependencies.assert_matches]
+-version = "1.2"
++[badges]
++travis-ci = { repository = "mozilla/authenticator-rs", branch = "master" }
++maintenance = { status = "actively-developed" }
+
+-[dev-dependencies.base64]
+-version = "^0.10"
++[features]
++binding-recompile = ["bindgen"]
++webdriver = ["base64", "bytes", "warp", "tokio", "serde", "serde_json"]
+
+-[dev-dependencies.env_logger]
+-version = "^0.6"
++[target.'cfg(target_os = "linux")'.dependencies]
++libudev = "^0.2"
+
+-[dev-dependencies.getopts]
+-version = "^0.2"
++[target.'cfg(target_os = "freebsd")'.dependencies]
++devd-rs = "0.3"
+
+-[dev-dependencies.sha2]
+-version = "^0.8.2"
+-[build-dependencies.bindgen]
+-version = "^0.51"
+-optional = true
++[target.'cfg(target_os = "macos")'.dependencies]
++core-foundation = "0.9"
+
+-[features]
+-binding-recompile = ["bindgen"]
+-webdriver = ["base64", "bytes", "warp", "tokio", "serde", "serde_json"]
+-[target."cfg(target_os = \"freebsd\")".dependencies.devd-rs]
+-version = "0.3"
+-[target."cfg(target_os = \"linux\")".dependencies.libudev]
+-version = "^0.2"
+-[target."cfg(target_os = \"macos\")".dependencies.core-foundation]
+-version = "0.9"
+-[target."cfg(target_os = \"windows\")".dependencies.winapi]
++[target.'cfg(target_os = "windows")'.dependencies.winapi]
+ version = "^0.3"
+-features = ["handleapi", "hidclass", "hidpi", "hidusage", "setupapi"]
+-[badges.maintenance]
+-status = "actively-developed"
+-
+-[badges.travis-ci]
+-branch = "master"
+-repository = "mozilla/authenticator-rs"
++features = [
++ "handleapi",
++ "hidclass",
++ "hidpi",
++ "hidusage",
++ "setupapi",
++]
++
++[build-dependencies]
++bindgen = { version = "^0.58.1", optional = true }
++
++[dependencies]
++rand = "0.7"
++log = "0.4"
++libc = "0.2"
++runloop = "0.1.0"
++bitflags = "1.0"
++tokio = { version = "0.2", optional = true, features = ["macros"] }
++warp = { version = "0.2.4", optional = true }
++serde = { version = "1.0", optional = true, features = ["derive"] }
++serde_json = { version = "1.0", optional = true }
++bytes = { version = "0.5", optional = true, features = ["serde"] }
++base64 = { version = "^0.10", optional = true }
++
++[dev-dependencies]
++sha2 = "^0.8.2"
++base64 = "^0.10"
++env_logger = "^0.6"
++getopts = "^0.2"
++assert_matches = "1.2"
+diff --git a/third_party/rust/authenticator/build.rs b/third_party/rust/authenticator/build.rs
+index 299e4df6d7331..c972d85b898ea 100644
+--- a/third_party/rust/authenticator/build.rs
++++ b/third_party/rust/authenticator/build.rs
+@@ -45,6 +45,8 @@ fn main() {
+ "ioctl_aarch64be.rs"
+ } else if cfg!(all(target_arch = "s390x", target_endian = "big")) {
+ "ioctl_s390xbe.rs"
++ } else if cfg!(all(target_arch = "riscv64", target_endian = "little")) {
++ "ioctl_riscv64.rs"
+ } else {
+ panic!("architecture not supported");
+ };
+diff --git a/third_party/rust/authenticator/src/linux/hidwrapper.rs b/third_party/rust/authenticator/src/linux/hidwrapper.rs
+index ea1a39051b63a..82aabc6301017 100644
+--- a/third_party/rust/authenticator/src/linux/hidwrapper.rs
++++ b/third_party/rust/authenticator/src/linux/hidwrapper.rs
+@@ -46,3 +46,6 @@ include!("ioctl_aarch64be.rs");
+
+ #[cfg(all(target_arch = "s390x", target_endian = "big"))]
+ include!("ioctl_s390xbe.rs");
++
++#[cfg(all(target_arch = "riscv64", target_endian = "little"))]
++include!("ioctl_riscv64.rs");
+diff --git a/third_party/rust/authenticator/src/linux/ioctl_riscv64.rs b/third_party/rust/authenticator/src/linux/ioctl_riscv64.rs
+new file mode 100644
+index 0000000000000..a784e9bf4600b
+--- /dev/null
++++ b/third_party/rust/authenticator/src/linux/ioctl_riscv64.rs
+@@ -0,0 +1,5 @@
++/* automatically generated by rust-bindgen */
++
++pub type __u32 = ::std::os::raw::c_uint;
++pub const _HIDIOCGRDESCSIZE: __u32 = 2147764225;
++pub const _HIDIOCGRDESC: __u32 = 2416199682;
+--- a/toolkit/library/rust/shared/Cargo.toml 2022-02-10 20:41:52.387673027 +0800
++++ b/toolkit/library/rust/shared/Cargo.toml 2022-02-12 17:34:42.861720793 +0800
+@@ -24,7 +24,7 @@
+ cubeb-pulse = { git = "https://github.com/mozilla/cubeb-pulse-rs", rev="f2456201dbfdc467b80f0ff6bbb1b8a6faf7df02", optional = true, features=["pulse-dlopen"] }
+ cubeb-sys = { version = "0.9", optional = true, features=["gecko-in-tree"] }
+ encoding_glue = { path = "../../../../intl/encoding_glue" }
+-authenticator = "0.3.1"
++authenticator = { git = "https://github.com/makotokato/authenticator-rs", rev = "eed8919d50559f4959e2d7d2af7b4d48869b5366" }
+ gkrust_utils = { path = "../../../../xpcom/rust/gkrust_utils" }
+ gecko_logger = { path = "../../../../xpcom/rust/gecko_logger" }
+ rsdparsa_capi = { path = "../../../../dom/media/webrtc/sdp/rsdparsa_capi" }
+From a418c651c88cd2682c4cfe61e9f57b5389078c09 Mon Sep 17 00:00:00 2001
+From: Makoto Kato <m_kato@ga2.so-net.ne.jp>
+Date: Thu, 17 Jun 2021 21:50:49 +0900
+Subject: [PATCH] signal handler
+
+---
+ js/src/wasm/WasmSignalHandlers.cpp | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+--- a/js/src/wasm/WasmSignalHandlers.cpp 2022-02-12 19:29:33.566924464 +0800
++++ b/js/src/wasm/WasmSignalHandlers.cpp 2022-02-12 19:50:29.499985612 +0800
+@@ -156,6 +156,11 @@
+ # define R01_sig(p) ((p)->uc_mcontext.gp_regs[1])
+ # define R32_sig(p) ((p)->uc_mcontext.gp_regs[32])
+ # endif
++# if defined(__linux__) && defined(__riscv) && __riscv_xlen == 64
++# define EPC_sig(p) ((p)->uc_mcontext.__gregs[0])
++# define X02_sig(p) ((p)->uc_mcontext.__gregs[2])
++# define X08_sig(p) ((p)->uc_mcontext.__gregs[8])
++# endif
+ # elif defined(__NetBSD__)
+ # define EIP_sig(p) ((p)->uc_mcontext.__gregs[_REG_EIP])
+ # define EBP_sig(p) ((p)->uc_mcontext.__gregs[_REG_EBP])
+@@ -376,6 +381,10 @@
+ # define PC_sig(p) R32_sig(p)
+ # define SP_sig(p) R01_sig(p)
+ # define FP_sig(p) R01_sig(p)
++#elif defined(__riscv) && __riscv_xlen == 64
++# define PC_sig(p) EPC_sig(p)
++# define SP_sig(p) X02_sig(p)
++# define FP_sig(p) X08_sig(p)
+ # endif
+
+ static void SetContextPC(CONTEXT* context, uint8_t* pc) {
+From b6be52755af09f55e78d86bdd02a99efa0d16f9f Mon Sep 17 00:00:00 2001
+From: Makoto Kato <m_kato@ga2.so-net.ne.jp>
+Date: Fri, 28 Jan 2022 12:21:06 +0900
+Subject: [PATCH] mach vendor rust
+
+---
+ .cargo/config.in | 10 +-
+ Cargo.lock | 29 +-
+ Cargo.toml | 3 +-
+ .../mozbuild/mozbuild/vendor/vendor_rust.py | 1 +
+ third_party/rust/alsa/.cargo-checksum.json | 2 +-
+ third_party/rust/alsa/Cargo.toml | 8 +-
+ third_party/rust/alsa/src/direct/pcm.rs | 2 +-
+ third_party/rust/alsa/src/error.rs | 1 -
+ third_party/rust/alsa/src/lib.rs | 8 +-
+ third_party/rust/alsa/src/mixer.rs | 8 +
+ third_party/rust/alsa/src/pcm.rs | 78 +-
+ .../rust/bitflags/.cargo-checksum.json | 2 +-
+ third_party/rust/bitflags/CHANGELOG.md | 57 -
+ third_party/rust/bitflags/Cargo.toml | 34 +-
+ third_party/rust/bitflags/README.md | 12 +-
+ third_party/rust/bitflags/build.rs | 44 +
+ third_party/rust/bitflags/src/lib.rs | 873 ++----
+ third_party/rust/bitflags/tests/basic.rs | 20 -
+ .../bitflags/tests/compile-fail/impls/copy.rs | 10 -
+ .../tests/compile-fail/impls/copy.stderr.beta | 27 -
+ .../bitflags/tests/compile-fail/impls/eq.rs | 10 -
+ .../tests/compile-fail/impls/eq.stderr.beta | 55 -
+ .../non_integer_base/all_defined.rs | 123 -
+ .../non_integer_base/all_defined.stderr.beta | 27 -
+ .../non_integer_base/all_missing.rs | 13 -
+ .../non_integer_base/all_missing.stderr.beta | 13 -
+ .../compile-fail/visibility/private_field.rs | 13 -
+ .../visibility/private_field.stderr.beta | 10 -
+ .../compile-fail/visibility/private_flags.rs | 18 -
+ .../visibility/private_flags.stderr.beta | 18 -
+ .../compile-fail/visibility/pub_const.rs | 9 -
+ .../visibility/pub_const.stderr.beta | 5 -
+ .../tests/compile-pass/impls/convert.rs | 17 -
+ .../tests/compile-pass/impls/default.rs | 10 -
+ .../compile-pass/impls/inherent_methods.rs | 15 -
+ .../tests/compile-pass/redefinition/core.rs | 14 -
+ .../compile-pass/redefinition/stringify.rs | 19 -
+ .../bitflags/tests/compile-pass/repr/c.rs | 10 -
+ .../tests/compile-pass/repr/transparent.rs | 10 -
+ .../compile-pass/visibility/bits_field.rs | 11 -
+ .../tests/compile-pass/visibility/pub_in.rs | 19 -
+ third_party/rust/bitflags/tests/compile.rs | 63 -
+ third_party/rust/midir/.cargo-checksum.json | 2 +-
+ third_party/rust/midir/Cargo.toml | 4 +-
+ .../rust/nix-0.15.0/.cargo-checksum.json | 1 +
+ third_party/rust/nix-0.15.0/CHANGELOG.md | 742 +++++
+ third_party/rust/nix-0.15.0/CONTRIBUTING.md | 114 +
+ third_party/rust/nix-0.15.0/CONVENTIONS.md | 87 +
+ third_party/rust/nix-0.15.0/Cargo.toml | 71 +
+ third_party/rust/nix-0.15.0/LICENSE | 21 +
+ third_party/rust/nix-0.15.0/README.md | 111 +
+ third_party/rust/{nix => nix-0.15.0}/build.rs | 0
+ third_party/rust/nix-0.15.0/src/dir.rs | 193 ++
+ third_party/rust/nix-0.15.0/src/errno.rs | 1963 ++++++++++++++
+ .../{nix => nix-0.15.0}/src/errno_dragonfly.c | 0
+ third_party/rust/nix-0.15.0/src/fcntl.rs | 506 ++++
+ third_party/rust/nix-0.15.0/src/features.rs | 103 +
+ third_party/rust/nix-0.15.0/src/ifaddrs.rs | 146 +
+ third_party/rust/nix-0.15.0/src/kmod.rs | 123 +
+ third_party/rust/nix-0.15.0/src/lib.rs | 284 ++
+ third_party/rust/nix-0.15.0/src/macros.rs | 264 ++
+ third_party/rust/nix-0.15.0/src/mount.rs | 98 +
+ third_party/rust/nix-0.15.0/src/mqueue.rs | 162 ++
+ third_party/rust/nix-0.15.0/src/net/if_.rs | 268 ++
+ third_party/rust/nix-0.15.0/src/net/mod.rs | 4 +
+ third_party/rust/nix-0.15.0/src/poll.rs | 143 +
+ third_party/rust/nix-0.15.0/src/pty.rs | 326 +++
+ third_party/rust/nix-0.15.0/src/sched.rs | 147 +
+ third_party/rust/nix-0.15.0/src/sys/aio.rs | 1280 +++++++++
+ third_party/rust/nix-0.15.0/src/sys/epoll.rs | 109 +
+ third_party/rust/nix-0.15.0/src/sys/event.rs | 351 +++
+ .../rust/nix-0.15.0/src/sys/eventfd.rs | 18 +
+ .../rust/nix-0.15.0/src/sys/inotify.rs | 230 ++
+ .../rust/nix-0.15.0/src/sys/ioctl/bsd.rs | 102 +
+ .../rust/nix-0.15.0/src/sys/ioctl/linux.rs | 140 +
+ .../rust/nix-0.15.0/src/sys/ioctl/mod.rs | 778 ++++++
+ third_party/rust/nix-0.15.0/src/sys/memfd.rs | 20 +
+ third_party/rust/nix-0.15.0/src/sys/mman.rs | 325 +++
+ third_party/rust/nix-0.15.0/src/sys/mod.rs | 100 +
+ .../rust/nix-0.15.0/src/sys/pthread.rs | 13 +
+ .../rust/nix-0.15.0/src/sys/ptrace/bsd.rs | 170 ++
+ .../rust/nix-0.15.0/src/sys/ptrace/linux.rs | 402 +++
+ .../rust/nix-0.15.0/src/sys/ptrace/mod.rs | 22 +
+ third_party/rust/nix-0.15.0/src/sys/quota.rs | 273 ++
+ third_party/rust/nix-0.15.0/src/sys/reboot.rs | 45 +
+ third_party/rust/nix-0.15.0/src/sys/select.rs | 334 +++
+ .../rust/nix-0.15.0/src/sys/sendfile.rs | 200 ++
+ third_party/rust/nix-0.15.0/src/sys/signal.rs | 966 +++++++
+ .../rust/nix-0.15.0/src/sys/signalfd.rs | 170 ++
+ .../rust/nix-0.15.0/src/sys/socket/addr.rs | 1278 +++++++++
+ .../rust/nix-0.15.0/src/sys/socket/mod.rs | 1294 +++++++++
+ .../rust/nix-0.15.0/src/sys/socket/sockopt.rs | 680 +++++
+ third_party/rust/nix-0.15.0/src/sys/stat.rs | 294 ++
+ third_party/rust/nix-0.15.0/src/sys/statfs.rs | 548 ++++
+ .../rust/nix-0.15.0/src/sys/statvfs.rs | 160 ++
+ .../rust/nix-0.15.0/src/sys/sysinfo.rs | 72 +
+ .../rust/nix-0.15.0/src/sys/termios.rs | 1107 ++++++++
+ third_party/rust/nix-0.15.0/src/sys/time.rs | 542 ++++
+ third_party/rust/nix-0.15.0/src/sys/uio.rs | 194 ++
+ .../rust/nix-0.15.0/src/sys/utsname.rs | 67 +
+ third_party/rust/nix-0.15.0/src/sys/wait.rs | 239 ++
+ third_party/rust/nix-0.15.0/src/ucontext.rs | 39 +
+ third_party/rust/nix-0.15.0/src/unistd.rs | 2394 +++++++++++++++++
+ third_party/rust/nix-0.15.0/test/sys/mod.rs | 38 +
+ .../rust/nix-0.15.0/test/sys/test_aio.rs | 654 +++++
+ .../rust/nix-0.15.0/test/sys/test_aio_drop.rs | 32 +
+ .../rust/nix-0.15.0/test/sys/test_epoll.rs | 24 +
+ .../rust/nix-0.15.0/test/sys/test_inotify.rs | 65 +
+ .../rust/nix-0.15.0/test/sys/test_ioctl.rs | 334 +++
+ .../test/sys/test_lio_listio_resubmit.rs | 111 +
+ .../rust/nix-0.15.0/test/sys/test_pthread.rs | 15 +
+ .../rust/nix-0.15.0/test/sys/test_ptrace.rs | 107 +
+ .../rust/nix-0.15.0/test/sys/test_select.rs | 54 +
+ .../rust/nix-0.15.0/test/sys/test_signal.rs | 104 +
+ .../rust/nix-0.15.0/test/sys/test_signalfd.rs | 25 +
+ .../rust/nix-0.15.0/test/sys/test_socket.rs | 1066 ++++++++
+ .../rust/nix-0.15.0/test/sys/test_sockopt.rs | 53 +
+ .../rust/nix-0.15.0/test/sys/test_sysinfo.rs | 18 +
+ .../rust/nix-0.15.0/test/sys/test_termios.rs | 136 +
+ .../rust/nix-0.15.0/test/sys/test_uio.rs | 241 ++
+ .../rust/nix-0.15.0/test/sys/test_wait.rs | 104 +
+ third_party/rust/nix-0.15.0/test/test.rs | 149 +
+ third_party/rust/nix-0.15.0/test/test_dir.rs | 46 +
+ .../rust/nix-0.15.0/test/test_fcntl.rs | 234 ++
+ .../test/test_kmod/hello_mod/Makefile | 7 +
+ .../test/test_kmod/hello_mod/hello.c | 26 +
+ .../rust/nix-0.15.0/test/test_kmod/mod.rs | 166 ++
+ .../rust/nix-0.15.0/test/test_mount.rs | 238 ++
+ third_party/rust/nix-0.15.0/test/test_mq.rs | 152 ++
+ third_party/rust/nix-0.15.0/test/test_net.rs | 12 +
+ .../rust/nix-0.15.0/test/test_nix_path.rs | 0
+ third_party/rust/nix-0.15.0/test/test_poll.rs | 50 +
+ third_party/rust/nix-0.15.0/test/test_pty.rs | 235 ++
+ .../nix-0.15.0/test/test_ptymaster_drop.rs | 21 +
+ .../rust/nix-0.15.0/test/test_sendfile.rs | 129 +
+ third_party/rust/nix-0.15.0/test/test_stat.rs | 296 ++
+ .../rust/nix-0.15.0/test/test_unistd.rs | 669 +++++
+ third_party/rust/nix/.cargo-checksum.json | 2 +-
+ third_party/rust/nix/CHANGELOG.md | 306 ++-
+ third_party/rust/nix/CONTRIBUTING.md | 10 +-
+ third_party/rust/nix/CONVENTIONS.md | 9 +-
+ third_party/rust/nix/Cargo.toml | 40 +-
+ third_party/rust/nix/README.md | 22 +-
+ third_party/rust/nix/src/dir.rs | 99 +-
+ third_party/rust/nix/src/env.rs | 53 +
+ third_party/rust/nix/src/errno.rs | 480 +++-
+ third_party/rust/nix/src/fcntl.rs | 268 +-
+ third_party/rust/nix/src/features.rs | 7 +-
+ third_party/rust/nix/src/ifaddrs.rs | 29 +-
+ third_party/rust/nix/src/kmod.rs | 4 +-
+ third_party/rust/nix/src/lib.rs | 74 +-
+ third_party/rust/nix/src/macros.rs | 79 +-
+ third_party/rust/nix/src/mount.rs | 43 +-
+ third_party/rust/nix/src/mqueue.rs | 65 +-
+ third_party/rust/nix/src/net/if_.rs | 3 +-
+ third_party/rust/nix/src/poll.rs | 29 +-
+ third_party/rust/nix/src/pty.rs | 80 +-
+ third_party/rust/nix/src/sched.rs | 104 +-
+ third_party/rust/nix/src/sys/aio.rs | 44 +-
+ third_party/rust/nix/src/sys/epoll.rs | 8 +-
+ third_party/rust/nix/src/sys/event.rs | 45 +-
+ third_party/rust/nix/src/sys/eventfd.rs | 4 +-
+ third_party/rust/nix/src/sys/inotify.rs | 37 +-
+ third_party/rust/nix/src/sys/ioctl/bsd.rs | 4 +-
+ third_party/rust/nix/src/sys/ioctl/linux.rs | 3 +-
+ third_party/rust/nix/src/sys/ioctl/mod.rs | 12 +-
+ third_party/rust/nix/src/sys/memfd.rs | 4 +-
+ third_party/rust/nix/src/sys/mman.rs | 136 +-
+ third_party/rust/nix/src/sys/mod.rs | 10 +
+ third_party/rust/nix/src/sys/personality.rs | 70 +
+ third_party/rust/nix/src/sys/ptrace/bsd.rs | 25 +-
+ third_party/rust/nix/src/sys/ptrace/linux.rs | 164 +-
+ third_party/rust/nix/src/sys/quota.rs | 16 +-
+ third_party/rust/nix/src/sys/reboot.rs | 8 +-
+ third_party/rust/nix/src/sys/select.rs | 140 +-
+ third_party/rust/nix/src/sys/sendfile.rs | 11 +-
+ third_party/rust/nix/src/sys/signal.rs | 300 ++-
+ third_party/rust/nix/src/sys/signalfd.rs | 28 +-
+ third_party/rust/nix/src/sys/socket/addr.rs | 205 +-
+ third_party/rust/nix/src/sys/socket/mod.rs | 930 +++++--
+ .../rust/nix/src/sys/socket/sockopt.rs | 117 +-
+ third_party/rust/nix/src/sys/stat.rs | 39 +-
+ third_party/rust/nix/src/sys/statfs.rs | 216 +-
+ third_party/rust/nix/src/sys/statvfs.rs | 21 +-
+ third_party/rust/nix/src/sys/sysinfo.rs | 19 +-
+ third_party/rust/nix/src/sys/termios.rs | 217 +-
+ third_party/rust/nix/src/sys/time.rs | 79 +-
+ third_party/rust/nix/src/sys/timerfd.rs | 285 ++
+ third_party/rust/nix/src/sys/uio.rs | 18 +-
+ third_party/rust/nix/src/sys/utsname.rs | 8 +-
+ third_party/rust/nix/src/sys/wait.rs | 43 +-
+ third_party/rust/nix/src/time.rs | 260 ++
+ third_party/rust/nix/src/ucontext.rs | 25 +-
+ third_party/rust/nix/src/unistd.rs | 809 ++++--
+ third_party/rust/nix/test/common/mod.rs | 127 +
+ third_party/rust/nix/test/sys/mod.rs | 7 +
+ third_party/rust/nix/test/sys/test_aio.rs | 104 +-
+ .../rust/nix/test/sys/test_aio_drop.rs | 4 +-
+ third_party/rust/nix/test/sys/test_ioctl.rs | 55 +-
+ .../nix/test/sys/test_lio_listio_resubmit.rs | 4 -
+ third_party/rust/nix/test/sys/test_mman.rs | 80 +
+ third_party/rust/nix/test/sys/test_pthread.rs | 4 +-
+ third_party/rust/nix/test/sys/test_ptrace.rs | 79 +-
+ third_party/rust/nix/test/sys/test_select.rs | 2 +-
+ third_party/rust/nix/test/sys/test_signal.rs | 25 +-
+ .../rust/nix/test/sys/test_signalfd.rs | 6 +-
+ third_party/rust/nix/test/sys/test_socket.rs | 555 +++-
+ third_party/rust/nix/test/sys/test_sockopt.rs | 43 +
+ third_party/rust/nix/test/sys/test_termios.rs | 22 +-
+ third_party/rust/nix/test/sys/test_timerfd.rs | 61 +
+ third_party/rust/nix/test/sys/test_uio.rs | 12 +-
+ third_party/rust/nix/test/sys/test_wait.rs | 21 +-
+ third_party/rust/nix/test/test.rs | 71 +-
+ third_party/rust/nix/test/test_clearenv.rs | 9 +
+ third_party/rust/nix/test/test_dir.rs | 7 +-
+ third_party/rust/nix/test/test_fcntl.rs | 199 +-
+ third_party/rust/nix/test/test_kmod/mod.rs | 31 +-
+ third_party/rust/nix/test/test_mount.rs | 7 +-
+ third_party/rust/nix/test/test_mq.rs | 28 +-
+ third_party/rust/nix/test/test_poll.rs | 27 +-
+ third_party/rust/nix/test/test_pty.rs | 104 +-
+ .../rust/nix/test/test_ptymaster_drop.rs | 41 +-
+ third_party/rust/nix/test/test_sched.rs | 32 +
+ third_party/rust/nix/test/test_stat.rs | 61 +-
+ third_party/rust/nix/test/test_time.rs | 56 +
+ third_party/rust/nix/test/test_unistd.rs | 575 +++-
+ 226 files changed, 33484 insertions(+), 3322 deletions(-)
+ create mode 100644 third_party/rust/bitflags/build.rs
+ delete mode 100644 third_party/rust/bitflags/tests/basic.rs
+ delete mode 100644 third_party/rust/bitflags/tests/compile-fail/impls/copy.rs
+ delete mode 100644 third_party/rust/bitflags/tests/compile-fail/impls/copy.stderr.beta
+ delete mode 100644 third_party/rust/bitflags/tests/compile-fail/impls/eq.rs
+ delete mode 100644 third_party/rust/bitflags/tests/compile-fail/impls/eq.stderr.beta
+ delete mode 100644 third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_defined.rs
+ delete mode 100644 third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_defined.stderr.beta
+ delete mode 100644 third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_missing.rs
+ delete mode 100644 third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_missing.stderr.beta
+ delete mode 100644 third_party/rust/bitflags/tests/compile-fail/visibility/private_field.rs
+ delete mode 100644 third_party/rust/bitflags/tests/compile-fail/visibility/private_field.stderr.beta
+ delete mode 100644 third_party/rust/bitflags/tests/compile-fail/visibility/private_flags.rs
+ delete mode 100644 third_party/rust/bitflags/tests/compile-fail/visibility/private_flags.stderr.beta
+ delete mode 100644 third_party/rust/bitflags/tests/compile-fail/visibility/pub_const.rs
+ delete mode 100644 third_party/rust/bitflags/tests/compile-fail/visibility/pub_const.stderr.beta
+ delete mode 100644 third_party/rust/bitflags/tests/compile-pass/impls/convert.rs
+ delete mode 100644 third_party/rust/bitflags/tests/compile-pass/impls/default.rs
+ delete mode 100644 third_party/rust/bitflags/tests/compile-pass/impls/inherent_methods.rs
+ delete mode 100644 third_party/rust/bitflags/tests/compile-pass/redefinition/core.rs
+ delete mode 100644 third_party/rust/bitflags/tests/compile-pass/redefinition/stringify.rs
+ delete mode 100644 third_party/rust/bitflags/tests/compile-pass/repr/c.rs
+ delete mode 100644 third_party/rust/bitflags/tests/compile-pass/repr/transparent.rs
+ delete mode 100644 third_party/rust/bitflags/tests/compile-pass/visibility/bits_field.rs
+ delete mode 100644 third_party/rust/bitflags/tests/compile-pass/visibility/pub_in.rs
+ delete mode 100644 third_party/rust/bitflags/tests/compile.rs
+ create mode 100644 third_party/rust/nix-0.15.0/.cargo-checksum.json
+ create mode 100644 third_party/rust/nix-0.15.0/CHANGELOG.md
+ create mode 100644 third_party/rust/nix-0.15.0/CONTRIBUTING.md
+ create mode 100644 third_party/rust/nix-0.15.0/CONVENTIONS.md
+ create mode 100644 third_party/rust/nix-0.15.0/Cargo.toml
+ create mode 100644 third_party/rust/nix-0.15.0/LICENSE
+ create mode 100644 third_party/rust/nix-0.15.0/README.md
+ rename third_party/rust/{nix => nix-0.15.0}/build.rs (100%)
+ create mode 100644 third_party/rust/nix-0.15.0/src/dir.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/errno.rs
+ rename third_party/rust/{nix => nix-0.15.0}/src/errno_dragonfly.c (100%)
+ create mode 100644 third_party/rust/nix-0.15.0/src/fcntl.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/features.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/ifaddrs.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/kmod.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/lib.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/macros.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/mount.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/mqueue.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/net/if_.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/net/mod.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/poll.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/pty.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sched.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/aio.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/epoll.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/event.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/eventfd.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/inotify.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/ioctl/bsd.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/ioctl/linux.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/ioctl/mod.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/memfd.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/mman.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/mod.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/pthread.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/ptrace/bsd.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/ptrace/linux.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/ptrace/mod.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/quota.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/reboot.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/select.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/sendfile.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/signal.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/signalfd.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/socket/addr.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/socket/mod.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/socket/sockopt.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/stat.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/statfs.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/statvfs.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/sysinfo.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/termios.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/time.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/uio.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/utsname.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/sys/wait.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/ucontext.rs
+ create mode 100644 third_party/rust/nix-0.15.0/src/unistd.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/mod.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_aio.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_aio_drop.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_epoll.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_inotify.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_ioctl.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_lio_listio_resubmit.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_pthread.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_ptrace.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_select.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_signal.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_signalfd.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_socket.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_sockopt.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_sysinfo.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_termios.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_uio.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_wait.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/test.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/test_dir.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/test_fcntl.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/test_kmod/hello_mod/Makefile
+ create mode 100644 third_party/rust/nix-0.15.0/test/test_kmod/hello_mod/hello.c
+ create mode 100644 third_party/rust/nix-0.15.0/test/test_kmod/mod.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/test_mount.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/test_mq.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/test_net.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/test_nix_path.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/test_poll.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/test_pty.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/test_ptymaster_drop.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/test_sendfile.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/test_stat.rs
+ create mode 100644 third_party/rust/nix-0.15.0/test/test_unistd.rs
+ create mode 100644 third_party/rust/nix/src/env.rs
+ create mode 100644 third_party/rust/nix/src/sys/personality.rs
+ create mode 100644 third_party/rust/nix/src/sys/timerfd.rs
+ create mode 100644 third_party/rust/nix/src/time.rs
+ create mode 100644 third_party/rust/nix/test/common/mod.rs
+ create mode 100644 third_party/rust/nix/test/sys/test_mman.rs
+ create mode 100644 third_party/rust/nix/test/sys/test_timerfd.rs
+ create mode 100644 third_party/rust/nix/test/test_clearenv.rs
+ create mode 100644 third_party/rust/nix/test/test_sched.rs
+ create mode 100644 third_party/rust/nix/test/test_time.rs
+
+diff --git a/Cargo.lock b/Cargo.lock
+index edc5ef5ff2d98..f6240163e1440 100644
+--- a/Cargo.lock
++++ b/Cargo.lock
+@@ -25,14 +25,14 @@ dependencies = [
+
+ [[package]]
+ name = "alsa"
+-version = "0.4.3"
++version = "0.5.0"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "eb213f6b3e4b1480a60931ca2035794aa67b73103d254715b1db7b70dcb3c934"
++checksum = "75c4da790adcb2ce5e758c064b4f3ec17a30349f9961d3e5e6c9688b052a9e18"
+ dependencies = [
+ "alsa-sys",
+ "bitflags",
+ "libc",
+- "nix",
++ "nix 0.20.2",
+ ]
+
+ [[package]]
+@@ -427,9 +427,9 @@ checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
+
+ [[package]]
+ name = "bitflags"
+-version = "1.3.2"
++version = "1.2.1"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
++checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+
+ [[package]]
+ name = "bitflags_serde_shim"
+@@ -3073,7 +3073,7 @@ dependencies = [
+ [[package]]
+ name = "midir"
+ version = "0.7.0"
+-source = "git+https://github.com/mozilla/midir.git?rev=4c11f0ffb5d6a10de4aff40a7b81218b33b94e6f#4c11f0ffb5d6a10de4aff40a7b81218b33b94e6f"
++source = "git+https://github.com/makotokato/midir.git?rev=6140b2825dd4dc2b40e49e154ca7596e7b9a131a#6140b2825dd4dc2b40e49e154ca7596e7b9a131a"
+ dependencies = [
+ "alsa",
+ "bitflags",
+@@ -3081,7 +3081,7 @@ dependencies = [
+ "js-sys",
+ "libc",
+ "memalloc",
+- "nix",
++ "nix 0.20.2",
+ "wasm-bindgen",
+ "web-sys",
+ "winapi",
+@@ -3123,7 +3123,7 @@ dependencies = [
+ "libc",
+ "memmap2 0.2.3",
+ "memoffset 0.5.6",
+- "nix",
++ "nix 0.15.0",
+ "tempfile",
+ "thiserror",
+ ]
+@@ -3535,6 +3535,19 @@ dependencies = [
+ "void",
+ ]
+
++[[package]]
++name = "nix"
++version = "0.20.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "f5e06129fb611568ef4e868c14b326274959aa70ff7776e9d55323531c374945"
++dependencies = [
++ "bitflags",
++ "cc",
++ "cfg-if 1.0.0",
++ "libc",
++ "memoffset 0.6.5",
++]
++
+ [[package]]
+ name = "nom"
+ version = "5.1.2"
+diff --git a/Cargo.toml b/Cargo.toml
+index 1c2437f1f5675..2923c7e5ea9bf 100644
+--- a/Cargo.toml 2022-03-10 14:19:47.963772765 +0800
++++ b/Cargo.toml 2022-03-10 14:33:46.354649188 +0800
+@@ -103,13 +103,14 @@
+ moz_asserts = { path = "mozglue/static/rust/moz_asserts" }
+
+ # Other overrides
++authenticator = { git = "https://github.com/makotokato/authenticator-rs", rev="eed8919d50559f4959e2d7d2af7b4d48869b5366" }
+ async-task = { git = "https://github.com/smol-rs/async-task", rev="f6488e35beccb26eb6e85847b02aa78a42cd3d0e" }
+ chardetng = { git = "https://github.com/hsivonen/chardetng", rev="3484d3e3ebdc8931493aa5df4d7ee9360a90e76b" }
+ chardetng_c = { git = "https://github.com/hsivonen/chardetng_c", rev="ed8a4c6f900a90d4dbc1d64b856e61490a1c3570" }
+ coremidi = { git = "https://github.com/chris-zen/coremidi.git", rev="fc68464b5445caf111e41f643a2e69ccce0b4f83" }
+ libudev-sys = { path = "dom/webauthn/libudev-sys" }
+ packed_simd = { git = "https://github.com/hsivonen/packed_simd", rev="8b4bd7d8229660a749dbe419a57ea01df9de5453" }
+-midir = { git = "https://github.com/mozilla/midir.git", rev = "4c11f0ffb5d6a10de4aff40a7b81218b33b94e6f" }
++midir = { git = "https://github.com/makotokato/midir.git", rev = "6140b2825dd4dc2b40e49e154ca7596e7b9a131a" }
+ minidump_writer_linux = { git = "https://github.com/msirringhaus/minidump_writer_linux.git", rev = "029ac0d54b237f27dc7d8d4e51bc0fb076e5e852" }
+
+ # Patch mio 0.6 to use winapi 0.3 and miow 0.3, getting rid of winapi 0.2.
+
+diff --git a/third_party/rust/alsa/.cargo-checksum.json b/third_party/rust/alsa/.cargo-checksum.json
+index 17227c0a74d16..2bd6b2e2ce47b 100644
+--- a/third_party/rust/alsa/.cargo-checksum.json
++++ b/third_party/rust/alsa/.cargo-checksum.json
+@@ -1 +1 @@
+-{"files":{"Cargo.toml":"5c7a276dd872b47ff86f892e5d8991f38fbe3d61b64eb7138a4ee7ed43d437b7","README.md":"4ccf86e184eda628989919a15560c1ada2c00808cf34740f6e8de466338a1d48","src/card.rs":"f49c6cd6afb83848d34ce7a2e71ede2741ef60262d073be631347871c2768401","src/chmap.rs":"c639f9018fe7d49179a64b73d4f7ef418483c7b150b7edba61d81963c4056770","src/ctl_int.rs":"ebff40ad723a62632ed59840c15c4ec8e4cea2053e4f61d49bdae95e7a74da70","src/device_name.rs":"1e8ad5efbca9c4f062289213e3de8c3429d97a4acf6312c2016553b06e7fa57b","src/direct.rs":"fbd40addd2458bb0b3e856e5b0225fd24dc0ad46ce3662aef12635cf34ef7f55","src/direct/asound_ioctl.rs":"27c8935a0e7bd6e1925d947411c37ca81befba60468a6f2206da9fb08805be89","src/direct/ffi.rs":"aeb0871bd764198558557b5af1a1f6038efe8c8a400d77b4ddfc91143029ac90","src/direct/pcm.rs":"a258e7ba908ef6a2d7d0851ce5279ccc9f7b1579511f48550927fbe4306edaae","src/error.rs":"c8e9839123d760d49b58f46574445550c2c48b90c738b4daaf48aab8dd9a205f","src/hctl.rs":"cc33947cb0810d3edeec7b71686f0231d06c88b4214994605de7f4fd0f6de1a1","src/io.rs":"a6e21b94a265b7de56388e035b104877c8b6a0f5d10002c5931dacc90dd577fd","src/lib.rs":"df35e75bb2d83ddddcc90f4ed76e4bcef6843b3b2be09d9b8197c9ede564fbdf","src/mixer.rs":"d6610712f80eb4fd292d5b6e1d10723dfb245be4d85d0370a675034d83010e75","src/pcm.rs":"4259a5b33421e0b144de59da938af1ff1f70a1a3f6e0d2ab665dda4b94441d8c","src/poll.rs":"a6472dbcc96bcbdcc574563f305550df66870e48820d5e90609b0f105d12bb07","src/rawmidi.rs":"ca891bf1cd43ad59b1657efd58356f78ea476d5de999ed756eba74b729f0c184","src/seq.rs":"d229b36f12bf0161c87e0820fd4a3313f19718790e38e0b6294b7e6b1123c611"},"package":"eb213f6b3e4b1480a60931ca2035794aa67b73103d254715b1db7b70dcb3c934"}
+\ No newline at end of file
++{"files":{"Cargo.toml":"e057013b541a2bcf1d2b7aa79a2860fec402dad4ae434a66ad2cf1f4e40d31b9","README.md":"4ccf86e184eda628989919a15560c1ada2c00808cf34740f6e8de466338a1d48","src/card.rs":"f49c6cd6afb83848d34ce7a2e71ede2741ef60262d073be631347871c2768401","src/chmap.rs":"c639f9018fe7d49179a64b73d4f7ef418483c7b150b7edba61d81963c4056770","src/ctl_int.rs":"ebff40ad723a62632ed59840c15c4ec8e4cea2053e4f61d49bdae95e7a74da70","src/device_name.rs":"1e8ad5efbca9c4f062289213e3de8c3429d97a4acf6312c2016553b06e7fa57b","src/direct.rs":"fbd40addd2458bb0b3e856e5b0225fd24dc0ad46ce3662aef12635cf34ef7f55","src/direct/asound_ioctl.rs":"27c8935a0e7bd6e1925d947411c37ca81befba60468a6f2206da9fb08805be89","src/direct/ffi.rs":"aeb0871bd764198558557b5af1a1f6038efe8c8a400d77b4ddfc91143029ac90","src/direct/pcm.rs":"e8d464f08405e4edfc35be12d715012b3c765093794dd8fafc8991a5f4367c67","src/error.rs":"b37d9958dd200362c44d7015d1b03813efec183c9c76168f2608d1e798035ea1","src/hctl.rs":"cc33947cb0810d3edeec7b71686f0231d06c88b4214994605de7f4fd0f6de1a1","src/io.rs":"a6e21b94a265b7de56388e035b104877c8b6a0f5d10002c5931dacc90dd577fd","src/lib.rs":"b1235da87167b3a329b5a1a1d8670db0ab411676c0cdb2bfd1b8884bca34f469","src/mixer.rs":"a358bb2ad1db787348c29cdfeda339c4cd16c5a85f5cea8d7e0e9dda8335cbbd","src/pcm.rs":"6c5c87c9d959626d717c6e0e6f13248a56297a0cb390ab0e58d27ca7ad901cac","src/poll.rs":"a6472dbcc96bcbdcc574563f305550df66870e48820d5e90609b0f105d12bb07","src/rawmidi.rs":"ca891bf1cd43ad59b1657efd58356f78ea476d5de999ed756eba74b729f0c184","src/seq.rs":"d229b36f12bf0161c87e0820fd4a3313f19718790e38e0b6294b7e6b1123c611"},"package":"75c4da790adcb2ce5e758c064b4f3ec17a30349f9961d3e5e6c9688b052a9e18"}
+\ No newline at end of file
+diff --git a/third_party/rust/alsa/Cargo.toml b/third_party/rust/alsa/Cargo.toml
+index c7578fb0785b9..b4af1a6dae284 100644
+--- a/third_party/rust/alsa/Cargo.toml
++++ b/third_party/rust/alsa/Cargo.toml
+@@ -13,7 +13,7 @@
+ [package]
+ edition = "2018"
+ name = "alsa"
+-version = "0.4.3"
++version = "0.5.0"
+ authors = ["David Henningsson <diwic@ubuntu.com>"]
+ description = "Thin but safe wrappers for ALSA (Linux sound API)"
+ documentation = "http://docs.rs/alsa"
+@@ -23,16 +23,16 @@ categories = ["multimedia::audio", "api-bindings"]
+ license = "Apache-2.0/MIT"
+ repository = "https://github.com/diwic/alsa-rs"
+ [dependencies.alsa-sys]
+-version = "0.3.0"
++version = "0.3.1"
+
+ [dependencies.bitflags]
+ version = "1.2.1"
+
+ [dependencies.libc]
+-version = "0.2.65"
++version = "0.2.88"
+
+ [dependencies.nix]
+-version = "0.15"
++version = "0.20"
+ [badges.is-it-maintained-issue-resolution]
+ repository = "diwic/alsa-rs"
+
+diff --git a/third_party/rust/alsa/src/direct/pcm.rs b/third_party/rust/alsa/src/direct/pcm.rs
+index 13a16a993b030..f248a70c67031 100644
+--- a/third_party/rust/alsa/src/direct/pcm.rs
++++ b/third_party/rust/alsa/src/direct/pcm.rs
+@@ -19,7 +19,7 @@ don't expect it to work with, e g, the PulseAudio plugin or so.
+ For an example of how to use this mode, look in the "synth-example" directory.
+ */
+
+-use {libc, nix};
++use libc;
+ use std::{mem, ptr, fmt, cmp};
+ use crate::error::{Error, Result};
+ use std::os::unix::io::RawFd;
+diff --git a/third_party/rust/alsa/src/error.rs b/third_party/rust/alsa/src/error.rs
+index 4711b0fd2016d..25089c4cbd1d7 100644
+--- a/third_party/rust/alsa/src/error.rs
++++ b/third_party/rust/alsa/src/error.rs
+@@ -3,7 +3,6 @@
+ use libc::{c_void, c_int, c_char, free};
+ use std::{fmt, ptr, str};
+ use std::ffi::CStr;
+-use nix;
+ use std::error::Error as StdError;
+
+ /// ALSA error
+diff --git a/third_party/rust/alsa/src/lib.rs b/third_party/rust/alsa/src/lib.rs
+index cf172cb6c60c6..b1a98df7804f3 100644
+--- a/third_party/rust/alsa/src/lib.rs
++++ b/third_party/rust/alsa/src/lib.rs
+@@ -18,7 +18,7 @@ extern crate libc;
+ #[macro_use]
+ extern crate bitflags;
+ #[macro_use]
+-extern crate nix;
++extern crate nix as nix_the_crate;
+
+ macro_rules! alsa_enum {
+ ($(#[$attr:meta])+ $name:ident, $static_name:ident [$count:expr], $( $a:ident = $b:ident),* ,) =>
+@@ -125,3 +125,9 @@ pub use crate::io::Output;
+ mod chmap;
+
+ pub mod direct;
++
++/// Re-exports from the nix crate.
++pub mod nix {
++ pub use nix_the_crate::Error;
++ pub use nix_the_crate::errno;
++}
+diff --git a/third_party/rust/alsa/src/mixer.rs b/third_party/rust/alsa/src/mixer.rs
+index cb16247a85b62..834aafaf35c18 100644
+--- a/third_party/rust/alsa/src/mixer.rs
++++ b/third_party/rust/alsa/src/mixer.rs
+@@ -112,11 +112,19 @@ impl ops::Add for MilliBel {
+ fn add(self, rhs: Self) -> Self { MilliBel(self.0 + rhs.0) }
+ }
+
++impl ops::AddAssign for MilliBel {
++ fn add_assign(&mut self, rhs: Self) { self.0 += rhs.0 }
++}
++
+ impl ops::Sub for MilliBel {
+ type Output = MilliBel;
+ fn sub(self, rhs: Self) -> Self { MilliBel(self.0 - rhs.0) }
+ }
+
++impl ops::SubAssign for MilliBel {
++ fn sub_assign(&mut self, rhs: Self) { self.0 -= rhs.0 }
++}
++
+ /// Wraps [snd_mixer_elem_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___mixer.html)
+ #[derive(Copy, Clone, Debug)]
+ pub struct Elem<'a>{
+diff --git a/third_party/rust/alsa/src/pcm.rs b/third_party/rust/alsa/src/pcm.rs
+index 359b44c6db2cb..5696df9dc691e 100644
+--- a/third_party/rust/alsa/src/pcm.rs
++++ b/third_party/rust/alsa/src/pcm.rs
+@@ -174,8 +174,7 @@ impl PCM {
+ }
+
+ pub fn status(&self) -> Result<Status> {
+- let z = Status::new();
+- acheck!(snd_pcm_status(self.0, z.ptr())).map(|_| z)
++ StatusBuilder::new().build(self)
+ }
+
+ fn verify_format(&self, f: Format) -> Result<()> {
+@@ -416,6 +415,7 @@ alsa_enum!(
+ );
+
+ alsa_enum!(
++ #[non_exhaustive]
+ /// [SND_PCM_FORMAT_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants
+ Format, ALL_FORMATS[48],
+
+@@ -470,21 +470,21 @@ alsa_enum!(
+ );
+
+ impl Format {
+- pub fn s16() -> Format { <i16 as IoFormat>::FORMAT }
+- pub fn u16() -> Format { <u16 as IoFormat>::FORMAT }
+- pub fn s32() -> Format { <i32 as IoFormat>::FORMAT }
+- pub fn u32() -> Format { <u32 as IoFormat>::FORMAT }
+- pub fn float() -> Format { <f32 as IoFormat>::FORMAT }
+- pub fn float64() -> Format { <f64 as IoFormat>::FORMAT }
++ pub const fn s16() -> Format { <i16 as IoFormat>::FORMAT }
++ pub const fn u16() -> Format { <u16 as IoFormat>::FORMAT }
++ pub const fn s32() -> Format { <i32 as IoFormat>::FORMAT }
++ pub const fn u32() -> Format { <u32 as IoFormat>::FORMAT }
++ pub const fn float() -> Format { <f32 as IoFormat>::FORMAT }
++ pub const fn float64() -> Format { <f64 as IoFormat>::FORMAT }
+
+- #[cfg(target_endian = "little")] pub fn s24() -> Format { Format::S24LE }
+- #[cfg(target_endian = "big")] pub fn s24() -> Format { Format::S24BE }
++ #[cfg(target_endian = "little")] pub const fn s24() -> Format { Format::S24LE }
++ #[cfg(target_endian = "big")] pub const fn s24() -> Format { Format::S24BE }
+
+- #[cfg(target_endian = "little")] pub fn u24() -> Format { Format::U24LE }
+- #[cfg(target_endian = "big")] pub fn u24() -> Format { Format::U24BE }
++ #[cfg(target_endian = "little")] pub const fn u24() -> Format { Format::U24LE }
++ #[cfg(target_endian = "big")] pub const fn u24() -> Format { Format::U24BE }
+
+- #[cfg(target_endian = "little")] pub fn iec958_subframe() -> Format { Format::IEC958SubframeLE }
+- #[cfg(target_endian = "big")] pub fn iec958_subframe() -> Format { Format::IEC958SubframeBE }
++ #[cfg(target_endian = "little")] pub const fn iec958_subframe() -> Format { Format::IEC958SubframeLE }
++ #[cfg(target_endian = "big")] pub const fn iec958_subframe() -> Format { Format::IEC958SubframeBE }
+ }
+
+
+@@ -769,6 +769,15 @@ impl<'a> HwParams<'a> {
+ unsafe { alsa::snd_pcm_hw_params_can_resume(self.0) != 0 }
+ }
+
++ /// Returns true if the alsa stream supports the provided `AudioTstampType`, false if not.
++ ///
++ /// This function should only be called when the configuration space contains a single
++ /// configuration. Call `PCM::hw_params` to choose a single configuration from the
++ /// configuration space.
++ pub fn supports_audio_ts_type(&self, type_: AudioTstampType) -> bool {
++ unsafe { alsa::snd_pcm_hw_params_supports_audio_ts_type(self.0, type_ as libc::c_int) != 0 }
++ }
++
+ pub fn dump(&self, o: &mut Output) -> Result<()> {
+ acheck!(snd_pcm_hw_params_dump(self.0, super::io::output_handle(o))).map(|_| ())
+ }
+@@ -923,6 +932,47 @@ impl Status {
+ }
+ }
+
++/// Builder for [`Status`].
++///
++/// Allows setting the audio timestamp configuration before retrieving the
++/// status from the stream.
++pub struct StatusBuilder(Status);
++
++impl StatusBuilder {
++ pub fn new() -> Self {
++ StatusBuilder(Status::new())
++ }
++
++ pub fn audio_htstamp_config(
++ self,
++ type_requested: AudioTstampType,
++ report_delay: bool,
++ ) -> Self {
++ let mut cfg: alsa::snd_pcm_audio_tstamp_config_t = unsafe { std::mem::zeroed() };
++ cfg.set_type_requested(type_requested as _);
++ cfg.set_report_delay(report_delay as _);
++ unsafe { alsa::snd_pcm_status_set_audio_htstamp_config(self.0.ptr(), &mut cfg) };
++ self
++ }
++
++ pub fn build(self, pcm: &PCM) -> Result<Status> {
++ acheck!(snd_pcm_status(pcm.0, self.0.ptr())).map(|_| self.0)
++ }
++}
++
++alsa_enum!(
++ #[non_exhaustive]
++ /// [SND_PCM_AUDIO_TSTAMP_TYPE_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants
++ AudioTstampType, ALL_AUDIO_TSTAMP_TYPES[6],
++
++ Compat = SND_PCM_AUDIO_TSTAMP_TYPE_COMPAT,
++ Default = SND_PCM_AUDIO_TSTAMP_TYPE_DEFAULT,
++ Link = SND_PCM_AUDIO_TSTAMP_TYPE_LINK,
++ LinkAbsolute = SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE,
++ LinkEstimated = SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED,
++ LinkSynchronized = SND_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED,
++);
++
+ #[test]
+ fn info_from_default() {
+ use std::ffi::CString;
+diff --git a/third_party/rust/bitflags/.cargo-checksum.json b/third_party/rust/bitflags/.cargo-checksum.json
+index 7e8d470b53a37..a8b031c6517a2 100644
+--- a/third_party/rust/bitflags/.cargo-checksum.json
++++ b/third_party/rust/bitflags/.cargo-checksum.json
+@@ -1 +1 @@
+-{"files":{"CHANGELOG.md":"d362fc1fccaaf4d421bcf0fe8b80ddb4f625dade0c1ee52d08bd0b95509a49d1","CODE_OF_CONDUCT.md":"42634d0f6d922f49857175af991802822f7f920487aefa2ee250a50d12251a66","Cargo.toml":"87aced7532a7974eb37ab5fe6037f0abafc36d6b2d74891ecd2bf2f14f50d11e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"baa8604f8afb34fd93b9c79729daafb884dedcaf34023e4af8ad037d916061fd","src/example_generated.rs":"e43eb59e90f317f38d436670a6067d2fd9eb35fb319fe716184e4a04e24ed1b2","src/lib.rs":"e6477688535ee326d27238aeedc9cb4320ac35b9d17a4deda09e0587b0ccdbd4","tests/basic.rs":"146f1cbf6279bc609242cd3349f29cb21b41294f5e4921875f5ec95bd83529a2","tests/compile-fail/impls/copy.rs":"b791371237ddc75a7c04d2130e03b462c9c00a80dca08bd45aa97433d9c0d13a","tests/compile-fail/impls/copy.stderr.beta":"77d83484ce221d4b6ff2f7de843929a452d779fcfff428122710dd8218c298e3","tests/compile-fail/impls/eq.rs":"0cee8b9e07d537890e0189710293b53972d0fab63c09366f33c391065afafa99","tests/compile-fail/impls/eq.stderr.beta":"381fc6143d45ce76d7cecc47aa59cb69fe5e79c0b60a4a85d5c6163b400b3cc7","tests/compile-fail/non_integer_base/all_defined.rs":"95e14cad9e94560262f2862c3c01865ac30369b69da1001b0e7285cb55e6cb75","tests/compile-fail/non_integer_base/all_defined.stderr.beta":"1760739a276690903bb03844025587d37939f5dfcbfab309db3c86f32bdbf748","tests/compile-fail/non_integer_base/all_missing.rs":"b3d9da619d23213731ba2581aa7999c796c3c79aaf4f0ee6b11ceec08a11537f","tests/compile-fail/non_integer_base/all_missing.stderr.beta":"37e102290d3867e175b21976be798939f294efb17580d5b51e7b17b590d55132","tests/compile-fail/visibility/private_field.rs":"38e4d3fe6471829360d12c8d09b097f6a21aa93fb51eac3b215d96bdae23316b","tests/compile-fail/visibility/private_field.stderr.beta":"5aa24a3ebb39326f31927721c5017b8beb66c3e501fb865a3fa814c9763bfa0f","tests/compile-fail/visibility/private_flags.rs":"2ce4235802aa4e9c96c4e77d9e31d8401ef58dcda4741325184f0764ab1fe393","tests/compile-fail/visibility/private_flags.stderr.beta":"f3eb9f7baf2689258f3519ff7ee5c6ec3c237264ebcfe63f40c40f2023e5022f","tests/compile-fail/visibility/pub_const.rs":"8f813a97ac518c5ea8ac65b184101912452384afaf7b8d6c5e62f8370eca3c0a","tests/compile-fail/visibility/pub_const.stderr.beta":"823976ae1794d7f5372e2ec9aabba497e7bb88004722904c38da342ed98e8962","tests/compile-pass/impls/convert.rs":"88fe80bfb9cd5779f0e1d92c9ec02a8b6bb67e334c07f2309e9c0ba5ef776eb0","tests/compile-pass/impls/default.rs":"c508f9a461691f44b45142fa5ad599f02326e1de4c0cbca6c0593f4652eba109","tests/compile-pass/impls/inherent_methods.rs":"ecc26388e9a394bfa7a5bb69a5d621ab3d4d1e53f28f657bb8e78fe79f437913","tests/compile-pass/redefinition/core.rs":"ff5b6e72f87acc6ebb12405d3c0f6e3fa62e669933656a454bb63b30ea44179c","tests/compile-pass/redefinition/stringify.rs":"1edbce42b900c14425d7ffa14e83e165ebe452d7dccd8c0a8a821bdec64f5c93","tests/compile-pass/repr/c.rs":"6fda17f7c2edfcd155314579e83d0fc8a16209e400f1f9a5ca77bd9a799041f2","tests/compile-pass/repr/transparent.rs":"6cdc87a2137d8a4e0c8ce9b6cba83c82255f8ea125951bf614418685600489ce","tests/compile-pass/visibility/bits_field.rs":"1f3e5ba5a047440066a9f6bf7b7af33f5b06f6b1da3dd9af6886168199a7ea0a","tests/compile-pass/visibility/pub_in.rs":"e95312ff60966d42ec4bc00225507895a9b8ec24056ce6a9edd9145be35d730f","tests/compile.rs":"f27c67a7dd183ca30efea1b6e0880e3469a6dd63b92b1fd711c082df182c9eec"},"package":"bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"}
+\ No newline at end of file
++{"files":{"CHANGELOG.md":"00224cc8d292567bdd212c36db66a1f662cd2e6c58e947900680234937e288a9","CODE_OF_CONDUCT.md":"42634d0f6d922f49857175af991802822f7f920487aefa2ee250a50d12251a66","Cargo.toml":"abacd42e33056c16008ab8eefd16eb2403cbc3393f8a6ed352a9a39d945ad3a5","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"6b236f8b62c82f189fabce0756e01a2c0ab1f32cb84cad9ff3c96b2ce5282bda","build.rs":"8923f38056f859b30aa9022980bb517755cbef57e1b09c34b33b27eb03b0626c","src/example_generated.rs":"e43eb59e90f317f38d436670a6067d2fd9eb35fb319fe716184e4a04e24ed1b2","src/lib.rs":"bd4e44ac35831c75af8815ba3a11ee1659afe0f72ce9c5f638a66bf50aa23d2a"},"package":"cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"}
+\ No newline at end of file
+diff --git a/third_party/rust/bitflags/CHANGELOG.md b/third_party/rust/bitflags/CHANGELOG.md
+index 12fea1673ac30..0d4910153d909 100644
+--- a/third_party/rust/bitflags/CHANGELOG.md
++++ b/third_party/rust/bitflags/CHANGELOG.md
+@@ -1,60 +1,3 @@
+-# 1.3.2
+-
+-- Allow `non_snake_case` in generated flags types ([#256])
+-
+-[#252]: https://github.com/bitflags/bitflags/pull/256
+-
+-# 1.3.1
+-
+-- Revert unconditional `#[repr(transparent)]` ([#252])
+-
+-[#252]: https://github.com/bitflags/bitflags/pull/252
+-
+-# 1.3.0 (yanked)
+-
+-- Add `#[repr(transparent)]` ([#187])
+-
+-- End `empty` doc comment with full stop ([#202])
+-
+-- Fix typo in crate root docs ([#206])
+-
+-- Document from_bits_unchecked unsafety ([#207])
+-
+-- Let `is_all` ignore extra bits ([#211])
+-
+-- Allows empty flag definition ([#225])
+-
+-- Making crate accessible from std ([#227])
+-
+-- Make `from_bits` a const fn ([#229])
+-
+-- Allow multiple bitflags structs in one macro invocation ([#235])
+-
+-- Add named functions to perform set operations ([#244])
+-
+-- Fix typos in method docs ([#245])
+-
+-- Modernization of the `bitflags` macro to take advantage of newer features and 2018 idioms ([#246])
+-
+-- Fix regression (in an unreleased feature) and simplify tests ([#247])
+-
+-- Use `Self` and fix bug when overriding `stringify!` ([#249])
+-
+-[#187]: https://github.com/bitflags/bitflags/pull/187
+-[#202]: https://github.com/bitflags/bitflags/pull/202
+-[#206]: https://github.com/bitflags/bitflags/pull/206
+-[#207]: https://github.com/bitflags/bitflags/pull/207
+-[#211]: https://github.com/bitflags/bitflags/pull/211
+-[#225]: https://github.com/bitflags/bitflags/pull/225
+-[#227]: https://github.com/bitflags/bitflags/pull/227
+-[#229]: https://github.com/bitflags/bitflags/pull/229
+-[#235]: https://github.com/bitflags/bitflags/pull/235
+-[#244]: https://github.com/bitflags/bitflags/pull/244
+-[#245]: https://github.com/bitflags/bitflags/pull/245
+-[#246]: https://github.com/bitflags/bitflags/pull/246
+-[#247]: https://github.com/bitflags/bitflags/pull/247
+-[#249]: https://github.com/bitflags/bitflags/pull/249
+-
+ # 1.2.1
+
+ - Remove extraneous `#[inline]` attributes ([#194])
+diff --git a/third_party/rust/bitflags/Cargo.toml b/third_party/rust/bitflags/Cargo.toml
+index 9d54c725a1c5d..b803644d44753 100644
+--- a/third_party/rust/bitflags/Cargo.toml
++++ b/third_party/rust/bitflags/Cargo.toml
+@@ -11,11 +11,11 @@
+ # will likely look very different (and much more reasonable)
+
+ [package]
+-edition = "2018"
+ name = "bitflags"
+-version = "1.3.2"
++version = "1.2.1"
+ authors = ["The Rust Project Developers"]
+-exclude = ["bors.toml"]
++build = "build.rs"
++exclude = [".travis.yml", "appveyor.yml", "bors.toml"]
+ description = "A macro to generate structures which behave like bitflags.\n"
+ homepage = "https://github.com/bitflags/bitflags"
+ documentation = "https://docs.rs/bitflags"
+@@ -26,33 +26,9 @@ license = "MIT/Apache-2.0"
+ repository = "https://github.com/bitflags/bitflags"
+ [package.metadata.docs.rs]
+ features = ["example_generated"]
+-[dependencies.compiler_builtins]
+-version = "0.1.2"
+-optional = true
+-
+-[dependencies.core]
+-version = "1.0.0"
+-optional = true
+-package = "rustc-std-workspace-core"
+-[dev-dependencies.rustversion]
+-version = "1.0"
+-
+-[dev-dependencies.serde]
+-version = "1.0"
+-
+-[dev-dependencies.serde_derive]
+-version = "1.0"
+-
+-[dev-dependencies.serde_json]
+-version = "1.0"
+-
+-[dev-dependencies.trybuild]
+-version = "1.0"
+-
+-[dev-dependencies.walkdir]
+-version = "2.3"
+
+ [features]
+ default = []
+ example_generated = []
+-rustc-dep-of-std = ["core", "compiler_builtins"]
++[badges.travis-ci]
++repository = "bitflags/bitflags"
+diff --git a/third_party/rust/bitflags/README.md b/third_party/rust/bitflags/README.md
+index 0da0f853661b0..df12934c3e28a 100644
+--- a/third_party/rust/bitflags/README.md
++++ b/third_party/rust/bitflags/README.md
+@@ -1,10 +1,11 @@
+ bitflags
+ ========
+
+-[![Rust](https://github.com/bitflags/bitflags/workflows/Rust/badge.svg)](https://github.com/bitflags/bitflags/actions)
++[![Build Status](https://travis-ci.com/bitflags/bitflags.svg?branch=master)](https://travis-ci.com/bitflags/bitflags)
+ [![Join the chat at https://gitter.im/bitflags/Lobby](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/bitflags/Lobby?utm_source=badge&utm_medium=badge&utm_content=badge)
+ [![Latest version](https://img.shields.io/crates/v/bitflags.svg)](https://crates.io/crates/bitflags)
+ [![Documentation](https://docs.rs/bitflags/badge.svg)](https://docs.rs/bitflags)
++![Minimum rustc version](https://img.shields.io/badge/rustc-1.20+-yellow.svg)
+ ![License](https://img.shields.io/crates/l/bitflags.svg)
+
+ A Rust macro to generate structures which behave like a set of bitflags
+@@ -18,15 +19,16 @@ Add this to your `Cargo.toml`:
+
+ ```toml
+ [dependencies]
+-bitflags = "1.3"
++bitflags = "1.0"
+ ```
+
+-and this to your source code:
++and this to your crate root:
+
+ ```rust
+-use bitflags::bitflags;
++#[macro_use]
++extern crate bitflags;
+ ```
+
+ ## Rust Version Support
+
+-The minimum supported Rust version is 1.46 due to use of associated constants and const functions.
++The minimum supported Rust version is 1.20 due to use of associated constants.
+diff --git a/third_party/rust/bitflags/build.rs b/third_party/rust/bitflags/build.rs
+new file mode 100644
+index 0000000000000..985757a6f6126
+--- /dev/null
++++ b/third_party/rust/bitflags/build.rs
+@@ -0,0 +1,44 @@
++use std::env;
++use std::process::Command;
++use std::str::{self, FromStr};
++
++fn main(){
++ let minor = match rustc_minor_version() {
++ Some(minor) => minor,
++ None => return,
++ };
++
++ // const fn stabilized in Rust 1.31:
++ if minor >= 31 {
++ println!("cargo:rustc-cfg=bitflags_const_fn");
++ }
++}
++
++fn rustc_minor_version() -> Option<u32> {
++ let rustc = match env::var_os("RUSTC") {
++ Some(rustc) => rustc,
++ None => return None,
++ };
++
++ let output = match Command::new(rustc).arg("--version").output() {
++ Ok(output) => output,
++ Err(_) => return None,
++ };
++
++ let version = match str::from_utf8(&output.stdout) {
++ Ok(version) => version,
++ Err(_) => return None,
++ };
++
++ let mut pieces = version.split('.');
++ if pieces.next() != Some("rustc 1") {
++ return None;
++ }
++
++ let next = match pieces.next() {
++ Some(next) => next,
++ None => return None,
++ };
++
++ u32::from_str(next).ok()
++}
+\ No newline at end of file
+diff --git a/third_party/rust/bitflags/src/lib.rs b/third_party/rust/bitflags/src/lib.rs
+index 935e432f1701e..3929b02ac10d7 100644
+--- a/third_party/rust/bitflags/src/lib.rs
++++ b/third_party/rust/bitflags/src/lib.rs
+@@ -11,14 +11,15 @@
+ //! A typesafe bitmask flag generator useful for sets of C-style bitmask flags.
+ //! It can be used for creating typesafe wrappers around C APIs.
+ //!
+-//! The `bitflags!` macro generates `struct`s that manage a set of flags. The
++//! The `bitflags!` macro generates a `struct` that manages a set of flags. The
+ //! flags should only be defined for integer types, otherwise unexpected type
+ //! errors may occur at compile time.
+ //!
+ //! # Example
+ //!
+ //! ```
+-//! use bitflags::bitflags;
++//! #[macro_use]
++//! extern crate bitflags;
+ //!
+ //! bitflags! {
+ //! struct Flags: u32 {
+@@ -46,9 +47,10 @@
+ //! implementations:
+ //!
+ //! ```
+-//! use std::fmt;
++//! #[macro_use]
++//! extern crate bitflags;
+ //!
+-//! use bitflags::bitflags;
++//! use std::fmt;
+ //!
+ //! bitflags! {
+ //! struct Flags: u32 {
+@@ -82,19 +84,21 @@
+ //!
+ //! # Visibility
+ //!
+-//! The generated structs and their associated flag constants are not exported
++//! The generated struct and its associated flag constants are not exported
+ //! out of the current module by default. A definition can be exported out of
+-//! the current module by adding `pub` before `struct`:
++//! the current module by adding `pub` before `flags`:
+ //!
+ //! ```
+-//! mod example {
+-//! use bitflags::bitflags;
++//! #[macro_use]
++//! extern crate bitflags;
+ //!
++//! mod example {
+ //! bitflags! {
+ //! pub struct Flags1: u32 {
+ //! const A = 0b00000001;
+ //! }
+-//!
++//! }
++//! bitflags! {
+ //! # pub
+ //! struct Flags2: u32 {
+ //! const B = 0b00000010;
+@@ -110,44 +114,26 @@
+ //!
+ //! # Attributes
+ //!
+-//! Attributes can be attached to the generated `struct`s by placing them
+-//! before the `struct` keyword.
+-//!
+-//! ## Representations
+-//!
+-//! It's valid to add a `#[repr(C)]` or `#[repr(transparent)]` attribute to a type
+-//! generated by `bitflags!`. In these cases, the type is guaranteed to be a newtype.
+-//!
+-//! ```
+-//! use bitflags::bitflags;
+-//!
+-//! bitflags! {
+-//! #[repr(transparent)]
+-//! struct Flags: u32 {
+-//! const A = 0b00000001;
+-//! const B = 0b00000010;
+-//! const C = 0b00000100;
+-//! }
+-//! }
+-//! ```
++//! Attributes can be attached to the generated `struct` by placing them
++//! before the `flags` keyword.
+ //!
+ //! # Trait implementations
+ //!
+ //! The `Copy`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord` and `Hash`
+-//! traits are automatically derived for the `struct`s using the `derive` attribute.
++//! traits automatically derived for the `struct` using the `derive` attribute.
+ //! Additional traits can be derived by providing an explicit `derive`
+-//! attribute on `struct`.
++//! attribute on `flags`.
+ //!
+-//! The `Extend` and `FromIterator` traits are implemented for the `struct`s,
++//! The `Extend` and `FromIterator` traits are implemented for the `struct`,
+ //! too: `Extend` adds the union of the instances of the `struct` iterated over,
+ //! while `FromIterator` calculates the union.
+ //!
+-//! The `Binary`, `Debug`, `LowerHex`, `Octal` and `UpperHex` traits are also
++//! The `Binary`, `Debug`, `LowerHex`, `Octal` and `UpperHex` trait is also
+ //! implemented by displaying the bits value of the internal struct.
+ //!
+ //! ## Operators
+ //!
+-//! The following operator traits are implemented for the generated `struct`s:
++//! The following operator traits are implemented for the generated `struct`:
+ //!
+ //! - `BitOr` and `BitOrAssign`: union
+ //! - `BitAnd` and `BitAndAssign`: intersection
+@@ -157,7 +143,7 @@
+ //!
+ //! # Methods
+ //!
+-//! The following methods are defined for the generated `struct`s:
++//! The following methods are defined for the generated `struct`:
+ //!
+ //! - `empty`: an empty set of flags
+ //! - `all`: the set of all defined flags
+@@ -173,34 +159,23 @@
+ //! - `is_empty`: `true` if no flags are currently stored
+ //! - `is_all`: `true` if currently set flags exactly equal all defined flags
+ //! - `intersects`: `true` if there are flags common to both `self` and `other`
+-//! - `contains`: `true` if all of the flags in `other` are contained within `self`
++//! - `contains`: `true` all of the flags in `other` are contained within `self`
+ //! - `insert`: inserts the specified flags in-place
+ //! - `remove`: removes the specified flags in-place
+ //! - `toggle`: the specified flags will be inserted if not present, and removed
+ //! if they are.
+ //! - `set`: inserts or removes the specified flags depending on the passed value
+-//! - `intersection`: returns a new set of flags, containing only the flags present
+-//! in both `self` and `other` (the argument to the function).
+-//! - `union`: returns a new set of flags, containing any flags present in
+-//! either `self` or `other` (the argument to the function).
+-//! - `difference`: returns a new set of flags, containing all flags present in
+-//! `self` without any of the flags present in `other` (the
+-//! argument to the function).
+-//! - `symmetric_difference`: returns a new set of flags, containing all flags
+-//! present in either `self` or `other` (the argument
+-//! to the function), but not both.
+-//! - `complement`: returns a new set of flags, containing all flags which are
+-//! not set in `self`, but which are allowed for this type.
+ //!
+ //! ## Default
+ //!
+-//! The `Default` trait is not automatically implemented for the generated structs.
++//! The `Default` trait is not automatically implemented for the generated struct.
+ //!
+ //! If your default value is equal to `0` (which is the same value as calling `empty()`
+ //! on the generated struct), you can simply derive `Default`:
+ //!
+ //! ```
+-//! use bitflags::bitflags;
++//! #[macro_use]
++//! extern crate bitflags;
+ //!
+ //! bitflags! {
+ //! // Results in default value with bits: 0
+@@ -221,7 +196,8 @@
+ //! If your default value is not equal to `0` you need to implement `Default` yourself:
+ //!
+ //! ```
+-//! use bitflags::bitflags;
++//! #[macro_use]
++//! extern crate bitflags;
+ //!
+ //! bitflags! {
+ //! struct Flags: u32 {
+@@ -249,7 +225,8 @@
+ //! Flags with a value equal to zero will have some strange behavior that one should be aware of.
+ //!
+ //! ```
+-//! use bitflags::bitflags;
++//! #[macro_use]
++//! extern crate bitflags;
+ //!
+ //! bitflags! {
+ //! struct Flags: u32 {
+@@ -272,23 +249,28 @@
+ //! assert!(none.is_empty());
+ //! }
+ //! ```
+-//!
+-//! Users should generally avoid defining a flag with a value of zero.
+
+-#![cfg_attr(not(test), no_std)]
+-#![doc(html_root_url = "https://docs.rs/bitflags/1.3.2")]
++#![no_std]
++#![doc(html_root_url = "https://docs.rs/bitflags/1.2.1")]
++
++#[cfg(test)]
++#[macro_use]
++extern crate std;
+
++// Re-export libcore using an alias so that the macros can work without
++// requiring `extern crate core` downstream.
+ #[doc(hidden)]
+ pub extern crate core as _core;
+
+-/// The macro used to generate the flag structures.
++/// The macro used to generate the flag structure.
+ ///
+ /// See the [crate level docs](../bitflags/index.html) for complete documentation.
+ ///
+ /// # Example
+ ///
+ /// ```
+-/// use bitflags::bitflags;
++/// #[macro_use]
++/// extern crate bitflags;
+ ///
+ /// bitflags! {
+ /// struct Flags: u32 {
+@@ -313,9 +295,10 @@ pub extern crate core as _core;
+ /// implementations:
+ ///
+ /// ```
+-/// use std::fmt;
++/// #[macro_use]
++/// extern crate bitflags;
+ ///
+-/// use bitflags::bitflags;
++/// use std::fmt;
+ ///
+ /// bitflags! {
+ /// struct Flags: u32 {
+@@ -350,18 +333,78 @@ pub extern crate core as _core;
+ macro_rules! bitflags {
+ (
+ $(#[$outer:meta])*
+- $vis:vis struct $BitFlags:ident: $T:ty {
++ pub struct $BitFlags:ident: $T:ty {
++ $(
++ $(#[$inner:ident $($args:tt)*])*
++ const $Flag:ident = $value:expr;
++ )+
++ }
++ ) => {
++ __bitflags! {
++ $(#[$outer])*
++ (pub) $BitFlags: $T {
++ $(
++ $(#[$inner $($args)*])*
++ $Flag = $value;
++ )+
++ }
++ }
++ };
++ (
++ $(#[$outer:meta])*
++ struct $BitFlags:ident: $T:ty {
++ $(
++ $(#[$inner:ident $($args:tt)*])*
++ const $Flag:ident = $value:expr;
++ )+
++ }
++ ) => {
++ __bitflags! {
++ $(#[$outer])*
++ () $BitFlags: $T {
++ $(
++ $(#[$inner $($args)*])*
++ $Flag = $value;
++ )+
++ }
++ }
++ };
++ (
++ $(#[$outer:meta])*
++ pub ($($vis:tt)+) struct $BitFlags:ident: $T:ty {
+ $(
+ $(#[$inner:ident $($args:tt)*])*
+ const $Flag:ident = $value:expr;
+- )*
++ )+
++ }
++ ) => {
++ __bitflags! {
++ $(#[$outer])*
++ (pub ($($vis)+)) $BitFlags: $T {
++ $(
++ $(#[$inner $($args)*])*
++ $Flag = $value;
++ )+
++ }
+ }
++ };
++}
+
+- $($t:tt)*
++#[macro_export(local_inner_macros)]
++#[doc(hidden)]
++macro_rules! __bitflags {
++ (
++ $(#[$outer:meta])*
++ ($($vis:tt)*) $BitFlags:ident: $T:ty {
++ $(
++ $(#[$inner:ident $($args:tt)*])*
++ $Flag:ident = $value:expr;
++ )+
++ }
+ ) => {
+ $(#[$outer])*
+ #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
+- $vis struct $BitFlags {
++ $($vis)* struct $BitFlags {
+ bits: $T,
+ }
+
+@@ -370,52 +413,63 @@ macro_rules! bitflags {
+ $(
+ $(#[$inner $($args)*])*
+ $Flag = $value;
+- )*
++ )+
+ }
+ }
++ };
++}
+
+- bitflags! {
+- $($t)*
+- }
++#[macro_export(local_inner_macros)]
++#[doc(hidden)]
++#[cfg(bitflags_const_fn)]
++macro_rules! __fn_bitflags {
++ (
++ $(# $attr_args:tt)*
++ const fn $($item:tt)*
++ ) => {
++ $(# $attr_args)*
++ const fn $($item)*
++ };
++ (
++ $(# $attr_args:tt)*
++ pub const fn $($item:tt)*
++ ) => {
++ $(# $attr_args)*
++ pub const fn $($item)*
++ };
++ (
++ $(# $attr_args:tt)*
++ pub const unsafe fn $($item:tt)*
++ ) => {
++ $(# $attr_args)*
++ pub const unsafe fn $($item)*
+ };
+- () => {};
+ }
+
+-// A helper macro to implement the `all` function.
+ #[macro_export(local_inner_macros)]
+ #[doc(hidden)]
+-macro_rules! __impl_all_bitflags {
++#[cfg(not(bitflags_const_fn))]
++macro_rules! __fn_bitflags {
+ (
+- $BitFlags:ident: $T:ty {
+- $(
+- $(#[$attr:ident $($args:tt)*])*
+- $Flag:ident = $value:expr;
+- )+
+- }
++ $(# $attr_args:tt)*
++ const fn $($item:tt)*
+ ) => {
+- // See `Debug::fmt` for why this approach is taken.
+- #[allow(non_snake_case)]
+- trait __BitFlags {
+- $(
+- const $Flag: $T = 0;
+- )+
+- }
+- #[allow(non_snake_case)]
+- impl __BitFlags for $BitFlags {
+- $(
+- __impl_bitflags! {
+- #[allow(deprecated)]
+- $(? #[$attr $($args)*])*
+- const $Flag: $T = Self::$Flag.bits;
+- }
+- )+
+- }
+- Self { bits: $(<Self as __BitFlags>::$Flag)|+ }
++ $(# $attr_args)*
++ fn $($item)*
++ };
++ (
++ $(# $attr_args:tt)*
++ pub const fn $($item:tt)*
++ ) => {
++ $(# $attr_args)*
++ pub fn $($item)*
+ };
+ (
+- $BitFlags:ident: $T:ty { }
++ $(# $attr_args:tt)*
++ pub const unsafe fn $($item:tt)*
+ ) => {
+- Self { bits: 0 }
++ $(# $attr_args)*
++ pub unsafe fn $($item)*
+ };
+ }
+
+@@ -427,7 +481,7 @@ macro_rules! __impl_bitflags {
+ $(
+ $(#[$attr:ident $($args:tt)*])*
+ $Flag:ident = $value:expr;
+- )*
++ )+
+ }
+ ) => {
+ impl $crate::_core::fmt::Debug for $BitFlags {
+@@ -445,12 +499,11 @@ macro_rules! __impl_bitflags {
+ $(
+ #[inline]
+ fn $Flag(&self) -> bool { false }
+- )*
++ )+
+ }
+
+ // Conditionally override the check for just those flags that
+ // are not #[cfg]ed away.
+- #[allow(non_snake_case)]
+ impl __BitFlags for $BitFlags {
+ $(
+ __impl_bitflags! {
+@@ -465,20 +518,20 @@ macro_rules! __impl_bitflags {
+ }
+ }
+ }
+- )*
++ )+
+ }
+
+ let mut first = true;
+ $(
+- if <Self as __BitFlags>::$Flag(self) {
++ if <$BitFlags as __BitFlags>::$Flag(self) {
+ if !first {
+ f.write_str(" | ")?;
+ }
+ first = false;
+- f.write_str($crate::_core::stringify!($Flag))?;
++ f.write_str(__bitflags_stringify!($Flag))?;
+ }
+- )*
+- let extra_bits = self.bits & !Self::all().bits();
++ )+
++ let extra_bits = self.bits & !$BitFlags::all().bits();
+ if extra_bits != 0 {
+ if !first {
+ f.write_str(" | ")?;
+@@ -518,295 +571,227 @@ macro_rules! __impl_bitflags {
+ impl $BitFlags {
+ $(
+ $(#[$attr $($args)*])*
+- pub const $Flag: Self = Self { bits: $value };
+- )*
++ pub const $Flag: $BitFlags = $BitFlags { bits: $value };
++ )+
+
+- /// Returns an empty set of flags.
+- #[inline]
+- pub const fn empty() -> Self {
+- Self { bits: 0 }
++ __fn_bitflags! {
++ /// Returns an empty set of flags
++ #[inline]
++ pub const fn empty() -> $BitFlags {
++ $BitFlags { bits: 0 }
++ }
+ }
+
+- /// Returns the set containing all flags.
+- #[inline]
+- pub const fn all() -> Self {
+- __impl_all_bitflags! {
+- $BitFlags: $T {
++ __fn_bitflags! {
++ /// Returns the set containing all flags.
++ #[inline]
++ pub const fn all() -> $BitFlags {
++ // See `Debug::fmt` for why this approach is taken.
++ #[allow(non_snake_case)]
++ trait __BitFlags {
+ $(
+- $(#[$attr $($args)*])*
+- $Flag = $value;
+- )*
++ const $Flag: $T = 0;
++ )+
+ }
++ impl __BitFlags for $BitFlags {
++ $(
++ __impl_bitflags! {
++ #[allow(deprecated)]
++ $(? #[$attr $($args)*])*
++ const $Flag: $T = Self::$Flag.bits;
++ }
++ )+
++ }
++ $BitFlags { bits: $(<$BitFlags as __BitFlags>::$Flag)|+ }
+ }
+ }
+
+- /// Returns the raw value of the flags currently stored.
+- #[inline]
+- pub const fn bits(&self) -> $T {
+- self.bits
++ __fn_bitflags! {
++ /// Returns the raw value of the flags currently stored.
++ #[inline]
++ pub const fn bits(&self) -> $T {
++ self.bits
++ }
+ }
+
+ /// Convert from underlying bit representation, unless that
+ /// representation contains bits that do not correspond to a flag.
+ #[inline]
+- pub const fn from_bits(bits: $T) -> $crate::_core::option::Option<Self> {
+- if (bits & !Self::all().bits()) == 0 {
+- $crate::_core::option::Option::Some(Self { bits })
++ pub fn from_bits(bits: $T) -> $crate::_core::option::Option<$BitFlags> {
++ if (bits & !$BitFlags::all().bits()) == 0 {
++ $crate::_core::option::Option::Some($BitFlags { bits })
+ } else {
+ $crate::_core::option::Option::None
+ }
+ }
+
+- /// Convert from underlying bit representation, dropping any bits
+- /// that do not correspond to flags.
+- #[inline]
+- pub const fn from_bits_truncate(bits: $T) -> Self {
+- Self { bits: bits & Self::all().bits }
++ __fn_bitflags! {
++ /// Convert from underlying bit representation, dropping any bits
++ /// that do not correspond to flags.
++ #[inline]
++ pub const fn from_bits_truncate(bits: $T) -> $BitFlags {
++ $BitFlags { bits: bits & $BitFlags::all().bits }
++ }
+ }
+
+- /// Convert from underlying bit representation, preserving all
+- /// bits (even those not corresponding to a defined flag).
+- ///
+- /// # Safety
+- ///
+- /// The caller of the `bitflags!` macro can chose to allow or
+- /// disallow extra bits for their bitflags type.
+- ///
+- /// The caller of `from_bits_unchecked()` has to ensure that
+- /// all bits correspond to a defined flag or that extra bits
+- /// are valid for this bitflags type.
+- #[inline]
+- pub const unsafe fn from_bits_unchecked(bits: $T) -> Self {
+- Self { bits }
++ __fn_bitflags! {
++ /// Convert from underlying bit representation, preserving all
++ /// bits (even those not corresponding to a defined flag).
++ #[inline]
++ pub const unsafe fn from_bits_unchecked(bits: $T) -> $BitFlags {
++ $BitFlags { bits }
++ }
+ }
+
+- /// Returns `true` if no flags are currently stored.
+- #[inline]
+- pub const fn is_empty(&self) -> bool {
+- self.bits() == Self::empty().bits()
++ __fn_bitflags! {
++ /// Returns `true` if no flags are currently stored.
++ #[inline]
++ pub const fn is_empty(&self) -> bool {
++ self.bits() == $BitFlags::empty().bits()
++ }
+ }
+
+- /// Returns `true` if all flags are currently set.
+- #[inline]
+- pub const fn is_all(&self) -> bool {
+- Self::all().bits | self.bits == self.bits
++ __fn_bitflags! {
++ /// Returns `true` if all flags are currently set.
++ #[inline]
++ pub const fn is_all(&self) -> bool {
++ self.bits == $BitFlags::all().bits
++ }
+ }
+
+- /// Returns `true` if there are flags common to both `self` and `other`.
+- #[inline]
+- pub const fn intersects(&self, other: Self) -> bool {
+- !(Self { bits: self.bits & other.bits}).is_empty()
++ __fn_bitflags! {
++ /// Returns `true` if there are flags common to both `self` and `other`.
++ #[inline]
++ pub const fn intersects(&self, other: $BitFlags) -> bool {
++ !$BitFlags{ bits: self.bits & other.bits}.is_empty()
++ }
+ }
+
+- /// Returns `true` if all of the flags in `other` are contained within `self`.
+- #[inline]
+- pub const fn contains(&self, other: Self) -> bool {
+- (self.bits & other.bits) == other.bits
++ __fn_bitflags! {
++ /// Returns `true` all of the flags in `other` are contained within `self`.
++ #[inline]
++ pub const fn contains(&self, other: $BitFlags) -> bool {
++ (self.bits & other.bits) == other.bits
++ }
+ }
+
+ /// Inserts the specified flags in-place.
+ #[inline]
+- pub fn insert(&mut self, other: Self) {
++ pub fn insert(&mut self, other: $BitFlags) {
+ self.bits |= other.bits;
+ }
+
+ /// Removes the specified flags in-place.
+ #[inline]
+- pub fn remove(&mut self, other: Self) {
++ pub fn remove(&mut self, other: $BitFlags) {
+ self.bits &= !other.bits;
+ }
+
+ /// Toggles the specified flags in-place.
+ #[inline]
+- pub fn toggle(&mut self, other: Self) {
++ pub fn toggle(&mut self, other: $BitFlags) {
+ self.bits ^= other.bits;
+ }
+
+ /// Inserts or removes the specified flags depending on the passed value.
+ #[inline]
+- pub fn set(&mut self, other: Self, value: bool) {
++ pub fn set(&mut self, other: $BitFlags, value: bool) {
+ if value {
+ self.insert(other);
+ } else {
+ self.remove(other);
+ }
+ }
+-
+- /// Returns the intersection between the flags in `self` and
+- /// `other`.
+- ///
+- /// Specifically, the returned set contains only the flags which are
+- /// present in *both* `self` *and* `other`.
+- ///
+- /// This is equivalent to using the `&` operator (e.g.
+- /// [`ops::BitAnd`]), as in `flags & other`.
+- ///
+- /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
+- #[inline]
+- #[must_use]
+- pub const fn intersection(self, other: Self) -> Self {
+- Self { bits: self.bits & other.bits }
+- }
+-
+- /// Returns the union of between the flags in `self` and `other`.
+- ///
+- /// Specifically, the returned set contains all flags which are
+- /// present in *either* `self` *or* `other`, including any which are
+- /// present in both (see [`Self::symmetric_difference`] if that
+- /// is undesirable).
+- ///
+- /// This is equivalent to using the `|` operator (e.g.
+- /// [`ops::BitOr`]), as in `flags | other`.
+- ///
+- /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
+- #[inline]
+- #[must_use]
+- pub const fn union(self, other: Self) -> Self {
+- Self { bits: self.bits | other.bits }
+- }
+-
+- /// Returns the difference between the flags in `self` and `other`.
+- ///
+- /// Specifically, the returned set contains all flags present in
+- /// `self`, except for the ones present in `other`.
+- ///
+- /// It is also conceptually equivalent to the "bit-clear" operation:
+- /// `flags & !other` (and this syntax is also supported).
+- ///
+- /// This is equivalent to using the `-` operator (e.g.
+- /// [`ops::Sub`]), as in `flags - other`.
+- ///
+- /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
+- #[inline]
+- #[must_use]
+- pub const fn difference(self, other: Self) -> Self {
+- Self { bits: self.bits & !other.bits }
+- }
+-
+- /// Returns the [symmetric difference][sym-diff] between the flags
+- /// in `self` and `other`.
+- ///
+- /// Specifically, the returned set contains the flags present which
+- /// are present in `self` or `other`, but that are not present in
+- /// both. Equivalently, it contains the flags present in *exactly
+- /// one* of the sets `self` and `other`.
+- ///
+- /// This is equivalent to using the `^` operator (e.g.
+- /// [`ops::BitXor`]), as in `flags ^ other`.
+- ///
+- /// [sym-diff]: https://en.wikipedia.org/wiki/Symmetric_difference
+- /// [`ops::BitXor`]: https://doc.rust-lang.org/std/ops/trait.BitXor.html
+- #[inline]
+- #[must_use]
+- pub const fn symmetric_difference(self, other: Self) -> Self {
+- Self { bits: self.bits ^ other.bits }
+- }
+-
+- /// Returns the complement of this set of flags.
+- ///
+- /// Specifically, the returned set contains all the flags which are
+- /// not set in `self`, but which are allowed for this type.
+- ///
+- /// Alternatively, it can be thought of as the set difference
+- /// between [`Self::all()`] and `self` (e.g. `Self::all() - self`)
+- ///
+- /// This is equivalent to using the `!` operator (e.g.
+- /// [`ops::Not`]), as in `!flags`.
+- ///
+- /// [`Self::all()`]: Self::all
+- /// [`ops::Not`]: https://doc.rust-lang.org/std/ops/trait.Not.html
+- #[inline]
+- #[must_use]
+- pub const fn complement(self) -> Self {
+- Self::from_bits_truncate(!self.bits)
+- }
+-
+ }
+
+ impl $crate::_core::ops::BitOr for $BitFlags {
+- type Output = Self;
++ type Output = $BitFlags;
+
+ /// Returns the union of the two sets of flags.
+ #[inline]
+- fn bitor(self, other: $BitFlags) -> Self {
+- Self { bits: self.bits | other.bits }
++ fn bitor(self, other: $BitFlags) -> $BitFlags {
++ $BitFlags { bits: self.bits | other.bits }
+ }
+ }
+
+ impl $crate::_core::ops::BitOrAssign for $BitFlags {
++
+ /// Adds the set of flags.
+ #[inline]
+- fn bitor_assign(&mut self, other: Self) {
++ fn bitor_assign(&mut self, other: $BitFlags) {
+ self.bits |= other.bits;
+ }
+ }
+
+ impl $crate::_core::ops::BitXor for $BitFlags {
+- type Output = Self;
++ type Output = $BitFlags;
+
+ /// Returns the left flags, but with all the right flags toggled.
+ #[inline]
+- fn bitxor(self, other: Self) -> Self {
+- Self { bits: self.bits ^ other.bits }
++ fn bitxor(self, other: $BitFlags) -> $BitFlags {
++ $BitFlags { bits: self.bits ^ other.bits }
+ }
+ }
+
+ impl $crate::_core::ops::BitXorAssign for $BitFlags {
++
+ /// Toggles the set of flags.
+ #[inline]
+- fn bitxor_assign(&mut self, other: Self) {
++ fn bitxor_assign(&mut self, other: $BitFlags) {
+ self.bits ^= other.bits;
+ }
+ }
+
+ impl $crate::_core::ops::BitAnd for $BitFlags {
+- type Output = Self;
++ type Output = $BitFlags;
+
+ /// Returns the intersection between the two sets of flags.
+ #[inline]
+- fn bitand(self, other: Self) -> Self {
+- Self { bits: self.bits & other.bits }
++ fn bitand(self, other: $BitFlags) -> $BitFlags {
++ $BitFlags { bits: self.bits & other.bits }
+ }
+ }
+
+ impl $crate::_core::ops::BitAndAssign for $BitFlags {
++
+ /// Disables all flags disabled in the set.
+ #[inline]
+- fn bitand_assign(&mut self, other: Self) {
++ fn bitand_assign(&mut self, other: $BitFlags) {
+ self.bits &= other.bits;
+ }
+ }
+
+ impl $crate::_core::ops::Sub for $BitFlags {
+- type Output = Self;
++ type Output = $BitFlags;
+
+ /// Returns the set difference of the two sets of flags.
+ #[inline]
+- fn sub(self, other: Self) -> Self {
+- Self { bits: self.bits & !other.bits }
++ fn sub(self, other: $BitFlags) -> $BitFlags {
++ $BitFlags { bits: self.bits & !other.bits }
+ }
+ }
+
+ impl $crate::_core::ops::SubAssign for $BitFlags {
++
+ /// Disables all flags enabled in the set.
+ #[inline]
+- fn sub_assign(&mut self, other: Self) {
++ fn sub_assign(&mut self, other: $BitFlags) {
+ self.bits &= !other.bits;
+ }
+ }
+
+ impl $crate::_core::ops::Not for $BitFlags {
+- type Output = Self;
++ type Output = $BitFlags;
+
+ /// Returns the complement of this set of flags.
+ #[inline]
+- fn not(self) -> Self {
+- Self { bits: !self.bits } & Self::all()
++ fn not(self) -> $BitFlags {
++ $BitFlags { bits: !self.bits } & $BitFlags::all()
+ }
+ }
+
+ impl $crate::_core::iter::Extend<$BitFlags> for $BitFlags {
+- fn extend<T: $crate::_core::iter::IntoIterator<Item=Self>>(&mut self, iterator: T) {
++ fn extend<T: $crate::_core::iter::IntoIterator<Item=$BitFlags>>(&mut self, iterator: T) {
+ for item in iterator {
+ self.insert(item)
+ }
+@@ -814,7 +799,7 @@ macro_rules! __impl_bitflags {
+ }
+
+ impl $crate::_core::iter::FromIterator<$BitFlags> for $BitFlags {
+- fn from_iter<T: $crate::_core::iter::IntoIterator<Item=Self>>(iterator: T) -> Self {
++ fn from_iter<T: $crate::_core::iter::IntoIterator<Item=$BitFlags>>(iterator: T) -> $BitFlags {
+ let mut result = Self::empty();
+ result.extend(iterator);
+ result
+@@ -832,7 +817,7 @@ macro_rules! __impl_bitflags {
+ // Input:
+ //
+ // ? #[cfg(feature = "advanced")]
+- // ? #[deprecated(note = "Use something else.")]
++ // ? #[deprecated(note = "Use somthing else.")]
+ // ? #[doc = r"High quality documentation."]
+ // fn f() -> i32 { /* ... */ }
+ //
+@@ -887,7 +872,7 @@ macro_rules! __impl_bitflags {
+ // Input:
+ //
+ // ? #[cfg(feature = "advanced")]
+- // ? #[deprecated(note = "Use something else.")]
++ // ? #[deprecated(note = "Use somthing else.")]
+ // ? #[doc = r"High quality documentation."]
+ // const f: i32 { /* ... */ }
+ //
+@@ -931,6 +916,16 @@ macro_rules! __impl_bitflags {
+ };
+ }
+
++// Same as std::stringify but callable from __impl_bitflags, which needs to use
++// local_inner_macros so can only directly call macros from this crate.
++#[macro_export]
++#[doc(hidden)]
++macro_rules! __bitflags_stringify {
++ ($s:ident) => {
++ stringify!($s)
++ };
++}
++
+ #[cfg(feature = "example_generated")]
+ pub mod example_generated;
+
+@@ -944,7 +939,6 @@ mod tests {
+ #[doc = "> you are the easiest person to fool."]
+ #[doc = "> "]
+ #[doc = "> - Richard Feynman"]
+- #[derive(Default)]
+ struct Flags: u32 {
+ const A = 0b00000001;
+ #[doc = "<pcwalton> macros are way better at generating code than trans is"]
+@@ -955,7 +949,9 @@ mod tests {
+ #[doc = "<strcat> wait what?"]
+ const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
+ }
++ }
+
++ bitflags! {
+ struct _CfgFlags: u32 {
+ #[cfg(unix)]
+ const _CFG_A = 0b01;
+@@ -964,18 +960,17 @@ mod tests {
+ #[cfg(unix)]
+ const _CFG_C = Self::_CFG_A.bits | 0b10;
+ }
++ }
+
++ bitflags! {
+ struct AnotherSetOfFlags: i8 {
+ const ANOTHER_FLAG = -1_i8;
+ }
+-
+- struct LongFlags: u32 {
+- const LONG_A = 0b1111111111111111;
+- }
+ }
+
+ bitflags! {
+- struct EmptyFlags: u32 {
++ struct LongFlags: u32 {
++ const LONG_A = 0b1111111111111111;
+ }
+ }
+
+@@ -987,8 +982,6 @@ mod tests {
+
+ assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00);
+ assert_eq!(AnotherSetOfFlags::ANOTHER_FLAG.bits(), !0_i8);
+-
+- assert_eq!(EmptyFlags::empty().bits(), 0b00000000);
+ }
+
+ #[test]
+@@ -1003,9 +996,6 @@ mod tests {
+ AnotherSetOfFlags::from_bits(!0_i8),
+ Some(AnotherSetOfFlags::ANOTHER_FLAG)
+ );
+-
+- assert_eq!(EmptyFlags::from_bits(0), Some(EmptyFlags::empty()));
+- assert_eq!(EmptyFlags::from_bits(0b1), None);
+ }
+
+ #[test]
+@@ -1021,9 +1011,6 @@ mod tests {
+ AnotherSetOfFlags::from_bits_truncate(0_i8),
+ AnotherSetOfFlags::empty()
+ );
+-
+- assert_eq!(EmptyFlags::from_bits_truncate(0), EmptyFlags::empty());
+- assert_eq!(EmptyFlags::from_bits_truncate(0b1), EmptyFlags::empty());
+ }
+
+ #[test]
+@@ -1032,25 +1019,9 @@ mod tests {
+ assert_eq!(unsafe { Flags::from_bits_unchecked(0) }, Flags::empty());
+ assert_eq!(unsafe { Flags::from_bits_unchecked(0b1) }, Flags::A);
+ assert_eq!(unsafe { Flags::from_bits_unchecked(0b10) }, Flags::B);
+-
+- assert_eq!(
+- unsafe { Flags::from_bits_unchecked(0b11) },
+- (Flags::A | Flags::B)
+- );
+- assert_eq!(
+- unsafe { Flags::from_bits_unchecked(0b1000) },
+- (extra | Flags::empty())
+- );
+- assert_eq!(
+- unsafe { Flags::from_bits_unchecked(0b1001) },
+- (extra | Flags::A)
+- );
+-
+- let extra = unsafe { EmptyFlags::from_bits_unchecked(0b1000) };
+- assert_eq!(
+- unsafe { EmptyFlags::from_bits_unchecked(0b1000) },
+- (extra | EmptyFlags::empty())
+- );
++ assert_eq!(unsafe { Flags::from_bits_unchecked(0b11) }, (Flags::A | Flags::B));
++ assert_eq!(unsafe { Flags::from_bits_unchecked(0b1000) }, (extra | Flags::empty()));
++ assert_eq!(unsafe { Flags::from_bits_unchecked(0b1001) }, (extra | Flags::A));
+ }
+
+ #[test]
+@@ -1060,9 +1031,6 @@ mod tests {
+ assert!(!Flags::ABC.is_empty());
+
+ assert!(!AnotherSetOfFlags::ANOTHER_FLAG.is_empty());
+-
+- assert!(EmptyFlags::empty().is_empty());
+- assert!(EmptyFlags::all().is_empty());
+ }
+
+ #[test]
+@@ -1071,15 +1039,7 @@ mod tests {
+ assert!(!Flags::A.is_all());
+ assert!(Flags::ABC.is_all());
+
+- let extra = unsafe { Flags::from_bits_unchecked(0b1000) };
+- assert!(!extra.is_all());
+- assert!(!(Flags::A | extra).is_all());
+- assert!((Flags::ABC | extra).is_all());
+-
+ assert!(AnotherSetOfFlags::ANOTHER_FLAG.is_all());
+-
+- assert!(EmptyFlags::all().is_all());
+- assert!(EmptyFlags::empty().is_all());
+ }
+
+ #[test]
+@@ -1121,8 +1081,6 @@ mod tests {
+ assert!(Flags::ABC.contains(e2));
+
+ assert!(AnotherSetOfFlags::ANOTHER_FLAG.contains(AnotherSetOfFlags::ANOTHER_FLAG));
+-
+- assert!(EmptyFlags::empty().contains(EmptyFlags::empty()));
+ }
+
+ #[test]
+@@ -1183,188 +1141,6 @@ mod tests {
+ assert_eq!(e3, Flags::A | Flags::B | extra);
+ }
+
+- #[test]
+- fn test_set_ops_basic() {
+- let ab = Flags::A.union(Flags::B);
+- let ac = Flags::A.union(Flags::C);
+- let bc = Flags::B.union(Flags::C);
+- assert_eq!(ab.bits, 0b011);
+- assert_eq!(bc.bits, 0b110);
+- assert_eq!(ac.bits, 0b101);
+-
+- assert_eq!(ab, Flags::B.union(Flags::A));
+- assert_eq!(ac, Flags::C.union(Flags::A));
+- assert_eq!(bc, Flags::C.union(Flags::B));
+-
+- assert_eq!(ac, Flags::A | Flags::C);
+- assert_eq!(bc, Flags::B | Flags::C);
+- assert_eq!(ab.union(bc), Flags::ABC);
+-
+- assert_eq!(ac, Flags::A | Flags::C);
+- assert_eq!(bc, Flags::B | Flags::C);
+-
+- assert_eq!(ac.union(bc), ac | bc);
+- assert_eq!(ac.union(bc), Flags::ABC);
+- assert_eq!(bc.union(ac), Flags::ABC);
+-
+- assert_eq!(ac.intersection(bc), ac & bc);
+- assert_eq!(ac.intersection(bc), Flags::C);
+- assert_eq!(bc.intersection(ac), Flags::C);
+-
+- assert_eq!(ac.difference(bc), ac - bc);
+- assert_eq!(bc.difference(ac), bc - ac);
+- assert_eq!(ac.difference(bc), Flags::A);
+- assert_eq!(bc.difference(ac), Flags::B);
+-
+- assert_eq!(bc.complement(), !bc);
+- assert_eq!(bc.complement(), Flags::A);
+- assert_eq!(ac.symmetric_difference(bc), Flags::A.union(Flags::B));
+- assert_eq!(bc.symmetric_difference(ac), Flags::A.union(Flags::B));
+- }
+-
+- #[test]
+- fn test_set_ops_const() {
+- // These just test that these compile and don't cause use-site panics
+- // (would be possible if we had some sort of UB)
+- const INTERSECT: Flags = Flags::all().intersection(Flags::C);
+- const UNION: Flags = Flags::A.union(Flags::C);
+- const DIFFERENCE: Flags = Flags::all().difference(Flags::A);
+- const COMPLEMENT: Flags = Flags::C.complement();
+- const SYM_DIFFERENCE: Flags = UNION.symmetric_difference(DIFFERENCE);
+- assert_eq!(INTERSECT, Flags::C);
+- assert_eq!(UNION, Flags::A | Flags::C);
+- assert_eq!(DIFFERENCE, Flags::all() - Flags::A);
+- assert_eq!(COMPLEMENT, !Flags::C);
+- assert_eq!(SYM_DIFFERENCE, (Flags::A | Flags::C) ^ (Flags::all() - Flags::A));
+- }
+-
+- #[test]
+- fn test_set_ops_unchecked() {
+- let extra = unsafe { Flags::from_bits_unchecked(0b1000) };
+- let e1 = Flags::A.union(Flags::C).union(extra);
+- let e2 = Flags::B.union(Flags::C);
+- assert_eq!(e1.bits, 0b1101);
+- assert_eq!(e1.union(e2), (Flags::ABC | extra));
+- assert_eq!(e1.intersection(e2), Flags::C);
+- assert_eq!(e1.difference(e2), Flags::A | extra);
+- assert_eq!(e2.difference(e1), Flags::B);
+- assert_eq!(e2.complement(), Flags::A);
+- assert_eq!(e1.complement(), Flags::B);
+- assert_eq!(e1.symmetric_difference(e2), Flags::A | Flags::B | extra); // toggle
+- }
+-
+- #[test]
+- fn test_set_ops_exhaustive() {
+- // Define a flag that contains gaps to help exercise edge-cases,
+- // especially around "unknown" flags (e.g. ones outside of `all()`
+- // `from_bits_unchecked`).
+- // - when lhs and rhs both have different sets of unknown flags.
+- // - unknown flags at both ends, and in the middle
+- // - cases with "gaps".
+- bitflags! {
+- struct Test: u16 {
+- // Intentionally no `A`
+- const B = 0b000000010;
+- // Intentionally no `C`
+- const D = 0b000001000;
+- const E = 0b000010000;
+- const F = 0b000100000;
+- const G = 0b001000000;
+- // Intentionally no `H`
+- const I = 0b100000000;
+- }
+- }
+- let iter_test_flags =
+- || (0..=0b111_1111_1111).map(|bits| unsafe { Test::from_bits_unchecked(bits) });
+-
+- for a in iter_test_flags() {
+- assert_eq!(
+- a.complement(),
+- Test::from_bits_truncate(!a.bits),
+- "wrong result: !({:?})",
+- a,
+- );
+- assert_eq!(a.complement(), !a, "named != op: !({:?})", a);
+- for b in iter_test_flags() {
+- // Check that the named operations produce the expected bitwise
+- // values.
+- assert_eq!(
+- a.union(b).bits,
+- a.bits | b.bits,
+- "wrong result: `{:?}` | `{:?}`",
+- a,
+- b,
+- );
+- assert_eq!(
+- a.intersection(b).bits,
+- a.bits & b.bits,
+- "wrong result: `{:?}` & `{:?}`",
+- a,
+- b,
+- );
+- assert_eq!(
+- a.symmetric_difference(b).bits,
+- a.bits ^ b.bits,
+- "wrong result: `{:?}` ^ `{:?}`",
+- a,
+- b,
+- );
+- assert_eq!(
+- a.difference(b).bits,
+- a.bits & !b.bits,
+- "wrong result: `{:?}` - `{:?}`",
+- a,
+- b,
+- );
+- // Note: Difference is checked as both `a - b` and `b - a`
+- assert_eq!(
+- b.difference(a).bits,
+- b.bits & !a.bits,
+- "wrong result: `{:?}` - `{:?}`",
+- b,
+- a,
+- );
+- // Check that the named set operations are equivalent to the
+- // bitwise equivalents
+- assert_eq!(a.union(b), a | b, "named != op: `{:?}` | `{:?}`", a, b,);
+- assert_eq!(
+- a.intersection(b),
+- a & b,
+- "named != op: `{:?}` & `{:?}`",
+- a,
+- b,
+- );
+- assert_eq!(
+- a.symmetric_difference(b),
+- a ^ b,
+- "named != op: `{:?}` ^ `{:?}`",
+- a,
+- b,
+- );
+- assert_eq!(a.difference(b), a - b, "named != op: `{:?}` - `{:?}`", a, b,);
+- // Note: Difference is checked as both `a - b` and `b - a`
+- assert_eq!(b.difference(a), b - a, "named != op: `{:?}` - `{:?}`", b, a,);
+- // Verify that the operations which should be symmetric are
+- // actually symmetric.
+- assert_eq!(a.union(b), b.union(a), "asymmetry: `{:?}` | `{:?}`", a, b,);
+- assert_eq!(
+- a.intersection(b),
+- b.intersection(a),
+- "asymmetry: `{:?}` & `{:?}`",
+- a,
+- b,
+- );
+- assert_eq!(
+- a.symmetric_difference(b),
+- b.symmetric_difference(a),
+- "asymmetry: `{:?}` ^ `{:?}`",
+- a,
+- b,
+- );
+- }
+- }
+- }
+-
+ #[test]
+ fn test_set() {
+ let mut e1 = Flags::A | Flags::C;
+@@ -1392,6 +1168,8 @@ mod tests {
+ assert_eq!(m1, e1);
+ }
+
++
++ #[cfg(bitflags_const_fn)]
+ #[test]
+ fn test_const_fn() {
+ const _M1: Flags = Flags::empty();
+@@ -1481,11 +1259,6 @@ mod tests {
+ assert_eq!(hash(&x), hash(&y));
+ }
+
+- #[test]
+- fn test_default() {
+- assert_eq!(Flags::empty(), Flags::default());
+- }
+-
+ #[test]
+ fn test_debug() {
+ assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B");
+@@ -1494,13 +1267,7 @@ mod tests {
+ let extra = unsafe { Flags::from_bits_unchecked(0xb8) };
+ assert_eq!(format!("{:?}", extra), "0xb8");
+ assert_eq!(format!("{:?}", Flags::A | extra), "A | 0xb8");
+-
+- assert_eq!(
+- format!("{:?}", Flags::ABC | extra),
+- "A | B | C | ABC | 0xb8"
+- );
+-
+- assert_eq!(format!("{:?}", EmptyFlags::empty()), "(empty)");
++ assert_eq!(format!("{:?}", Flags::ABC | extra), "A | B | C | ABC | 0xb8");
+ }
+
+ #[test]
+@@ -1544,7 +1311,8 @@ mod tests {
+ pub struct PublicFlags: i8 {
+ const X = 0;
+ }
+-
++ }
++ bitflags! {
+ struct PrivateFlags: i8 {
+ const Y = 0;
+ }
+@@ -1659,71 +1427,4 @@ mod tests {
+ assert_eq!(format!("{:?}", Flags::empty()), "NONE");
+ assert_eq!(format!("{:?}", Flags::SOME), "SOME");
+ }
+-
+- #[test]
+- fn test_empty_bitflags() {
+- bitflags! {}
+- }
+-
+- #[test]
+- fn test_u128_bitflags() {
+- bitflags! {
+- struct Flags128: u128 {
+- const A = 0x0000_0000_0000_0000_0000_0000_0000_0001;
+- const B = 0x0000_0000_0000_1000_0000_0000_0000_0000;
+- const C = 0x8000_0000_0000_0000_0000_0000_0000_0000;
+- const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
+- }
+- }
+-
+- assert_eq!(Flags128::ABC, Flags128::A | Flags128::B | Flags128::C);
+- assert_eq!(Flags128::A.bits, 0x0000_0000_0000_0000_0000_0000_0000_0001);
+- assert_eq!(Flags128::B.bits, 0x0000_0000_0000_1000_0000_0000_0000_0000);
+- assert_eq!(Flags128::C.bits, 0x8000_0000_0000_0000_0000_0000_0000_0000);
+- assert_eq!(
+- Flags128::ABC.bits,
+- 0x8000_0000_0000_1000_0000_0000_0000_0001
+- );
+- assert_eq!(format!("{:?}", Flags128::A), "A");
+- assert_eq!(format!("{:?}", Flags128::B), "B");
+- assert_eq!(format!("{:?}", Flags128::C), "C");
+- assert_eq!(format!("{:?}", Flags128::ABC), "A | B | C | ABC");
+- }
+-
+- #[test]
+- fn test_serde_bitflags_serialize() {
+- let flags = SerdeFlags::A | SerdeFlags::B;
+-
+- let serialized = serde_json::to_string(&flags).unwrap();
+-
+- assert_eq!(serialized, r#"{"bits":3}"#);
+- }
+-
+- #[test]
+- fn test_serde_bitflags_deserialize() {
+- let deserialized: SerdeFlags = serde_json::from_str(r#"{"bits":12}"#).unwrap();
+-
+- let expected = SerdeFlags::C | SerdeFlags::D;
+-
+- assert_eq!(deserialized.bits, expected.bits);
+- }
+-
+- #[test]
+- fn test_serde_bitflags_roundtrip() {
+- let flags = SerdeFlags::A | SerdeFlags::B;
+-
+- let deserialized: SerdeFlags = serde_json::from_str(&serde_json::to_string(&flags).unwrap()).unwrap();
+-
+- assert_eq!(deserialized.bits, flags.bits);
+- }
+-
+- bitflags! {
+- #[derive(serde::Serialize, serde::Deserialize)]
+- struct SerdeFlags: u32 {
+- const A = 1;
+- const B = 2;
+- const C = 4;
+- const D = 8;
+- }
+- }
+ }
+diff --git a/third_party/rust/bitflags/tests/basic.rs b/third_party/rust/bitflags/tests/basic.rs
+deleted file mode 100644
+index 73a52bec50b60..0000000000000
+--- a/third_party/rust/bitflags/tests/basic.rs
++++ /dev/null
+@@ -1,20 +0,0 @@
+-#![no_std]
+-
+-use bitflags::bitflags;
+-
+-bitflags! {
+- /// baz
+- struct Flags: u32 {
+- const A = 0b00000001;
+- #[doc = "bar"]
+- const B = 0b00000010;
+- const C = 0b00000100;
+- #[doc = "foo"]
+- const ABC = Flags::A.bits | Flags::B.bits | Flags::C.bits;
+- }
+-}
+-
+-#[test]
+-fn basic() {
+- assert_eq!(Flags::ABC, Flags::A | Flags::B | Flags::C);
+-}
+diff --git a/third_party/rust/bitflags/tests/compile-fail/impls/copy.rs b/third_party/rust/bitflags/tests/compile-fail/impls/copy.rs
+deleted file mode 100644
+index 38f4822f5a5f2..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-fail/impls/copy.rs
++++ /dev/null
+@@ -1,10 +0,0 @@
+-use bitflags::bitflags;
+-
+-bitflags! {
+- #[derive(Clone, Copy)]
+- struct Flags: u32 {
+- const A = 0b00000001;
+- }
+-}
+-
+-fn main() {}
+diff --git a/third_party/rust/bitflags/tests/compile-fail/impls/copy.stderr.beta b/third_party/rust/bitflags/tests/compile-fail/impls/copy.stderr.beta
+deleted file mode 100644
+index 0c13aa5024197..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-fail/impls/copy.stderr.beta
++++ /dev/null
+@@ -1,27 +0,0 @@
+-error[E0119]: conflicting implementations of trait `std::clone::Clone` for type `Flags`
+- --> $DIR/copy.rs:3:1
+- |
+-3 | / bitflags! {
+-4 | | #[derive(Clone, Copy)]
+- | | ----- first implementation here
+-5 | | struct Flags: u32 {
+-6 | | const A = 0b00000001;
+-7 | | }
+-8 | | }
+- | |_^ conflicting implementation for `Flags`
+- |
+- = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+-
+-error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `Flags`
+- --> $DIR/copy.rs:3:1
+- |
+-3 | / bitflags! {
+-4 | | #[derive(Clone, Copy)]
+- | | ---- first implementation here
+-5 | | struct Flags: u32 {
+-6 | | const A = 0b00000001;
+-7 | | }
+-8 | | }
+- | |_^ conflicting implementation for `Flags`
+- |
+- = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
+diff --git a/third_party/rust/bitflags/tests/compile-fail/impls/eq.rs b/third_party/rust/bitflags/tests/compile-fail/impls/eq.rs
+deleted file mode 100644
+index 4abbd630c6e12..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-fail/impls/eq.rs
++++ /dev/null
+@@ -1,10 +0,0 @@
+-use bitflags::bitflags;
+-
+-bitflags! {
+- #[derive(PartialEq, Eq)]
+- struct Flags: u32 {
+- const A = 0b00000001;
+- }
+-}
+-
+-fn main() {}
+diff --git a/third_party/rust/bitflags/tests/compile-fail/impls/eq.stderr.beta b/third_party/rust/bitflags/tests/compile-fail/impls/eq.stderr.beta
+deleted file mode 100644
+index 8a1a3b410a0e0..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-fail/impls/eq.stderr.beta
++++ /dev/null
+@@ -1,55 +0,0 @@
+-error[E0119]: conflicting implementations of trait `std::cmp::PartialEq` for type `Flags`
+- --> $DIR/eq.rs:3:1
+- |
+-3 | / bitflags! {
+-4 | | #[derive(PartialEq, Eq)]
+- | | --------- first implementation here
+-5 | | struct Flags: u32 {
+-6 | | const A = 0b00000001;
+-7 | | }
+-8 | | }
+- | |_^ conflicting implementation for `Flags`
+- |
+- = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
+-
+-error[E0119]: conflicting implementations of trait `std::cmp::Eq` for type `Flags`
+- --> $DIR/eq.rs:3:1
+- |
+-3 | / bitflags! {
+-4 | | #[derive(PartialEq, Eq)]
+- | | -- first implementation here
+-5 | | struct Flags: u32 {
+-6 | | const A = 0b00000001;
+-7 | | }
+-8 | | }
+- | |_^ conflicting implementation for `Flags`
+- |
+- = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+-
+-error[E0119]: conflicting implementations of trait `std::marker::StructuralPartialEq` for type `Flags`
+- --> $DIR/eq.rs:3:1
+- |
+-3 | / bitflags! {
+-4 | | #[derive(PartialEq, Eq)]
+- | | --------- first implementation here
+-5 | | struct Flags: u32 {
+-6 | | const A = 0b00000001;
+-7 | | }
+-8 | | }
+- | |_^ conflicting implementation for `Flags`
+- |
+- = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
+-
+-error[E0119]: conflicting implementations of trait `std::marker::StructuralEq` for type `Flags`
+- --> $DIR/eq.rs:3:1
+- |
+-3 | / bitflags! {
+-4 | | #[derive(PartialEq, Eq)]
+- | | -- first implementation here
+-5 | | struct Flags: u32 {
+-6 | | const A = 0b00000001;
+-7 | | }
+-8 | | }
+- | |_^ conflicting implementation for `Flags`
+- |
+- = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+diff --git a/third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_defined.rs b/third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_defined.rs
+deleted file mode 100644
+index c2856b10830d3..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_defined.rs
++++ /dev/null
+@@ -1,123 +0,0 @@
+-use std::{
+- fmt::{
+- self,
+- Debug,
+- Display,
+- LowerHex,
+- UpperHex,
+- Octal,
+- Binary,
+- },
+- ops::{
+- BitAnd,
+- BitOr,
+- BitXor,
+- BitAndAssign,
+- BitOrAssign,
+- BitXorAssign,
+- Not,
+- },
+-};
+-
+-use bitflags::bitflags;
+-
+-// Ideally we'd actually want this to work, but currently need something like `num`'s `Zero`
+-// With some design work it could be made possible
+-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+-struct MyInt(u8);
+-
+-impl BitAnd for MyInt {
+- type Output = Self;
+-
+- fn bitand(self, other: Self) -> Self {
+- MyInt(self.0 & other.0)
+- }
+-}
+-
+-impl BitOr for MyInt {
+- type Output = Self;
+-
+- fn bitor(self, other: Self) -> Self {
+- MyInt(self.0 | other.0)
+- }
+-}
+-
+-impl BitXor for MyInt {
+- type Output = Self;
+-
+- fn bitxor(self, other: Self) -> Self {
+- MyInt(self.0 ^ other.0)
+- }
+-}
+-
+-impl BitAndAssign for MyInt {
+- fn bitand_assign(&mut self, other: Self) {
+- self.0 &= other.0
+- }
+-}
+-
+-impl BitOrAssign for MyInt {
+- fn bitor_assign(&mut self, other: Self) {
+- self.0 |= other.0
+- }
+-}
+-
+-impl BitXorAssign for MyInt {
+- fn bitxor_assign(&mut self, other: Self) {
+- self.0 ^= other.0
+- }
+-}
+-
+-impl Debug for MyInt {
+- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+- Debug::fmt(&self.0, f)
+- }
+-}
+-
+-impl Display for MyInt {
+- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+- Display::fmt(&self.0, f)
+- }
+-}
+-
+-impl LowerHex for MyInt {
+- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+- LowerHex::fmt(&self.0, f)
+- }
+-}
+-
+-impl UpperHex for MyInt {
+- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+- UpperHex::fmt(&self.0, f)
+- }
+-}
+-
+-impl Octal for MyInt {
+- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+- Octal::fmt(&self.0, f)
+- }
+-}
+-
+-impl Binary for MyInt {
+- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+- Binary::fmt(&self.0, f)
+- }
+-}
+-
+-impl Not for MyInt {
+- type Output = MyInt;
+-
+- fn not(self) -> Self {
+- MyInt(!self.0)
+- }
+-}
+-
+-bitflags! {
+- struct Flags128: MyInt {
+- const A = MyInt(0b0000_0001u8);
+- const B = MyInt(0b0000_0010u8);
+- const C = MyInt(0b0000_0100u8);
+- }
+-}
+-
+-fn main() {}
+diff --git a/third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_defined.stderr.beta b/third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_defined.stderr.beta
+deleted file mode 100644
+index 1f0fb5cf7ad0b..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_defined.stderr.beta
++++ /dev/null
+@@ -1,27 +0,0 @@
+-error[E0308]: mismatched types
+- --> $DIR/all_defined.rs:115:1
+- |
+-115 | / bitflags! {
+-116 | | struct Flags128: MyInt {
+-117 | | const A = MyInt(0b0000_0001u8);
+-118 | | const B = MyInt(0b0000_0010u8);
+-119 | | const C = MyInt(0b0000_0100u8);
+-120 | | }
+-121 | | }
+- | |_^ expected struct `MyInt`, found integer
+- |
+- = note: this error originates in the macro `__impl_all_bitflags` (in Nightly builds, run with -Z macro-backtrace for more info)
+-
+-error[E0308]: mismatched types
+- --> $DIR/all_defined.rs:115:1
+- |
+-115 | / bitflags! {
+-116 | | struct Flags128: MyInt {
+-117 | | const A = MyInt(0b0000_0001u8);
+-118 | | const B = MyInt(0b0000_0010u8);
+-119 | | const C = MyInt(0b0000_0100u8);
+-120 | | }
+-121 | | }
+- | |_^ expected struct `MyInt`, found integer
+- |
+- = note: this error originates in the macro `__impl_bitflags` (in Nightly builds, run with -Z macro-backtrace for more info)
+diff --git a/third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_missing.rs b/third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_missing.rs
+deleted file mode 100644
+index fff6b2cc13062..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_missing.rs
++++ /dev/null
+@@ -1,13 +0,0 @@
+-use bitflags::bitflags;
+-
+-struct MyInt(u8);
+-
+-bitflags! {
+- struct Flags128: MyInt {
+- const A = MyInt(0b0000_0001);
+- const B = MyInt(0b0000_0010);
+- const C = MyInt(0b0000_0100);
+- }
+-}
+-
+-fn main() {}
+diff --git a/third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_missing.stderr.beta b/third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_missing.stderr.beta
+deleted file mode 100644
+index ee95f8365e33e..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_missing.stderr.beta
++++ /dev/null
+@@ -1,13 +0,0 @@
+-error[E0204]: the trait `Copy` may not be implemented for this type
+- --> $DIR/all_missing.rs:5:1
+- |
+-5 | / bitflags! {
+-6 | | struct Flags128: MyInt {
+-7 | | const A = MyInt(0b0000_0001);
+-8 | | const B = MyInt(0b0000_0010);
+-9 | | const C = MyInt(0b0000_0100);
+-10 | | }
+-11 | | }
+- | |_^ this field does not implement `Copy`
+- |
+- = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
+diff --git a/third_party/rust/bitflags/tests/compile-fail/visibility/private_field.rs b/third_party/rust/bitflags/tests/compile-fail/visibility/private_field.rs
+deleted file mode 100644
+index a6a3912aea30a..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-fail/visibility/private_field.rs
++++ /dev/null
+@@ -1,13 +0,0 @@
+-mod example {
+- use bitflags::bitflags;
+-
+- bitflags! {
+- pub struct Flags1: u32 {
+- const FLAG_A = 0b00000001;
+- }
+- }
+-}
+-
+-fn main() {
+- let flag1 = example::Flags1::FLAG_A.bits;
+-}
+diff --git a/third_party/rust/bitflags/tests/compile-fail/visibility/private_field.stderr.beta b/third_party/rust/bitflags/tests/compile-fail/visibility/private_field.stderr.beta
+deleted file mode 100644
+index 58a04660166a8..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-fail/visibility/private_field.stderr.beta
++++ /dev/null
+@@ -1,10 +0,0 @@
+-error[E0616]: field `bits` of struct `Flags1` is private
+- --> $DIR/private_field.rs:12:41
+- |
+-12 | let flag1 = example::Flags1::FLAG_A.bits;
+- | ^^^^ private field
+- |
+-help: a method `bits` also exists, call it with parentheses
+- |
+-12 | let flag1 = example::Flags1::FLAG_A.bits();
+- | ^^
+diff --git a/third_party/rust/bitflags/tests/compile-fail/visibility/private_flags.rs b/third_party/rust/bitflags/tests/compile-fail/visibility/private_flags.rs
+deleted file mode 100644
+index 85a5b1863dd43..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-fail/visibility/private_flags.rs
++++ /dev/null
+@@ -1,18 +0,0 @@
+-mod example {
+- use bitflags::bitflags;
+-
+- bitflags! {
+- pub struct Flags1: u32 {
+- const FLAG_A = 0b00000001;
+- }
+-
+- struct Flags2: u32 {
+- const FLAG_B = 0b00000010;
+- }
+- }
+-}
+-
+-fn main() {
+- let flag1 = example::Flags1::FLAG_A;
+- let flag2 = example::Flags2::FLAG_B;
+-}
+diff --git a/third_party/rust/bitflags/tests/compile-fail/visibility/private_flags.stderr.beta b/third_party/rust/bitflags/tests/compile-fail/visibility/private_flags.stderr.beta
+deleted file mode 100644
+index d23f83209ba90..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-fail/visibility/private_flags.stderr.beta
++++ /dev/null
+@@ -1,18 +0,0 @@
+-error[E0603]: struct `Flags2` is private
+- --> $DIR/private_flags.rs:17:26
+- |
+-17 | let flag2 = example::Flags2::FLAG_B;
+- | ^^^^^^ private struct
+- |
+-note: the struct `Flags2` is defined here
+- --> $DIR/private_flags.rs:4:5
+- |
+-4 | / bitflags! {
+-5 | | pub struct Flags1: u32 {
+-6 | | const FLAG_A = 0b00000001;
+-7 | | }
+-... |
+-11 | | }
+-12 | | }
+- | |_____^
+- = note: this error originates in the macro `bitflags` (in Nightly builds, run with -Z macro-backtrace for more info)
+diff --git a/third_party/rust/bitflags/tests/compile-fail/visibility/pub_const.rs b/third_party/rust/bitflags/tests/compile-fail/visibility/pub_const.rs
+deleted file mode 100644
+index b90f0ce92d1e6..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-fail/visibility/pub_const.rs
++++ /dev/null
+@@ -1,9 +0,0 @@
+-use bitflags::bitflags;
+-
+-bitflags! {
+- pub struct Flags1: u32 {
+- pub const FLAG_A = 0b00000001;
+- }
+-}
+-
+-fn main() {}
+diff --git a/third_party/rust/bitflags/tests/compile-fail/visibility/pub_const.stderr.beta b/third_party/rust/bitflags/tests/compile-fail/visibility/pub_const.stderr.beta
+deleted file mode 100644
+index b01122c7ad879..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-fail/visibility/pub_const.stderr.beta
++++ /dev/null
+@@ -1,5 +0,0 @@
+-error: no rules expected the token `pub`
+- --> $DIR/pub_const.rs:5:9
+- |
+-5 | pub const FLAG_A = 0b00000001;
+- | ^^^ no rules expected this token in macro call
+diff --git a/third_party/rust/bitflags/tests/compile-pass/impls/convert.rs b/third_party/rust/bitflags/tests/compile-pass/impls/convert.rs
+deleted file mode 100644
+index 1f02982a8fa24..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-pass/impls/convert.rs
++++ /dev/null
+@@ -1,17 +0,0 @@
+-use bitflags::bitflags;
+-
+-bitflags! {
+- struct Flags: u32 {
+- const A = 0b00000001;
+- }
+-}
+-
+-impl From<u32> for Flags {
+- fn from(v: u32) -> Flags {
+- Flags::from_bits_truncate(v)
+- }
+-}
+-
+-fn main() {
+-
+-}
+diff --git a/third_party/rust/bitflags/tests/compile-pass/impls/default.rs b/third_party/rust/bitflags/tests/compile-pass/impls/default.rs
+deleted file mode 100644
+index a97b6536f2b58..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-pass/impls/default.rs
++++ /dev/null
+@@ -1,10 +0,0 @@
+-use bitflags::bitflags;
+-
+-bitflags! {
+- #[derive(Default)]
+- struct Flags: u32 {
+- const A = 0b00000001;
+- }
+-}
+-
+-fn main() {}
+diff --git a/third_party/rust/bitflags/tests/compile-pass/impls/inherent_methods.rs b/third_party/rust/bitflags/tests/compile-pass/impls/inherent_methods.rs
+deleted file mode 100644
+index 3052c460ec33a..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-pass/impls/inherent_methods.rs
++++ /dev/null
+@@ -1,15 +0,0 @@
+-use bitflags::bitflags;
+-
+-bitflags! {
+- struct Flags: u32 {
+- const A = 0b00000001;
+- }
+-}
+-
+-impl Flags {
+- pub fn new() -> Flags {
+- Flags::A
+- }
+-}
+-
+-fn main() {}
+diff --git a/third_party/rust/bitflags/tests/compile-pass/redefinition/core.rs b/third_party/rust/bitflags/tests/compile-pass/redefinition/core.rs
+deleted file mode 100644
+index 47549215948d1..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-pass/redefinition/core.rs
++++ /dev/null
+@@ -1,14 +0,0 @@
+-use bitflags::bitflags;
+-
+-// Checks for possible errors caused by overriding names used by `bitflags!` internally.
+-
+-mod core {}
+-mod _core {}
+-
+-bitflags! {
+- struct Test: u8 {
+- const A = 1;
+- }
+-}
+-
+-fn main() {}
+diff --git a/third_party/rust/bitflags/tests/compile-pass/redefinition/stringify.rs b/third_party/rust/bitflags/tests/compile-pass/redefinition/stringify.rs
+deleted file mode 100644
+index b04f2f6a49332..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-pass/redefinition/stringify.rs
++++ /dev/null
+@@ -1,19 +0,0 @@
+-use bitflags::bitflags;
+-
+-// Checks for possible errors caused by overriding names used by `bitflags!` internally.
+-
+-#[allow(unused_macros)]
+-macro_rules! stringify {
+- ($($t:tt)*) => { "..." };
+-}
+-
+-bitflags! {
+- struct Test: u8 {
+- const A = 1;
+- }
+-}
+-
+-fn main() {
+- // Just make sure we don't call the redefined `stringify` macro
+- assert_eq!(format!("{:?}", Test::A), "A");
+-}
+diff --git a/third_party/rust/bitflags/tests/compile-pass/repr/c.rs b/third_party/rust/bitflags/tests/compile-pass/repr/c.rs
+deleted file mode 100644
+index 6feba36ed82c1..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-pass/repr/c.rs
++++ /dev/null
+@@ -1,10 +0,0 @@
+-use bitflags::bitflags;
+-
+-bitflags! {
+- #[repr(C)]
+- struct Flags: u32 {
+- const A = 0b00000001;
+- }
+-}
+-
+-fn main() {}
+diff --git a/third_party/rust/bitflags/tests/compile-pass/repr/transparent.rs b/third_party/rust/bitflags/tests/compile-pass/repr/transparent.rs
+deleted file mode 100644
+index e38db4dd11b99..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-pass/repr/transparent.rs
++++ /dev/null
+@@ -1,10 +0,0 @@
+-use bitflags::bitflags;
+-
+-bitflags! {
+- #[repr(transparent)]
+- struct Flags: u32 {
+- const A = 0b00000001;
+- }
+-}
+-
+-fn main() {}
+diff --git a/third_party/rust/bitflags/tests/compile-pass/visibility/bits_field.rs b/third_party/rust/bitflags/tests/compile-pass/visibility/bits_field.rs
+deleted file mode 100644
+index 33a7967e629ef..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-pass/visibility/bits_field.rs
++++ /dev/null
+@@ -1,11 +0,0 @@
+-use bitflags::bitflags;
+-
+-bitflags! {
+- pub struct Flags1: u32 {
+- const FLAG_A = 0b00000001;
+- }
+-}
+-
+-fn main() {
+- assert_eq!(0b00000001, Flags1::FLAG_A.bits);
+-}
+diff --git a/third_party/rust/bitflags/tests/compile-pass/visibility/pub_in.rs b/third_party/rust/bitflags/tests/compile-pass/visibility/pub_in.rs
+deleted file mode 100644
+index c11050e3baf0c..0000000000000
+--- a/third_party/rust/bitflags/tests/compile-pass/visibility/pub_in.rs
++++ /dev/null
+@@ -1,19 +0,0 @@
+-mod a {
+- mod b {
+- use bitflags::bitflags;
+-
+- bitflags! {
+- pub(in crate::a) struct Flags: u32 {
+- const FLAG_A = 0b00000001;
+- }
+- }
+- }
+-
+- pub fn flags() -> u32 {
+- b::Flags::FLAG_A.bits()
+- }
+-}
+-
+-fn main() {
+- assert_eq!(0b00000001, a::flags());
+-}
+diff --git a/third_party/rust/bitflags/tests/compile.rs b/third_party/rust/bitflags/tests/compile.rs
+deleted file mode 100644
+index ed02d01e9ca1b..0000000000000
+--- a/third_party/rust/bitflags/tests/compile.rs
++++ /dev/null
+@@ -1,63 +0,0 @@
+-use std::{
+- fs,
+- ffi::OsStr,
+- io,
+- path::Path,
+-};
+-
+-use walkdir::WalkDir;
+-
+-#[test]
+-fn fail() {
+- prepare_stderr_files("tests/compile-fail").unwrap();
+-
+- let t = trybuild::TestCases::new();
+- t.compile_fail("tests/compile-fail/**/*.rs");
+-}
+-
+-#[test]
+-fn pass() {
+- let t = trybuild::TestCases::new();
+- t.pass("tests/compile-pass/**/*.rs");
+-}
+-
+-// Compiler messages may change between versions
+-// We don't want to have to track these too closely for `bitflags`, but
+-// having some message to check makes sure user-facing errors are sensical.
+-//
+-// The approach we use is to run the test on all compilers, but only check stderr
+-// output on beta (which is the next stable release). We do this by default ignoring
+-// any `.stderr` files in the `compile-fail` directory, and copying `.stderr.beta` files
+-// when we happen to be running on a beta compiler.
+-fn prepare_stderr_files(path: impl AsRef<Path>) -> io::Result<()> {
+- for entry in WalkDir::new(path) {
+- let entry = entry?;
+-
+- if entry.path().extension().and_then(OsStr::to_str) == Some("beta") {
+- let renamed = entry.path().with_extension("");
+-
+- // Unconditionally remove a corresponding `.stderr` file for a `.stderr.beta`
+- // file if it exists. On `beta` compilers, we'll recreate it. On other compilers,
+- // we don't want to end up checking it anyways.
+- if renamed.exists() {
+- fs::remove_file(&renamed)?;
+- }
+-
+- rename_beta_stderr(entry.path(), renamed)?;
+- }
+- }
+-
+- Ok(())
+-}
+-
+-#[rustversion::beta]
+-fn rename_beta_stderr(from: impl AsRef<Path>, to: impl AsRef<Path>) -> io::Result<()> {
+- fs::copy(from, to)?;
+-
+- Ok(())
+-}
+-
+-#[rustversion::not(beta)]
+-fn rename_beta_stderr(_: impl AsRef<Path>, _: impl AsRef<Path>) -> io::Result<()> {
+- Ok(())
+-}
+diff --git a/third_party/rust/midir/.cargo-checksum.json b/third_party/rust/midir/.cargo-checksum.json
+index 390b25b1e0118..34b17c2c5c548 100644
+--- a/third_party/rust/midir/.cargo-checksum.json
++++ b/third_party/rust/midir/.cargo-checksum.json
+@@ -1 +1 @@
+-{"files":{"CHANGELOG.md":"10db6f8dbb1c5566e75f2eeda6b2ee8bb44fe4a76f57e0bfb98c62f7f8c04f89","Cargo.toml":"41aa086ea813af75458515ff515917bb48d20eaef42a74352ea12ff8d5d16bce","LICENSE":"6fe6f623b1fa80e90679aee2f917d8978a184988ebb995ebc254cc9633903cac","README.md":"4131b953217e77a4463fde307ba3262b4df11732c1ff209668df12dff3c73ffc","azure-pipelines-template.yml":"c787791a94e654226a299aaa875fcc48f6eedf4dae631855cb5a7067891dbe3a","azure-pipelines.yml":"1b4fab0afacc66732a385cb6e5b213c170fc9717219a03ccda9c5db78cd461dd","examples/test_forward.rs":"6cb060aba7e8c39eaf53ea95a72d4c7939ffb4bebc82c291135fdc35495078ce","examples/test_list_ports.rs":"41ba21ab1e56d76206abc8b291d27050cb1a788372f00f6761c78f03fb5981ff","examples/test_play.rs":"22630e46af9628d8193ad8e19ff095ad02542b7ab697be4e513da78210ad5c0c","examples/test_read_input.rs":"4901f18435c3f8021750ccd4687abe92194ab38f1e7721896a6a31f6650d524c","examples/test_reuse.rs":"fdb3b430aec42c7c648fbecf22e6c726ef8a20638936a1a70fb373dff94c0632","examples/test_sysex.rs":"ea06427a644c3639f1c49271be5d16c9d3890d3741eb6ebf2ff64d2f7fd36e96","src/backend/alsa/mod.rs":"6bc784435247c3302bf12c3f558b6027abfbec997a280baa113c7344e5b0479f","src/backend/coremidi/mod.rs":"f827cbc5db7086ea58c5927213a2c3e0246244d5939c2ba0ff787caae7089511","src/backend/jack/mod.rs":"8f2eace3e9046ec6de8c7fc37d3502d2b971a73fe2a96e5c2a423d51445f1505","src/backend/jack/wrappers.rs":"f18718f234e41c91bb5463546fbbe61be64e9581a4fae6ef2de20cafae487298","src/backend/mod.rs":"1a8106889ecd053af27b3a72515bfb286da1b08bb90909fa6d4e7b816b50c447","src/backend/webmidi/mod.rs":"4af5b288833ee99f047a638b368eca293f89356f1e82147c9a9c1633d950955d","src/backend/winmm/handler.rs":"45b36067fd280a38943f385d3d7f6885d7448153f53e9c8f66b58b484535ad1c","src/backend/winmm/mod.rs":"94d8c57fd2d327993d01ef06d8c68190c528fe52dd39e6b97c88d9f1f0afa753","src/backend/winrt/mod.rs":"ca7ac4ac310e7f6a6c28dd6374bfe97b38ed8656c7ca343494264cce45f93ae6","src/common.rs":"2cab2e987428522ca601544b516b64b858859730fbd1be0e53c828e82025319d","src/errors.rs":"495ba80f9dcfeefd343b460b74549b12cb1825c3e1b315848f859d0b4d66ddbe","src/lib.rs":"ecde030ca02a90a99577cd71446857a2c00aee8ff1bc7890c54a5d0d22d2be2c","src/os/mod.rs":"507dfa95e57805c489a883dcf9efddcb718d5178267f296294f72b3c397c12c7","src/os/unix.rs":"a1977659d270fcf31111d4446b949d2760d76e2077639e6008d634800861b77b","tests/virtual.rs":"b47501eeb313f3e255d2d1888c333ff994d958865272929fe7bf116be45b6805"},"package":null}
+\ No newline at end of file
++{"files":{"CHANGELOG.md":"10db6f8dbb1c5566e75f2eeda6b2ee8bb44fe4a76f57e0bfb98c62f7f8c04f89","Cargo.toml":"792c11a1ab6ce0443cb040994b02f1e80e07d19e6bf59f683a7fb227539bc028","LICENSE":"6fe6f623b1fa80e90679aee2f917d8978a184988ebb995ebc254cc9633903cac","README.md":"4131b953217e77a4463fde307ba3262b4df11732c1ff209668df12dff3c73ffc","azure-pipelines-template.yml":"c787791a94e654226a299aaa875fcc48f6eedf4dae631855cb5a7067891dbe3a","azure-pipelines.yml":"1b4fab0afacc66732a385cb6e5b213c170fc9717219a03ccda9c5db78cd461dd","examples/test_forward.rs":"6cb060aba7e8c39eaf53ea95a72d4c7939ffb4bebc82c291135fdc35495078ce","examples/test_list_ports.rs":"41ba21ab1e56d76206abc8b291d27050cb1a788372f00f6761c78f03fb5981ff","examples/test_play.rs":"22630e46af9628d8193ad8e19ff095ad02542b7ab697be4e513da78210ad5c0c","examples/test_read_input.rs":"4901f18435c3f8021750ccd4687abe92194ab38f1e7721896a6a31f6650d524c","examples/test_reuse.rs":"fdb3b430aec42c7c648fbecf22e6c726ef8a20638936a1a70fb373dff94c0632","examples/test_sysex.rs":"ea06427a644c3639f1c49271be5d16c9d3890d3741eb6ebf2ff64d2f7fd36e96","src/backend/alsa/mod.rs":"6bc784435247c3302bf12c3f558b6027abfbec997a280baa113c7344e5b0479f","src/backend/coremidi/mod.rs":"f827cbc5db7086ea58c5927213a2c3e0246244d5939c2ba0ff787caae7089511","src/backend/jack/mod.rs":"8f2eace3e9046ec6de8c7fc37d3502d2b971a73fe2a96e5c2a423d51445f1505","src/backend/jack/wrappers.rs":"f18718f234e41c91bb5463546fbbe61be64e9581a4fae6ef2de20cafae487298","src/backend/mod.rs":"1a8106889ecd053af27b3a72515bfb286da1b08bb90909fa6d4e7b816b50c447","src/backend/webmidi/mod.rs":"4af5b288833ee99f047a638b368eca293f89356f1e82147c9a9c1633d950955d","src/backend/winmm/handler.rs":"45b36067fd280a38943f385d3d7f6885d7448153f53e9c8f66b58b484535ad1c","src/backend/winmm/mod.rs":"94d8c57fd2d327993d01ef06d8c68190c528fe52dd39e6b97c88d9f1f0afa753","src/backend/winrt/mod.rs":"ca7ac4ac310e7f6a6c28dd6374bfe97b38ed8656c7ca343494264cce45f93ae6","src/common.rs":"2cab2e987428522ca601544b516b64b858859730fbd1be0e53c828e82025319d","src/errors.rs":"495ba80f9dcfeefd343b460b74549b12cb1825c3e1b315848f859d0b4d66ddbe","src/lib.rs":"ecde030ca02a90a99577cd71446857a2c00aee8ff1bc7890c54a5d0d22d2be2c","src/os/mod.rs":"507dfa95e57805c489a883dcf9efddcb718d5178267f296294f72b3c397c12c7","src/os/unix.rs":"a1977659d270fcf31111d4446b949d2760d76e2077639e6008d634800861b77b","tests/virtual.rs":"b47501eeb313f3e255d2d1888c333ff994d958865272929fe7bf116be45b6805"},"package":null}
+\ No newline at end of file
+diff --git a/third_party/rust/midir/Cargo.toml b/third_party/rust/midir/Cargo.toml
+index 49089e0ffe86e..ac48aab304db9 100644
+--- a/third_party/rust/midir/Cargo.toml
++++ b/third_party/rust/midir/Cargo.toml
+@@ -28,8 +28,8 @@ libc = { version = "0.2.21", optional = true }
+ winrt = { version = "0.7.0", optional = true}
+
+ [target.'cfg(target_os = "linux")'.dependencies]
+-alsa = "0.4.3"
+-nix = "0.15"
++alsa = "0.5.0"
++nix = "0.20"
+ libc = "0.2.21"
+
+ [target.'cfg(target_os = "macos")'.dependencies]
+diff --git a/third_party/rust/nix-0.15.0/.cargo-checksum.json b/third_party/rust/nix-0.15.0/.cargo-checksum.json
+new file mode 100644
+index 0000000000000..e5f2bc789185a
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/.cargo-checksum.json
+@@ -0,0 +1 @@
++{"files":{"CHANGELOG.md":"91af9fd5f2d9cdb9c8bb750e24b625742e95a6c74bcff419f3de70eb26578281","CONTRIBUTING.md":"a9101e3d1487170d691d5f062ff49a433c167582ac8984dd41a744be92652f74","CONVENTIONS.md":"e150ce43c1d188c392c1a3bf7f2e08e3cf84906705c7bef43f319037d29ea385","Cargo.toml":"af0cc0ae7ff4bf6c2e5b35fe062f54fe2d619f70ba67795f4f43a981420b5de0","LICENSE":"66e3ee1fa7f909ad3c612d556f2a0cdabcd809ad6e66f3b0605015ac64841b70","README.md":"80d71b9eaac7bf7f0d307372592ed1467f994291e6fad816a44f3c70e2887d0f","build.rs":"14c9c678c33f5894509da47f77d6a326b14aecb4190ce87a24cce98687ca63b2","src/dir.rs":"21e330cbe6594274335b94d9e9b6059f1fa8e53d2e5b5c697058c52ec6b3c5ff","src/errno.rs":"a009ccf18b45c0a4c9319c65b0dc5bc322d9ad43cfe462ec4661559f44162451","src/errno_dragonfly.c":"a857e47b114acb85fddcb252a610ab5734d225c26b7bedd7c35d7789d46c8526","src/fcntl.rs":"6ae2f7f01dd2568b82a4e57f86e02b1d63eec6c26111c5adb2ca5d78a2a99fe7","src/features.rs":"22ff626ff8287a07dd55bcfc63c9f518c19c56144e15f9b6f9e3bbdcda51c2a8","src/ifaddrs.rs":"9a93de176edcca4613e668b8ccc2c3e3b6b711aa2d8d94ccb0ba08694d1ef35f","src/kmod.rs":"4d8a695d3d761f351a39d654303a1bd168e74295b7d142b918737e355b24f34d","src/lib.rs":"fdd8049a79ffb92384c72f0a6b0bab717001ddfa9b01f2b33413c83f424f2ac8","src/macros.rs":"aec27fa0fd98900913fada926c9a4581cd28f2640e3a7b5480707f923c9200f8","src/mount.rs":"cdf5db8409017483132db9d7493b5d6cc96df5560d0fa5ad8f385aff72db10ca","src/mqueue.rs":"82af42b31381af73e7966f845d1ed93957f0b9976bf2da524b178fad15b2b08d","src/net/if_.rs":"f7e02076fcf3cadf3fdf141884c9bd2c468a7047ba60bc490f0057df802b53ce","src/net/mod.rs":"577f70170e53d4a6de1abb70bf8f1031ec3e65c0e63ef5fcf05c907125e7ac17","src/poll.rs":"7305e250066cd1a7318cd239ed3db787937ee98426fe9289cf00fa874d76b6c7","src/pty.rs":"6b965b586579933af47d4efef4c82c391b927037eaa08d8c83fc974ef17fc7c8","src/sched.rs":"f9b214fa60006b5450ffb3589a55ec59c3694bd49597c65c38ac813fcd96c7dd","src/sys/aio.rs":"a1ba629258b3ce1268e5fe8e5b41dce3581f77d415dc5e2455c1f82f26dd3085","src/sys/epoll.rs":"f0b539e0645569657f2142db91a38c94ebe1925f44852d64c61c818758dbbf0b","src/sys/event.rs":"ef8bc02a08d9ce7924c87f8f891fa051587b195a36913712fe85237a2fe0685b","src/sys/eventfd.rs":"08008cf3dc64c2216847c02c0dd8d7189cf08edbaafe35ba2c57c053fde09ef4","src/sys/inotify.rs":"687c8417d737939aa93f805d6003afc4f84f50828b1bd9429ef5d00bef0e0955","src/sys/ioctl/bsd.rs":"56ca6ecf5f7cfb566f4f3ba589fcc778f747a517dd45e13780981922e6215344","src/sys/ioctl/linux.rs":"6cfbdff4dbfa1a3782acdedebe89ffa9f000fdfc4ab68cb46f52890ebc1c6f2d","src/sys/ioctl/mod.rs":"20bc3cf1fcbbc7c31e4d507baa4e576a793ea42fb33618d2e7afeda730c4324f","src/sys/memfd.rs":"11cd93c867fdbdbc9588cecb94268691de42b2ef2a38fe33525be7c7f60c85d5","src/sys/mman.rs":"f77d28611a7ff3bf62784a3c4f26d7d79969395b1d9bbc6ff15e734f52dc404f","src/sys/mod.rs":"f39a08c72e37638c7cecfb9c087e0a41e2b69409aa545b0ef7bbd59c0a063ee2","src/sys/pthread.rs":"cfa9ccd6f3b86c0c3fe012773c9c82a7813b298c2f20f8ab629781db627ce56b","src/sys/ptrace/bsd.rs":"8a7eacfc172b55763ae32109bf9b252669ba68b72cd5122f7504eb35c0c08345","src/sys/ptrace/linux.rs":"f09b45148004f4b28d8503c397a8d112d31046c98e68335bf4e89425d5b33f07","src/sys/ptrace/mod.rs":"671a6ccac955e75d5998f7e53ffc45ed4c7b6522a0f24a0937d60141f692dd39","src/sys/quota.rs":"7eb8e797466b506f6ed882f18eda92c4639cf43d9384a19bc39cd1bf982989c9","src/sys/reboot.rs":"fde9da27c2928f7026231430fa14fec2058df4e49a0aeda2a237a60524f11241","src/sys/select.rs":"57d6c4403d1bf788bd52ab6f03cfc16a189d31b6bfb338b135cb775fe369121f","src/sys/sendfile.rs":"ea386e83baf9b5b23488aca26635aacdc92f2bfe238e4399a7380bd0331e0ef7","src/sys/signal.rs":"9216cdd609b4dfb9c2e559c411be6b7c722f7ddd8024682c0895a32126b488aa","src/sys/signalfd.rs":"bfcfce619bf199e50f9cc80a3eb778d48474a015cfdafc64a0c3517373a225a9","src/sys/socket/addr.rs":"8b297ce13cd8ad200b3e764888c26ceb582ee505385d1e172440de94ade99644","src/sys/socket/mod.rs":"e0353f04f3d098a8bf5e2aae431645897b96e0889fb76537dc0330159c6f233d","src/sys/socket/sockopt.rs":"c663505d6a7a7ae9d76e03fbc17e53d308ea6b1eae92212812e1d76b2bf2916f","src/sys/stat.rs":"c4807048f86be67026756737cf81f448ec23c2a4745776cb40f40b533a88e0c8","src/sys/statfs.rs":"d2b72069f20aa7782ce5de4ec2d00c76a82a92376c2066bbb270cdac2167719e","src/sys/statvfs.rs":"2d328cf525ba04ab1e1351128624a7df7d0c55ea91fda6c8d620d13710d61606","src/sys/sysinfo.rs":"0c05244655aa9e6dff5138392c5c1ae97630d35bae0e5510d7f51a75c31fd425","src/sys/termios.rs":"a2e99afdfc3526641a2cb82b57bfd0a25a362fb9be5ad37ff9f11acaeb0b9439","src/sys/time.rs":"8a1224b9262026086af698630aedbed21b45d661fbd045fc6c6af41a16a23374","src/sys/uio.rs":"60a974275ff8c485ea183bdd6f7e25894e6f2360a5bfb25442391a825a3b9b8c","src/sys/utsname.rs":"c977a1aec6e051c72b27506395e942abab9cbd9523e6d345ea66dc10875ee87d","src/sys/wait.rs":"30b14a8f518d031805cae6c6ff644116f162d8c8a75fddcfce4479d8d55fd1c0","src/ucontext.rs":"075560ec08a362881534211f8c6b78844886d6b767c2f7067174600e38ed3f63","src/unistd.rs":"82308ec31b6293b55f86fafd04e976a41127fedebb8f158abd1399c7399af947","test/sys/mod.rs":"e0821cbc289ad952f17229609c7de4282cca1e44cd13e1a7494a6378ecbc12f8","test/sys/test_aio.rs":"b2544bfb321ca7fbed276ee637c769fb438156d14666cdc1e1d547b3514a44e3","test/sys/test_aio_drop.rs":"30dd1d238269d00381fa50f6d3cb2b13794b7cceb9f6455f3878fcbffa9aa62d","test/sys/test_epoll.rs":"35093d0cb1096a934dfc4f6efc737eadc4bdc2e2134d2a879061374a51b10c97","test/sys/test_inotify.rs":"a4f804bcf414b6635d9863c8534769a609009c451c3476cc839cdc30c439b3b1","test/sys/test_ioctl.rs":"eea690ed386da0a666df5eb23a417421fddb99dc8e39556f63b30969bb6cf779","test/sys/test_lio_listio_resubmit.rs":"203a583313542593148f375b087ae30620222a745680173fa98fc448d1e5ae7f","test/sys/test_pthread.rs":"3890e5ecbf2082e0d05d102cc9cec6e76ede3c15f250d104e3483b1c1c3400b1","test/sys/test_ptrace.rs":"4e8d5dff5fe6bc56e4ae53bdfd10f5e8ea567d8099576d1c690cf7a6b2bc955f","test/sys/test_select.rs":"bdb20211fc6ec1e3f186337eac51e08757acb6901d307d67c71bf9011f0d54bd","test/sys/test_signal.rs":"84ae63c2baa49eebeabe5bbd347b9c5417e14ba97f342719d753dc1c1c768d60","test/sys/test_signalfd.rs":"71b5d6d782283f6db64ca90f7fb06617faec71091d59d2587e41bbc9d8c43d5c","test/sys/test_socket.rs":"09a7ef0322e07b4579893e0307a7c4f81fbbc653d005b827a519c33a33e185ce","test/sys/test_sockopt.rs":"b3d386c8279f86bf9439c772317bafcdba5630fa806c8319e87ddac0ccfa3a03","test/sys/test_sysinfo.rs":"1e1bea9130fe38ccb07cd0ad7334c7be1e45efc33f7656a5973f8cad7126f225","test/sys/test_termios.rs":"fa4be3ade859b527bf33408f85a6f57b127917cf5f2afb662d09f6019d07913a","test/sys/test_uio.rs":"9da234e3bd5003fd200cc37c4a5be147ecda1a7670feb1d505f23d646d3e1c57","test/sys/test_wait.rs":"e6c5147e213daa93892cd828f53214995d2e019ff2372cc48d85ce9b93d26ec9","test/test.rs":"e6307f82a39426a949b8e925a2df4a62e31c0e43081d7a33d23759bdfeeece1f","test/test_dir.rs":"5d137a62f11d1a4993b4bb35dccc38a4c4416b7da374887f2335a9895b4fdee4","test/test_fcntl.rs":"730e64e99dc867ba5af7cc4ca83a4489c8b96b1a52f8937bcc666d673af27002","test/test_kmod/hello_mod/Makefile":"0219f7bce0603f97d997fb377ca071966c90333ecc665e78a54dfeb97a9c811b","test/test_kmod/hello_mod/hello.c":"bcac6b19c5bd807e1f3878c15e426acc85785a8ade9840c3bb4d068635c9188c","test/test_kmod/mod.rs":"f4754f028402a8ba788c87686288424cd3784e77c7eb5d96682ef491b1dd5262","test/test_mount.rs":"78ddc657f5098360c764fffa3a7d844503e4b6b65b44bfd42d9aa9045b415cb6","test/test_mq.rs":"5806f8825e91edc79dd0e2bc81d8be3ba094c2de6c0b2ac0268221ae2ad22701","test/test_net.rs":"ec6d580b87292519d514b0236bdd5abdd576fcf4835cfe49ed1ddb47c5f1aea3","test/test_nix_path.rs":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","test/test_poll.rs":"46c71ee988fe1b85561ea0530d099750be8c1b8f95ab6e845c8a9f46f16f060c","test/test_pty.rs":"be04f99904fa47b60400c2bd156a388b73df4b9aec2eebf13df7dcdfc9aacf45","test/test_ptymaster_drop.rs":"5cfbbb79551c205ab510c2d4ef497bf937ceac9151fbe2f2e543d6515e406990","test/test_sendfile.rs":"e0cbabbd34052ccaa03d6555d5631686aa076728f6378ee90f7ecec68f891144","test/test_stat.rs":"1dc420d3119bf4d863a7ae0ba63efa7f1416f6e46e4100ea161003fe1c3f66ba","test/test_unistd.rs":"0325c998acca1e826e9e2b3d351d55ab9723a6cb2ca2072245978e7f5a9acee8"},"package":"3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229"}
+\ No newline at end of file
+diff --git a/third_party/rust/nix-0.15.0/CHANGELOG.md b/third_party/rust/nix-0.15.0/CHANGELOG.md
+new file mode 100644
+index 0000000000000..d93a5ce6bbfc9
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/CHANGELOG.md
+@@ -0,0 +1,742 @@
++# Change Log
++
++All notable changes to this project will be documented in this file.
++This project adheres to [Semantic Versioning](http://semver.org/).
++
++## [Unreleased] - ReleaseDate
++### Added
++### Changed
++### Fixed
++### Removed
++
++## [0.15.0] - 10 August 2019
++### Added
++- Added `MSG_WAITALL` to `MsgFlags` in `sys::socket`.
++ ([#1079](https://github.com/nix-rust/nix/pull/1079))
++- Implemented `Clone`, `Copy`, `Debug`, `Eq`, `Hash`, and `PartialEq` for most
++ types that support them. ([#1035](https://github.com/nix-rust/nix/pull/1035))
++- Added `copy_file_range` wrapper
++ ([#1069](https://github.com/nix-rust/nix/pull/1069))
++- Add `mkdirat`.
++ ([#1084](https://github.com/nix-rust/nix/pull/1084))
++- Add `posix_fadvise`.
++ ([#1089](https://github.com/nix-rust/nix/pull/1089))
++- Added `AF_VSOCK` to `AddressFamily`.
++ ([#1091](https://github.com/nix-rust/nix/pull/1091))
++- Add `unlinkat`
++ ([#1058](https://github.com/nix-rust/nix/pull/1058))
++- Add `renameat`.
++ ([#1097](https://github.com/nix-rust/nix/pull/1097))
++
++### Changed
++- Support for `ifaddrs` now present when building for Android.
++ ([#1077](https://github.com/nix-rust/nix/pull/1077))
++- Minimum supported Rust version is now 1.31.0
++ ([#1035](https://github.com/nix-rust/nix/pull/1035))
++ ([#1095](https://github.com/nix-rust/nix/pull/1095))
++- Now functions `statfs()` and `fstatfs()` return result with `Statfs` wrapper
++ ([#928](https://github.com/nix-rust/nix/pull/928))
++
++### Fixed
++- Enabled `sched_yield` for all nix hosts.
++ ([#1090](https://github.com/nix-rust/nix/pull/1090))
++
++### Removed
++
++## [0.14.1] - 2019-06-06
++### Added
++- Macros exported by `nix` may now be imported via `use` on the Rust 2018
++ edition without importing helper macros on Linux targets.
++ ([#1066](https://github.com/nix-rust/nix/pull/1066))
++
++ For example, in Rust 2018, the `ioctl_read_bad!` macro can now be imported
++ without importing the `convert_ioctl_res!` macro.
++
++ ```rust
++ use nix::ioctl_read_bad;
++
++ ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios);
++ ```
++
++### Changed
++- Changed some public types from reexports of libc types like `uint32_t` to the
++ native equivalents like `u32.`
++ ([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
++
++### Fixed
++- Fix the build on Android and Linux/mips with recent versions of libc.
++ ([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
++
++### Removed
++
++## [0.14.0] - 2019-05-21
++### Added
++- Add IP_RECVIF & IP_RECVDSTADDR. Enable IP_PKTINFO and IP6_PKTINFO on netbsd/openbsd.
++ ([#1002](https://github.com/nix-rust/nix/pull/1002))
++- Added `inotify_init1`, `inotify_add_watch` and `inotify_rm_watch` wrappers for
++ Android and Linux. ([#1016](https://github.com/nix-rust/nix/pull/1016))
++- Add `ALG_SET_IV`, `ALG_SET_OP` and `ALG_SET_AEAD_ASSOCLEN` control messages and `AF_ALG`
++ socket types on Linux and Android ([#1031](https://github.com/nix-rust/nix/pull/1031))
++- Add killpg
++ ([#1034](https://github.com/nix-rust/nix/pull/1034))
++- Added ENOTSUP errno support for Linux and Android.
++ ([#969](https://github.com/nix-rust/nix/pull/969))
++- Add several errno constants from OpenBSD 6.2
++ ([#1036](https://github.com/nix-rust/nix/pull/1036))
++- Added `from_std` and `to_std` methods for `sys::socket::IpAddr`
++ ([#1043](https://github.com/nix-rust/nix/pull/1043))
++- Added `nix::unistd:seteuid` and `nix::unistd::setegid` for those platforms that do
++ not support `setresuid` nor `setresgid` respectively.
++ ([#1044](https://github.com/nix-rust/nix/pull/1044))
++- Added a `access` wrapper
++ ([#1045](https://github.com/nix-rust/nix/pull/1045))
++- Add `forkpty`
++ ([#1042](https://github.com/nix-rust/nix/pull/1042))
++- Add `sched_yield`
++ ([#1050](https://github.com/nix-rust/nix/pull/1050))
++
++### Changed
++- `PollFd` event flags renamed to `PollFlags` ([#1024](https://github.com/nix-rust/nix/pull/1024/))
++- `recvmsg` now returns an Iterator over `ControlMessageOwned` objects rather
++ than `ControlMessage` objects. This is sadly not backwards-compatible. Fix
++ code like this:
++ ```rust
++ if let ControlMessage::ScmRights(&fds) = cmsg {
++ ```
++
++ By replacing it with code like this:
++ ```rust
++ if let ControlMessageOwned::ScmRights(fds) = cmsg {
++ ```
++ ([#1020](https://github.com/nix-rust/nix/pull/1020))
++- Replaced `CmsgSpace` with the `cmsg_space` macro.
++ ([#1020](https://github.com/nix-rust/nix/pull/1020))
++
++### Fixed
++- Fixed multiple bugs when using `sendmsg` and `recvmsg` with ancillary control messages
++ ([#1020](https://github.com/nix-rust/nix/pull/1020))
++- Macros exported by `nix` may now be imported via `use` on the Rust 2018
++ edition without importing helper macros for BSD targets.
++ ([#1041](https://github.com/nix-rust/nix/pull/1041))
++
++ For example, in Rust 2018, the `ioctl_read_bad!` macro can now be imported
++ without importing the `convert_ioctl_res!` macro.
++
++ ```rust
++ use nix::ioctl_read_bad;
++
++ ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios);
++ ```
++
++### Removed
++- `Daemon`, `NOTE_REAP`, and `NOTE_EXIT_REPARENTED` are now deprecated on OSX
++ and iOS.
++ ([#1033](https://github.com/nix-rust/nix/pull/1033))
++- `PTRACE_GETREGS`, `PTRACE_SETREGS`, `PTRACE_GETFPREGS`, and
++ `PTRACE_SETFPREGS` have been removed from some platforms where they never
++ should've been defined in the first place.
++ ([#1055](https://github.com/nix-rust/nix/pull/1055))
++
++## [0.13.0] - 2019-01-15
++### Added
++- Added PKTINFO(V4) & V6PKTINFO cmsg support - Android/FreeBSD/iOS/Linux/MacOS.
++ ([#990](https://github.com/nix-rust/nix/pull/990))
++- Added support of CString type in `setsockopt`.
++ ([#972](https://github.com/nix-rust/nix/pull/972))
++- Added option `TCP_CONGESTION` in `setsockopt`.
++ ([#972](https://github.com/nix-rust/nix/pull/972))
++- Added `symlinkat` wrapper.
++ ([#997](https://github.com/nix-rust/nix/pull/997))
++- Added `ptrace::{getregs, setregs}`.
++ ([#1010](https://github.com/nix-rust/nix/pull/1010))
++- Added `nix::sys::signal::signal`.
++ ([#817](https://github.com/nix-rust/nix/pull/817))
++- Added an `mprotect` wrapper.
++ ([#991](https://github.com/nix-rust/nix/pull/991))
++
++### Changed
++### Fixed
++- `lutimes` never worked on OpenBSD as it is not implemented on OpenBSD. It has
++ been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000))
++- `fexecve` never worked on NetBSD or on OpenBSD as it is not implemented on
++ either OS. It has been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000))
++
++### Removed
++
++## [0.12.0] 2018-11-28
++
++### Added
++- Added `FromStr` and `Display` impls for `nix::sys::Signal`
++ ([#884](https://github.com/nix-rust/nix/pull/884))
++- Added a `sync` wrapper.
++ ([#961](https://github.com/nix-rust/nix/pull/961))
++- Added a `sysinfo` wrapper.
++ ([#922](https://github.com/nix-rust/nix/pull/922))
++- Support the `SO_PEERCRED` socket option and the `UnixCredentials` type on all Linux and Android targets.
++ ([#921](https://github.com/nix-rust/nix/pull/921))
++- Added support for `SCM_CREDENTIALS`, allowing to send process credentials over Unix sockets.
++ ([#923](https://github.com/nix-rust/nix/pull/923))
++- Added a `dir` module for reading directories (wraps `fdopendir`, `readdir`, and `rewinddir`).
++ ([#916](https://github.com/nix-rust/nix/pull/916))
++- Added `kmod` module that allows loading and unloading kernel modules on Linux.
++ ([#930](https://github.com/nix-rust/nix/pull/930))
++- Added `futimens` and `utimesat` wrappers ([#944](https://github.com/nix-rust/nix/pull/944)),
++ an `lutimes` wrapper ([#967](https://github.com/nix-rust/nix/pull/967)),
++ and a `utimes` wrapper ([#946](https://github.com/nix-rust/nix/pull/946)).
++- Added `AF_UNSPEC` wrapper to `AddressFamily` ([#948](https://github.com/nix-rust/nix/pull/948))
++- Added the `mode_t` public alias within `sys::stat`.
++ ([#954](https://github.com/nix-rust/nix/pull/954))
++- Added a `truncate` wrapper.
++ ([#956](https://github.com/nix-rust/nix/pull/956))
++- Added a `fchownat` wrapper.
++ ([#955](https://github.com/nix-rust/nix/pull/955))
++- Added support for `ptrace` on BSD operating systems ([#949](https://github.com/nix-rust/nix/pull/949))
++- Added `ptrace` functions for reads and writes to tracee memory and ptrace kill
++ ([#949](https://github.com/nix-rust/nix/pull/949)) ([#958](https://github.com/nix-rust/nix/pull/958))
++- Added a `acct` wrapper module for enabling and disabling process accounting
++ ([#952](https://github.com/nix-rust/nix/pull/952))
++- Added the `time_t` and `suseconds_t` public aliases within `sys::time`.
++ ([#968](https://github.com/nix-rust/nix/pull/968))
++- Added `unistd::execvpe` for Haiku, Linux and OpenBSD
++ ([#975](https://github.com/nix-rust/nix/pull/975))
++- Added `Error::as_errno`.
++ ([#977](https://github.com/nix-rust/nix/pull/977))
++
++### Changed
++- Increased required Rust version to 1.24.1
++ ([#900](https://github.com/nix-rust/nix/pull/900))
++ ([#966](https://github.com/nix-rust/nix/pull/966))
++
++### Fixed
++- Made `preadv` take immutable slice of IoVec.
++ ([#914](https://github.com/nix-rust/nix/pull/914))
++- Fixed passing multiple file descriptors over Unix Sockets.
++ ([#918](https://github.com/nix-rust/nix/pull/918))
++
++### Removed
++
++## [0.11.0] 2018-06-01
++
++### Added
++- Added `sendfile` on FreeBSD and Darwin.
++ ([#901](https://github.com/nix-rust/nix/pull/901))
++- Added `pselect`
++ ([#894](https://github.com/nix-rust/nix/pull/894))
++- Exposed `preadv` and `pwritev` on the BSDs.
++ ([#883](https://github.com/nix-rust/nix/pull/883))
++- Added `mlockall` and `munlockall`
++ ([#876](https://github.com/nix-rust/nix/pull/876))
++- Added `SO_MARK` on Linux.
++ ([#873](https://github.com/nix-rust/nix/pull/873))
++- Added safe support for nearly any buffer type in the `sys::aio` module.
++ ([#872](https://github.com/nix-rust/nix/pull/872))
++- Added `sys::aio::LioCb` as a wrapper for `libc::lio_listio`.
++ ([#872](https://github.com/nix-rust/nix/pull/872))
++- Added `unistd::getsid`
++ ([#850](https://github.com/nix-rust/nix/pull/850))
++- Added `alarm`. ([#830](https://github.com/nix-rust/nix/pull/830))
++- Added interface flags `IFF_NO_PI, IFF_TUN, IFF_TAP` on linux-like systems.
++ ([#853](https://github.com/nix-rust/nix/pull/853))
++- Added `statvfs` module to all MacOS and Linux architectures.
++ ([#832](https://github.com/nix-rust/nix/pull/832))
++- Added `EVFILT_EMPTY`, `EVFILT_PROCDESC`, and `EVFILT_SENDFILE` on FreeBSD.
++ ([#825](https://github.com/nix-rust/nix/pull/825))
++- Exposed `termios::cfmakesane` on FreeBSD.
++ ([#825](https://github.com/nix-rust/nix/pull/825))
++- Exposed `MSG_CMSG_CLOEXEC` on *BSD.
++ ([#825](https://github.com/nix-rust/nix/pull/825))
++- Added `fchmod`, `fchmodat`.
++ ([#857](https://github.com/nix-rust/nix/pull/857))
++- Added `request_code_write_int!` on FreeBSD/DragonFlyBSD
++ ([#833](https://github.com/nix-rust/nix/pull/833))
++
++### Changed
++- `Display` and `Debug` for `SysControlAddr` now includes all fields.
++ ([#837](https://github.com/nix-rust/nix/pull/837))
++- `ioctl!` has been replaced with a family of `ioctl_*!` macros.
++ ([#833](https://github.com/nix-rust/nix/pull/833))
++- `io!`, `ior!`, `iow!`, and `iorw!` has been renamed to `request_code_none!`, `request_code_read!`,
++ `request_code_write!`, and `request_code_readwrite!` respectively. These have also now been exposed
++ in the documentation.
++ ([#833](https://github.com/nix-rust/nix/pull/833))
++- Enabled more `ptrace::Request` definitions for uncommon Linux platforms
++ ([#892](https://github.com/nix-rust/nix/pull/892))
++- Emulation of `FD_CLOEXEC` and `O_NONBLOCK` was removed from `socket()`, `accept4()`, and
++ `socketpair()`.
++ ([#907](https://github.com/nix-rust/nix/pull/907))
++
++### Fixed
++- Fixed possible panics when using `SigAction::flags` on Linux
++ ([#869](https://github.com/nix-rust/nix/pull/869))
++- Properly exposed 460800 and 921600 baud rates on NetBSD
++ ([#837](https://github.com/nix-rust/nix/pull/837))
++- Fixed `ioctl_write_int!` on FreeBSD/DragonFlyBSD
++ ([#833](https://github.com/nix-rust/nix/pull/833))
++- `ioctl_write_int!` now properly supports passing a `c_ulong` as the parameter on Linux non-musl targets
++ ([#833](https://github.com/nix-rust/nix/pull/833))
++
++### Removed
++- Removed explicit support for the `bytes` crate from the `sys::aio` module.
++ See `sys::aio::AioCb::from_boxed_slice` examples for alternatives.
++ ([#872](https://github.com/nix-rust/nix/pull/872))
++- Removed `sys::aio::lio_listio`. Use `sys::aio::LioCb::listio` instead.
++ ([#872](https://github.com/nix-rust/nix/pull/872))
++- Removed emulated `accept4()` from macos, ios, and netbsd targets
++ ([#907](https://github.com/nix-rust/nix/pull/907))
++- Removed `IFF_NOTRAILERS` on OpenBSD, as it has been removed in OpenBSD 6.3
++ ([#893](https://github.com/nix-rust/nix/pull/893))
++
++## [0.10.0] 2018-01-26
++
++### Added
++- Added specialized wrapper: `sys::ptrace::step`
++ ([#852](https://github.com/nix-rust/nix/pull/852))
++- Added `AioCb::from_ptr` and `AioCb::from_mut_ptr`
++ ([#820](https://github.com/nix-rust/nix/pull/820))
++- Added specialized wrappers: `sys::ptrace::{traceme, syscall, cont, attach}`. Using the matching routines
++ with `sys::ptrace::ptrace` is now deprecated.
++- Added `nix::poll` module for all platforms
++ ([#672](https://github.com/nix-rust/nix/pull/672))
++- Added `nix::ppoll` function for FreeBSD and DragonFly
++ ([#672](https://github.com/nix-rust/nix/pull/672))
++- Added protocol families in `AddressFamily` enum.
++ ([#647](https://github.com/nix-rust/nix/pull/647))
++- Added the `pid()` method to `WaitStatus` for extracting the PID.
++ ([#722](https://github.com/nix-rust/nix/pull/722))
++- Added `nix::unistd:fexecve`.
++ ([#727](https://github.com/nix-rust/nix/pull/727))
++- Expose `uname()` on all platforms.
++ ([#739](https://github.com/nix-rust/nix/pull/739))
++- Expose `signalfd` module on Android as well.
++ ([#739](https://github.com/nix-rust/nix/pull/739))
++- Added `nix::sys::ptrace::detach`.
++ ([#749](https://github.com/nix-rust/nix/pull/749))
++- Added timestamp socket control message variant:
++ `nix::sys::socket::ControlMessage::ScmTimestamp`
++ ([#663](https://github.com/nix-rust/nix/pull/663))
++- Added socket option variant that enables the timestamp socket
++ control message: `nix::sys::socket::sockopt::ReceiveTimestamp`
++ ([#663](https://github.com/nix-rust/nix/pull/663))
++- Added more accessor methods for `AioCb`
++ ([#773](https://github.com/nix-rust/nix/pull/773))
++- Add `nix::sys::fallocate`
++ ([#768](https:://github.com/nix-rust/nix/pull/768))
++- Added `nix::unistd::mkfifo`.
++ ([#602](https://github.com/nix-rust/nix/pull/774))
++- Added `ptrace::Options::PTRACE_O_EXITKILL` on Linux and Android.
++ ([#771](https://github.com/nix-rust/nix/pull/771))
++- Added `nix::sys::uio::{process_vm_readv, process_vm_writev}` on Linux
++ ([#568](https://github.com/nix-rust/nix/pull/568))
++- Added `nix::unistd::{getgroups, setgroups, getgrouplist, initgroups}`. ([#733](https://github.com/nix-rust/nix/pull/733))
++- Added `nix::sys::socket::UnixAddr::as_abstract` on Linux and Android.
++ ([#785](https://github.com/nix-rust/nix/pull/785))
++- Added `nix::unistd::execveat` on Linux and Android.
++ ([#800](https://github.com/nix-rust/nix/pull/800))
++- Added the `from_raw()` method to `WaitStatus` for converting raw status values
++ to `WaitStatus` independent of syscalls.
++ ([#741](https://github.com/nix-rust/nix/pull/741))
++- Added more standard trait implementations for various types.
++ ([#814](https://github.com/nix-rust/nix/pull/814))
++- Added `sigprocmask` to the signal module.
++ ([#826](https://github.com/nix-rust/nix/pull/826))
++- Added `nix::sys::socket::LinkAddr` on Linux and all bsdlike system.
++ ([#813](https://github.com/nix-rust/nix/pull/813))
++- Add socket options for `IP_TRANSPARENT` / `BIND_ANY`.
++ ([#835](https://github.com/nix-rust/nix/pull/835))
++
++### Changed
++- Exposed the `mqueue` module for all supported operating systems.
++ ([#834](https://github.com/nix-rust/nix/pull/834))
++- Use native `pipe2` on all BSD targets. Users should notice no difference.
++ ([#777](https://github.com/nix-rust/nix/pull/777))
++- Renamed existing `ptrace` wrappers to encourage namespacing ([#692](https://github.com/nix-rust/nix/pull/692))
++- Marked `sys::ptrace::ptrace` as `unsafe`.
++- Changed function signature of `socket()` and `socketpair()`. The `protocol` argument
++ has changed type from `c_int` to `SockProtocol`.
++ It accepts a `None` value for default protocol that was specified with zero using `c_int`.
++ ([#647](https://github.com/nix-rust/nix/pull/647))
++- Made `select` easier to use, adding the ability to automatically calculate the `nfds` parameter using the new
++ `FdSet::highest` ([#701](https://github.com/nix-rust/nix/pull/701))
++- Exposed `unistd::setresuid` and `unistd::setresgid` on FreeBSD and OpenBSD
++ ([#721](https://github.com/nix-rust/nix/pull/721))
++- Refactored the `statvfs` module removing extraneous API functions and the
++ `statvfs::vfs` module. Additionally `(f)statvfs()` now return the struct
++ directly. And the returned `Statvfs` struct now exposes its data through
++ accessor methods. ([#729](https://github.com/nix-rust/nix/pull/729))
++- The `addr` argument to `madvise` and `msync` is now `*mut` to better match the
++ libc API. ([#731](https://github.com/nix-rust/nix/pull/731))
++- `shm_open` and `shm_unlink` are no longer exposed on Android targets, where
++ they are not officially supported. ([#731](https://github.com/nix-rust/nix/pull/731))
++- `MapFlags`, `MmapAdvise`, and `MsFlags` expose some more variants and only
++ officially-supported variants are provided for each target.
++ ([#731](https://github.com/nix-rust/nix/pull/731))
++- Marked `pty::ptsname` function as `unsafe`
++ ([#744](https://github.com/nix-rust/nix/pull/744))
++- Moved constants ptrace request, event and options to enums and updated ptrace functions and argument types accordingly.
++ ([#749](https://github.com/nix-rust/nix/pull/749))
++- `AioCb::Drop` will now panic if the `AioCb` is still in-progress ([#715](https://github.com/nix-rust/nix/pull/715))
++- Restricted `nix::sys::socket::UnixAddr::new_abstract` to Linux and Android only.
++ ([#785](https://github.com/nix-rust/nix/pull/785))
++- The `ucred` struct has been removed in favor of a `UserCredentials` struct that
++ contains only getters for its fields.
++ ([#814](https://github.com/nix-rust/nix/pull/814))
++- Both `ip_mreq` and `ipv6_mreq` have been replaced with `IpMembershipRequest` and
++ `Ipv6MembershipRequest`.
++ ([#814](https://github.com/nix-rust/nix/pull/814))
++- Removed return type from `pause`.
++ ([#829](https://github.com/nix-rust/nix/pull/829))
++- Changed the termios APIs to allow for using a `u32` instead of the `BaudRate`
++ enum on BSD platforms to support arbitrary baud rates. See the module docs for
++ `nix::sys::termios` for more details.
++ ([#843](https://github.com/nix-rust/nix/pull/843))
++
++### Fixed
++- Fix compilation and tests for OpenBSD targets
++ ([#688](https://github.com/nix-rust/nix/pull/688))
++- Fixed error handling in `AioCb::fsync`, `AioCb::read`, and `AioCb::write`.
++ It is no longer an error to drop an `AioCb` that failed to enqueue in the OS.
++ ([#715](https://github.com/nix-rust/nix/pull/715))
++- Fix potential memory corruption on non-Linux platforms when using
++ `sendmsg`/`recvmsg`, caused by mismatched `msghdr` definition.
++ ([#648](https://github.com/nix-rust/nix/pull/648))
++
++### Removed
++- `AioCb::from_boxed_slice` has been removed. It was never actually safe. Use
++ `from_bytes` or `from_bytes_mut` instead.
++ ([#820](https://github.com/nix-rust/nix/pull/820))
++- The syscall module has been removed. This only exposed enough functionality for
++ `memfd_create()` and `pivot_root()`, which are still exposed as separate functions.
++ ([#747](https://github.com/nix-rust/nix/pull/747))
++- The `Errno` variants are no longer reexported from the `errno` module. `Errno` itself is no longer reexported from the
++ crate root and instead must be accessed using the `errno` module. ([#696](https://github.com/nix-rust/nix/pull/696))
++- Removed `MS_VERBOSE`, `MS_NOSEC`, and `MS_BORN` from `MsFlags`. These
++ are internal kernel flags and should never have been exposed.
++ ([#814](https://github.com/nix-rust/nix/pull/814))
++
++
++## [0.9.0] 2017-07-23
++
++### Added
++- Added `sysconf`, `pathconf`, and `fpathconf`
++ ([#630](https://github.com/nix-rust/nix/pull/630)
++- Added `sys::signal::SigAction::{ flags, mask, handler}`
++ ([#611](https://github.com/nix-rust/nix/pull/609)
++- Added `nix::sys::pthread::pthread_self`
++ ([#591](https://github.com/nix-rust/nix/pull/591)
++- Added `AioCb::from_boxed_slice`
++ ([#582](https://github.com/nix-rust/nix/pull/582)
++- Added `nix::unistd::{openat, fstatat, readlink, readlinkat}`
++ ([#551](https://github.com/nix-rust/nix/pull/551))
++- Added `nix::pty::{grantpt, posix_openpt, ptsname/ptsname_r, unlockpt}`
++ ([#556](https://github.com/nix-rust/nix/pull/556)
++- Added `nix::ptr::openpty`
++ ([#456](https://github.com/nix-rust/nix/pull/456))
++- Added `nix::ptrace::{ptrace_get_data, ptrace_getsiginfo, ptrace_setsiginfo
++ and nix::Error::UnsupportedOperation}`
++ ([#614](https://github.com/nix-rust/nix/pull/614))
++- Added `cfmakeraw`, `cfsetspeed`, and `tcgetsid`. ([#527](https://github.com/nix-rust/nix/pull/527))
++- Added "bad none", "bad write_ptr", "bad write_int", and "bad readwrite" variants to the `ioctl!`
++ macro. ([#670](https://github.com/nix-rust/nix/pull/670))
++- On Linux and Android, added support for receiving `PTRACE_O_TRACESYSGOOD`
++ events from `wait` and `waitpid` using `WaitStatus::PtraceSyscall`
++ ([#566](https://github.com/nix-rust/nix/pull/566)).
++
++### Changed
++- The `ioctl!` macro and its variants now allow the generated functions to have
++ doccomments. ([#661](https://github.com/nix-rust/nix/pull/661))
++- Changed `ioctl!(write ...)` into `ioctl!(write_ptr ...)` and `ioctl!(write_int ..)` variants
++ to more clearly separate those use cases. ([#670](https://github.com/nix-rust/nix/pull/670))
++- Marked `sys::mman::{ mmap, munmap, madvise, munlock, msync }` as unsafe.
++ ([#559](https://github.com/nix-rust/nix/pull/559))
++- Minimum supported Rust version is now 1.13.
++- Removed `revents` argument from `PollFd::new()` as it's an output argument and
++ will be overwritten regardless of value.
++ ([#542](https://github.com/nix-rust/nix/pull/542))
++- Changed type signature of `sys::select::FdSet::contains` to make `self`
++ immutable ([#564](https://github.com/nix-rust/nix/pull/564))
++- Introduced wrapper types for `gid_t`, `pid_t`, and `uid_t` as `Gid`, `Pid`, and `Uid`
++ respectively. Various functions have been changed to use these new types as
++ arguments. ([#629](https://github.com/nix-rust/nix/pull/629))
++- Fixed compilation on all Android and iOS targets ([#527](https://github.com/nix-rust/nix/pull/527))
++ and promoted them to Tier 2 support.
++- `nix::sys::statfs::{statfs,fstatfs}` uses statfs definition from `libc::statfs` instead of own linux specific type `nix::sys::Statfs`.
++ Also file system type constants like `nix::sys::statfs::ADFS_SUPER_MAGIC` were removed in favor of the libc equivalent.
++ ([#561](https://github.com/nix-rust/nix/pull/561))
++- Revised the termios API including additional tests and documentation and exposed it on iOS. ([#527](https://github.com/nix-rust/nix/pull/527))
++- `eventfd`, `signalfd`, and `pwritev`/`preadv` functionality is now included by default for all
++ supported platforms. ([#681](https://github.com/nix-rust/nix/pull/561))
++- The `ioctl!` macro's plain variants has been replaced with "bad read" to be consistent with
++ other variants. The generated functions also have more strict types for their arguments. The
++ "*_buf" variants also now calculate total array size and take slice references for improved type
++ safety. The documentation has also been dramatically improved.
++ ([#670](https://github.com/nix-rust/nix/pull/670))
++
++### Removed
++- Removed `io::Error` from `nix::Error` and the conversion from `nix::Error` to `Errno`
++ ([#614](https://github.com/nix-rust/nix/pull/614))
++- All feature flags have been removed in favor of conditional compilation on supported platforms.
++ `execvpe` is no longer supported, but this was already broken and will be added back in the next
++ release. ([#681](https://github.com/nix-rust/nix/pull/561))
++- Removed `ioc_*` functions and many helper constants and macros within the `ioctl` module. These
++ should always have been private and only the `ioctl!` should be used in public code.
++ ([#670](https://github.com/nix-rust/nix/pull/670))
++
++### Fixed
++- Fixed multiple issues compiling under different archetectures and OSes.
++ Now compiles on Linux/MIPS ([#538](https://github.com/nix-rust/nix/pull/538)),
++ `Linux/PPC` ([#553](https://github.com/nix-rust/nix/pull/553)),
++ `MacOS/x86_64,i686` ([#553](https://github.com/nix-rust/nix/pull/553)),
++ `NetBSD/x64_64` ([#538](https://github.com/nix-rust/nix/pull/538)),
++ `FreeBSD/x86_64,i686` ([#536](https://github.com/nix-rust/nix/pull/536)), and
++ `Android` ([#631](https://github.com/nix-rust/nix/pull/631)).
++- `bind` and `errno_location` now work correctly on `Android`
++ ([#631](https://github.com/nix-rust/nix/pull/631))
++- Added `nix::ptrace` on all Linux-kernel-based platforms
++ [#624](https://github.com/nix-rust/nix/pull/624). Previously it was
++ only available on x86, x86-64, and ARM, and also not on Android.
++- Fixed `sys::socket::sendmsg` with zero entry `cmsgs` parameter.
++ ([#623](https://github.com/nix-rust/nix/pull/623))
++- Multiple constants related to the termios API have now been properly defined for
++ all supported platforms. ([#527](https://github.com/nix-rust/nix/pull/527))
++- `ioctl!` macro now supports working with non-int datatypes and properly supports all platforms.
++ ([#670](https://github.com/nix-rust/nix/pull/670))
++
++## [0.8.1] 2017-04-16
++
++### Fixed
++- Fixed build on FreeBSD. (Cherry-picked
++ [a859ee3c](https://github.com/nix-rust/nix/commit/a859ee3c9396dfdb118fcc2c8ecc697e2d303467))
++
++## [0.8.0] 2017-03-02
++
++### Added
++- Added `::nix::sys::termios::BaudRate` enum to provide portable baudrate
++ values. ([#518](https://github.com/nix-rust/nix/pull/518))
++- Added a new `WaitStatus::PtraceEvent` to support ptrace events on Linux
++ and Android ([#438](https://github.com/nix-rust/nix/pull/438))
++- Added support for POSIX AIO
++ ([#483](https://github.com/nix-rust/nix/pull/483))
++ ([#506](https://github.com/nix-rust/nix/pull/506))
++- Added support for XNU system control sockets
++ ([#478](https://github.com/nix-rust/nix/pull/478))
++- Added support for `ioctl` calls on BSD platforms
++ ([#478](https://github.com/nix-rust/nix/pull/478))
++- Added struct `TimeSpec`
++ ([#475](https://github.com/nix-rust/nix/pull/475))
++ ([#483](https://github.com/nix-rust/nix/pull/483))
++- Added complete definitions for all kqueue-related constants on all supported
++ OSes
++ ([#415](https://github.com/nix-rust/nix/pull/415))
++- Added function `epoll_create1` and bitflags `EpollCreateFlags` in
++ `::nix::sys::epoll` in order to support `::libc::epoll_create1`.
++ ([#410](https://github.com/nix-rust/nix/pull/410))
++- Added `setresuid` and `setresgid` for Linux in `::nix::unistd`
++ ([#448](https://github.com/nix-rust/nix/pull/448))
++- Added `getpgid` in `::nix::unistd`
++ ([#433](https://github.com/nix-rust/nix/pull/433))
++- Added `tcgetpgrp` and `tcsetpgrp` in `::nix::unistd`
++ ([#451](https://github.com/nix-rust/nix/pull/451))
++- Added `CLONE_NEWCGROUP` in `::nix::sched`
++ ([#457](https://github.com/nix-rust/nix/pull/457))
++- Added `getpgrp` in `::nix::unistd`
++ ([#491](https://github.com/nix-rust/nix/pull/491))
++- Added `fchdir` in `::nix::unistd`
++ ([#497](https://github.com/nix-rust/nix/pull/497))
++- Added `major` and `minor` in `::nix::sys::stat` for decomposing `dev_t`
++ ([#508](https://github.com/nix-rust/nix/pull/508))
++- Fixed the style of many bitflags and use `libc` in more places.
++ ([#503](https://github.com/nix-rust/nix/pull/503))
++- Added `ppoll` in `::nix::poll`
++ ([#520](https://github.com/nix-rust/nix/pull/520))
++- Added support for getting and setting pipe size with fcntl(2) on Linux
++ ([#540](https://github.com/nix-rust/nix/pull/540))
++
++### Changed
++- `::nix::sys::termios::{cfgetispeed, cfsetispeed, cfgetospeed, cfsetospeed}`
++ switched to use `BaudRate` enum from `speed_t`.
++ ([#518](https://github.com/nix-rust/nix/pull/518))
++- `epoll_ctl` now could accept None as argument `event`
++ when op is `EpollOp::EpollCtlDel`.
++ ([#480](https://github.com/nix-rust/nix/pull/480))
++- Removed the `bad` keyword from the `ioctl!` macro
++ ([#478](https://github.com/nix-rust/nix/pull/478))
++- Changed `TimeVal` into an opaque Newtype
++ ([#475](https://github.com/nix-rust/nix/pull/475))
++- `kill`'s signature, defined in `::nix::sys::signal`, changed, so that the
++ signal parameter has type `T: Into<Option<Signal>>`. `None` as an argument
++ for that parameter will result in a 0 passed to libc's `kill`, while a
++ `Some`-argument will result in the previous behavior for the contained
++ `Signal`.
++ ([#445](https://github.com/nix-rust/nix/pull/445))
++- The minimum supported version of rustc is now 1.7.0.
++ ([#444](https://github.com/nix-rust/nix/pull/444))
++- Changed `KEvent` to an opaque structure that may only be modified by its
++ constructor and the `ev_set` method.
++ ([#415](https://github.com/nix-rust/nix/pull/415))
++ ([#442](https://github.com/nix-rust/nix/pull/442))
++ ([#463](https://github.com/nix-rust/nix/pull/463))
++- `pipe2` now calls `libc::pipe2` where available. Previously it was emulated
++ using `pipe`, which meant that setting `O_CLOEXEC` was not atomic.
++ ([#427](https://github.com/nix-rust/nix/pull/427))
++- Renamed `EpollEventKind` to `EpollFlags` in `::nix::sys::epoll` in order for
++ it to conform with our conventions.
++ ([#410](https://github.com/nix-rust/nix/pull/410))
++- `EpollEvent` in `::nix::sys::epoll` is now an opaque proxy for
++ `::libc::epoll_event`. The formerly public field `events` is now be read-only
++ accessible with the new method `events()` of `EpollEvent`. Instances of
++ `EpollEvent` can be constructed using the new method `new()` of EpollEvent.
++ ([#410](https://github.com/nix-rust/nix/pull/410))
++- `SigFlags` in `::nix::sys::signal` has be renamed to `SigmaskHow` and its type
++ has changed from `bitflags` to `enum` in order to conform to our conventions.
++ ([#460](https://github.com/nix-rust/nix/pull/460))
++- `sethostname` now takes a `&str` instead of a `&[u8]` as this provides an API
++ that makes more sense in normal, correct usage of the API.
++- `gethostname` previously did not expose the actual length of the hostname
++ written from the underlying system call at all. This has been updated to
++ return a `&CStr` within the provided buffer that is always properly
++ NUL-terminated (this is not guaranteed by the call with all platforms/libc
++ implementations).
++- Exposed all fcntl(2) operations at the module level, so they can be
++ imported direclty instead of via `FcntlArg` enum.
++ ([#541](https://github.com/nix-rust/nix/pull/541))
++
++### Fixed
++- Fixed multiple issues with Unix domain sockets on non-Linux OSes
++ ([#474](https://github.com/nix-rust/nix/pull/415))
++- Fixed using kqueue with `EVFILT_USER` on FreeBSD
++ ([#415](https://github.com/nix-rust/nix/pull/415))
++- Fixed the build on FreeBSD, and fixed the getsockopt, sendmsg, and recvmsg
++ functions on that same OS.
++ ([#397](https://github.com/nix-rust/nix/pull/397))
++- Fixed an off-by-one bug in `UnixAddr::new_abstract` in `::nix::sys::socket`.
++ ([#429](https://github.com/nix-rust/nix/pull/429))
++- Fixed clone passing a potentially unaligned stack.
++ ([#490](https://github.com/nix-rust/nix/pull/490))
++- Fixed mkdev not creating a `dev_t` the same way as libc.
++ ([#508](https://github.com/nix-rust/nix/pull/508))
++
++## [0.7.0] 2016-09-09
++
++### Added
++- Added `lseek` and `lseek64` in `::nix::unistd`
++ ([#377](https://github.com/nix-rust/nix/pull/377))
++- Added `mkdir` and `getcwd` in `::nix::unistd`
++ ([#416](https://github.com/nix-rust/nix/pull/416))
++- Added accessors `sigmask_mut` and `sigmask` to `UContext` in
++ `::nix::ucontext`.
++ ([#370](https://github.com/nix-rust/nix/pull/370))
++- Added `WUNTRACED` to `WaitPidFlag` in `::nix::sys::wait` for non-_linux_
++ targets.
++ ([#379](https://github.com/nix-rust/nix/pull/379))
++- Added new module `::nix::sys::reboot` with enumeration `RebootMode` and
++ functions `reboot` and `set_cad_enabled`. Currently for _linux_ only.
++ ([#386](https://github.com/nix-rust/nix/pull/386))
++- `FdSet` in `::nix::sys::select` now also implements `Clone`.
++ ([#405](https://github.com/nix-rust/nix/pull/405))
++- Added `F_FULLFSYNC` to `FcntlArg` in `::nix::fcntl` for _apple_ targets.
++ ([#407](https://github.com/nix-rust/nix/pull/407))
++- Added `CpuSet::unset` in `::nix::sched`.
++ ([#402](https://github.com/nix-rust/nix/pull/402))
++- Added constructor method `new()` to `PollFd` in `::nix::poll`, in order to
++ allow creation of objects, after removing public access to members.
++ ([#399](https://github.com/nix-rust/nix/pull/399))
++- Added method `revents()` to `PollFd` in `::nix::poll`, in order to provide
++ read access to formerly public member `revents`.
++ ([#399](https://github.com/nix-rust/nix/pull/399))
++- Added `MSG_CMSG_CLOEXEC` to `MsgFlags` in `::nix::sys::socket` for _linux_ only.
++ ([#422](https://github.com/nix-rust/nix/pull/422))
++
++### Changed
++- Replaced the reexported integer constants for signals by the enumeration
++ `Signal` in `::nix::sys::signal`.
++ ([#362](https://github.com/nix-rust/nix/pull/362))
++- Renamed `EventFdFlag` to `EfdFlags` in `::nix::sys::eventfd`.
++ ([#383](https://github.com/nix-rust/nix/pull/383))
++- Changed the result types of `CpuSet::is_set` and `CpuSet::set` in
++ `::nix::sched` to `Result<bool>` and `Result<()>`, respectively. They now
++ return `EINVAL`, if an invalid argument for the `field` parameter is passed.
++ ([#402](https://github.com/nix-rust/nix/pull/402))
++- `MqAttr` in `::nix::mqueue` is now an opaque proxy for `::libc::mq_attr`,
++ which has the same structure as the old `MqAttr`. The field `mq_flags` of
++ `::libc::mq_attr` is readable using the new method `flags()` of `MqAttr`.
++ `MqAttr` also no longer implements `Debug`.
++ ([#392](https://github.com/nix-rust/nix/pull/392))
++- The parameter `msq_prio` of `mq_receive` with type `u32` in `::nix::mqueue`
++ was replaced by a parameter named `msg_prio` with type `&mut u32`, so that
++ the message priority can be obtained by the caller.
++ ([#392](https://github.com/nix-rust/nix/pull/392))
++- The type alias `MQd` in `::nix::queue` was replaced by the type alias
++ `libc::mqd_t`, both of which are aliases for the same type.
++ ([#392](https://github.com/nix-rust/nix/pull/392))
++
++### Removed
++- Type alias `SigNum` from `::nix::sys::signal`.
++ ([#362](https://github.com/nix-rust/nix/pull/362))
++- Type alias `CpuMask` from `::nix::shed`.
++ ([#402](https://github.com/nix-rust/nix/pull/402))
++- Removed public fields from `PollFd` in `::nix::poll`. (See also added method
++ `revents()`.
++ ([#399](https://github.com/nix-rust/nix/pull/399))
++
++### Fixed
++- Fixed the build problem for NetBSD (Note, that we currently do not support
++ it, so it might already be broken again).
++ ([#389](https://github.com/nix-rust/nix/pull/389))
++- Fixed the build on FreeBSD, and fixed the getsockopt, sendmsg, and recvmsg
++ functions on that same OS.
++ ([#397](https://github.com/nix-rust/nix/pull/397))
++
++## [0.6.0] 2016-06-10
++
++### Added
++- Added `gettid` in `::nix::unistd` for _linux_ and _android_.
++ ([#293](https://github.com/nix-rust/nix/pull/293))
++- Some _mips_ support in `::nix::sched` and `::nix::sys::syscall`.
++ ([#301](https://github.com/nix-rust/nix/pull/301))
++- Added `SIGNALFD_SIGINFO_SIZE` in `::nix::sys::signalfd`.
++ ([#309](https://github.com/nix-rust/nix/pull/309))
++- Added new module `::nix::ucontext` with struct `UContext`. Currently for
++ _linux_ only.
++ ([#311](https://github.com/nix-rust/nix/pull/311))
++- Added `EPOLLEXCLUSIVE` to `EpollEventKind` in `::nix::sys::epoll`.
++ ([#330](https://github.com/nix-rust/nix/pull/330))
++- Added `pause` to `::nix::unistd`.
++ ([#336](https://github.com/nix-rust/nix/pull/336))
++- Added `sleep` to `::nix::unistd`.
++ ([#351](https://github.com/nix-rust/nix/pull/351))
++- Added `S_IFDIR`, `S_IFLNK`, `S_IFMT` to `SFlag` in `::nix::sys::stat`.
++ ([#359](https://github.com/nix-rust/nix/pull/359))
++- Added `clear` and `extend` functions to `SigSet`'s implementation in
++ `::nix::sys::signal`.
++ ([#347](https://github.com/nix-rust/nix/pull/347))
++- `sockaddr_storage_to_addr` in `::nix::sys::socket` now supports `sockaddr_nl`
++ on _linux_ and _android_.
++ ([#366](https://github.com/nix-rust/nix/pull/366))
++- Added support for `SO_ORIGINAL_DST` in `::nix::sys::socket` on _linux_.
++ ([#367](https://github.com/nix-rust/nix/pull/367))
++- Added `SIGINFO` in `::nix::sys::signal` for the _macos_ target as well as
++ `SIGPWR` and `SIGSTKFLT` in `::nix::sys::signal` for non-_macos_ targets.
++ ([#361](https://github.com/nix-rust/nix/pull/361))
++
++### Changed
++- Changed the structure `IoVec` in `::nix::sys::uio`.
++ ([#304](https://github.com/nix-rust/nix/pull/304))
++- Replaced `CREATE_NEW_FD` by `SIGNALFD_NEW` in `::nix::sys::signalfd`.
++ ([#309](https://github.com/nix-rust/nix/pull/309))
++- Renamed `SaFlag` to `SaFlags` and `SigFlag` to `SigFlags` in
++ `::nix::sys::signal`.
++ ([#314](https://github.com/nix-rust/nix/pull/314))
++- Renamed `Fork` to `ForkResult` and changed its fields in `::nix::unistd`.
++ ([#332](https://github.com/nix-rust/nix/pull/332))
++- Added the `signal` parameter to `clone`'s signature in `::nix::sched`.
++ ([#344](https://github.com/nix-rust/nix/pull/344))
++- `execv`, `execve`, and `execvp` now return `Result<Void>` instead of
++ `Result<()>` in `::nix::unistd`.
++ ([#357](https://github.com/nix-rust/nix/pull/357))
++
++### Fixed
++- Improved the conversion from `std::net::SocketAddr` to `InetAddr` in
++ `::nix::sys::socket::addr`.
++ ([#335](https://github.com/nix-rust/nix/pull/335))
++
++## [0.5.0] 2016-03-01
+diff --git a/third_party/rust/nix-0.15.0/CONTRIBUTING.md b/third_party/rust/nix-0.15.0/CONTRIBUTING.md
+new file mode 100644
+index 0000000000000..03a1f630dbb06
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/CONTRIBUTING.md
+@@ -0,0 +1,114 @@
++# Contributing to nix
++
++We're really glad you're interested in contributing to nix! This
++document has a few pointers and guidelines to help get you started.
++
++To have a welcoming and inclusive project, nix uses the Rust project's
++[Code of Conduct][conduct]. All contributors are expected to follow it.
++
++[conduct]: https://www.rust-lang.org/conduct.html
++
++
++# Issues
++
++We use GitHub's [issue tracker][issues].
++
++[issues]: https://github.com/nix-rust/nix/issues
++
++
++## Bug reports
++
++Before submitting a new bug report, please [search existing
++issues][issue-search] to see if there's something related. If not, just
++[open a new issue][new-issue]!
++
++As a reminder, the more information you can give in your issue, the
++easier it is to figure out how to fix it. For nix, this will likely
++include the OS and version, and the architecture.
++
++[issue-search]: https://github.com/nix-rust/nix/search?utf8=%E2%9C%93&q=is%3Aissue&type=Issues
++[new-issue]: https://github.com/nix-rust/nix/issues/new
++
++
++## Feature / API requests
++
++If you'd like a new API or feature added, please [open a new
++issue][new-issue] requesting it. As with reporting a bug, the more
++information you can provide, the better.
++
++
++## Labels
++
++We use labels to help manage issues. The structure is modeled after
++[Rust's issue labeling scheme][rust-labels]:
++- **A-**prefixed labels state which area of the project the issue
++ relates to
++- **E-**prefixed labels explain the level of experience necessary to fix the
++ issue
++- **O-**prefixed labels specify the OS for issues that are OS-specific
++- **R-**prefixed labels specify the architecture for issues that are
++ architecture-specific
++
++[rust-labels]: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#issue-triage
++
++
++# Pull requests
++
++GitHub pull requests are the primary mechanism we use to change nix. GitHub itself has
++some [great documentation][pr-docs] on using the Pull Request feature. We use the 'fork and
++pull' model described there.
++
++Please make pull requests against the `master` branch.
++
++If you change the API by way of adding, removing or changing something or if
++you fix a bug, please add an appropriate note to the [change log][cl]. We
++follow the conventions of [Keep A CHANGELOG][kacl].
++
++[cl]: https://github.com/nix-rust/nix/blob/master/CHANGELOG.md
++[kacl]: https://github.com/olivierlacan/keep-a-changelog/tree/18adb5f5be7a898d046f6a4acb93e39dcf40c4ad
++[pr-docs]: https://help.github.com/articles/using-pull-requests/
++
++## Testing
++
++nix has a test suite that you can run with `cargo test`. Ideally, we'd like pull
++requests to include tests where they make sense. For example, when fixing a bug,
++add a test that would have failed without the fix.
++
++After you've made your change, make sure the tests pass in your development
++environment. We also have [continuous integration set up on
++Travis-CI][travis-ci], which might find some issues on other platforms. The CI
++will run once you open a pull request.
++
++There is also infrastructure for running tests for other targets
++locally. More information is available in the [CI Readme][ci-readme].
++
++[travis-ci]: https://travis-ci.org/nix-rust/nix
++[ci-readme]: ci/README.md
++
++### Disabling a test in the CI environment
++
++Sometimes there are features that cannot be tested in the CI environment.
++To stop a test from running under CI, add `#[cfg_attr(travis, ignore)]`
++to it. Please include a comment describing the reason it shouldn't run
++under CI, and a link to an upstream issue if possible!
++
++## bors, the bot who merges all the PRs
++
++All pull requests are merged via [bors], an integration bot. After the
++pull request has been reviewed, the reviewer will leave a comment like
++
++> bors r+
++
++to let bors know that it was approved. Then bors will check that it passes
++tests when merged with the latest changes in the `master` branch, and
++merge if the tests succeed.
++
++[bors]: https://bors-ng.github.io/
++
++
++## API conventions
++
++If you're adding a new API, we have a [document with
++conventions][conventions] to use throughout the nix project.
++
++[conventions]: https://github.com/nix-rust/nix/blob/master/CONVENTIONS.md
+diff --git a/third_party/rust/nix-0.15.0/CONVENTIONS.md b/third_party/rust/nix-0.15.0/CONVENTIONS.md
+new file mode 100644
+index 0000000000000..48daa937345d2
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/CONVENTIONS.md
+@@ -0,0 +1,87 @@
++# Conventions
++
++In order to achieve our goal of wrapping [libc][libc] code in idiomatic rust
++constructs with minimal performance overhead, we follow the following
++conventions.
++
++Note that, thus far, not all the code follows these conventions and not all
++conventions we try to follow have been documented here. If you find an instance
++of either, feel free to remedy the flaw by opening a pull request with
++appropriate changes or additions.
++
++## Change Log
++
++We follow the conventions laid out in [Keep A CHANGELOG][kacl].
++
++[kacl]: https://github.com/olivierlacan/keep-a-changelog/tree/18adb5f5be7a898d046f6a4acb93e39dcf40c4ad
++
++## libc constants, functions and structs
++
++We do not define integer constants ourselves, but use or reexport them from the
++[libc crate][libc].
++
++We use the functions exported from [libc][libc] instead of writing our own
++`extern` declarations.
++
++We use the `struct` definitions from [libc][libc] internally instead of writing
++our own. If we want to add methods to a libc type, we use the newtype pattern.
++For example,
++
++```rust
++pub struct SigSet(libc::sigset_t);
++
++impl SigSet {
++ ...
++}
++```
++
++When creating newtypes, we use Rust's `CamelCase` type naming convention.
++
++## Bitflags
++
++Many C functions have flags parameters that are combined from constants using
++bitwise operations. We represent the types of these parameters by types defined
++using our `libc_bitflags!` macro, which is a convenience wrapper around the
++`bitflags!` macro from the [bitflags crate][bitflags] that brings in the
++constant value from `libc`.
++
++We name the type for a set of constants whose element's names start with `FOO_`
++`FooFlags`.
++
++For example,
++
++```rust
++libc_bitflags!{
++ pub struct ProtFlags: libc::c_int {
++ PROT_NONE;
++ PROT_READ;
++ PROT_WRITE;
++ PROT_EXEC;
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ PROT_GROWSDOWN;
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ PROT_GROWSUP;
++ }
++}
++```
++
++
++## Enumerations
++
++We represent sets of constants that are intended as mutually exclusive arguments
++to parameters of functions by [enumerations][enum].
++
++
++## Structures Initialized by libc Functions
++
++Whenever we need to use a [libc][libc] function to properly initialize a
++variable and said function allows us to use uninitialized memory, we use
++[`std::mem::uninitialized`][std_uninitialized] (or [`core::mem::uninitialized`][core_uninitialized])
++when defining the variable. This allows us to avoid the overhead incurred by
++zeroing or otherwise initializing the variable.
++
++[bitflags]: https://crates.io/crates/bitflags/
++[core_uninitialized]: https://doc.rust-lang.org/core/mem/fn.uninitialized.html
++[enum]: https://doc.rust-lang.org/reference.html#enumerations
++[libc]: https://crates.io/crates/libc/
++[std_uninitialized]: https://doc.rust-lang.org/std/mem/fn.uninitialized.html
+diff --git a/third_party/rust/nix-0.15.0/Cargo.toml b/third_party/rust/nix-0.15.0/Cargo.toml
+new file mode 100644
+index 0000000000000..555b99020d68f
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/Cargo.toml
+@@ -0,0 +1,71 @@
++# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
++#
++# When uploading crates to the registry Cargo will automatically
++# "normalize" Cargo.toml files for maximal compatibility
++# with all versions of Cargo and also rewrite `path` dependencies
++# to registry (e.g., crates.io) dependencies
++#
++# If you believe there's an error in this file please file an
++# issue against the rust-lang/cargo repository. If you're
++# editing this file be aware that the upstream Cargo.toml
++# will likely look very different (and much more reasonable)
++
++[package]
++name = "nix"
++version = "0.15.0"
++authors = ["The nix-rust Project Developers"]
++exclude = ["/.gitignore", "/.travis.yml", "/ci/*", "/Cross.toml", "/RELEASE_PROCEDURE.md", "/bors.toml"]
++description = "Rust friendly bindings to *nix APIs"
++categories = ["os::unix-apis"]
++license = "MIT"
++repository = "https://github.com/nix-rust/nix"
++
++[[test]]
++name = "test"
++path = "test/test.rs"
++
++[[test]]
++name = "test-aio-drop"
++path = "test/sys/test_aio_drop.rs"
++
++[[test]]
++name = "test-lio-listio-resubmit"
++path = "test/sys/test_lio_listio_resubmit.rs"
++
++[[test]]
++name = "test-mount"
++path = "test/test_mount.rs"
++harness = false
++
++[[test]]
++name = "test-ptymaster-drop"
++path = "test/test_ptymaster_drop.rs"
++[dependencies.bitflags]
++version = "1.0"
++
++[dependencies.cfg-if]
++version = "0.1.2"
++
++[dependencies.libc]
++version = "0.2.60"
++features = ["extra_traits"]
++
++[dependencies.void]
++version = "1.0.2"
++[dev-dependencies.bytes]
++version = "0.4.8"
++
++[dev-dependencies.lazy_static]
++version = "1.2"
++
++[dev-dependencies.rand]
++version = ">= 0.6, < 0.7"
++
++[dev-dependencies.tempfile]
++version = ">= 3.0.5, < 3.0.9"
++[target."cfg(any(target_os = \"android\", target_os = \"linux\"))".dev-dependencies.caps]
++version = "0.3.1"
++[target."cfg(target_os = \"dragonfly\")".build-dependencies.cc]
++version = "1"
++[target."cfg(target_os = \"freebsd\")".dev-dependencies.sysctl]
++version = "0.1"
+diff --git a/third_party/rust/nix-0.15.0/LICENSE b/third_party/rust/nix-0.15.0/LICENSE
+new file mode 100644
+index 0000000000000..aff9096fdf11d
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/LICENSE
+@@ -0,0 +1,21 @@
++The MIT License (MIT)
++
++Copyright (c) 2015 Carl Lerche + nix-rust Authors
++
++Permission is hereby granted, free of charge, to any person obtaining a copy
++of this software and associated documentation files (the "Software"), to deal
++in the Software without restriction, including without limitation the rights
++to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++copies of the Software, and to permit persons to whom the Software is
++furnished to do so, subject to the following conditions:
++
++The above copyright notice and this permission notice shall be included in
++all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
++THE SOFTWARE.
+diff --git a/third_party/rust/nix-0.15.0/README.md b/third_party/rust/nix-0.15.0/README.md
+new file mode 100644
+index 0000000000000..0e540ba5b968e
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/README.md
+@@ -0,0 +1,111 @@
++# Rust bindings to *nix APIs
++
++[![Build Status](https://travis-ci.org/nix-rust/nix.svg?branch=master)](https://travis-ci.org/nix-rust/nix)
++[![crates.io](http://meritbadge.herokuapp.com/nix)](https://crates.io/crates/nix)
++
++[Documentation (Releases)](https://docs.rs/nix/)
++
++Nix seeks to provide friendly bindings to various *nix platform APIs (Linux, Darwin,
++...). The goal is to not provide a 100% unified interface, but to unify
++what can be while still providing platform specific APIs.
++
++For many system APIs, Nix provides a safe alternative to the unsafe APIs
++exposed by the [libc crate](https://github.com/rust-lang/libc). This is done by
++wrapping the libc functionality with types/abstractions that enforce legal/safe
++usage.
++
++
++As an example of what Nix provides, examine the differences between what is
++exposed by libc and nix for the
++[gethostname](http://man7.org/linux/man-pages/man2/gethostname.2.html) system
++call:
++
++```rust,ignore
++// libc api (unsafe, requires handling return code/errno)
++pub unsafe extern fn gethostname(name: *mut c_char, len: size_t) -> c_int;
++
++// nix api (returns a nix::Result<CStr>)
++pub fn gethostname<'a>(buffer: &'a mut [u8]) -> Result<&'a CStr>;
++```
++
++## Supported Platforms
++
++nix target support consists of two tiers. While nix attempts to support all
++platforms supported by [libc](https://github.com/rust-lang/libc), only some
++platforms are actively supported due to either technical or manpower
++limitations. Support for platforms is split into three tiers:
++
++ * Tier 1 - Builds and tests for this target are run in CI. Failures of either
++ block the inclusion of new code.
++ * Tier 2 - Builds for this target are run in CI. Failures during the build
++ blocks the inclusion of new code. Tests may be run, but failures
++ in tests don't block the inclusion of new code.
++ * Tier 3 - Builds for this target are run in CI. Failures during the build
++ *do not* block the inclusion of new code. Testing may be run, but
++ failures in tests don't block the inclusion of new code.
++
++The following targets are supported by `nix`:
++
++Tier 1:
++ * aarch64-unknown-linux-gnu
++ * arm-unknown-linux-gnueabi
++ * armv7-unknown-linux-gnueabihf
++ * i686-apple-darwin
++ * i686-unknown-freebsd
++ * i686-unknown-linux-gnu
++ * i686-unknown-linux-musl
++ * mips-unknown-linux-gnu
++ * mips64-unknown-linux-gnuabi64
++ * mips64el-unknown-linux-gnuabi64
++ * mipsel-unknown-linux-gnu
++ * powerpc64-unknown-linux-gnu
++ * powerpc64le-unknown-linux-gnu
++ * x86_64-apple-darwin
++ * x86_64-unknown-freebsd
++ * x86_64-unknown-linux-gnu
++ * x86_64-unknown-linux-musl
++
++Tier 2:
++ * aarch64-apple-ios
++ * aarch64-linux-android
++ * arm-linux-androideabi
++ * arm-unknown-linux-musleabi
++ * armv7-apple-ios
++ * armv7-linux-androideabi
++ * armv7s-apple-ios
++ * i386-apple-ios
++ * i686-linux-android
++ * powerpc-unknown-linux-gnu
++ * s390x-unknown-linux-gnu
++ * x86_64-apple-ios
++ * x86_64-linux-android
++ * x86_64-unknown-netbsd
++
++## Usage
++
++`nix` requires Rust 1.31.0 or newer.
++
++To use `nix`, first add this to your `Cargo.toml`:
++
++```toml
++[dependencies]
++nix = "0.15.0"
++```
++
++Then, add this to your crate root:
++
++```rust,ignore
++extern crate nix;
++```
++
++## Contributing
++
++Contributions are very welcome. Please See [CONTRIBUTING](CONTRIBUTING.md) for
++additional details.
++
++Feel free to join us in [the nix-rust/nix](https://gitter.im/nix-rust/nix) channel on Gitter to
++discuss `nix` development.
++
++## License
++
++Nix is licensed under the MIT license. See [LICENSE](LICENSE) for more details.
+diff --git a/third_party/rust/nix/build.rs b/third_party/rust/nix-0.15.0/build.rs
+similarity index 100%
+rename from third_party/rust/nix/build.rs
+rename to third_party/rust/nix-0.15.0/build.rs
+diff --git a/third_party/rust/nix-0.15.0/src/dir.rs b/third_party/rust/nix-0.15.0/src/dir.rs
+new file mode 100644
+index 0000000000000..1820b5330ff60
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/dir.rs
+@@ -0,0 +1,193 @@
++use {Error, NixPath, Result};
++use errno::Errno;
++use fcntl::{self, OFlag};
++use libc;
++use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
++use std::{ffi, ptr};
++use sys;
++
++#[cfg(target_os = "linux")]
++use libc::{dirent64 as dirent, readdir64_r as readdir_r};
++
++#[cfg(not(target_os = "linux"))]
++use libc::{dirent, readdir_r};
++
++/// An open directory.
++///
++/// This is a lower-level interface than `std::fs::ReadDir`. Notable differences:
++/// * can be opened from a file descriptor (as returned by `openat`, perhaps before knowing
++/// if the path represents a file or directory).
++/// * implements `AsRawFd`, so it can be passed to `fstat`, `openat`, etc.
++/// The file descriptor continues to be owned by the `Dir`, so callers must not keep a `RawFd`
++/// after the `Dir` is dropped.
++/// * can be iterated through multiple times without closing and reopening the file
++/// descriptor. Each iteration rewinds when finished.
++/// * returns entries for `.` (current directory) and `..` (parent directory).
++/// * returns entries' names as a `CStr` (no allocation or conversion beyond whatever libc
++/// does).
++#[derive(Clone, Debug, Eq, Hash, PartialEq)]
++pub struct Dir(
++ ptr::NonNull<libc::DIR>
++);
++
++impl Dir {
++ /// Opens the given path as with `fcntl::open`.
++ pub fn open<P: ?Sized + NixPath>(path: &P, oflag: OFlag,
++ mode: sys::stat::Mode) -> Result<Self> {
++ let fd = fcntl::open(path, oflag, mode)?;
++ Dir::from_fd(fd)
++ }
++
++ /// Opens the given path as with `fcntl::openat`.
++ pub fn openat<P: ?Sized + NixPath>(dirfd: RawFd, path: &P, oflag: OFlag,
++ mode: sys::stat::Mode) -> Result<Self> {
++ let fd = fcntl::openat(dirfd, path, oflag, mode)?;
++ Dir::from_fd(fd)
++ }
++
++ /// Converts from a descriptor-based object, closing the descriptor on success or failure.
++ #[inline]
++ pub fn from<F: IntoRawFd>(fd: F) -> Result<Self> {
++ Dir::from_fd(fd.into_raw_fd())
++ }
++
++ /// Converts from a file descriptor, closing it on success or failure.
++ pub fn from_fd(fd: RawFd) -> Result<Self> {
++ let d = unsafe { libc::fdopendir(fd) };
++ if d.is_null() {
++ let e = Error::last();
++ unsafe { libc::close(fd) };
++ return Err(e);
++ };
++ // Always guaranteed to be non-null by the previous check
++ Ok(Dir(ptr::NonNull::new(d).unwrap()))
++ }
++
++ /// Returns an iterator of `Result<Entry>` which rewinds when finished.
++ pub fn iter(&mut self) -> Iter {
++ Iter(self)
++ }
++}
++
++// `Dir` is not `Sync`. With the current implementation, it could be, but according to
++// https://www.gnu.org/software/libc/manual/html_node/Reading_002fClosing-Directory.html,
++// future versions of POSIX are likely to obsolete `readdir_r` and specify that it's unsafe to
++// call `readdir` simultaneously from multiple threads.
++//
++// `Dir` is safe to pass from one thread to another, as it's not reference-counted.
++unsafe impl Send for Dir {}
++
++impl AsRawFd for Dir {
++ fn as_raw_fd(&self) -> RawFd {
++ unsafe { libc::dirfd(self.0.as_ptr()) }
++ }
++}
++
++impl Drop for Dir {
++ fn drop(&mut self) {
++ unsafe { libc::closedir(self.0.as_ptr()) };
++ }
++}
++
++#[derive(Debug, Eq, Hash, PartialEq)]
++pub struct Iter<'d>(&'d mut Dir);
++
++impl<'d> Iterator for Iter<'d> {
++ type Item = Result<Entry>;
++
++ fn next(&mut self) -> Option<Self::Item> {
++ unsafe {
++ // Note: POSIX specifies that portable applications should dynamically allocate a
++ // buffer with room for a `d_name` field of size `pathconf(..., _PC_NAME_MAX)` plus 1
++ // for the NUL byte. It doesn't look like the std library does this; it just uses
++ // fixed-sized buffers (and libc's dirent seems to be sized so this is appropriate).
++ // Probably fine here too then.
++ let mut ent: Entry = Entry(::std::mem::uninitialized());
++ let mut result = ptr::null_mut();
++ if let Err(e) = Errno::result(readdir_r((self.0).0.as_ptr(), &mut ent.0, &mut result)) {
++ return Some(Err(e));
++ }
++ if result == ptr::null_mut() {
++ return None;
++ }
++ assert_eq!(result, &mut ent.0 as *mut dirent);
++ return Some(Ok(ent));
++ }
++ }
++}
++
++impl<'d> Drop for Iter<'d> {
++ fn drop(&mut self) {
++ unsafe { libc::rewinddir((self.0).0.as_ptr()) }
++ }
++}
++
++/// A directory entry, similar to `std::fs::DirEntry`.
++///
++/// Note that unlike the std version, this may represent the `.` or `..` entries.
++#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
++pub struct Entry(dirent);
++
++#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
++pub enum Type {
++ Fifo,
++ CharacterDevice,
++ Directory,
++ BlockDevice,
++ File,
++ Symlink,
++ Socket,
++}
++
++impl Entry {
++ /// Returns the inode number (`d_ino`) of the underlying `dirent`.
++ #[cfg(any(target_os = "android",
++ target_os = "emscripten",
++ target_os = "fuchsia",
++ target_os = "haiku",
++ target_os = "ios",
++ target_os = "l4re",
++ target_os = "linux",
++ target_os = "macos",
++ target_os = "solaris"))]
++ pub fn ino(&self) -> u64 {
++ self.0.d_ino as u64
++ }
++
++ /// Returns the inode number (`d_fileno`) of the underlying `dirent`.
++ #[cfg(not(any(target_os = "android",
++ target_os = "emscripten",
++ target_os = "fuchsia",
++ target_os = "haiku",
++ target_os = "ios",
++ target_os = "l4re",
++ target_os = "linux",
++ target_os = "macos",
++ target_os = "solaris")))]
++ pub fn ino(&self) -> u64 {
++ self.0.d_fileno as u64
++ }
++
++ /// Returns the bare file name of this directory entry without any other leading path component.
++ pub fn file_name(&self) -> &ffi::CStr {
++ unsafe { ::std::ffi::CStr::from_ptr(self.0.d_name.as_ptr()) }
++ }
++
++ /// Returns the type of this directory entry, if known.
++ ///
++ /// See platform `readdir(3)` or `dirent(5)` manpage for when the file type is known;
++ /// notably, some Linux filesystems don't implement this. The caller should use `stat` or
++ /// `fstat` if this returns `None`.
++ pub fn file_type(&self) -> Option<Type> {
++ match self.0.d_type {
++ libc::DT_FIFO => Some(Type::Fifo),
++ libc::DT_CHR => Some(Type::CharacterDevice),
++ libc::DT_DIR => Some(Type::Directory),
++ libc::DT_BLK => Some(Type::BlockDevice),
++ libc::DT_REG => Some(Type::File),
++ libc::DT_LNK => Some(Type::Symlink),
++ libc::DT_SOCK => Some(Type::Socket),
++ /* libc::DT_UNKNOWN | */ _ => None,
++ }
++ }
++}
+diff --git a/third_party/rust/nix-0.15.0/src/errno.rs b/third_party/rust/nix-0.15.0/src/errno.rs
+new file mode 100644
+index 0000000000000..6a2447bc52675
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/errno.rs
+@@ -0,0 +1,1963 @@
++#[cfg(not(target_os = "dragonfly"))]
++use libc;
++use libc::{c_int, c_void};
++use std::{fmt, io, error};
++use {Error, Result};
++
++pub use self::consts::*;
++
++cfg_if! {
++ if #[cfg(any(target_os = "freebsd",
++ target_os = "ios",
++ target_os = "macos"))] {
++ unsafe fn errno_location() -> *mut c_int {
++ libc::__error()
++ }
++ } else if #[cfg(target_os = "dragonfly")] {
++ // DragonFly uses a thread-local errno variable, but #[thread_local] is
++ // feature-gated and not available in stable Rust as of this writing
++ // (Rust 1.21.0). We have to use a C extension to access it
++ // (src/errno_dragonfly.c).
++ //
++ // Tracking issue for `thread_local` stabilization:
++ //
++ // https://github.com/rust-lang/rust/issues/29594
++ //
++ // Once this becomes stable, we can remove build.rs,
++ // src/errno_dragonfly.c, and use:
++ //
++ // extern { #[thread_local] static errno: c_int; }
++ //
++ #[link(name="errno_dragonfly", kind="static")]
++ extern {
++ pub fn errno_location() -> *mut c_int;
++ }
++ } else if #[cfg(any(target_os = "android",
++ target_os = "netbsd",
++ target_os = "openbsd"))] {
++ unsafe fn errno_location() -> *mut c_int {
++ libc::__errno()
++ }
++ } else if #[cfg(target_os = "linux")] {
++ unsafe fn errno_location() -> *mut c_int {
++ libc::__errno_location()
++ }
++ }
++}
++
++/// Sets the platform-specific errno to no-error
++unsafe fn clear() -> () {
++ *errno_location() = 0;
++}
++
++/// Returns the platform-specific value of errno
++pub fn errno() -> i32 {
++ unsafe {
++ (*errno_location()) as i32
++ }
++}
++
++impl Errno {
++ pub fn last() -> Self {
++ last()
++ }
++
++ pub fn desc(self) -> &'static str {
++ desc(self)
++ }
++
++ pub fn from_i32(err: i32) -> Errno {
++ from_i32(err)
++ }
++
++ pub unsafe fn clear() -> () {
++ clear()
++ }
++
++ /// Returns `Ok(value)` if it does not contain the sentinel value. This
++ /// should not be used when `-1` is not the errno sentinel value.
++ pub fn result<S: ErrnoSentinel + PartialEq<S>>(value: S) -> Result<S> {
++ if value == S::sentinel() {
++ Err(Error::Sys(Self::last()))
++ } else {
++ Ok(value)
++ }
++ }
++}
++
++/// The sentinel value indicates that a function failed and more detailed
++/// information about the error can be found in `errno`
++pub trait ErrnoSentinel: Sized {
++ fn sentinel() -> Self;
++}
++
++impl ErrnoSentinel for isize {
++ fn sentinel() -> Self { -1 }
++}
++
++impl ErrnoSentinel for i32 {
++ fn sentinel() -> Self { -1 }
++}
++
++impl ErrnoSentinel for i64 {
++ fn sentinel() -> Self { -1 }
++}
++
++impl ErrnoSentinel for *mut c_void {
++ fn sentinel() -> Self { (-1 as isize) as *mut c_void }
++}
++
++impl ErrnoSentinel for libc::sighandler_t {
++ fn sentinel() -> Self { libc::SIG_ERR }
++}
++
++impl error::Error for Errno {
++ fn description(&self) -> &str {
++ self.desc()
++ }
++}
++
++impl fmt::Display for Errno {
++ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
++ write!(f, "{:?}: {}", self, self.desc())
++ }
++}
++
++impl From<Errno> for io::Error {
++ fn from(err: Errno) -> Self {
++ io::Error::from_raw_os_error(err as i32)
++ }
++}
++
++fn last() -> Errno {
++ Errno::from_i32(errno())
++}
++
++fn desc(errno: Errno) -> &'static str {
++ use self::Errno::*;
++ match errno {
++ UnknownErrno => "Unknown errno",
++ EPERM => "Operation not permitted",
++ ENOENT => "No such file or directory",
++ ESRCH => "No such process",
++ EINTR => "Interrupted system call",
++ EIO => "I/O error",
++ ENXIO => "No such device or address",
++ E2BIG => "Argument list too long",
++ ENOEXEC => "Exec format error",
++ EBADF => "Bad file number",
++ ECHILD => "No child processes",
++ EAGAIN => "Try again",
++ ENOMEM => "Out of memory",
++ EACCES => "Permission denied",
++ EFAULT => "Bad address",
++ ENOTBLK => "Block device required",
++ EBUSY => "Device or resource busy",
++ EEXIST => "File exists",
++ EXDEV => "Cross-device link",
++ ENODEV => "No such device",
++ ENOTDIR => "Not a directory",
++ EISDIR => "Is a directory",
++ EINVAL => "Invalid argument",
++ ENFILE => "File table overflow",
++ EMFILE => "Too many open files",
++ ENOTTY => "Not a typewriter",
++ ETXTBSY => "Text file busy",
++ EFBIG => "File too large",
++ ENOSPC => "No space left on device",
++ ESPIPE => "Illegal seek",
++ EROFS => "Read-only file system",
++ EMLINK => "Too many links",
++ EPIPE => "Broken pipe",
++ EDOM => "Math argument out of domain of func",
++ ERANGE => "Math result not representable",
++ EDEADLK => "Resource deadlock would occur",
++ ENAMETOOLONG => "File name too long",
++ ENOLCK => "No record locks available",
++ ENOSYS => "Function not implemented",
++ ENOTEMPTY => "Directory not empty",
++ ELOOP => "Too many symbolic links encountered",
++ ENOMSG => "No message of desired type",
++ EIDRM => "Identifier removed",
++ EINPROGRESS => "Operation now in progress",
++ EALREADY => "Operation already in progress",
++ ENOTSOCK => "Socket operation on non-socket",
++ EDESTADDRREQ => "Destination address required",
++ EMSGSIZE => "Message too long",
++ EPROTOTYPE => "Protocol wrong type for socket",
++ ENOPROTOOPT => "Protocol not available",
++ EPROTONOSUPPORT => "Protocol not supported",
++ ESOCKTNOSUPPORT => "Socket type not supported",
++ EPFNOSUPPORT => "Protocol family not supported",
++ EAFNOSUPPORT => "Address family not supported by protocol",
++ EADDRINUSE => "Address already in use",
++ EADDRNOTAVAIL => "Cannot assign requested address",
++ ENETDOWN => "Network is down",
++ ENETUNREACH => "Network is unreachable",
++ ENETRESET => "Network dropped connection because of reset",
++ ECONNABORTED => "Software caused connection abort",
++ ECONNRESET => "Connection reset by peer",
++ ENOBUFS => "No buffer space available",
++ EISCONN => "Transport endpoint is already connected",
++ ENOTCONN => "Transport endpoint is not connected",
++ ESHUTDOWN => "Cannot send after transport endpoint shutdown",
++ ETOOMANYREFS => "Too many references: cannot splice",
++ ETIMEDOUT => "Connection timed out",
++ ECONNREFUSED => "Connection refused",
++ EHOSTDOWN => "Host is down",
++ EHOSTUNREACH => "No route to host",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ECHRNG => "Channel number out of range",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EL2NSYNC => "Level 2 not synchronized",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EL3HLT => "Level 3 halted",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EL3RST => "Level 3 reset",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ELNRNG => "Link number out of range",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EUNATCH => "Protocol driver not attached",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ENOCSI => "No CSI structure available",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EL2HLT => "Level 2 halted",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EBADE => "Invalid exchange",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EBADR => "Invalid request descriptor",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EXFULL => "Exchange full",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ENOANO => "No anode",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EBADRQC => "Invalid request code",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EBADSLT => "Invalid slot",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EBFONT => "Bad font file format",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ENOSTR => "Device not a stream",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ENODATA => "No data available",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ETIME => "Timer expired",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ENOSR => "Out of streams resources",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ENONET => "Machine is not on the network",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ENOPKG => "Package not installed",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EREMOTE => "Object is remote",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ENOLINK => "Link has been severed",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EADV => "Advertise error",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ESRMNT => "Srmount error",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ECOMM => "Communication error on send",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EPROTO => "Protocol error",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EMULTIHOP => "Multihop attempted",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EDOTDOT => "RFS specific error",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EBADMSG => "Not a data message",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EOVERFLOW => "Value too large for defined data type",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ENOTUNIQ => "Name not unique on network",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EBADFD => "File descriptor in bad state",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EREMCHG => "Remote address changed",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ELIBACC => "Can not access a needed shared library",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ELIBBAD => "Accessing a corrupted shared library",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ELIBSCN => ".lib section in a.out corrupted",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ELIBMAX => "Attempting to link in too many shared libraries",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ELIBEXEC => "Cannot exec a shared library directly",
++
++ #[cfg(any(target_os = "linux", target_os = "android", target_os = "openbsd"))]
++ EILSEQ => "Illegal byte sequence",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ERESTART => "Interrupted system call should be restarted",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ESTRPIPE => "Streams pipe error",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EUSERS => "Too many users",
++
++ #[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))]
++ EOPNOTSUPP => "Operation not supported on transport endpoint",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ESTALE => "Stale file handle",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EUCLEAN => "Structure needs cleaning",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ENOTNAM => "Not a XENIX named type file",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ENAVAIL => "No XENIX semaphores available",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EISNAM => "Is a named type file",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EREMOTEIO => "Remote I/O error",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EDQUOT => "Quota exceeded",
++
++ #[cfg(any(target_os = "linux", target_os = "android",
++ target_os = "openbsd", target_os = "dragonfly"))]
++ ENOMEDIUM => "No medium found",
++
++ #[cfg(any(target_os = "linux", target_os = "android", target_os = "openbsd"))]
++ EMEDIUMTYPE => "Wrong medium type",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ECANCELED => "Operation canceled",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ENOKEY => "Required key not available",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EKEYEXPIRED => "Key has expired",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EKEYREVOKED => "Key has been revoked",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EKEYREJECTED => "Key was rejected by service",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ EOWNERDEAD => "Owner died",
++
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ ENOTRECOVERABLE => "State not recoverable",
++
++ #[cfg(all(target_os = "linux", not(target_arch="mips")))]
++ ERFKILL => "Operation not possible due to RF-kill",
++
++ #[cfg(all(target_os = "linux", not(target_arch="mips")))]
++ EHWPOISON => "Memory page has hardware error",
++
++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
++ EDOOFUS => "Programming error",
++
++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
++ EMULTIHOP => "Multihop attempted",
++
++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
++ ENOLINK => "Link has been severed",
++
++ #[cfg(target_os = "freebsd")]
++ ENOTCAPABLE => "Capabilities insufficient",
++
++ #[cfg(target_os = "freebsd")]
++ ECAPMODE => "Not permitted in capability mode",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ ENEEDAUTH => "Need authenticator",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ EOVERFLOW => "Value too large to be stored in data type",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "netbsd"))]
++ EILSEQ => "Illegal byte sequence",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ ENOATTR => "Attribute not found",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ EBADMSG => "Bad message",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ EPROTO => "Protocol error",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "ios", target_os = "openbsd", ))]
++ ENOTRECOVERABLE => "State not recoverable",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "ios", target_os = "openbsd"))]
++ EOWNERDEAD => "Previous owner died",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ ENOTSUP => "Operation not supported",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ EPROCLIM => "Too many processes",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ EUSERS => "Too many users",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ EDQUOT => "Disc quota exceeded",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ ESTALE => "Stale NFS file handle",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ EREMOTE => "Too many levels of remote in path",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ EBADRPC => "RPC struct is bad",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ ERPCMISMATCH => "RPC version wrong",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ EPROGUNAVAIL => "RPC prog. not avail",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ EPROGMISMATCH => "Program version wrong",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ EPROCUNAVAIL => "Bad procedure for program",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ EFTYPE => "Inappropriate file type or format",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ EAUTH => "Authentication error",
++
++ #[cfg(any(target_os = "macos", target_os = "freebsd",
++ target_os = "dragonfly", target_os = "ios",
++ target_os = "openbsd", target_os = "netbsd"))]
++ ECANCELED => "Operation canceled",
++
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ EPWROFF => "Device power is off",
++
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ EDEVERR => "Device error, e.g. paper out",
++
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ EBADEXEC => "Bad executable",
++
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ EBADARCH => "Bad CPU type in executable",
++
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ ESHLIBVERS => "Shared library version mismatch",
++
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ EBADMACHO => "Malformed Macho file",
++
++ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
++ EMULTIHOP => "Reserved",
++
++ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
++ ENODATA => "No message available on STREAM",
++
++ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
++ ENOLINK => "Reserved",
++
++ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
++ ENOSR => "No STREAM resources",
++
++ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
++ ENOSTR => "Not a STREAM",
++
++ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
++ ETIME => "STREAM ioctl timeout",
++
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ EOPNOTSUPP => "Operation not supported on socket",
++
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ ENOPOLICY => "No such policy registered",
++
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ EQFULL => "Interface output queue is full",
++
++ #[cfg(target_os = "openbsd")]
++ EOPNOTSUPP => "Operation not supported",
++
++ #[cfg(target_os = "openbsd")]
++ EIPSEC => "IPsec processing failure",
++
++ #[cfg(target_os = "dragonfly")]
++ EASYNC => "Async",
++ }
++}
++
++#[cfg(any(target_os = "linux", target_os = "android"))]
++mod consts {
++ use libc;
++
++ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
++ #[repr(i32)]
++ pub enum Errno {
++ UnknownErrno = 0,
++ EPERM = libc::EPERM,
++ ENOENT = libc::ENOENT,
++ ESRCH = libc::ESRCH,
++ EINTR = libc::EINTR,
++ EIO = libc::EIO,
++ ENXIO = libc::ENXIO,
++ E2BIG = libc::E2BIG,
++ ENOEXEC = libc::ENOEXEC,
++ EBADF = libc::EBADF,
++ ECHILD = libc::ECHILD,
++ EAGAIN = libc::EAGAIN,
++ ENOMEM = libc::ENOMEM,
++ EACCES = libc::EACCES,
++ EFAULT = libc::EFAULT,
++ ENOTBLK = libc::ENOTBLK,
++ EBUSY = libc::EBUSY,
++ EEXIST = libc::EEXIST,
++ EXDEV = libc::EXDEV,
++ ENODEV = libc::ENODEV,
++ ENOTDIR = libc::ENOTDIR,
++ EISDIR = libc::EISDIR,
++ EINVAL = libc::EINVAL,
++ ENFILE = libc::ENFILE,
++ EMFILE = libc::EMFILE,
++ ENOTTY = libc::ENOTTY,
++ ETXTBSY = libc::ETXTBSY,
++ EFBIG = libc::EFBIG,
++ ENOSPC = libc::ENOSPC,
++ ESPIPE = libc::ESPIPE,
++ EROFS = libc::EROFS,
++ EMLINK = libc::EMLINK,
++ EPIPE = libc::EPIPE,
++ EDOM = libc::EDOM,
++ ERANGE = libc::ERANGE,
++ EDEADLK = libc::EDEADLK,
++ ENAMETOOLONG = libc::ENAMETOOLONG,
++ ENOLCK = libc::ENOLCK,
++ ENOSYS = libc::ENOSYS,
++ ENOTEMPTY = libc::ENOTEMPTY,
++ ELOOP = libc::ELOOP,
++ ENOMSG = libc::ENOMSG,
++ EIDRM = libc::EIDRM,
++ ECHRNG = libc::ECHRNG,
++ EL2NSYNC = libc::EL2NSYNC,
++ EL3HLT = libc::EL3HLT,
++ EL3RST = libc::EL3RST,
++ ELNRNG = libc::ELNRNG,
++ EUNATCH = libc::EUNATCH,
++ ENOCSI = libc::ENOCSI,
++ EL2HLT = libc::EL2HLT,
++ EBADE = libc::EBADE,
++ EBADR = libc::EBADR,
++ EXFULL = libc::EXFULL,
++ ENOANO = libc::ENOANO,
++ EBADRQC = libc::EBADRQC,
++ EBADSLT = libc::EBADSLT,
++ EBFONT = libc::EBFONT,
++ ENOSTR = libc::ENOSTR,
++ ENODATA = libc::ENODATA,
++ ETIME = libc::ETIME,
++ ENOSR = libc::ENOSR,
++ ENONET = libc::ENONET,
++ ENOPKG = libc::ENOPKG,
++ EREMOTE = libc::EREMOTE,
++ ENOLINK = libc::ENOLINK,
++ EADV = libc::EADV,
++ ESRMNT = libc::ESRMNT,
++ ECOMM = libc::ECOMM,
++ EPROTO = libc::EPROTO,
++ EMULTIHOP = libc::EMULTIHOP,
++ EDOTDOT = libc::EDOTDOT,
++ EBADMSG = libc::EBADMSG,
++ EOVERFLOW = libc::EOVERFLOW,
++ ENOTUNIQ = libc::ENOTUNIQ,
++ EBADFD = libc::EBADFD,
++ EREMCHG = libc::EREMCHG,
++ ELIBACC = libc::ELIBACC,
++ ELIBBAD = libc::ELIBBAD,
++ ELIBSCN = libc::ELIBSCN,
++ ELIBMAX = libc::ELIBMAX,
++ ELIBEXEC = libc::ELIBEXEC,
++ EILSEQ = libc::EILSEQ,
++ ERESTART = libc::ERESTART,
++ ESTRPIPE = libc::ESTRPIPE,
++ EUSERS = libc::EUSERS,
++ ENOTSOCK = libc::ENOTSOCK,
++ EDESTADDRREQ = libc::EDESTADDRREQ,
++ EMSGSIZE = libc::EMSGSIZE,
++ EPROTOTYPE = libc::EPROTOTYPE,
++ ENOPROTOOPT = libc::ENOPROTOOPT,
++ EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
++ ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
++ EOPNOTSUPP = libc::EOPNOTSUPP,
++ EPFNOSUPPORT = libc::EPFNOSUPPORT,
++ EAFNOSUPPORT = libc::EAFNOSUPPORT,
++ EADDRINUSE = libc::EADDRINUSE,
++ EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
++ ENETDOWN = libc::ENETDOWN,
++ ENETUNREACH = libc::ENETUNREACH,
++ ENETRESET = libc::ENETRESET,
++ ECONNABORTED = libc::ECONNABORTED,
++ ECONNRESET = libc::ECONNRESET,
++ ENOBUFS = libc::ENOBUFS,
++ EISCONN = libc::EISCONN,
++ ENOTCONN = libc::ENOTCONN,
++ ESHUTDOWN = libc::ESHUTDOWN,
++ ETOOMANYREFS = libc::ETOOMANYREFS,
++ ETIMEDOUT = libc::ETIMEDOUT,
++ ECONNREFUSED = libc::ECONNREFUSED,
++ EHOSTDOWN = libc::EHOSTDOWN,
++ EHOSTUNREACH = libc::EHOSTUNREACH,
++ EALREADY = libc::EALREADY,
++ EINPROGRESS = libc::EINPROGRESS,
++ ESTALE = libc::ESTALE,
++ EUCLEAN = libc::EUCLEAN,
++ ENOTNAM = libc::ENOTNAM,
++ ENAVAIL = libc::ENAVAIL,
++ EISNAM = libc::EISNAM,
++ EREMOTEIO = libc::EREMOTEIO,
++ EDQUOT = libc::EDQUOT,
++ ENOMEDIUM = libc::ENOMEDIUM,
++ EMEDIUMTYPE = libc::EMEDIUMTYPE,
++ ECANCELED = libc::ECANCELED,
++ ENOKEY = libc::ENOKEY,
++ EKEYEXPIRED = libc::EKEYEXPIRED,
++ EKEYREVOKED = libc::EKEYREVOKED,
++ EKEYREJECTED = libc::EKEYREJECTED,
++ EOWNERDEAD = libc::EOWNERDEAD,
++ ENOTRECOVERABLE = libc::ENOTRECOVERABLE,
++ #[cfg(not(any(target_os = "android", target_arch="mips")))]
++ ERFKILL = libc::ERFKILL,
++ #[cfg(not(any(target_os = "android", target_arch="mips")))]
++ EHWPOISON = libc::EHWPOISON,
++ }
++
++ pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
++ pub const EDEADLOCK: Errno = Errno::EDEADLK;
++ pub const ENOTSUP: Errno = Errno::EOPNOTSUPP;
++
++ pub fn from_i32(e: i32) -> Errno {
++ use self::Errno::*;
++
++ match e {
++ libc::EPERM => EPERM,
++ libc::ENOENT => ENOENT,
++ libc::ESRCH => ESRCH,
++ libc::EINTR => EINTR,
++ libc::EIO => EIO,
++ libc::ENXIO => ENXIO,
++ libc::E2BIG => E2BIG,
++ libc::ENOEXEC => ENOEXEC,
++ libc::EBADF => EBADF,
++ libc::ECHILD => ECHILD,
++ libc::EAGAIN => EAGAIN,
++ libc::ENOMEM => ENOMEM,
++ libc::EACCES => EACCES,
++ libc::EFAULT => EFAULT,
++ libc::ENOTBLK => ENOTBLK,
++ libc::EBUSY => EBUSY,
++ libc::EEXIST => EEXIST,
++ libc::EXDEV => EXDEV,
++ libc::ENODEV => ENODEV,
++ libc::ENOTDIR => ENOTDIR,
++ libc::EISDIR => EISDIR,
++ libc::EINVAL => EINVAL,
++ libc::ENFILE => ENFILE,
++ libc::EMFILE => EMFILE,
++ libc::ENOTTY => ENOTTY,
++ libc::ETXTBSY => ETXTBSY,
++ libc::EFBIG => EFBIG,
++ libc::ENOSPC => ENOSPC,
++ libc::ESPIPE => ESPIPE,
++ libc::EROFS => EROFS,
++ libc::EMLINK => EMLINK,
++ libc::EPIPE => EPIPE,
++ libc::EDOM => EDOM,
++ libc::ERANGE => ERANGE,
++ libc::EDEADLK => EDEADLK,
++ libc::ENAMETOOLONG => ENAMETOOLONG,
++ libc::ENOLCK => ENOLCK,
++ libc::ENOSYS => ENOSYS,
++ libc::ENOTEMPTY => ENOTEMPTY,
++ libc::ELOOP => ELOOP,
++ libc::ENOMSG => ENOMSG,
++ libc::EIDRM => EIDRM,
++ libc::ECHRNG => ECHRNG,
++ libc::EL2NSYNC => EL2NSYNC,
++ libc::EL3HLT => EL3HLT,
++ libc::EL3RST => EL3RST,
++ libc::ELNRNG => ELNRNG,
++ libc::EUNATCH => EUNATCH,
++ libc::ENOCSI => ENOCSI,
++ libc::EL2HLT => EL2HLT,
++ libc::EBADE => EBADE,
++ libc::EBADR => EBADR,
++ libc::EXFULL => EXFULL,
++ libc::ENOANO => ENOANO,
++ libc::EBADRQC => EBADRQC,
++ libc::EBADSLT => EBADSLT,
++ libc::EBFONT => EBFONT,
++ libc::ENOSTR => ENOSTR,
++ libc::ENODATA => ENODATA,
++ libc::ETIME => ETIME,
++ libc::ENOSR => ENOSR,
++ libc::ENONET => ENONET,
++ libc::ENOPKG => ENOPKG,
++ libc::EREMOTE => EREMOTE,
++ libc::ENOLINK => ENOLINK,
++ libc::EADV => EADV,
++ libc::ESRMNT => ESRMNT,
++ libc::ECOMM => ECOMM,
++ libc::EPROTO => EPROTO,
++ libc::EMULTIHOP => EMULTIHOP,
++ libc::EDOTDOT => EDOTDOT,
++ libc::EBADMSG => EBADMSG,
++ libc::EOVERFLOW => EOVERFLOW,
++ libc::ENOTUNIQ => ENOTUNIQ,
++ libc::EBADFD => EBADFD,
++ libc::EREMCHG => EREMCHG,
++ libc::ELIBACC => ELIBACC,
++ libc::ELIBBAD => ELIBBAD,
++ libc::ELIBSCN => ELIBSCN,
++ libc::ELIBMAX => ELIBMAX,
++ libc::ELIBEXEC => ELIBEXEC,
++ libc::EILSEQ => EILSEQ,
++ libc::ERESTART => ERESTART,
++ libc::ESTRPIPE => ESTRPIPE,
++ libc::EUSERS => EUSERS,
++ libc::ENOTSOCK => ENOTSOCK,
++ libc::EDESTADDRREQ => EDESTADDRREQ,
++ libc::EMSGSIZE => EMSGSIZE,
++ libc::EPROTOTYPE => EPROTOTYPE,
++ libc::ENOPROTOOPT => ENOPROTOOPT,
++ libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
++ libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
++ libc::EOPNOTSUPP => EOPNOTSUPP,
++ libc::EPFNOSUPPORT => EPFNOSUPPORT,
++ libc::EAFNOSUPPORT => EAFNOSUPPORT,
++ libc::EADDRINUSE => EADDRINUSE,
++ libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
++ libc::ENETDOWN => ENETDOWN,
++ libc::ENETUNREACH => ENETUNREACH,
++ libc::ENETRESET => ENETRESET,
++ libc::ECONNABORTED => ECONNABORTED,
++ libc::ECONNRESET => ECONNRESET,
++ libc::ENOBUFS => ENOBUFS,
++ libc::EISCONN => EISCONN,
++ libc::ENOTCONN => ENOTCONN,
++ libc::ESHUTDOWN => ESHUTDOWN,
++ libc::ETOOMANYREFS => ETOOMANYREFS,
++ libc::ETIMEDOUT => ETIMEDOUT,
++ libc::ECONNREFUSED => ECONNREFUSED,
++ libc::EHOSTDOWN => EHOSTDOWN,
++ libc::EHOSTUNREACH => EHOSTUNREACH,
++ libc::EALREADY => EALREADY,
++ libc::EINPROGRESS => EINPROGRESS,
++ libc::ESTALE => ESTALE,
++ libc::EUCLEAN => EUCLEAN,
++ libc::ENOTNAM => ENOTNAM,
++ libc::ENAVAIL => ENAVAIL,
++ libc::EISNAM => EISNAM,
++ libc::EREMOTEIO => EREMOTEIO,
++ libc::EDQUOT => EDQUOT,
++ libc::ENOMEDIUM => ENOMEDIUM,
++ libc::EMEDIUMTYPE => EMEDIUMTYPE,
++ libc::ECANCELED => ECANCELED,
++ libc::ENOKEY => ENOKEY,
++ libc::EKEYEXPIRED => EKEYEXPIRED,
++ libc::EKEYREVOKED => EKEYREVOKED,
++ libc::EKEYREJECTED => EKEYREJECTED,
++ libc::EOWNERDEAD => EOWNERDEAD,
++ libc::ENOTRECOVERABLE => ENOTRECOVERABLE,
++ #[cfg(not(any(target_os = "android", target_arch="mips")))]
++ libc::ERFKILL => ERFKILL,
++ #[cfg(not(any(target_os = "android", target_arch="mips")))]
++ libc::EHWPOISON => EHWPOISON,
++ _ => UnknownErrno,
++ }
++ }
++}
++
++#[cfg(any(target_os = "macos", target_os = "ios"))]
++mod consts {
++ use libc;
++
++ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
++ #[repr(i32)]
++ pub enum Errno {
++ UnknownErrno = 0,
++ EPERM = libc::EPERM,
++ ENOENT = libc::ENOENT,
++ ESRCH = libc::ESRCH,
++ EINTR = libc::EINTR,
++ EIO = libc::EIO,
++ ENXIO = libc::ENXIO,
++ E2BIG = libc::E2BIG,
++ ENOEXEC = libc::ENOEXEC,
++ EBADF = libc::EBADF,
++ ECHILD = libc::ECHILD,
++ EDEADLK = libc::EDEADLK,
++ ENOMEM = libc::ENOMEM,
++ EACCES = libc::EACCES,
++ EFAULT = libc::EFAULT,
++ ENOTBLK = libc::ENOTBLK,
++ EBUSY = libc::EBUSY,
++ EEXIST = libc::EEXIST,
++ EXDEV = libc::EXDEV,
++ ENODEV = libc::ENODEV,
++ ENOTDIR = libc::ENOTDIR,
++ EISDIR = libc::EISDIR,
++ EINVAL = libc::EINVAL,
++ ENFILE = libc::ENFILE,
++ EMFILE = libc::EMFILE,
++ ENOTTY = libc::ENOTTY,
++ ETXTBSY = libc::ETXTBSY,
++ EFBIG = libc::EFBIG,
++ ENOSPC = libc::ENOSPC,
++ ESPIPE = libc::ESPIPE,
++ EROFS = libc::EROFS,
++ EMLINK = libc::EMLINK,
++ EPIPE = libc::EPIPE,
++ EDOM = libc::EDOM,
++ ERANGE = libc::ERANGE,
++ EAGAIN = libc::EAGAIN,
++ EINPROGRESS = libc::EINPROGRESS,
++ EALREADY = libc::EALREADY,
++ ENOTSOCK = libc::ENOTSOCK,
++ EDESTADDRREQ = libc::EDESTADDRREQ,
++ EMSGSIZE = libc::EMSGSIZE,
++ EPROTOTYPE = libc::EPROTOTYPE,
++ ENOPROTOOPT = libc::ENOPROTOOPT,
++ EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
++ ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
++ ENOTSUP = libc::ENOTSUP,
++ EPFNOSUPPORT = libc::EPFNOSUPPORT,
++ EAFNOSUPPORT = libc::EAFNOSUPPORT,
++ EADDRINUSE = libc::EADDRINUSE,
++ EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
++ ENETDOWN = libc::ENETDOWN,
++ ENETUNREACH = libc::ENETUNREACH,
++ ENETRESET = libc::ENETRESET,
++ ECONNABORTED = libc::ECONNABORTED,
++ ECONNRESET = libc::ECONNRESET,
++ ENOBUFS = libc::ENOBUFS,
++ EISCONN = libc::EISCONN,
++ ENOTCONN = libc::ENOTCONN,
++ ESHUTDOWN = libc::ESHUTDOWN,
++ ETOOMANYREFS = libc::ETOOMANYREFS,
++ ETIMEDOUT = libc::ETIMEDOUT,
++ ECONNREFUSED = libc::ECONNREFUSED,
++ ELOOP = libc::ELOOP,
++ ENAMETOOLONG = libc::ENAMETOOLONG,
++ EHOSTDOWN = libc::EHOSTDOWN,
++ EHOSTUNREACH = libc::EHOSTUNREACH,
++ ENOTEMPTY = libc::ENOTEMPTY,
++ EPROCLIM = libc::EPROCLIM,
++ EUSERS = libc::EUSERS,
++ EDQUOT = libc::EDQUOT,
++ ESTALE = libc::ESTALE,
++ EREMOTE = libc::EREMOTE,
++ EBADRPC = libc::EBADRPC,
++ ERPCMISMATCH = libc::ERPCMISMATCH,
++ EPROGUNAVAIL = libc::EPROGUNAVAIL,
++ EPROGMISMATCH = libc::EPROGMISMATCH,
++ EPROCUNAVAIL = libc::EPROCUNAVAIL,
++ ENOLCK = libc::ENOLCK,
++ ENOSYS = libc::ENOSYS,
++ EFTYPE = libc::EFTYPE,
++ EAUTH = libc::EAUTH,
++ ENEEDAUTH = libc::ENEEDAUTH,
++ EPWROFF = libc::EPWROFF,
++ EDEVERR = libc::EDEVERR,
++ EOVERFLOW = libc::EOVERFLOW,
++ EBADEXEC = libc::EBADEXEC,
++ EBADARCH = libc::EBADARCH,
++ ESHLIBVERS = libc::ESHLIBVERS,
++ EBADMACHO = libc::EBADMACHO,
++ ECANCELED = libc::ECANCELED,
++ EIDRM = libc::EIDRM,
++ ENOMSG = libc::ENOMSG,
++ EILSEQ = libc::EILSEQ,
++ ENOATTR = libc::ENOATTR,
++ EBADMSG = libc::EBADMSG,
++ EMULTIHOP = libc::EMULTIHOP,
++ ENODATA = libc::ENODATA,
++ ENOLINK = libc::ENOLINK,
++ ENOSR = libc::ENOSR,
++ ENOSTR = libc::ENOSTR,
++ EPROTO = libc::EPROTO,
++ ETIME = libc::ETIME,
++ EOPNOTSUPP = libc::EOPNOTSUPP,
++ ENOPOLICY = libc::ENOPOLICY,
++ ENOTRECOVERABLE = libc::ENOTRECOVERABLE,
++ EOWNERDEAD = libc::EOWNERDEAD,
++ EQFULL = libc::EQFULL,
++ }
++
++ pub const ELAST: Errno = Errno::EQFULL;
++ pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
++ pub const EDEADLOCK: Errno = Errno::EDEADLK;
++
++ pub const EL2NSYNC: Errno = Errno::UnknownErrno;
++
++ pub fn from_i32(e: i32) -> Errno {
++ use self::Errno::*;
++
++ match e {
++ libc::EPERM => EPERM,
++ libc::ENOENT => ENOENT,
++ libc::ESRCH => ESRCH,
++ libc::EINTR => EINTR,
++ libc::EIO => EIO,
++ libc::ENXIO => ENXIO,
++ libc::E2BIG => E2BIG,
++ libc::ENOEXEC => ENOEXEC,
++ libc::EBADF => EBADF,
++ libc::ECHILD => ECHILD,
++ libc::EDEADLK => EDEADLK,
++ libc::ENOMEM => ENOMEM,
++ libc::EACCES => EACCES,
++ libc::EFAULT => EFAULT,
++ libc::ENOTBLK => ENOTBLK,
++ libc::EBUSY => EBUSY,
++ libc::EEXIST => EEXIST,
++ libc::EXDEV => EXDEV,
++ libc::ENODEV => ENODEV,
++ libc::ENOTDIR => ENOTDIR,
++ libc::EISDIR => EISDIR,
++ libc::EINVAL => EINVAL,
++ libc::ENFILE => ENFILE,
++ libc::EMFILE => EMFILE,
++ libc::ENOTTY => ENOTTY,
++ libc::ETXTBSY => ETXTBSY,
++ libc::EFBIG => EFBIG,
++ libc::ENOSPC => ENOSPC,
++ libc::ESPIPE => ESPIPE,
++ libc::EROFS => EROFS,
++ libc::EMLINK => EMLINK,
++ libc::EPIPE => EPIPE,
++ libc::EDOM => EDOM,
++ libc::ERANGE => ERANGE,
++ libc::EAGAIN => EAGAIN,
++ libc::EINPROGRESS => EINPROGRESS,
++ libc::EALREADY => EALREADY,
++ libc::ENOTSOCK => ENOTSOCK,
++ libc::EDESTADDRREQ => EDESTADDRREQ,
++ libc::EMSGSIZE => EMSGSIZE,
++ libc::EPROTOTYPE => EPROTOTYPE,
++ libc::ENOPROTOOPT => ENOPROTOOPT,
++ libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
++ libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
++ libc::ENOTSUP => ENOTSUP,
++ libc::EPFNOSUPPORT => EPFNOSUPPORT,
++ libc::EAFNOSUPPORT => EAFNOSUPPORT,
++ libc::EADDRINUSE => EADDRINUSE,
++ libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
++ libc::ENETDOWN => ENETDOWN,
++ libc::ENETUNREACH => ENETUNREACH,
++ libc::ENETRESET => ENETRESET,
++ libc::ECONNABORTED => ECONNABORTED,
++ libc::ECONNRESET => ECONNRESET,
++ libc::ENOBUFS => ENOBUFS,
++ libc::EISCONN => EISCONN,
++ libc::ENOTCONN => ENOTCONN,
++ libc::ESHUTDOWN => ESHUTDOWN,
++ libc::ETOOMANYREFS => ETOOMANYREFS,
++ libc::ETIMEDOUT => ETIMEDOUT,
++ libc::ECONNREFUSED => ECONNREFUSED,
++ libc::ELOOP => ELOOP,
++ libc::ENAMETOOLONG => ENAMETOOLONG,
++ libc::EHOSTDOWN => EHOSTDOWN,
++ libc::EHOSTUNREACH => EHOSTUNREACH,
++ libc::ENOTEMPTY => ENOTEMPTY,
++ libc::EPROCLIM => EPROCLIM,
++ libc::EUSERS => EUSERS,
++ libc::EDQUOT => EDQUOT,
++ libc::ESTALE => ESTALE,
++ libc::EREMOTE => EREMOTE,
++ libc::EBADRPC => EBADRPC,
++ libc::ERPCMISMATCH => ERPCMISMATCH,
++ libc::EPROGUNAVAIL => EPROGUNAVAIL,
++ libc::EPROGMISMATCH => EPROGMISMATCH,
++ libc::EPROCUNAVAIL => EPROCUNAVAIL,
++ libc::ENOLCK => ENOLCK,
++ libc::ENOSYS => ENOSYS,
++ libc::EFTYPE => EFTYPE,
++ libc::EAUTH => EAUTH,
++ libc::ENEEDAUTH => ENEEDAUTH,
++ libc::EPWROFF => EPWROFF,
++ libc::EDEVERR => EDEVERR,
++ libc::EOVERFLOW => EOVERFLOW,
++ libc::EBADEXEC => EBADEXEC,
++ libc::EBADARCH => EBADARCH,
++ libc::ESHLIBVERS => ESHLIBVERS,
++ libc::EBADMACHO => EBADMACHO,
++ libc::ECANCELED => ECANCELED,
++ libc::EIDRM => EIDRM,
++ libc::ENOMSG => ENOMSG,
++ libc::EILSEQ => EILSEQ,
++ libc::ENOATTR => ENOATTR,
++ libc::EBADMSG => EBADMSG,
++ libc::EMULTIHOP => EMULTIHOP,
++ libc::ENODATA => ENODATA,
++ libc::ENOLINK => ENOLINK,
++ libc::ENOSR => ENOSR,
++ libc::ENOSTR => ENOSTR,
++ libc::EPROTO => EPROTO,
++ libc::ETIME => ETIME,
++ libc::EOPNOTSUPP => EOPNOTSUPP,
++ libc::ENOPOLICY => ENOPOLICY,
++ libc::ENOTRECOVERABLE => ENOTRECOVERABLE,
++ libc::EOWNERDEAD => EOWNERDEAD,
++ libc::EQFULL => EQFULL,
++ _ => UnknownErrno,
++ }
++ }
++}
++
++#[cfg(target_os = "freebsd")]
++mod consts {
++ use libc;
++
++ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
++ #[repr(i32)]
++ pub enum Errno {
++ UnknownErrno = 0,
++ EPERM = libc::EPERM,
++ ENOENT = libc::ENOENT,
++ ESRCH = libc::ESRCH,
++ EINTR = libc::EINTR,
++ EIO = libc::EIO,
++ ENXIO = libc::ENXIO,
++ E2BIG = libc::E2BIG,
++ ENOEXEC = libc::ENOEXEC,
++ EBADF = libc::EBADF,
++ ECHILD = libc::ECHILD,
++ EDEADLK = libc::EDEADLK,
++ ENOMEM = libc::ENOMEM,
++ EACCES = libc::EACCES,
++ EFAULT = libc::EFAULT,
++ ENOTBLK = libc::ENOTBLK,
++ EBUSY = libc::EBUSY,
++ EEXIST = libc::EEXIST,
++ EXDEV = libc::EXDEV,
++ ENODEV = libc::ENODEV,
++ ENOTDIR = libc::ENOTDIR,
++ EISDIR = libc::EISDIR,
++ EINVAL = libc::EINVAL,
++ ENFILE = libc::ENFILE,
++ EMFILE = libc::EMFILE,
++ ENOTTY = libc::ENOTTY,
++ ETXTBSY = libc::ETXTBSY,
++ EFBIG = libc::EFBIG,
++ ENOSPC = libc::ENOSPC,
++ ESPIPE = libc::ESPIPE,
++ EROFS = libc::EROFS,
++ EMLINK = libc::EMLINK,
++ EPIPE = libc::EPIPE,
++ EDOM = libc::EDOM,
++ ERANGE = libc::ERANGE,
++ EAGAIN = libc::EAGAIN,
++ EINPROGRESS = libc::EINPROGRESS,
++ EALREADY = libc::EALREADY,
++ ENOTSOCK = libc::ENOTSOCK,
++ EDESTADDRREQ = libc::EDESTADDRREQ,
++ EMSGSIZE = libc::EMSGSIZE,
++ EPROTOTYPE = libc::EPROTOTYPE,
++ ENOPROTOOPT = libc::ENOPROTOOPT,
++ EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
++ ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
++ ENOTSUP = libc::ENOTSUP,
++ EPFNOSUPPORT = libc::EPFNOSUPPORT,
++ EAFNOSUPPORT = libc::EAFNOSUPPORT,
++ EADDRINUSE = libc::EADDRINUSE,
++ EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
++ ENETDOWN = libc::ENETDOWN,
++ ENETUNREACH = libc::ENETUNREACH,
++ ENETRESET = libc::ENETRESET,
++ ECONNABORTED = libc::ECONNABORTED,
++ ECONNRESET = libc::ECONNRESET,
++ ENOBUFS = libc::ENOBUFS,
++ EISCONN = libc::EISCONN,
++ ENOTCONN = libc::ENOTCONN,
++ ESHUTDOWN = libc::ESHUTDOWN,
++ ETOOMANYREFS = libc::ETOOMANYREFS,
++ ETIMEDOUT = libc::ETIMEDOUT,
++ ECONNREFUSED = libc::ECONNREFUSED,
++ ELOOP = libc::ELOOP,
++ ENAMETOOLONG = libc::ENAMETOOLONG,
++ EHOSTDOWN = libc::EHOSTDOWN,
++ EHOSTUNREACH = libc::EHOSTUNREACH,
++ ENOTEMPTY = libc::ENOTEMPTY,
++ EPROCLIM = libc::EPROCLIM,
++ EUSERS = libc::EUSERS,
++ EDQUOT = libc::EDQUOT,
++ ESTALE = libc::ESTALE,
++ EREMOTE = libc::EREMOTE,
++ EBADRPC = libc::EBADRPC,
++ ERPCMISMATCH = libc::ERPCMISMATCH,
++ EPROGUNAVAIL = libc::EPROGUNAVAIL,
++ EPROGMISMATCH = libc::EPROGMISMATCH,
++ EPROCUNAVAIL = libc::EPROCUNAVAIL,
++ ENOLCK = libc::ENOLCK,
++ ENOSYS = libc::ENOSYS,
++ EFTYPE = libc::EFTYPE,
++ EAUTH = libc::EAUTH,
++ ENEEDAUTH = libc::ENEEDAUTH,
++ EIDRM = libc::EIDRM,
++ ENOMSG = libc::ENOMSG,
++ EOVERFLOW = libc::EOVERFLOW,
++ ECANCELED = libc::ECANCELED,
++ EILSEQ = libc::EILSEQ,
++ ENOATTR = libc::ENOATTR,
++ EDOOFUS = libc::EDOOFUS,
++ EBADMSG = libc::EBADMSG,
++ EMULTIHOP = libc::EMULTIHOP,
++ ENOLINK = libc::ENOLINK,
++ EPROTO = libc::EPROTO,
++ ENOTCAPABLE = libc::ENOTCAPABLE,
++ ECAPMODE = libc::ECAPMODE,
++ ENOTRECOVERABLE = libc::ENOTRECOVERABLE,
++ EOWNERDEAD = libc::EOWNERDEAD,
++ }
++
++ pub const ELAST: Errno = Errno::EOWNERDEAD;
++ pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
++ pub const EDEADLOCK: Errno = Errno::EDEADLK;
++
++ pub const EL2NSYNC: Errno = Errno::UnknownErrno;
++
++ pub fn from_i32(e: i32) -> Errno {
++ use self::Errno::*;
++
++ match e {
++ libc::EPERM => EPERM,
++ libc::ENOENT => ENOENT,
++ libc::ESRCH => ESRCH,
++ libc::EINTR => EINTR,
++ libc::EIO => EIO,
++ libc::ENXIO => ENXIO,
++ libc::E2BIG => E2BIG,
++ libc::ENOEXEC => ENOEXEC,
++ libc::EBADF => EBADF,
++ libc::ECHILD => ECHILD,
++ libc::EDEADLK => EDEADLK,
++ libc::ENOMEM => ENOMEM,
++ libc::EACCES => EACCES,
++ libc::EFAULT => EFAULT,
++ libc::ENOTBLK => ENOTBLK,
++ libc::EBUSY => EBUSY,
++ libc::EEXIST => EEXIST,
++ libc::EXDEV => EXDEV,
++ libc::ENODEV => ENODEV,
++ libc::ENOTDIR => ENOTDIR,
++ libc::EISDIR => EISDIR,
++ libc::EINVAL => EINVAL,
++ libc::ENFILE => ENFILE,
++ libc::EMFILE => EMFILE,
++ libc::ENOTTY => ENOTTY,
++ libc::ETXTBSY => ETXTBSY,
++ libc::EFBIG => EFBIG,
++ libc::ENOSPC => ENOSPC,
++ libc::ESPIPE => ESPIPE,
++ libc::EROFS => EROFS,
++ libc::EMLINK => EMLINK,
++ libc::EPIPE => EPIPE,
++ libc::EDOM => EDOM,
++ libc::ERANGE => ERANGE,
++ libc::EAGAIN => EAGAIN,
++ libc::EINPROGRESS => EINPROGRESS,
++ libc::EALREADY => EALREADY,
++ libc::ENOTSOCK => ENOTSOCK,
++ libc::EDESTADDRREQ => EDESTADDRREQ,
++ libc::EMSGSIZE => EMSGSIZE,
++ libc::EPROTOTYPE => EPROTOTYPE,
++ libc::ENOPROTOOPT => ENOPROTOOPT,
++ libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
++ libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
++ libc::ENOTSUP => ENOTSUP,
++ libc::EPFNOSUPPORT => EPFNOSUPPORT,
++ libc::EAFNOSUPPORT => EAFNOSUPPORT,
++ libc::EADDRINUSE => EADDRINUSE,
++ libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
++ libc::ENETDOWN => ENETDOWN,
++ libc::ENETUNREACH => ENETUNREACH,
++ libc::ENETRESET => ENETRESET,
++ libc::ECONNABORTED => ECONNABORTED,
++ libc::ECONNRESET => ECONNRESET,
++ libc::ENOBUFS => ENOBUFS,
++ libc::EISCONN => EISCONN,
++ libc::ENOTCONN => ENOTCONN,
++ libc::ESHUTDOWN => ESHUTDOWN,
++ libc::ETOOMANYREFS => ETOOMANYREFS,
++ libc::ETIMEDOUT => ETIMEDOUT,
++ libc::ECONNREFUSED => ECONNREFUSED,
++ libc::ELOOP => ELOOP,
++ libc::ENAMETOOLONG => ENAMETOOLONG,
++ libc::EHOSTDOWN => EHOSTDOWN,
++ libc::EHOSTUNREACH => EHOSTUNREACH,
++ libc::ENOTEMPTY => ENOTEMPTY,
++ libc::EPROCLIM => EPROCLIM,
++ libc::EUSERS => EUSERS,
++ libc::EDQUOT => EDQUOT,
++ libc::ESTALE => ESTALE,
++ libc::EREMOTE => EREMOTE,
++ libc::EBADRPC => EBADRPC,
++ libc::ERPCMISMATCH => ERPCMISMATCH,
++ libc::EPROGUNAVAIL => EPROGUNAVAIL,
++ libc::EPROGMISMATCH => EPROGMISMATCH,
++ libc::EPROCUNAVAIL => EPROCUNAVAIL,
++ libc::ENOLCK => ENOLCK,
++ libc::ENOSYS => ENOSYS,
++ libc::EFTYPE => EFTYPE,
++ libc::EAUTH => EAUTH,
++ libc::ENEEDAUTH => ENEEDAUTH,
++ libc::EIDRM => EIDRM,
++ libc::ENOMSG => ENOMSG,
++ libc::EOVERFLOW => EOVERFLOW,
++ libc::ECANCELED => ECANCELED,
++ libc::EILSEQ => EILSEQ,
++ libc::ENOATTR => ENOATTR,
++ libc::EDOOFUS => EDOOFUS,
++ libc::EBADMSG => EBADMSG,
++ libc::EMULTIHOP => EMULTIHOP,
++ libc::ENOLINK => ENOLINK,
++ libc::EPROTO => EPROTO,
++ libc::ENOTCAPABLE => ENOTCAPABLE,
++ libc::ECAPMODE => ECAPMODE,
++ libc::ENOTRECOVERABLE => ENOTRECOVERABLE,
++ libc::EOWNERDEAD => EOWNERDEAD,
++ _ => UnknownErrno,
++ }
++ }
++}
++
++
++#[cfg(target_os = "dragonfly")]
++mod consts {
++ use libc;
++
++ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
++ #[repr(i32)]
++ pub enum Errno {
++ UnknownErrno = 0,
++ EPERM = libc::EPERM,
++ ENOENT = libc::ENOENT,
++ ESRCH = libc::ESRCH,
++ EINTR = libc::EINTR,
++ EIO = libc::EIO,
++ ENXIO = libc::ENXIO,
++ E2BIG = libc::E2BIG,
++ ENOEXEC = libc::ENOEXEC,
++ EBADF = libc::EBADF,
++ ECHILD = libc::ECHILD,
++ EDEADLK = libc::EDEADLK,
++ ENOMEM = libc::ENOMEM,
++ EACCES = libc::EACCES,
++ EFAULT = libc::EFAULT,
++ ENOTBLK = libc::ENOTBLK,
++ EBUSY = libc::EBUSY,
++ EEXIST = libc::EEXIST,
++ EXDEV = libc::EXDEV,
++ ENODEV = libc::ENODEV,
++ ENOTDIR = libc::ENOTDIR,
++ EISDIR = libc::EISDIR,
++ EINVAL = libc::EINVAL,
++ ENFILE = libc::ENFILE,
++ EMFILE = libc::EMFILE,
++ ENOTTY = libc::ENOTTY,
++ ETXTBSY = libc::ETXTBSY,
++ EFBIG = libc::EFBIG,
++ ENOSPC = libc::ENOSPC,
++ ESPIPE = libc::ESPIPE,
++ EROFS = libc::EROFS,
++ EMLINK = libc::EMLINK,
++ EPIPE = libc::EPIPE,
++ EDOM = libc::EDOM,
++ ERANGE = libc::ERANGE,
++ EAGAIN = libc::EAGAIN,
++ EINPROGRESS = libc::EINPROGRESS,
++ EALREADY = libc::EALREADY,
++ ENOTSOCK = libc::ENOTSOCK,
++ EDESTADDRREQ = libc::EDESTADDRREQ,
++ EMSGSIZE = libc::EMSGSIZE,
++ EPROTOTYPE = libc::EPROTOTYPE,
++ ENOPROTOOPT = libc::ENOPROTOOPT,
++ EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
++ ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
++ ENOTSUP = libc::ENOTSUP,
++ EPFNOSUPPORT = libc::EPFNOSUPPORT,
++ EAFNOSUPPORT = libc::EAFNOSUPPORT,
++ EADDRINUSE = libc::EADDRINUSE,
++ EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
++ ENETDOWN = libc::ENETDOWN,
++ ENETUNREACH = libc::ENETUNREACH,
++ ENETRESET = libc::ENETRESET,
++ ECONNABORTED = libc::ECONNABORTED,
++ ECONNRESET = libc::ECONNRESET,
++ ENOBUFS = libc::ENOBUFS,
++ EISCONN = libc::EISCONN,
++ ENOTCONN = libc::ENOTCONN,
++ ESHUTDOWN = libc::ESHUTDOWN,
++ ETOOMANYREFS = libc::ETOOMANYREFS,
++ ETIMEDOUT = libc::ETIMEDOUT,
++ ECONNREFUSED = libc::ECONNREFUSED,
++ ELOOP = libc::ELOOP,
++ ENAMETOOLONG = libc::ENAMETOOLONG,
++ EHOSTDOWN = libc::EHOSTDOWN,
++ EHOSTUNREACH = libc::EHOSTUNREACH,
++ ENOTEMPTY = libc::ENOTEMPTY,
++ EPROCLIM = libc::EPROCLIM,
++ EUSERS = libc::EUSERS,
++ EDQUOT = libc::EDQUOT,
++ ESTALE = libc::ESTALE,
++ EREMOTE = libc::EREMOTE,
++ EBADRPC = libc::EBADRPC,
++ ERPCMISMATCH = libc::ERPCMISMATCH,
++ EPROGUNAVAIL = libc::EPROGUNAVAIL,
++ EPROGMISMATCH = libc::EPROGMISMATCH,
++ EPROCUNAVAIL = libc::EPROCUNAVAIL,
++ ENOLCK = libc::ENOLCK,
++ ENOSYS = libc::ENOSYS,
++ EFTYPE = libc::EFTYPE,
++ EAUTH = libc::EAUTH,
++ ENEEDAUTH = libc::ENEEDAUTH,
++ EIDRM = libc::EIDRM,
++ ENOMSG = libc::ENOMSG,
++ EOVERFLOW = libc::EOVERFLOW,
++ ECANCELED = libc::ECANCELED,
++ EILSEQ = libc::EILSEQ,
++ ENOATTR = libc::ENOATTR,
++ EDOOFUS = libc::EDOOFUS,
++ EBADMSG = libc::EBADMSG,
++ EMULTIHOP = libc::EMULTIHOP,
++ ENOLINK = libc::ENOLINK,
++ EPROTO = libc::EPROTO,
++ ENOMEDIUM = libc::ENOMEDIUM,
++ EASYNC = libc::EASYNC,
++ }
++
++ pub const ELAST: Errno = Errno::EASYNC;
++ pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
++ pub const EDEADLOCK: Errno = Errno::EDEADLK;
++ pub const EOPNOTSUPP: Errno = Errno::ENOTSUP;
++
++ pub const EL2NSYNC: Errno = Errno::UnknownErrno;
++
++ pub fn from_i32(e: i32) -> Errno {
++ use self::Errno::*;
++
++ match e {
++ libc::EPERM => EPERM,
++ libc::ENOENT => ENOENT,
++ libc::ESRCH => ESRCH,
++ libc::EINTR => EINTR,
++ libc::EIO => EIO,
++ libc::ENXIO => ENXIO,
++ libc::E2BIG => E2BIG,
++ libc::ENOEXEC => ENOEXEC,
++ libc::EBADF => EBADF,
++ libc::ECHILD => ECHILD,
++ libc::EDEADLK => EDEADLK,
++ libc::ENOMEM => ENOMEM,
++ libc::EACCES => EACCES,
++ libc::EFAULT => EFAULT,
++ libc::ENOTBLK => ENOTBLK,
++ libc::EBUSY => EBUSY,
++ libc::EEXIST => EEXIST,
++ libc::EXDEV => EXDEV,
++ libc::ENODEV => ENODEV,
++ libc::ENOTDIR => ENOTDIR,
++ libc::EISDIR=> EISDIR,
++ libc::EINVAL => EINVAL,
++ libc::ENFILE => ENFILE,
++ libc::EMFILE => EMFILE,
++ libc::ENOTTY => ENOTTY,
++ libc::ETXTBSY => ETXTBSY,
++ libc::EFBIG => EFBIG,
++ libc::ENOSPC => ENOSPC,
++ libc::ESPIPE => ESPIPE,
++ libc::EROFS => EROFS,
++ libc::EMLINK => EMLINK,
++ libc::EPIPE => EPIPE,
++ libc::EDOM => EDOM,
++ libc::ERANGE => ERANGE,
++ libc::EAGAIN => EAGAIN,
++ libc::EINPROGRESS => EINPROGRESS,
++ libc::EALREADY => EALREADY,
++ libc::ENOTSOCK => ENOTSOCK,
++ libc::EDESTADDRREQ => EDESTADDRREQ,
++ libc::EMSGSIZE => EMSGSIZE,
++ libc::EPROTOTYPE => EPROTOTYPE,
++ libc::ENOPROTOOPT => ENOPROTOOPT,
++ libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
++ libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
++ libc::ENOTSUP => ENOTSUP,
++ libc::EPFNOSUPPORT => EPFNOSUPPORT,
++ libc::EAFNOSUPPORT => EAFNOSUPPORT,
++ libc::EADDRINUSE => EADDRINUSE,
++ libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
++ libc::ENETDOWN => ENETDOWN,
++ libc::ENETUNREACH => ENETUNREACH,
++ libc::ENETRESET => ENETRESET,
++ libc::ECONNABORTED => ECONNABORTED,
++ libc::ECONNRESET => ECONNRESET,
++ libc::ENOBUFS => ENOBUFS,
++ libc::EISCONN => EISCONN,
++ libc::ENOTCONN => ENOTCONN,
++ libc::ESHUTDOWN => ESHUTDOWN,
++ libc::ETOOMANYREFS => ETOOMANYREFS,
++ libc::ETIMEDOUT => ETIMEDOUT,
++ libc::ECONNREFUSED => ECONNREFUSED,
++ libc::ELOOP => ELOOP,
++ libc::ENAMETOOLONG => ENAMETOOLONG,
++ libc::EHOSTDOWN => EHOSTDOWN,
++ libc::EHOSTUNREACH => EHOSTUNREACH,
++ libc::ENOTEMPTY => ENOTEMPTY,
++ libc::EPROCLIM => EPROCLIM,
++ libc::EUSERS => EUSERS,
++ libc::EDQUOT => EDQUOT,
++ libc::ESTALE => ESTALE,
++ libc::EREMOTE => EREMOTE,
++ libc::EBADRPC => EBADRPC,
++ libc::ERPCMISMATCH => ERPCMISMATCH,
++ libc::EPROGUNAVAIL => EPROGUNAVAIL,
++ libc::EPROGMISMATCH => EPROGMISMATCH,
++ libc::EPROCUNAVAIL => EPROCUNAVAIL,
++ libc::ENOLCK => ENOLCK,
++ libc::ENOSYS => ENOSYS,
++ libc::EFTYPE => EFTYPE,
++ libc::EAUTH => EAUTH,
++ libc::ENEEDAUTH => ENEEDAUTH,
++ libc::EIDRM => EIDRM,
++ libc::ENOMSG => ENOMSG,
++ libc::EOVERFLOW => EOVERFLOW,
++ libc::ECANCELED => ECANCELED,
++ libc::EILSEQ => EILSEQ,
++ libc::ENOATTR => ENOATTR,
++ libc::EDOOFUS => EDOOFUS,
++ libc::EBADMSG => EBADMSG,
++ libc::EMULTIHOP => EMULTIHOP,
++ libc::ENOLINK => ENOLINK,
++ libc::EPROTO => EPROTO,
++ libc::ENOMEDIUM => ENOMEDIUM,
++ libc::EASYNC => EASYNC,
++ _ => UnknownErrno,
++ }
++ }
++}
++
++
++#[cfg(target_os = "openbsd")]
++mod consts {
++ use libc;
++
++ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
++ #[repr(i32)]
++ pub enum Errno {
++ UnknownErrno = 0,
++ EPERM = libc::EPERM,
++ ENOENT = libc::ENOENT,
++ ESRCH = libc::ESRCH,
++ EINTR = libc::EINTR,
++ EIO = libc::EIO,
++ ENXIO = libc::ENXIO,
++ E2BIG = libc::E2BIG,
++ ENOEXEC = libc::ENOEXEC,
++ EBADF = libc::EBADF,
++ ECHILD = libc::ECHILD,
++ EDEADLK = libc::EDEADLK,
++ ENOMEM = libc::ENOMEM,
++ EACCES = libc::EACCES,
++ EFAULT = libc::EFAULT,
++ ENOTBLK = libc::ENOTBLK,
++ EBUSY = libc::EBUSY,
++ EEXIST = libc::EEXIST,
++ EXDEV = libc::EXDEV,
++ ENODEV = libc::ENODEV,
++ ENOTDIR = libc::ENOTDIR,
++ EISDIR = libc::EISDIR,
++ EINVAL = libc::EINVAL,
++ ENFILE = libc::ENFILE,
++ EMFILE = libc::EMFILE,
++ ENOTTY = libc::ENOTTY,
++ ETXTBSY = libc::ETXTBSY,
++ EFBIG = libc::EFBIG,
++ ENOSPC = libc::ENOSPC,
++ ESPIPE = libc::ESPIPE,
++ EROFS = libc::EROFS,
++ EMLINK = libc::EMLINK,
++ EPIPE = libc::EPIPE,
++ EDOM = libc::EDOM,
++ ERANGE = libc::ERANGE,
++ EAGAIN = libc::EAGAIN,
++ EINPROGRESS = libc::EINPROGRESS,
++ EALREADY = libc::EALREADY,
++ ENOTSOCK = libc::ENOTSOCK,
++ EDESTADDRREQ = libc::EDESTADDRREQ,
++ EMSGSIZE = libc::EMSGSIZE,
++ EPROTOTYPE = libc::EPROTOTYPE,
++ ENOPROTOOPT = libc::ENOPROTOOPT,
++ EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
++ ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
++ EOPNOTSUPP = libc::EOPNOTSUPP,
++ EPFNOSUPPORT = libc::EPFNOSUPPORT,
++ EAFNOSUPPORT = libc::EAFNOSUPPORT,
++ EADDRINUSE = libc::EADDRINUSE,
++ EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
++ ENETDOWN = libc::ENETDOWN,
++ ENETUNREACH = libc::ENETUNREACH,
++ ENETRESET = libc::ENETRESET,
++ ECONNABORTED = libc::ECONNABORTED,
++ ECONNRESET = libc::ECONNRESET,
++ ENOBUFS = libc::ENOBUFS,
++ EISCONN = libc::EISCONN,
++ ENOTCONN = libc::ENOTCONN,
++ ESHUTDOWN = libc::ESHUTDOWN,
++ ETOOMANYREFS = libc::ETOOMANYREFS,
++ ETIMEDOUT = libc::ETIMEDOUT,
++ ECONNREFUSED = libc::ECONNREFUSED,
++ ELOOP = libc::ELOOP,
++ ENAMETOOLONG = libc::ENAMETOOLONG,
++ EHOSTDOWN = libc::EHOSTDOWN,
++ EHOSTUNREACH = libc::EHOSTUNREACH,
++ ENOTEMPTY = libc::ENOTEMPTY,
++ EPROCLIM = libc::EPROCLIM,
++ EUSERS = libc::EUSERS,
++ EDQUOT = libc::EDQUOT,
++ ESTALE = libc::ESTALE,
++ EREMOTE = libc::EREMOTE,
++ EBADRPC = libc::EBADRPC,
++ ERPCMISMATCH = libc::ERPCMISMATCH,
++ EPROGUNAVAIL = libc::EPROGUNAVAIL,
++ EPROGMISMATCH = libc::EPROGMISMATCH,
++ EPROCUNAVAIL = libc::EPROCUNAVAIL,
++ ENOLCK = libc::ENOLCK,
++ ENOSYS = libc::ENOSYS,
++ EFTYPE = libc::EFTYPE,
++ EAUTH = libc::EAUTH,
++ ENEEDAUTH = libc::ENEEDAUTH,
++ EIPSEC = libc::EIPSEC,
++ ENOATTR = libc::ENOATTR,
++ EILSEQ = libc::EILSEQ,
++ ENOMEDIUM = libc::ENOMEDIUM,
++ EMEDIUMTYPE = libc::EMEDIUMTYPE,
++ EOVERFLOW = libc::EOVERFLOW,
++ ECANCELED = libc::ECANCELED,
++ EIDRM = libc::EIDRM,
++ ENOMSG = libc::ENOMSG,
++ ENOTSUP = libc::ENOTSUP,
++ EBADMSG = libc::EBADMSG,
++ ENOTRECOVERABLE = libc::ENOTRECOVERABLE,
++ EOWNERDEAD = libc::EOWNERDEAD,
++ EPROTO = libc::EPROTO,
++ }
++
++ pub const ELAST: Errno = Errno::ENOTSUP;
++ pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
++
++ pub const EL2NSYNC: Errno = Errno::UnknownErrno;
++
++ pub fn from_i32(e: i32) -> Errno {
++ use self::Errno::*;
++
++ match e {
++ libc::EPERM => EPERM,
++ libc::ENOENT => ENOENT,
++ libc::ESRCH => ESRCH,
++ libc::EINTR => EINTR,
++ libc::EIO => EIO,
++ libc::ENXIO => ENXIO,
++ libc::E2BIG => E2BIG,
++ libc::ENOEXEC => ENOEXEC,
++ libc::EBADF => EBADF,
++ libc::ECHILD => ECHILD,
++ libc::EDEADLK => EDEADLK,
++ libc::ENOMEM => ENOMEM,
++ libc::EACCES => EACCES,
++ libc::EFAULT => EFAULT,
++ libc::ENOTBLK => ENOTBLK,
++ libc::EBUSY => EBUSY,
++ libc::EEXIST => EEXIST,
++ libc::EXDEV => EXDEV,
++ libc::ENODEV => ENODEV,
++ libc::ENOTDIR => ENOTDIR,
++ libc::EISDIR => EISDIR,
++ libc::EINVAL => EINVAL,
++ libc::ENFILE => ENFILE,
++ libc::EMFILE => EMFILE,
++ libc::ENOTTY => ENOTTY,
++ libc::ETXTBSY => ETXTBSY,
++ libc::EFBIG => EFBIG,
++ libc::ENOSPC => ENOSPC,
++ libc::ESPIPE => ESPIPE,
++ libc::EROFS => EROFS,
++ libc::EMLINK => EMLINK,
++ libc::EPIPE => EPIPE,
++ libc::EDOM => EDOM,
++ libc::ERANGE => ERANGE,
++ libc::EAGAIN => EAGAIN,
++ libc::EINPROGRESS => EINPROGRESS,
++ libc::EALREADY => EALREADY,
++ libc::ENOTSOCK => ENOTSOCK,
++ libc::EDESTADDRREQ => EDESTADDRREQ,
++ libc::EMSGSIZE => EMSGSIZE,
++ libc::EPROTOTYPE => EPROTOTYPE,
++ libc::ENOPROTOOPT => ENOPROTOOPT,
++ libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
++ libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
++ libc::EOPNOTSUPP => EOPNOTSUPP,
++ libc::EPFNOSUPPORT => EPFNOSUPPORT,
++ libc::EAFNOSUPPORT => EAFNOSUPPORT,
++ libc::EADDRINUSE => EADDRINUSE,
++ libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
++ libc::ENETDOWN => ENETDOWN,
++ libc::ENETUNREACH => ENETUNREACH,
++ libc::ENETRESET => ENETRESET,
++ libc::ECONNABORTED => ECONNABORTED,
++ libc::ECONNRESET => ECONNRESET,
++ libc::ENOBUFS => ENOBUFS,
++ libc::EISCONN => EISCONN,
++ libc::ENOTCONN => ENOTCONN,
++ libc::ESHUTDOWN => ESHUTDOWN,
++ libc::ETOOMANYREFS => ETOOMANYREFS,
++ libc::ETIMEDOUT => ETIMEDOUT,
++ libc::ECONNREFUSED => ECONNREFUSED,
++ libc::ELOOP => ELOOP,
++ libc::ENAMETOOLONG => ENAMETOOLONG,
++ libc::EHOSTDOWN => EHOSTDOWN,
++ libc::EHOSTUNREACH => EHOSTUNREACH,
++ libc::ENOTEMPTY => ENOTEMPTY,
++ libc::EPROCLIM => EPROCLIM,
++ libc::EUSERS => EUSERS,
++ libc::EDQUOT => EDQUOT,
++ libc::ESTALE => ESTALE,
++ libc::EREMOTE => EREMOTE,
++ libc::EBADRPC => EBADRPC,
++ libc::ERPCMISMATCH => ERPCMISMATCH,
++ libc::EPROGUNAVAIL => EPROGUNAVAIL,
++ libc::EPROGMISMATCH => EPROGMISMATCH,
++ libc::EPROCUNAVAIL => EPROCUNAVAIL,
++ libc::ENOLCK => ENOLCK,
++ libc::ENOSYS => ENOSYS,
++ libc::EFTYPE => EFTYPE,
++ libc::EAUTH => EAUTH,
++ libc::ENEEDAUTH => ENEEDAUTH,
++ libc::EIPSEC => EIPSEC,
++ libc::ENOATTR => ENOATTR,
++ libc::EILSEQ => EILSEQ,
++ libc::ENOMEDIUM => ENOMEDIUM,
++ libc::EMEDIUMTYPE => EMEDIUMTYPE,
++ libc::EOVERFLOW => EOVERFLOW,
++ libc::ECANCELED => ECANCELED,
++ libc::EIDRM => EIDRM,
++ libc::ENOMSG => ENOMSG,
++ libc::ENOTSUP => ENOTSUP,
++ libc::EBADMSG => EBADMSG,
++ libc::ENOTRECOVERABLE => ENOTRECOVERABLE,
++ libc::EOWNERDEAD => EOWNERDEAD,
++ libc::EPROTO => EPROTO,
++ _ => UnknownErrno,
++ }
++ }
++}
++
++#[cfg(target_os = "netbsd")]
++mod consts {
++ use libc;
++
++ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
++ #[repr(i32)]
++ pub enum Errno {
++ UnknownErrno = 0,
++ EPERM = libc::EPERM,
++ ENOENT = libc::ENOENT,
++ ESRCH = libc::ESRCH,
++ EINTR = libc::EINTR,
++ EIO = libc::EIO,
++ ENXIO = libc::ENXIO,
++ E2BIG = libc::E2BIG,
++ ENOEXEC = libc::ENOEXEC,
++ EBADF = libc::EBADF,
++ ECHILD = libc::ECHILD,
++ EDEADLK = libc::EDEADLK,
++ ENOMEM = libc::ENOMEM,
++ EACCES = libc::EACCES,
++ EFAULT = libc::EFAULT,
++ ENOTBLK = libc::ENOTBLK,
++ EBUSY = libc::EBUSY,
++ EEXIST = libc::EEXIST,
++ EXDEV = libc::EXDEV,
++ ENODEV = libc::ENODEV,
++ ENOTDIR = libc::ENOTDIR,
++ EISDIR = libc::EISDIR,
++ EINVAL = libc::EINVAL,
++ ENFILE = libc::ENFILE,
++ EMFILE = libc::EMFILE,
++ ENOTTY = libc::ENOTTY,
++ ETXTBSY = libc::ETXTBSY,
++ EFBIG = libc::EFBIG,
++ ENOSPC = libc::ENOSPC,
++ ESPIPE = libc::ESPIPE,
++ EROFS = libc::EROFS,
++ EMLINK = libc::EMLINK,
++ EPIPE = libc::EPIPE,
++ EDOM = libc::EDOM,
++ ERANGE = libc::ERANGE,
++ EAGAIN = libc::EAGAIN,
++ EINPROGRESS = libc::EINPROGRESS,
++ EALREADY = libc::EALREADY,
++ ENOTSOCK = libc::ENOTSOCK,
++ EDESTADDRREQ = libc::EDESTADDRREQ,
++ EMSGSIZE = libc::EMSGSIZE,
++ EPROTOTYPE = libc::EPROTOTYPE,
++ ENOPROTOOPT = libc::ENOPROTOOPT,
++ EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
++ ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
++ EOPNOTSUPP = libc::EOPNOTSUPP,
++ EPFNOSUPPORT = libc::EPFNOSUPPORT,
++ EAFNOSUPPORT = libc::EAFNOSUPPORT,
++ EADDRINUSE = libc::EADDRINUSE,
++ EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
++ ENETDOWN = libc::ENETDOWN,
++ ENETUNREACH = libc::ENETUNREACH,
++ ENETRESET = libc::ENETRESET,
++ ECONNABORTED = libc::ECONNABORTED,
++ ECONNRESET = libc::ECONNRESET,
++ ENOBUFS = libc::ENOBUFS,
++ EISCONN = libc::EISCONN,
++ ENOTCONN = libc::ENOTCONN,
++ ESHUTDOWN = libc::ESHUTDOWN,
++ ETOOMANYREFS = libc::ETOOMANYREFS,
++ ETIMEDOUT = libc::ETIMEDOUT,
++ ECONNREFUSED = libc::ECONNREFUSED,
++ ELOOP = libc::ELOOP,
++ ENAMETOOLONG = libc::ENAMETOOLONG,
++ EHOSTDOWN = libc::EHOSTDOWN,
++ EHOSTUNREACH = libc::EHOSTUNREACH,
++ ENOTEMPTY = libc::ENOTEMPTY,
++ EPROCLIM = libc::EPROCLIM,
++ EUSERS = libc::EUSERS,
++ EDQUOT = libc::EDQUOT,
++ ESTALE = libc::ESTALE,
++ EREMOTE = libc::EREMOTE,
++ EBADRPC = libc::EBADRPC,
++ ERPCMISMATCH = libc::ERPCMISMATCH,
++ EPROGUNAVAIL = libc::EPROGUNAVAIL,
++ EPROGMISMATCH = libc::EPROGMISMATCH,
++ EPROCUNAVAIL = libc::EPROCUNAVAIL,
++ ENOLCK = libc::ENOLCK,
++ ENOSYS = libc::ENOSYS,
++ EFTYPE = libc::EFTYPE,
++ EAUTH = libc::EAUTH,
++ ENEEDAUTH = libc::ENEEDAUTH,
++ EIDRM = libc::EIDRM,
++ ENOMSG = libc::ENOMSG,
++ EOVERFLOW = libc::EOVERFLOW,
++ EILSEQ = libc::EILSEQ,
++ ENOTSUP = libc::ENOTSUP,
++ ECANCELED = libc::ECANCELED,
++ EBADMSG = libc::EBADMSG,
++ ENODATA = libc::ENODATA,
++ ENOSR = libc::ENOSR,
++ ENOSTR = libc::ENOSTR,
++ ETIME = libc::ETIME,
++ ENOATTR = libc::ENOATTR,
++ EMULTIHOP = libc::EMULTIHOP,
++ ENOLINK = libc::ENOLINK,
++ EPROTO = libc::EPROTO,
++ }
++
++ pub const ELAST: Errno = Errno::ENOTSUP;
++ pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
++
++ pub const EL2NSYNC: Errno = Errno::UnknownErrno;
++
++ pub fn from_i32(e: i32) -> Errno {
++ use self::Errno::*;
++
++ match e {
++ libc::EPERM => EPERM,
++ libc::ENOENT => ENOENT,
++ libc::ESRCH => ESRCH,
++ libc::EINTR => EINTR,
++ libc::EIO => EIO,
++ libc::ENXIO => ENXIO,
++ libc::E2BIG => E2BIG,
++ libc::ENOEXEC => ENOEXEC,
++ libc::EBADF => EBADF,
++ libc::ECHILD => ECHILD,
++ libc::EDEADLK => EDEADLK,
++ libc::ENOMEM => ENOMEM,
++ libc::EACCES => EACCES,
++ libc::EFAULT => EFAULT,
++ libc::ENOTBLK => ENOTBLK,
++ libc::EBUSY => EBUSY,
++ libc::EEXIST => EEXIST,
++ libc::EXDEV => EXDEV,
++ libc::ENODEV => ENODEV,
++ libc::ENOTDIR => ENOTDIR,
++ libc::EISDIR => EISDIR,
++ libc::EINVAL => EINVAL,
++ libc::ENFILE => ENFILE,
++ libc::EMFILE => EMFILE,
++ libc::ENOTTY => ENOTTY,
++ libc::ETXTBSY => ETXTBSY,
++ libc::EFBIG => EFBIG,
++ libc::ENOSPC => ENOSPC,
++ libc::ESPIPE => ESPIPE,
++ libc::EROFS => EROFS,
++ libc::EMLINK => EMLINK,
++ libc::EPIPE => EPIPE,
++ libc::EDOM => EDOM,
++ libc::ERANGE => ERANGE,
++ libc::EAGAIN => EAGAIN,
++ libc::EINPROGRESS => EINPROGRESS,
++ libc::EALREADY => EALREADY,
++ libc::ENOTSOCK => ENOTSOCK,
++ libc::EDESTADDRREQ => EDESTADDRREQ,
++ libc::EMSGSIZE => EMSGSIZE,
++ libc::EPROTOTYPE => EPROTOTYPE,
++ libc::ENOPROTOOPT => ENOPROTOOPT,
++ libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
++ libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
++ libc::EOPNOTSUPP => EOPNOTSUPP,
++ libc::EPFNOSUPPORT => EPFNOSUPPORT,
++ libc::EAFNOSUPPORT => EAFNOSUPPORT,
++ libc::EADDRINUSE => EADDRINUSE,
++ libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
++ libc::ENETDOWN => ENETDOWN,
++ libc::ENETUNREACH => ENETUNREACH,
++ libc::ENETRESET => ENETRESET,
++ libc::ECONNABORTED => ECONNABORTED,
++ libc::ECONNRESET => ECONNRESET,
++ libc::ENOBUFS => ENOBUFS,
++ libc::EISCONN => EISCONN,
++ libc::ENOTCONN => ENOTCONN,
++ libc::ESHUTDOWN => ESHUTDOWN,
++ libc::ETOOMANYREFS => ETOOMANYREFS,
++ libc::ETIMEDOUT => ETIMEDOUT,
++ libc::ECONNREFUSED => ECONNREFUSED,
++ libc::ELOOP => ELOOP,
++ libc::ENAMETOOLONG => ENAMETOOLONG,
++ libc::EHOSTDOWN => EHOSTDOWN,
++ libc::EHOSTUNREACH => EHOSTUNREACH,
++ libc::ENOTEMPTY => ENOTEMPTY,
++ libc::EPROCLIM => EPROCLIM,
++ libc::EUSERS => EUSERS,
++ libc::EDQUOT => EDQUOT,
++ libc::ESTALE => ESTALE,
++ libc::EREMOTE => EREMOTE,
++ libc::EBADRPC => EBADRPC,
++ libc::ERPCMISMATCH => ERPCMISMATCH,
++ libc::EPROGUNAVAIL => EPROGUNAVAIL,
++ libc::EPROGMISMATCH => EPROGMISMATCH,
++ libc::EPROCUNAVAIL => EPROCUNAVAIL,
++ libc::ENOLCK => ENOLCK,
++ libc::ENOSYS => ENOSYS,
++ libc::EFTYPE => EFTYPE,
++ libc::EAUTH => EAUTH,
++ libc::ENEEDAUTH => ENEEDAUTH,
++ libc::EIDRM => EIDRM,
++ libc::ENOMSG => ENOMSG,
++ libc::EOVERFLOW => EOVERFLOW,
++ libc::EILSEQ => EILSEQ,
++ libc::ENOTSUP => ENOTSUP,
++ libc::ECANCELED => ECANCELED,
++ libc::EBADMSG => EBADMSG,
++ libc::ENODATA => ENODATA,
++ libc::ENOSR => ENOSR,
++ libc::ENOSTR => ENOSTR,
++ libc::ETIME => ETIME,
++ libc::ENOATTR => ENOATTR,
++ libc::EMULTIHOP => EMULTIHOP,
++ libc::ENOLINK => ENOLINK,
++ libc::EPROTO => EPROTO,
++ _ => UnknownErrno,
++ }
++ }
++}
+diff --git a/third_party/rust/nix/src/errno_dragonfly.c b/third_party/rust/nix-0.15.0/src/errno_dragonfly.c
+similarity index 100%
+rename from third_party/rust/nix/src/errno_dragonfly.c
+rename to third_party/rust/nix-0.15.0/src/errno_dragonfly.c
+diff --git a/third_party/rust/nix-0.15.0/src/fcntl.rs b/third_party/rust/nix-0.15.0/src/fcntl.rs
+new file mode 100644
+index 0000000000000..be6ee0f73a8be
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/fcntl.rs
+@@ -0,0 +1,506 @@
++use {Error, Result, NixPath};
++use errno::Errno;
++use libc::{self, c_int, c_uint, c_char, size_t, ssize_t};
++use sys::stat::Mode;
++use std::os::raw;
++use std::os::unix::io::RawFd;
++use std::ffi::OsStr;
++use std::os::unix::ffi::OsStrExt;
++
++#[cfg(any(target_os = "android", target_os = "linux"))]
++use std::ptr; // For splice and copy_file_range
++#[cfg(any(target_os = "android", target_os = "linux"))]
++use sys::uio::IoVec; // For vmsplice
++
++#[cfg(any(target_os = "linux",
++ target_os = "android",
++ target_os = "emscripten",
++ target_os = "fuchsia",
++ any(target_os = "wasi", target_env = "wasi"),
++ target_env = "uclibc",
++ target_env = "freebsd"))]
++pub use self::posix_fadvise::*;
++
++libc_bitflags!{
++ pub struct AtFlags: c_int {
++ AT_REMOVEDIR;
++ AT_SYMLINK_NOFOLLOW;
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ AT_NO_AUTOMOUNT;
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ AT_EMPTY_PATH;
++ }
++}
++
++libc_bitflags!(
++ /// Configuration options for opened files.
++ pub struct OFlag: c_int {
++ /// Mask for the access mode of the file.
++ O_ACCMODE;
++ /// Use alternate I/O semantics.
++ #[cfg(target_os = "netbsd")]
++ O_ALT_IO;
++ /// Open the file in append-only mode.
++ O_APPEND;
++ /// Generate a signal when input or output becomes possible.
++ O_ASYNC;
++ /// Closes the file descriptor once an `execve` call is made.
++ ///
++ /// Also sets the file offset to the beginning of the file.
++ O_CLOEXEC;
++ /// Create the file if it does not exist.
++ O_CREAT;
++ /// Try to minimize cache effects of the I/O for this file.
++ #[cfg(any(target_os = "android",
++ target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "linux",
++ target_os = "netbsd"))]
++ O_DIRECT;
++ /// If the specified path isn't a directory, fail.
++ O_DIRECTORY;
++ /// Implicitly follow each `write()` with an `fdatasync()`.
++ #[cfg(any(target_os = "android",
++ target_os = "ios",
++ target_os = "linux",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd"))]
++ O_DSYNC;
++ /// Error out if a file was not created.
++ O_EXCL;
++ /// Open for execute only.
++ #[cfg(target_os = "freebsd")]
++ O_EXEC;
++ /// Open with an exclusive file lock.
++ #[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "ios",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd"))]
++ O_EXLOCK;
++ /// Same as `O_SYNC`.
++ #[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "ios",
++ all(target_os = "linux", not(target_env = "musl")),
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd"))]
++ O_FSYNC;
++ /// Allow files whose sizes can't be represented in an `off_t` to be opened.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ O_LARGEFILE;
++ /// Do not update the file last access time during `read(2)`s.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ O_NOATIME;
++ /// Don't attach the device as the process' controlling terminal.
++ O_NOCTTY;
++ /// Same as `O_NONBLOCK`.
++ O_NDELAY;
++ /// `open()` will fail if the given path is a symbolic link.
++ O_NOFOLLOW;
++ /// When possible, open the file in nonblocking mode.
++ O_NONBLOCK;
++ /// Don't deliver `SIGPIPE`.
++ #[cfg(target_os = "netbsd")]
++ O_NOSIGPIPE;
++ /// Obtain a file descriptor for low-level access.
++ ///
++ /// The file itself is not opened and other file operations will fail.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ O_PATH;
++ /// Only allow reading.
++ ///
++ /// This should not be combined with `O_WRONLY` or `O_RDWR`.
++ O_RDONLY;
++ /// Allow both reading and writing.
++ ///
++ /// This should not be combined with `O_WRONLY` or `O_RDONLY`.
++ O_RDWR;
++ /// Similar to `O_DSYNC` but applies to `read`s instead.
++ #[cfg(any(target_os = "linux", target_os = "netbsd", target_os = "openbsd"))]
++ O_RSYNC;
++ /// Skip search permission checks.
++ #[cfg(target_os = "netbsd")]
++ O_SEARCH;
++ /// Open with a shared file lock.
++ #[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "ios",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd"))]
++ O_SHLOCK;
++ /// Implicitly follow each `write()` with an `fsync()`.
++ O_SYNC;
++ /// Create an unnamed temporary file.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ O_TMPFILE;
++ /// Truncate an existing regular file to 0 length if it allows writing.
++ O_TRUNC;
++ /// Restore default TTY attributes.
++ #[cfg(target_os = "freebsd")]
++ O_TTY_INIT;
++ /// Only allow writing.
++ ///
++ /// This should not be combined with `O_RDONLY` or `O_RDWR`.
++ O_WRONLY;
++ }
++);
++
++pub fn open<P: ?Sized + NixPath>(path: &P, oflag: OFlag, mode: Mode) -> Result<RawFd> {
++ let fd = path.with_nix_path(|cstr| {
++ unsafe { libc::open(cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
++ })?;
++
++ Errno::result(fd)
++}
++
++pub fn openat<P: ?Sized + NixPath>(dirfd: RawFd, path: &P, oflag: OFlag, mode: Mode) -> Result<RawFd> {
++ let fd = path.with_nix_path(|cstr| {
++ unsafe { libc::openat(dirfd, cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
++ })?;
++ Errno::result(fd)
++}
++
++pub fn renameat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(old_dirfd: Option<RawFd>, old_path: &P1,
++ new_dirfd: Option<RawFd>, new_path: &P2)
++ -> Result<()> {
++ let res = old_path.with_nix_path(|old_cstr| {
++ new_path.with_nix_path(|new_cstr| unsafe {
++ libc::renameat(at_rawfd(old_dirfd), old_cstr.as_ptr(),
++ at_rawfd(new_dirfd), new_cstr.as_ptr())
++ })
++ })??;
++ Errno::result(res).map(drop)
++}
++
++fn wrap_readlink_result(buffer: &mut[u8], res: ssize_t) -> Result<&OsStr> {
++ match Errno::result(res) {
++ Err(err) => Err(err),
++ Ok(len) => {
++ if (len as usize) >= buffer.len() {
++ Err(Error::Sys(Errno::ENAMETOOLONG))
++ } else {
++ Ok(OsStr::from_bytes(&buffer[..(len as usize)]))
++ }
++ }
++ }
++}
++
++pub fn readlink<'a, P: ?Sized + NixPath>(path: &P, buffer: &'a mut [u8]) -> Result<&'a OsStr> {
++ let res = path.with_nix_path(|cstr| {
++ unsafe { libc::readlink(cstr.as_ptr(), buffer.as_mut_ptr() as *mut c_char, buffer.len() as size_t) }
++ })?;
++
++ wrap_readlink_result(buffer, res)
++}
++
++
++pub fn readlinkat<'a, P: ?Sized + NixPath>(dirfd: RawFd, path: &P, buffer: &'a mut [u8]) -> Result<&'a OsStr> {
++ let res = path.with_nix_path(|cstr| {
++ unsafe { libc::readlinkat(dirfd, cstr.as_ptr(), buffer.as_mut_ptr() as *mut c_char, buffer.len() as size_t) }
++ })?;
++
++ wrap_readlink_result(buffer, res)
++}
++
++/// Computes the raw fd consumed by a function of the form `*at`.
++pub(crate) fn at_rawfd(fd: Option<RawFd>) -> raw::c_int {
++ match fd {
++ None => libc::AT_FDCWD,
++ Some(fd) => fd,
++ }
++}
++
++#[cfg(any(target_os = "android", target_os = "linux"))]
++libc_bitflags!(
++ /// Additional flags for file sealing, which allows for limiting operations on a file.
++ pub struct SealFlag: c_int {
++ /// Prevents further calls to `fcntl()` with `F_ADD_SEALS`.
++ F_SEAL_SEAL;
++ /// The file cannot be reduced in size.
++ F_SEAL_SHRINK;
++ /// The size of the file cannot be increased.
++ F_SEAL_GROW;
++ /// The file contents cannot be modified.
++ F_SEAL_WRITE;
++ }
++);
++
++libc_bitflags!(
++ /// Additional configuration flags for `fcntl`'s `F_SETFD`.
++ pub struct FdFlag: c_int {
++ /// The file descriptor will automatically be closed during a successful `execve(2)`.
++ FD_CLOEXEC;
++ }
++);
++
++#[derive(Debug, Eq, Hash, PartialEq)]
++pub enum FcntlArg<'a> {
++ F_DUPFD(RawFd),
++ F_DUPFD_CLOEXEC(RawFd),
++ F_GETFD,
++ F_SETFD(FdFlag), // FD_FLAGS
++ F_GETFL,
++ F_SETFL(OFlag), // O_NONBLOCK
++ F_SETLK(&'a libc::flock),
++ F_SETLKW(&'a libc::flock),
++ F_GETLK(&'a mut libc::flock),
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ F_OFD_SETLK(&'a libc::flock),
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ F_OFD_SETLKW(&'a libc::flock),
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ F_OFD_GETLK(&'a mut libc::flock),
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ F_ADD_SEALS(SealFlag),
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ F_GET_SEALS,
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ F_FULLFSYNC,
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ F_GETPIPE_SZ,
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ F_SETPIPE_SZ(c_int),
++
++ // TODO: Rest of flags
++}
++pub use self::FcntlArg::*;
++
++// TODO: Figure out how to handle value fcntl returns
++pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
++ let res = unsafe {
++ match arg {
++ F_DUPFD(rawfd) => libc::fcntl(fd, libc::F_DUPFD, rawfd),
++ F_DUPFD_CLOEXEC(rawfd) => libc::fcntl(fd, libc::F_DUPFD_CLOEXEC, rawfd),
++ F_GETFD => libc::fcntl(fd, libc::F_GETFD),
++ F_SETFD(flag) => libc::fcntl(fd, libc::F_SETFD, flag.bits()),
++ F_GETFL => libc::fcntl(fd, libc::F_GETFL),
++ F_SETFL(flag) => libc::fcntl(fd, libc::F_SETFL, flag.bits()),
++ F_SETLK(flock) => libc::fcntl(fd, libc::F_SETLK, flock),
++ F_SETLKW(flock) => libc::fcntl(fd, libc::F_SETLKW, flock),
++ F_GETLK(flock) => libc::fcntl(fd, libc::F_GETLK, flock),
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ F_ADD_SEALS(flag) => libc::fcntl(fd, libc::F_ADD_SEALS, flag.bits()),
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ F_GET_SEALS => libc::fcntl(fd, libc::F_GET_SEALS),
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ F_FULLFSYNC => libc::fcntl(fd, libc::F_FULLFSYNC),
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ F_GETPIPE_SZ => libc::fcntl(fd, libc::F_GETPIPE_SZ),
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ F_SETPIPE_SZ(size) => libc::fcntl(fd, libc::F_SETPIPE_SZ, size),
++ #[cfg(any(target_os = "linux", target_os = "android"))]
++ _ => unimplemented!()
++ }
++ };
++
++ Errno::result(res)
++}
++
++#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
++pub enum FlockArg {
++ LockShared,
++ LockExclusive,
++ Unlock,
++ LockSharedNonblock,
++ LockExclusiveNonblock,
++ UnlockNonblock,
++}
++
++pub fn flock(fd: RawFd, arg: FlockArg) -> Result<()> {
++ use self::FlockArg::*;
++
++ let res = unsafe {
++ match arg {
++ LockShared => libc::flock(fd, libc::LOCK_SH),
++ LockExclusive => libc::flock(fd, libc::LOCK_EX),
++ Unlock => libc::flock(fd, libc::LOCK_UN),
++ LockSharedNonblock => libc::flock(fd, libc::LOCK_SH | libc::LOCK_NB),
++ LockExclusiveNonblock => libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB),
++ UnlockNonblock => libc::flock(fd, libc::LOCK_UN | libc::LOCK_NB),
++ }
++ };
++
++ Errno::result(res).map(drop)
++}
++
++#[cfg(any(target_os = "android", target_os = "linux"))]
++libc_bitflags! {
++ /// Additional flags to `splice` and friends.
++ pub struct SpliceFFlags: c_uint {
++ /// Request that pages be moved instead of copied.
++ ///
++ /// Not applicable to `vmsplice`.
++ SPLICE_F_MOVE;
++ /// Do not block on I/O.
++ SPLICE_F_NONBLOCK;
++ /// Hint that more data will be coming in a subsequent splice.
++ ///
++ /// Not applicable to `vmsplice`.
++ SPLICE_F_MORE;
++ /// Gift the user pages to the kernel.
++ ///
++ /// Not applicable to `splice`.
++ SPLICE_F_GIFT;
++ }
++}
++
++/// Copy a range of data from one file to another
++///
++/// The `copy_file_range` system call performs an in-kernel copy between
++/// file descriptors `fd_in` and `fd_out` without the additional cost of
++/// transferring data from the kernel to user space and then back into the
++/// kernel. It copies up to `len` bytes of data from file descriptor `fd_in` to
++/// file descriptor `fd_out`, overwriting any data that exists within the
++/// requested range of the target file.
++///
++/// If the `off_in` and/or `off_out` arguments are used, the values
++/// will be mutated to reflect the new position within the file after
++/// copying. If they are not used, the relevant filedescriptors will be seeked
++/// to the new position.
++///
++/// On successful completion the number of bytes actually copied will be
++/// returned.
++#[cfg(any(target_os = "android", target_os = "linux"))]
++pub fn copy_file_range(
++ fd_in: RawFd,
++ off_in: Option<&mut libc::loff_t>,
++ fd_out: RawFd,
++ off_out: Option<&mut libc::loff_t>,
++ len: usize,
++) -> Result<usize> {
++ let off_in = off_in
++ .map(|offset| offset as *mut libc::loff_t)
++ .unwrap_or(ptr::null_mut());
++ let off_out = off_out
++ .map(|offset| offset as *mut libc::loff_t)
++ .unwrap_or(ptr::null_mut());
++
++ let ret = unsafe {
++ libc::syscall(
++ libc::SYS_copy_file_range,
++ fd_in,
++ off_in,
++ fd_out,
++ off_out,
++ len,
++ 0,
++ )
++ };
++ Errno::result(ret).map(|r| r as usize)
++}
++
++#[cfg(any(target_os = "linux", target_os = "android"))]
++pub fn splice(
++ fd_in: RawFd,
++ off_in: Option<&mut libc::loff_t>,
++ fd_out: RawFd,
++ off_out: Option<&mut libc::loff_t>,
++ len: usize,
++ flags: SpliceFFlags,
++) -> Result<usize> {
++ let off_in = off_in
++ .map(|offset| offset as *mut libc::loff_t)
++ .unwrap_or(ptr::null_mut());
++ let off_out = off_out
++ .map(|offset| offset as *mut libc::loff_t)
++ .unwrap_or(ptr::null_mut());
++
++ let ret = unsafe {
++ libc::splice(fd_in, off_in, fd_out, off_out, len, flags.bits())
++ };
++ Errno::result(ret).map(|r| r as usize)
++}
++
++#[cfg(any(target_os = "linux", target_os = "android"))]
++pub fn tee(fd_in: RawFd, fd_out: RawFd, len: usize, flags: SpliceFFlags) -> Result<usize> {
++ let ret = unsafe { libc::tee(fd_in, fd_out, len, flags.bits()) };
++ Errno::result(ret).map(|r| r as usize)
++}
++
++#[cfg(any(target_os = "linux", target_os = "android"))]
++pub fn vmsplice(fd: RawFd, iov: &[IoVec<&[u8]>], flags: SpliceFFlags) -> Result<usize> {
++ let ret = unsafe {
++ libc::vmsplice(fd, iov.as_ptr() as *const libc::iovec, iov.len(), flags.bits())
++ };
++ Errno::result(ret).map(|r| r as usize)
++}
++
++#[cfg(any(target_os = "linux"))]
++libc_bitflags!(
++ /// Mode argument flags for fallocate determining operation performed on a given range.
++ pub struct FallocateFlags: c_int {
++ /// File size is not changed.
++ ///
++ /// offset + len can be greater than file size.
++ FALLOC_FL_KEEP_SIZE;
++ /// Deallocates space by creating a hole.
++ ///
++ /// Must be ORed with FALLOC_FL_KEEP_SIZE. Byte range starts at offset and continues for len bytes.
++ FALLOC_FL_PUNCH_HOLE;
++ /// Removes byte range from a file without leaving a hole.
++ ///
++ /// Byte range to collapse starts at offset and continues for len bytes.
++ FALLOC_FL_COLLAPSE_RANGE;
++ /// Zeroes space in specified byte range.
++ ///
++ /// Byte range starts at offset and continues for len bytes.
++ FALLOC_FL_ZERO_RANGE;
++ /// Increases file space by inserting a hole within the file size.
++ ///
++ /// Does not overwrite existing data. Hole starts at offset and continues for len bytes.
++ FALLOC_FL_INSERT_RANGE;
++ /// Shared file data extants are made private to the file.
++ ///
++ /// Gaurantees that a subsequent write will not fail due to lack of space.
++ FALLOC_FL_UNSHARE_RANGE;
++ }
++);
++
++/// Manipulates file space.
++///
++/// Allows the caller to directly manipulate the allocated disk space for the
++/// file referred to by fd.
++#[cfg(any(target_os = "linux"))]
++pub fn fallocate(fd: RawFd, mode: FallocateFlags, offset: libc::off_t, len: libc::off_t) -> Result<c_int> {
++ let res = unsafe { libc::fallocate(fd, mode.bits(), offset, len) };
++ Errno::result(res)
++}
++
++#[cfg(any(target_os = "linux",
++ target_os = "android",
++ target_os = "emscripten",
++ target_os = "fuchsia",
++ any(target_os = "wasi", target_env = "wasi"),
++ target_env = "uclibc",
++ target_env = "freebsd"))]
++mod posix_fadvise {
++ use Result;
++ use libc;
++ use errno::Errno;
++ use std::os::unix::io::RawFd;
++
++ libc_enum! {
++ #[repr(i32)]
++ pub enum PosixFadviseAdvice {
++ POSIX_FADV_NORMAL,
++ POSIX_FADV_SEQUENTIAL,
++ POSIX_FADV_RANDOM,
++ POSIX_FADV_NOREUSE,
++ POSIX_FADV_WILLNEED,
++ POSIX_FADV_DONTNEED,
++ }
++ }
++
++ pub fn posix_fadvise(fd: RawFd,
++ offset: libc::off_t,
++ len: libc::off_t,
++ advice: PosixFadviseAdvice) -> Result<libc::c_int> {
++ let res = unsafe { libc::posix_fadvise(fd, offset, len, advice as libc::c_int) };
++ Errno::result(res)
++ }
++}
+diff --git a/third_party/rust/nix-0.15.0/src/features.rs b/third_party/rust/nix-0.15.0/src/features.rs
+new file mode 100644
+index 0000000000000..76cdfd3a1a6f1
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/features.rs
+@@ -0,0 +1,103 @@
++//! Feature tests for OS functionality
++pub use self::os::*;
++
++#[cfg(any(target_os = "linux", target_os = "android"))]
++mod os {
++ use sys::utsname::uname;
++
++ // Features:
++ // * atomic cloexec on socket: 2.6.27
++ // * pipe2: 2.6.27
++ // * accept4: 2.6.28
++
++ static VERS_UNKNOWN: usize = 1;
++ static VERS_2_6_18: usize = 2;
++ static VERS_2_6_27: usize = 3;
++ static VERS_2_6_28: usize = 4;
++ static VERS_3: usize = 5;
++
++ #[inline]
++ fn digit(dst: &mut usize, b: u8) {
++ *dst *= 10;
++ *dst += (b - b'0') as usize;
++ }
++
++ fn parse_kernel_version() -> usize {
++ let u = uname();
++
++ let mut curr: usize = 0;
++ let mut major: usize = 0;
++ let mut minor: usize = 0;
++ let mut patch: usize = 0;
++
++ for b in u.release().bytes() {
++ if curr >= 3 {
++ break;
++ }
++
++ match b {
++ b'.' | b'-' => {
++ curr += 1;
++ }
++ b'0'..=b'9' => {
++ match curr {
++ 0 => digit(&mut major, b),
++ 1 => digit(&mut minor, b),
++ _ => digit(&mut patch, b),
++ }
++ }
++ _ => break,
++ }
++ }
++
++ if major >= 3 {
++ VERS_3
++ } else if major >= 2 {
++ if minor >= 7 {
++ VERS_UNKNOWN
++ } else if minor >= 6 {
++ if patch >= 28 {
++ VERS_2_6_28
++ } else if patch >= 27 {
++ VERS_2_6_27
++ } else {
++ VERS_2_6_18
++ }
++ } else {
++ VERS_UNKNOWN
++ }
++ } else {
++ VERS_UNKNOWN
++ }
++ }
++
++ fn kernel_version() -> usize {
++ static mut KERNEL_VERS: usize = 0;
++
++ unsafe {
++ if KERNEL_VERS == 0 {
++ KERNEL_VERS = parse_kernel_version();
++ }
++
++ KERNEL_VERS
++ }
++ }
++
++ /// Check if the OS supports atomic close-on-exec for sockets
++ pub fn socket_atomic_cloexec() -> bool {
++ kernel_version() >= VERS_2_6_27
++ }
++
++ #[test]
++ pub fn test_parsing_kernel_version() {
++ assert!(kernel_version() > 0);
++ }
++}
++
++#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "dragonfly", target_os = "ios", target_os = "openbsd", target_os = "netbsd"))]
++mod os {
++ /// Check if the OS supports atomic close-on-exec for sockets
++ pub fn socket_atomic_cloexec() -> bool {
++ false
++ }
++}
+diff --git a/third_party/rust/nix-0.15.0/src/ifaddrs.rs b/third_party/rust/nix-0.15.0/src/ifaddrs.rs
+new file mode 100644
+index 0000000000000..12b59bcc92bef
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/ifaddrs.rs
+@@ -0,0 +1,146 @@
++//! Query network interface addresses
++//!
++//! Uses the Linux and/or BSD specific function `getifaddrs` to query the list
++//! of interfaces and their associated addresses.
++
++use std::ffi;
++use std::iter::Iterator;
++use std::mem;
++use std::option::Option;
++
++use libc;
++
++use {Result, Errno};
++use sys::socket::SockAddr;
++use net::if_::*;
++
++/// Describes a single address for an interface as returned by `getifaddrs`.
++#[derive(Clone, Debug, Eq, Hash, PartialEq)]
++pub struct InterfaceAddress {
++ /// Name of the network interface
++ pub interface_name: String,
++ /// Flags as from `SIOCGIFFLAGS` ioctl
++ pub flags: InterfaceFlags,
++ /// Network address of this interface
++ pub address: Option<SockAddr>,
++ /// Netmask of this interface
++ pub netmask: Option<SockAddr>,
++ /// Broadcast address of this interface, if applicable
++ pub broadcast: Option<SockAddr>,
++ /// Point-to-point destination address
++ pub destination: Option<SockAddr>,
++}
++
++cfg_if! {
++ if #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "fuchsia", target_os = "linux"))] {
++ fn get_ifu_from_sockaddr(info: &libc::ifaddrs) -> *const libc::sockaddr {
++ info.ifa_ifu
++ }
++ } else {
++ fn get_ifu_from_sockaddr(info: &libc::ifaddrs) -> *const libc::sockaddr {
++ info.ifa_dstaddr
++ }
++ }
++}
++
++impl InterfaceAddress {
++ /// Create an `InterfaceAddress` from the libc struct.
++ fn from_libc_ifaddrs(info: &libc::ifaddrs) -> InterfaceAddress {
++ let ifname = unsafe { ffi::CStr::from_ptr(info.ifa_name) };
++ let address = unsafe { SockAddr::from_libc_sockaddr(info.ifa_addr) };
++ let netmask = unsafe { SockAddr::from_libc_sockaddr(info.ifa_netmask) };
++ let mut addr = InterfaceAddress {
++ interface_name: ifname.to_string_lossy().to_string(),
++ flags: InterfaceFlags::from_bits_truncate(info.ifa_flags as i32),
++ address: address,
++ netmask: netmask,
++ broadcast: None,
++ destination: None,
++ };
++
++ let ifu = get_ifu_from_sockaddr(info);
++ if addr.flags.contains(InterfaceFlags::IFF_POINTOPOINT) {
++ addr.destination = unsafe { SockAddr::from_libc_sockaddr(ifu) };
++ } else if addr.flags.contains(InterfaceFlags::IFF_BROADCAST) {
++ addr.broadcast = unsafe { SockAddr::from_libc_sockaddr(ifu) };
++ }
++
++ addr
++ }
++}
++
++/// Holds the results of `getifaddrs`.
++///
++/// Use the function `getifaddrs` to create this Iterator. Note that the
++/// actual list of interfaces can be iterated once and will be freed as
++/// soon as the Iterator goes out of scope.
++#[derive(Debug, Eq, Hash, PartialEq)]
++pub struct InterfaceAddressIterator {
++ base: *mut libc::ifaddrs,
++ next: *mut libc::ifaddrs,
++}
++
++impl Drop for InterfaceAddressIterator {
++ fn drop(&mut self) {
++ unsafe { libc::freeifaddrs(self.base) };
++ }
++}
++
++impl Iterator for InterfaceAddressIterator {
++ type Item = InterfaceAddress;
++ fn next(&mut self) -> Option<<Self as Iterator>::Item> {
++ match unsafe { self.next.as_ref() } {
++ Some(ifaddr) => {
++ self.next = ifaddr.ifa_next;
++ Some(InterfaceAddress::from_libc_ifaddrs(ifaddr))
++ }
++ None => None,
++ }
++ }
++}
++
++/// Get interface addresses using libc's `getifaddrs`
++///
++/// Note that the underlying implementation differs between OSes. Only the
++/// most common address families are supported by the nix crate (due to
++/// lack of time and complexity of testing). The address family is encoded
++/// in the specific variant of `SockAddr` returned for the fields `address`,
++/// `netmask`, `broadcast`, and `destination`. For any entry not supported,
++/// the returned list will contain a `None` entry.
++///
++/// # Example
++/// ```
++/// let addrs = nix::ifaddrs::getifaddrs().unwrap();
++/// for ifaddr in addrs {
++/// match ifaddr.address {
++/// Some(address) => {
++/// println!("interface {} address {}",
++/// ifaddr.interface_name, address);
++/// },
++/// None => {
++/// println!("interface {} with unsupported address family",
++/// ifaddr.interface_name);
++/// }
++/// }
++/// }
++/// ```
++pub fn getifaddrs() -> Result<InterfaceAddressIterator> {
++ let mut addrs: *mut libc::ifaddrs = unsafe { mem::uninitialized() };
++ Errno::result(unsafe { libc::getifaddrs(&mut addrs) }).map(|_| {
++ InterfaceAddressIterator {
++ base: addrs,
++ next: addrs,
++ }
++ })
++}
++
++#[cfg(test)]
++mod tests {
++ use super::*;
++
++ // Only checks if `getifaddrs` can be invoked without panicking.
++ #[test]
++ fn test_getifaddrs() {
++ let _ = getifaddrs();
++ }
++}
+diff --git a/third_party/rust/nix-0.15.0/src/kmod.rs b/third_party/rust/nix-0.15.0/src/kmod.rs
+new file mode 100644
+index 0000000000000..e853261b14f9d
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/kmod.rs
+@@ -0,0 +1,123 @@
++//! Load and unload kernel modules.
++//!
++//! For more details see
++
++use libc;
++use std::ffi::CStr;
++use std::os::unix::io::AsRawFd;
++
++use errno::Errno;
++use Result;
++
++/// Loads a kernel module from a buffer.
++///
++/// It loads an ELF image into kernel space,
++/// performs any necessary symbol relocations,
++/// initializes module parameters to values provided by the caller,
++/// and then runs the module's init function.
++///
++/// This function requires `CAP_SYS_MODULE` privilege.
++///
++/// The `module_image` argument points to a buffer containing the binary image
++/// to be loaded. The buffer should contain a valid ELF image
++/// built for the running kernel.
++///
++/// The `param_values` argument is a string containing space-delimited specifications
++/// of the values for module parameters.
++/// Each of the parameter specifications has the form:
++///
++/// `name[=value[,value...]]`
++///
++/// # Example
++///
++/// ```no_run
++/// use std::fs::File;
++/// use std::io::Read;
++/// use std::ffi::CString;
++/// use nix::kmod::init_module;
++///
++/// let mut f = File::open("mykernel.ko").unwrap();
++/// let mut contents: Vec<u8> = Vec::new();
++/// f.read_to_end(&mut contents).unwrap();
++/// init_module(&mut contents, &CString::new("who=Rust when=Now,12").unwrap()).unwrap();
++/// ```
++///
++/// See [`man init_module(2)`](http://man7.org/linux/man-pages/man2/init_module.2.html) for more information.
++pub fn init_module(module_image: &[u8], param_values: &CStr) -> Result<()> {
++ let res = unsafe {
++ libc::syscall(
++ libc::SYS_init_module,
++ module_image.as_ptr(),
++ module_image.len(),
++ param_values.as_ptr(),
++ )
++ };
++
++ Errno::result(res).map(drop)
++}
++
++libc_bitflags!(
++ /// Flags used by the `finit_module` function.
++ pub struct ModuleInitFlags: libc::c_uint {
++ /// Ignore symbol version hashes.
++ MODULE_INIT_IGNORE_MODVERSIONS;
++ /// Ignore kernel version magic.
++ MODULE_INIT_IGNORE_VERMAGIC;
++ }
++);
++
++/// Loads a kernel module from a given file descriptor.
++///
++/// # Example
++///
++/// ```no_run
++/// use std::fs::File;
++/// use std::ffi::CString;
++/// use nix::kmod::{finit_module, ModuleInitFlags};
++///
++/// let f = File::open("mymod.ko").unwrap();
++/// finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()).unwrap();
++/// ```
++///
++/// See [`man init_module(2)`](http://man7.org/linux/man-pages/man2/init_module.2.html) for more information.
++pub fn finit_module<T: AsRawFd>(fd: &T, param_values: &CStr, flags: ModuleInitFlags) -> Result<()> {
++ let res = unsafe {
++ libc::syscall(
++ libc::SYS_finit_module,
++ fd.as_raw_fd(),
++ param_values.as_ptr(),
++ flags.bits(),
++ )
++ };
++
++ Errno::result(res).map(drop)
++}
++
++libc_bitflags!(
++ /// Flags used by `delete_module`.
++ ///
++ /// See [`man delete_module(2)`](http://man7.org/linux/man-pages/man2/delete_module.2.html)
++ /// for a detailed description how these flags work.
++ pub struct DeleteModuleFlags: libc::c_int {
++ O_NONBLOCK;
++ O_TRUNC;
++ }
++);
++
++/// Unloads the kernel module with the given name.
++///
++/// # Example
++///
++/// ```no_run
++/// use std::ffi::CString;
++/// use nix::kmod::{delete_module, DeleteModuleFlags};
++///
++/// delete_module(&CString::new("mymod").unwrap(), DeleteModuleFlags::O_NONBLOCK).unwrap();
++/// ```
++///
++/// See [`man delete_module(2)`](http://man7.org/linux/man-pages/man2/delete_module.2.html) for more information.
++pub fn delete_module(name: &CStr, flags: DeleteModuleFlags) -> Result<()> {
++ let res = unsafe { libc::syscall(libc::SYS_delete_module, name.as_ptr(), flags.bits()) };
++
++ Errno::result(res).map(drop)
++}
+diff --git a/third_party/rust/nix-0.15.0/src/lib.rs b/third_party/rust/nix-0.15.0/src/lib.rs
+new file mode 100644
+index 0000000000000..71485d2af1824
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/lib.rs
+@@ -0,0 +1,284 @@
++//! Rust friendly bindings to the various *nix system functions.
++//!
++//! Modules are structured according to the C header file that they would be
++//! defined in.
++#![crate_name = "nix"]
++#![cfg(unix)]
++#![allow(non_camel_case_types)]
++// latest bitflags triggers a rustc bug with cross-crate macro expansions causing dead_code
++// warnings even though the macro expands into something with allow(dead_code)
++#![allow(dead_code)]
++#![cfg_attr(test, deny(warnings))]
++#![recursion_limit = "500"]
++#![deny(unused)]
++#![deny(unstable_features)]
++#![deny(missing_copy_implementations)]
++#![deny(missing_debug_implementations)]
++// XXX Allow deprecated items until release 0.16.0. See issue #1096.
++#![allow(deprecated)]
++
++// External crates
++#[macro_use]
++extern crate bitflags;
++#[macro_use]
++extern crate cfg_if;
++extern crate void;
++
++// Re-exported external crates
++pub extern crate libc;
++
++// Private internal modules
++#[macro_use] mod macros;
++
++// Public crates
++pub mod dir;
++pub mod errno;
++#[deny(missing_docs)]
++pub mod features;
++pub mod fcntl;
++#[deny(missing_docs)]
++#[cfg(any(target_os = "android",
++ target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "ios",
++ target_os = "linux",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd"))]
++pub mod ifaddrs;
++#[cfg(any(target_os = "android",
++ target_os = "linux"))]
++pub mod kmod;
++#[cfg(any(target_os = "android",
++ target_os = "linux"))]
++pub mod mount;
++#[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "fushsia",
++ target_os = "linux",
++ target_os = "netbsd"))]
++pub mod mqueue;
++#[deny(missing_docs)]
++pub mod net;
++#[deny(missing_docs)]
++pub mod poll;
++#[deny(missing_docs)]
++pub mod pty;
++pub mod sched;
++pub mod sys;
++// This can be implemented for other platforms as soon as libc
++// provides bindings for them.
++#[cfg(all(target_os = "linux",
++ any(target_arch = "x86", target_arch = "x86_64")))]
++pub mod ucontext;
++pub mod unistd;
++
++/*
++ *
++ * ===== Result / Error =====
++ *
++ */
++
++use libc::{c_char, PATH_MAX};
++
++use std::{error, fmt, ptr, result};
++use std::ffi::{CStr, OsStr};
++use std::os::unix::ffi::OsStrExt;
++use std::path::{Path, PathBuf};
++
++use errno::Errno;
++
++/// Nix Result Type
++pub type Result<T> = result::Result<T, Error>;
++
++/// Nix Error Type
++///
++/// The nix error type provides a common way of dealing with
++/// various system system/libc calls that might fail. Each
++/// error has a corresponding errno (usually the one from the
++/// underlying OS) to which it can be mapped in addition to
++/// implementing other common traits.
++#[derive(Clone, Copy, Debug, Eq, PartialEq)]
++pub enum Error {
++ Sys(Errno),
++ InvalidPath,
++ /// The operation involved a conversion to Rust's native String type, which failed because the
++ /// string did not contain all valid UTF-8.
++ InvalidUtf8,
++ /// The operation is not supported by Nix, in this instance either use the libc bindings or
++ /// consult the module documentation to see if there is a more appropriate interface available.
++ UnsupportedOperation,
++}
++
++impl Error {
++ /// Convert this `Error` to an [`Errno`](enum.Errno.html).
++ ///
++ /// # Example
++ ///
++ /// ```
++ /// # use nix::Error;
++ /// # use nix::errno::Errno;
++ /// let e = Error::from(Errno::EPERM);
++ /// assert_eq!(Some(Errno::EPERM), e.as_errno());
++ /// ```
++ pub fn as_errno(&self) -> Option<Errno> {
++ if let &Error::Sys(ref e) = self {
++ Some(*e)
++ } else {
++ None
++ }
++ }
++
++ /// Create a nix Error from a given errno
++ pub fn from_errno(errno: Errno) -> Error {
++ Error::Sys(errno)
++ }
++
++ /// Get the current errno and convert it to a nix Error
++ pub fn last() -> Error {
++ Error::Sys(Errno::last())
++ }
++
++ /// Create a new invalid argument error (`EINVAL`)
++ pub fn invalid_argument() -> Error {
++ Error::Sys(Errno::EINVAL)
++ }
++
++}
++
++impl From<Errno> for Error {
++ fn from(errno: Errno) -> Error { Error::from_errno(errno) }
++}
++
++impl From<std::string::FromUtf8Error> for Error {
++ fn from(_: std::string::FromUtf8Error) -> Error { Error::InvalidUtf8 }
++}
++
++impl error::Error for Error {
++ fn description(&self) -> &str {
++ match *self {
++ Error::InvalidPath => "Invalid path",
++ Error::InvalidUtf8 => "Invalid UTF-8 string",
++ Error::UnsupportedOperation => "Unsupported Operation",
++ Error::Sys(ref errno) => errno.desc(),
++ }
++ }
++}
++
++impl fmt::Display for Error {
++ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
++ match *self {
++ Error::InvalidPath => write!(f, "Invalid path"),
++ Error::InvalidUtf8 => write!(f, "Invalid UTF-8 string"),
++ Error::UnsupportedOperation => write!(f, "Unsupported Operation"),
++ Error::Sys(errno) => write!(f, "{:?}: {}", errno, errno.desc()),
++ }
++ }
++}
++
++pub trait NixPath {
++ fn len(&self) -> usize;
++
++ fn with_nix_path<T, F>(&self, f: F) -> Result<T>
++ where F: FnOnce(&CStr) -> T;
++}
++
++impl NixPath for str {
++ fn len(&self) -> usize {
++ NixPath::len(OsStr::new(self))
++ }
++
++ fn with_nix_path<T, F>(&self, f: F) -> Result<T>
++ where F: FnOnce(&CStr) -> T {
++ OsStr::new(self).with_nix_path(f)
++ }
++}
++
++impl NixPath for OsStr {
++ fn len(&self) -> usize {
++ self.as_bytes().len()
++ }
++
++ fn with_nix_path<T, F>(&self, f: F) -> Result<T>
++ where F: FnOnce(&CStr) -> T {
++ self.as_bytes().with_nix_path(f)
++ }
++}
++
++impl NixPath for CStr {
++ fn len(&self) -> usize {
++ self.to_bytes().len()
++ }
++
++ fn with_nix_path<T, F>(&self, f: F) -> Result<T>
++ where F: FnOnce(&CStr) -> T {
++ // Equivalence with the [u8] impl.
++ if self.len() >= PATH_MAX as usize {
++ return Err(Error::InvalidPath);
++ }
++
++ Ok(f(self))
++ }
++}
++
++impl NixPath for [u8] {
++ fn len(&self) -> usize {
++ self.len()
++ }
++
++ fn with_nix_path<T, F>(&self, f: F) -> Result<T>
++ where F: FnOnce(&CStr) -> T {
++ let mut buf = [0u8; PATH_MAX as usize];
++
++ if self.len() >= PATH_MAX as usize {
++ return Err(Error::InvalidPath);
++ }
++
++ match self.iter().position(|b| *b == 0) {
++ Some(_) => Err(Error::InvalidPath),
++ None => {
++ unsafe {
++ // TODO: Replace with bytes::copy_memory. rust-lang/rust#24028
++ ptr::copy_nonoverlapping(self.as_ptr(), buf.as_mut_ptr(), self.len());
++ Ok(f(CStr::from_ptr(buf.as_ptr() as *const c_char)))
++ }
++
++ }
++ }
++ }
++}
++
++impl NixPath for Path {
++ fn len(&self) -> usize {
++ NixPath::len(self.as_os_str())
++ }
++
++ fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
++ self.as_os_str().with_nix_path(f)
++ }
++}
++
++impl NixPath for PathBuf {
++ fn len(&self) -> usize {
++ NixPath::len(self.as_os_str())
++ }
++
++ fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
++ self.as_os_str().with_nix_path(f)
++ }
++}
++
++/// Treats `None` as an empty string.
++impl<'a, NP: ?Sized + NixPath> NixPath for Option<&'a NP> {
++ fn len(&self) -> usize {
++ self.map_or(0, NixPath::len)
++ }
++
++ fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
++ if let Some(nix_path) = *self {
++ nix_path.with_nix_path(f)
++ } else {
++ unsafe { CStr::from_ptr("\0".as_ptr() as *const _).with_nix_path(f) }
++ }
++ }
++}
+diff --git a/third_party/rust/nix-0.15.0/src/macros.rs b/third_party/rust/nix-0.15.0/src/macros.rs
+new file mode 100644
+index 0000000000000..3d1b0e4b7699c
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/macros.rs
+@@ -0,0 +1,264 @@
++/// The `libc_bitflags!` macro helps with a common use case of defining a public bitflags type
++/// with values from the libc crate. It is used the same way as the `bitflags!` macro, except
++/// that only the name of the flag value has to be given.
++///
++/// The `libc` crate must be in scope with the name `libc`.
++///
++/// # Example
++/// ```
++/// libc_bitflags!{
++/// pub struct ProtFlags: libc::c_int {
++/// PROT_NONE;
++/// PROT_READ;
++/// /// PROT_WRITE enables write protect
++/// PROT_WRITE;
++/// PROT_EXEC;
++/// #[cfg(any(target_os = "linux", target_os = "android"))]
++/// PROT_GROWSDOWN;
++/// #[cfg(any(target_os = "linux", target_os = "android"))]
++/// PROT_GROWSUP;
++/// }
++/// }
++/// ```
++///
++/// Example with casting, due to a mistake in libc. In this example, the
++/// various flags have different types, so we cast the broken ones to the right
++/// type.
++///
++/// ```
++/// libc_bitflags!{
++/// pub struct SaFlags: libc::c_ulong {
++/// SA_NOCLDSTOP as libc::c_ulong;
++/// SA_NOCLDWAIT;
++/// SA_NODEFER as libc::c_ulong;
++/// SA_ONSTACK;
++/// SA_RESETHAND as libc::c_ulong;
++/// SA_RESTART as libc::c_ulong;
++/// SA_SIGINFO;
++/// }
++/// }
++/// ```
++macro_rules! libc_bitflags {
++ (
++ $(#[$outer:meta])*
++ pub struct $BitFlags:ident: $T:ty {
++ $(
++ $(#[$inner:ident $($args:tt)*])*
++ $Flag:ident $(as $cast:ty)*;
++ )+
++ }
++ ) => {
++ bitflags! {
++ $(#[$outer])*
++ pub struct $BitFlags: $T {
++ $(
++ $(#[$inner $($args)*])*
++ const $Flag = libc::$Flag $(as $cast)*;
++ )+
++ }
++ }
++ };
++}
++
++/// The `libc_enum!` macro helps with a common use case of defining an enum exclusively using
++/// values from the `libc` crate. This macro supports both `pub` and private `enum`s.
++///
++/// The `libc` crate must be in scope with the name `libc`.
++///
++/// # Example
++/// ```
++/// libc_enum!{
++/// pub enum ProtFlags {
++/// PROT_NONE,
++/// PROT_READ,
++/// PROT_WRITE,
++/// PROT_EXEC,
++/// #[cfg(any(target_os = "linux", target_os = "android"))]
++/// PROT_GROWSDOWN,
++/// #[cfg(any(target_os = "linux", target_os = "android"))]
++/// PROT_GROWSUP,
++/// }
++/// }
++/// ```
++macro_rules! libc_enum {
++ // (non-pub) Exit rule.
++ (@make_enum
++ {
++ name: $BitFlags:ident,
++ attrs: [$($attrs:tt)*],
++ entries: [$($entries:tt)*],
++ }
++ ) => {
++ $($attrs)*
++ #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
++ enum $BitFlags {
++ $($entries)*
++ }
++ };
++
++ // (pub) Exit rule.
++ (@make_enum
++ {
++ pub,
++ name: $BitFlags:ident,
++ attrs: [$($attrs:tt)*],
++ entries: [$($entries:tt)*],
++ }
++ ) => {
++ $($attrs)*
++ #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
++ pub enum $BitFlags {
++ $($entries)*
++ }
++ };
++
++ // (non-pub) Done accumulating.
++ (@accumulate_entries
++ {
++ name: $BitFlags:ident,
++ attrs: $attrs:tt,
++ },
++ $entries:tt;
++ ) => {
++ libc_enum! {
++ @make_enum
++ {
++ name: $BitFlags,
++ attrs: $attrs,
++ entries: $entries,
++ }
++ }
++ };
++
++ // (pub) Done accumulating.
++ (@accumulate_entries
++ {
++ pub,
++ name: $BitFlags:ident,
++ attrs: $attrs:tt,
++ },
++ $entries:tt;
++ ) => {
++ libc_enum! {
++ @make_enum
++ {
++ pub,
++ name: $BitFlags,
++ attrs: $attrs,
++ entries: $entries,
++ }
++ }
++ };
++
++ // Munch an attr.
++ (@accumulate_entries
++ $prefix:tt,
++ [$($entries:tt)*];
++ #[$attr:meta] $($tail:tt)*
++ ) => {
++ libc_enum! {
++ @accumulate_entries
++ $prefix,
++ [
++ $($entries)*
++ #[$attr]
++ ];
++ $($tail)*
++ }
++ };
++
++ // Munch last ident if not followed by a comma.
++ (@accumulate_entries
++ $prefix:tt,
++ [$($entries:tt)*];
++ $entry:ident
++ ) => {
++ libc_enum! {
++ @accumulate_entries
++ $prefix,
++ [
++ $($entries)*
++ $entry = libc::$entry,
++ ];
++ }
++ };
++
++ // Munch an ident; covers terminating comma case.
++ (@accumulate_entries
++ $prefix:tt,
++ [$($entries:tt)*];
++ $entry:ident, $($tail:tt)*
++ ) => {
++ libc_enum! {
++ @accumulate_entries
++ $prefix,
++ [
++ $($entries)*
++ $entry = libc::$entry,
++ ];
++ $($tail)*
++ }
++ };
++
++ // Munch an ident and cast it to the given type; covers terminating comma.
++ (@accumulate_entries
++ $prefix:tt,
++ [$($entries:tt)*];
++ $entry:ident as $ty:ty, $($tail:tt)*
++ ) => {
++ libc_enum! {
++ @accumulate_entries
++ $prefix,
++ [
++ $($entries)*
++ $entry = libc::$entry as $ty,
++ ];
++ $($tail)*
++ }
++ };
++
++ // (non-pub) Entry rule.
++ (
++ $(#[$attr:meta])*
++ enum $BitFlags:ident {
++ $($vals:tt)*
++ }
++ ) => {
++ libc_enum! {
++ @accumulate_entries
++ {
++ name: $BitFlags,
++ attrs: [$(#[$attr])*],
++ },
++ [];
++ $($vals)*
++ }
++ };
++
++ // (pub) Entry rule.
++ (
++ $(#[$attr:meta])*
++ pub enum $BitFlags:ident {
++ $($vals:tt)*
++ }
++ ) => {
++ libc_enum! {
++ @accumulate_entries
++ {
++ pub,
++ name: $BitFlags,
++ attrs: [$(#[$attr])*],
++ },
++ [];
++ $($vals)*
++ }
++ };
++}
++
++/// A Rust version of the familiar C `offset_of` macro. It returns the byte
++/// offset of `field` within struct `ty`
++macro_rules! offset_of {
++ ($ty:ty, $field:ident) => {
++ &(*(0 as *const $ty)).$field as *const _ as usize
++ }
++}
+diff --git a/third_party/rust/nix-0.15.0/src/mount.rs b/third_party/rust/nix-0.15.0/src/mount.rs
+new file mode 100644
+index 0000000000000..a9902b170ace8
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/mount.rs
+@@ -0,0 +1,98 @@
++use libc::{self, c_ulong, c_int};
++use {Result, NixPath};
++use errno::Errno;
++
++libc_bitflags!(
++ pub struct MsFlags: c_ulong {
++ /// Mount read-only
++ MS_RDONLY;
++ /// Ignore suid and sgid bits
++ MS_NOSUID;
++ /// Disallow access to device special files
++ MS_NODEV;
++ /// Disallow program execution
++ MS_NOEXEC;
++ /// Writes are synced at once
++ MS_SYNCHRONOUS;
++ /// Alter flags of a mounted FS
++ MS_REMOUNT;
++ /// Allow mandatory locks on a FS
++ MS_MANDLOCK;
++ /// Directory modifications are synchronous
++ MS_DIRSYNC;
++ /// Do not update access times
++ MS_NOATIME;
++ /// Do not update directory access times
++ MS_NODIRATIME;
++ /// Linux 2.4.0 - Bind directory at different place
++ MS_BIND;
++ MS_MOVE;
++ MS_REC;
++ MS_SILENT;
++ MS_POSIXACL;
++ MS_UNBINDABLE;
++ MS_PRIVATE;
++ MS_SLAVE;
++ MS_SHARED;
++ MS_RELATIME;
++ MS_KERNMOUNT;
++ MS_I_VERSION;
++ MS_STRICTATIME;
++ MS_ACTIVE;
++ MS_NOUSER;
++ MS_RMT_MASK;
++ MS_MGC_VAL;
++ MS_MGC_MSK;
++ }
++);
++
++libc_bitflags!(
++ pub struct MntFlags: c_int {
++ MNT_FORCE;
++ MNT_DETACH;
++ MNT_EXPIRE;
++ }
++);
++
++pub fn mount<P1: ?Sized + NixPath, P2: ?Sized + NixPath, P3: ?Sized + NixPath, P4: ?Sized + NixPath>(
++ source: Option<&P1>,
++ target: &P2,
++ fstype: Option<&P3>,
++ flags: MsFlags,
++ data: Option<&P4>) -> Result<()> {
++
++ let res =
++ source.with_nix_path(|source| {
++ target.with_nix_path(|target| {
++ fstype.with_nix_path(|fstype| {
++ data.with_nix_path(|data| {
++ unsafe {
++ libc::mount(source.as_ptr(),
++ target.as_ptr(),
++ fstype.as_ptr(),
++ flags.bits,
++ data.as_ptr() as *const libc::c_void)
++ }
++ })
++ })
++ })
++ })????;
++
++ Errno::result(res).map(drop)
++}
++
++pub fn umount<P: ?Sized + NixPath>(target: &P) -> Result<()> {
++ let res = target.with_nix_path(|cstr| {
++ unsafe { libc::umount(cstr.as_ptr()) }
++ })?;
++
++ Errno::result(res).map(drop)
++}
++
++pub fn umount2<P: ?Sized + NixPath>(target: &P, flags: MntFlags) -> Result<()> {
++ let res = target.with_nix_path(|cstr| {
++ unsafe { libc::umount2(cstr.as_ptr(), flags.bits) }
++ })?;
++
++ Errno::result(res).map(drop)
++}
+diff --git a/third_party/rust/nix-0.15.0/src/mqueue.rs b/third_party/rust/nix-0.15.0/src/mqueue.rs
+new file mode 100644
+index 0000000000000..b958b71cddb46
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/mqueue.rs
+@@ -0,0 +1,162 @@
++//! Posix Message Queue functions
++//!
++//! [Further reading and details on the C API](http://man7.org/linux/man-pages/man7/mq_overview.7.html)
++
++use Result;
++use errno::Errno;
++
++use libc::{self, c_char, c_long, mqd_t, size_t};
++use std::ffi::CString;
++use sys::stat::Mode;
++use std::mem;
++
++libc_bitflags!{
++ pub struct MQ_OFlag: libc::c_int {
++ O_RDONLY;
++ O_WRONLY;
++ O_RDWR;
++ O_CREAT;
++ O_EXCL;
++ O_NONBLOCK;
++ O_CLOEXEC;
++ }
++}
++
++libc_bitflags!{
++ pub struct FdFlag: libc::c_int {
++ FD_CLOEXEC;
++ }
++}
++
++#[repr(C)]
++#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
++pub struct MqAttr {
++ mq_attr: libc::mq_attr,
++}
++
++impl MqAttr {
++ pub fn new(mq_flags: c_long,
++ mq_maxmsg: c_long,
++ mq_msgsize: c_long,
++ mq_curmsgs: c_long)
++ -> MqAttr {
++ let mut attr = unsafe { mem::uninitialized::<libc::mq_attr>() };
++ attr.mq_flags = mq_flags;
++ attr.mq_maxmsg = mq_maxmsg;
++ attr.mq_msgsize = mq_msgsize;
++ attr.mq_curmsgs = mq_curmsgs;
++ MqAttr { mq_attr: attr }
++ }
++
++ pub fn flags(&self) -> c_long {
++ self.mq_attr.mq_flags
++ }
++}
++
++
++/// Open a message queue
++///
++/// See also [`mq_open(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_open.html)
++pub fn mq_open(name: &CString,
++ oflag: MQ_OFlag,
++ mode: Mode,
++ attr: Option<&MqAttr>)
++ -> Result<mqd_t> {
++ let res = match attr {
++ Some(mq_attr) => unsafe {
++ libc::mq_open(name.as_ptr(),
++ oflag.bits(),
++ mode.bits() as libc::c_int,
++ &mq_attr.mq_attr as *const libc::mq_attr)
++ },
++ None => unsafe { libc::mq_open(name.as_ptr(), oflag.bits()) },
++ };
++ Errno::result(res)
++}
++
++/// Remove a message queue
++///
++/// See also [`mq_unlink(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_unlink.html)
++pub fn mq_unlink(name: &CString) -> Result<()> {
++ let res = unsafe { libc::mq_unlink(name.as_ptr()) };
++ Errno::result(res).map(drop)
++}
++
++/// Close a message queue
++///
++/// See also [`mq_close(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_close.html)
++pub fn mq_close(mqdes: mqd_t) -> Result<()> {
++ let res = unsafe { libc::mq_close(mqdes) };
++ Errno::result(res).map(drop)
++}
++
++/// Receive a message from a message queue
++///
++/// See also [`mq_receive(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html)
++pub fn mq_receive(mqdes: mqd_t, message: &mut [u8], msg_prio: &mut u32) -> Result<usize> {
++ let len = message.len() as size_t;
++ let res = unsafe {
++ libc::mq_receive(mqdes,
++ message.as_mut_ptr() as *mut c_char,
++ len,
++ msg_prio as *mut u32)
++ };
++ Errno::result(res).map(|r| r as usize)
++}
++
++/// Send a message to a message queue
++///
++/// See also [`mq_send(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html)
++pub fn mq_send(mqdes: mqd_t, message: &[u8], msq_prio: u32) -> Result<()> {
++ let res = unsafe {
++ libc::mq_send(mqdes,
++ message.as_ptr() as *const c_char,
++ message.len(),
++ msq_prio)
++ };
++ Errno::result(res).map(drop)
++}
++
++/// Get message queue attributes
++///
++/// See also [`mq_getattr(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_getattr.html)
++pub fn mq_getattr(mqd: mqd_t) -> Result<MqAttr> {
++ let mut attr = unsafe { mem::uninitialized::<libc::mq_attr>() };
++ let res = unsafe { libc::mq_getattr(mqd, &mut attr) };
++ Errno::result(res).map(|_| MqAttr { mq_attr: attr })
++}
++
++/// Set the attributes of the message queue. Only `O_NONBLOCK` can be set, everything else will be ignored
++/// Returns the old attributes
++/// It is recommend to use the `mq_set_nonblock()` and `mq_remove_nonblock()` convenience functions as they are easier to use
++///
++/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_setattr.html)
++pub fn mq_setattr(mqd: mqd_t, newattr: &MqAttr) -> Result<MqAttr> {
++ let mut attr = unsafe { mem::uninitialized::<libc::mq_attr>() };
++ let res = unsafe { libc::mq_setattr(mqd, &newattr.mq_attr as *const libc::mq_attr, &mut attr) };
++ Errno::result(res).map(|_| MqAttr { mq_attr: attr })
++}
++
++/// Convenience function.
++/// Sets the `O_NONBLOCK` attribute for a given message queue descriptor
++/// Returns the old attributes
++pub fn mq_set_nonblock(mqd: mqd_t) -> Result<(MqAttr)> {
++ let oldattr = mq_getattr(mqd)?;
++ let newattr = MqAttr::new(MQ_OFlag::O_NONBLOCK.bits() as c_long,
++ oldattr.mq_attr.mq_maxmsg,
++ oldattr.mq_attr.mq_msgsize,
++ oldattr.mq_attr.mq_curmsgs);
++ mq_setattr(mqd, &newattr)
++}
++
++/// Convenience function.
++/// Removes `O_NONBLOCK` attribute for a given message queue descriptor
++/// Returns the old attributes
++pub fn mq_remove_nonblock(mqd: mqd_t) -> Result<(MqAttr)> {
++ let oldattr = mq_getattr(mqd)?;
++ let newattr = MqAttr::new(0,
++ oldattr.mq_attr.mq_maxmsg,
++ oldattr.mq_attr.mq_msgsize,
++ oldattr.mq_attr.mq_curmsgs);
++ mq_setattr(mqd, &newattr)
++}
+diff --git a/third_party/rust/nix-0.15.0/src/net/if_.rs b/third_party/rust/nix-0.15.0/src/net/if_.rs
+new file mode 100644
+index 0000000000000..58d677ae343d1
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/net/if_.rs
+@@ -0,0 +1,268 @@
++//! Network interface name resolution.
++//!
++//! Uses Linux and/or POSIX functions to resolve interface names like "eth0"
++//! or "socan1" into device numbers.
++
++use libc;
++use libc::c_uint;
++use {Result, Error, NixPath};
++
++/// Resolve an interface into a interface number.
++pub fn if_nametoindex<P: ?Sized + NixPath>(name: &P) -> Result<c_uint> {
++ let if_index = name.with_nix_path(|name| unsafe { libc::if_nametoindex(name.as_ptr()) })?;
++
++ if if_index == 0 {
++ Err(Error::last())
++ } else {
++ Ok(if_index)
++ }
++}
++
++libc_bitflags!(
++ /// Standard interface flags, used by `getifaddrs`
++ pub struct InterfaceFlags: libc::c_int {
++ /// Interface is running. (see
++ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
++ IFF_UP;
++ /// Valid broadcast address set. (see
++ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
++ IFF_BROADCAST;
++ /// Internal debugging flag. (see
++ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
++ IFF_DEBUG;
++ /// Interface is a loopback interface. (see
++ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
++ IFF_LOOPBACK;
++ /// Interface is a point-to-point link. (see
++ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
++ IFF_POINTOPOINT;
++ /// Avoid use of trailers. (see
++ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
++ #[cfg(any(target_os = "android",
++ target_os = "fuchsia",
++ target_os = "ios",
++ target_os = "linux",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "solaris"))]
++ IFF_NOTRAILERS;
++ /// Interface manages own routes.
++ #[cfg(any(target_os = "dragonfly"))]
++ IFF_SMART;
++ /// Resources allocated. (see
++ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
++ #[cfg(any(target_os = "android",
++ target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "fuchsia",
++ target_os = "ios",
++ target_os = "linux",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd",
++ target_os = "solaris"))]
++ IFF_RUNNING;
++ /// No arp protocol, L2 destination address not set. (see
++ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
++ IFF_NOARP;
++ /// Interface is in promiscuous mode. (see
++ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
++ IFF_PROMISC;
++ /// Receive all multicast packets. (see
++ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
++ IFF_ALLMULTI;
++ /// Master of a load balancing bundle. (see
++ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
++ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
++ IFF_MASTER;
++ /// transmission in progress, tx hardware queue is full
++ #[cfg(any(target_os = "freebsd",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd",
++ target_os = "ios"))]
++ IFF_OACTIVE;
++ /// Protocol code on board.
++ #[cfg(target_os = "solaris")]
++ IFF_INTELLIGENT;
++ /// Slave of a load balancing bundle. (see
++ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
++ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
++ IFF_SLAVE;
++ /// Can't hear own transmissions.
++ #[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd",
++ target_os = "osx"))]
++ IFF_SIMPLEX;
++ /// Supports multicast. (see
++ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
++ IFF_MULTICAST;
++ /// Per link layer defined bit.
++ #[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd",
++ target_os = "ios"))]
++ IFF_LINK0;
++ /// Multicast using broadcast.
++ #[cfg(any(target_os = "solaris"))]
++ IFF_MULTI_BCAST;
++ /// Is able to select media type via ifmap. (see
++ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
++ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
++ IFF_PORTSEL;
++ /// Per link layer defined bit.
++ #[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd",
++ target_os = "ios"))]
++ IFF_LINK1;
++ /// Non-unique address.
++ #[cfg(any(target_os = "solaris"))]
++ IFF_UNNUMBERED;
++ /// Auto media selection active. (see
++ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
++ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
++ IFF_AUTOMEDIA;
++ /// Per link layer defined bit.
++ #[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd",
++ target_os = "ios"))]
++ IFF_LINK2;
++ /// Use alternate physical connection.
++ #[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "macos",
++ target_os = "ios"))]
++ IFF_ALTPHYS;
++ /// DHCP controlls interface.
++ #[cfg(any(target_os = "solaris"))]
++ IFF_DHCPRUNNING;
++ /// The addresses are lost when the interface goes down. (see
++ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
++ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
++ IFF_DYNAMIC;
++ /// Do not advertise.
++ #[cfg(any(target_os = "solaris"))]
++ IFF_PRIVATE;
++ /// Driver signals L1 up. Volatile.
++ #[cfg(any(target_os = "fuchsia", target_os = "linux"))]
++ IFF_LOWER_UP;
++ /// Interface is in polling mode.
++ #[cfg(any(target_os = "dragonfly"))]
++ IFF_POLLING_COMPAT;
++ /// Unconfigurable using ioctl(2).
++ #[cfg(any(target_os = "freebsd"))]
++ IFF_CANTCONFIG;
++ /// Do not transmit packets.
++ #[cfg(any(target_os = "solaris"))]
++ IFF_NOXMIT;
++ /// Driver signals dormant. Volatile.
++ #[cfg(any(target_os = "fuchsia", target_os = "linux"))]
++ IFF_DORMANT;
++ /// User-requested promisc mode.
++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
++ IFF_PPROMISC;
++ /// Just on-link subnet.
++ #[cfg(any(target_os = "solaris"))]
++ IFF_NOLOCAL;
++ /// Echo sent packets. Volatile.
++ #[cfg(any(target_os = "fuchsia", target_os = "linux"))]
++ IFF_ECHO;
++ /// User-requested monitor mode.
++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
++ IFF_MONITOR;
++ /// Address is deprecated.
++ #[cfg(any(target_os = "solaris"))]
++ IFF_DEPRECATED;
++ /// Static ARP.
++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
++ IFF_STATICARP;
++ /// Address from stateless addrconf.
++ #[cfg(any(target_os = "solaris"))]
++ IFF_ADDRCONF;
++ /// Interface is in polling mode.
++ #[cfg(any(target_os = "dragonfly"))]
++ IFF_NPOLLING;
++ /// Router on interface.
++ #[cfg(any(target_os = "solaris"))]
++ IFF_ROUTER;
++ /// Interface is in polling mode.
++ #[cfg(any(target_os = "dragonfly"))]
++ IFF_IDIRECT;
++ /// Interface is winding down
++ #[cfg(any(target_os = "freebsd"))]
++ IFF_DYING;
++ /// No NUD on interface.
++ #[cfg(any(target_os = "solaris"))]
++ IFF_NONUD;
++ /// Interface is being renamed
++ #[cfg(any(target_os = "freebsd"))]
++ IFF_RENAMING;
++ /// Anycast address.
++ #[cfg(any(target_os = "solaris"))]
++ IFF_ANYCAST;
++ /// Don't exchange routing info.
++ #[cfg(any(target_os = "solaris"))]
++ IFF_NORTEXCH;
++ /// Do not provide packet information
++ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
++ IFF_NO_PI as libc::c_int;
++ /// TUN device (no Ethernet headers)
++ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
++ IFF_TUN as libc::c_int;
++ /// TAP device
++ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
++ IFF_TAP as libc::c_int;
++ /// IPv4 interface.
++ #[cfg(any(target_os = "solaris"))]
++ IFF_IPV4;
++ /// IPv6 interface.
++ #[cfg(any(target_os = "solaris"))]
++ IFF_IPV6;
++ /// in.mpathd test address
++ #[cfg(any(target_os = "solaris"))]
++ IFF_NOFAILOVER;
++ /// Interface has failed
++ #[cfg(any(target_os = "solaris"))]
++ IFF_FAILED;
++ /// Interface is a hot-spare
++ #[cfg(any(target_os = "solaris"))]
++ IFF_STANDBY;
++ /// Functioning but not used
++ #[cfg(any(target_os = "solaris"))]
++ IFF_INACTIVE;
++ /// Interface is offline
++ #[cfg(any(target_os = "solaris"))]
++ IFF_OFFLINE;
++ #[cfg(any(target_os = "solaris"))]
++ IFF_COS_ENABLED;
++ /// Prefer as source addr.
++ #[cfg(any(target_os = "solaris"))]
++ IFF_PREFERRED;
++ /// RFC3041
++ #[cfg(any(target_os = "solaris"))]
++ IFF_TEMPORARY;
++ /// MTU set with SIOCSLIFMTU
++ #[cfg(any(target_os = "solaris"))]
++ IFF_FIXEDMTU;
++ /// Cannot send / receive packets
++ #[cfg(any(target_os = "solaris"))]
++ IFF_VIRTUAL;
++ /// Local address in use
++ #[cfg(any(target_os = "solaris"))]
++ IFF_DUPLICATE;
++ /// IPMP IP interface
++ #[cfg(any(target_os = "solaris"))]
++ IFF_IPMP;
++ }
++);
+diff --git a/third_party/rust/nix-0.15.0/src/net/mod.rs b/third_party/rust/nix-0.15.0/src/net/mod.rs
+new file mode 100644
+index 0000000000000..079fcfde6fd44
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/net/mod.rs
+@@ -0,0 +1,4 @@
++//! Functionality involving network interfaces
++// To avoid clashing with the keyword "if", we use "if_" as the module name.
++// The original header is called "net/if.h".
++pub mod if_;
+diff --git a/third_party/rust/nix-0.15.0/src/poll.rs b/third_party/rust/nix-0.15.0/src/poll.rs
+new file mode 100644
+index 0000000000000..c603611e3176f
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/poll.rs
+@@ -0,0 +1,143 @@
++//! Wait for events to trigger on specific file descriptors
++#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
++use sys::time::TimeSpec;
++#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
++use sys::signal::SigSet;
++use std::os::unix::io::RawFd;
++
++use libc;
++use Result;
++use errno::Errno;
++
++/// This is a wrapper around `libc::pollfd`.
++///
++/// It's meant to be used as an argument to the [`poll`](fn.poll.html) and
++/// [`ppoll`](fn.ppoll.html) functions to specify the events of interest
++/// for a specific file descriptor.
++///
++/// After a call to `poll` or `ppoll`, the events that occured can be
++/// retrieved by calling [`revents()`](#method.revents) on the `PollFd`.
++#[repr(C)]
++#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
++pub struct PollFd {
++ pollfd: libc::pollfd,
++}
++
++impl PollFd {
++ /// Creates a new `PollFd` specifying the events of interest
++ /// for a given file descriptor.
++ pub fn new(fd: RawFd, events: PollFlags) -> PollFd {
++ PollFd {
++ pollfd: libc::pollfd {
++ fd: fd,
++ events: events.bits(),
++ revents: PollFlags::empty().bits(),
++ },
++ }
++ }
++
++ /// Returns the events that occured in the last call to `poll` or `ppoll`.
++ pub fn revents(&self) -> Option<PollFlags> {
++ PollFlags::from_bits(self.pollfd.revents)
++ }
++}
++
++libc_bitflags! {
++ /// These flags define the different events that can be monitored by `poll` and `ppoll`
++ pub struct PollFlags: libc::c_short {
++ /// There is data to read.
++ POLLIN;
++ /// There is some exceptional condition on the file descriptor.
++ ///
++ /// Possibilities include:
++ ///
++ /// * There is out-of-band data on a TCP socket (see
++ /// [tcp(7)](http://man7.org/linux/man-pages/man7/tcp.7.html)).
++ /// * A pseudoterminal master in packet mode has seen a state
++ /// change on the slave (see
++ /// [ioctl_tty(2)](http://man7.org/linux/man-pages/man2/ioctl_tty.2.html)).
++ /// * A cgroup.events file has been modified (see
++ /// [cgroups(7)](http://man7.org/linux/man-pages/man7/cgroups.7.html)).
++ POLLPRI;
++ /// Writing is now possible, though a write larger that the
++ /// available space in a socket or pipe will still block (unless
++ /// `O_NONBLOCK` is set).
++ POLLOUT;
++ /// Equivalent to [`POLLIN`](constant.POLLIN.html)
++ POLLRDNORM;
++ /// Equivalent to [`POLLOUT`](constant.POLLOUT.html)
++ POLLWRNORM;
++ /// Priority band data can be read (generally unused on Linux).
++ POLLRDBAND;
++ /// Priority data may be written.
++ POLLWRBAND;
++ /// Error condition (only returned in
++ /// [`PollFd::revents`](struct.PollFd.html#method.revents);
++ /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
++ /// This bit is also set for a file descriptor referring to the
++ /// write end of a pipe when the read end has been closed.
++ POLLERR;
++ /// Hang up (only returned in [`PollFd::revents`](struct.PollFd.html#method.revents);
++ /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
++ /// Note that when reading from a channel such as a pipe or a stream
++ /// socket, this event merely indicates that the peer closed its
++ /// end of the channel. Subsequent reads from the channel will
++ /// return 0 (end of file) only after all outstanding data in the
++ /// channel has been consumed.
++ POLLHUP;
++ /// Invalid request: `fd` not open (only returned in
++ /// [`PollFd::revents`](struct.PollFd.html#method.revents);
++ /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
++ POLLNVAL;
++ }
++}
++
++/// `poll` waits for one of a set of file descriptors to become ready to perform I/O.
++/// ([`poll(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html))
++///
++/// `fds` contains all [`PollFd`](struct.PollFd.html) to poll.
++/// The function will return as soon as any event occur for any of these `PollFd`s.
++///
++/// The `timeout` argument specifies the number of milliseconds that `poll()`
++/// should block waiting for a file descriptor to become ready. The call
++/// will block until either:
++///
++/// * a file descriptor becomes ready;
++/// * the call is interrupted by a signal handler; or
++/// * the timeout expires.
++///
++/// Note that the timeout interval will be rounded up to the system clock
++/// granularity, and kernel scheduling delays mean that the blocking
++/// interval may overrun by a small amount. Specifying a negative value
++/// in timeout means an infinite timeout. Specifying a timeout of zero
++/// causes `poll()` to return immediately, even if no file descriptors are
++/// ready.
++pub fn poll(fds: &mut [PollFd], timeout: libc::c_int) -> Result<libc::c_int> {
++ let res = unsafe {
++ libc::poll(fds.as_mut_ptr() as *mut libc::pollfd,
++ fds.len() as libc::nfds_t,
++ timeout)
++ };
++
++ Errno::result(res)
++}
++
++/// `ppoll()` allows an application to safely wait until either a file
++/// descriptor becomes ready or until a signal is caught.
++/// ([`poll(2)`](http://man7.org/linux/man-pages/man2/poll.2.html))
++///
++/// `ppoll` behaves like `poll`, but let you specify what signals may interrupt it
++/// with the `sigmask` argument.
++///
++#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
++pub fn ppoll(fds: &mut [PollFd], timeout: TimeSpec, sigmask: SigSet) -> Result<libc::c_int> {
++
++
++ let res = unsafe {
++ libc::ppoll(fds.as_mut_ptr() as *mut libc::pollfd,
++ fds.len() as libc::nfds_t,
++ timeout.as_ref(),
++ sigmask.as_ref())
++ };
++ Errno::result(res)
++}
+diff --git a/third_party/rust/nix-0.15.0/src/pty.rs b/third_party/rust/nix-0.15.0/src/pty.rs
+new file mode 100644
+index 0000000000000..db012d8158c53
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/pty.rs
+@@ -0,0 +1,326 @@
++//! Create master and slave virtual pseudo-terminals (PTYs)
++
++use libc;
++
++pub use libc::pid_t as SessionId;
++pub use libc::winsize as Winsize;
++
++use std::ffi::CStr;
++use std::mem;
++use std::os::unix::prelude::*;
++
++use sys::termios::Termios;
++use unistd::ForkResult;
++use {Result, Error, fcntl};
++use errno::Errno;
++
++/// Representation of a master/slave pty pair
++///
++/// This is returned by `openpty`. Note that this type does *not* implement `Drop`, so the user
++/// must manually close the file descriptors.
++#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
++pub struct OpenptyResult {
++ /// The master port in a virtual pty pair
++ pub master: RawFd,
++ /// The slave port in a virtual pty pair
++ pub slave: RawFd,
++}
++
++/// Representation of a master with a forked pty
++///
++/// This is returned by `forkpty`. Note that this type does *not* implement `Drop`, so the user
++/// must manually close the file descriptors.
++#[derive(Clone, Copy, Debug)]
++pub struct ForkptyResult {
++ /// The master port in a virtual pty pair
++ pub master: RawFd,
++ /// Metadata about forked process
++ pub fork_result: ForkResult,
++}
++
++
++/// Representation of the Master device in a master/slave pty pair
++///
++/// While this datatype is a thin wrapper around `RawFd`, it enforces that the available PTY
++/// functions are given the correct file descriptor. Additionally this type implements `Drop`,
++/// so that when it's consumed or goes out of scope, it's automatically cleaned-up.
++#[derive(Clone, Debug, Eq, Hash, PartialEq)]
++pub struct PtyMaster(RawFd);
++
++impl AsRawFd for PtyMaster {
++ fn as_raw_fd(&self) -> RawFd {
++ self.0
++ }
++}
++
++impl IntoRawFd for PtyMaster {
++ fn into_raw_fd(self) -> RawFd {
++ let fd = self.0;
++ mem::forget(self);
++ fd
++ }
++}
++
++impl Drop for PtyMaster {
++ fn drop(&mut self) {
++ // On drop, we ignore errors like EINTR and EIO because there's no clear
++ // way to handle them, we can't return anything, and (on FreeBSD at
++ // least) the file descriptor is deallocated in these cases. However,
++ // we must panic on EBADF, because it is always an error to close an
++ // invalid file descriptor. That frequently indicates a double-close
++ // condition, which can cause confusing errors for future I/O
++ // operations.
++ let e = ::unistd::close(self.0);
++ if e == Err(Error::Sys(Errno::EBADF)) {
++ panic!("Closing an invalid file descriptor!");
++ };
++ }
++}
++
++/// Grant access to a slave pseudoterminal (see
++/// [`grantpt(3)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/grantpt.html))
++///
++/// `grantpt()` changes the mode and owner of the slave pseudoterminal device corresponding to the
++/// master pseudoterminal referred to by `fd`. This is a necessary step towards opening the slave.
++#[inline]
++pub fn grantpt(fd: &PtyMaster) -> Result<()> {
++ if unsafe { libc::grantpt(fd.as_raw_fd()) } < 0 {
++ return Err(Error::last());
++ }
++
++ Ok(())
++}
++
++/// Open a pseudoterminal device (see
++/// [`posix_openpt(3)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_openpt.html))
++///
++/// `posix_openpt()` returns a file descriptor to an existing unused pseuterminal master device.
++///
++/// # Examples
++///
++/// A common use case with this function is to open both a master and slave PTY pair. This can be
++/// done as follows:
++///
++/// ```
++/// use std::path::Path;
++/// use nix::fcntl::{OFlag, open};
++/// use nix::pty::{grantpt, posix_openpt, ptsname, unlockpt};
++/// use nix::sys::stat::Mode;
++///
++/// # #[allow(dead_code)]
++/// # fn run() -> nix::Result<()> {
++/// // Open a new PTY master
++/// let master_fd = posix_openpt(OFlag::O_RDWR)?;
++///
++/// // Allow a slave to be generated for it
++/// grantpt(&master_fd)?;
++/// unlockpt(&master_fd)?;
++///
++/// // Get the name of the slave
++/// let slave_name = unsafe { ptsname(&master_fd) }?;
++///
++/// // Try to open the slave
++/// let _slave_fd = open(Path::new(&slave_name), OFlag::O_RDWR, Mode::empty())?;
++/// # Ok(())
++/// # }
++/// ```
++#[inline]
++pub fn posix_openpt(flags: fcntl::OFlag) -> Result<PtyMaster> {
++ let fd = unsafe {
++ libc::posix_openpt(flags.bits())
++ };
++
++ if fd < 0 {
++ return Err(Error::last());
++ }
++
++ Ok(PtyMaster(fd))
++}
++
++/// Get the name of the slave pseudoterminal (see
++/// [`ptsname(3)`](http://man7.org/linux/man-pages/man3/ptsname.3.html))
++///
++/// `ptsname()` returns the name of the slave pseudoterminal device corresponding to the master
++/// referred to by `fd`.
++///
++/// This value is useful for opening the slave pty once the master has already been opened with
++/// `posix_openpt()`.
++///
++/// # Safety
++///
++/// `ptsname()` mutates global variables and is *not* threadsafe.
++/// Mutating global variables is always considered `unsafe` by Rust and this
++/// function is marked as `unsafe` to reflect that.
++///
++/// For a threadsafe and non-`unsafe` alternative on Linux, see `ptsname_r()`.
++#[inline]
++pub unsafe fn ptsname(fd: &PtyMaster) -> Result<String> {
++ let name_ptr = libc::ptsname(fd.as_raw_fd());
++ if name_ptr.is_null() {
++ return Err(Error::last());
++ }
++
++ let name = CStr::from_ptr(name_ptr);
++ Ok(name.to_string_lossy().into_owned())
++}
++
++/// Get the name of the slave pseudoterminal (see
++/// [`ptsname(3)`](http://man7.org/linux/man-pages/man3/ptsname.3.html))
++///
++/// `ptsname_r()` returns the name of the slave pseudoterminal device corresponding to the master
++/// referred to by `fd`. This is the threadsafe version of `ptsname()`, but it is not part of the
++/// POSIX standard and is instead a Linux-specific extension.
++///
++/// This value is useful for opening the slave ptty once the master has already been opened with
++/// `posix_openpt()`.
++#[cfg(any(target_os = "android", target_os = "linux"))]
++#[inline]
++pub fn ptsname_r(fd: &PtyMaster) -> Result<String> {
++ let mut name_buf = vec![0u8; 64];
++ let name_buf_ptr = name_buf.as_mut_ptr() as *mut libc::c_char;
++ if unsafe { libc::ptsname_r(fd.as_raw_fd(), name_buf_ptr, name_buf.capacity()) } != 0 {
++ return Err(Error::last());
++ }
++
++ // Find the first null-character terminating this string. This is guaranteed to succeed if the
++ // return value of `libc::ptsname_r` is 0.
++ let null_index = name_buf.iter().position(|c| *c == b'\0').unwrap();
++ name_buf.truncate(null_index);
++
++ let name = String::from_utf8(name_buf)?;
++ Ok(name)
++}
++
++/// Unlock a pseudoterminal master/slave pseudoterminal pair (see
++/// [`unlockpt(3)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlockpt.html))
++///
++/// `unlockpt()` unlocks the slave pseudoterminal device corresponding to the master pseudoterminal
++/// referred to by `fd`. This must be called before trying to open the slave side of a
++/// pseuoterminal.
++#[inline]
++pub fn unlockpt(fd: &PtyMaster) -> Result<()> {
++ if unsafe { libc::unlockpt(fd.as_raw_fd()) } < 0 {
++ return Err(Error::last());
++ }
++
++ Ok(())
++}
++
++
++/// Create a new pseudoterminal, returning the slave and master file descriptors
++/// in `OpenptyResult`
++/// (see [`openpty`](http://man7.org/linux/man-pages/man3/openpty.3.html)).
++///
++/// If `winsize` is not `None`, the window size of the slave will be set to
++/// the values in `winsize`. If `termios` is not `None`, the pseudoterminal's
++/// terminal settings of the slave will be set to the values in `termios`.
++#[inline]
++pub fn openpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b Termios>>>(winsize: T, termios: U) -> Result<OpenptyResult> {
++ use std::ptr;
++
++ let mut slave: libc::c_int = unsafe { mem::uninitialized() };
++ let mut master: libc::c_int = unsafe { mem::uninitialized() };
++ let ret = {
++ match (termios.into(), winsize.into()) {
++ (Some(termios), Some(winsize)) => {
++ let inner_termios = termios.get_libc_termios();
++ unsafe {
++ libc::openpty(
++ &mut master,
++ &mut slave,
++ ptr::null_mut(),
++ &*inner_termios as *const libc::termios as *mut _,
++ winsize as *const Winsize as *mut _,
++ )
++ }
++ }
++ (None, Some(winsize)) => {
++ unsafe {
++ libc::openpty(
++ &mut master,
++ &mut slave,
++ ptr::null_mut(),
++ ptr::null_mut(),
++ winsize as *const Winsize as *mut _,
++ )
++ }
++ }
++ (Some(termios), None) => {
++ let inner_termios = termios.get_libc_termios();
++ unsafe {
++ libc::openpty(
++ &mut master,
++ &mut slave,
++ ptr::null_mut(),
++ &*inner_termios as *const libc::termios as *mut _,
++ ptr::null_mut(),
++ )
++ }
++ }
++ (None, None) => {
++ unsafe {
++ libc::openpty(
++ &mut master,
++ &mut slave,
++ ptr::null_mut(),
++ ptr::null_mut(),
++ ptr::null_mut(),
++ )
++ }
++ }
++ }
++ };
++
++ Errno::result(ret)?;
++
++ Ok(OpenptyResult {
++ master: master,
++ slave: slave,
++ })
++}
++
++/// Create a new pseudoterminal, returning the master file descriptor and forked pid.
++/// in `ForkptyResult`
++/// (see [`forkpty`](http://man7.org/linux/man-pages/man3/forkpty.3.html)).
++///
++/// If `winsize` is not `None`, the window size of the slave will be set to
++/// the values in `winsize`. If `termios` is not `None`, the pseudoterminal's
++/// terminal settings of the slave will be set to the values in `termios`.
++pub fn forkpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b Termios>>>(
++ winsize: T,
++ termios: U,
++) -> Result<ForkptyResult> {
++ use std::ptr;
++ use unistd::Pid;
++ use unistd::ForkResult::*;
++
++ let mut master: libc::c_int = unsafe { mem::uninitialized() };
++
++ let term = match termios.into() {
++ Some(termios) => {
++ let inner_termios = termios.get_libc_termios();
++ &*inner_termios as *const libc::termios as *mut _
++ },
++ None => ptr::null_mut(),
++ };
++
++ let win = winsize
++ .into()
++ .map(|ws| ws as *const Winsize as *mut _)
++ .unwrap_or(ptr::null_mut());
++
++ let res = unsafe {
++ libc::forkpty(&mut master, ptr::null_mut(), term, win)
++ };
++
++ let fork_result = Errno::result(res).map(|res| match res {
++ 0 => Child,
++ res => Parent { child: Pid::from_raw(res) },
++ })?;
++
++ Ok(ForkptyResult {
++ master: master,
++ fork_result: fork_result,
++ })
++}
++
+diff --git a/third_party/rust/nix-0.15.0/src/sched.rs b/third_party/rust/nix-0.15.0/src/sched.rs
+new file mode 100644
+index 0000000000000..67188c57eef7d
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sched.rs
+@@ -0,0 +1,147 @@
++use libc;
++use {Errno, Result};
++
++#[cfg(any(target_os = "android", target_os = "linux"))]
++pub use self::sched_linux_like::*;
++
++#[cfg(any(target_os = "android", target_os = "linux"))]
++mod sched_linux_like {
++ use errno::Errno;
++ use libc::{self, c_int, c_void};
++ use std::mem;
++ use std::option::Option;
++ use std::os::unix::io::RawFd;
++ use unistd::Pid;
++ use {Error, Result};
++
++ // For some functions taking with a parameter of type CloneFlags,
++ // only a subset of these flags have an effect.
++ libc_bitflags! {
++ pub struct CloneFlags: c_int {
++ CLONE_VM;
++ CLONE_FS;
++ CLONE_FILES;
++ CLONE_SIGHAND;
++ CLONE_PTRACE;
++ CLONE_VFORK;
++ CLONE_PARENT;
++ CLONE_THREAD;
++ CLONE_NEWNS;
++ CLONE_SYSVSEM;
++ CLONE_SETTLS;
++ CLONE_PARENT_SETTID;
++ CLONE_CHILD_CLEARTID;
++ CLONE_DETACHED;
++ CLONE_UNTRACED;
++ CLONE_CHILD_SETTID;
++ CLONE_NEWCGROUP;
++ CLONE_NEWUTS;
++ CLONE_NEWIPC;
++ CLONE_NEWUSER;
++ CLONE_NEWPID;
++ CLONE_NEWNET;
++ CLONE_IO;
++ }
++ }
++
++ pub type CloneCb<'a> = Box<dyn FnMut() -> isize + 'a>;
++
++ #[repr(C)]
++ #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
++ pub struct CpuSet {
++ cpu_set: libc::cpu_set_t,
++ }
++
++ impl CpuSet {
++ pub fn new() -> CpuSet {
++ CpuSet {
++ cpu_set: unsafe { mem::zeroed() },
++ }
++ }
++
++ pub fn is_set(&self, field: usize) -> Result<bool> {
++ if field >= 8 * mem::size_of::<libc::cpu_set_t>() {
++ Err(Error::Sys(Errno::EINVAL))
++ } else {
++ Ok(unsafe { libc::CPU_ISSET(field, &self.cpu_set) })
++ }
++ }
++
++ pub fn set(&mut self, field: usize) -> Result<()> {
++ if field >= 8 * mem::size_of::<libc::cpu_set_t>() {
++ Err(Error::Sys(Errno::EINVAL))
++ } else {
++ Ok(unsafe { libc::CPU_SET(field, &mut self.cpu_set) })
++ }
++ }
++
++ pub fn unset(&mut self, field: usize) -> Result<()> {
++ if field >= 8 * mem::size_of::<libc::cpu_set_t>() {
++ Err(Error::Sys(Errno::EINVAL))
++ } else {
++ Ok(unsafe { libc::CPU_CLR(field, &mut self.cpu_set) })
++ }
++ }
++ }
++
++ pub fn sched_setaffinity(pid: Pid, cpuset: &CpuSet) -> Result<()> {
++ let res = unsafe {
++ libc::sched_setaffinity(
++ pid.into(),
++ mem::size_of::<CpuSet>() as libc::size_t,
++ &cpuset.cpu_set,
++ )
++ };
++
++ Errno::result(res).map(drop)
++ }
++
++ pub fn clone(
++ mut cb: CloneCb,
++ stack: &mut [u8],
++ flags: CloneFlags,
++ signal: Option<c_int>,
++ ) -> Result<Pid> {
++ extern "C" fn callback(data: *mut CloneCb) -> c_int {
++ let cb: &mut CloneCb = unsafe { &mut *data };
++ (*cb)() as c_int
++ }
++
++ let res = unsafe {
++ let combined = flags.bits() | signal.unwrap_or(0);
++ let ptr = stack.as_mut_ptr().offset(stack.len() as isize);
++ let ptr_aligned = ptr.offset((ptr as usize % 16) as isize * -1);
++ libc::clone(
++ mem::transmute(
++ callback as extern "C" fn(*mut Box<dyn FnMut() -> isize>) -> i32,
++ ),
++ ptr_aligned as *mut c_void,
++ combined,
++ &mut cb as *mut _ as *mut c_void,
++ )
++ };
++
++ Errno::result(res).map(Pid::from_raw)
++ }
++
++ pub fn unshare(flags: CloneFlags) -> Result<()> {
++ let res = unsafe { libc::unshare(flags.bits()) };
++
++ Errno::result(res).map(drop)
++ }
++
++ pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> {
++ let res = unsafe { libc::setns(fd, nstype.bits()) };
++
++ Errno::result(res).map(drop)
++ }
++}
++
++/// Explicitly yield the processor to other threads.
++///
++/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_yield.html)
++pub fn sched_yield() -> Result<()> {
++ let res = unsafe { libc::sched_yield() };
++
++ Errno::result(res).map(drop)
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/aio.rs b/third_party/rust/nix-0.15.0/src/sys/aio.rs
+new file mode 100644
+index 0000000000000..9258a0657cc8a
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/aio.rs
+@@ -0,0 +1,1280 @@
++// vim: tw=80
++//! POSIX Asynchronous I/O
++//!
++//! The POSIX AIO interface is used for asynchronous I/O on files and disk-like
++//! devices. It supports [`read`](struct.AioCb.html#method.read),
++//! [`write`](struct.AioCb.html#method.write), and
++//! [`fsync`](struct.AioCb.html#method.fsync) operations. Completion
++//! notifications can optionally be delivered via
++//! [signals](../signal/enum.SigevNotify.html#variant.SigevSignal), via the
++//! [`aio_suspend`](fn.aio_suspend.html) function, or via polling. Some
++//! platforms support other completion
++//! notifications, such as
++//! [kevent](../signal/enum.SigevNotify.html#variant.SigevKevent).
++//!
++//! Multiple operations may be submitted in a batch with
++//! [`lio_listio`](fn.lio_listio.html), though the standard does not guarantee
++//! that they will be executed atomically.
++//!
++//! Outstanding operations may be cancelled with
++//! [`cancel`](struct.AioCb.html#method.cancel) or
++//! [`aio_cancel_all`](fn.aio_cancel_all.html), though the operating system may
++//! not support this for all filesystems and devices.
++
++use {Error, Result};
++use errno::Errno;
++use std::os::unix::io::RawFd;
++use libc::{c_void, off_t, size_t};
++use libc;
++use std::borrow::{Borrow, BorrowMut};
++use std::fmt;
++use std::fmt::Debug;
++use std::marker::PhantomData;
++use std::mem;
++use std::ptr::{null, null_mut};
++use sys::signal::*;
++use std::thread;
++use sys::time::TimeSpec;
++
++libc_enum! {
++ /// Mode for `AioCb::fsync`. Controls whether only data or both data and
++ /// metadata are synced.
++ #[repr(i32)]
++ pub enum AioFsyncMode {
++ /// do it like `fsync`
++ O_SYNC,
++ /// on supported operating systems only, do it like `fdatasync`
++ #[cfg(any(target_os = "ios",
++ target_os = "linux",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd"))]
++ O_DSYNC
++ }
++}
++
++libc_enum! {
++ /// When used with [`lio_listio`](fn.lio_listio.html), determines whether a
++ /// given `aiocb` should be used for a read operation, a write operation, or
++ /// ignored. Has no effect for any other aio functions.
++ #[repr(i32)]
++ pub enum LioOpcode {
++ LIO_NOP,
++ LIO_WRITE,
++ LIO_READ,
++ }
++}
++
++libc_enum! {
++ /// Mode for [`lio_listio`](fn.lio_listio.html)
++ #[repr(i32)]
++ pub enum LioMode {
++ /// Requests that [`lio_listio`](fn.lio_listio.html) block until all
++ /// requested operations have been completed
++ LIO_WAIT,
++ /// Requests that [`lio_listio`](fn.lio_listio.html) return immediately
++ LIO_NOWAIT,
++ }
++}
++
++/// Return values for [`AioCb::cancel`](struct.AioCb.html#method.cancel) and
++/// [`aio_cancel_all`](fn.aio_cancel_all.html)
++#[repr(i32)]
++#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
++pub enum AioCancelStat {
++ /// All outstanding requests were canceled
++ AioCanceled = libc::AIO_CANCELED,
++ /// Some requests were not canceled. Their status should be checked with
++ /// `AioCb::error`
++ AioNotCanceled = libc::AIO_NOTCANCELED,
++ /// All of the requests have already finished
++ AioAllDone = libc::AIO_ALLDONE,
++}
++
++/// Owns (uniquely or shared) a memory buffer to keep it from `Drop`ing while
++/// the kernel has a pointer to it.
++pub enum Buffer<'a> {
++ /// No buffer to own.
++ ///
++ /// Used for operations like `aio_fsync` that have no data, or for unsafe
++ /// operations that work with raw pointers.
++ None,
++ /// Keeps a reference to a slice
++ Phantom(PhantomData<&'a mut [u8]>),
++ /// Generic thing that keeps a buffer from dropping
++ BoxedSlice(Box<dyn Borrow<[u8]>>),
++ /// Generic thing that keeps a mutable buffer from dropping
++ BoxedMutSlice(Box<dyn BorrowMut<[u8]>>),
++}
++
++impl<'a> Debug for Buffer<'a> {
++ // Note: someday it may be possible to Derive Debug for a trait object, but
++ // not today.
++ // https://github.com/rust-lang/rust/issues/1563
++ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
++ match *self {
++ Buffer::None => write!(fmt, "None"),
++ Buffer::Phantom(p) => p.fmt(fmt),
++ Buffer::BoxedSlice(ref bs) => {
++ let borrowed : &dyn Borrow<[u8]> = bs.borrow();
++ write!(fmt, "BoxedSlice({:?})",
++ borrowed as *const dyn Borrow<[u8]>)
++ },
++ Buffer::BoxedMutSlice(ref bms) => {
++ let borrowed : &dyn BorrowMut<[u8]> = bms.borrow();
++ write!(fmt, "BoxedMutSlice({:?})",
++ borrowed as *const dyn BorrowMut<[u8]>)
++ }
++ }
++ }
++}
++
++/// AIO Control Block.
++///
++/// The basic structure used by all aio functions. Each `AioCb` represents one
++/// I/O request.
++pub struct AioCb<'a> {
++ aiocb: libc::aiocb,
++ /// Tracks whether the buffer pointed to by `libc::aiocb.aio_buf` is mutable
++ mutable: bool,
++ /// Could this `AioCb` potentially have any in-kernel state?
++ in_progress: bool,
++ /// Optionally keeps a reference to the data.
++ ///
++ /// Used to keep buffers from `Drop`'ing, and may be returned once the
++ /// `AioCb` is completed by [`buffer`](#method.buffer).
++ buffer: Buffer<'a>
++}
++
++impl<'a> AioCb<'a> {
++ /// Remove the inner `Buffer` and return it
++ ///
++ /// It is an error to call this method while the `AioCb` is still in
++ /// progress.
++ pub fn buffer(&mut self) -> Buffer<'a> {
++ assert!(!self.in_progress);
++ let mut x = Buffer::None;
++ mem::swap(&mut self.buffer, &mut x);
++ x
++ }
++
++ /// Remove the inner boxed slice, if any, and return it.
++ ///
++ /// The returned value will be the argument that was passed to
++ /// `from_boxed_slice` when this `AioCb` was created.
++ ///
++ /// It is an error to call this method while the `AioCb` is still in
++ /// progress.
++ pub fn boxed_slice(&mut self) -> Option<Box<dyn Borrow<[u8]>>> {
++ assert!(!self.in_progress, "Can't remove the buffer from an AioCb that's still in-progress. Did you forget to call aio_return?");
++ if let Buffer::BoxedSlice(_) = self.buffer {
++ let mut oldbuffer = Buffer::None;
++ mem::swap(&mut self.buffer, &mut oldbuffer);
++ if let Buffer::BoxedSlice(inner) = oldbuffer {
++ Some(inner)
++ } else {
++ unreachable!();
++ }
++ } else {
++ None
++ }
++ }
++
++ /// Remove the inner boxed mutable slice, if any, and return it.
++ ///
++ /// The returned value will be the argument that was passed to
++ /// `from_boxed_mut_slice` when this `AioCb` was created.
++ ///
++ /// It is an error to call this method while the `AioCb` is still in
++ /// progress.
++ pub fn boxed_mut_slice(&mut self) -> Option<Box<dyn BorrowMut<[u8]>>> {
++ assert!(!self.in_progress, "Can't remove the buffer from an AioCb that's still in-progress. Did you forget to call aio_return?");
++ if let Buffer::BoxedMutSlice(_) = self.buffer {
++ let mut oldbuffer = Buffer::None;
++ mem::swap(&mut self.buffer, &mut oldbuffer);
++ if let Buffer::BoxedMutSlice(inner) = oldbuffer {
++ Some(inner)
++ } else {
++ unreachable!();
++ }
++ } else {
++ None
++ }
++ }
++
++ /// Returns the underlying file descriptor associated with the `AioCb`
++ pub fn fd(&self) -> RawFd {
++ self.aiocb.aio_fildes
++ }
++
++ /// Constructs a new `AioCb` with no associated buffer.
++ ///
++ /// The resulting `AioCb` structure is suitable for use with `AioCb::fsync`.
++ ///
++ /// # Parameters
++ ///
++ /// * `fd`: File descriptor. Required for all aio functions.
++ /// * `prio`: If POSIX Prioritized IO is supported, then the
++ /// operation will be prioritized at the process's
++ /// priority level minus `prio`.
++ /// * `sigev_notify`: Determines how you will be notified of event
++ /// completion.
++ ///
++ /// # Examples
++ ///
++ /// Create an `AioCb` from a raw file descriptor and use it for an
++ /// [`fsync`](#method.fsync) operation.
++ ///
++ /// ```
++ /// # extern crate tempfile;
++ /// # extern crate nix;
++ /// # use nix::errno::Errno;
++ /// # use nix::Error;
++ /// # use nix::sys::aio::*;
++ /// # use nix::sys::signal::SigevNotify::SigevNone;
++ /// # use std::{thread, time};
++ /// # use std::os::unix::io::AsRawFd;
++ /// # use tempfile::tempfile;
++ /// # fn main() {
++ /// let f = tempfile().unwrap();
++ /// let mut aiocb = AioCb::from_fd( f.as_raw_fd(), 0, SigevNone);
++ /// aiocb.fsync(AioFsyncMode::O_SYNC).expect("aio_fsync failed early");
++ /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) {
++ /// thread::sleep(time::Duration::from_millis(10));
++ /// }
++ /// aiocb.aio_return().expect("aio_fsync failed late");
++ /// # }
++ /// ```
++ pub fn from_fd(fd: RawFd, prio: libc::c_int,
++ sigev_notify: SigevNotify) -> AioCb<'a> {
++ let mut a = AioCb::common_init(fd, prio, sigev_notify);
++ a.aio_offset = 0;
++ a.aio_nbytes = 0;
++ a.aio_buf = null_mut();
++
++ AioCb {
++ aiocb: a,
++ mutable: false,
++ in_progress: false,
++ buffer: Buffer::None
++ }
++ }
++
++ /// Constructs a new `AioCb` from a mutable slice.
++ ///
++ /// The resulting `AioCb` will be suitable for both read and write
++ /// operations, but only if the borrow checker can guarantee that the slice
++ /// will outlive the `AioCb`. That will usually be the case if the `AioCb`
++ /// is stack-allocated. If the borrow checker gives you trouble, try using
++ /// [`from_boxed_mut_slice`](#method.from_boxed_mut_slice) instead.
++ ///
++ /// # Parameters
++ ///
++ /// * `fd`: File descriptor. Required for all aio functions.
++ /// * `offs`: File offset
++ /// * `buf`: A memory buffer
++ /// * `prio`: If POSIX Prioritized IO is supported, then the
++ /// operation will be prioritized at the process's
++ /// priority level minus `prio`
++ /// * `sigev_notify`: Determines how you will be notified of event
++ /// completion.
++ /// * `opcode`: This field is only used for `lio_listio`. It
++ /// determines which operation to use for this individual
++ /// aiocb
++ ///
++ /// # Examples
++ ///
++ /// Create an `AioCb` from a mutable slice and read into it.
++ ///
++ /// ```
++ /// # extern crate tempfile;
++ /// # extern crate nix;
++ /// # use nix::errno::Errno;
++ /// # use nix::Error;
++ /// # use nix::sys::aio::*;
++ /// # use nix::sys::signal::SigevNotify;
++ /// # use std::{thread, time};
++ /// # use std::io::Write;
++ /// # use std::os::unix::io::AsRawFd;
++ /// # use tempfile::tempfile;
++ /// # fn main() {
++ /// const INITIAL: &[u8] = b"abcdef123456";
++ /// const LEN: usize = 4;
++ /// let mut rbuf = vec![0; LEN];
++ /// let mut f = tempfile().unwrap();
++ /// f.write_all(INITIAL).unwrap();
++ /// {
++ /// let mut aiocb = AioCb::from_mut_slice( f.as_raw_fd(),
++ /// 2, //offset
++ /// &mut rbuf,
++ /// 0, //priority
++ /// SigevNotify::SigevNone,
++ /// LioOpcode::LIO_NOP);
++ /// aiocb.read().unwrap();
++ /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) {
++ /// thread::sleep(time::Duration::from_millis(10));
++ /// }
++ /// assert_eq!(aiocb.aio_return().unwrap() as usize, LEN);
++ /// }
++ /// assert_eq!(rbuf, b"cdef");
++ /// # }
++ /// ```
++ pub fn from_mut_slice(fd: RawFd, offs: off_t, buf: &'a mut [u8],
++ prio: libc::c_int, sigev_notify: SigevNotify,
++ opcode: LioOpcode) -> AioCb<'a> {
++ let mut a = AioCb::common_init(fd, prio, sigev_notify);
++ a.aio_offset = offs;
++ a.aio_nbytes = buf.len() as size_t;
++ a.aio_buf = buf.as_ptr() as *mut c_void;
++ a.aio_lio_opcode = opcode as libc::c_int;
++
++ AioCb {
++ aiocb: a,
++ mutable: true,
++ in_progress: false,
++ buffer: Buffer::Phantom(PhantomData),
++ }
++ }
++
++ /// The safest and most flexible way to create an `AioCb`.
++ ///
++ /// Unlike [`from_slice`], this method returns a structure suitable for
++ /// placement on the heap. It may be used for write operations, but not
++ /// read operations. Unlike `from_ptr`, this method will ensure that the
++ /// buffer doesn't `drop` while the kernel is still processing it. Any
++ /// object that can be borrowed as a boxed slice will work.
++ ///
++ /// # Parameters
++ ///
++ /// * `fd`: File descriptor. Required for all aio functions.
++ /// * `offs`: File offset
++ /// * `buf`: A boxed slice-like object
++ /// * `prio`: If POSIX Prioritized IO is supported, then the
++ /// operation will be prioritized at the process's
++ /// priority level minus `prio`
++ /// * `sigev_notify`: Determines how you will be notified of event
++ /// completion.
++ /// * `opcode`: This field is only used for `lio_listio`. It
++ /// determines which operation to use for this individual
++ /// aiocb
++ ///
++ /// # Examples
++ ///
++ /// Create an `AioCb` from a Vector and use it for writing
++ ///
++ /// ```
++ /// # extern crate tempfile;
++ /// # extern crate nix;
++ /// # use nix::errno::Errno;
++ /// # use nix::Error;
++ /// # use nix::sys::aio::*;
++ /// # use nix::sys::signal::SigevNotify;
++ /// # use std::{thread, time};
++ /// # use std::io::Write;
++ /// # use std::os::unix::io::AsRawFd;
++ /// # use tempfile::tempfile;
++ /// # fn main() {
++ /// let wbuf = Box::new(Vec::from("CDEF"));
++ /// let expected_len = wbuf.len();
++ /// let mut f = tempfile().unwrap();
++ /// let mut aiocb = AioCb::from_boxed_slice( f.as_raw_fd(),
++ /// 2, //offset
++ /// wbuf,
++ /// 0, //priority
++ /// SigevNotify::SigevNone,
++ /// LioOpcode::LIO_NOP);
++ /// aiocb.write().unwrap();
++ /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) {
++ /// thread::sleep(time::Duration::from_millis(10));
++ /// }
++ /// assert_eq!(aiocb.aio_return().unwrap() as usize, expected_len);
++ /// # }
++ /// ```
++ ///
++ /// Create an `AioCb` from a `Bytes` object
++ ///
++ /// ```
++ /// # extern crate bytes;
++ /// # extern crate tempfile;
++ /// # extern crate nix;
++ /// # use bytes::Bytes;
++ /// # use nix::sys::aio::*;
++ /// # use nix::sys::signal::SigevNotify;
++ /// # use std::os::unix::io::AsRawFd;
++ /// # use tempfile::tempfile;
++ /// # fn main() {
++ /// let wbuf = Box::new(Bytes::from(&b"CDEF"[..]));
++ /// let mut f = tempfile().unwrap();
++ /// let mut aiocb = AioCb::from_boxed_slice( f.as_raw_fd(),
++ /// 2, //offset
++ /// wbuf,
++ /// 0, //priority
++ /// SigevNotify::SigevNone,
++ /// LioOpcode::LIO_NOP);
++ /// # }
++ /// ```
++ ///
++ /// If a library needs to work with buffers that aren't `Box`ed, it can
++ /// create a `Box`ed container for use with this method. Here's an example
++ /// using an un`Box`ed `Bytes` object.
++ ///
++ /// ```
++ /// # extern crate bytes;
++ /// # extern crate tempfile;
++ /// # extern crate nix;
++ /// # use bytes::Bytes;
++ /// # use nix::sys::aio::*;
++ /// # use nix::sys::signal::SigevNotify;
++ /// # use std::borrow::Borrow;
++ /// # use std::os::unix::io::AsRawFd;
++ /// # use tempfile::tempfile;
++ /// struct BytesContainer(Bytes);
++ /// impl Borrow<[u8]> for BytesContainer {
++ /// fn borrow(&self) -> &[u8] {
++ /// self.0.as_ref()
++ /// }
++ /// }
++ /// fn main() {
++ /// let wbuf = Bytes::from(&b"CDEF"[..]);
++ /// let boxed_wbuf = Box::new(BytesContainer(wbuf));
++ /// let mut f = tempfile().unwrap();
++ /// let mut aiocb = AioCb::from_boxed_slice( f.as_raw_fd(),
++ /// 2, //offset
++ /// boxed_wbuf,
++ /// 0, //priority
++ /// SigevNotify::SigevNone,
++ /// LioOpcode::LIO_NOP);
++ /// }
++ /// ```
++ ///
++ /// [`from_slice`]: #method.from_slice
++ pub fn from_boxed_slice(fd: RawFd, offs: off_t, buf: Box<dyn Borrow<[u8]>>,
++ prio: libc::c_int, sigev_notify: SigevNotify,
++ opcode: LioOpcode) -> AioCb<'a> {
++ let mut a = AioCb::common_init(fd, prio, sigev_notify);
++ {
++ let borrowed : &dyn Borrow<[u8]> = buf.borrow();
++ let slice : &[u8] = borrowed.borrow();
++ a.aio_nbytes = slice.len() as size_t;
++ a.aio_buf = slice.as_ptr() as *mut c_void;
++ }
++ a.aio_offset = offs;
++ a.aio_lio_opcode = opcode as libc::c_int;
++
++ AioCb {
++ aiocb: a,
++ mutable: false,
++ in_progress: false,
++ buffer: Buffer::BoxedSlice(buf),
++ }
++ }
++
++ /// The safest and most flexible way to create an `AioCb` for reading.
++ ///
++ /// Like [`from_boxed_slice`], but the slice is a mutable one. More
++ /// flexible than [`from_mut_slice`], because a wide range of objects can be
++ /// used.
++ ///
++ /// # Examples
++ ///
++ /// Create an `AioCb` from a Vector and use it for reading
++ ///
++ /// ```
++ /// # extern crate tempfile;
++ /// # extern crate nix;
++ /// # use nix::errno::Errno;
++ /// # use nix::Error;
++ /// # use nix::sys::aio::*;
++ /// # use nix::sys::signal::SigevNotify;
++ /// # use std::{thread, time};
++ /// # use std::io::Write;
++ /// # use std::os::unix::io::AsRawFd;
++ /// # use tempfile::tempfile;
++ /// # fn main() {
++ /// const INITIAL: &[u8] = b"abcdef123456";
++ /// const LEN: usize = 4;
++ /// let rbuf = Box::new(vec![0; LEN]);
++ /// let mut f = tempfile().unwrap();
++ /// f.write_all(INITIAL).unwrap();
++ /// let mut aiocb = AioCb::from_boxed_mut_slice( f.as_raw_fd(),
++ /// 2, //offset
++ /// rbuf,
++ /// 0, //priority
++ /// SigevNotify::SigevNone,
++ /// LioOpcode::LIO_NOP);
++ /// aiocb.read().unwrap();
++ /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) {
++ /// thread::sleep(time::Duration::from_millis(10));
++ /// }
++ /// assert_eq!(aiocb.aio_return().unwrap() as usize, LEN);
++ /// let mut buffer = aiocb.boxed_mut_slice().unwrap();
++ /// const EXPECT: &[u8] = b"cdef";
++ /// assert_eq!(buffer.borrow_mut(), EXPECT);
++ /// # }
++ /// ```
++ ///
++ /// [`from_boxed_slice`]: #method.from_boxed_slice
++ /// [`from_mut_slice`]: #method.from_mut_slice
++ pub fn from_boxed_mut_slice(fd: RawFd, offs: off_t,
++ mut buf: Box<dyn BorrowMut<[u8]>>,
++ prio: libc::c_int, sigev_notify: SigevNotify,
++ opcode: LioOpcode) -> AioCb<'a> {
++ let mut a = AioCb::common_init(fd, prio, sigev_notify);
++ {
++ let borrowed : &mut dyn BorrowMut<[u8]> = buf.borrow_mut();
++ let slice : &mut [u8] = borrowed.borrow_mut();
++ a.aio_nbytes = slice.len() as size_t;
++ a.aio_buf = slice.as_mut_ptr() as *mut c_void;
++ }
++ a.aio_offset = offs;
++ a.aio_lio_opcode = opcode as libc::c_int;
++
++ AioCb {
++ aiocb: a,
++ mutable: true,
++ in_progress: false,
++ buffer: Buffer::BoxedMutSlice(buf),
++ }
++ }
++
++ /// Constructs a new `AioCb` from a mutable raw pointer
++ ///
++ /// Unlike `from_mut_slice`, this method returns a structure suitable for
++ /// placement on the heap. It may be used for both reads and writes. Due
++ /// to its unsafety, this method is not recommended. It is most useful when
++ /// heap allocation is required but for some reason the data cannot be
++ /// wrapped in a `struct` that implements `BorrowMut<[u8]>`
++ ///
++ /// # Parameters
++ ///
++ /// * `fd`: File descriptor. Required for all aio functions.
++ /// * `offs`: File offset
++ /// * `buf`: Pointer to the memory buffer
++ /// * `len`: Length of the buffer pointed to by `buf`
++ /// * `prio`: If POSIX Prioritized IO is supported, then the
++ /// operation will be prioritized at the process's
++ /// priority level minus `prio`
++ /// * `sigev_notify`: Determines how you will be notified of event
++ /// completion.
++ /// * `opcode`: This field is only used for `lio_listio`. It
++ /// determines which operation to use for this individual
++ /// aiocb
++ ///
++ /// # Safety
++ ///
++ /// The caller must ensure that the storage pointed to by `buf` outlives the
++ /// `AioCb`. The lifetime checker can't help here.
++ pub unsafe fn from_mut_ptr(fd: RawFd, offs: off_t,
++ buf: *mut c_void, len: usize,
++ prio: libc::c_int, sigev_notify: SigevNotify,
++ opcode: LioOpcode) -> AioCb<'a> {
++ let mut a = AioCb::common_init(fd, prio, sigev_notify);
++ a.aio_offset = offs;
++ a.aio_nbytes = len;
++ a.aio_buf = buf;
++ a.aio_lio_opcode = opcode as libc::c_int;
++
++ AioCb {
++ aiocb: a,
++ mutable: true,
++ in_progress: false,
++ buffer: Buffer::None
++ }
++ }
++
++ /// Constructs a new `AioCb` from a raw pointer.
++ ///
++ /// Unlike `from_slice`, this method returns a structure suitable for
++ /// placement on the heap. Due to its unsafety, this method is not
++ /// recommended. It is most useful when heap allocation is required but for
++ /// some reason the data cannot be wrapped in a `struct` that implements
++ /// `Borrow<[u8]>`
++ ///
++ /// # Parameters
++ ///
++ /// * `fd`: File descriptor. Required for all aio functions.
++ /// * `offs`: File offset
++ /// * `buf`: Pointer to the memory buffer
++ /// * `len`: Length of the buffer pointed to by `buf`
++ /// * `prio`: If POSIX Prioritized IO is supported, then the
++ /// operation will be prioritized at the process's
++ /// priority level minus `prio`
++ /// * `sigev_notify`: Determines how you will be notified of event
++ /// completion.
++ /// * `opcode`: This field is only used for `lio_listio`. It
++ /// determines which operation to use for this individual
++ /// aiocb
++ ///
++ /// # Safety
++ ///
++ /// The caller must ensure that the storage pointed to by `buf` outlives the
++ /// `AioCb`. The lifetime checker can't help here.
++ pub unsafe fn from_ptr(fd: RawFd, offs: off_t,
++ buf: *const c_void, len: usize,
++ prio: libc::c_int, sigev_notify: SigevNotify,
++ opcode: LioOpcode) -> AioCb<'a> {
++ let mut a = AioCb::common_init(fd, prio, sigev_notify);
++ a.aio_offset = offs;
++ a.aio_nbytes = len;
++ // casting a const ptr to a mutable ptr here is ok, because we set the
++ // AioCb's mutable field to false
++ a.aio_buf = buf as *mut c_void;
++ a.aio_lio_opcode = opcode as libc::c_int;
++
++ AioCb {
++ aiocb: a,
++ mutable: false,
++ in_progress: false,
++ buffer: Buffer::None
++ }
++ }
++
++ /// Like `from_mut_slice`, but works on constant slices rather than
++ /// mutable slices.
++ ///
++ /// An `AioCb` created this way cannot be used with `read`, and its
++ /// `LioOpcode` cannot be set to `LIO_READ`. This method is useful when
++ /// writing a const buffer with `AioCb::write`, since `from_mut_slice` can't
++ /// work with const buffers.
++ ///
++ /// # Examples
++ ///
++ /// Construct an `AioCb` from a slice and use it for writing.
++ ///
++ /// ```
++ /// # extern crate tempfile;
++ /// # extern crate nix;
++ /// # use nix::errno::Errno;
++ /// # use nix::Error;
++ /// # use nix::sys::aio::*;
++ /// # use nix::sys::signal::SigevNotify;
++ /// # use std::{thread, time};
++ /// # use std::os::unix::io::AsRawFd;
++ /// # use tempfile::tempfile;
++ /// # fn main() {
++ /// const WBUF: &[u8] = b"abcdef123456";
++ /// let mut f = tempfile().unwrap();
++ /// let mut aiocb = AioCb::from_slice( f.as_raw_fd(),
++ /// 2, //offset
++ /// WBUF,
++ /// 0, //priority
++ /// SigevNotify::SigevNone,
++ /// LioOpcode::LIO_NOP);
++ /// aiocb.write().unwrap();
++ /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) {
++ /// thread::sleep(time::Duration::from_millis(10));
++ /// }
++ /// assert_eq!(aiocb.aio_return().unwrap() as usize, WBUF.len());
++ /// # }
++ /// ```
++ // Note: another solution to the problem of writing const buffers would be
++ // to genericize AioCb for both &mut [u8] and &[u8] buffers. AioCb::read
++ // could take the former and AioCb::write could take the latter. However,
++ // then lio_listio wouldn't work, because that function needs a slice of
++ // AioCb, and they must all be of the same type.
++ pub fn from_slice(fd: RawFd, offs: off_t, buf: &'a [u8],
++ prio: libc::c_int, sigev_notify: SigevNotify,
++ opcode: LioOpcode) -> AioCb {
++ let mut a = AioCb::common_init(fd, prio, sigev_notify);
++ a.aio_offset = offs;
++ a.aio_nbytes = buf.len() as size_t;
++ // casting an immutable buffer to a mutable pointer looks unsafe,
++ // but technically its only unsafe to dereference it, not to create
++ // it.
++ a.aio_buf = buf.as_ptr() as *mut c_void;
++ assert!(opcode != LioOpcode::LIO_READ, "Can't read into an immutable buffer");
++ a.aio_lio_opcode = opcode as libc::c_int;
++
++ AioCb {
++ aiocb: a,
++ mutable: false,
++ in_progress: false,
++ buffer: Buffer::None,
++ }
++ }
++
++ fn common_init(fd: RawFd, prio: libc::c_int,
++ sigev_notify: SigevNotify) -> libc::aiocb {
++ // Use mem::zeroed instead of explicitly zeroing each field, because the
++ // number and name of reserved fields is OS-dependent. On some OSes,
++ // some reserved fields are used the kernel for state, and must be
++ // explicitly zeroed when allocated.
++ let mut a = unsafe { mem::zeroed::<libc::aiocb>()};
++ a.aio_fildes = fd;
++ a.aio_reqprio = prio;
++ a.aio_sigevent = SigEvent::new(sigev_notify).sigevent();
++ a
++ }
++
++ /// Update the notification settings for an existing `aiocb`
++ pub fn set_sigev_notify(&mut self, sigev_notify: SigevNotify) {
++ self.aiocb.aio_sigevent = SigEvent::new(sigev_notify).sigevent();
++ }
++
++ /// Cancels an outstanding AIO request.
++ ///
++ /// The operating system is not required to implement cancellation for all
++ /// file and device types. Even if it does, there is no guarantee that the
++ /// operation has not already completed. So the caller must check the
++ /// result and handle operations that were not canceled or that have already
++ /// completed.
++ ///
++ /// # Examples
++ ///
++ /// Cancel an outstanding aio operation. Note that we must still call
++ /// `aio_return` to free resources, even though we don't care about the
++ /// result.
++ ///
++ /// ```
++ /// # extern crate tempfile;
++ /// # extern crate nix;
++ /// # use nix::errno::Errno;
++ /// # use nix::Error;
++ /// # use nix::sys::aio::*;
++ /// # use nix::sys::signal::SigevNotify;
++ /// # use std::{thread, time};
++ /// # use std::io::Write;
++ /// # use std::os::unix::io::AsRawFd;
++ /// # use tempfile::tempfile;
++ /// # fn main() {
++ /// let wbuf = b"CDEF";
++ /// let mut f = tempfile().unwrap();
++ /// let mut aiocb = AioCb::from_slice( f.as_raw_fd(),
++ /// 2, //offset
++ /// &wbuf[..],
++ /// 0, //priority
++ /// SigevNotify::SigevNone,
++ /// LioOpcode::LIO_NOP);
++ /// aiocb.write().unwrap();
++ /// let cs = aiocb.cancel().unwrap();
++ /// if cs == AioCancelStat::AioNotCanceled {
++ /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) {
++ /// thread::sleep(time::Duration::from_millis(10));
++ /// }
++ /// }
++ /// // Must call `aio_return`, but ignore the result
++ /// let _ = aiocb.aio_return();
++ /// # }
++ /// ```
++ ///
++ /// # References
++ ///
++ /// [aio_cancel](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_cancel.html)
++ pub fn cancel(&mut self) -> Result<AioCancelStat> {
++ match unsafe { libc::aio_cancel(self.aiocb.aio_fildes, &mut self.aiocb) } {
++ libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled),
++ libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled),
++ libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone),
++ -1 => Err(Error::last()),
++ _ => panic!("unknown aio_cancel return value")
++ }
++ }
++
++ /// Retrieve error status of an asynchronous operation.
++ ///
++ /// If the request has not yet completed, returns `EINPROGRESS`. Otherwise,
++ /// returns `Ok` or any other error.
++ ///
++ /// # Examples
++ ///
++ /// Issue an aio operation and use `error` to poll for completion. Polling
++ /// is an alternative to `aio_suspend`, used by most of the other examples.
++ ///
++ /// ```
++ /// # extern crate tempfile;
++ /// # extern crate nix;
++ /// # use nix::errno::Errno;
++ /// # use nix::Error;
++ /// # use nix::sys::aio::*;
++ /// # use nix::sys::signal::SigevNotify;
++ /// # use std::{thread, time};
++ /// # use std::os::unix::io::AsRawFd;
++ /// # use tempfile::tempfile;
++ /// # fn main() {
++ /// const WBUF: &[u8] = b"abcdef123456";
++ /// let mut f = tempfile().unwrap();
++ /// let mut aiocb = AioCb::from_slice( f.as_raw_fd(),
++ /// 2, //offset
++ /// WBUF,
++ /// 0, //priority
++ /// SigevNotify::SigevNone,
++ /// LioOpcode::LIO_NOP);
++ /// aiocb.write().unwrap();
++ /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) {
++ /// thread::sleep(time::Duration::from_millis(10));
++ /// }
++ /// assert_eq!(aiocb.aio_return().unwrap() as usize, WBUF.len());
++ /// # }
++ /// ```
++ ///
++ /// # References
++ ///
++ /// [aio_error](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_error.html)
++ pub fn error(&mut self) -> Result<()> {
++ match unsafe { libc::aio_error(&mut self.aiocb as *mut libc::aiocb) } {
++ 0 => Ok(()),
++ num if num > 0 => Err(Error::from_errno(Errno::from_i32(num))),
++ -1 => Err(Error::last()),
++ num => panic!("unknown aio_error return value {:?}", num)
++ }
++ }
++
++ /// An asynchronous version of `fsync(2)`.
++ ///
++ /// # References
++ ///
++ /// [aio_fsync](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_fsync.html)
++ pub fn fsync(&mut self, mode: AioFsyncMode) -> Result<()> {
++ let p: *mut libc::aiocb = &mut self.aiocb;
++ Errno::result(unsafe {
++ libc::aio_fsync(mode as libc::c_int, p)
++ }).map(|_| {
++ self.in_progress = true;
++ })
++ }
++
++ /// Returns the `aiocb`'s `LioOpcode` field
++ ///
++ /// If the value cannot be represented as an `LioOpcode`, returns `None`
++ /// instead.
++ pub fn lio_opcode(&self) -> Option<LioOpcode> {
++ match self.aiocb.aio_lio_opcode {
++ libc::LIO_READ => Some(LioOpcode::LIO_READ),
++ libc::LIO_WRITE => Some(LioOpcode::LIO_WRITE),
++ libc::LIO_NOP => Some(LioOpcode::LIO_NOP),
++ _ => None
++ }
++ }
++
++ /// Returns the requested length of the aio operation in bytes
++ ///
++ /// This method returns the *requested* length of the operation. To get the
++ /// number of bytes actually read or written by a completed operation, use
++ /// `aio_return` instead.
++ pub fn nbytes(&self) -> usize {
++ self.aiocb.aio_nbytes
++ }
++
++ /// Returns the file offset stored in the `AioCb`
++ pub fn offset(&self) -> off_t {
++ self.aiocb.aio_offset
++ }
++
++ /// Returns the priority of the `AioCb`
++ pub fn priority(&self) -> libc::c_int {
++ self.aiocb.aio_reqprio
++ }
++
++ /// Asynchronously reads from a file descriptor into a buffer
++ ///
++ /// # References
++ ///
++ /// [aio_read](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_read.html)
++ pub fn read(&mut self) -> Result<()> {
++ assert!(self.mutable, "Can't read into an immutable buffer");
++ let p: *mut libc::aiocb = &mut self.aiocb;
++ Errno::result(unsafe {
++ libc::aio_read(p)
++ }).map(|_| {
++ self.in_progress = true;
++ })
++ }
++
++ /// Returns the `SigEvent` stored in the `AioCb`
++ pub fn sigevent(&self) -> SigEvent {
++ SigEvent::from(&self.aiocb.aio_sigevent)
++ }
++
++ /// Retrieve return status of an asynchronous operation.
++ ///
++ /// Should only be called once for each `AioCb`, after `AioCb::error`
++ /// indicates that it has completed. The result is the same as for the
++ /// synchronous `read(2)`, `write(2)`, of `fsync(2)` functions.
++ ///
++ /// # References
++ ///
++ /// [aio_return](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_return.html)
++ // Note: this should be just `return`, but that's a reserved word
++ pub fn aio_return(&mut self) -> Result<isize> {
++ let p: *mut libc::aiocb = &mut self.aiocb;
++ self.in_progress = false;
++ Errno::result(unsafe { libc::aio_return(p) })
++ }
++
++ /// Asynchronously writes from a buffer to a file descriptor
++ ///
++ /// # References
++ ///
++ /// [aio_write](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_write.html)
++ pub fn write(&mut self) -> Result<()> {
++ let p: *mut libc::aiocb = &mut self.aiocb;
++ Errno::result(unsafe {
++ libc::aio_write(p)
++ }).map(|_| {
++ self.in_progress = true;
++ })
++ }
++
++}
++
++/// Cancels outstanding AIO requests for a given file descriptor.
++///
++/// # Examples
++///
++/// Issue an aio operation, then cancel all outstanding operations on that file
++/// descriptor.
++///
++/// ```
++/// # extern crate tempfile;
++/// # extern crate nix;
++/// # use nix::errno::Errno;
++/// # use nix::Error;
++/// # use nix::sys::aio::*;
++/// # use nix::sys::signal::SigevNotify;
++/// # use std::{thread, time};
++/// # use std::io::Write;
++/// # use std::os::unix::io::AsRawFd;
++/// # use tempfile::tempfile;
++/// # fn main() {
++/// let wbuf = b"CDEF";
++/// let mut f = tempfile().unwrap();
++/// let mut aiocb = AioCb::from_slice( f.as_raw_fd(),
++/// 2, //offset
++/// &wbuf[..],
++/// 0, //priority
++/// SigevNotify::SigevNone,
++/// LioOpcode::LIO_NOP);
++/// aiocb.write().unwrap();
++/// let cs = aio_cancel_all(f.as_raw_fd()).unwrap();
++/// if cs == AioCancelStat::AioNotCanceled {
++/// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) {
++/// thread::sleep(time::Duration::from_millis(10));
++/// }
++/// }
++/// // Must call `aio_return`, but ignore the result
++/// let _ = aiocb.aio_return();
++/// # }
++/// ```
++///
++/// # References
++///
++/// [`aio_cancel`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_cancel.html)
++pub fn aio_cancel_all(fd: RawFd) -> Result<AioCancelStat> {
++ match unsafe { libc::aio_cancel(fd, null_mut()) } {
++ libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled),
++ libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled),
++ libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone),
++ -1 => Err(Error::last()),
++ _ => panic!("unknown aio_cancel return value")
++ }
++}
++
++/// Suspends the calling process until at least one of the specified `AioCb`s
++/// has completed, a signal is delivered, or the timeout has passed.
++///
++/// If `timeout` is `None`, `aio_suspend` will block indefinitely.
++///
++/// # Examples
++///
++/// Use `aio_suspend` to block until an aio operation completes.
++///
++// Disable doctest due to a known bug in FreeBSD's 32-bit emulation. The fix
++// will be included in release 11.2.
++// FIXME reenable the doc test when the CI machine gets upgraded to that release.
++// https://svnweb.freebsd.org/base?view=revision&revision=325018
++/// ```no_run
++/// # extern crate tempfile;
++/// # extern crate nix;
++/// # use nix::sys::aio::*;
++/// # use nix::sys::signal::SigevNotify;
++/// # use std::os::unix::io::AsRawFd;
++/// # use tempfile::tempfile;
++/// # fn main() {
++/// const WBUF: &[u8] = b"abcdef123456";
++/// let mut f = tempfile().unwrap();
++/// let mut aiocb = AioCb::from_slice( f.as_raw_fd(),
++/// 2, //offset
++/// WBUF,
++/// 0, //priority
++/// SigevNotify::SigevNone,
++/// LioOpcode::LIO_NOP);
++/// aiocb.write().unwrap();
++/// aio_suspend(&[&aiocb], None).expect("aio_suspend failed");
++/// assert_eq!(aiocb.aio_return().unwrap() as usize, WBUF.len());
++/// # }
++/// ```
++/// # References
++///
++/// [`aio_suspend`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_suspend.html)
++pub fn aio_suspend(list: &[&AioCb], timeout: Option<TimeSpec>) -> Result<()> {
++ let plist = list as *const [&AioCb] as *const [*const libc::aiocb];
++ let p = plist as *const *const libc::aiocb;
++ let timep = match timeout {
++ None => null::<libc::timespec>(),
++ Some(x) => x.as_ref() as *const libc::timespec
++ };
++ Errno::result(unsafe {
++ libc::aio_suspend(p, list.len() as i32, timep)
++ }).map(drop)
++}
++
++impl<'a> Debug for AioCb<'a> {
++ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
++ fmt.debug_struct("AioCb")
++ .field("aiocb", &self.aiocb)
++ .field("mutable", &self.mutable)
++ .field("in_progress", &self.in_progress)
++ .finish()
++ }
++}
++
++impl<'a> Drop for AioCb<'a> {
++ /// If the `AioCb` has no remaining state in the kernel, just drop it.
++ /// Otherwise, dropping constitutes a resource leak, which is an error
++ fn drop(&mut self) {
++ assert!(thread::panicking() || !self.in_progress,
++ "Dropped an in-progress AioCb");
++ }
++}
++
++/// LIO Control Block.
++///
++/// The basic structure used to issue multiple AIO operations simultaneously.
++#[cfg(not(any(target_os = "ios", target_os = "macos")))]
++pub struct LioCb<'a> {
++ /// A collection of [`AioCb`]s. All of these will be issued simultaneously
++ /// by the [`listio`] method.
++ ///
++ /// [`AioCb`]: struct.AioCb.html
++ /// [`listio`]: #method.listio
++ pub aiocbs: Vec<AioCb<'a>>,
++
++ /// The actual list passed to `libc::lio_listio`.
++ ///
++ /// It must live for as long as any of the operations are still being
++ /// processesed, because the aio subsystem uses its address as a unique
++ /// identifier.
++ list: Vec<*mut libc::aiocb>,
++
++ /// A partial set of results. This field will get populated by
++ /// `listio_resubmit` when an `LioCb` is resubmitted after an error
++ results: Vec<Option<Result<isize>>>
++}
++
++#[cfg(not(any(target_os = "ios", target_os = "macos")))]
++impl<'a> LioCb<'a> {
++ /// Initialize an empty `LioCb`
++ pub fn with_capacity(capacity: usize) -> LioCb<'a> {
++ LioCb {
++ aiocbs: Vec::with_capacity(capacity),
++ list: Vec::with_capacity(capacity),
++ results: Vec::with_capacity(capacity)
++ }
++ }
++
++ /// Submits multiple asynchronous I/O requests with a single system call.
++ ///
++ /// They are not guaranteed to complete atomically, and the order in which
++ /// the requests are carried out is not specified. Reads, writes, and
++ /// fsyncs may be freely mixed.
++ ///
++ /// This function is useful for reducing the context-switch overhead of
++ /// submitting many AIO operations. It can also be used with
++ /// `LioMode::LIO_WAIT` to block on the result of several independent
++ /// operations. Used that way, it is often useful in programs that
++ /// otherwise make little use of AIO.
++ ///
++ /// # Examples
++ ///
++ /// Use `listio` to submit an aio operation and wait for its completion. In
++ /// this case, there is no need to use [`aio_suspend`] to wait or
++ /// [`AioCb::error`] to poll.
++ ///
++ /// ```
++ /// # extern crate tempfile;
++ /// # extern crate nix;
++ /// # use nix::sys::aio::*;
++ /// # use nix::sys::signal::SigevNotify;
++ /// # use std::os::unix::io::AsRawFd;
++ /// # use tempfile::tempfile;
++ /// # fn main() {
++ /// const WBUF: &[u8] = b"abcdef123456";
++ /// let mut f = tempfile().unwrap();
++ /// let mut liocb = LioCb::with_capacity(1);
++ /// liocb.aiocbs.push(AioCb::from_slice( f.as_raw_fd(),
++ /// 2, //offset
++ /// WBUF,
++ /// 0, //priority
++ /// SigevNotify::SigevNone,
++ /// LioOpcode::LIO_WRITE));
++ /// liocb.listio(LioMode::LIO_WAIT,
++ /// SigevNotify::SigevNone).unwrap();
++ /// assert_eq!(liocb.aio_return(0).unwrap() as usize, WBUF.len());
++ /// # }
++ /// ```
++ ///
++ /// # References
++ ///
++ /// [`lio_listio`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/lio_listio.html)
++ ///
++ /// [`aio_suspend`]: fn.aio_suspend.html
++ /// [`AioCb::error`]: struct.AioCb.html#method.error
++ pub fn listio(&mut self, mode: LioMode,
++ sigev_notify: SigevNotify) -> Result<()> {
++ let sigev = SigEvent::new(sigev_notify);
++ let sigevp = &mut sigev.sigevent() as *mut libc::sigevent;
++ self.list.clear();
++ for a in &mut self.aiocbs {
++ a.in_progress = true;
++ self.list.push(a as *mut AioCb<'a>
++ as *mut libc::aiocb);
++ }
++ let p = self.list.as_ptr();
++ Errno::result(unsafe {
++ libc::lio_listio(mode as i32, p, self.list.len() as i32, sigevp)
++ }).map(drop)
++ }
++
++ /// Resubmits any incomplete operations with [`lio_listio`].
++ ///
++ /// Sometimes, due to system resource limitations, an `lio_listio` call will
++ /// return `EIO`, or `EAGAIN`. Or, if a signal is received, it may return
++ /// `EINTR`. In any of these cases, only a subset of its constituent
++ /// operations will actually have been initiated. `listio_resubmit` will
++ /// resubmit any operations that are still uninitiated.
++ ///
++ /// After calling `listio_resubmit`, results should be collected by
++ /// [`LioCb::aio_return`].
++ ///
++ /// # Examples
++ /// ```no_run
++ /// # extern crate tempfile;
++ /// # extern crate nix;
++ /// # use nix::Error;
++ /// # use nix::errno::Errno;
++ /// # use nix::sys::aio::*;
++ /// # use nix::sys::signal::SigevNotify;
++ /// # use std::os::unix::io::AsRawFd;
++ /// # use std::{thread, time};
++ /// # use tempfile::tempfile;
++ /// # fn main() {
++ /// const WBUF: &[u8] = b"abcdef123456";
++ /// let mut f = tempfile().unwrap();
++ /// let mut liocb = LioCb::with_capacity(1);
++ /// liocb.aiocbs.push(AioCb::from_slice( f.as_raw_fd(),
++ /// 2, //offset
++ /// WBUF,
++ /// 0, //priority
++ /// SigevNotify::SigevNone,
++ /// LioOpcode::LIO_WRITE));
++ /// let mut err = liocb.listio(LioMode::LIO_WAIT, SigevNotify::SigevNone);
++ /// while err == Err(Error::Sys(Errno::EIO)) ||
++ /// err == Err(Error::Sys(Errno::EAGAIN)) {
++ /// thread::sleep(time::Duration::from_millis(10));
++ /// err = liocb.listio_resubmit(LioMode::LIO_WAIT, SigevNotify::SigevNone);
++ /// }
++ /// assert_eq!(liocb.aio_return(0).unwrap() as usize, WBUF.len());
++ /// # }
++ /// ```
++ ///
++ /// # References
++ ///
++ /// [`lio_listio`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/lio_listio.html)
++ ///
++ /// [`lio_listio`]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/lio_listio.html
++ /// [`LioCb::aio_return`]: struct.LioCb.html#method.aio_return
++ // Note: the addresses of any EINPROGRESS or EOK aiocbs _must_ not be
++ // changed by this method, because the kernel relies on their addresses
++ // being stable.
++ // Note: aiocbs that are Ok(()) must be finalized by aio_return, or else the
++ // sigev_notify will immediately refire.
++ pub fn listio_resubmit(&mut self, mode:LioMode,
++ sigev_notify: SigevNotify) -> Result<()> {
++ let sigev = SigEvent::new(sigev_notify);
++ let sigevp = &mut sigev.sigevent() as *mut libc::sigevent;
++ self.list.clear();
++
++ while self.results.len() < self.aiocbs.len() {
++ self.results.push(None);
++ }
++
++ for (i, a) in self.aiocbs.iter_mut().enumerate() {
++ if self.results[i].is_some() {
++ // Already collected final status for this operation
++ continue;
++ }
++ match a.error() {
++ Ok(()) => {
++ // aiocb is complete; collect its status and don't resubmit
++ self.results[i] = Some(a.aio_return());
++ },
++ Err(Error::Sys(Errno::EAGAIN)) => {
++ self.list.push(a as *mut AioCb<'a> as *mut libc::aiocb);
++ },
++ Err(Error::Sys(Errno::EINPROGRESS)) => {
++ // aiocb is was successfully queued; no need to do anything
++ ()
++ },
++ Err(Error::Sys(Errno::EINVAL)) => panic!(
++ "AioCb was never submitted, or already finalized"),
++ _ => unreachable!()
++ }
++ }
++ let p = self.list.as_ptr();
++ Errno::result(unsafe {
++ libc::lio_listio(mode as i32, p, self.list.len() as i32, sigevp)
++ }).map(drop)
++ }
++
++ /// Collect final status for an individual `AioCb` submitted as part of an
++ /// `LioCb`.
++ ///
++ /// This is just like [`AioCb::aio_return`], except it takes into account
++ /// operations that were restarted by [`LioCb::listio_resubmit`]
++ ///
++ /// [`AioCb::aio_return`]: struct.AioCb.html#method.aio_return
++ /// [`LioCb::listio_resubmit`]: #method.listio_resubmit
++ pub fn aio_return(&mut self, i: usize) -> Result<isize> {
++ if i >= self.results.len() || self.results[i].is_none() {
++ self.aiocbs[i].aio_return()
++ } else {
++ self.results[i].unwrap()
++ }
++ }
++
++ /// Retrieve error status of an individual `AioCb` submitted as part of an
++ /// `LioCb`.
++ ///
++ /// This is just like [`AioCb::error`], except it takes into account
++ /// operations that were restarted by [`LioCb::listio_resubmit`]
++ ///
++ /// [`AioCb::error`]: struct.AioCb.html#method.error
++ /// [`LioCb::listio_resubmit`]: #method.listio_resubmit
++ pub fn error(&mut self, i: usize) -> Result<()> {
++ if i >= self.results.len() || self.results[i].is_none() {
++ self.aiocbs[i].error()
++ } else {
++ Ok(())
++ }
++ }
++}
++
++#[cfg(not(any(target_os = "ios", target_os = "macos")))]
++impl<'a> Debug for LioCb<'a> {
++ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
++ fmt.debug_struct("LioCb")
++ .field("aiocbs", &self.aiocbs)
++ .finish()
++ }
++}
++
++#[cfg(not(any(target_os = "ios", target_os = "macos")))]
++impl<'a> From<Vec<AioCb<'a>>> for LioCb<'a> {
++ fn from(src: Vec<AioCb<'a>>) -> LioCb<'a> {
++ LioCb {
++ list: Vec::with_capacity(src.capacity()),
++ results: Vec::with_capacity(src.capacity()),
++ aiocbs: src,
++ }
++ }
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/epoll.rs b/third_party/rust/nix-0.15.0/src/sys/epoll.rs
+new file mode 100644
+index 0000000000000..fef6f4e3ec92c
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/epoll.rs
+@@ -0,0 +1,109 @@
++use Result;
++use errno::Errno;
++use libc::{self, c_int};
++use std::os::unix::io::RawFd;
++use std::ptr;
++use std::mem;
++use ::Error;
++
++libc_bitflags!(
++ pub struct EpollFlags: c_int {
++ EPOLLIN;
++ EPOLLPRI;
++ EPOLLOUT;
++ EPOLLRDNORM;
++ EPOLLRDBAND;
++ EPOLLWRNORM;
++ EPOLLWRBAND;
++ EPOLLMSG;
++ EPOLLERR;
++ EPOLLHUP;
++ EPOLLRDHUP;
++ #[cfg(target_os = "linux")] // Added in 4.5; not in Android.
++ EPOLLEXCLUSIVE;
++ #[cfg(not(target_arch = "mips"))]
++ EPOLLWAKEUP;
++ EPOLLONESHOT;
++ EPOLLET;
++ }
++);
++
++#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
++#[repr(i32)]
++pub enum EpollOp {
++ EpollCtlAdd = libc::EPOLL_CTL_ADD,
++ EpollCtlDel = libc::EPOLL_CTL_DEL,
++ EpollCtlMod = libc::EPOLL_CTL_MOD,
++}
++
++libc_bitflags!{
++ pub struct EpollCreateFlags: c_int {
++ EPOLL_CLOEXEC;
++ }
++}
++
++#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
++#[repr(C)]
++pub struct EpollEvent {
++ event: libc::epoll_event,
++}
++
++impl EpollEvent {
++ pub fn new(events: EpollFlags, data: u64) -> Self {
++ EpollEvent { event: libc::epoll_event { events: events.bits() as u32, u64: data } }
++ }
++
++ pub fn empty() -> Self {
++ unsafe { mem::zeroed::<EpollEvent>() }
++ }
++
++ pub fn events(&self) -> EpollFlags {
++ EpollFlags::from_bits(self.event.events as c_int).unwrap()
++ }
++
++ pub fn data(&self) -> u64 {
++ self.event.u64
++ }
++}
++
++#[inline]
++pub fn epoll_create() -> Result<RawFd> {
++ let res = unsafe { libc::epoll_create(1024) };
++
++ Errno::result(res)
++}
++
++#[inline]
++pub fn epoll_create1(flags: EpollCreateFlags) -> Result<RawFd> {
++ let res = unsafe { libc::epoll_create1(flags.bits()) };
++
++ Errno::result(res)
++}
++
++#[inline]
++pub fn epoll_ctl<'a, T>(epfd: RawFd, op: EpollOp, fd: RawFd, event: T) -> Result<()>
++ where T: Into<Option<&'a mut EpollEvent>>
++{
++ let mut event: Option<&mut EpollEvent> = event.into();
++ if event.is_none() && op != EpollOp::EpollCtlDel {
++ Err(Error::Sys(Errno::EINVAL))
++ } else {
++ let res = unsafe {
++ if let Some(ref mut event) = event {
++ libc::epoll_ctl(epfd, op as c_int, fd, &mut event.event)
++ } else {
++ libc::epoll_ctl(epfd, op as c_int, fd, ptr::null_mut())
++ }
++ };
++ Errno::result(res).map(drop)
++ }
++}
++
++#[inline]
++pub fn epoll_wait(epfd: RawFd, events: &mut [EpollEvent], timeout_ms: isize) -> Result<usize> {
++ let res = unsafe {
++ libc::epoll_wait(epfd, events.as_mut_ptr() as *mut libc::epoll_event, events.len() as c_int, timeout_ms as c_int)
++ };
++
++ Errno::result(res).map(|r| r as usize)
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/event.rs b/third_party/rust/nix-0.15.0/src/sys/event.rs
+new file mode 100644
+index 0000000000000..8cd7372f88188
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/event.rs
+@@ -0,0 +1,351 @@
++/* TOOD: Implement for other kqueue based systems
++ */
++
++use {Errno, Result};
++#[cfg(not(target_os = "netbsd"))]
++use libc::{timespec, time_t, c_int, c_long, intptr_t, uintptr_t};
++#[cfg(target_os = "netbsd")]
++use libc::{timespec, time_t, c_long, intptr_t, uintptr_t, size_t};
++use libc;
++use std::os::unix::io::RawFd;
++use std::ptr;
++use std::mem;
++
++// Redefine kevent in terms of programmer-friendly enums and bitfields.
++#[repr(C)]
++#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
++pub struct KEvent {
++ kevent: libc::kevent,
++}
++
++#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
++ target_os = "ios", target_os = "macos",
++ target_os = "openbsd"))]
++type type_of_udata = *mut libc::c_void;
++#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
++ target_os = "ios", target_os = "macos"))]
++type type_of_data = intptr_t;
++#[cfg(any(target_os = "netbsd"))]
++type type_of_udata = intptr_t;
++#[cfg(any(target_os = "netbsd", target_os = "openbsd"))]
++type type_of_data = libc::int64_t;
++
++#[cfg(target_os = "netbsd")]
++type type_of_event_filter = u32;
++#[cfg(not(target_os = "netbsd"))]
++type type_of_event_filter = i16;
++libc_enum! {
++ #[cfg_attr(target_os = "netbsd", repr(u32))]
++ #[cfg_attr(not(target_os = "netbsd"), repr(i16))]
++ pub enum EventFilter {
++ EVFILT_AIO,
++ /// Returns whenever there is no remaining data in the write buffer
++ #[cfg(target_os = "freebsd")]
++ EVFILT_EMPTY,
++ #[cfg(target_os = "dragonfly")]
++ EVFILT_EXCEPT,
++ #[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "ios",
++ target_os = "macos"))]
++ EVFILT_FS,
++ #[cfg(target_os = "freebsd")]
++ EVFILT_LIO,
++ #[cfg(any(target_os = "ios", target_os = "macos"))]
++ EVFILT_MACHPORT,
++ EVFILT_PROC,
++ /// Returns events associated with the process referenced by a given
++ /// process descriptor, created by `pdfork()`. The events to monitor are:
++ ///
++ /// - NOTE_EXIT: the process has exited. The exit status will be stored in data.
++ #[cfg(target_os = "freebsd")]
++ EVFILT_PROCDESC,
++ EVFILT_READ,
++ /// Returns whenever an asynchronous `sendfile()` call completes.
++ #[cfg(target_os = "freebsd")]
++ EVFILT_SENDFILE,
++ EVFILT_SIGNAL,
++ EVFILT_TIMER,
++ #[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "ios",
++ target_os = "macos"))]
++ EVFILT_USER,
++ #[cfg(any(target_os = "ios", target_os = "macos"))]
++ EVFILT_VM,
++ EVFILT_VNODE,
++ EVFILT_WRITE,
++ }
++}
++
++#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
++ target_os = "ios", target_os = "macos",
++ target_os = "openbsd"))]
++pub type type_of_event_flag = u16;
++#[cfg(any(target_os = "netbsd"))]
++pub type type_of_event_flag = u32;
++libc_bitflags!{
++ pub struct EventFlag: type_of_event_flag {
++ EV_ADD;
++ EV_CLEAR;
++ EV_DELETE;
++ EV_DISABLE;
++ // No released version of OpenBSD supports EV_DISPATCH or EV_RECEIPT.
++ // These have been commited to the -current branch though and are
++ // expected to be part of the OpenBSD 6.2 release in Nov 2017.
++ // See: https://marc.info/?l=openbsd-tech&m=149621427511219&w=2
++ // https://github.com/rust-lang/libc/pull/613
++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
++ target_os = "ios", target_os = "macos",
++ target_os = "netbsd"))]
++ EV_DISPATCH;
++ #[cfg(target_os = "freebsd")]
++ EV_DROP;
++ EV_ENABLE;
++ EV_EOF;
++ EV_ERROR;
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ EV_FLAG0;
++ EV_FLAG1;
++ #[cfg(target_os = "dragonfly")]
++ EV_NODATA;
++ EV_ONESHOT;
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ EV_OOBAND;
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ EV_POLL;
++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
++ target_os = "ios", target_os = "macos",
++ target_os = "netbsd"))]
++ EV_RECEIPT;
++ EV_SYSFLAGS;
++ }
++}
++
++libc_bitflags!(
++ pub struct FilterFlag: u32 {
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ NOTE_ABSOLUTE;
++ NOTE_ATTRIB;
++ NOTE_CHILD;
++ NOTE_DELETE;
++ #[cfg(target_os = "openbsd")]
++ NOTE_EOF;
++ NOTE_EXEC;
++ NOTE_EXIT;
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ #[deprecated( since="0.14.0", note="Deprecated since OSX 10.9")]
++ #[allow(deprecated)]
++ NOTE_EXIT_REPARENTED;
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ NOTE_EXITSTATUS;
++ NOTE_EXTEND;
++ #[cfg(any(target_os = "macos",
++ target_os = "ios",
++ target_os = "freebsd",
++ target_os = "dragonfly"))]
++ NOTE_FFAND;
++ #[cfg(any(target_os = "macos",
++ target_os = "ios",
++ target_os = "freebsd",
++ target_os = "dragonfly"))]
++ NOTE_FFCOPY;
++ #[cfg(any(target_os = "macos",
++ target_os = "ios",
++ target_os = "freebsd",
++ target_os = "dragonfly"))]
++ NOTE_FFCTRLMASK;
++ #[cfg(any(target_os = "macos",
++ target_os = "ios",
++ target_os = "freebsd",
++ target_os = "dragonfly"))]
++ NOTE_FFLAGSMASK;
++ #[cfg(any(target_os = "macos",
++ target_os = "ios",
++ target_os = "freebsd",
++ target_os = "dragonfly"))]
++ NOTE_FFNOP;
++ #[cfg(any(target_os = "macos",
++ target_os = "ios",
++ target_os = "freebsd",
++ target_os = "dragonfly"))]
++ NOTE_FFOR;
++ NOTE_FORK;
++ NOTE_LINK;
++ NOTE_LOWAT;
++ #[cfg(target_os = "freebsd")]
++ NOTE_MSECONDS;
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ NOTE_NONE;
++ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))]
++ NOTE_NSECONDS;
++ #[cfg(target_os = "dragonfly")]
++ NOTE_OOB;
++ NOTE_PCTRLMASK;
++ NOTE_PDATAMASK;
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ #[deprecated( since="0.14.0", note="Deprecated since OSX 10.9")]
++ #[allow(deprecated)]
++ NOTE_REAP;
++ NOTE_RENAME;
++ NOTE_REVOKE;
++ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))]
++ NOTE_SECONDS;
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ NOTE_SIGNAL;
++ NOTE_TRACK;
++ NOTE_TRACKERR;
++ #[cfg(any(target_os = "macos",
++ target_os = "ios",
++ target_os = "freebsd",
++ target_os = "dragonfly"))]
++ NOTE_TRIGGER;
++ #[cfg(target_os = "openbsd")]
++ NOTE_TRUNCATE;
++ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))]
++ NOTE_USECONDS;
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ NOTE_VM_ERROR;
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ NOTE_VM_PRESSURE;
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ NOTE_VM_PRESSURE_SUDDEN_TERMINATE;
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ NOTE_VM_PRESSURE_TERMINATE;
++ NOTE_WRITE;
++ }
++);
++
++pub fn kqueue() -> Result<RawFd> {
++ let res = unsafe { libc::kqueue() };
++
++ Errno::result(res)
++}
++
++
++// KEvent can't derive Send because on some operating systems, udata is defined
++// as a void*. However, KEvent's public API always treats udata as an intptr_t,
++// which is safe to Send.
++unsafe impl Send for KEvent {
++}
++
++impl KEvent {
++ pub fn new(ident: uintptr_t, filter: EventFilter, flags: EventFlag,
++ fflags:FilterFlag, data: intptr_t, udata: intptr_t) -> KEvent {
++ KEvent { kevent: libc::kevent {
++ ident: ident,
++ filter: filter as type_of_event_filter,
++ flags: flags.bits(),
++ fflags: fflags.bits(),
++ data: data as type_of_data,
++ udata: udata as type_of_udata
++ } }
++ }
++
++ pub fn ident(&self) -> uintptr_t {
++ self.kevent.ident
++ }
++
++ pub fn filter(&self) -> EventFilter {
++ unsafe { mem::transmute(self.kevent.filter as type_of_event_filter) }
++ }
++
++ pub fn flags(&self) -> EventFlag {
++ EventFlag::from_bits(self.kevent.flags).unwrap()
++ }
++
++ pub fn fflags(&self) -> FilterFlag {
++ FilterFlag::from_bits(self.kevent.fflags).unwrap()
++ }
++
++ pub fn data(&self) -> intptr_t {
++ self.kevent.data as intptr_t
++ }
++
++ pub fn udata(&self) -> intptr_t {
++ self.kevent.udata as intptr_t
++ }
++}
++
++pub fn kevent(kq: RawFd,
++ changelist: &[KEvent],
++ eventlist: &mut [KEvent],
++ timeout_ms: usize) -> Result<usize> {
++
++ // Convert ms to timespec
++ let timeout = timespec {
++ tv_sec: (timeout_ms / 1000) as time_t,
++ tv_nsec: ((timeout_ms % 1000) * 1_000_000) as c_long
++ };
++
++ kevent_ts(kq, changelist, eventlist, Some(timeout))
++}
++
++#[cfg(any(target_os = "macos",
++ target_os = "ios",
++ target_os = "freebsd",
++ target_os = "dragonfly",
++ target_os = "openbsd"))]
++type type_of_nchanges = c_int;
++#[cfg(target_os = "netbsd")]
++type type_of_nchanges = size_t;
++
++pub fn kevent_ts(kq: RawFd,
++ changelist: &[KEvent],
++ eventlist: &mut [KEvent],
++ timeout_opt: Option<timespec>) -> Result<usize> {
++
++ let res = unsafe {
++ libc::kevent(
++ kq,
++ changelist.as_ptr() as *const libc::kevent,
++ changelist.len() as type_of_nchanges,
++ eventlist.as_mut_ptr() as *mut libc::kevent,
++ eventlist.len() as type_of_nchanges,
++ if let Some(ref timeout) = timeout_opt {timeout as *const timespec} else {ptr::null()})
++ };
++
++ Errno::result(res).map(|r| r as usize)
++}
++
++#[inline]
++pub fn ev_set(ev: &mut KEvent,
++ ident: usize,
++ filter: EventFilter,
++ flags: EventFlag,
++ fflags: FilterFlag,
++ udata: intptr_t) {
++
++ ev.kevent.ident = ident as uintptr_t;
++ ev.kevent.filter = filter as type_of_event_filter;
++ ev.kevent.flags = flags.bits();
++ ev.kevent.fflags = fflags.bits();
++ ev.kevent.data = 0;
++ ev.kevent.udata = udata as type_of_udata;
++}
++
++#[test]
++fn test_struct_kevent() {
++ let udata : intptr_t = 12345;
++
++ let expected = libc::kevent{ident: 0xdead_beef,
++ filter: libc::EVFILT_READ,
++ flags: libc::EV_ONESHOT | libc::EV_ADD,
++ fflags: libc::NOTE_CHILD | libc::NOTE_EXIT,
++ data: 0x1337,
++ udata: udata as type_of_udata};
++ let actual = KEvent::new(0xdead_beef,
++ EventFilter::EVFILT_READ,
++ EventFlag::EV_ONESHOT | EventFlag::EV_ADD,
++ FilterFlag::NOTE_CHILD | FilterFlag::NOTE_EXIT,
++ 0x1337,
++ udata);
++ assert!(expected.ident == actual.ident());
++ assert!(expected.filter == actual.filter() as type_of_event_filter);
++ assert!(expected.flags == actual.flags().bits());
++ assert!(expected.fflags == actual.fflags().bits());
++ assert!(expected.data == actual.data() as type_of_data);
++ assert!(expected.udata == actual.udata() as type_of_udata);
++ assert!(mem::size_of::<libc::kevent>() == mem::size_of::<KEvent>());
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/eventfd.rs b/third_party/rust/nix-0.15.0/src/sys/eventfd.rs
+new file mode 100644
+index 0000000000000..c5a54e46a1735
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/eventfd.rs
+@@ -0,0 +1,18 @@
++use libc;
++use std::os::unix::io::RawFd;
++use Result;
++use errno::Errno;
++
++libc_bitflags! {
++ pub struct EfdFlags: libc::c_int {
++ EFD_CLOEXEC; // Since Linux 2.6.27
++ EFD_NONBLOCK; // Since Linux 2.6.27
++ EFD_SEMAPHORE; // Since Linux 2.6.30
++ }
++}
++
++pub fn eventfd(initval: libc::c_uint, flags: EfdFlags) -> Result<RawFd> {
++ let res = unsafe { libc::eventfd(initval, flags.bits()) };
++
++ Errno::result(res).map(|r| r as RawFd)
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/inotify.rs b/third_party/rust/nix-0.15.0/src/sys/inotify.rs
+new file mode 100644
+index 0000000000000..e6c2cf64d29dc
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/inotify.rs
+@@ -0,0 +1,230 @@
++//! Monitoring API for filesystem events.
++//!
++//! Inotify is a Linux-only API to monitor filesystems events.
++//!
++//! For more documentation, please read [inotify(7)](http://man7.org/linux/man-pages/man7/inotify.7.html).
++//!
++//! # Examples
++//!
++//! Monitor all events happening in directory "test":
++//! ```no_run
++//! # use nix::sys::inotify::{AddWatchFlags,InitFlags,Inotify};
++//! #
++//! // We create a new inotify instance.
++//! let instance = Inotify::init(InitFlags::empty()).unwrap();
++//!
++//! // We add a new watch on directory "test" for all events.
++//! let wd = instance.add_watch("test", AddWatchFlags::IN_ALL_EVENTS).unwrap();
++//!
++//! loop {
++//! // We read from our inotify instance for events.
++//! let events = instance.read_events().unwrap();
++//! println!("Events: {:?}", events);
++//! }
++//! ```
++
++use libc;
++use libc::{
++ c_char,
++ c_int,
++};
++use std::ffi::{OsString,OsStr,CStr};
++use std::os::unix::ffi::OsStrExt;
++use std::mem::size_of;
++use std::os::unix::io::{RawFd,AsRawFd,FromRawFd};
++use unistd::read;
++use Result;
++use NixPath;
++use errno::Errno;
++
++libc_bitflags! {
++ /// Configuration options for [`inotify_add_watch`](fn.inotify_add_watch.html).
++ pub struct AddWatchFlags: u32 {
++ IN_ACCESS;
++ IN_MODIFY;
++ IN_ATTRIB;
++ IN_CLOSE_WRITE;
++ IN_CLOSE_NOWRITE;
++ IN_OPEN;
++ IN_MOVED_FROM;
++ IN_MOVED_TO;
++ IN_CREATE;
++ IN_DELETE;
++ IN_DELETE_SELF;
++ IN_MOVE_SELF;
++
++ IN_UNMOUNT;
++ IN_Q_OVERFLOW;
++ IN_IGNORED;
++
++ IN_CLOSE;
++ IN_MOVE;
++
++ IN_ONLYDIR;
++ IN_DONT_FOLLOW;
++
++ IN_ISDIR;
++ IN_ONESHOT;
++ IN_ALL_EVENTS;
++ }
++}
++
++libc_bitflags! {
++ /// Configuration options for [`inotify_init1`](fn.inotify_init1.html).
++ pub struct InitFlags: c_int {
++ IN_CLOEXEC;
++ IN_NONBLOCK;
++ }
++}
++
++/// An inotify instance. This is also a file descriptor, you can feed it to
++/// other interfaces consuming file descriptors, epoll for example.
++#[derive(Debug, Clone, Copy)]
++pub struct Inotify {
++ fd: RawFd
++}
++
++/// This object is returned when you create a new watch on an inotify instance.
++/// It is then returned as part of an event once triggered. It allows you to
++/// know which watch triggered which event.
++#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd)]
++pub struct WatchDescriptor {
++ wd: i32
++}
++
++/// A single inotify event.
++///
++/// For more documentation see, [inotify(7)](http://man7.org/linux/man-pages/man7/inotify.7.html).
++#[derive(Debug)]
++pub struct InotifyEvent {
++ /// Watch descriptor. This field corresponds to the watch descriptor you
++ /// were issued when calling add_watch. It allows you to know which watch
++ /// this event comes from.
++ pub wd: WatchDescriptor,
++ /// Event mask. This field is a bitfield describing the exact event that
++ /// occured.
++ pub mask: AddWatchFlags,
++ /// This cookie is a number that allows you to connect related events. For
++ /// now only IN_MOVED_FROM and IN_MOVED_TO can be connected.
++ pub cookie: u32,
++ /// Filename. This field exists only if the event was triggered for a file
++ /// inside the watched directory.
++ pub name: Option<OsString>
++}
++
++impl Inotify {
++ /// Initialize a new inotify instance.
++ ///
++ /// Returns a Result containing an inotify instance.
++ ///
++ /// For more information see, [inotify_init(2)](http://man7.org/linux/man-pages/man2/inotify_init.2.html).
++ pub fn init(flags: InitFlags) -> Result<Inotify> {
++ let res = Errno::result(unsafe {
++ libc::inotify_init1(flags.bits())
++ });
++
++ res.map(|fd| Inotify { fd })
++ }
++
++ /// Adds a new watch on the target file or directory.
++ ///
++ /// Returns a watch descriptor. This is not a File Descriptor!
++ ///
++ /// For more information see, [inotify_add_watch(2)](http://man7.org/linux/man-pages/man2/inotify_add_watch.2.html).
++ pub fn add_watch<P: ?Sized + NixPath>(&self,
++ path: &P,
++ mask: AddWatchFlags)
++ -> Result<WatchDescriptor>
++ {
++ let res = path.with_nix_path(|cstr| {
++ unsafe {
++ libc::inotify_add_watch(self.fd, cstr.as_ptr(), mask.bits())
++ }
++ })?;
++
++ Errno::result(res).map(|wd| WatchDescriptor { wd })
++ }
++
++ /// Removes an existing watch using the watch descriptor returned by
++ /// inotify_add_watch.
++ ///
++ /// Returns an EINVAL error if the watch descriptor is invalid.
++ ///
++ /// For more information see, [inotify_rm_watch(2)](http://man7.org/linux/man-pages/man2/inotify_rm_watch.2.html).
++ #[cfg(target_os = "linux")]
++ pub fn rm_watch(&self, wd: WatchDescriptor) -> Result<()> {
++ let res = unsafe { libc::inotify_rm_watch(self.fd, wd.wd) };
++
++ Errno::result(res).map(drop)
++ }
++
++ #[cfg(target_os = "android")]
++ pub fn rm_watch(&self, wd: WatchDescriptor) -> Result<()> {
++ let res = unsafe { libc::inotify_rm_watch(self.fd, wd.wd as u32) };
++
++ Errno::result(res).map(drop)
++ }
++
++ /// Reads a collection of events from the inotify file descriptor. This call
++ /// can either be blocking or non blocking depending on whether IN_NONBLOCK
++ /// was set at initialization.
++ ///
++ /// Returns as many events as available. If the call was non blocking and no
++ /// events could be read then the EAGAIN error is returned.
++ pub fn read_events(&self) -> Result<Vec<InotifyEvent>> {
++ let header_size = size_of::<libc::inotify_event>();
++ let mut buffer = [0u8; 4096];
++ let mut events = Vec::new();
++ let mut offset = 0;
++
++ let nread = read(self.fd, &mut buffer)?;
++
++ while (nread - offset) >= header_size {
++ let event = unsafe {
++ &*(
++ buffer
++ .as_ptr()
++ .offset(offset as isize) as *const libc::inotify_event
++ )
++ };
++
++ let name = match event.len {
++ 0 => None,
++ _ => {
++ let ptr = unsafe {
++ buffer
++ .as_ptr()
++ .offset(offset as isize + header_size as isize)
++ as *const c_char
++ };
++ let cstr = unsafe { CStr::from_ptr(ptr) };
++
++ Some(OsStr::from_bytes(cstr.to_bytes()).to_owned())
++ }
++ };
++
++ events.push(InotifyEvent {
++ wd: WatchDescriptor { wd: event.wd },
++ mask: AddWatchFlags::from_bits_truncate(event.mask),
++ cookie: event.cookie,
++ name
++ });
++
++ offset += header_size + event.len as usize;
++ }
++
++ Ok(events)
++ }
++}
++
++impl AsRawFd for Inotify {
++ fn as_raw_fd(&self) -> RawFd {
++ self.fd
++ }
++}
++
++impl FromRawFd for Inotify {
++ unsafe fn from_raw_fd(fd: RawFd) -> Self {
++ Inotify { fd }
++ }
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/ioctl/bsd.rs b/third_party/rust/nix-0.15.0/src/sys/ioctl/bsd.rs
+new file mode 100644
+index 0000000000000..9b8b0ff1a155f
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/ioctl/bsd.rs
+@@ -0,0 +1,102 @@
++/// The datatype used for the ioctl number
++#[doc(hidden)]
++pub type ioctl_num_type = ::libc::c_ulong;
++/// The datatype used for the 3rd argument
++#[doc(hidden)]
++pub type ioctl_param_type = ::libc::c_int;
++
++mod consts {
++ use ::sys::ioctl::ioctl_num_type;
++ #[doc(hidden)]
++ pub const VOID: ioctl_num_type = 0x2000_0000;
++ #[doc(hidden)]
++ pub const OUT: ioctl_num_type = 0x4000_0000;
++ #[doc(hidden)]
++ pub const IN: ioctl_num_type = 0x8000_0000;
++ #[doc(hidden)]
++ pub const INOUT: ioctl_num_type = (IN|OUT);
++ #[doc(hidden)]
++ pub const IOCPARM_MASK: ioctl_num_type = 0x1fff;
++}
++
++pub use self::consts::*;
++
++#[macro_export]
++#[doc(hidden)]
++macro_rules! ioc {
++ ($inout:expr, $group:expr, $num:expr, $len:expr) => (
++ $inout | (($len as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::IOCPARM_MASK) << 16) | (($group as $crate::sys::ioctl::ioctl_num_type) << 8) | ($num as $crate::sys::ioctl::ioctl_num_type)
++ )
++}
++
++/// Generate an ioctl request code for a command that passes no data.
++///
++/// This is equivalent to the `_IO()` macro exposed by the C ioctl API.
++///
++/// You should only use this macro directly if the `ioctl` you're working
++/// with is "bad" and you cannot use `ioctl_none!()` directly.
++///
++/// # Example
++///
++/// ```
++/// # #[macro_use] extern crate nix;
++/// const KVMIO: u8 = 0xAE;
++/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
++/// # fn main() {}
++/// ```
++#[macro_export(local_inner_macros)]
++macro_rules! request_code_none {
++ ($g:expr, $n:expr) => (ioc!($crate::sys::ioctl::VOID, $g, $n, 0))
++}
++
++/// Generate an ioctl request code for a command that passes an integer
++///
++/// This is equivalent to the `_IOWINT()` macro exposed by the C ioctl API.
++///
++/// You should only use this macro directly if the `ioctl` you're working
++/// with is "bad" and you cannot use `ioctl_write_int!()` directly.
++#[macro_export(local_inner_macros)]
++macro_rules! request_code_write_int {
++ ($g:expr, $n:expr) => (ioc!($crate::sys::ioctl::VOID, $g, $n, ::std::mem::size_of::<$crate::libc::c_int>()))
++}
++
++/// Generate an ioctl request code for a command that reads.
++///
++/// This is equivalent to the `_IOR()` macro exposed by the C ioctl API.
++///
++/// You should only use this macro directly if the `ioctl` you're working
++/// with is "bad" and you cannot use `ioctl_read!()` directly.
++///
++/// The read/write direction is relative to userland, so this
++/// command would be userland is reading and the kernel is
++/// writing.
++#[macro_export(local_inner_macros)]
++macro_rules! request_code_read {
++ ($g:expr, $n:expr, $len:expr) => (ioc!($crate::sys::ioctl::OUT, $g, $n, $len))
++}
++
++/// Generate an ioctl request code for a command that writes.
++///
++/// This is equivalent to the `_IOW()` macro exposed by the C ioctl API.
++///
++/// You should only use this macro directly if the `ioctl` you're working
++/// with is "bad" and you cannot use `ioctl_write!()` directly.
++///
++/// The read/write direction is relative to userland, so this
++/// command would be userland is writing and the kernel is
++/// reading.
++#[macro_export(local_inner_macros)]
++macro_rules! request_code_write {
++ ($g:expr, $n:expr, $len:expr) => (ioc!($crate::sys::ioctl::IN, $g, $n, $len))
++}
++
++/// Generate an ioctl request code for a command that reads and writes.
++///
++/// This is equivalent to the `_IOWR()` macro exposed by the C ioctl API.
++///
++/// You should only use this macro directly if the `ioctl` you're working
++/// with is "bad" and you cannot use `ioctl_readwrite!()` directly.
++#[macro_export(local_inner_macros)]
++macro_rules! request_code_readwrite {
++ ($g:expr, $n:expr, $len:expr) => (ioc!($crate::sys::ioctl::INOUT, $g, $n, $len))
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/ioctl/linux.rs b/third_party/rust/nix-0.15.0/src/sys/ioctl/linux.rs
+new file mode 100644
+index 0000000000000..9cdac72a4b80b
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/ioctl/linux.rs
+@@ -0,0 +1,140 @@
++/// The datatype used for the ioctl number
++#[cfg(any(target_os = "android", target_env = "musl"))]
++#[doc(hidden)]
++pub type ioctl_num_type = ::libc::c_int;
++#[cfg(not(any(target_os = "android", target_env = "musl")))]
++#[doc(hidden)]
++pub type ioctl_num_type = ::libc::c_ulong;
++/// The datatype used for the 3rd argument
++#[doc(hidden)]
++pub type ioctl_param_type = ::libc::c_ulong;
++
++#[doc(hidden)]
++pub const NRBITS: ioctl_num_type = 8;
++#[doc(hidden)]
++pub const TYPEBITS: ioctl_num_type = 8;
++
++#[cfg(any(target_arch = "mips", target_arch = "mips64", target_arch = "powerpc", target_arch = "powerpc64", target_arch = "sparc64"))]
++mod consts {
++ #[doc(hidden)]
++ pub const NONE: u8 = 1;
++ #[doc(hidden)]
++ pub const READ: u8 = 2;
++ #[doc(hidden)]
++ pub const WRITE: u8 = 4;
++ #[doc(hidden)]
++ pub const SIZEBITS: u8 = 13;
++ #[doc(hidden)]
++ pub const DIRBITS: u8 = 3;
++}
++
++// "Generic" ioctl protocol
++#[cfg(any(target_arch = "x86",
++ target_arch = "arm",
++ target_arch = "s390x",
++ target_arch = "x86_64",
++ target_arch = "aarch64"))]
++mod consts {
++ #[doc(hidden)]
++ pub const NONE: u8 = 0;
++ #[doc(hidden)]
++ pub const READ: u8 = 2;
++ #[doc(hidden)]
++ pub const WRITE: u8 = 1;
++ #[doc(hidden)]
++ pub const SIZEBITS: u8 = 14;
++ #[doc(hidden)]
++ pub const DIRBITS: u8 = 2;
++}
++
++pub use self::consts::*;
++
++#[doc(hidden)]
++pub const NRSHIFT: ioctl_num_type = 0;
++#[doc(hidden)]
++pub const TYPESHIFT: ioctl_num_type = NRSHIFT + NRBITS as ioctl_num_type;
++#[doc(hidden)]
++pub const SIZESHIFT: ioctl_num_type = TYPESHIFT + TYPEBITS as ioctl_num_type;
++#[doc(hidden)]
++pub const DIRSHIFT: ioctl_num_type = SIZESHIFT + SIZEBITS as ioctl_num_type;
++
++#[doc(hidden)]
++pub const NRMASK: ioctl_num_type = (1 << NRBITS) - 1;
++#[doc(hidden)]
++pub const TYPEMASK: ioctl_num_type = (1 << TYPEBITS) - 1;
++#[doc(hidden)]
++pub const SIZEMASK: ioctl_num_type = (1 << SIZEBITS) - 1;
++#[doc(hidden)]
++pub const DIRMASK: ioctl_num_type = (1 << DIRBITS) - 1;
++
++/// Encode an ioctl command.
++#[macro_export]
++#[doc(hidden)]
++macro_rules! ioc {
++ ($dir:expr, $ty:expr, $nr:expr, $sz:expr) => (
++ (($dir as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::DIRMASK) << $crate::sys::ioctl::DIRSHIFT) |
++ (($ty as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::TYPEMASK) << $crate::sys::ioctl::TYPESHIFT) |
++ (($nr as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::NRMASK) << $crate::sys::ioctl::NRSHIFT) |
++ (($sz as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::SIZEMASK) << $crate::sys::ioctl::SIZESHIFT))
++}
++
++/// Generate an ioctl request code for a command that passes no data.
++///
++/// This is equivalent to the `_IO()` macro exposed by the C ioctl API.
++///
++/// You should only use this macro directly if the `ioctl` you're working
++/// with is "bad" and you cannot use `ioctl_none!()` directly.
++///
++/// # Example
++///
++/// ```
++/// # #[macro_use] extern crate nix;
++/// const KVMIO: u8 = 0xAE;
++/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
++/// # fn main() {}
++/// ```
++#[macro_export(local_inner_macros)]
++macro_rules! request_code_none {
++ ($ty:expr, $nr:expr) => (ioc!($crate::sys::ioctl::NONE, $ty, $nr, 0))
++}
++
++/// Generate an ioctl request code for a command that reads.
++///
++/// This is equivalent to the `_IOR()` macro exposed by the C ioctl API.
++///
++/// You should only use this macro directly if the `ioctl` you're working
++/// with is "bad" and you cannot use `ioctl_read!()` directly.
++///
++/// The read/write direction is relative to userland, so this
++/// command would be userland is reading and the kernel is
++/// writing.
++#[macro_export(local_inner_macros)]
++macro_rules! request_code_read {
++ ($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::READ, $ty, $nr, $sz))
++}
++
++/// Generate an ioctl request code for a command that writes.
++///
++/// This is equivalent to the `_IOW()` macro exposed by the C ioctl API.
++///
++/// You should only use this macro directly if the `ioctl` you're working
++/// with is "bad" and you cannot use `ioctl_write!()` directly.
++///
++/// The read/write direction is relative to userland, so this
++/// command would be userland is writing and the kernel is
++/// reading.
++#[macro_export(local_inner_macros)]
++macro_rules! request_code_write {
++ ($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::WRITE, $ty, $nr, $sz))
++}
++
++/// Generate an ioctl request code for a command that reads and writes.
++///
++/// This is equivalent to the `_IOWR()` macro exposed by the C ioctl API.
++///
++/// You should only use this macro directly if the `ioctl` you're working
++/// with is "bad" and you cannot use `ioctl_readwrite!()` directly.
++#[macro_export(local_inner_macros)]
++macro_rules! request_code_readwrite {
++ ($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::READ | $crate::sys::ioctl::WRITE, $ty, $nr, $sz))
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/ioctl/mod.rs b/third_party/rust/nix-0.15.0/src/sys/ioctl/mod.rs
+new file mode 100644
+index 0000000000000..4513bf877434a
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/ioctl/mod.rs
+@@ -0,0 +1,778 @@
++//! Provide helpers for making ioctl system calls.
++//!
++//! This library is pretty low-level and messy. `ioctl` is not fun.
++//!
++//! What is an `ioctl`?
++//! ===================
++//!
++//! The `ioctl` syscall is the grab-bag syscall on POSIX systems. Don't want to add a new
++//! syscall? Make it an `ioctl`! `ioctl` refers to both the syscall, and the commands that can be
++//! sent with it. `ioctl` stands for "IO control", and the commands are always sent to a file
++//! descriptor.
++//!
++//! It is common to see `ioctl`s used for the following purposes:
++//!
++//! * Provide read/write access to out-of-band data related to a device such as configuration
++//! (for instance, setting serial port options)
++//! * Provide a mechanism for performing full-duplex data transfers (for instance, xfer on SPI
++//! devices).
++//! * Provide access to control functions on a device (for example, on Linux you can send
++//! commands like pause, resume, and eject to the CDROM device.
++//! * Do whatever else the device driver creator thought made most sense.
++//!
++//! `ioctl`s are synchronous system calls and are similar to read and write calls in that regard.
++//! They operate on file descriptors and have an identifier that specifies what the ioctl is.
++//! Additionally they may read or write data and therefore need to pass along a data pointer.
++//! Besides the semantics of the ioctls being confusing, the generation of this identifer can also
++//! be difficult.
++//!
++//! Historically `ioctl` numbers were arbitrary hard-coded values. In Linux (before 2.6) and some
++//! unices this has changed to a more-ordered system where the ioctl numbers are partitioned into
++//! subcomponents (For linux this is documented in
++//! [`Documentation/ioctl/ioctl-number.txt`](http://elixir.free-electrons.com/linux/latest/source/Documentation/ioctl/ioctl-number.txt)):
++//!
++//! * Number: The actual ioctl ID
++//! * Type: A grouping of ioctls for a common purpose or driver
++//! * Size: The size in bytes of the data that will be transferred
++//! * Direction: Whether there is any data and if it's read, write, or both
++//!
++//! Newer drivers should not generate complete integer identifiers for their `ioctl`s instead
++//! preferring to use the 4 components above to generate the final ioctl identifier. Because of
++//! how old `ioctl`s are, however, there are many hard-coded `ioctl` identifiers. These are
++//! commonly referred to as "bad" in `ioctl` documentation.
++//!
++//! Defining `ioctl`s
++//! =================
++//!
++//! This library provides several `ioctl_*!` macros for binding `ioctl`s. These generate public
++//! unsafe functions that can then be used for calling the ioctl. This macro has a few different
++//! ways it can be used depending on the specific ioctl you're working with.
++//!
++//! A simple `ioctl` is `SPI_IOC_RD_MODE`. This ioctl works with the SPI interface on Linux. This
++//! specific `ioctl` reads the mode of the SPI device as a `u8`. It's declared in
++//! `/include/uapi/linux/spi/spidev.h` as `_IOR(SPI_IOC_MAGIC, 1, __u8)`. Since it uses the `_IOR`
++//! macro, we know it's a `read` ioctl and can use the `ioctl_read!` macro as follows:
++//!
++//! ```
++//! # #[macro_use] extern crate nix;
++//! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
++//! const SPI_IOC_TYPE_MODE: u8 = 1;
++//! ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8);
++//! # fn main() {}
++//! ```
++//!
++//! This generates the function:
++//!
++//! ```
++//! # #[macro_use] extern crate nix;
++//! # use std::mem;
++//! # use nix::{libc, Result};
++//! # use nix::errno::Errno;
++//! # use nix::libc::c_int as c_int;
++//! # const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
++//! # const SPI_IOC_TYPE_MODE: u8 = 1;
++//! pub unsafe fn spi_read_mode(fd: c_int, data: *mut u8) -> Result<c_int> {
++//! let res = libc::ioctl(fd, request_code_read!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, mem::size_of::<u8>()), data);
++//! Errno::result(res)
++//! }
++//! # fn main() {}
++//! ```
++//!
++//! The return value for the wrapper functions generated by the `ioctl_*!` macros are `nix::Error`s.
++//! These are generated by assuming the return value of the ioctl is `-1` on error and everything
++//! else is a valid return value. If this is not the case, `Result::map` can be used to map some
++//! of the range of "good" values (-Inf..-2, 0..Inf) into a smaller range in a helper function.
++//!
++//! Writing `ioctl`s generally use pointers as their data source and these should use the
++//! `ioctl_write_ptr!`. But in some cases an `int` is passed directly. For these `ioctl`s use the
++//! `ioctl_write_int!` macro. This variant does not take a type as the last argument:
++//!
++//! ```
++//! # #[macro_use] extern crate nix;
++//! const HCI_IOC_MAGIC: u8 = b'k';
++//! const HCI_IOC_HCIDEVUP: u8 = 1;
++//! ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
++//! # fn main() {}
++//! ```
++//!
++//! Some `ioctl`s don't transfer any data, and those should use `ioctl_none!`. This macro
++//! doesn't take a type and so it is declared similar to the `write_int` variant shown above.
++//!
++//! The mode for a given `ioctl` should be clear from the documentation if it has good
++//! documentation. Otherwise it will be clear based on the macro used to generate the `ioctl`
++//! number where `_IO`, `_IOR`, `_IOW`, and `_IOWR` map to "none", "read", "write_*", and "readwrite"
++//! respectively. To determine the specific `write_` variant to use you'll need to find
++//! what the argument type is supposed to be. If it's an `int`, then `write_int` should be used,
++//! otherwise it should be a pointer and `write_ptr` should be used. On Linux the
++//! [`ioctl_list` man page](http://man7.org/linux/man-pages/man2/ioctl_list.2.html) describes a
++//! large number of `ioctl`s and describes their argument data type.
++//!
++//! Using "bad" `ioctl`s
++//! --------------------
++//!
++//! As mentioned earlier, there are many old `ioctl`s that do not use the newer method of
++//! generating `ioctl` numbers and instead use hardcoded values. These can be used with the
++//! `ioctl_*_bad!` macros. This naming comes from the Linux kernel which refers to these
++//! `ioctl`s as "bad". These are a different variant as they bypass calling the macro that generates
++//! the ioctl number and instead use the defined value directly.
++//!
++//! For example the `TCGETS` `ioctl` reads a `termios` data structure for a given file descriptor.
++//! It's defined as `0x5401` in `ioctls.h` on Linux and can be implemented as:
++//!
++//! ```
++//! # #[macro_use] extern crate nix;
++//! # #[cfg(any(target_os = "android", target_os = "linux"))]
++//! # use nix::libc::TCGETS as TCGETS;
++//! # #[cfg(any(target_os = "android", target_os = "linux"))]
++//! # use nix::libc::termios as termios;
++//! # #[cfg(any(target_os = "android", target_os = "linux"))]
++//! ioctl_read_bad!(tcgets, TCGETS, termios);
++//! # fn main() {}
++//! ```
++//!
++//! The generated function has the same form as that generated by `ioctl_read!`:
++//!
++//! ```text
++//! pub unsafe fn tcgets(fd: c_int, data: *mut termios) -> Result<c_int>;
++//! ```
++//!
++//! Working with Arrays
++//! -------------------
++//!
++//! Some `ioctl`s work with entire arrays of elements. These are supported by the `ioctl_*_buf`
++//! family of macros: `ioctl_read_buf`, `ioctl_write_buf`, and `ioctl_readwrite_buf`. Note that
++//! there are no "bad" versions for working with buffers. The generated functions include a `len`
++//! argument to specify the number of elements (where the type of each element is specified in the
++//! macro).
++//!
++//! Again looking to the SPI `ioctl`s on Linux for an example, there is a `SPI_IOC_MESSAGE` `ioctl`
++//! that queues up multiple SPI messages by writing an entire array of `spi_ioc_transfer` structs.
++//! `linux/spi/spidev.h` defines a macro to calculate the `ioctl` number like:
++//!
++//! ```C
++//! #define SPI_IOC_MAGIC 'k'
++//! #define SPI_MSGSIZE(N) ...
++//! #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)])
++//! ```
++//!
++//! The `SPI_MSGSIZE(N)` calculation is already handled by the `ioctl_*!` macros, so all that's
++//! needed to define this `ioctl` is:
++//!
++//! ```
++//! # #[macro_use] extern crate nix;
++//! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
++//! const SPI_IOC_TYPE_MESSAGE: u8 = 0;
++//! # pub struct spi_ioc_transfer(u64);
++//! ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer);
++//! # fn main() {}
++//! ```
++//!
++//! This generates a function like:
++//!
++//! ```
++//! # #[macro_use] extern crate nix;
++//! # use std::mem;
++//! # use nix::{libc, Result};
++//! # use nix::errno::Errno;
++//! # use nix::libc::c_int as c_int;
++//! # const SPI_IOC_MAGIC: u8 = b'k';
++//! # const SPI_IOC_TYPE_MESSAGE: u8 = 0;
++//! # pub struct spi_ioc_transfer(u64);
++//! pub unsafe fn spi_message(fd: c_int, data: &mut [spi_ioc_transfer]) -> Result<c_int> {
++//! let res = libc::ioctl(fd,
++//! request_code_write!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, data.len() * mem::size_of::<spi_ioc_transfer>()),
++//! data);
++//! Errno::result(res)
++//! }
++//! # fn main() {}
++//! ```
++//!
++//! Finding `ioctl` Documentation
++//! -----------------------------
++//!
++//! For Linux, look at your system's headers. For example, `/usr/include/linux/input.h` has a lot
++//! of lines defining macros which use `_IO`, `_IOR`, `_IOW`, `_IOC`, and `_IOWR`. Some `ioctl`s are
++//! documented directly in the headers defining their constants, but others have more extensive
++//! documentation in man pages (like termios' `ioctl`s which are in `tty_ioctl(4)`).
++//!
++//! Documenting the Generated Functions
++//! ===================================
++//!
++//! In many cases, users will wish for the functions generated by the `ioctl`
++//! macro to be public and documented. For this reason, the generated functions
++//! are public by default. If you wish to hide the ioctl, you will need to put
++//! them in a private module.
++//!
++//! For documentation, it is possible to use doc comments inside the `ioctl_*!` macros. Here is an
++//! example :
++//!
++//! ```
++//! # #[macro_use] extern crate nix;
++//! # use nix::libc::c_int;
++//! ioctl_read! {
++//! /// Make the given terminal the controlling terminal of the calling process. The calling
++//! /// process must be a session leader and not have a controlling terminal already. If the
++//! /// terminal is already the controlling terminal of a different session group then the
++//! /// ioctl will fail with **EPERM**, unless the caller is root (more precisely: has the
++//! /// **CAP_SYS_ADMIN** capability) and arg equals 1, in which case the terminal is stolen
++//! /// and all processes that had it as controlling terminal lose it.
++//! tiocsctty, b't', 19, c_int
++//! }
++//!
++//! # fn main() {}
++//! ```
++#[cfg(any(target_os = "android", target_os = "linux"))]
++#[macro_use]
++mod linux;
++
++#[cfg(any(target_os = "android", target_os = "linux"))]
++pub use self::linux::*;
++
++#[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "ios",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd"))]
++#[macro_use]
++mod bsd;
++
++#[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "ios",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd"))]
++pub use self::bsd::*;
++
++/// Convert raw ioctl return value to a Nix result
++#[macro_export]
++#[doc(hidden)]
++macro_rules! convert_ioctl_res {
++ ($w:expr) => (
++ {
++ $crate::errno::Errno::result($w)
++ }
++ );
++}
++
++/// Generates a wrapper function for an ioctl that passes no data to the kernel.
++///
++/// The arguments to this macro are:
++///
++/// * The function name
++/// * The ioctl identifier
++/// * The ioctl sequence number
++///
++/// The generated function has the following signature:
++///
++/// ```rust,ignore
++/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int>
++/// ```
++///
++/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
++///
++/// # Example
++///
++/// The `videodev2` driver on Linux defines the `log_status` `ioctl` as:
++///
++/// ```C
++/// #define VIDIOC_LOG_STATUS _IO('V', 70)
++/// ```
++///
++/// This can be implemented in Rust like:
++///
++/// ```no_run
++/// # #[macro_use] extern crate nix;
++/// ioctl_none!(log_status, b'V', 70);
++/// fn main() {}
++/// ```
++#[macro_export(local_inner_macros)]
++macro_rules! ioctl_none {
++ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
++ $(#[$attr])*
++ pub unsafe fn $name(fd: $crate::libc::c_int)
++ -> $crate::Result<$crate::libc::c_int> {
++ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_none!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type))
++ }
++ )
++}
++
++/// Generates a wrapper function for a "bad" ioctl that passes no data to the kernel.
++///
++/// The arguments to this macro are:
++///
++/// * The function name
++/// * The ioctl request code
++///
++/// The generated function has the following signature:
++///
++/// ```rust,ignore
++/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int>
++/// ```
++///
++/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
++///
++/// # Example
++///
++/// ```no_run
++/// # #[macro_use] extern crate nix;
++/// # extern crate libc;
++/// # use libc::TIOCNXCL;
++/// # use std::fs::File;
++/// # use std::os::unix::io::AsRawFd;
++/// ioctl_none_bad!(tiocnxcl, TIOCNXCL);
++/// fn main() {
++/// let file = File::open("/dev/ttyUSB0").unwrap();
++/// unsafe { tiocnxcl(file.as_raw_fd()) }.unwrap();
++/// }
++/// ```
++// TODO: add an example using request_code_*!()
++#[macro_export(local_inner_macros)]
++macro_rules! ioctl_none_bad {
++ ($(#[$attr:meta])* $name:ident, $nr:expr) => (
++ $(#[$attr])*
++ pub unsafe fn $name(fd: $crate::libc::c_int)
++ -> $crate::Result<$crate::libc::c_int> {
++ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type))
++ }
++ )
++}
++
++/// Generates a wrapper function for an ioctl that reads data from the kernel.
++///
++/// The arguments to this macro are:
++///
++/// * The function name
++/// * The ioctl identifier
++/// * The ioctl sequence number
++/// * The data type passed by this ioctl
++///
++/// The generated function has the following signature:
++///
++/// ```rust,ignore
++/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
++/// ```
++///
++/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
++///
++/// # Example
++///
++/// ```
++/// # #[macro_use] extern crate nix;
++/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
++/// const SPI_IOC_TYPE_MODE: u8 = 1;
++/// ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8);
++/// # fn main() {}
++/// ```
++#[macro_export(local_inner_macros)]
++macro_rules! ioctl_read {
++ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
++ $(#[$attr])*
++ pub unsafe fn $name(fd: $crate::libc::c_int,
++ data: *mut $ty)
++ -> $crate::Result<$crate::libc::c_int> {
++ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
++ }
++ )
++}
++
++/// Generates a wrapper function for a "bad" ioctl that reads data from the kernel.
++///
++/// The arguments to this macro are:
++///
++/// * The function name
++/// * The ioctl request code
++/// * The data type passed by this ioctl
++///
++/// The generated function has the following signature:
++///
++/// ```rust,ignore
++/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
++/// ```
++///
++/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
++///
++/// # Example
++///
++/// ```
++/// # extern crate libc;
++/// # #[macro_use] extern crate nix;
++/// # #[cfg(any(target_os = "android", target_os = "linux"))]
++/// ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios);
++/// # fn main() {}
++/// ```
++#[macro_export(local_inner_macros)]
++macro_rules! ioctl_read_bad {
++ ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
++ $(#[$attr])*
++ pub unsafe fn $name(fd: $crate::libc::c_int,
++ data: *mut $ty)
++ -> $crate::Result<$crate::libc::c_int> {
++ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
++ }
++ )
++}
++
++/// Generates a wrapper function for an ioctl that writes data through a pointer to the kernel.
++///
++/// The arguments to this macro are:
++///
++/// * The function name
++/// * The ioctl identifier
++/// * The ioctl sequence number
++/// * The data type passed by this ioctl
++///
++/// The generated function has the following signature:
++///
++/// ```rust,ignore
++/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int>
++/// ```
++///
++/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
++///
++/// # Example
++///
++/// ```
++/// # #[macro_use] extern crate nix;
++/// # pub struct v4l2_audio {}
++/// ioctl_write_ptr!(s_audio, b'V', 34, v4l2_audio);
++/// # fn main() {}
++/// ```
++#[macro_export(local_inner_macros)]
++macro_rules! ioctl_write_ptr {
++ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
++ $(#[$attr])*
++ pub unsafe fn $name(fd: $crate::libc::c_int,
++ data: *const $ty)
++ -> $crate::Result<$crate::libc::c_int> {
++ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
++ }
++ )
++}
++
++/// Generates a wrapper function for a "bad" ioctl that writes data through a pointer to the kernel.
++///
++/// The arguments to this macro are:
++///
++/// * The function name
++/// * The ioctl request code
++/// * The data type passed by this ioctl
++///
++/// The generated function has the following signature:
++///
++/// ```rust,ignore
++/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int>
++/// ```
++///
++/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
++///
++/// # Example
++///
++/// ```
++/// # extern crate libc;
++/// # #[macro_use] extern crate nix;
++/// # #[cfg(any(target_os = "android", target_os = "linux"))]
++/// ioctl_write_ptr_bad!(tcsets, libc::TCSETS, libc::termios);
++/// # fn main() {}
++/// ```
++#[macro_export(local_inner_macros)]
++macro_rules! ioctl_write_ptr_bad {
++ ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
++ $(#[$attr])*
++ pub unsafe fn $name(fd: $crate::libc::c_int,
++ data: *const $ty)
++ -> $crate::Result<$crate::libc::c_int> {
++ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
++ }
++ )
++}
++
++cfg_if!{
++ if #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] {
++ /// Generates a wrapper function for a ioctl that writes an integer to the kernel.
++ ///
++ /// The arguments to this macro are:
++ ///
++ /// * The function name
++ /// * The ioctl identifier
++ /// * The ioctl sequence number
++ ///
++ /// The generated function has the following signature:
++ ///
++ /// ```rust,ignore
++ /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int>
++ /// ```
++ ///
++ /// `nix::sys::ioctl::ioctl_param_type` depends on the OS:
++ /// * BSD - `libc::c_int`
++ /// * Linux - `libc::c_ulong`
++ ///
++ /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
++ ///
++ /// # Example
++ ///
++ /// ```
++ /// # #[macro_use] extern crate nix;
++ /// ioctl_write_int!(vt_activate, b'v', 4);
++ /// # fn main() {}
++ /// ```
++ #[macro_export(local_inner_macros)]
++ macro_rules! ioctl_write_int {
++ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
++ $(#[$attr])*
++ pub unsafe fn $name(fd: $crate::libc::c_int,
++ data: $crate::sys::ioctl::ioctl_param_type)
++ -> $crate::Result<$crate::libc::c_int> {
++ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write_int!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type, data))
++ }
++ )
++ }
++ } else {
++ /// Generates a wrapper function for a ioctl that writes an integer to the kernel.
++ ///
++ /// The arguments to this macro are:
++ ///
++ /// * The function name
++ /// * The ioctl identifier
++ /// * The ioctl sequence number
++ ///
++ /// The generated function has the following signature:
++ ///
++ /// ```rust,ignore
++ /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int>
++ /// ```
++ ///
++ /// `nix::sys::ioctl::ioctl_param_type` depends on the OS:
++ /// * BSD - `libc::c_int`
++ /// * Linux - `libc::c_ulong`
++ ///
++ /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
++ ///
++ /// # Example
++ ///
++ /// ```
++ /// # #[macro_use] extern crate nix;
++ /// const HCI_IOC_MAGIC: u8 = b'k';
++ /// const HCI_IOC_HCIDEVUP: u8 = 1;
++ /// ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
++ /// # fn main() {}
++ /// ```
++ #[macro_export(local_inner_macros)]
++ macro_rules! ioctl_write_int {
++ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
++ $(#[$attr])*
++ pub unsafe fn $name(fd: $crate::libc::c_int,
++ data: $crate::sys::ioctl::ioctl_param_type)
++ -> $crate::Result<$crate::libc::c_int> {
++ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of::<$crate::libc::c_int>()) as $crate::sys::ioctl::ioctl_num_type, data))
++ }
++ )
++ }
++ }
++}
++
++/// Generates a wrapper function for a "bad" ioctl that writes an integer to the kernel.
++///
++/// The arguments to this macro are:
++///
++/// * The function name
++/// * The ioctl request code
++///
++/// The generated function has the following signature:
++///
++/// ```rust,ignore
++/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: libc::c_int) -> Result<libc::c_int>
++/// ```
++///
++/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
++///
++/// # Examples
++///
++/// ```
++/// # extern crate libc;
++/// # #[macro_use] extern crate nix;
++/// # #[cfg(any(target_os = "android", target_os = "linux"))]
++/// ioctl_write_int_bad!(tcsbrk, libc::TCSBRK);
++/// # fn main() {}
++/// ```
++///
++/// ```rust
++/// # #[macro_use] extern crate nix;
++/// const KVMIO: u8 = 0xAE;
++/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
++/// # fn main() {}
++/// ```
++#[macro_export(local_inner_macros)]
++macro_rules! ioctl_write_int_bad {
++ ($(#[$attr:meta])* $name:ident, $nr:expr) => (
++ $(#[$attr])*
++ pub unsafe fn $name(fd: $crate::libc::c_int,
++ data: $crate::libc::c_int)
++ -> $crate::Result<$crate::libc::c_int> {
++ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
++ }
++ )
++}
++
++/// Generates a wrapper function for an ioctl that reads and writes data to the kernel.
++///
++/// The arguments to this macro are:
++///
++/// * The function name
++/// * The ioctl identifier
++/// * The ioctl sequence number
++/// * The data type passed by this ioctl
++///
++/// The generated function has the following signature:
++///
++/// ```rust,ignore
++/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
++/// ```
++///
++/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
++///
++/// # Example
++///
++/// ```
++/// # #[macro_use] extern crate nix;
++/// # pub struct v4l2_audio {}
++/// ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio);
++/// # fn main() {}
++/// ```
++#[macro_export(local_inner_macros)]
++macro_rules! ioctl_readwrite {
++ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
++ $(#[$attr])*
++ pub unsafe fn $name(fd: $crate::libc::c_int,
++ data: *mut $ty)
++ -> $crate::Result<$crate::libc::c_int> {
++ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
++ }
++ )
++}
++
++/// Generates a wrapper function for a "bad" ioctl that reads and writes data to the kernel.
++///
++/// The arguments to this macro are:
++///
++/// * The function name
++/// * The ioctl request code
++/// * The data type passed by this ioctl
++///
++/// The generated function has the following signature:
++///
++/// ```rust,ignore
++/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
++/// ```
++///
++/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
++// TODO: Find an example for ioctl_readwrite_bad
++#[macro_export(local_inner_macros)]
++macro_rules! ioctl_readwrite_bad {
++ ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
++ $(#[$attr])*
++ pub unsafe fn $name(fd: $crate::libc::c_int,
++ data: *mut $ty)
++ -> $crate::Result<$crate::libc::c_int> {
++ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
++ }
++ )
++}
++
++/// Generates a wrapper function for an ioctl that reads an array of elements from the kernel.
++///
++/// The arguments to this macro are:
++///
++/// * The function name
++/// * The ioctl identifier
++/// * The ioctl sequence number
++/// * The data type passed by this ioctl
++///
++/// The generated function has the following signature:
++///
++/// ```rust,ignore
++/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int>
++/// ```
++///
++/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
++// TODO: Find an example for ioctl_read_buf
++#[macro_export(local_inner_macros)]
++macro_rules! ioctl_read_buf {
++ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
++ $(#[$attr])*
++ pub unsafe fn $name(fd: $crate::libc::c_int,
++ data: &mut [$ty])
++ -> $crate::Result<$crate::libc::c_int> {
++ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
++ }
++ )
++}
++
++/// Generates a wrapper function for an ioctl that writes an array of elements to the kernel.
++///
++/// The arguments to this macro are:
++///
++/// * The function name
++/// * The ioctl identifier
++/// * The ioctl sequence number
++/// * The data type passed by this ioctl
++///
++/// The generated function has the following signature:
++///
++/// ```rust,ignore
++/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &[DATA_TYPE]) -> Result<libc::c_int>
++/// ```
++///
++/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
++///
++/// # Examples
++///
++/// ```
++/// # #[macro_use] extern crate nix;
++/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
++/// const SPI_IOC_TYPE_MESSAGE: u8 = 0;
++/// # pub struct spi_ioc_transfer(u64);
++/// ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer);
++/// # fn main() {}
++/// ```
++#[macro_export(local_inner_macros)]
++macro_rules! ioctl_write_buf {
++ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
++ $(#[$attr])*
++ pub unsafe fn $name(fd: $crate::libc::c_int,
++ data: &[$ty])
++ -> $crate::Result<$crate::libc::c_int> {
++ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
++ }
++ )
++}
++
++/// Generates a wrapper function for an ioctl that reads and writes an array of elements to the kernel.
++///
++/// The arguments to this macro are:
++///
++/// * The function name
++/// * The ioctl identifier
++/// * The ioctl sequence number
++/// * The data type passed by this ioctl
++///
++/// The generated function has the following signature:
++///
++/// ```rust,ignore
++/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int>
++/// ```
++///
++/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
++// TODO: Find an example for readwrite_buf
++#[macro_export(local_inner_macros)]
++macro_rules! ioctl_readwrite_buf {
++ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
++ $(#[$attr])*
++ pub unsafe fn $name(fd: $crate::libc::c_int,
++ data: &mut [$ty])
++ -> $crate::Result<$crate::libc::c_int> {
++ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
++ }
++ )
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/memfd.rs b/third_party/rust/nix-0.15.0/src/sys/memfd.rs
+new file mode 100644
+index 0000000000000..9672429b31e7f
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/memfd.rs
+@@ -0,0 +1,20 @@
++use libc;
++use std::os::unix::io::RawFd;
++use Result;
++use errno::Errno;
++use std::ffi::CStr;
++
++libc_bitflags!(
++ pub struct MemFdCreateFlag: libc::c_uint {
++ MFD_CLOEXEC;
++ MFD_ALLOW_SEALING;
++ }
++);
++
++pub fn memfd_create(name: &CStr, flags: MemFdCreateFlag) -> Result<RawFd> {
++ let res = unsafe {
++ libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags.bits())
++ };
++
++ Errno::result(res).map(|r| r as RawFd)
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/mman.rs b/third_party/rust/nix-0.15.0/src/sys/mman.rs
+new file mode 100644
+index 0000000000000..4e250501dd0f0
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/mman.rs
+@@ -0,0 +1,325 @@
++use {Error, Result};
++#[cfg(not(target_os = "android"))]
++use NixPath;
++use errno::Errno;
++#[cfg(not(target_os = "android"))]
++use fcntl::OFlag;
++use libc::{self, c_int, c_void, size_t, off_t};
++#[cfg(not(target_os = "android"))]
++use sys::stat::Mode;
++use std::os::unix::io::RawFd;
++
++libc_bitflags!{
++ /// Desired memory protection of a memory mapping.
++ pub struct ProtFlags: c_int {
++ /// Pages cannot be accessed.
++ PROT_NONE;
++ /// Pages can be read.
++ PROT_READ;
++ /// Pages can be written.
++ PROT_WRITE;
++ /// Pages can be executed
++ PROT_EXEC;
++ /// Apply protection up to the end of a mapping that grows upwards.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ PROT_GROWSDOWN;
++ /// Apply protection down to the beginning of a mapping that grows downwards.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ PROT_GROWSUP;
++ }
++}
++
++libc_bitflags!{
++ /// Additional parameters for `mmap()`.
++ pub struct MapFlags: c_int {
++ /// Compatibility flag. Ignored.
++ MAP_FILE;
++ /// Share this mapping. Mutually exclusive with `MAP_PRIVATE`.
++ MAP_SHARED;
++ /// Create a private copy-on-write mapping. Mutually exclusive with `MAP_SHARED`.
++ MAP_PRIVATE;
++ /// Place the mapping at exactly the address specified in `addr`.
++ MAP_FIXED;
++ /// Synonym for `MAP_ANONYMOUS`.
++ MAP_ANON;
++ /// The mapping is not backed by any file.
++ #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
++ MAP_ANONYMOUS;
++ /// Put the mapping into the first 2GB of the process address space.
++ #[cfg(any(all(any(target_os = "android", target_os = "linux"),
++ any(target_arch = "x86", target_arch = "x86_64")),
++ all(target_os = "linux", target_env = "musl", any(target_arch = "x86", target_arch = "x86_64")),
++ all(target_os = "freebsd", target_pointer_width = "64")))]
++ MAP_32BIT;
++ /// Used for stacks; indicates to the kernel that the mapping should extend downward in memory.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ MAP_GROWSDOWN;
++ /// Compatibility flag. Ignored.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ MAP_DENYWRITE;
++ /// Compatibility flag. Ignored.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ MAP_EXECUTABLE;
++ /// Mark the mmaped region to be locked in the same way as `mlock(2)`.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ MAP_LOCKED;
++ /// Do not reserve swap space for this mapping.
++ ///
++ /// This was removed in FreeBSD 11.
++ #[cfg(not(target_os = "freebsd"))]
++ MAP_NORESERVE;
++ /// Populate page tables for a mapping.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ MAP_POPULATE;
++ /// Only meaningful when used with `MAP_POPULATE`. Don't perform read-ahead.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ MAP_NONBLOCK;
++ /// Allocate the mapping using "huge pages."
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ MAP_HUGETLB;
++ /// Lock the mapped region into memory as with `mlock(2)`.
++ #[cfg(target_os = "netbsd")]
++ MAP_WIRED;
++ /// Causes dirtied data in the specified range to be flushed to disk only when necessary.
++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
++ MAP_NOSYNC;
++ /// Rename private pages to a file.
++ ///
++ /// This was removed in FreeBSD 11.
++ #[cfg(any(target_os = "dragonfly", target_os = "netbsd", target_os = "openbsd"))]
++ MAP_RENAME;
++ /// Region may contain semaphores.
++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
++ MAP_HASSEMAPHORE;
++ /// Region grows down, like a stack.
++ #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
++ MAP_STACK;
++ /// Pages in this mapping are not retained in the kernel's memory cache.
++ #[cfg(any(target_os = "ios", target_os = "macos"))]
++ MAP_NOCACHE;
++ #[cfg(any(target_os = "ios", target_os = "macos"))]
++ MAP_JIT;
++ }
++}
++
++libc_enum!{
++ /// Usage information for a range of memory to allow for performance optimizations by the kernel.
++ ///
++ /// Used by [`madvise`](./fn.madvise.html).
++ #[repr(i32)]
++ pub enum MmapAdvise {
++ /// No further special treatment. This is the default.
++ MADV_NORMAL,
++ /// Expect random page references.
++ MADV_RANDOM,
++ /// Expect sequential page references.
++ MADV_SEQUENTIAL,
++ /// Expect access in the near future.
++ MADV_WILLNEED,
++ /// Do not expect access in the near future.
++ MADV_DONTNEED,
++ /// Free up a given range of pages and its associated backing store.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ MADV_REMOVE,
++ /// Do not make pages in this range available to the child after a `fork(2)`.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ MADV_DONTFORK,
++ /// Undo the effect of `MADV_DONTFORK`.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ MADV_DOFORK,
++ /// Poison the given pages.
++ ///
++ /// Subsequent references to those pages are treated like hardware memory corruption.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ MADV_HWPOISON,
++ /// Enable Kernel Samepage Merging (KSM) for the given pages.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ MADV_MERGEABLE,
++ /// Undo the effect of `MADV_MERGEABLE`
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ MADV_UNMERGEABLE,
++ /// Preserve the memory of each page but offline the original page.
++ #[cfg(any(target_os = "android",
++ all(target_os = "linux", any(
++ target_arch = "aarch64",
++ target_arch = "arm",
++ target_arch = "ppc",
++ target_arch = "s390x",
++ target_arch = "x86",
++ target_arch = "x86_64",
++ target_arch = "sparc64"))))]
++ MADV_SOFT_OFFLINE,
++ /// Enable Transparent Huge Pages (THP) for pages in the given range.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ MADV_HUGEPAGE,
++ /// Undo the effect of `MADV_HUGEPAGE`.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ MADV_NOHUGEPAGE,
++ /// Exclude the given range from a core dump.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ MADV_DONTDUMP,
++ /// Undo the effect of an earlier `MADV_DONTDUMP`.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ MADV_DODUMP,
++ /// Specify that the application no longer needs the pages in the given range.
++ MADV_FREE,
++ /// Request that the system not flush the current range to disk unless it needs to.
++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
++ MADV_NOSYNC,
++ /// Undoes the effects of `MADV_NOSYNC` for any future pages dirtied within the given range.
++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
++ MADV_AUTOSYNC,
++ /// Region is not included in a core file.
++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
++ MADV_NOCORE,
++ /// Include region in a core file
++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
++ MADV_CORE,
++ #[cfg(any(target_os = "freebsd"))]
++ MADV_PROTECT,
++ /// Invalidate the hardware page table for the given region.
++ #[cfg(target_os = "dragonfly")]
++ MADV_INVAL,
++ /// Set the offset of the page directory page to `value` for the virtual page table.
++ #[cfg(target_os = "dragonfly")]
++ MADV_SETMAP,
++ /// Indicates that the application will not need the data in the given range.
++ #[cfg(any(target_os = "ios", target_os = "macos"))]
++ MADV_ZERO_WIRED_PAGES,
++ #[cfg(any(target_os = "ios", target_os = "macos"))]
++ MADV_FREE_REUSABLE,
++ #[cfg(any(target_os = "ios", target_os = "macos"))]
++ MADV_FREE_REUSE,
++ #[cfg(any(target_os = "ios", target_os = "macos"))]
++ MADV_CAN_REUSE,
++ }
++}
++
++libc_bitflags!{
++ /// Configuration flags for `msync`.
++ pub struct MsFlags: c_int {
++ /// Schedule an update but return immediately.
++ MS_ASYNC;
++ /// Invalidate all cached data.
++ MS_INVALIDATE;
++ /// Invalidate pages, but leave them mapped.
++ #[cfg(any(target_os = "ios", target_os = "macos"))]
++ MS_KILLPAGES;
++ /// Deactivate pages, but leave them mapped.
++ #[cfg(any(target_os = "ios", target_os = "macos"))]
++ MS_DEACTIVATE;
++ /// Perform an update and wait for it to complete.
++ MS_SYNC;
++ }
++}
++
++libc_bitflags!{
++ /// Flags for `mlockall`.
++ pub struct MlockAllFlags: c_int {
++ /// Lock pages that are currently mapped into the address space of the process.
++ MCL_CURRENT;
++ /// Lock pages which will become mapped into the address space of the process in the future.
++ MCL_FUTURE;
++ }
++}
++
++/// Locks all memory pages that contain part of the address range with `length` bytes starting at
++/// `addr`. Locked pages never move to the swap area.
++pub unsafe fn mlock(addr: *const c_void, length: size_t) -> Result<()> {
++ Errno::result(libc::mlock(addr, length)).map(drop)
++}
++
++/// Unlocks all memory pages that contain part of the address range with `length` bytes starting at
++/// `addr`.
++pub unsafe fn munlock(addr: *const c_void, length: size_t) -> Result<()> {
++ Errno::result(libc::munlock(addr, length)).map(drop)
++}
++
++/// Locks all memory pages mapped into this process' address space. Locked pages never move to the
++/// swap area.
++pub fn mlockall(flags: MlockAllFlags) -> Result<()> {
++ unsafe { Errno::result(libc::mlockall(flags.bits())) }.map(drop)
++}
++
++/// Unlocks all memory pages mapped into this process' address space.
++pub fn munlockall() -> Result<()> {
++ unsafe { Errno::result(libc::munlockall()) }.map(drop)
++}
++
++/// Calls to mmap are inherently unsafe, so they must be made in an unsafe block. Typically
++/// a higher-level abstraction will hide the unsafe interactions with the mmap'd region.
++pub unsafe fn mmap(addr: *mut c_void, length: size_t, prot: ProtFlags, flags: MapFlags, fd: RawFd, offset: off_t) -> Result<*mut c_void> {
++ let ret = libc::mmap(addr, length, prot.bits(), flags.bits(), fd, offset);
++
++ if ret == libc::MAP_FAILED {
++ Err(Error::Sys(Errno::last()))
++ } else {
++ Ok(ret)
++ }
++}
++
++pub unsafe fn munmap(addr: *mut c_void, len: size_t) -> Result<()> {
++ Errno::result(libc::munmap(addr, len)).map(drop)
++}
++
++pub unsafe fn madvise(addr: *mut c_void, length: size_t, advise: MmapAdvise) -> Result<()> {
++ Errno::result(libc::madvise(addr, length, advise as i32)).map(drop)
++}
++
++/// Set protection of memory mapping.
++///
++/// See [`mprotect(3)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mprotect.html) for
++/// details.
++///
++/// # Safety
++///
++/// Calls to `mprotect` are inherently unsafe, as changes to memory protections can lead to
++/// SIGSEGVs.
++///
++/// ```
++/// # use nix::libc::size_t;
++/// # use nix::sys::mman::{mmap, mprotect, MapFlags, ProtFlags};
++/// # use std::ptr;
++/// const ONE_K: size_t = 1024;
++/// let mut slice: &mut [u8] = unsafe {
++/// let mem = mmap(ptr::null_mut(), ONE_K, ProtFlags::PROT_NONE,
++/// MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE, -1, 0).unwrap();
++/// mprotect(mem, ONE_K, ProtFlags::PROT_READ | ProtFlags::PROT_WRITE).unwrap();
++/// std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
++/// };
++/// assert_eq!(slice[0], 0x00);
++/// slice[0] = 0xFF;
++/// assert_eq!(slice[0], 0xFF);
++/// ```
++pub unsafe fn mprotect(addr: *mut c_void, length: size_t, prot: ProtFlags) -> Result<()> {
++ Errno::result(libc::mprotect(addr, length, prot.bits())).map(drop)
++}
++
++pub unsafe fn msync(addr: *mut c_void, length: size_t, flags: MsFlags) -> Result<()> {
++ Errno::result(libc::msync(addr, length, flags.bits())).map(drop)
++}
++
++#[cfg(not(target_os = "android"))]
++pub fn shm_open<P: ?Sized + NixPath>(name: &P, flag: OFlag, mode: Mode) -> Result<RawFd> {
++ let ret = name.with_nix_path(|cstr| {
++ #[cfg(any(target_os = "macos", target_os = "ios"))]
++ unsafe {
++ libc::shm_open(cstr.as_ptr(), flag.bits(), mode.bits() as libc::c_uint)
++ }
++ #[cfg(not(any(target_os = "macos", target_os = "ios")))]
++ unsafe {
++ libc::shm_open(cstr.as_ptr(), flag.bits(), mode.bits() as libc::mode_t)
++ }
++ })?;
++
++ Errno::result(ret)
++}
++
++#[cfg(not(target_os = "android"))]
++pub fn shm_unlink<P: ?Sized + NixPath>(name: &P) -> Result<()> {
++ let ret = name.with_nix_path(|cstr| {
++ unsafe { libc::shm_unlink(cstr.as_ptr()) }
++ })?;
++
++ Errno::result(ret).map(drop)
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/mod.rs b/third_party/rust/nix-0.15.0/src/sys/mod.rs
+new file mode 100644
+index 0000000000000..d3c2f92bbaaea
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/mod.rs
+@@ -0,0 +1,100 @@
++#[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "ios",
++ target_os = "linux",
++ target_os = "macos",
++ target_os = "netbsd"))]
++pub mod aio;
++
++#[cfg(any(target_os = "android", target_os = "linux"))]
++pub mod epoll;
++
++#[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "ios",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd"))]
++pub mod event;
++
++#[cfg(target_os = "linux")]
++pub mod eventfd;
++
++#[cfg(any(target_os = "android",
++ target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "ios",
++ target_os = "linux",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd"))]
++#[macro_use]
++pub mod ioctl;
++
++#[cfg(target_os = "linux")]
++pub mod memfd;
++
++pub mod mman;
++
++pub mod pthread;
++
++#[cfg(any(target_os = "android",
++ target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "linux",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd"))]
++pub mod ptrace;
++
++#[cfg(target_os = "linux")]
++pub mod quota;
++
++#[cfg(any(target_os = "linux"))]
++pub mod reboot;
++
++pub mod select;
++
++#[cfg(any(target_os = "android",
++ target_os = "freebsd",
++ target_os = "ios",
++ target_os = "linux",
++ target_os = "macos"))]
++pub mod sendfile;
++
++pub mod signal;
++
++#[cfg(any(target_os = "android", target_os = "linux"))]
++pub mod signalfd;
++
++pub mod socket;
++
++pub mod stat;
++
++#[cfg(any(target_os = "android",
++ target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "ios",
++ target_os = "linux",
++ target_os = "macos",
++ target_os = "openbsd"
++))]
++pub mod statfs;
++
++pub mod statvfs;
++
++#[cfg(any(target_os = "android", target_os = "linux"))]
++pub mod sysinfo;
++
++pub mod termios;
++
++pub mod time;
++
++pub mod uio;
++
++pub mod utsname;
++
++pub mod wait;
++
++#[cfg(any(target_os = "android", target_os = "linux"))]
++pub mod inotify;
+diff --git a/third_party/rust/nix-0.15.0/src/sys/pthread.rs b/third_party/rust/nix-0.15.0/src/sys/pthread.rs
+new file mode 100644
+index 0000000000000..a4d98250f2b8b
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/pthread.rs
+@@ -0,0 +1,13 @@
++use libc::{self, pthread_t};
++
++pub type Pthread = pthread_t;
++
++/// Obtain ID of the calling thread (see
++/// [`pthread_self(3)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_self.html)
++///
++/// The thread ID returned by `pthread_self()` is not the same thing as
++/// the kernel thread ID returned by a call to `gettid(2)`.
++#[inline]
++pub fn pthread_self() -> Pthread {
++ unsafe { libc::pthread_self() }
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/ptrace/bsd.rs b/third_party/rust/nix-0.15.0/src/sys/ptrace/bsd.rs
+new file mode 100644
+index 0000000000000..7797d10647ef4
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/ptrace/bsd.rs
+@@ -0,0 +1,170 @@
++use errno::Errno;
++use libc::{self, c_int};
++use std::ptr;
++use sys::signal::Signal;
++use unistd::Pid;
++use Result;
++
++pub type RequestType = c_int;
++
++cfg_if! {
++ if #[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "macos",
++ target_os = "openbsd"))] {
++ #[doc(hidden)]
++ pub type AddressType = *mut ::libc::c_char;
++ } else {
++ #[doc(hidden)]
++ pub type AddressType = *mut ::libc::c_void;
++ }
++}
++
++libc_enum! {
++ #[repr(i32)]
++ /// Ptrace Request enum defining the action to be taken.
++ pub enum Request {
++ PT_TRACE_ME,
++ PT_READ_I,
++ PT_READ_D,
++ #[cfg(target_os = "macos")]
++ PT_READ_U,
++ PT_WRITE_I,
++ PT_WRITE_D,
++ #[cfg(target_os = "macos")]
++ PT_WRITE_U,
++ PT_CONTINUE,
++ PT_KILL,
++ #[cfg(any(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "macos"),
++ all(target_os = "openbsd", target_arch = "x86_64"),
++ all(target_os = "netbsd", any(target_arch = "x86_64",
++ target_arch = "powerpc"))))]
++ PT_STEP,
++ PT_ATTACH,
++ PT_DETACH,
++ #[cfg(target_os = "macos")]
++ PT_SIGEXC,
++ #[cfg(target_os = "macos")]
++ PT_THUPDATE,
++ #[cfg(target_os = "macos")]
++ PT_ATTACHEXC
++ }
++}
++
++unsafe fn ptrace_other(
++ request: Request,
++ pid: Pid,
++ addr: AddressType,
++ data: c_int,
++) -> Result<c_int> {
++ Errno::result(libc::ptrace(
++ request as RequestType,
++ libc::pid_t::from(pid),
++ addr,
++ data,
++ )).map(|_| 0)
++}
++
++/// Sets the process as traceable, as with `ptrace(PT_TRACEME, ...)`
++///
++/// Indicates that this process is to be traced by its parent.
++/// This is the only ptrace request to be issued by the tracee.
++pub fn traceme() -> Result<()> {
++ unsafe { ptrace_other(Request::PT_TRACE_ME, Pid::from_raw(0), ptr::null_mut(), 0).map(drop) }
++}
++
++/// Attach to a running process, as with `ptrace(PT_ATTACH, ...)`
++///
++/// Attaches to the process specified in pid, making it a tracee of the calling process.
++pub fn attach(pid: Pid) -> Result<()> {
++ unsafe { ptrace_other(Request::PT_ATTACH, pid, ptr::null_mut(), 0).map(drop) }
++}
++
++/// Detaches the current running process, as with `ptrace(PT_DETACH, ...)`
++///
++/// Detaches from the process specified in pid allowing it to run freely
++pub fn detach(pid: Pid) -> Result<()> {
++ unsafe { ptrace_other(Request::PT_DETACH, pid, ptr::null_mut(), 0).map(drop) }
++}
++
++/// Restart the stopped tracee process, as with `ptrace(PTRACE_CONT, ...)`
++///
++/// Continues the execution of the process with PID `pid`, optionally
++/// delivering a signal specified by `sig`.
++pub fn cont<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
++ let data = match sig.into() {
++ Some(s) => s as c_int,
++ None => 0,
++ };
++ unsafe {
++ // Ignore the useless return value
++ ptrace_other(Request::PT_CONTINUE, pid, 1 as AddressType, data).map(drop)
++ }
++}
++
++/// Issues a kill request as with `ptrace(PT_KILL, ...)`
++///
++/// This request is equivalent to `ptrace(PT_CONTINUE, ..., SIGKILL);`
++pub fn kill(pid: Pid) -> Result<()> {
++ unsafe {
++ ptrace_other(Request::PT_KILL, pid, 0 as AddressType, 0).map(drop)
++ }
++}
++
++/// Move the stopped tracee process forward by a single step as with
++/// `ptrace(PT_STEP, ...)`
++///
++/// Advances the execution of the process with PID `pid` by a single step optionally delivering a
++/// signal specified by `sig`.
++///
++/// # Example
++/// ```rust
++/// extern crate nix;
++/// use nix::sys::ptrace::step;
++/// use nix::unistd::Pid;
++/// use nix::sys::signal::Signal;
++/// use nix::sys::wait::*;
++/// fn main() {
++/// // If a process changes state to the stopped state because of a SIGUSR1
++/// // signal, this will step the process forward and forward the user
++/// // signal to the stopped process
++/// match waitpid(Pid::from_raw(-1), None) {
++/// Ok(WaitStatus::Stopped(pid, Signal::SIGUSR1)) => {
++/// let _ = step(pid, Signal::SIGUSR1);
++/// }
++/// _ => {},
++/// }
++/// }
++/// ```
++#[cfg(
++ any(
++ any(target_os = "dragonfly", target_os = "freebsd", target_os = "macos"),
++ all(target_os = "openbsd", target_arch = "x86_64"),
++ all(target_os = "netbsd",
++ any(target_arch = "x86_64", target_arch = "powerpc")
++ )
++ )
++)]
++pub fn step<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
++ let data = match sig.into() {
++ Some(s) => s as c_int,
++ None => 0,
++ };
++ unsafe { ptrace_other(Request::PT_STEP, pid, ptr::null_mut(), data).map(drop) }
++}
++
++/// Reads a word from a processes memory at the given address
++pub fn read(pid: Pid, addr: AddressType) -> Result<c_int> {
++ unsafe {
++ // Traditionally there was a difference between reading data or
++ // instruction memory but not in modern systems.
++ ptrace_other(Request::PT_READ_D, pid, addr, 0)
++ }
++}
++
++/// Writes a word into the processes memory at the given address
++pub fn write(pid: Pid, addr: AddressType, data: c_int) -> Result<()> {
++ unsafe { ptrace_other(Request::PT_WRITE_D, pid, addr, data).map(drop) }
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/ptrace/linux.rs b/third_party/rust/nix-0.15.0/src/sys/ptrace/linux.rs
+new file mode 100644
+index 0000000000000..df15e66527562
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/ptrace/linux.rs
+@@ -0,0 +1,402 @@
++//! For detailed description of the ptrace requests, consult `man ptrace`.
++
++use std::{mem, ptr};
++use {Error, Result};
++use errno::Errno;
++use libc::{self, c_void, c_long, siginfo_t};
++use ::unistd::Pid;
++use sys::signal::Signal;
++
++pub type AddressType = *mut ::libc::c_void;
++
++#[cfg(all(target_os = "linux",
++ any(target_arch = "x86_64",
++ target_arch = "x86"),
++ target_env = "gnu"))]
++use libc::user_regs_struct;
++
++cfg_if! {
++ if #[cfg(any(all(target_os = "linux", target_arch = "s390x"),
++ all(target_os = "linux", target_env = "gnu")))] {
++ #[doc(hidden)]
++ pub type RequestType = ::libc::c_uint;
++ } else {
++ #[doc(hidden)]
++ pub type RequestType = ::libc::c_int;
++ }
++}
++
++libc_enum!{
++ #[cfg_attr(not(any(target_env = "musl", target_os = "android")), repr(u32))]
++ #[cfg_attr(any(target_env = "musl", target_os = "android"), repr(i32))]
++ /// Ptrace Request enum defining the action to be taken.
++ pub enum Request {
++ PTRACE_TRACEME,
++ PTRACE_PEEKTEXT,
++ PTRACE_PEEKDATA,
++ PTRACE_PEEKUSER,
++ PTRACE_POKETEXT,
++ PTRACE_POKEDATA,
++ PTRACE_POKEUSER,
++ PTRACE_CONT,
++ PTRACE_KILL,
++ PTRACE_SINGLESTEP,
++ #[cfg(any(all(target_os = "android", target_pointer_width = "32"),
++ all(target_os = "linux", any(target_env = "musl",
++ target_arch = "mips",
++ target_arch = "mips64",
++ target_arch = "x86_64",
++ target_pointer_width = "32"))))]
++ PTRACE_GETREGS,
++ #[cfg(any(all(target_os = "android", target_pointer_width = "32"),
++ all(target_os = "linux", any(target_env = "musl",
++ target_arch = "mips",
++ target_arch = "mips64",
++ target_arch = "x86_64",
++ target_pointer_width = "32"))))]
++ PTRACE_SETREGS,
++ #[cfg(any(all(target_os = "android", target_pointer_width = "32"),
++ all(target_os = "linux", any(target_env = "musl",
++ target_arch = "mips",
++ target_arch = "mips64",
++ target_arch = "x86_64",
++ target_pointer_width = "32"))))]
++ PTRACE_GETFPREGS,
++ #[cfg(any(all(target_os = "android", target_pointer_width = "32"),
++ all(target_os = "linux", any(target_env = "musl",
++ target_arch = "mips",
++ target_arch = "mips64",
++ target_arch = "x86_64",
++ target_pointer_width = "32"))))]
++ PTRACE_SETFPREGS,
++ PTRACE_ATTACH,
++ PTRACE_DETACH,
++ #[cfg(all(target_os = "linux", any(target_env = "musl",
++ target_arch = "mips",
++ target_arch = "mips64",
++ target_arch = "x86",
++ target_arch = "x86_64")))]
++ PTRACE_GETFPXREGS,
++ #[cfg(all(target_os = "linux", any(target_env = "musl",
++ target_arch = "mips",
++ target_arch = "mips64",
++ target_arch = "x86",
++ target_arch = "x86_64")))]
++ PTRACE_SETFPXREGS,
++ PTRACE_SYSCALL,
++ PTRACE_SETOPTIONS,
++ PTRACE_GETEVENTMSG,
++ PTRACE_GETSIGINFO,
++ PTRACE_SETSIGINFO,
++ #[cfg(all(target_os = "linux", not(any(target_arch = "mips",
++ target_arch = "mips64"))))]
++ PTRACE_GETREGSET,
++ #[cfg(all(target_os = "linux", not(any(target_arch = "mips",
++ target_arch = "mips64"))))]
++ PTRACE_SETREGSET,
++ #[cfg(all(target_os = "linux", not(any(target_arch = "mips",
++ target_arch = "mips64"))))]
++ PTRACE_SEIZE,
++ #[cfg(all(target_os = "linux", not(any(target_arch = "mips",
++ target_arch = "mips64"))))]
++ PTRACE_INTERRUPT,
++ #[cfg(all(target_os = "linux", not(any(target_arch = "mips",
++ target_arch = "mips64"))))]
++ PTRACE_LISTEN,
++ #[cfg(all(target_os = "linux", not(any(target_arch = "mips",
++ target_arch = "mips64"))))]
++ PTRACE_PEEKSIGINFO,
++ }
++}
++
++libc_enum!{
++ #[repr(i32)]
++ /// Using the ptrace options the tracer can configure the tracee to stop
++ /// at certain events. This enum is used to define those events as defined
++ /// in `man ptrace`.
++ pub enum Event {
++ /// Event that stops before a return from fork or clone.
++ PTRACE_EVENT_FORK,
++ /// Event that stops before a return from vfork or clone.
++ PTRACE_EVENT_VFORK,
++ /// Event that stops before a return from clone.
++ PTRACE_EVENT_CLONE,
++ /// Event that stops before a return from execve.
++ PTRACE_EVENT_EXEC,
++ /// Event for a return from vfork.
++ PTRACE_EVENT_VFORK_DONE,
++ /// Event for a stop before an exit. Unlike the waitpid Exit status program.
++ /// registers can still be examined
++ PTRACE_EVENT_EXIT,
++ /// STop triggered by a seccomp rule on a tracee.
++ PTRACE_EVENT_SECCOMP,
++ // PTRACE_EVENT_STOP not provided by libc because it's defined in glibc 2.26
++ }
++}
++
++libc_bitflags! {
++ /// Ptrace options used in conjunction with the PTRACE_SETOPTIONS request.
++ /// See `man ptrace` for more details.
++ pub struct Options: libc::c_int {
++ /// When delivering system call traps set a bit to allow tracer to
++ /// distinguish between normal stops or syscall stops. May not work on
++ /// all systems.
++ PTRACE_O_TRACESYSGOOD;
++ /// Stop tracee at next fork and start tracing the forked process.
++ PTRACE_O_TRACEFORK;
++ /// Stop tracee at next vfork call and trace the vforked process.
++ PTRACE_O_TRACEVFORK;
++ /// Stop tracee at next clone call and trace the cloned process.
++ PTRACE_O_TRACECLONE;
++ /// Stop tracee at next execve call.
++ PTRACE_O_TRACEEXEC;
++ /// Stop tracee at vfork completion.
++ PTRACE_O_TRACEVFORKDONE;
++ /// Stop tracee at next exit call. Stops before exit commences allowing
++ /// tracer to see location of exit and register states.
++ PTRACE_O_TRACEEXIT;
++ /// Stop tracee when a SECCOMP_RET_TRACE rule is triggered. See `man seccomp` for more
++ /// details.
++ PTRACE_O_TRACESECCOMP;
++ /// Send a SIGKILL to the tracee if the tracer exits. This is useful
++ /// for ptrace jailers to prevent tracees from escaping their control.
++ #[cfg(any(target_os = "android", target_os = "linux"))]
++ PTRACE_O_EXITKILL;
++ }
++}
++
++/// Performs a ptrace request. If the request in question is provided by a specialised function
++/// this function will return an unsupported operation error.
++#[deprecated(
++ since="0.10.0",
++ note="usages of `ptrace()` should be replaced with the specialized helper functions instead"
++)]
++pub unsafe fn ptrace(request: Request, pid: Pid, addr: AddressType, data: *mut c_void) -> Result<c_long> {
++ use self::Request::*;
++ match request {
++ PTRACE_PEEKTEXT | PTRACE_PEEKDATA | PTRACE_GETSIGINFO |
++ PTRACE_GETEVENTMSG | PTRACE_SETSIGINFO | PTRACE_SETOPTIONS |
++ PTRACE_POKETEXT | PTRACE_POKEDATA | PTRACE_KILL => Err(Error::UnsupportedOperation),
++ _ => ptrace_other(request, pid, addr, data)
++ }
++}
++
++fn ptrace_peek(request: Request, pid: Pid, addr: AddressType, data: *mut c_void) -> Result<c_long> {
++ let ret = unsafe {
++ Errno::clear();
++ libc::ptrace(request as RequestType, libc::pid_t::from(pid), addr, data)
++ };
++ match Errno::result(ret) {
++ Ok(..) | Err(Error::Sys(Errno::UnknownErrno)) => Ok(ret),
++ err @ Err(..) => err,
++ }
++}
++
++/// Get user registers, as with `ptrace(PTRACE_GETREGS, ...)`
++#[cfg(all(target_os = "linux",
++ any(target_arch = "x86_64",
++ target_arch = "x86"),
++ target_env = "gnu"))]
++pub fn getregs(pid: Pid) -> Result<user_regs_struct> {
++ ptrace_get_data::<user_regs_struct>(Request::PTRACE_GETREGS, pid)
++}
++
++/// Set user registers, as with `ptrace(PTRACE_SETREGS, ...)`
++#[cfg(all(target_os = "linux",
++ any(target_arch = "x86_64",
++ target_arch = "x86"),
++ target_env = "gnu"))]
++pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> {
++ let res = unsafe {
++ libc::ptrace(Request::PTRACE_SETREGS as RequestType,
++ libc::pid_t::from(pid),
++ ptr::null_mut::<c_void>(),
++ &regs as *const _ as *const c_void)
++ };
++ Errno::result(res).map(drop)
++}
++
++/// Function for ptrace requests that return values from the data field.
++/// Some ptrace get requests populate structs or larger elements than `c_long`
++/// and therefore use the data field to return values. This function handles these
++/// requests.
++fn ptrace_get_data<T>(request: Request, pid: Pid) -> Result<T> {
++ // Creates an uninitialized pointer to store result in
++ let data: T = unsafe { mem::uninitialized() };
++ let res = unsafe {
++ libc::ptrace(request as RequestType,
++ libc::pid_t::from(pid),
++ ptr::null_mut::<T>(),
++ &data as *const _ as *const c_void)
++ };
++ Errno::result(res)?;
++ Ok(data)
++}
++
++unsafe fn ptrace_other(request: Request, pid: Pid, addr: AddressType, data: *mut c_void) -> Result<c_long> {
++ Errno::result(libc::ptrace(request as RequestType, libc::pid_t::from(pid), addr, data)).map(|_| 0)
++}
++
++/// Set options, as with `ptrace(PTRACE_SETOPTIONS,...)`.
++pub fn setoptions(pid: Pid, options: Options) -> Result<()> {
++ let res = unsafe {
++ libc::ptrace(Request::PTRACE_SETOPTIONS as RequestType,
++ libc::pid_t::from(pid),
++ ptr::null_mut::<c_void>(),
++ options.bits() as *mut c_void)
++ };
++ Errno::result(res).map(drop)
++}
++
++/// Gets a ptrace event as described by `ptrace(PTRACE_GETEVENTMSG,...)`
++pub fn getevent(pid: Pid) -> Result<c_long> {
++ ptrace_get_data::<c_long>(Request::PTRACE_GETEVENTMSG, pid)
++}
++
++/// Get siginfo as with `ptrace(PTRACE_GETSIGINFO,...)`
++pub fn getsiginfo(pid: Pid) -> Result<siginfo_t> {
++ ptrace_get_data::<siginfo_t>(Request::PTRACE_GETSIGINFO, pid)
++}
++
++/// Set siginfo as with `ptrace(PTRACE_SETSIGINFO,...)`
++pub fn setsiginfo(pid: Pid, sig: &siginfo_t) -> Result<()> {
++ let ret = unsafe{
++ Errno::clear();
++ libc::ptrace(Request::PTRACE_SETSIGINFO as RequestType,
++ libc::pid_t::from(pid),
++ ptr::null_mut::<c_void>(),
++ sig as *const _ as *const c_void)
++ };
++ match Errno::result(ret) {
++ Ok(_) => Ok(()),
++ Err(e) => Err(e),
++ }
++}
++
++/// Sets the process as traceable, as with `ptrace(PTRACE_TRACEME, ...)`
++///
++/// Indicates that this process is to be traced by its parent.
++/// This is the only ptrace request to be issued by the tracee.
++pub fn traceme() -> Result<()> {
++ unsafe {
++ ptrace_other(
++ Request::PTRACE_TRACEME,
++ Pid::from_raw(0),
++ ptr::null_mut(),
++ ptr::null_mut(),
++ ).map(drop) // ignore the useless return value
++ }
++}
++
++/// Ask for next syscall, as with `ptrace(PTRACE_SYSCALL, ...)`
++///
++/// Arranges for the tracee to be stopped at the next entry to or exit from a system call.
++pub fn syscall(pid: Pid) -> Result<()> {
++ unsafe {
++ ptrace_other(
++ Request::PTRACE_SYSCALL,
++ pid,
++ ptr::null_mut(),
++ ptr::null_mut(),
++ ).map(drop) // ignore the useless return value
++ }
++}
++
++/// Attach to a running process, as with `ptrace(PTRACE_ATTACH, ...)`
++///
++/// Attaches to the process specified in pid, making it a tracee of the calling process.
++pub fn attach(pid: Pid) -> Result<()> {
++ unsafe {
++ ptrace_other(
++ Request::PTRACE_ATTACH,
++ pid,
++ ptr::null_mut(),
++ ptr::null_mut(),
++ ).map(drop) // ignore the useless return value
++ }
++}
++
++/// Detaches the current running process, as with `ptrace(PTRACE_DETACH, ...)`
++///
++/// Detaches from the process specified in pid allowing it to run freely
++pub fn detach(pid: Pid) -> Result<()> {
++ unsafe {
++ ptrace_other(
++ Request::PTRACE_DETACH,
++ pid,
++ ptr::null_mut(),
++ ptr::null_mut()
++ ).map(drop)
++ }
++}
++
++/// Restart the stopped tracee process, as with `ptrace(PTRACE_CONT, ...)`
++///
++/// Continues the execution of the process with PID `pid`, optionally
++/// delivering a signal specified by `sig`.
++pub fn cont<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
++ let data = match sig.into() {
++ Some(s) => s as i32 as *mut c_void,
++ None => ptr::null_mut(),
++ };
++ unsafe {
++ ptrace_other(Request::PTRACE_CONT, pid, ptr::null_mut(), data).map(drop) // ignore the useless return value
++ }
++}
++
++/// Issues a kill request as with `ptrace(PTRACE_KILL, ...)`
++///
++/// This request is equivalent to `ptrace(PTRACE_CONT, ..., SIGKILL);`
++pub fn kill(pid: Pid) -> Result<()> {
++ unsafe {
++ ptrace_other(Request::PTRACE_KILL, pid, ptr::null_mut(), ptr::null_mut()).map(drop)
++ }
++}
++
++/// Move the stopped tracee process forward by a single step as with
++/// `ptrace(PTRACE_SINGLESTEP, ...)`
++///
++/// Advances the execution of the process with PID `pid` by a single step optionally delivering a
++/// signal specified by `sig`.
++///
++/// # Example
++/// ```rust
++/// extern crate nix;
++/// use nix::sys::ptrace::step;
++/// use nix::unistd::Pid;
++/// use nix::sys::signal::Signal;
++/// use nix::sys::wait::*;
++/// fn main() {
++/// // If a process changes state to the stopped state because of a SIGUSR1
++/// // signal, this will step the process forward and forward the user
++/// // signal to the stopped process
++/// match waitpid(Pid::from_raw(-1), None) {
++/// Ok(WaitStatus::Stopped(pid, Signal::SIGUSR1)) => {
++/// let _ = step(pid, Signal::SIGUSR1);
++/// }
++/// _ => {},
++/// }
++/// }
++/// ```
++pub fn step<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
++ let data = match sig.into() {
++ Some(s) => s as i32 as *mut c_void,
++ None => ptr::null_mut(),
++ };
++ unsafe {
++ ptrace_other(Request::PTRACE_SINGLESTEP, pid, ptr::null_mut(), data).map(drop)
++ }
++}
++
++
++/// Reads a word from a processes memory at the given address
++pub fn read(pid: Pid, addr: AddressType) -> Result<c_long> {
++ ptrace_peek(Request::PTRACE_PEEKDATA, pid, addr, ptr::null_mut())
++}
++
++/// Writes a word into the processes memory at the given address
++pub fn write(pid: Pid, addr: AddressType, data: *mut c_void) -> Result<()> {
++ unsafe {
++ ptrace_other(Request::PTRACE_POKEDATA, pid, addr, data).map(drop)
++ }
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/ptrace/mod.rs b/third_party/rust/nix-0.15.0/src/sys/ptrace/mod.rs
+new file mode 100644
+index 0000000000000..782c30409bc12
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/ptrace/mod.rs
+@@ -0,0 +1,22 @@
++///! Provides helpers for making ptrace system calls
++
++#[cfg(any(target_os = "android", target_os = "linux"))]
++mod linux;
++
++#[cfg(any(target_os = "android", target_os = "linux"))]
++pub use self::linux::*;
++
++#[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd"))]
++mod bsd;
++
++#[cfg(any(target_os = "dragonfly",
++ target_os = "freebsd",
++ target_os = "macos",
++ target_os = "netbsd",
++ target_os = "openbsd"
++ ))]
++pub use self::bsd::*;
+diff --git a/third_party/rust/nix-0.15.0/src/sys/quota.rs b/third_party/rust/nix-0.15.0/src/sys/quota.rs
+new file mode 100644
+index 0000000000000..8946fca2213c8
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/quota.rs
+@@ -0,0 +1,273 @@
++//! Set and configure disk quotas for users, groups, or projects.
++//!
++//! # Examples
++//!
++//! Enabling and setting a quota:
++//!
++//! ```rust,no_run
++//! # use nix::sys::quota::{Dqblk, quotactl_on, quotactl_set, QuotaFmt, QuotaType, QuotaValidFlags};
++//! quotactl_on(QuotaType::USRQUOTA, "/dev/sda1", QuotaFmt::QFMT_VFS_V1, "aquota.user");
++//! let mut dqblk: Dqblk = Default::default();
++//! dqblk.set_blocks_hard_limit(10000);
++//! dqblk.set_blocks_soft_limit(8000);
++//! quotactl_set(QuotaType::USRQUOTA, "/dev/sda1", 50, &dqblk, QuotaValidFlags::QIF_BLIMITS);
++//! ```
++use std::default::Default;
++use std::{mem, ptr};
++use libc::{self, c_int, c_char};
++use {Result, NixPath};
++use errno::Errno;
++
++struct QuotaCmd(QuotaSubCmd, QuotaType);
++
++impl QuotaCmd {
++ fn as_int(&self) -> c_int {
++ unsafe { libc::QCMD(self.0 as i32, self.1 as i32) }
++ }
++}
++
++// linux quota version >= 2
++libc_enum!{
++ #[repr(i32)]
++ enum QuotaSubCmd {
++ Q_SYNC,
++ Q_QUOTAON,
++ Q_QUOTAOFF,
++ Q_GETQUOTA,
++ Q_SETQUOTA,
++ }
++}
++
++libc_enum!{
++ /// The scope of the quota.
++ #[repr(i32)]
++ pub enum QuotaType {
++ /// Specify a user quota
++ USRQUOTA,
++ /// Specify a group quota
++ GRPQUOTA,
++ }
++}
++
++libc_enum!{
++ /// The type of quota format to use.
++ #[repr(i32)]
++ pub enum QuotaFmt {
++ /// Use the original quota format.
++ QFMT_VFS_OLD,
++ /// Use the standard VFS v0 quota format.
++ ///
++ /// Handles 32-bit UIDs/GIDs and quota limits up to 2<sup>32</sup> bytes/2<sup>32</sup> inodes.
++ QFMT_VFS_V0,
++ /// Use the VFS v1 quota format.
++ ///
++ /// Handles 32-bit UIDs/GIDs and quota limits of 2<sup>64</sup> bytes/2<sup>64</sup> inodes.
++ QFMT_VFS_V1,
++ }
++}
++
++libc_bitflags!(
++ /// Indicates the quota fields that are valid to read from.
++ #[derive(Default)]
++ pub struct QuotaValidFlags: u32 {
++ /// The block hard & soft limit fields.
++ QIF_BLIMITS;
++ /// The current space field.
++ QIF_SPACE;
++ /// The inode hard & soft limit fields.
++ QIF_ILIMITS;
++ /// The current inodes field.
++ QIF_INODES;
++ /// The disk use time limit field.
++ QIF_BTIME;
++ /// The file quote time limit field.
++ QIF_ITIME;
++ /// All block & inode limits.
++ QIF_LIMITS;
++ /// The space & inodes usage fields.
++ QIF_USAGE;
++ /// The time limit fields.
++ QIF_TIMES;
++ /// All fields.
++ QIF_ALL;
++ }
++);
++
++/// Wrapper type for `if_dqblk`
++// FIXME: Change to repr(transparent)
++#[repr(C)]
++#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
++pub struct Dqblk(libc::dqblk);
++
++impl Default for Dqblk {
++ fn default() -> Dqblk {
++ Dqblk(libc::dqblk {
++ dqb_bhardlimit: 0,
++ dqb_bsoftlimit: 0,
++ dqb_curspace: 0,
++ dqb_ihardlimit: 0,
++ dqb_isoftlimit: 0,
++ dqb_curinodes: 0,
++ dqb_btime: 0,
++ dqb_itime: 0,
++ dqb_valid: 0,
++ })
++ }
++}
++
++impl Dqblk {
++ /// The absolute limit on disk quota blocks allocated.
++ pub fn blocks_hard_limit(&self) -> Option<u64> {
++ let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
++ if valid_fields.contains(QuotaValidFlags::QIF_BLIMITS) {
++ Some(self.0.dqb_bhardlimit)
++ } else {
++ None
++ }
++ }
++
++ /// Set the absolute limit on disk quota blocks allocated.
++ pub fn set_blocks_hard_limit(&mut self, limit: u64) {
++ self.0.dqb_bhardlimit = limit;
++ }
++
++ /// Preferred limit on disk quota blocks
++ pub fn blocks_soft_limit(&self) -> Option<u64> {
++ let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
++ if valid_fields.contains(QuotaValidFlags::QIF_BLIMITS) {
++ Some(self.0.dqb_bsoftlimit)
++ } else {
++ None
++ }
++ }
++
++ /// Set the preferred limit on disk quota blocks allocated.
++ pub fn set_blocks_soft_limit(&mut self, limit: u64) {
++ self.0.dqb_bsoftlimit = limit;
++ }
++
++ /// Current occupied space (bytes).
++ pub fn occupied_space(&self) -> Option<u64> {
++ let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
++ if valid_fields.contains(QuotaValidFlags::QIF_SPACE) {
++ Some(self.0.dqb_curspace)
++ } else {
++ None
++ }
++ }
++
++ /// Maximum number of allocated inodes.
++ pub fn inodes_hard_limit(&self) -> Option<u64> {
++ let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
++ if valid_fields.contains(QuotaValidFlags::QIF_ILIMITS) {
++ Some(self.0.dqb_ihardlimit)
++ } else {
++ None
++ }
++ }
++
++ /// Set the maximum number of allocated inodes.
++ pub fn set_inodes_hard_limit(&mut self, limit: u64) {
++ self.0.dqb_ihardlimit = limit;
++ }
++
++ /// Preferred inode limit
++ pub fn inodes_soft_limit(&self) -> Option<u64> {
++ let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
++ if valid_fields.contains(QuotaValidFlags::QIF_ILIMITS) {
++ Some(self.0.dqb_isoftlimit)
++ } else {
++ None
++ }
++ }
++
++ /// Set the preferred limit of allocated inodes.
++ pub fn set_inodes_soft_limit(&mut self, limit: u64) {
++ self.0.dqb_isoftlimit = limit;
++ }
++
++ /// Current number of allocated inodes.
++ pub fn allocated_inodes(&self) -> Option<u64> {
++ let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
++ if valid_fields.contains(QuotaValidFlags::QIF_INODES) {
++ Some(self.0.dqb_curinodes)
++ } else {
++ None
++ }
++ }
++
++ /// Time limit for excessive disk use.
++ pub fn block_time_limit(&self) -> Option<u64> {
++ let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
++ if valid_fields.contains(QuotaValidFlags::QIF_BTIME) {
++ Some(self.0.dqb_btime)
++ } else {
++ None
++ }
++ }
++
++ /// Set the time limit for excessive disk use.
++ pub fn set_block_time_limit(&mut self, limit: u64) {
++ self.0.dqb_btime = limit;
++ }
++
++ /// Time limit for excessive files.
++ pub fn inode_time_limit(&self) -> Option<u64> {
++ let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
++ if valid_fields.contains(QuotaValidFlags::QIF_ITIME) {
++ Some(self.0.dqb_itime)
++ } else {
++ None
++ }
++ }
++
++ /// Set the time limit for excessive files.
++ pub fn set_inode_time_limit(&mut self, limit: u64) {
++ self.0.dqb_itime = limit;
++ }
++}
++
++fn quotactl<P: ?Sized + NixPath>(cmd: QuotaCmd, special: Option<&P>, id: c_int, addr: *mut c_char) -> Result<()> {
++ unsafe {
++ Errno::clear();
++ let res = match special {
++ Some(dev) => dev.with_nix_path(|path| libc::quotactl(cmd.as_int(), path.as_ptr(), id, addr)),
++ None => Ok(libc::quotactl(cmd.as_int(), ptr::null(), id, addr)),
++ }?;
++
++ Errno::result(res).map(drop)
++ }
++}
++
++/// Turn on disk quotas for a block device.
++pub fn quotactl_on<P: ?Sized + NixPath>(which: QuotaType, special: &P, format: QuotaFmt, quota_file: &P) -> Result<()> {
++ quota_file.with_nix_path(|path| {
++ let mut path_copy = path.to_bytes_with_nul().to_owned();
++ let p: *mut c_char = path_copy.as_mut_ptr() as *mut c_char;
++ quotactl(QuotaCmd(QuotaSubCmd::Q_QUOTAON, which), Some(special), format as c_int, p)
++ })?
++}
++
++/// Disable disk quotas for a block device.
++pub fn quotactl_off<P: ?Sized + NixPath>(which: QuotaType, special: &P) -> Result<()> {
++ quotactl(QuotaCmd(QuotaSubCmd::Q_QUOTAOFF, which), Some(special), 0, ptr::null_mut())
++}
++
++/// Update the on-disk copy of quota usages for a filesystem.
++pub fn quotactl_sync<P: ?Sized + NixPath>(which: QuotaType, special: Option<&P>) -> Result<()> {
++ quotactl(QuotaCmd(QuotaSubCmd::Q_SYNC, which), special, 0, ptr::null_mut())
++}
++
++/// Get disk quota limits and current usage for the given user/group id.
++pub fn quotactl_get<P: ?Sized + NixPath>(which: QuotaType, special: &P, id: c_int) -> Result<Dqblk> {
++ let mut dqblk = unsafe { mem::uninitialized() };
++ quotactl(QuotaCmd(QuotaSubCmd::Q_GETQUOTA, which), Some(special), id, &mut dqblk as *mut _ as *mut c_char)?;
++ dqblk
++}
++
++/// Configure quota values for the specified fields for a given user/group id.
++pub fn quotactl_set<P: ?Sized + NixPath>(which: QuotaType, special: &P, id: c_int, dqblk: &Dqblk, fields: QuotaValidFlags) -> Result<()> {
++ let mut dqblk_copy = *dqblk;
++ dqblk_copy.0.dqb_valid = fields.bits();
++ quotactl(QuotaCmd(QuotaSubCmd::Q_SETQUOTA, which), Some(special), id, &mut dqblk_copy as *mut _ as *mut c_char)
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/reboot.rs b/third_party/rust/nix-0.15.0/src/sys/reboot.rs
+new file mode 100644
+index 0000000000000..bafa8fc11996d
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/reboot.rs
+@@ -0,0 +1,45 @@
++//! Reboot/shutdown or enable/disable Ctrl-Alt-Delete.
++
++use {Error, Result};
++use errno::Errno;
++use libc;
++use void::Void;
++use std::mem::drop;
++
++libc_enum! {
++ /// How exactly should the system be rebooted.
++ ///
++ /// See [`set_cad_enabled()`](fn.set_cad_enabled.html) for
++ /// enabling/disabling Ctrl-Alt-Delete.
++ #[repr(i32)]
++ pub enum RebootMode {
++ RB_HALT_SYSTEM,
++ RB_KEXEC,
++ RB_POWER_OFF,
++ RB_AUTOBOOT,
++ // we do not support Restart2,
++ RB_SW_SUSPEND,
++ }
++}
++
++pub fn reboot(how: RebootMode) -> Result<Void> {
++ unsafe {
++ libc::reboot(how as libc::c_int)
++ };
++ Err(Error::Sys(Errno::last()))
++}
++
++/// Enable or disable the reboot keystroke (Ctrl-Alt-Delete).
++///
++/// Corresponds to calling `reboot(RB_ENABLE_CAD)` or `reboot(RB_DISABLE_CAD)` in C.
++pub fn set_cad_enabled(enable: bool) -> Result<()> {
++ let cmd = if enable {
++ libc::RB_ENABLE_CAD
++ } else {
++ libc::RB_DISABLE_CAD
++ };
++ let res = unsafe {
++ libc::reboot(cmd)
++ };
++ Errno::result(res).map(drop)
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/select.rs b/third_party/rust/nix-0.15.0/src/sys/select.rs
+new file mode 100644
+index 0000000000000..1b518e29f67a6
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/select.rs
+@@ -0,0 +1,334 @@
++use std::mem;
++use std::os::unix::io::RawFd;
++use std::ptr::{null, null_mut};
++use libc::{self, c_int};
++use Result;
++use errno::Errno;
++use sys::signal::SigSet;
++use sys::time::{TimeSpec, TimeVal};
++
++pub use libc::FD_SETSIZE;
++
++// FIXME: Change to repr(transparent) once it's stable
++#[repr(C)]
++#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
++pub struct FdSet(libc::fd_set);
++
++impl FdSet {
++ pub fn new() -> FdSet {
++ let mut fdset = unsafe { mem::uninitialized() };
++ unsafe { libc::FD_ZERO(&mut fdset) };
++ FdSet(fdset)
++ }
++
++ pub fn insert(&mut self, fd: RawFd) {
++ unsafe { libc::FD_SET(fd, &mut self.0) };
++ }
++
++ pub fn remove(&mut self, fd: RawFd) {
++ unsafe { libc::FD_CLR(fd, &mut self.0) };
++ }
++
++ pub fn contains(&mut self, fd: RawFd) -> bool {
++ unsafe { libc::FD_ISSET(fd, &mut self.0) }
++ }
++
++ pub fn clear(&mut self) {
++ unsafe { libc::FD_ZERO(&mut self.0) };
++ }
++
++ /// Finds the highest file descriptor in the set.
++ ///
++ /// Returns `None` if the set is empty.
++ ///
++ /// This can be used to calculate the `nfds` parameter of the [`select`] function.
++ ///
++ /// # Example
++ ///
++ /// ```
++ /// # extern crate nix;
++ /// # use nix::sys::select::FdSet;
++ /// # fn main() {
++ /// let mut set = FdSet::new();
++ /// set.insert(4);
++ /// set.insert(9);
++ /// assert_eq!(set.highest(), Some(9));
++ /// # }
++ /// ```
++ ///
++ /// [`select`]: fn.select.html
++ pub fn highest(&mut self) -> Option<RawFd> {
++ for i in (0..FD_SETSIZE).rev() {
++ let i = i as RawFd;
++ if unsafe { libc::FD_ISSET(i, self as *mut _ as *mut libc::fd_set) } {
++ return Some(i)
++ }
++ }
++
++ None
++ }
++}
++
++/// Monitors file descriptors for readiness
++///
++/// Returns the total number of ready file descriptors in all sets. The sets are changed so that all
++/// file descriptors that are ready for the given operation are set.
++///
++/// When this function returns, `timeout` has an implementation-defined value.
++///
++/// # Parameters
++///
++/// * `nfds`: The highest file descriptor set in any of the passed `FdSet`s, plus 1. If `None`, this
++/// is calculated automatically by calling [`FdSet::highest`] on all descriptor sets and adding 1
++/// to the maximum of that.
++/// * `readfds`: File descriptors to check for being ready to read.
++/// * `writefds`: File descriptors to check for being ready to write.
++/// * `errorfds`: File descriptors to check for pending error conditions.
++/// * `timeout`: Maximum time to wait for descriptors to become ready (`None` to block
++/// indefinitely).
++///
++/// # References
++///
++/// [select(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html)
++///
++/// [`FdSet::highest`]: struct.FdSet.html#method.highest
++pub fn select<'a, N, R, W, E, T>(nfds: N,
++ readfds: R,
++ writefds: W,
++ errorfds: E,
++ timeout: T) -> Result<c_int>
++where
++ N: Into<Option<c_int>>,
++ R: Into<Option<&'a mut FdSet>>,
++ W: Into<Option<&'a mut FdSet>>,
++ E: Into<Option<&'a mut FdSet>>,
++ T: Into<Option<&'a mut TimeVal>>,
++{
++ let mut readfds = readfds.into();
++ let mut writefds = writefds.into();
++ let mut errorfds = errorfds.into();
++ let timeout = timeout.into();
++
++ let nfds = nfds.into().unwrap_or_else(|| {
++ readfds.iter_mut()
++ .chain(writefds.iter_mut())
++ .chain(errorfds.iter_mut())
++ .map(|set| set.highest().unwrap_or(-1))
++ .max()
++ .unwrap_or(-1) + 1
++ });
++
++ let readfds = readfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
++ let writefds = writefds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
++ let errorfds = errorfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
++ let timeout = timeout.map(|tv| tv as *mut _ as *mut libc::timeval)
++ .unwrap_or(null_mut());
++
++ let res = unsafe {
++ libc::select(nfds, readfds, writefds, errorfds, timeout)
++ };
++
++ Errno::result(res)
++}
++
++/// Monitors file descriptors for readiness with an altered signal mask.
++///
++/// Returns the total number of ready file descriptors in all sets. The sets are changed so that all
++/// file descriptors that are ready for the given operation are set.
++///
++/// When this function returns, the original signal mask is restored.
++///
++/// Unlike [`select`](#fn.select), `pselect` does not mutate the `timeout` value.
++///
++/// # Parameters
++///
++/// * `nfds`: The highest file descriptor set in any of the passed `FdSet`s, plus 1. If `None`, this
++/// is calculated automatically by calling [`FdSet::highest`] on all descriptor sets and adding 1
++/// to the maximum of that.
++/// * `readfds`: File descriptors to check for read readiness
++/// * `writefds`: File descriptors to check for write readiness
++/// * `errorfds`: File descriptors to check for pending error conditions.
++/// * `timeout`: Maximum time to wait for descriptors to become ready (`None` to block
++/// indefinitely).
++/// * `sigmask`: Signal mask to activate while waiting for file descriptors to turn
++/// ready (`None` to set no alternative signal mask).
++///
++/// # References
++///
++/// [pselect(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pselect.html)
++///
++/// [The new pselect() system call](https://lwn.net/Articles/176911/)
++///
++/// [`FdSet::highest`]: struct.FdSet.html#method.highest
++pub fn pselect<'a, N, R, W, E, T, S>(nfds: N,
++ readfds: R,
++ writefds: W,
++ errorfds: E,
++ timeout: T,
++ sigmask: S) -> Result<c_int>
++where
++ N: Into<Option<c_int>>,
++ R: Into<Option<&'a mut FdSet>>,
++ W: Into<Option<&'a mut FdSet>>,
++ E: Into<Option<&'a mut FdSet>>,
++ T: Into<Option<&'a TimeSpec>>,
++ S: Into<Option<&'a SigSet>>,
++{
++ let mut readfds = readfds.into();
++ let mut writefds = writefds.into();
++ let mut errorfds = errorfds.into();
++ let sigmask = sigmask.into();
++ let timeout = timeout.into();
++
++ let nfds = nfds.into().unwrap_or_else(|| {
++ readfds.iter_mut()
++ .chain(writefds.iter_mut())
++ .chain(errorfds.iter_mut())
++ .map(|set| set.highest().unwrap_or(-1))
++ .max()
++ .unwrap_or(-1) + 1
++ });
++
++ let readfds = readfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
++ let writefds = writefds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
++ let errorfds = errorfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
++ let timeout = timeout.map(|ts| ts.as_ref() as *const libc::timespec).unwrap_or(null());
++ let sigmask = sigmask.map(|sm| sm.as_ref() as *const libc::sigset_t).unwrap_or(null());
++
++ let res = unsafe {
++ libc::pselect(nfds, readfds, writefds, errorfds, timeout, sigmask)
++ };
++
++ Errno::result(res)
++}
++
++
++#[cfg(test)]
++mod tests {
++ use super::*;
++ use std::os::unix::io::RawFd;
++ use sys::time::{TimeVal, TimeValLike};
++ use unistd::{write, pipe};
++
++ #[test]
++ fn fdset_insert() {
++ let mut fd_set = FdSet::new();
++
++ for i in 0..FD_SETSIZE {
++ assert!(!fd_set.contains(i as RawFd));
++ }
++
++ fd_set.insert(7);
++
++ assert!(fd_set.contains(7));
++ }
++
++ #[test]
++ fn fdset_remove() {
++ let mut fd_set = FdSet::new();
++
++ for i in 0..FD_SETSIZE {
++ assert!(!fd_set.contains(i as RawFd));
++ }
++
++ fd_set.insert(7);
++ fd_set.remove(7);
++
++ for i in 0..FD_SETSIZE {
++ assert!(!fd_set.contains(i as RawFd));
++ }
++ }
++
++ #[test]
++ fn fdset_clear() {
++ let mut fd_set = FdSet::new();
++ fd_set.insert(1);
++ fd_set.insert((FD_SETSIZE / 2) as RawFd);
++ fd_set.insert((FD_SETSIZE - 1) as RawFd);
++
++ fd_set.clear();
++
++ for i in 0..FD_SETSIZE {
++ assert!(!fd_set.contains(i as RawFd));
++ }
++ }
++
++ #[test]
++ fn fdset_highest() {
++ let mut set = FdSet::new();
++ assert_eq!(set.highest(), None);
++ set.insert(0);
++ assert_eq!(set.highest(), Some(0));
++ set.insert(90);
++ assert_eq!(set.highest(), Some(90));
++ set.remove(0);
++ assert_eq!(set.highest(), Some(90));
++ set.remove(90);
++ assert_eq!(set.highest(), None);
++
++ set.insert(4);
++ set.insert(5);
++ set.insert(7);
++ assert_eq!(set.highest(), Some(7));
++ }
++
++ #[test]
++ fn test_select() {
++ let (r1, w1) = pipe().unwrap();
++ write(w1, b"hi!").unwrap();
++ let (r2, _w2) = pipe().unwrap();
++
++ let mut fd_set = FdSet::new();
++ fd_set.insert(r1);
++ fd_set.insert(r2);
++
++ let mut timeout = TimeVal::seconds(10);
++ assert_eq!(1, select(None,
++ &mut fd_set,
++ None,
++ None,
++ &mut timeout).unwrap());
++ assert!(fd_set.contains(r1));
++ assert!(!fd_set.contains(r2));
++ }
++
++ #[test]
++ fn test_select_nfds() {
++ let (r1, w1) = pipe().unwrap();
++ write(w1, b"hi!").unwrap();
++ let (r2, _w2) = pipe().unwrap();
++
++ let mut fd_set = FdSet::new();
++ fd_set.insert(r1);
++ fd_set.insert(r2);
++
++ let mut timeout = TimeVal::seconds(10);
++ assert_eq!(1, select(Some(fd_set.highest().unwrap() + 1),
++ &mut fd_set,
++ None,
++ None,
++ &mut timeout).unwrap());
++ assert!(fd_set.contains(r1));
++ assert!(!fd_set.contains(r2));
++ }
++
++ #[test]
++ fn test_select_nfds2() {
++ let (r1, w1) = pipe().unwrap();
++ write(w1, b"hi!").unwrap();
++ let (r2, _w2) = pipe().unwrap();
++
++ let mut fd_set = FdSet::new();
++ fd_set.insert(r1);
++ fd_set.insert(r2);
++
++ let mut timeout = TimeVal::seconds(10);
++ assert_eq!(1, select(::std::cmp::max(r1, r2) + 1,
++ &mut fd_set,
++ None,
++ None,
++ &mut timeout).unwrap());
++ assert!(fd_set.contains(r1));
++ assert!(!fd_set.contains(r2));
++ }
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/sendfile.rs b/third_party/rust/nix-0.15.0/src/sys/sendfile.rs
+new file mode 100644
+index 0000000000000..a47d8962f73fb
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/sendfile.rs
+@@ -0,0 +1,200 @@
++use std::os::unix::io::RawFd;
++use std::ptr;
++
++use libc::{self, off_t};
++
++use Result;
++use errno::Errno;
++
++/// Copy up to `count` bytes to `out_fd` from `in_fd` starting at `offset`.
++///
++/// Returns a `Result` with the number of bytes written.
++///
++/// If `offset` is `None`, `sendfile` will begin reading at the current offset of `in_fd`and will
++/// update the offset of `in_fd`. If `offset` is `Some`, `sendfile` will begin at the specified
++/// offset and will not update the offset of `in_fd`. Instead, it will mutate `offset` to point to
++/// the byte after the last byte copied.
++///
++/// `in_fd` must support `mmap`-like operations and therefore cannot be a socket.
++///
++/// For more information, see [the sendfile(2) man page.](http://man7.org/linux/man-pages/man2/sendfile.2.html)
++#[cfg(any(target_os = "android", target_os = "linux"))]
++pub fn sendfile(
++ out_fd: RawFd,
++ in_fd: RawFd,
++ offset: Option<&mut off_t>,
++ count: usize,
++) -> Result<usize> {
++ let offset = offset
++ .map(|offset| offset as *mut _)
++ .unwrap_or(ptr::null_mut());
++ let ret = unsafe { libc::sendfile(out_fd, in_fd, offset, count) };
++ Errno::result(ret).map(|r| r as usize)
++}
++
++cfg_if! {
++ if #[cfg(any(target_os = "freebsd",
++ target_os = "ios",
++ target_os = "macos"))] {
++ use sys::uio::IoVec;
++
++ #[derive(Clone, Debug, Eq, Hash, PartialEq)]
++ struct SendfileHeaderTrailer<'a>(
++ libc::sf_hdtr,
++ Option<Vec<IoVec<&'a [u8]>>>,
++ Option<Vec<IoVec<&'a [u8]>>>,
++ );
++
++ impl<'a> SendfileHeaderTrailer<'a> {
++ fn new(
++ headers: Option<&'a [&'a [u8]]>,
++ trailers: Option<&'a [&'a [u8]]>
++ ) -> SendfileHeaderTrailer<'a> {
++ let header_iovecs: Option<Vec<IoVec<&[u8]>>> =
++ headers.map(|s| s.iter().map(|b| IoVec::from_slice(b)).collect());
++ let trailer_iovecs: Option<Vec<IoVec<&[u8]>>> =
++ trailers.map(|s| s.iter().map(|b| IoVec::from_slice(b)).collect());
++ SendfileHeaderTrailer(
++ libc::sf_hdtr {
++ headers: {
++ header_iovecs
++ .as_ref()
++ .map_or(ptr::null(), |v| v.as_ptr()) as *mut libc::iovec
++ },
++ hdr_cnt: header_iovecs.as_ref().map(|v| v.len()).unwrap_or(0) as i32,
++ trailers: {
++ trailer_iovecs
++ .as_ref()
++ .map_or(ptr::null(), |v| v.as_ptr()) as *mut libc::iovec
++ },
++ trl_cnt: trailer_iovecs.as_ref().map(|v| v.len()).unwrap_or(0) as i32
++ },
++ header_iovecs,
++ trailer_iovecs,
++ )
++ }
++ }
++ }
++}
++
++cfg_if! {
++ if #[cfg(target_os = "freebsd")] {
++ use libc::c_int;
++
++ libc_bitflags!{
++ /// Configuration options for [`sendfile`.](fn.sendfile.html)
++ pub struct SfFlags: c_int {
++ /// Causes `sendfile` to return EBUSY instead of blocking when attempting to read a
++ /// busy page.
++ SF_NODISKIO;
++ /// Causes `sendfile` to sleep until the network stack releases its reference to the
++ /// VM pages read. When `sendfile` returns, the data is not guaranteed to have been
++ /// sent, but it is safe to modify the file.
++ SF_SYNC;
++ /// Causes `sendfile` to cache exactly the number of pages specified in the
++ /// `readahead` parameter, disabling caching heuristics.
++ SF_USER_READAHEAD;
++ /// Causes `sendfile` not to cache the data read.
++ SF_NOCACHE;
++ }
++ }
++
++ /// Read up to `count` bytes from `in_fd` starting at `offset` and write to `out_sock`.
++ ///
++ /// Returns a `Result` and a count of bytes written. Bytes written may be non-zero even if
++ /// an error occurs.
++ ///
++ /// `in_fd` must describe a regular file or shared memory object. `out_sock` must describe a
++ /// stream socket.
++ ///
++ /// If `offset` falls past the end of the file, the function returns success and zero bytes
++ /// written.
++ ///
++ /// If `count` is `None` or 0, bytes will be read from `in_fd` until reaching the end of
++ /// file (EOF).
++ ///
++ /// `headers` and `trailers` specify optional slices of byte slices to be sent before and
++ /// after the data read from `in_fd`, respectively. The length of headers and trailers sent
++ /// is included in the returned count of bytes written. The values of `offset` and `count`
++ /// do not apply to headers or trailers.
++ ///
++ /// `readahead` specifies the minimum number of pages to cache in memory ahead of the page
++ /// currently being sent.
++ ///
++ /// For more information, see
++ /// [the sendfile(2) man page.](https://www.freebsd.org/cgi/man.cgi?query=sendfile&sektion=2)
++ pub fn sendfile(
++ in_fd: RawFd,
++ out_sock: RawFd,
++ offset: off_t,
++ count: Option<usize>,
++ headers: Option<&[&[u8]]>,
++ trailers: Option<&[&[u8]]>,
++ flags: SfFlags,
++ readahead: u16
++ ) -> (Result<()>, off_t) {
++ // Readahead goes in upper 16 bits
++ // Flags goes in lower 16 bits
++ // see `man 2 sendfile`
++ let flags: u32 = ((readahead as u32) << 16) | (flags.bits() as u32);
++ let mut bytes_sent: off_t = 0;
++ let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers));
++ let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr);
++ let return_code = unsafe {
++ libc::sendfile(in_fd,
++ out_sock,
++ offset,
++ count.unwrap_or(0),
++ hdtr_ptr as *mut libc::sf_hdtr,
++ &mut bytes_sent as *mut off_t,
++ flags as c_int)
++ };
++ (Errno::result(return_code).and(Ok(())), bytes_sent)
++ }
++ } else if #[cfg(any(target_os = "ios", target_os = "macos"))] {
++ /// Read bytes from `in_fd` starting at `offset` and write up to `count` bytes to
++ /// `out_sock`.
++ ///
++ /// Returns a `Result` and a count of bytes written. Bytes written may be non-zero even if
++ /// an error occurs.
++ ///
++ /// `in_fd` must describe a regular file. `out_sock` must describe a stream socket.
++ ///
++ /// If `offset` falls past the end of the file, the function returns success and zero bytes
++ /// written.
++ ///
++ /// If `count` is `None` or 0, bytes will be read from `in_fd` until reaching the end of
++ /// file (EOF).
++ ///
++ /// `hdtr` specifies an optional list of headers and trailers to be sent before and after
++ /// the data read from `in_fd`, respectively. The length of headers and trailers sent is
++ /// included in the returned count of bytes written. If any headers are specified and
++ /// `count` is non-zero, the length of the headers will be counted in the limit of total
++ /// bytes sent. Trailers do not count toward the limit of bytes sent and will always be sent
++ /// regardless. The value of `offset` does not affect headers or trailers.
++ ///
++ /// For more information, see
++ /// [the sendfile(2) man page.](https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man2/sendfile.2.html)
++ pub fn sendfile(
++ in_fd: RawFd,
++ out_sock: RawFd,
++ offset: off_t,
++ count: Option<off_t>,
++ headers: Option<&[&[u8]]>,
++ trailers: Option<&[&[u8]]>
++ ) -> (Result<()>, off_t) {
++ let mut len = count.unwrap_or(0);
++ let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers));
++ let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr);
++ let return_code = unsafe {
++ libc::sendfile(in_fd,
++ out_sock,
++ offset,
++ &mut len as *mut off_t,
++ hdtr_ptr as *mut libc::sf_hdtr,
++ 0)
++ };
++ (Errno::result(return_code).and(Ok(())), len)
++ }
++ }
++}
+diff --git a/third_party/rust/nix-0.15.0/src/sys/signal.rs b/third_party/rust/nix-0.15.0/src/sys/signal.rs
+new file mode 100644
+index 0000000000000..1013a77fd4b40
+--- /dev/null
++++ b/third_party/rust/nix-0.15.0/src/sys/signal.rs
+@@ -0,0 +1,966 @@
++// Portions of this file are Copyright 2014 The Rust Project Developers.
++// See http://rust-lang.org/COPYRIGHT.
++
++///! Operating system signals.
++
++use libc;
++use {Error, Result};
++use errno::Errno;
++use std::mem;
++use std::fmt;
++use std::str::FromStr;
++#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
++use std::os::unix::io::RawFd;
++use std::ptr;
++
++#[cfg(not(target_os = "openbsd"))]
++pub use self::sigevent::*;
++
++libc_enum!{
++ // Currently there is only one definition of c_int in libc, as well as only one
++ // type for signal constants.
++ // We would prefer to use the libc::c_int alias in the repr attribute. Unfortunately
++ // this is not (yet) possible.
++ #[repr(i32)]
++ pub enum Signal {
++ SIGHUP,
++ SIGINT,
++ SIGQUIT,
++ SIGILL,
++ SIGTRAP,
++ SIGABRT,
++ SIGBUS,
++ SIGFPE,
++ SIGKILL,
++ SIGUSR1,
++ SIGSEGV,
++ SIGUSR2,
++ SIGPIPE,
++ SIGALRM,
++ SIGTERM,
++ #[cfg(all(any(target_os = "android", target_os = "emscripten", target_os = "linux"),
++ not(any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64"))))]
++ SIGSTKFLT,
++ SIGCHLD,
++ SIGCONT,
++ SIGSTOP,
++ SIGTSTP,
++ SIGTTIN,
++ SIGTTOU,
++ SIGURG,
++ SIGXCPU,
++ SIGXFSZ,
++ SIGVTALRM,
++ SIGPROF,
++ SIGWINCH,
++ SIGIO,
++ #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux"))]
++ SIGPWR,
++ SIGSYS,
++ #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
++ SIGEMT,
++ #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
++ SIGINFO,
++ }
++}
++
++impl FromStr for Signal {
++ type Err = Error;
++ fn from_str(s: &str) -> Result<Signal> {
++ Ok(match s {
++ "SIGHUP" => Signal::SIGHUP,
++ "SIGINT" => Signal::SIGINT,
++ "SIGQUIT" => Signal::SIGQUIT,
++ "SIGILL" => Signal::SIGILL,
++ "SIGTRAP" => Signal::SIGTRAP,
++ "SIGABRT" => Signal::SIGABRT,
++ "SIGBUS" => Signal::SIGBUS,
++ "SIGFPE" => Signal::SIGFPE,
++ "SIGKILL" => Signal::SIGKILL,
++ "SIGUSR1" => Signal::SIGUSR1,
++ "SIGSEGV" => Signal::SIGSEGV,
++ "SIGUSR2" => Signal::SIGUSR2,
++ "SIGPIPE" => Signal::SIGPIPE,
++ "SIGALRM" => Signal::SIGALRM,
++ "SIGTERM" => Signal::SIGTERM,
++ #[cfg(all(any(target_os = "android", target_os = "emscripten", target_os = "linux"),
++ not(any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64"))))]
++ "SIGSTKFLT" => Signal::SIGSTKFLT,
++ "SIGCHLD" => Signal::SIGCHLD,
++ "SIGCONT" => Signal::SIGCONT,
++ "SIGSTOP" => Signal::SIGSTOP,
++ "SIGTSTP" => Signal::SIGTSTP,
++ "SIGTTIN" => Signal::SIGTTIN,
++ "SIGTTOU" => Signal::SIGTTOU,
++ "SIGURG" => Signal::SIGURG,
++ "SIGXCPU" => Signal::SIGXCPU,
++ "SIGXFSZ" => Signal::SIGXFSZ,
++ "SIGVTALRM" => Signal::SIGVTALRM,
++ "SIGPROF" => Signal::SIGPROF,
++ "SIGWINCH" => Signal::SIGWINCH,
++ "SIGIO" => Signal::SIGIO,
++ #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux"))]
++ "SIGPWR" => Signal::SIGPWR,
++ "SIGSYS" => Signal::SIGSYS,
++ #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
++ "SIGEMT" => Signal::SIGEMT,
++ #[cfg(not(any(target_os = "android", target_os = "emscripte