Gentoo Archives: gentoo-commits

From: Yixun Lan <dlan@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/riscv:master commit in: www-client/firefox/files/, www-client/firefox/
Date: Wed, 31 Aug 2022 02:30:42
Message-Id: 1661912860.5183cfd4ccbd66fcf23f62c94dd359832eaa7006.dlan@gentoo
1 commit: 5183cfd4ccbd66fcf23f62c94dd359832eaa7006
2 Author: Alex Fan <alex.fan.q <AT> gmail <DOT> com>
3 AuthorDate: Sun Aug 28 05:34:55 2022 +0000
4 Commit: Yixun Lan <dlan <AT> gentoo <DOT> org>
5 CommitDate: Wed Aug 31 02:27:40 2022 +0000
6 URL: https://gitweb.gentoo.org/proj/riscv.git/commit/?id=5183cfd4
7
8 www-client/firefox: bump to 103.0.1
9
10 update riscv support patch. To avoid huge patches of rust third party
11 libs, we have to download it on the fly. To do this, network-sandbox
12 is restricted and ./mach vendor rust is run before ./mach configure.
13 cargo-vet is disabled as mozbuild cannot pass correct PATH to it with
14 non-git firefox src and we don't audit libs anyway.
15
16 Signed-off-by: Alex Fan <alex.fan.q <AT> gmail.com>
17 Signed-off-by: Yixun Lan <dlan <AT> gentoo.org>
18
19 .../firefox/files/firefox-riscv64-hack.patch | 102 +
20 .../firefox/files/firefox-riscv64-support.patch | 3283 ++
21 www-client/firefox/files/firefox-wayland.sh | 7 -
22 www-client/firefox/files/firefox-x11.sh | 7 -
23 www-client/firefox/files/firefox.sh | 128 -
24 .../firefox/files/gentoo-hwaccel-prefs.js-r2 | 5 +
25 ...o-riscv64-support-and-zenithal-backported.patch | 47126 -------------------
26 www-client/firefox/firefox-103.0.1.ebuild | 1301 +
27 8 files changed, 4691 insertions(+), 47268 deletions(-)
28
29 diff --git a/www-client/firefox/files/firefox-riscv64-hack.patch b/www-client/firefox/files/firefox-riscv64-hack.patch
30 new file mode 100644
31 index 0000000..b4fca4d
32 --- /dev/null
33 +++ b/www-client/firefox/files/firefox-riscv64-hack.patch
34 @@ -0,0 +1,102 @@
35 +Temporary hack to allow us to directly apply diff of matoko's branch. Disable
36 +rust-vet to skip auditing third party libs in order to download/vendor rust
37 +deps on non-git firefox src. Skip some style checks, as
38 +macroassembler support in js/src/jit/ is not complete yet
39 +
40 +diff --git a/python/mozbuild/mozbuild/vendor/vendor_rust.py b/python/mozbuild/mozbuild/vendor/vendor_rust.py
41 +index 7394ccaf40..491bd7fbdb 100644
42 +--- a/python/mozbuild/mozbuild/vendor/vendor_rust.py
43 ++++ b/python/mozbuild/mozbuild/vendor/vendor_rust.py
44 +@@ -740,38 +740,40 @@ license file's hash.
45 + failed = True
46 +
47 + # Only emit warnings for cargo-vet for now.
48 +- env = os.environ.copy()
49 +- env["PATH"] = os.pathsep.join(
50 +- (
51 +- str(Path(cargo).parent),
52 +- os.environ["PATH"],
53 +- )
54 +- )
55 +- flags = ["--output-format=json"]
56 +- if "MOZ_AUTOMATION" in os.environ:
57 +- flags.append("--locked")
58 +- flags.append("--frozen")
59 +- res = cargo_vet(
60 +- self,
61 +- flags,
62 +- stdout=subprocess.PIPE,
63 +- env=env,
64 +- )
65 +- if res.returncode:
66 +- vet = json.loads(res.stdout)
67 +- for failure in vet.get("failures", []):
68 +- failure["crate"] = failure.pop("name")
69 +- self.log(
70 +- logging.ERROR,
71 +- "cargo_vet_failed",
72 +- failure,
73 +- "Missing audit for {crate}:{version} (requires {missing_criteria})."
74 +- " Run `./mach cargo vet` for more information.",
75 +- )
76 +- failed = True
77 +-
78 +- if failed:
79 +- return False
80 ++ #env = os.environ.copy()
81 ++ #env["PATH"] = os.pathsep.join(
82 ++ # (
83 ++ # str(Path(cargo).parent),
84 ++ # os.environ["PATH"],
85 ++ # )
86 ++ #)
87 ++ #print(env["PATH"])
88 ++ #print(self.topsrcdir)
89 ++ #flags = ["--output-format=json"]
90 ++ #if "MOZ_AUTOMATION" in os.environ:
91 ++ # flags.append("--locked")
92 ++ # flags.append("--frozen")
93 ++ #res = cargo_vet(
94 ++ # self,
95 ++ # flags,
96 ++ # stdout=subprocess.PIPE,
97 ++ # env=env,
98 ++ #)
99 ++ #if res.returncode:
100 ++ # vet = json.loads(res.stdout)
101 ++ # for failure in vet.get("failures", []):
102 ++ # failure["crate"] = failure.pop("name")
103 ++ # self.log(
104 ++ # logging.ERROR,
105 ++ # "cargo_vet_failed",
106 ++ # failure,
107 ++ # "Missing audit for {crate}:{version} (requires {missing_criteria})."
108 ++ # " Run `./mach cargo vet` for more information.",
109 ++ # )
110 ++ # failed = True
111 ++
112 ++ #if failed:
113 ++ # return False
114 +
115 + res = subprocess.run(
116 + [cargo, "vendor", vendor_dir], cwd=self.topsrcdir, stdout=subprocess.PIPE
117 +@@ -848,6 +848,7 @@ license file's hash.
118 + directory=replace["directory"],
119 + )
120 + )
121 ++ return True
122 +
123 + if not self._check_licenses(vendor_dir):
124 + self.log(
125 +diff --git a/js/src/build/moz.build b/js/src/build/moz.build
126 +index 4c48a5c4ff..e68d79447e 100644
127 +--- a/js/src/build/moz.build
128 ++++ b/js/src/build/moz.build
129 +@@ -101,7 +101,5 @@ GeneratedFile(
130 + inputs=[
131 + "!%sjs_static.%s" % (CONFIG["LIB_PREFIX"], CONFIG["LIB_SUFFIX"]),
132 +- "/config/check_spidermonkey_style.py",
133 +- "/config/check_macroassembler_style.py",
134 + "/config/check_js_opcode.py",
135 + ],
136 + )
137
138 diff --git a/www-client/firefox/files/firefox-riscv64-support.patch b/www-client/firefox/files/firefox-riscv64-support.patch
139 new file mode 100644
140 index 0000000..7e9abfc
141 --- /dev/null
142 +++ b/www-client/firefox/files/firefox-riscv64-support.patch
143 @@ -0,0 +1,3283 @@
144 +patch generated directly from https://github.com/makotokato/gecko-dev by
145 +
146 + git diff master..riscv64 -- . :^third_party
147 +
148 +:^third_party is a git feature to exclude third_party/ from diff
149 +
150 +diff --git a/.cargo/config.in b/.cargo/config.in
151 +index 20b8c3fad8..34c5f9a1f4 100644
152 +--- a/.cargo/config.in
153 ++++ b/.cargo/config.in
154 +@@ -22,11 +22,6 @@ git = "https://github.com/mozilla/mp4parse-rust"
155 + replace-with = "vendored-sources"
156 + rev = "3bfc47d9a571d0842676043ba60716318e946c06"
157 +
158 +-[source."https://github.com/mozilla/midir.git"]
159 +-git = "https://github.com/mozilla/midir.git"
160 +-replace-with = "vendored-sources"
161 +-rev = "4c11f0ffb5d6a10de4aff40a7b81218b33b94e6f"
162 +-
163 + [source."https://github.com/mozilla/cubeb-pulse-rs"]
164 + git = "https://github.com/mozilla/cubeb-pulse-rs"
165 + replace-with = "vendored-sources"
166 +@@ -37,6 +32,11 @@ git = "https://github.com/mozilla/cubeb-coreaudio-rs"
167 + replace-with = "vendored-sources"
168 + rev = "44eca95823bb57e964cf7b6d9791ed2ccb4b2108"
169 +
170 ++[source."https://github.com/mozilla/authenticator-rs"]
171 ++git = "https://github.com/mozilla/authenticator-rs"
172 ++replace-with = "vendored-sources"
173 ++rev = "b85bccf0527e42c877573029e8d35ff13ef06f9d"
174 ++
175 + [source."https://github.com/mozilla/audioipc"]
176 + git = "https://github.com/mozilla/audioipc"
177 + replace-with = "vendored-sources"
178 +diff --git a/Cargo.lock b/Cargo.lock
179 +index 85a143565c..b4924869cb 100644
180 +--- a/Cargo.lock
181 ++++ b/Cargo.lock
182 +@@ -30,14 +30,14 @@ dependencies = [
183 +
184 + [[package]]
185 + name = "alsa"
186 +-version = "0.4.3"
187 ++version = "0.6.0"
188 + source = "registry+https://github.com/rust-lang/crates.io-index"
189 +-checksum = "eb213f6b3e4b1480a60931ca2035794aa67b73103d254715b1db7b70dcb3c934"
190 ++checksum = "5915f52fe2cf65e83924d037b6c5290b7cee097c6b5c8700746e6168a343fd6b"
191 + dependencies = [
192 + "alsa-sys",
193 + "bitflags",
194 + "libc",
195 +- "nix",
196 ++ "nix 0.23.1",
197 + ]
198 +
199 + [[package]]
200 +@@ -359,9 +359,8 @@ dependencies = [
201 +
202 + [[package]]
203 + name = "authenticator"
204 +-version = "0.3.1"
205 +-source = "registry+https://github.com/rust-lang/crates.io-index"
206 +-checksum = "08cee7a0952628fde958e149507c2bb321ab4fccfafd225da0b20adc956ef88a"
207 ++version = "0.3.2"
208 ++source = "git+https://github.com/mozilla/authenticator-rs?rev=b85bccf0527e42c877573029e8d35ff13ef06f9d#b85bccf0527e42c877573029e8d35ff13ef06f9d"
209 + dependencies = [
210 + "bitflags",
211 + "core-foundation",
212 +@@ -369,7 +368,7 @@ dependencies = [
213 + "libc",
214 + "libudev",
215 + "log",
216 +- "rand 0.7.999",
217 ++ "rand 0.8.5",
218 + "runloop",
219 + "winapi",
220 + ]
221 +@@ -2204,6 +2203,7 @@ dependencies = [
222 + "log",
223 + "mapped_hyph",
224 + "mdns_service",
225 ++ "midir",
226 + "midir_impl",
227 + "mio 0.8.0",
228 + "moz_asserts",
229 +@@ -3274,8 +3274,9 @@ dependencies = [
230 +
231 + [[package]]
232 + name = "midir"
233 +-version = "0.7.0"
234 +-source = "git+https://github.com/mozilla/midir.git?rev=4c11f0ffb5d6a10de4aff40a7b81218b33b94e6f#4c11f0ffb5d6a10de4aff40a7b81218b33b94e6f"
235 ++version = "0.8.0"
236 ++source = "registry+https://github.com/rust-lang/crates.io-index"
237 ++checksum = "2c1c68e2b589cce71b14a10d7d1599a845673f9decde80fa9e8500fdccd50dca"
238 + dependencies = [
239 + "alsa",
240 + "bitflags",
241 +@@ -3283,10 +3284,9 @@ dependencies = [
242 + "js-sys",
243 + "libc",
244 + "memalloc",
245 +- "nix",
246 + "wasm-bindgen",
247 + "web-sys",
248 +- "winapi",
249 ++ "windows",
250 + ]
251 +
252 + [[package]]
253 +@@ -3325,7 +3325,7 @@ dependencies = [
254 + "libc",
255 + "memmap2 0.2.999",
256 + "memoffset 0.5.6",
257 +- "nix",
258 ++ "nix 0.15.0",
259 + "tempfile",
260 + "thiserror",
261 + ]
262 +@@ -3735,6 +3735,19 @@ dependencies = [
263 + "void",
264 + ]
265 +
266 ++[[package]]
267 ++name = "nix"
268 ++version = "0.23.1"
269 ++source = "registry+https://github.com/rust-lang/crates.io-index"
270 ++checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6"
271 ++dependencies = [
272 ++ "bitflags",
273 ++ "cc",
274 ++ "cfg-if 1.0.0",
275 ++ "libc",
276 ++ "memoffset 0.6.5",
277 ++]
278 ++
279 + [[package]]
280 + name = "nom"
281 + version = "5.999.999"
282 +@@ -6218,6 +6231,49 @@ version = "0.4.0"
283 + source = "registry+https://github.com/rust-lang/crates.io-index"
284 + checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
285 +
286 ++[[package]]
287 ++name = "windows"
288 ++version = "0.32.0"
289 ++source = "registry+https://github.com/rust-lang/crates.io-index"
290 ++checksum = "fbedf6db9096bc2364adce0ae0aa636dcd89f3c3f2cd67947062aaf0ca2a10ec"
291 ++dependencies = [
292 ++ "windows_aarch64_msvc",
293 ++ "windows_i686_gnu",
294 ++ "windows_i686_msvc",
295 ++ "windows_x86_64_gnu",
296 ++ "windows_x86_64_msvc",
297 ++]
298 ++
299 ++[[package]]
300 ++name = "windows_aarch64_msvc"
301 ++version = "0.32.0"
302 ++source = "registry+https://github.com/rust-lang/crates.io-index"
303 ++checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5"
304 ++
305 ++[[package]]
306 ++name = "windows_i686_gnu"
307 ++version = "0.32.0"
308 ++source = "registry+https://github.com/rust-lang/crates.io-index"
309 ++checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615"
310 ++
311 ++[[package]]
312 ++name = "windows_i686_msvc"
313 ++version = "0.32.0"
314 ++source = "registry+https://github.com/rust-lang/crates.io-index"
315 ++checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172"
316 ++
317 ++[[package]]
318 ++name = "windows_x86_64_gnu"
319 ++version = "0.32.0"
320 ++source = "registry+https://github.com/rust-lang/crates.io-index"
321 ++checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc"
322 ++
323 ++[[package]]
324 ++name = "windows_x86_64_msvc"
325 ++version = "0.32.0"
326 ++source = "registry+https://github.com/rust-lang/crates.io-index"
327 ++checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316"
328 ++
329 + [[package]]
330 + name = "wineventlog"
331 + version = "0.1.0"
332 +diff --git a/Cargo.toml b/Cargo.toml
333 +index 2b499a0841..dcf1e401d7 100644
334 +--- a/Cargo.toml
335 ++++ b/Cargo.toml
336 +@@ -153,7 +153,6 @@ coremidi = { git = "https://github.com/chris-zen/coremidi.git", rev="fc68464b544
337 + fog = { path = "toolkit/components/glean/api" }
338 + libudev-sys = { path = "dom/webauthn/libudev-sys" }
339 + packed_simd = { package = "packed_simd_2", git = "https://github.com/hsivonen/packed_simd", rev="c149d0a519bf878567c7630096737669ec2ff15f" }
340 +-midir = { git = "https://github.com/mozilla/midir.git", rev = "4c11f0ffb5d6a10de4aff40a7b81218b33b94e6f" }
341 + minidump_writer_linux = { git = "https://github.com/rust-minidump/minidump-writer.git", rev = "75ada456c92a429704691a85e1cb42fef8cafc0d" }
342 +
343 + # application-services overrides to make updating them all simpler.
344 +diff --git a/README.riscv64.md b/README.riscv64.md
345 +new file mode 100644
346 +index 0000000000..705099a3db
347 +--- /dev/null
348 ++++ b/README.riscv64.md
349 +@@ -0,0 +1,69 @@
350 ++## Cross building
351 ++I recommend you should use docker environment
352 ++
353 ++#### Dockerfile
354 ++```dockerfile
355 ++FROM ubuntu:21.04
356 ++MAINTAINER Makoto Kato <m_kato@×××××××××××××.jp>
357 ++
358 ++ADD sources.list /etc/apt/
359 ++ENV DEBIAN_FRONTEND=noninteractive
360 ++RUN dpkg --add-architecture riscv64 && \
361 ++ apt-get update && \
362 ++ apt-get install -y clang g++ mercurial g++-riscv64-linux-gnu curl gyp ninja-build make python-is-python3 libssl-dev zlib1g-dev nodejs build-essential libpython3-dev m4 unzip zip uuid git python3-pip && \
363 ++ apt-get install -y zlib1g-dev:riscv64 libssl-dev:riscv64 libffi-dev:riscv64 libasound2-dev:riscv64 libcurl4-openssl-dev:riscv64 libdbus-1-dev:riscv64 libdbus-glib-1-dev:riscv64 libdrm-dev:riscv64 libgtk-3-dev:riscv64 libpulse-dev:riscv64 libx11-xcb-dev:riscv64 libxt-dev:riscv64 xvfb:riscv64 libstdc++-10-dev:riscv64 && \
364 ++ apt-get clean
365 ++WORKDIR /root
366 ++ENV PATH="/root/.cargo/bin:${PATH}"
367 ++RUN curl https://sh.rustup.rs -s -o install.sh && sh install.sh -y && rm install.sh && rustup target add riscv64gc-unknown-linux-gnu
368 ++RUN cargo install cbindgen
369 ++```
370 ++
371 ++#### sources.list
372 ++```
373 ++deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ hirsute main restricted
374 ++deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ hirsute-updates main restricted
375 ++deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ hirsute universe
376 ++deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ hirsute-updates universe
377 ++deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ hirsute multiverse
378 ++deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ hirsute-updates multiverse
379 ++deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ hirsute-backports main restricted universe multiverse
380 ++deb [arch=amd64] http://security.ubuntu.com/ubuntu/ hirsute-security main restricted
381 ++deb [arch=amd64] http://security.ubuntu.com/ubuntu/ hirsute-security universe
382 ++deb [arch=amd64] http://security.ubuntu.com/ubuntu/ hirsute-security multiverse
383 ++
384 ++deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports hirsute main restricted
385 ++deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports hirsute-updates main restricted
386 ++deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports hirsute universe
387 ++deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports hirsute-updates universe
388 ++deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports hirsute multiverse
389 ++deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports hirsute-updates multiverse
390 ++deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports hirsute-backports main restricted universe multiverse
391 ++deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports hirsute-security main restricted
392 ++deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports hirsute-security universe
393 ++deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports hirsute-security multiverse
394 ++```
395 ++
396 ++## mozconfig
397 ++```
398 ++mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir
399 ++mk_add_options AUTOCLOBBER=1
400 ++
401 ++ac_add_options --disable-debug
402 ++ac_add_options --enable-optimize
403 ++
404 ++ac_add_options --target=riscv64
405 ++export CC=riscv64-linux-gnu-gcc
406 ++export CXX=riscv64-linux-gnu-g++
407 ++export HOST_CC=gcc
408 ++export HOST_CXX=g++
409 ++ac_add_options --disable-bootstrap
410 ++ac_add_options --without-wasm-sandboxed-libraries
411 ++ac_add_options --enable-webrtc
412 ++ac_add_options --disable-crashreporter
413 ++ac_add_options --disable-jit
414 ++```
415 ++
416 ++## How to build
417 ++1. `./mach build`
418 ++2. `./mach package`
419 +diff --git a/dom/bindings/moz.build b/dom/bindings/moz.build
420 +index cf3a8d5017..5e1388cfe5 100644
421 +--- a/dom/bindings/moz.build
422 ++++ b/dom/bindings/moz.build
423 +@@ -96,12 +96,16 @@ LOCAL_INCLUDES += [
424 + "/layout/xul/tree",
425 + "/media/webrtc/",
426 + "/netwerk/base/",
427 +- "/third_party/libwebrtc",
428 +- "/third_party/libwebrtc/third_party/abseil-cpp",
429 + ]
430 +
431 + LOCAL_INCLUDES += ["/third_party/msgpack/include"]
432 +
433 ++if CONFIG["MOZ_WEBRTC"]:
434 ++ LOCAL_INCLUDES += [
435 ++ "/third_party/libwebrtc",
436 ++ "/third_party/libwebrtc/third_party/abseil-cpp",
437 ++ ]
438 ++
439 + DEFINES["GOOGLE_PROTOBUF_NO_RTTI"] = True
440 + DEFINES["GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER"] = True
441 +
442 +diff --git a/dom/media/gtest/moz.build b/dom/media/gtest/moz.build
443 +index 05803392cb..d689c7bd77 100644
444 +--- a/dom/media/gtest/moz.build
445 ++++ b/dom/media/gtest/moz.build
446 +@@ -13,10 +13,14 @@ LOCAL_INCLUDES += [
447 + "/dom/media/systemservices",
448 + "/dom/media/webrtc",
449 + "/dom/media/webrtc/common",
450 +- "/third_party/libwebrtc",
451 +- "/third_party/libwebrtc/third_party/abseil-cpp",
452 + ]
453 +
454 ++if CONFIG["MOZ_WEBRTC"]:
455 ++ LOCAL_INCLUDES += [
456 ++ "/third_party/libwebrtc",
457 ++ "/third_party/libwebrtc/third_party/abseil-cpp",
458 ++ ]
459 ++
460 + UNIFIED_SOURCES += [
461 + "MockCubeb.cpp",
462 + "MockMediaResource.cpp",
463 +diff --git a/dom/midi/midir_impl/Cargo.toml b/dom/midi/midir_impl/Cargo.toml
464 +index 7628fb4a68..a918ff2227 100644
465 +--- a/dom/midi/midir_impl/Cargo.toml
466 ++++ b/dom/midi/midir_impl/Cargo.toml
467 +@@ -7,7 +7,7 @@ edition = "2018"
468 + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
469 +
470 + [dependencies]
471 +-midir = "0.7.0"
472 ++midir = "0.8.0"
473 + nsstring = { path = "../../../xpcom/rust/nsstring/" }
474 + uuid = { version = "0.8", features = ["v4"] }
475 + thin-vec = { version = "0.2.1", features = ["gecko-ffi"] }
476 +diff --git a/ipc/glue/moz.build b/ipc/glue/moz.build
477 +index c4b7c1d69e..775f553d05 100644
478 +--- a/ipc/glue/moz.build
479 ++++ b/ipc/glue/moz.build
480 +@@ -220,6 +220,12 @@ LOCAL_INCLUDES += [
481 + "/xpcom/build",
482 + ]
483 +
484 ++if CONFIG["MOZ_WEBRTC"]:
485 ++ LOCAL_INCLUDES += [
486 ++ "/third_party/libwebrtc",
487 ++ "/third_party/libwebrtc/third_party/abseil-cpp",
488 ++ ]
489 ++
490 + PREPROCESSED_IPDL_SOURCES = [
491 + "PUtilityProcess.ipdl",
492 + ]
493 +diff --git a/js/moz.configure b/js/moz.configure
494 +index 4f9bb8992f..d53c672aa0 100644
495 +--- a/js/moz.configure
496 ++++ b/js/moz.configure
497 +@@ -184,7 +184,7 @@ def report_deprecated(value):
498 + # =======================================================
499 + option(
500 + "--enable-simulator",
501 +- choices=("arm", "arm64", "mips32", "mips64", "loong64"),
502 ++ choices=("arm", "arm64", "mips32", "mips64", "loong64", "riscv64"),
503 + nargs=1,
504 + help="Enable a JIT code simulator for the specified architecture",
505 + )
506 +@@ -201,7 +201,7 @@ def simulator(jit_enabled, simulator_enabled, target):
507 + if target.cpu != "x86":
508 + die("The %s simulator only works on x86." % sim_cpu)
509 +
510 +- if sim_cpu in ("arm64", "mips64", "loong64"):
511 ++ if sim_cpu in ("arm64", "mips64", "loong64", "riscv64"):
512 + if target.cpu != "x86_64" and target.cpu != "aarch64":
513 + die("The %s simulator only works on x86-64 or arm64." % sim_cpu)
514 +
515 +@@ -214,12 +214,14 @@ set_config("JS_SIMULATOR_ARM64", simulator.arm64)
516 + set_config("JS_SIMULATOR_MIPS32", simulator.mips32)
517 + set_config("JS_SIMULATOR_MIPS64", simulator.mips64)
518 + set_config("JS_SIMULATOR_LOONG64", simulator.loong64)
519 ++set_config("JS_SIMULATOR_RISCV64", simulator.riscv64)
520 + set_define("JS_SIMULATOR", depends_if(simulator)(lambda x: True))
521 + set_define("JS_SIMULATOR_ARM", simulator.arm)
522 + set_define("JS_SIMULATOR_ARM64", simulator.arm64)
523 + set_define("JS_SIMULATOR_MIPS32", simulator.mips32)
524 + set_define("JS_SIMULATOR_MIPS64", simulator.mips64)
525 + set_define("JS_SIMULATOR_LOONG64", simulator.loong64)
526 ++set_define("JS_SIMULATOR_RISCV64", simulator.riscv64)
527 +
528 +
529 + @depends("--enable-jit", simulator, target)
530 +@@ -244,6 +246,7 @@ set_config("JS_CODEGEN_ARM64", jit_codegen.arm64)
531 + set_config("JS_CODEGEN_MIPS32", jit_codegen.mips32)
532 + set_config("JS_CODEGEN_MIPS64", jit_codegen.mips64)
533 + set_config("JS_CODEGEN_LOONG64", jit_codegen.loong64)
534 ++set_config("JS_CODEGEN_RISCV64", jit_codegen.riscv64)
535 + set_config("JS_CODEGEN_X86", jit_codegen.x86)
536 + set_config("JS_CODEGEN_X64", jit_codegen.x64)
537 + set_define("JS_CODEGEN_NONE", jit_codegen.none)
538 +@@ -252,6 +255,7 @@ set_define("JS_CODEGEN_ARM64", jit_codegen.arm64)
539 + set_define("JS_CODEGEN_MIPS32", jit_codegen.mips32)
540 + set_define("JS_CODEGEN_MIPS64", jit_codegen.mips64)
541 + set_define("JS_CODEGEN_LOONG64", jit_codegen.loong64)
542 ++set_define("JS_CODEGEN_RISCV64", jit_codegen.riscv64)
543 + set_define("JS_CODEGEN_X86", jit_codegen.x86)
544 + set_define("JS_CODEGEN_X64", jit_codegen.x64)
545 +
546 +diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp
547 +index 2b8de6284f..1b9b4b62c7 100644
548 +--- a/js/src/builtin/TestingFunctions.cpp
549 ++++ b/js/src/builtin/TestingFunctions.cpp
550 +@@ -426,6 +426,24 @@ static bool GetBuildConfiguration(JSContext* cx, unsigned argc, Value* vp) {
551 + return false;
552 + }
553 +
554 ++#ifdef JS_CODEGEN_RISCV64
555 ++ value = BooleanValue(true);
556 ++#else
557 ++ value = BooleanValue(false);
558 ++#endif
559 ++ if (!JS_SetProperty(cx, info, "riscv64", value)) {
560 ++ return false;
561 ++ }
562 ++
563 ++#ifdef JS_SIMULATOR_RISCV64
564 ++ value = BooleanValue(true);
565 ++#else
566 ++ value = BooleanValue(false);
567 ++#endif
568 ++ if (!JS_SetProperty(cx, info, "riscv64-simulator", value)) {
569 ++ return false;
570 ++ }
571 ++
572 + #ifdef JS_SIMULATOR
573 + value = BooleanValue(true);
574 + #else
575 +diff --git a/js/src/jit/Assembler.h b/js/src/jit/Assembler.h
576 +index 04dcdc647e..2081f254b0 100644
577 +--- a/js/src/jit/Assembler.h
578 ++++ b/js/src/jit/Assembler.h
579 +@@ -19,6 +19,8 @@
580 + # include "jit/mips32/Assembler-mips32.h"
581 + #elif defined(JS_CODEGEN_MIPS64)
582 + # include "jit/mips64/Assembler-mips64.h"
583 ++#elif defined(JS_CODEGEN_RISCV64)
584 ++# include "jit/riscv64/Assembler-riscv64.h"
585 + #elif defined(JS_CODEGEN_LOONG64)
586 + # include "jit/loong64/Assembler-loong64.h"
587 + #elif defined(JS_CODEGEN_NONE)
588 +diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h
589 +index 67453d3cd3..82e58d2a16 100644
590 +--- a/js/src/jit/CodeGenerator.h
591 ++++ b/js/src/jit/CodeGenerator.h
592 +@@ -26,6 +26,8 @@
593 + # include "jit/mips64/CodeGenerator-mips64.h"
594 + #elif defined(JS_CODEGEN_LOONG64)
595 + # include "jit/loong64/CodeGenerator-loong64.h"
596 ++#elif defined(JS_CODEGEN_RISCV64)
597 ++# include "jit/riscv64/CodeGenerator-riscv64.h"
598 + #elif defined(JS_CODEGEN_NONE)
599 + # include "jit/none/CodeGenerator-none.h"
600 + #else
601 +diff --git a/js/src/jit/FlushICache.h b/js/src/jit/FlushICache.h
602 +index 42b1fb045c..feeae3c793 100644
603 +--- a/js/src/jit/FlushICache.h
604 ++++ b/js/src/jit/FlushICache.h
605 +@@ -25,7 +25,7 @@ inline void FlushICache(void* code, size_t size,
606 +
607 + #elif (defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)) || \
608 + (defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)) || \
609 +- defined(JS_CODEGEN_LOONG64)
610 ++ defined(JS_CODEGEN_LOONG64) || defined(JS_CODEGEN_RISCV64)
611 +
612 + extern void FlushICache(void* code, size_t size, bool codeIsThreadLocal = true);
613 +
614 +diff --git a/js/src/jit/LIR.h b/js/src/jit/LIR.h
615 +index 66c665b5ba..016c8246f7 100644
616 +--- a/js/src/jit/LIR.h
617 ++++ b/js/src/jit/LIR.h
618 +@@ -1933,6 +1933,8 @@ AnyRegister LAllocation::toRegister() const {
619 + # include "jit/mips64/LIR-mips64.h"
620 + # endif
621 + # include "jit/mips-shared/LIR-mips-shared.h"
622 ++#elif defined(JS_CODEGEN_RISCV64)
623 ++# include "jit/riscv64/LIR-riscv64.h"
624 + #elif defined(JS_CODEGEN_NONE)
625 + # include "jit/none/LIR-none.h"
626 + #else
627 +diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h
628 +index a04d09c446..21094a616e 100644
629 +--- a/js/src/jit/Lowering.h
630 ++++ b/js/src/jit/Lowering.h
631 +@@ -23,6 +23,8 @@
632 + # include "jit/mips32/Lowering-mips32.h"
633 + #elif defined(JS_CODEGEN_MIPS64)
634 + # include "jit/mips64/Lowering-mips64.h"
635 ++#elif defined(JS_CODEGEN_RISCV64)
636 ++# include "jit/riscv64/Lowering-riscv64.h"
637 + #elif defined(JS_CODEGEN_LOONG64)
638 + # include "jit/loong64/Lowering-loong64.h"
639 + #elif defined(JS_CODEGEN_NONE)
640 +diff --git a/js/src/jit/MacroAssembler-inl.h b/js/src/jit/MacroAssembler-inl.h
641 +index 5ed4ac7458..1c208e676d 100644
642 +--- a/js/src/jit/MacroAssembler-inl.h
643 ++++ b/js/src/jit/MacroAssembler-inl.h
644 +@@ -39,6 +39,8 @@
645 + # include "jit/mips64/MacroAssembler-mips64-inl.h"
646 + #elif defined(JS_CODEGEN_LOONG64)
647 + # include "jit/loong64/MacroAssembler-loong64-inl.h"
648 ++#elif defined(JS_CODEGEN_RISCV64)
649 ++# include "jit/riscv64/MacroAssembler-riscv64-inl.h"
650 + #elif !defined(JS_CODEGEN_NONE)
651 + # error "Unknown architecture!"
652 + #endif
653 +diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp
654 +index 3abc601bec..0665601509 100644
655 +--- a/js/src/jit/MacroAssembler.cpp
656 ++++ b/js/src/jit/MacroAssembler.cpp
657 +@@ -4145,6 +4145,8 @@ void MacroAssembler::emitPreBarrierFastPath(JSRuntime* rt, MIRType type,
658 + ma_dsll(temp1, temp1, temp3);
659 + #elif JS_CODEGEN_LOONG64
660 + as_sll_d(temp1, temp1, temp3);
661 ++#elif JS_CODEGEN_RISCV64
662 ++ MOZ_CRASH();
663 + #elif JS_CODEGEN_NONE
664 + MOZ_CRASH();
665 + #else
666 +diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h
667 +index 5fa8f40bd1..3395a139d3 100644
668 +--- a/js/src/jit/MacroAssembler.h
669 ++++ b/js/src/jit/MacroAssembler.h
670 +@@ -25,6 +25,8 @@
671 + # include "jit/mips32/MacroAssembler-mips32.h"
672 + #elif defined(JS_CODEGEN_MIPS64)
673 + # include "jit/mips64/MacroAssembler-mips64.h"
674 ++#elif defined(JS_CODEGEN_RISCV64)
675 ++# include "jit/riscv64/MacroAssembler-riscv64.h"
676 + #elif defined(JS_CODEGEN_LOONG64)
677 + # include "jit/loong64/MacroAssembler-loong64.h"
678 + #elif defined(JS_CODEGEN_NONE)
679 +@@ -94,8 +96,8 @@
680 + // }
681 + // ////}}} check_macroassembler_style
682 +
683 +-#define ALL_ARCH mips32, mips64, arm, arm64, x86, x64, loong64
684 +-#define ALL_SHARED_ARCH arm, arm64, loong64, x86_shared, mips_shared
685 ++#define ALL_ARCH mips32, mips64, arm, arm64, x86, x64, loong64, riscv64
686 ++#define ALL_SHARED_ARCH arm, arm64, loong64, riscv64, x86_shared, mips_shared
687 +
688 + // * How this macro works:
689 + //
690 +@@ -142,6 +144,7 @@
691 + #define DEFINED_ON_mips64
692 + #define DEFINED_ON_mips_shared
693 + #define DEFINED_ON_loong64
694 ++#define DEFINED_ON_riscv64
695 + #define DEFINED_ON_none
696 +
697 + // Specialize for each architecture.
698 +@@ -174,6 +177,9 @@
699 + #elif defined(JS_CODEGEN_LOONG64)
700 + # undef DEFINED_ON_loong64
701 + # define DEFINED_ON_loong64 define
702 ++#elif defined(JS_CODEGEN_RISCV64)
703 ++# undef DEFINED_ON_riscv64
704 ++# define DEFINED_ON_riscv64 define
705 + #elif defined(JS_CODEGEN_NONE)
706 + # undef DEFINED_ON_none
707 + # define DEFINED_ON_none crash
708 +@@ -491,10 +497,10 @@ class MacroAssembler : public MacroAssemblerSpecific {
709 +
710 + // The size of the area used by PushRegsInMask.
711 + size_t PushRegsInMaskSizeInBytes(LiveRegisterSet set)
712 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
713 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
714 +
715 + void PushRegsInMask(LiveRegisterSet set)
716 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
717 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
718 + void PushRegsInMask(LiveGeneralRegisterSet set);
719 +
720 + // Like PushRegsInMask, but instead of pushing the registers, store them to
721 +@@ -505,12 +511,12 @@ class MacroAssembler : public MacroAssemblerSpecific {
722 + // must point to either the lowest address in the save area, or some address
723 + // below that.
724 + void storeRegsInMask(LiveRegisterSet set, Address dest, Register scratch)
725 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
726 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
727 +
728 + void PopRegsInMask(LiveRegisterSet set);
729 + void PopRegsInMask(LiveGeneralRegisterSet set);
730 + void PopRegsInMaskIgnore(LiveRegisterSet set, LiveRegisterSet ignore)
731 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
732 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
733 +
734 + // ===============================================================
735 + // Stack manipulation functions -- single registers/values.
736 +@@ -543,7 +549,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
737 + void Pop(FloatRegister t) PER_SHARED_ARCH;
738 + void Pop(const ValueOperand& val) PER_SHARED_ARCH;
739 + void PopFlags() DEFINED_ON(x86_shared);
740 +- void PopStackPtr() DEFINED_ON(arm, mips_shared, x86_shared, loong64);
741 ++ void PopStackPtr() DEFINED_ON(arm, mips_shared, x86_shared, loong64, riscv64);
742 + void popRooted(VMFunctionData::RootType rootType, Register cellReg,
743 + const ValueOperand& valueReg);
744 +
745 +@@ -601,8 +607,9 @@ class MacroAssembler : public MacroAssemblerSpecific {
746 + void callAndPushReturnAddress(Label* label) DEFINED_ON(x86_shared);
747 +
748 + // These do not adjust framePushed().
749 +- void pushReturnAddress() DEFINED_ON(mips_shared, arm, arm64, loong64);
750 +- void popReturnAddress() DEFINED_ON(mips_shared, arm, arm64, loong64);
751 ++ void pushReturnAddress()
752 ++ DEFINED_ON(mips_shared, arm, arm64, loong64, riscv64);
753 ++ void popReturnAddress() DEFINED_ON(mips_shared, arm, arm64, loong64, riscv64);
754 +
755 + // Useful for dealing with two-valued returns.
756 + void moveRegPair(Register src0, Register src1, Register dst0, Register dst1,
757 +@@ -633,10 +640,10 @@ class MacroAssembler : public MacroAssemblerSpecific {
758 + // Note: "Near" applies to ARM64 where the target must be within 1 MB (this is
759 + // release-asserted).
760 + CodeOffset moveNearAddressWithPatch(Register dest)
761 +- DEFINED_ON(x86, x64, arm, arm64, loong64, mips_shared);
762 ++ DEFINED_ON(x86, x64, arm, arm64, loong64, mips_shared, riscv64);
763 + static void patchNearAddressMove(CodeLocationLabel loc,
764 + CodeLocationLabel target)
765 +- DEFINED_ON(x86, x64, arm, arm64, loong64, mips_shared);
766 ++ DEFINED_ON(x86, x64, arm, arm64, loong64, mips_shared, riscv64);
767 +
768 + public:
769 + // ===============================================================
770 +@@ -1045,17 +1052,17 @@ class MacroAssembler : public MacroAssemblerSpecific {
771 + inline void addPtr(ImmWord imm, Register dest) PER_ARCH;
772 + inline void addPtr(ImmPtr imm, Register dest);
773 + inline void addPtr(Imm32 imm, const Address& dest)
774 +- DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64);
775 ++ DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64, riscv64);
776 + inline void addPtr(Imm32 imm, const AbsoluteAddress& dest)
777 + DEFINED_ON(x86, x64);
778 + inline void addPtr(const Address& src, Register dest)
779 +- DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64);
780 ++ DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64, riscv64);
781 +
782 + inline void add64(Register64 src, Register64 dest) PER_ARCH;
783 + inline void add64(Imm32 imm, Register64 dest) PER_ARCH;
784 + inline void add64(Imm64 imm, Register64 dest) PER_ARCH;
785 + inline void add64(const Operand& src, Register64 dest)
786 +- DEFINED_ON(x64, mips64, loong64);
787 ++ DEFINED_ON(x64, mips64, loong64, riscv64);
788 +
789 + inline void addFloat32(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH;
790 +
791 +@@ -1074,16 +1081,16 @@ class MacroAssembler : public MacroAssemblerSpecific {
792 +
793 + inline void subPtr(Register src, Register dest) PER_ARCH;
794 + inline void subPtr(Register src, const Address& dest)
795 +- DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64);
796 ++ DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64, riscv64);
797 + inline void subPtr(Imm32 imm, Register dest) PER_ARCH;
798 + inline void subPtr(ImmWord imm, Register dest) DEFINED_ON(x64);
799 + inline void subPtr(const Address& addr, Register dest)
800 +- DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64);
801 ++ DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64, riscv64);
802 +
803 + inline void sub64(Register64 src, Register64 dest) PER_ARCH;
804 + inline void sub64(Imm64 imm, Register64 dest) PER_ARCH;
805 + inline void sub64(const Operand& src, Register64 dest)
806 +- DEFINED_ON(x64, mips64, loong64);
807 ++ DEFINED_ON(x64, mips64, loong64, riscv64);
808 +
809 + inline void subFloat32(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH;
810 +
811 +@@ -1099,10 +1106,11 @@ class MacroAssembler : public MacroAssemblerSpecific {
812 +
813 + inline void mul64(const Operand& src, const Register64& dest) DEFINED_ON(x64);
814 + inline void mul64(const Operand& src, const Register64& dest,
815 +- const Register temp) DEFINED_ON(x64, mips64, loong64);
816 ++ const Register temp)
817 ++ DEFINED_ON(x64, mips64, loong64, riscv64);
818 + inline void mul64(Imm64 imm, const Register64& dest) PER_ARCH;
819 + inline void mul64(Imm64 imm, const Register64& dest, const Register temp)
820 +- DEFINED_ON(x86, x64, arm, mips32, mips64, loong64);
821 ++ DEFINED_ON(x86, x64, arm, mips32, mips64, loong64, riscv64);
822 + inline void mul64(const Register64& src, const Register64& dest,
823 + const Register temp) PER_ARCH;
824 + inline void mul64(const Register64& src1, const Register64& src2,
825 +@@ -1116,14 +1124,14 @@ class MacroAssembler : public MacroAssemblerSpecific {
826 + inline void mulDouble(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH;
827 +
828 + inline void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest)
829 +- DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64);
830 ++ DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64, riscv64);
831 +
832 + // Perform an integer division, returning the integer part rounded toward
833 + // zero. rhs must not be zero, and the division must not overflow.
834 + //
835 + // On ARM, the chip must have hardware division instructions.
836 + inline void quotient32(Register rhs, Register srcDest, bool isUnsigned)
837 +- DEFINED_ON(mips_shared, arm, arm64, loong64);
838 ++ DEFINED_ON(mips_shared, arm, arm64, loong64, riscv64);
839 +
840 + // As above, but srcDest must be eax and tempEdx must be edx.
841 + inline void quotient32(Register rhs, Register srcDest, Register tempEdx,
842 +@@ -1134,7 +1142,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
843 + //
844 + // On ARM, the chip must have hardware division instructions.
845 + inline void remainder32(Register rhs, Register srcDest, bool isUnsigned)
846 +- DEFINED_ON(mips_shared, arm, arm64, loong64);
847 ++ DEFINED_ON(mips_shared, arm, arm64, loong64, riscv64);
848 +
849 + // As above, but srcDest must be eax and tempEdx must be edx.
850 + inline void remainder32(Register rhs, Register srcDest, Register tempEdx,
851 +@@ -1149,7 +1157,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
852 + // rhs is preserved, srdDest is clobbered.
853 + void flexibleRemainder32(Register rhs, Register srcDest, bool isUnsigned,
854 + const LiveRegisterSet& volatileLiveRegs)
855 +- DEFINED_ON(mips_shared, arm, arm64, x86_shared, loong64);
856 ++ DEFINED_ON(mips_shared, arm, arm64, x86_shared, loong64, riscv64);
857 +
858 + // Perform an integer division, returning the integer part rounded toward
859 + // zero. rhs must not be zero, and the division must not overflow.
860 +@@ -1160,7 +1168,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
861 + // rhs is preserved, srdDest is clobbered.
862 + void flexibleQuotient32(Register rhs, Register srcDest, bool isUnsigned,
863 + const LiveRegisterSet& volatileLiveRegs)
864 +- DEFINED_ON(mips_shared, arm, arm64, x86_shared, loong64);
865 ++ DEFINED_ON(mips_shared, arm, arm64, x86_shared, loong64, riscv64);
866 +
867 + // Perform an integer division, returning the integer part rounded toward
868 + // zero. rhs must not be zero, and the division must not overflow. The
869 +@@ -1173,7 +1181,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
870 + void flexibleDivMod32(Register rhs, Register srcDest, Register remOutput,
871 + bool isUnsigned,
872 + const LiveRegisterSet& volatileLiveRegs)
873 +- DEFINED_ON(mips_shared, arm, arm64, x86_shared, loong64);
874 ++ DEFINED_ON(mips_shared, arm, arm64, x86_shared, loong64, riscv64);
875 +
876 + inline void divFloat32(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH;
877 + inline void divDouble(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH;
878 +@@ -1380,7 +1388,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
879 +
880 + template <typename T1, typename T2>
881 + inline void cmp32Set(Condition cond, T1 lhs, T2 rhs, Register dest)
882 +- DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64);
883 ++ DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64, riscv64);
884 +
885 + // Only the NotEqual and Equal conditions are allowed.
886 + inline void cmp64Set(Condition cond, Address lhs, Imm64 rhs,
887 +@@ -1415,10 +1423,10 @@ class MacroAssembler : public MacroAssemblerSpecific {
888 +
889 + inline void branch32(Condition cond, const AbsoluteAddress& lhs, Register rhs,
890 + Label* label)
891 +- DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64);
892 ++ DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64);
893 + inline void branch32(Condition cond, const AbsoluteAddress& lhs, Imm32 rhs,
894 + Label* label)
895 +- DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64);
896 ++ DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64);
897 +
898 + inline void branch32(Condition cond, const BaseIndex& lhs, Register rhs,
899 + Label* label) DEFINED_ON(arm, x86_shared);
900 +@@ -1432,7 +1440,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
901 +
902 + inline void branch32(Condition cond, wasm::SymbolicAddress lhs, Imm32 rhs,
903 + Label* label)
904 +- DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64);
905 ++ DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64);
906 +
907 + // The supported condition are Equal, NotEqual, LessThan(orEqual),
908 + // GreaterThan(orEqual), Below(orEqual) and Above(orEqual). When a fail label
909 +@@ -1483,14 +1491,14 @@ class MacroAssembler : public MacroAssemblerSpecific {
910 +
911 + inline void branchPtr(Condition cond, const AbsoluteAddress& lhs,
912 + Register rhs, Label* label)
913 +- DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64);
914 ++ DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64);
915 + inline void branchPtr(Condition cond, const AbsoluteAddress& lhs, ImmWord rhs,
916 + Label* label)
917 +- DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64);
918 ++ DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64);
919 +
920 + inline void branchPtr(Condition cond, wasm::SymbolicAddress lhs, Register rhs,
921 + Label* label)
922 +- DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64);
923 ++ DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64);
924 +
925 + // Given a pointer to a GC Cell, retrieve the StoreBuffer pointer from its
926 + // chunk header, or nullptr if it is in the tenured heap.
927 +@@ -1498,7 +1506,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
928 +
929 + void branchPtrInNurseryChunk(Condition cond, Register ptr, Register temp,
930 + Label* label)
931 +- DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64);
932 ++ DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64);
933 + void branchPtrInNurseryChunk(Condition cond, const Address& address,
934 + Register temp, Label* label) DEFINED_ON(x86);
935 + void branchValueIsNurseryCell(Condition cond, const Address& address,
936 +@@ -1520,10 +1528,10 @@ class MacroAssembler : public MacroAssemblerSpecific {
937 + // x64 variants will do this only in the int64_t range.
938 + inline void branchTruncateFloat32MaybeModUint32(FloatRegister src,
939 + Register dest, Label* fail)
940 +- DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64);
941 ++ DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64);
942 + inline void branchTruncateDoubleMaybeModUint32(FloatRegister src,
943 + Register dest, Label* fail)
944 +- DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64);
945 ++ DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64);
946 +
947 + // Truncate a double/float32 to intptr and when it doesn't fit jump to the
948 + // failure label.
949 +@@ -1536,10 +1544,10 @@ class MacroAssembler : public MacroAssemblerSpecific {
950 + // failure label.
951 + inline void branchTruncateFloat32ToInt32(FloatRegister src, Register dest,
952 + Label* fail)
953 +- DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64);
954 ++ DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64);
955 + inline void branchTruncateDoubleToInt32(FloatRegister src, Register dest,
956 + Label* fail)
957 +- DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64);
958 ++ DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64);
959 +
960 + inline void branchDouble(DoubleCondition cond, FloatRegister lhs,
961 + FloatRegister rhs, Label* label) PER_SHARED_ARCH;
962 +@@ -1596,7 +1604,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
963 + Label* label) PER_SHARED_ARCH;
964 + inline void branchTest32(Condition cond, const AbsoluteAddress& lhs,
965 + Imm32 rhs, Label* label)
966 +- DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64);
967 ++ DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64);
968 +
969 + template <class L>
970 + inline void branchTestPtr(Condition cond, Register lhs, Register rhs,
971 +@@ -1757,7 +1765,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
972 + inline void branchTestInt32(Condition cond, Register tag,
973 + Label* label) PER_SHARED_ARCH;
974 + inline void branchTestDouble(Condition cond, Register tag, Label* label)
975 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
976 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
977 + inline void branchTestNumber(Condition cond, Register tag,
978 + Label* label) PER_SHARED_ARCH;
979 + inline void branchTestBoolean(Condition cond, Register tag,
980 +@@ -1789,7 +1797,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
981 + Label* label) PER_SHARED_ARCH;
982 + inline void branchTestUndefined(Condition cond, const ValueOperand& value,
983 + Label* label)
984 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
985 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
986 +
987 + inline void branchTestInt32(Condition cond, const Address& address,
988 + Label* label) PER_SHARED_ARCH;
989 +@@ -1797,7 +1805,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
990 + Label* label) PER_SHARED_ARCH;
991 + inline void branchTestInt32(Condition cond, const ValueOperand& value,
992 + Label* label)
993 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
994 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
995 +
996 + inline void branchTestDouble(Condition cond, const Address& address,
997 + Label* label) PER_SHARED_ARCH;
998 +@@ -1805,11 +1813,11 @@ class MacroAssembler : public MacroAssemblerSpecific {
999 + Label* label) PER_SHARED_ARCH;
1000 + inline void branchTestDouble(Condition cond, const ValueOperand& value,
1001 + Label* label)
1002 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
1003 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
1004 +
1005 + inline void branchTestNumber(Condition cond, const ValueOperand& value,
1006 + Label* label)
1007 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
1008 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
1009 +
1010 + inline void branchTestBoolean(Condition cond, const Address& address,
1011 + Label* label) PER_SHARED_ARCH;
1012 +@@ -1817,7 +1825,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
1013 + Label* label) PER_SHARED_ARCH;
1014 + inline void branchTestBoolean(Condition cond, const ValueOperand& value,
1015 + Label* label)
1016 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
1017 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
1018 +
1019 + inline void branchTestString(Condition cond, const Address& address,
1020 + Label* label) PER_SHARED_ARCH;
1021 +@@ -1825,7 +1833,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
1022 + Label* label) PER_SHARED_ARCH;
1023 + inline void branchTestString(Condition cond, const ValueOperand& value,
1024 + Label* label)
1025 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
1026 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
1027 +
1028 + inline void branchTestSymbol(Condition cond, const Address& address,
1029 + Label* label) PER_SHARED_ARCH;
1030 +@@ -1833,7 +1841,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
1031 + Label* label) PER_SHARED_ARCH;
1032 + inline void branchTestSymbol(Condition cond, const ValueOperand& value,
1033 + Label* label)
1034 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
1035 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
1036 +
1037 + inline void branchTestBigInt(Condition cond, const Address& address,
1038 + Label* label) PER_SHARED_ARCH;
1039 +@@ -1841,7 +1849,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
1040 + Label* label) PER_SHARED_ARCH;
1041 + inline void branchTestBigInt(Condition cond, const ValueOperand& value,
1042 + Label* label)
1043 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
1044 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
1045 +
1046 + inline void branchTestNull(Condition cond, const Address& address,
1047 + Label* label) PER_SHARED_ARCH;
1048 +@@ -1849,7 +1857,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
1049 + Label* label) PER_SHARED_ARCH;
1050 + inline void branchTestNull(Condition cond, const ValueOperand& value,
1051 + Label* label)
1052 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
1053 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
1054 +
1055 + // Clobbers the ScratchReg on x64.
1056 + inline void branchTestObject(Condition cond, const Address& address,
1057 +@@ -1858,7 +1866,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
1058 + Label* label) PER_SHARED_ARCH;
1059 + inline void branchTestObject(Condition cond, const ValueOperand& value,
1060 + Label* label)
1061 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
1062 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
1063 +
1064 + inline void branchTestGCThing(Condition cond, const Address& address,
1065 + Label* label) PER_SHARED_ARCH;
1066 +@@ -1869,7 +1877,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
1067 +
1068 + inline void branchTestPrimitive(Condition cond, const ValueOperand& value,
1069 + Label* label)
1070 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
1071 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
1072 +
1073 + inline void branchTestMagic(Condition cond, const Address& address,
1074 + Label* label) PER_SHARED_ARCH;
1075 +@@ -1878,7 +1886,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
1076 + template <class L>
1077 + inline void branchTestMagic(Condition cond, const ValueOperand& value,
1078 + L label)
1079 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
1080 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
1081 +
1082 + inline void branchTestMagic(Condition cond, const Address& valaddr,
1083 + JSWhyMagic why, Label* label) PER_ARCH;
1084 +@@ -1896,17 +1904,17 @@ class MacroAssembler : public MacroAssemblerSpecific {
1085 + // The type of the value should match the type of the method.
1086 + inline void branchTestInt32Truthy(bool truthy, const ValueOperand& value,
1087 + Label* label)
1088 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
1089 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
1090 + inline void branchTestDoubleTruthy(bool truthy, FloatRegister reg,
1091 + Label* label) PER_SHARED_ARCH;
1092 + inline void branchTestBooleanTruthy(bool truthy, const ValueOperand& value,
1093 + Label* label) PER_ARCH;
1094 + inline void branchTestStringTruthy(bool truthy, const ValueOperand& value,
1095 + Label* label)
1096 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
1097 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
1098 + inline void branchTestBigIntTruthy(bool truthy, const ValueOperand& value,
1099 + Label* label)
1100 +- DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared);
1101 ++ DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64);
1102 +
1103 + // Create an unconditional branch to the address given as argument.
1104 + inline void branchToComputedAddress(const BaseIndex& address) PER_ARCH;
1105 +@@ -2008,11 +2016,11 @@ class MacroAssembler : public MacroAssemblerSpecific {
1106 +
1107 + inline void cmp32Move32(Condition cond, Register lhs, Register rhs,
1108 + Register src, Register dest)
1109 +- DEFINED_ON(arm, arm64, loong64, mips_shared, x86_shared);
1110 ++ DEFINED_ON(arm, arm64, loong64, mips_shared, x86_shared, riscv64);
1111 +
1112 + inline void cmp32Move32(Condition cond, Register lhs, const Address& rhs,
1113 + Register src, Register dest)
1114 +- DEFINED_ON(arm, arm64, loong64, mips_shared, x86_shared);
1115 ++ DEFINED_ON(arm, arm64, loong64, mips_shared, x86_shared, riscv64);
1116 +
1117 + inline void cmpPtrMovePtr(Condition cond, Register lhs, Register rhs,
1118 + Register src, Register dest) PER_ARCH;
1119 +@@ -2022,36 +2030,36 @@ class MacroAssembler : public MacroAssemblerSpecific {
1120 +
1121 + inline void cmp32Load32(Condition cond, Register lhs, const Address& rhs,
1122 + const Address& src, Register dest)
1123 +- DEFINED_ON(arm, arm64, loong64, mips_shared, x86_shared);
1124 ++ DEFINED_ON(arm, arm64, loong64, mips_shared, x86_shared, riscv64);
1125 +
1126 + inline void cmp32Load32(Condition cond, Register lhs, Register rhs,
1127 + const Address& src, Register dest)
1128 +- DEFINED_ON(arm, arm64, loong64, mips_shared, x86_shared);
1129 ++ DEFINED_ON(arm, arm64, loong64, mips_shared, x86_shared, riscv64);
1130 +
1131 + inline void cmp32LoadPtr(Condition cond, const Address& lhs, Imm32 rhs,
1132 + const Address& src, Register dest)
1133 +- DEFINED_ON(arm, arm64, loong64, mips_shared, x86, x64);
1134 ++ DEFINED_ON(arm, arm64, loong64, mips_shared, x86, x64, riscv64);
1135 +
1136 + inline void cmp32MovePtr(Condition cond, Register lhs, Imm32 rhs,
1137 + Register src, Register dest)
1138 +- DEFINED_ON(arm, arm64, loong64, mips_shared, x86, x64);
1139 ++ DEFINED_ON(arm, arm64, loong64, mips_shared, x86, x64, riscv64);
1140 +
1141 + inline void test32LoadPtr(Condition cond, const Address& addr, Imm32 mask,
1142 + const Address& src, Register dest)
1143 +- DEFINED_ON(arm, arm64, loong64, mips_shared, x86, x64);
1144 ++ DEFINED_ON(arm, arm64, loong64, mips_shared, x86, x64, riscv64);
1145 +
1146 + inline void test32MovePtr(Condition cond, const Address& addr, Imm32 mask,
1147 + Register src, Register dest)
1148 +- DEFINED_ON(arm, arm64, loong64, mips_shared, x86, x64);
1149 ++ DEFINED_ON(arm, arm64, loong64, mips_shared, x86, x64, riscv64);
1150 +
1151 + // Conditional move for Spectre mitigations.
1152 + inline void spectreMovePtr(Condition cond, Register src, Register dest)
1153 +- DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64);
1154 ++ DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64);
1155 +
1156 + // Zeroes dest if the condition is true.
1157 + inline void spectreZeroRegister(Condition cond, Register scratch,
1158 + Register dest)
1159 +- DEFINED_ON(arm, arm64, mips_shared, x86_shared, loong64);
1160 ++ DEFINED_ON(arm, arm64, mips_shared, x86_shared, loong64, riscv64);
1161 +
1162 + // Performs a bounds check and zeroes the index register if out-of-bounds
1163 + // (to mitigate Spectre).
1164 +@@ -2063,17 +2071,17 @@ class MacroAssembler : public MacroAssemblerSpecific {
1165 + public:
1166 + inline void spectreBoundsCheck32(Register index, Register length,
1167 + Register maybeScratch, Label* failure)
1168 +- DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64);
1169 ++ DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64);
1170 + inline void spectreBoundsCheck32(Register index, const Address& length,
1171 + Register maybeScratch, Label* failure)
1172 +- DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64);
1173 ++ DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64);
1174 +
1175 + inline void spectreBoundsCheckPtr(Register index, Register length,
1176 + Register maybeScratch, Label* failure)
1177 +- DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64);
1178 ++ DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64);
1179 + inline void spectreBoundsCheckPtr(Register index, const Address& length,
1180 + Register maybeScratch, Label* failure)
1181 +- DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64);
1182 ++ DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64);
1183 +
1184 + // ========================================================================
1185 + // Canonicalization primitives.
1186 +@@ -2087,10 +2095,10 @@ class MacroAssembler : public MacroAssemblerSpecific {
1187 + // ========================================================================
1188 + // Memory access primitives.
1189 + inline void storeUncanonicalizedDouble(FloatRegister src, const Address& dest)
1190 +- DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64);
1191 ++ DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64, riscv64);
1192 + inline void storeUncanonicalizedDouble(FloatRegister src,
1193 + const BaseIndex& dest)
1194 +- DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64);
1195 ++ DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64, riscv64);
1196 + inline void storeUncanonicalizedDouble(FloatRegister src, const Operand& dest)
1197 + DEFINED_ON(x86_shared);
1198 +
1199 +@@ -2104,10 +2112,10 @@ class MacroAssembler : public MacroAssemblerSpecific {
1200 +
1201 + inline void storeUncanonicalizedFloat32(FloatRegister src,
1202 + const Address& dest)
1203 +- DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64);
1204 ++ DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64, riscv64);
1205 + inline void storeUncanonicalizedFloat32(FloatRegister src,
1206 + const BaseIndex& dest)
1207 +- DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64);
1208 ++ DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64, riscv64);
1209 + inline void storeUncanonicalizedFloat32(FloatRegister src,
1210 + const Operand& dest)
1211 + DEFINED_ON(x86_shared);
1212 +@@ -3508,10 +3516,10 @@ class MacroAssembler : public MacroAssemblerSpecific {
1213 +
1214 + // temp required on x86 and x64; must be undefined on mips64 and loong64.
1215 + void convertUInt64ToFloat32(Register64 src, FloatRegister dest, Register temp)
1216 +- DEFINED_ON(arm64, mips64, loong64, x64, x86);
1217 ++ DEFINED_ON(arm64, mips64, loong64, x64, x86, riscv64);
1218 +
1219 + void convertInt64ToFloat32(Register64 src, FloatRegister dest)
1220 +- DEFINED_ON(arm64, mips64, loong64, x64, x86);
1221 ++ DEFINED_ON(arm64, mips64, loong64, x64, x86, riscv64);
1222 +
1223 + bool convertUInt64ToDoubleNeedsTemp() PER_ARCH;
1224 +
1225 +@@ -3563,19 +3571,19 @@ class MacroAssembler : public MacroAssemblerSpecific {
1226 +
1227 + void wasmBoundsCheck32(Condition cond, Register index,
1228 + Register boundsCheckLimit, Label* ok)
1229 +- DEFINED_ON(arm, arm64, mips32, mips64, x86_shared, loong64);
1230 ++ DEFINED_ON(arm, arm64, mips32, mips64, x86_shared, loong64, riscv64);
1231 +
1232 + void wasmBoundsCheck32(Condition cond, Register index,
1233 + Address boundsCheckLimit, Label* ok)
1234 +- DEFINED_ON(arm, arm64, mips32, mips64, x86_shared, loong64);
1235 ++ DEFINED_ON(arm, arm64, mips32, mips64, x86_shared, loong64, riscv64);
1236 +
1237 + void wasmBoundsCheck64(Condition cond, Register64 index,
1238 + Register64 boundsCheckLimit, Label* ok)
1239 +- DEFINED_ON(arm64, mips64, x64, x86, arm, loong64);
1240 ++ DEFINED_ON(arm64, mips64, x64, x86, arm, loong64, riscv64);
1241 +
1242 + void wasmBoundsCheck64(Condition cond, Register64 index,
1243 + Address boundsCheckLimit, Label* ok)
1244 +- DEFINED_ON(arm64, mips64, x64, x86, arm, loong64);
1245 ++ DEFINED_ON(arm64, mips64, x64, x86, arm, loong64, riscv64);
1246 +
1247 + // Each wasm load/store instruction appends its own wasm::Trap::OutOfBounds.
1248 + void wasmLoad(const wasm::MemoryAccessDesc& access, Operand srcAddr,
1249 +@@ -3668,7 +3676,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
1250 + void oolWasmTruncateCheckF64ToI32(FloatRegister input, Register output,
1251 + TruncFlags flags, wasm::BytecodeOffset off,
1252 + Label* rejoin)
1253 +- DEFINED_ON(arm, arm64, x86_shared, mips_shared, loong64);
1254 ++ DEFINED_ON(arm, arm64, x86_shared, mips_shared, loong64, riscv64);
1255 +
1256 + void wasmTruncateFloat32ToUInt32(FloatRegister input, Register output,
1257 + bool isSaturating, Label* oolEntry) PER_ARCH;
1258 +@@ -3678,35 +3686,35 @@ class MacroAssembler : public MacroAssemblerSpecific {
1259 + void oolWasmTruncateCheckF32ToI32(FloatRegister input, Register output,
1260 + TruncFlags flags, wasm::BytecodeOffset off,
1261 + Label* rejoin)
1262 +- DEFINED_ON(arm, arm64, x86_shared, mips_shared, loong64);
1263 ++ DEFINED_ON(arm, arm64, x86_shared, mips_shared, loong64, riscv64);
1264 +
1265 + // The truncate-to-int64 methods will always bind the `oolRejoin` label
1266 + // after the last emitted instruction.
1267 + void wasmTruncateDoubleToInt64(FloatRegister input, Register64 output,
1268 + bool isSaturating, Label* oolEntry,
1269 + Label* oolRejoin, FloatRegister tempDouble)
1270 +- DEFINED_ON(arm64, x86, x64, mips64, loong64);
1271 ++ DEFINED_ON(arm64, x86, x64, mips64, loong64, riscv64);
1272 + void wasmTruncateDoubleToUInt64(FloatRegister input, Register64 output,
1273 + bool isSaturating, Label* oolEntry,
1274 + Label* oolRejoin, FloatRegister tempDouble)
1275 +- DEFINED_ON(arm64, x86, x64, mips64, loong64);
1276 ++ DEFINED_ON(arm64, x86, x64, mips64, loong64, riscv64);
1277 + void oolWasmTruncateCheckF64ToI64(FloatRegister input, Register64 output,
1278 + TruncFlags flags, wasm::BytecodeOffset off,
1279 + Label* rejoin)
1280 +- DEFINED_ON(arm, arm64, x86_shared, mips_shared, loong64);
1281 ++ DEFINED_ON(arm, arm64, x86_shared, mips_shared, loong64, riscv64);
1282 +
1283 + void wasmTruncateFloat32ToInt64(FloatRegister input, Register64 output,
1284 + bool isSaturating, Label* oolEntry,
1285 + Label* oolRejoin, FloatRegister tempDouble)
1286 +- DEFINED_ON(arm64, x86, x64, mips64, loong64);
1287 ++ DEFINED_ON(arm64, x86, x64, mips64, loong64, riscv64);
1288 + void wasmTruncateFloat32ToUInt64(FloatRegister input, Register64 output,
1289 + bool isSaturating, Label* oolEntry,
1290 + Label* oolRejoin, FloatRegister tempDouble)
1291 +- DEFINED_ON(arm64, x86, x64, mips64, loong64);
1292 ++ DEFINED_ON(arm64, x86, x64, mips64, loong64, riscv64);
1293 + void oolWasmTruncateCheckF32ToI64(FloatRegister input, Register64 output,
1294 + TruncFlags flags, wasm::BytecodeOffset off,
1295 + Label* rejoin)
1296 +- DEFINED_ON(arm, arm64, x86_shared, mips_shared, loong64);
1297 ++ DEFINED_ON(arm, arm64, x86_shared, mips_shared, loong64, riscv64);
1298 +
1299 + void loadWasmGlobalPtr(uint32_t globalDataOffset, Register dest);
1300 +
1301 +@@ -3764,7 +3772,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
1302 + // convention, which requires predictable high bits. In practice, this means
1303 + // that the 32-bit value will be zero-extended or sign-extended to 64 bits as
1304 + // appropriate for the platform.
1305 +- void widenInt32(Register r) DEFINED_ON(arm64, x64, mips64, loong64);
1306 ++ void widenInt32(Register r) DEFINED_ON(arm64, x64, mips64, loong64, riscv64);
1307 +
1308 + // As enterFakeExitFrame(), but using register conventions appropriate for
1309 + // wasm stubs.
1310 +@@ -5006,7 +5014,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
1311 + inline void addStackPtrTo(T t);
1312 +
1313 + void subFromStackPtr(Imm32 imm32)
1314 +- DEFINED_ON(mips32, mips64, loong64, arm, x86, x64);
1315 ++ DEFINED_ON(mips32, mips64, loong64, arm, x86, x64, riscv64);
1316 + void subFromStackPtr(Register reg);
1317 +
1318 + template <typename T>
1319 +diff --git a/js/src/jit/MoveEmitter.h b/js/src/jit/MoveEmitter.h
1320 +index a51cbc100a..ea4d92bedc 100644
1321 +--- a/js/src/jit/MoveEmitter.h
1322 ++++ b/js/src/jit/MoveEmitter.h
1323 +@@ -17,6 +17,8 @@
1324 + # include "jit/mips32/MoveEmitter-mips32.h"
1325 + #elif defined(JS_CODEGEN_MIPS64)
1326 + # include "jit/mips64/MoveEmitter-mips64.h"
1327 ++#elif defined(JS_CODEGEN_RISCV64)
1328 ++# include "jit/riscv64/MoveEmitter-riscv64.h"
1329 + #elif defined(JS_CODEGEN_LOONG64)
1330 + # include "jit/loong64/MoveEmitter-loong64.h"
1331 + #elif defined(JS_CODEGEN_NONE)
1332 +diff --git a/js/src/jit/Registers.h b/js/src/jit/Registers.h
1333 +index 2c1cec0771..baf0630e07 100644
1334 +--- a/js/src/jit/Registers.h
1335 ++++ b/js/src/jit/Registers.h
1336 +@@ -20,6 +20,8 @@
1337 + # include "jit/mips32/Architecture-mips32.h"
1338 + #elif defined(JS_CODEGEN_MIPS64)
1339 + # include "jit/mips64/Architecture-mips64.h"
1340 ++#elif defined(JS_CODEGEN_RISCV64)
1341 ++# include "jit/riscv64/Architecture-riscv64.h"
1342 + #elif defined(JS_CODEGEN_LOONG64)
1343 + # include "jit/loong64/Architecture-loong64.h"
1344 + #elif defined(JS_CODEGEN_NONE)
1345 +diff --git a/js/src/jit/SharedICHelpers-inl.h b/js/src/jit/SharedICHelpers-inl.h
1346 +index 60a77956f0..242f5d3f27 100644
1347 +--- a/js/src/jit/SharedICHelpers-inl.h
1348 ++++ b/js/src/jit/SharedICHelpers-inl.h
1349 +@@ -17,6 +17,8 @@
1350 + # include "jit/arm64/SharedICHelpers-arm64-inl.h"
1351 + #elif defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
1352 + # include "jit/mips-shared/SharedICHelpers-mips-shared-inl.h"
1353 ++#elif defined(JS_CODEGEN_RISCV64)
1354 ++# include "jit/riscv64/SharedICHelpers-riscv64-inl.h"
1355 + #elif defined(JS_CODEGEN_LOONG64)
1356 + # include "jit/loong64/SharedICHelpers-loong64-inl.h"
1357 + #elif defined(JS_CODEGEN_NONE)
1358 +diff --git a/js/src/jit/SharedICHelpers.h b/js/src/jit/SharedICHelpers.h
1359 +index da8378ebae..bfe4a1b672 100644
1360 +--- a/js/src/jit/SharedICHelpers.h
1361 ++++ b/js/src/jit/SharedICHelpers.h
1362 +@@ -17,6 +17,8 @@
1363 + # include "jit/arm64/SharedICHelpers-arm64.h"
1364 + #elif defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
1365 + # include "jit/mips-shared/SharedICHelpers-mips-shared.h"
1366 ++#elif defined(JS_CODEGEN_RISCV64)
1367 ++# include "jit/riscv64/SharedICHelpers-riscv64.h"
1368 + #elif defined(JS_CODEGEN_LOONG64)
1369 + # include "jit/loong64/SharedICHelpers-loong64.h"
1370 + #elif defined(JS_CODEGEN_NONE)
1371 +diff --git a/js/src/jit/SharedICRegisters.h b/js/src/jit/SharedICRegisters.h
1372 +index e29f21c28d..4091d9f595 100644
1373 +--- a/js/src/jit/SharedICRegisters.h
1374 ++++ b/js/src/jit/SharedICRegisters.h
1375 +@@ -19,6 +19,8 @@
1376 + # include "jit/mips32/SharedICRegisters-mips32.h"
1377 + #elif defined(JS_CODEGEN_MIPS64)
1378 + # include "jit/mips64/SharedICRegisters-mips64.h"
1379 ++#elif defined(JS_CODEGEN_RISCV64)
1380 ++# include "jit/riscv64/SharedICRegisters-riscv64.h"
1381 + #elif defined(JS_CODEGEN_LOONG64)
1382 + # include "jit/loong64/SharedICRegisters-loong64.h"
1383 + #elif defined(JS_CODEGEN_NONE)
1384 +diff --git a/js/src/jit/moz.build b/js/src/jit/moz.build
1385 +index 967146e32f..1519351bbb 100644
1386 +--- a/js/src/jit/moz.build
1387 ++++ b/js/src/jit/moz.build
1388 +@@ -212,6 +212,13 @@ elif CONFIG["JS_CODEGEN_MIPS32"] or CONFIG["JS_CODEGEN_MIPS64"]:
1389 + ]
1390 + if CONFIG["JS_SIMULATOR_MIPS64"]:
1391 + UNIFIED_SOURCES += ["mips64/Simulator-mips64.cpp"]
1392 ++elif CONFIG["JS_CODEGEN_RISCV64"]:
1393 ++ UNIFIED_SOURCES += [
1394 ++ "riscv64/Assembler-riscv64.cpp",
1395 ++ "riscv64/Trampoline-riscv64.cpp",
1396 ++ ]
1397 ++ if CONFIG["JS_SIMULATOR_RISC64"]:
1398 ++ UNIFIED_SOURCES += ["riscv64/Simulator-riscv64.cpp"]
1399 + elif CONFIG["JS_CODEGEN_LOONG64"]:
1400 + UNIFIED_SOURCES += [
1401 + "loong64/Architecture-loong64.cpp",
1402 +@@ -225,7 +232,6 @@ elif CONFIG["JS_CODEGEN_LOONG64"]:
1403 + if CONFIG["JS_SIMULATOR_LOONG64"]:
1404 + UNIFIED_SOURCES += ["loong64/Simulator-loong64.cpp"]
1405 +
1406 +-
1407 + # Generate jit/MIROpsGenerated.h from jit/MIROps.yaml
1408 + GeneratedFile(
1409 + "MIROpsGenerated.h",
1410 +diff --git a/js/src/jit/riscv64/Architecture-riscv64.h b/js/src/jit/riscv64/Architecture-riscv64.h
1411 +new file mode 100644
1412 +index 0000000000..a676dc142e
1413 +--- /dev/null
1414 ++++ b/js/src/jit/riscv64/Architecture-riscv64.h
1415 +@@ -0,0 +1,404 @@
1416 ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
1417 ++ * vim: set ts=8 sts=2 et sw=2 tw=80:
1418 ++ * This Source Code Form is subject to the terms of the Mozilla Public
1419 ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
1420 ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
1421 ++
1422 ++#ifndef jit_riscv64_Architecture_riscv64_h
1423 ++#define jit_riscv64_Architecture_riscv64_h
1424 ++
1425 ++// JitSpewer.h is included through MacroAssembler implementations for other
1426 ++// platforms, so include it here to avoid inadvertent build bustage.
1427 ++#include "jit/JitSpewer.h"
1428 ++
1429 ++#include "jit/shared/Architecture-shared.h"
1430 ++
1431 ++namespace js {
1432 ++namespace jit {
1433 ++
1434 ++static const uint32_t SimdMemoryAlignment =
1435 ++ 4; // Make it 4 to avoid a bunch of div-by-zero warnings
1436 ++static const uint32_t WasmStackAlignment = 8;
1437 ++static const uint32_t WasmTrapInstructionLength = 0;
1438 ++
1439 ++// See comments in wasm::GenerateFunctionPrologue.
1440 ++static constexpr uint32_t WasmCheckedCallEntryOffset = 0u;
1441 ++static constexpr uint32_t WasmCheckedTailEntryOffset = 1u;
1442 ++
1443 ++class Registers {
1444 ++ public:
1445 ++ enum RegisterID {
1446 ++ x0 = 0,
1447 ++ zero = 0,
1448 ++ x1 = 1,
1449 ++ ra = 1,
1450 ++ x2 = 2,
1451 ++ sp = 2,
1452 ++ x3 = 3,
1453 ++ gp = 3,
1454 ++ x4 = 4,
1455 ++ tp = 4,
1456 ++ x5 = 5,
1457 ++ t0 = 5,
1458 ++ x6 = 6,
1459 ++ t1 = 6,
1460 ++ x7 = 7,
1461 ++ t2 = 7,
1462 ++ x8 = 8,
1463 ++ fp = 8,
1464 ++ s0 = 8,
1465 ++ x9 = 9,
1466 ++ s1 = 9,
1467 ++ x10 = 10,
1468 ++ a0 = 10,
1469 ++ x11 = 11,
1470 ++ a1 = 11,
1471 ++ x12 = 12,
1472 ++ a2 = 12,
1473 ++ x13 = 13,
1474 ++ a3 = 13,
1475 ++ x14 = 14,
1476 ++ a4 = 14,
1477 ++ x15 = 15,
1478 ++ a5 = 15,
1479 ++ x16 = 16,
1480 ++ a6 = 16,
1481 ++ x17 = 17,
1482 ++ a7 = 17,
1483 ++ x18 = 18,
1484 ++ s2 = 18,
1485 ++ x19 = 19,
1486 ++ s3 = 19,
1487 ++ x20 = 20,
1488 ++ s4 = 20,
1489 ++ x21 = 21,
1490 ++ s5 = 21,
1491 ++ x22 = 22,
1492 ++ s6 = 22,
1493 ++ x23 = 23,
1494 ++ s7 = 23,
1495 ++ x24 = 24,
1496 ++ s8 = 24,
1497 ++ x25 = 25,
1498 ++ s9 = 25,
1499 ++ x26 = 26,
1500 ++ s10 = 26,
1501 ++ x27 = 27,
1502 ++ s11 = 27,
1503 ++ x28 = 28,
1504 ++ t3 = 28,
1505 ++ x29 = 29,
1506 ++ t4 = 29,
1507 ++ x30 = 30,
1508 ++ t5 = 30,
1509 ++ x31 = 31,
1510 ++ t6 = 31,
1511 ++ invalid_reg
1512 ++ };
1513 ++ typedef uint8_t Code;
1514 ++ typedef RegisterID Encoding;
1515 ++ union RegisterContent {
1516 ++ uintptr_t r;
1517 ++ };
1518 ++
1519 ++ typedef uint32_t SetType;
1520 ++
1521 ++ static uint32_t SetSize(SetType x) {
1522 ++ static_assert(sizeof(SetType) == 4, "SetType must be 32 bits");
1523 ++ return mozilla::CountPopulation32(x);
1524 ++ }
1525 ++ static uint32_t FirstBit(SetType x) {
1526 ++ return mozilla::CountTrailingZeroes32(x);
1527 ++ }
1528 ++ static uint32_t LastBit(SetType x) {
1529 ++ return 31 - mozilla::CountLeadingZeroes32(x);
1530 ++ }
1531 ++
1532 ++ static const char* GetName(uint32_t code) {
1533 ++ // clang-format off
1534 ++ static const char* const Names[] = {
1535 ++ "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2",
1536 ++ "fp", "s1", "a0", "a1", "a2", "a3", "a4", "a5",
1537 ++ "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7",
1538 ++ "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6"};
1539 ++ // clang-format on
1540 ++ static_assert(Total == sizeof(Names) / sizeof(Names[0]),
1541 ++ "Table is the correct size");
1542 ++ if (code >= Total) {
1543 ++ return "invalid";
1544 ++ }
1545 ++ return Names[code];
1546 ++ }
1547 ++
1548 ++ static Code FromName(const char* name) {
1549 ++ for (size_t i = 0; i < Total; i++) {
1550 ++ if (strcmp(GetName(Code(i)), name) == 0) {
1551 ++ return Code(i);
1552 ++ }
1553 ++ }
1554 ++ return Invalid;
1555 ++ }
1556 ++
1557 ++ static const Encoding StackPointer = sp;
1558 ++ static const Encoding Invalid = invalid_reg;
1559 ++ static const uint32_t Total = 32;
1560 ++ static const uint32_t TotalPhys = 32;
1561 ++ static const uint32_t Allocatable = 28;
1562 ++ static const SetType AllMask = 0xffffffff;
1563 ++ static const SetType ArgRegMask =
1564 ++ (1 << Registers::a0) | (1 << Registers::a1) | (1 << Registers::a2) |
1565 ++ (1 << Registers::a3) | (1 << Registers::a4) | (1 << Registers::a5) |
1566 ++ (1 << Registers::a6) | (1 << Registers::a7);
1567 ++ static const SetType VolatileMask =
1568 ++ (1 << Registers::a0) | (1 << Registers::a1) | (1 << Registers::a2) |
1569 ++ (1 << Registers::a3) | (1 << Registers::a4) | (1 << Registers::a5) |
1570 ++ (1 << Registers::a6) | (1 << Registers::a7) | (1 << Registers::t0) |
1571 ++ (1 << Registers::t1) | (1 << Registers::t2) | (1 << Registers::t3) |
1572 ++ (1 << Registers::t4) | (1 << Registers::t5) | (1 << Registers::t6);
1573 ++ static const SetType NonVolatileMask =
1574 ++ (1 << Registers::s0) | (1 << Registers::s1) | (1 << Registers::s2) |
1575 ++ (1 << Registers::s3) | (1 << Registers::s4) | (1 << Registers::s5) |
1576 ++ (1 << Registers::s6) | (1 << Registers::s7) | (1 << Registers::s8) |
1577 ++ (1 << Registers::s9) | (1 << Registers::s10) | (1 << Registers::s11);
1578 ++ static const SetType NonAllocatableMask =
1579 ++ (1 << Registers::zero) | (1 << Registers::sp) | (1 << Registers::tp) |
1580 ++ (1 << Registers::gp);
1581 ++ static const SetType AllocatableMask = AllMask & ~NonAllocatableMask;
1582 ++ static const SetType JSCallMask = 0;
1583 ++ static const SetType CallMask = 0;
1584 ++};
1585 ++
1586 ++typedef uint8_t PackedRegisterMask;
1587 ++
1588 ++class FloatRegisters {
1589 ++ public:
1590 ++ enum FPRegisterID {
1591 ++ f0 = 0,
1592 ++ ft0 = 0,
1593 ++ f1 = 1,
1594 ++ ft1 = 1,
1595 ++ f2 = 2,
1596 ++ ft2 = 2,
1597 ++ f3 = 3,
1598 ++ ft3 = 3,
1599 ++ f4 = 4,
1600 ++ ft4 = 4,
1601 ++ f5 = 5,
1602 ++ ft5 = 5,
1603 ++ f6 = 6,
1604 ++ ft6 = 6,
1605 ++ f7 = 7,
1606 ++ ft7 = 7,
1607 ++ f8 = 8,
1608 ++ fs0 = 8,
1609 ++ f9 = 9,
1610 ++ fs1 = 9,
1611 ++ f10 = 10,
1612 ++ fa0 = 10,
1613 ++ f11 = 11,
1614 ++ fa1 = 11,
1615 ++ f12 = 12,
1616 ++ fa2 = 12,
1617 ++ f13 = 13,
1618 ++ fa3 = 13,
1619 ++ f14 = 14,
1620 ++ fa4 = 14,
1621 ++ f15 = 15,
1622 ++ fa5 = 15,
1623 ++ f16 = 16,
1624 ++ fa6 = 16,
1625 ++ f17 = 17,
1626 ++ fa7 = 17,
1627 ++ f18 = 18,
1628 ++ fs2 = 18,
1629 ++ f19 = 19,
1630 ++ fs3 = 19,
1631 ++ f20 = 20,
1632 ++ fs4 = 20,
1633 ++ f21 = 21,
1634 ++ fs5 = 21,
1635 ++ f22 = 22,
1636 ++ fs6 = 22,
1637 ++ f23 = 23,
1638 ++ fs7 = 23,
1639 ++ f24 = 24,
1640 ++ fs8 = 24,
1641 ++ f25 = 25,
1642 ++ fs9 = 25,
1643 ++ f26 = 26,
1644 ++ fs10 = 26,
1645 ++ f27 = 27,
1646 ++ fs11 = 27,
1647 ++ f28 = 28,
1648 ++ ft8 = 28,
1649 ++ f29 = 29,
1650 ++ ft9 = 29,
1651 ++ f30 = 30,
1652 ++ ft10 = 30,
1653 ++ f31 = 31,
1654 ++ ft11 = 31,
1655 ++ invalid_reg
1656 ++ };
1657 ++
1658 ++ typedef uint8_t Code;
1659 ++ typedef FPRegisterID Encoding;
1660 ++ typedef uint32_t SetType;
1661 ++
1662 ++ enum Kind : uint8_t { Double, Single };
1663 ++
1664 ++ union RegisterContent {
1665 ++ float s;
1666 ++ double d;
1667 ++ };
1668 ++
1669 ++ static const char* GetName(uint32_t code) {
1670 ++ // clang-format off
1671 ++ static const char* const Names[] = {
1672 ++ "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7",
1673 ++ "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5",
1674 ++ "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7",
1675 ++ "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11",
1676 ++ };
1677 ++ // clang-format on
1678 ++ static_assert(Total == sizeof(Names) / sizeof(Names[0]),
1679 ++ "Table is the correct size");
1680 ++ if (code >= Total) {
1681 ++ return "invalid";
1682 ++ }
1683 ++ return Names[code];
1684 ++ }
1685 ++ static Code FromName(const char* name) {
1686 ++ for (size_t i = 0; i < Total; i++) {
1687 ++ if (strcmp(GetName(i), name) == 0) {
1688 ++ return Code(i);
1689 ++ }
1690 ++ }
1691 ++
1692 ++ return Invalid;
1693 ++ }
1694 ++
1695 ++ static constexpr Encoding encoding(Code c) { return Encoding(c & 31); }
1696 ++
1697 ++ static const Encoding Invalid = invalid_reg;
1698 ++ static const uint32_t Total = 32;
1699 ++ static const uint32_t TotalPhys = 32;
1700 ++ static const uint32_t Allocatable = 32;
1701 ++ static const SetType AllMask = 0xffffffff;
1702 ++ static const SetType AllDoubleMask = 0;
1703 ++ static const SetType AllSingleMask = 0;
1704 ++ static const SetType VolatileMask =
1705 ++ (1 << FloatRegisters::ft0) | (1 << FloatRegisters::ft1) |
1706 ++ (1 << FloatRegisters::ft2) | (1 << FloatRegisters::ft3) |
1707 ++ (1 << FloatRegisters::ft4) | (1 << FloatRegisters::ft5) |
1708 ++ (1 << FloatRegisters::ft6) | (1 << FloatRegisters::ft7) |
1709 ++ (1 << FloatRegisters::ft8) | (1 << FloatRegisters::ft9) |
1710 ++ (1 << FloatRegisters::ft10) | (1 << FloatRegisters::ft11) |
1711 ++ (1 << FloatRegisters::fa0) | (1 << FloatRegisters::fa1) |
1712 ++ (1 << FloatRegisters::fa2) | (1 << FloatRegisters::fa3) |
1713 ++ (1 << FloatRegisters::fa4) | (1 << FloatRegisters::fa5) |
1714 ++ (1 << FloatRegisters::fa6) | (1 << FloatRegisters::fa7);
1715 ++ static const SetType NonVolatileMask =
1716 ++ (1 << FloatRegisters::fs0) | (1 << FloatRegisters::fs1) |
1717 ++ (1 << FloatRegisters::fs2) | (1 << FloatRegisters::fs3) |
1718 ++ (1 << FloatRegisters::fs4) | (1 << FloatRegisters::fs5) |
1719 ++ (1 << FloatRegisters::fs6) | (1 << FloatRegisters::fs7) |
1720 ++ (1 << FloatRegisters::fs8) | (1 << FloatRegisters::fs9) |
1721 ++ (1 << FloatRegisters::fs10) | (1 << FloatRegisters::fs11);
1722 ++ static const SetType NonAllocatableMask = 0;
1723 ++ static const SetType AllocatableMask = AllMask & ~NonAllocatableMask;
1724 ++};
1725 ++
1726 ++template <typename T>
1727 ++class TypedRegisterSet;
1728 ++
1729 ++struct FloatRegister {
1730 ++ typedef FloatRegisters Codes;
1731 ++ typedef size_t Code;
1732 ++ typedef Codes::Encoding Encoding;
1733 ++ typedef Codes::SetType SetType;
1734 ++ typedef Codes::Kind Kind;
1735 ++
1736 ++ private:
1737 ++ uint8_t encoding_;
1738 ++ uint8_t kind_;
1739 ++ bool invalid_;
1740 ++
1741 ++ public:
1742 ++ constexpr FloatRegister(Encoding encoding)
1743 ++ : encoding_(encoding), kind_(FloatRegisters::Double), invalid_(false) {}
1744 ++ constexpr FloatRegister(Encoding encoding, Kind kind)
1745 ++ : encoding_(encoding), kind_(kind), invalid_(false) {}
1746 ++ constexpr FloatRegister()
1747 ++ : encoding_(0), kind_(FloatRegisters::Double), invalid_(true) {}
1748 ++
1749 ++ static uint32_t FirstBit(SetType) { MOZ_CRASH(); }
1750 ++ static uint32_t LastBit(SetType) { MOZ_CRASH(); }
1751 ++ static FloatRegister FromCode(uint32_t i) {
1752 ++ return FloatRegister(FloatRegisters::encoding(i), FloatRegisters::Double);
1753 ++ }
1754 ++ bool isSingle() const { return kind_ == FloatRegisters::Single; }
1755 ++ bool isDouble() const { return kind_ == FloatRegisters::Double; }
1756 ++ bool isSimd128() const { return false; }
1757 ++ bool isInvalid() const { return invalid_; }
1758 ++ FloatRegister asSingle() const { MOZ_CRASH(); }
1759 ++ FloatRegister asDouble() const { MOZ_CRASH(); }
1760 ++ FloatRegister asSimd128() const { MOZ_CRASH(); }
1761 ++ Code code() const { MOZ_CRASH(); }
1762 ++ Encoding encoding() const { return Encoding(encoding_); }
1763 ++ const char* name() const { return FloatRegisters::GetName(code()); }
1764 ++ bool volatile_() const { MOZ_CRASH(); }
1765 ++ bool operator!=(FloatRegister) const { MOZ_CRASH(); }
1766 ++ bool operator==(FloatRegister) const { MOZ_CRASH(); }
1767 ++ bool aliases(FloatRegister) const { MOZ_CRASH(); }
1768 ++ uint32_t numAliased() const { MOZ_CRASH(); }
1769 ++ FloatRegister aliased(uint32_t) { MOZ_CRASH(); }
1770 ++ bool equiv(FloatRegister) const { MOZ_CRASH(); }
1771 ++ uint32_t size() const { MOZ_CRASH(); }
1772 ++ uint32_t numAlignedAliased() const { MOZ_CRASH(); }
1773 ++ FloatRegister alignedAliased(uint32_t) { MOZ_CRASH(); }
1774 ++ SetType alignedOrDominatedAliasedSet() const { MOZ_CRASH(); }
1775 ++
1776 ++ static constexpr RegTypeName DefaultType = RegTypeName::Float64;
1777 ++
1778 ++ template <RegTypeName = DefaultType>
1779 ++ static SetType LiveAsIndexableSet(SetType s) {
1780 ++ return SetType(0);
1781 ++ }
1782 ++
1783 ++ template <RegTypeName Name = DefaultType>
1784 ++ static SetType AllocatableAsIndexableSet(SetType s) {
1785 ++ static_assert(Name != RegTypeName::Any, "Allocatable set are not iterable");
1786 ++ return SetType(0);
1787 ++ }
1788 ++
1789 ++ template <typename T>
1790 ++ static T ReduceSetForPush(T) {
1791 ++ MOZ_CRASH();
1792 ++ }
1793 ++ uint32_t getRegisterDumpOffsetInBytes() {
1794 ++ MOZ_CRASH();
1795 ++ return 0;
1796 ++ }
1797 ++ static uint32_t SetSize(SetType x) {
1798 ++ MOZ_CRASH();
1799 ++ return 0;
1800 ++ }
1801 ++ static Code FromName(const char* name) { return 0; }
1802 ++
1803 ++ // This is used in static initializers, so produce a bogus value instead of
1804 ++ // crashing.
1805 ++ static uint32_t GetPushSizeInBytes(const TypedRegisterSet<FloatRegister>&) {
1806 ++ return 0;
1807 ++ }
1808 ++};
1809 ++
1810 ++inline bool hasUnaliasedDouble() { MOZ_CRASH(); }
1811 ++inline bool hasMultiAlias() { MOZ_CRASH(); }
1812 ++
1813 ++static const uint32_t ShadowStackSpace = 0;
1814 ++static const uint32_t JumpImmediateRange = INT32_MAX;
1815 ++
1816 ++} // namespace jit
1817 ++} // namespace js
1818 ++
1819 ++#endif /* jit_riscv64_Architecture_riscv64_h */
1820 +diff --git a/js/src/jit/riscv64/Assembler-riscv64.cpp b/js/src/jit/riscv64/Assembler-riscv64.cpp
1821 +new file mode 100644
1822 +index 0000000000..90fa6d87a8
1823 +--- /dev/null
1824 ++++ b/js/src/jit/riscv64/Assembler-riscv64.cpp
1825 +@@ -0,0 +1,47 @@
1826 ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
1827 ++ * vim: set ts=8 sts=2 et sw=2 tw=80:
1828 ++ * This Source Code Form is subject to the terms of the Mozilla Public
1829 ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
1830 ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
1831 ++
1832 ++#include "jit/riscv64/Assembler-riscv64.h"
1833 ++
1834 ++using namespace js;
1835 ++using namespace js::jit;
1836 ++
1837 ++ABIArg ABIArgGenerator::next(MIRType type) {
1838 ++ switch (type) {
1839 ++ case MIRType::Int32:
1840 ++ case MIRType::Int64:
1841 ++ case MIRType::Pointer:
1842 ++ case MIRType::RefOrNull:
1843 ++ case MIRType::StackResults:
1844 ++ if (intRegIndex_ == NumIntArgRegs) {
1845 ++ current_ = ABIArg(stackOffset_);
1846 ++ stackOffset_ += sizeof(uintptr_t);
1847 ++ break;
1848 ++ }
1849 ++ current_ = ABIArg(Register::FromCode(intRegIndex_));
1850 ++ intRegIndex_++;
1851 ++ break;
1852 ++
1853 ++ case MIRType::Float32:
1854 ++ case MIRType::Double:
1855 ++ if (floatRegIndex_ == NumFloatArgRegs) {
1856 ++ current_ = ABIArg(stackOffset_);
1857 ++ stackOffset_ += sizeof(double);
1858 ++ break;
1859 ++ }
1860 ++ current_ = ABIArg(FloatRegister(FloatRegisters::Encoding(floatRegIndex_),
1861 ++ type == MIRType::Double
1862 ++ ? FloatRegisters::Double
1863 ++ : FloatRegisters::Single));
1864 ++ floatRegIndex_++;
1865 ++ break;
1866 ++
1867 ++ case MIRType::Simd128:
1868 ++ default:
1869 ++ MOZ_CRASH("Unexpected argument type");
1870 ++ }
1871 ++ return current_;
1872 ++}
1873 +diff --git a/js/src/jit/riscv64/Assembler-riscv64.h b/js/src/jit/riscv64/Assembler-riscv64.h
1874 +new file mode 100644
1875 +index 0000000000..a58e6c4aff
1876 +--- /dev/null
1877 ++++ b/js/src/jit/riscv64/Assembler-riscv64.h
1878 +@@ -0,0 +1,303 @@
1879 ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
1880 ++ * vim: set ts=8 sts=2 et sw=2 tw=80:
1881 ++ * This Source Code Form is subject to the terms of the Mozilla Public
1882 ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
1883 ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
1884 ++
1885 ++#ifndef jit_riscv64_Assembler_riscv64_h
1886 ++#define jit_riscv64_Assembler_riscv64_h
1887 ++
1888 ++#include "mozilla/Sprintf.h"
1889 ++#include <iterator>
1890 ++
1891 ++#include "jit/CompactBuffer.h"
1892 ++#include "jit/JitCode.h"
1893 ++#include "jit/JitSpewer.h"
1894 ++#include "jit/riscv64/Architecture-riscv64.h"
1895 ++#include "jit/shared/Assembler-shared.h"
1896 ++#include "jit/shared/Disassembler-shared.h"
1897 ++#include "jit/shared/IonAssemblerBuffer.h"
1898 ++#include "wasm/WasmTypeDecls.h"
1899 ++
1900 ++namespace js {
1901 ++namespace jit {
1902 ++
1903 ++class MacroAssembler;
1904 ++
1905 ++static constexpr Register t0{Registers::t0};
1906 ++static constexpr Register t1{Registers::t1};
1907 ++static constexpr Register t2{Registers::t2};
1908 ++static constexpr Register t3{Registers::t3};
1909 ++static constexpr Register t4{Registers::t4};
1910 ++static constexpr Register t5{Registers::t5};
1911 ++static constexpr Register t6{Registers::t6};
1912 ++static constexpr Register s0{Registers::s0};
1913 ++static constexpr Register s4{Registers::s4};
1914 ++
1915 ++static constexpr Register StackPointer{Registers::sp};
1916 ++static constexpr Register FramePointer{Registers::fp};
1917 ++static constexpr Register ReturnReg{Registers::a0};
1918 ++static constexpr FloatRegister InvalidFloatReg;
1919 ++static constexpr FloatRegister ReturnFloat32Reg{FloatRegisters::fa0,
1920 ++ FloatRegisters::Single};
1921 ++static constexpr FloatRegister ReturnDoubleReg{FloatRegisters::fa0,
1922 ++ FloatRegisters::Double};
1923 ++static constexpr FloatRegister ReturnSimd128Reg = InvalidFloatReg;
1924 ++static constexpr FloatRegister ScratchSimd128Reg = InvalidFloatReg;
1925 ++static constexpr FloatRegister ScratchFloat32Reg_ = InvalidFloatReg;
1926 ++static constexpr FloatRegister ScratchDoubleReg_ = InvalidFloatReg;
1927 ++
1928 ++static constexpr Register ScratchRegister = t6;
1929 ++
1930 ++// Helper class for ScratchRegister usage. Asserts that only one piece
1931 ++// of code thinks it has exclusive ownership of the scratch register.
1932 ++struct ScratchRegisterScope : public AutoRegisterScope {
1933 ++ explicit ScratchRegisterScope(MacroAssembler& masm)
1934 ++ : AutoRegisterScope(masm, ScratchRegister) {}
1935 ++};
1936 ++
1937 ++struct SecondScratchRegisterScope : public AutoRegisterScope {
1938 ++ explicit SecondScratchRegisterScope(MacroAssembler& masm);
1939 ++};
1940 ++
1941 ++struct ScratchFloat32Scope : AutoFloatRegisterScope {
1942 ++ explicit ScratchFloat32Scope(MacroAssembler& masm)
1943 ++ : AutoFloatRegisterScope(masm, ScratchFloat32Reg_) {}
1944 ++};
1945 ++
1946 ++struct ScratchDoubleScope : AutoFloatRegisterScope {
1947 ++ explicit ScratchDoubleScope(MacroAssembler& masm)
1948 ++ : AutoFloatRegisterScope(masm, ScratchDoubleReg_) {}
1949 ++};
1950 ++
1951 ++static constexpr Register OsrFrameReg{Registers::invalid_reg};
1952 ++static constexpr Register PreBarrierReg{Registers::invalid_reg};
1953 ++static constexpr Register InterpreterPCReg{Registers::invalid_reg};
1954 ++static constexpr Register CallTempReg0 = t0;
1955 ++static constexpr Register CallTempReg1 = t1;
1956 ++static constexpr Register CallTempReg2 = t2;
1957 ++static constexpr Register CallTempReg3 = t3;
1958 ++static constexpr Register CallTempReg4 = t4;
1959 ++static constexpr Register CallTempReg5 = t5;
1960 ++static constexpr Register InvalidReg{Registers::invalid_reg};
1961 ++static constexpr Register CallTempNonArgRegs[] = {t0, t1, t2, t3, t4, t5, t6};
1962 ++static const uint32_t NumCallTempNonArgRegs = std::size(CallTempNonArgRegs);
1963 ++
1964 ++static constexpr Register IntArgReg0{Registers::a0};
1965 ++static constexpr Register IntArgReg1{Registers::a1};
1966 ++static constexpr Register IntArgReg2{Registers::a2};
1967 ++static constexpr Register IntArgReg3{Registers::a3};
1968 ++static constexpr Register IntArgReg4{Registers::a4};
1969 ++static constexpr Register IntArgReg5{Registers::a5};
1970 ++static constexpr Register IntArgReg6{Registers::a6};
1971 ++static constexpr Register IntArgReg7{Registers::a7};
1972 ++static constexpr Register HeapReg{Registers::invalid_reg};
1973 ++
1974 ++// Registerd used in RegExpTester instruction (do not use ReturnReg).
1975 ++static constexpr Register RegExpTesterRegExpReg = CallTempReg0;
1976 ++static constexpr Register RegExpTesterStringReg = CallTempReg1;
1977 ++static constexpr Register RegExpTesterLastIndexReg = CallTempReg2;
1978 ++
1979 ++// Registerd used in RegExpMatcher instruction (do not use JSReturnOperand).
1980 ++static constexpr Register RegExpMatcherRegExpReg = CallTempReg0;
1981 ++static constexpr Register RegExpMatcherStringReg = CallTempReg1;
1982 ++static constexpr Register RegExpMatcherLastIndexReg = CallTempReg2;
1983 ++
1984 ++static constexpr Register JSReturnReg_Type{Registers::a3};
1985 ++static constexpr Register JSReturnReg_Data{Registers::a2};
1986 ++static constexpr Register JSReturnReg{Registers::a2};
1987 ++
1988 ++static constexpr Register64 ReturnReg64(ReturnReg);
1989 ++
1990 ++static constexpr Register ABINonArgReg0{Registers::s0};
1991 ++static constexpr Register ABINonArgReg1{Registers::s1};
1992 ++static constexpr Register ABINonArgReg2{Registers::s2};
1993 ++static constexpr Register ABINonArgReg3{Registers::s3};
1994 ++static constexpr Register ABINonArgReturnReg0{Registers::s0};
1995 ++static constexpr Register ABINonArgReturnReg1{Registers::s1};
1996 ++static constexpr Register ABINonVolatileReg{Registers::fp};
1997 ++static constexpr Register ABINonArgReturnVolatileReg{Registers::ra};
1998 ++
1999 ++static constexpr FloatRegister ABINonArgDoubleReg = InvalidFloatReg;
2000 ++
2001 ++// Instance pointer argument register for WebAssembly functions. This must not
2002 ++// alias any other register used for passing function arguments or return
2003 ++// values. Preserved by WebAssembly functions.
2004 ++static constexpr Register InstanceReg = s4;
2005 ++
2006 ++static constexpr Register WasmTableCallScratchReg0{Registers::invalid_reg};
2007 ++static constexpr Register WasmTableCallScratchReg1{Registers::invalid_reg};
2008 ++static constexpr Register WasmTableCallSigReg{Registers::invalid_reg};
2009 ++static constexpr Register WasmTableCallIndexReg{Registers::invalid_reg};
2010 ++static constexpr Register WasmTlsReg{Registers::invalid_reg};
2011 ++static constexpr Register WasmJitEntryReturnScratch{Registers::invalid_reg};
2012 ++
2013 ++static constexpr uint32_t ABIStackAlignment = 16;
2014 ++static constexpr uint32_t CodeAlignment = 16;
2015 ++static constexpr uint32_t JitStackAlignment = 8;
2016 ++static constexpr uint32_t JitStackValueAlignment =
2017 ++ JitStackAlignment / sizeof(Value);
2018 ++
2019 ++static const Scale ScalePointer = TimesOne;
2020 ++
2021 ++class Instruction;
2022 ++typedef js::jit::AssemblerBuffer<1024, Instruction> RISCVBuffer;
2023 ++
2024 ++class Assembler : public AssemblerShared {
2025 ++ public:
2026 ++ enum RISCVCondition : uint32_t {
2027 ++ EQ = 0b000,
2028 ++ NE = 0b001,
2029 ++ LT = 0b100,
2030 ++ GE = 0b101,
2031 ++ LTU = 0b110,
2032 ++ GEU = 0b111,
2033 ++ };
2034 ++
2035 ++ enum Condition {
2036 ++ Equal,
2037 ++ NotEqual,
2038 ++ Above,
2039 ++ AboveOrEqual,
2040 ++ Below,
2041 ++ BelowOrEqual,
2042 ++ GreaterThan,
2043 ++ GreaterThanOrEqual,
2044 ++ LessThan,
2045 ++ LessThanOrEqual,
2046 ++ Overflow,
2047 ++ CarrySet,
2048 ++ CarryClear,
2049 ++ Signed,
2050 ++ NotSigned,
2051 ++ Zero,
2052 ++ NonZero,
2053 ++ Always,
2054 ++ };
2055 ++
2056 ++ enum DoubleCondition {
2057 ++ DoubleOrdered,
2058 ++ DoubleEqual,
2059 ++ DoubleNotEqual,
2060 ++ DoubleGreaterThan,
2061 ++ DoubleGreaterThanOrEqual,
2062 ++ DoubleLessThan,
2063 ++ DoubleLessThanOrEqual,
2064 ++ DoubleUnordered,
2065 ++ DoubleEqualOrUnordered,
2066 ++ DoubleNotEqualOrUnordered,
2067 ++ DoubleGreaterThanOrUnordered,
2068 ++ DoubleGreaterThanOrEqualOrUnordered,
2069 ++ DoubleLessThanOrUnordered,
2070 ++ DoubleLessThanOrEqualOrUnordered
2071 ++ };
2072 ++
2073 ++ RISCVBuffer m_buffer;
2074 ++
2075 ++ BufferOffset nextOffset() { return m_buffer.nextOffset(); }
2076 ++
2077 ++ static Condition InvertCondition(Condition) { MOZ_CRASH(); }
2078 ++
2079 ++ static DoubleCondition InvertCondition(DoubleCondition) { MOZ_CRASH(); }
2080 ++
2081 ++ static void TraceJumpRelocations(JSTracer* trc, JitCode* code,
2082 ++ CompactBufferReader& reader);
2083 ++ static void TraceDataRelocations(JSTracer* trc, JitCode* code,
2084 ++ CompactBufferReader& reader);
2085 ++
2086 ++ template <typename T, typename S>
2087 ++ static void PatchDataWithValueCheck(CodeLocationLabel, T, S) {
2088 ++ MOZ_CRASH();
2089 ++ }
2090 ++ static void PatchWrite_Imm32(CodeLocationLabel, Imm32) { MOZ_CRASH(); }
2091 ++
2092 ++ static void PatchWrite_NearCall(CodeLocationLabel, CodeLocationLabel) {
2093 ++ MOZ_CRASH();
2094 ++ }
2095 ++ static uint32_t PatchWrite_NearCallSize() { MOZ_CRASH(); }
2096 ++
2097 ++ static void ToggleToJmp(CodeLocationLabel) { MOZ_CRASH(); }
2098 ++ static void ToggleToCmp(CodeLocationLabel) { MOZ_CRASH(); }
2099 ++ static void ToggleCall(CodeLocationLabel, bool) { MOZ_CRASH(); }
2100 ++
2101 ++ static void Bind(uint8_t* rawCode, const CodeLabel& label) { MOZ_CRASH(); }
2102 ++
2103 ++ static uintptr_t GetPointer(uint8_t*) { MOZ_CRASH(); }
2104 ++
2105 ++ static bool HasRoundInstruction(RoundingMode) { return false; }
2106 ++
2107 ++ void verifyHeapAccessDisassembly(uint32_t begin, uint32_t end,
2108 ++ const Disassembler::HeapAccess& heapAccess) {
2109 ++ MOZ_CRASH();
2110 ++ }
2111 ++
2112 ++ void setUnlimitedBuffer() { MOZ_CRASH(); }
2113 ++
2114 ++ MOZ_ALWAYS_INLINE BufferOffset writeInst(uint32_t x) {
2115 ++ MOZ_ASSERT(hasCreator());
2116 ++ return m_buffer.putInt(x);
2117 ++ }
2118 ++};
2119 ++
2120 ++class Instruction {
2121 ++ protected:
2122 ++ uint32_t data;
2123 ++
2124 ++ // Standard constructor
2125 ++ Instruction(uint32_t data_) : data(data_) {}
2126 ++
2127 ++ public:
2128 ++ uint32_t encode() const { return data; }
2129 ++
2130 ++ void setData(uint32_t data) { this->data = data; }
2131 ++ Instruction* next();
2132 ++ const uint32_t* raw() const { return &data; }
2133 ++ uint32_t size() const { return sizeof(data); }
2134 ++};
2135 ++
2136 ++class Operand {
2137 ++ public:
2138 ++ enum Kind { REG };
2139 ++
2140 ++ private:
2141 ++ Kind kind_ : 4;
2142 ++ uint32_t reg_ : 5;
2143 ++ int32_t offset_;
2144 ++
2145 ++ public:
2146 ++ explicit Operand(const Register reg)
2147 ++ : kind_(REG), reg_(reg.code()), offset_(0) {}
2148 ++ explicit Operand(const FloatRegister) { MOZ_CRASH(); }
2149 ++ explicit Operand(const Address& adress) { MOZ_CRASH(); }
2150 ++ explicit Operand(Register reg, Imm32 offset)
2151 ++ : kind_(REG), reg_(reg.code()), offset_(offset.value) {}
2152 ++ explicit Operand(Register reg, int32_t offset)
2153 ++ : kind_(REG), reg_(reg.code()), offset_(offset) {}
2154 ++
2155 ++ Kind kind() const { return kind_; }
2156 ++};
2157 ++
2158 ++static const uint32_t NumIntArgRegs = 8;
2159 ++static const uint32_t NumFloatArgRegs = 8;
2160 ++
2161 ++class ABIArgGenerator {
2162 ++ public:
2163 ++ ABIArgGenerator()
2164 ++ : intRegIndex_(0), floatRegIndex_(0), stackOffset_(0), current_() {}
2165 ++
2166 ++ ABIArg next(MIRType);
2167 ++ ABIArg& current() { return current_; }
2168 ++ uint32_t stackBytesConsumedSoFar() const { return stackOffset_; }
2169 ++ void increaseStackOffset(uint32_t bytes) { stackOffset_ += bytes; }
2170 ++
2171 ++ private:
2172 ++ unsigned intRegIndex_;
2173 ++ unsigned floatRegIndex_;
2174 ++ uint32_t stackOffset_;
2175 ++ ABIArg current_;
2176 ++};
2177 ++
2178 ++} // namespace jit
2179 ++} // namespace js
2180 ++
2181 ++#endif /* jit_riscv64_Assembler_riscv64_h */
2182 +diff --git a/js/src/jit/riscv64/CodeGenerator-riscv64.h b/js/src/jit/riscv64/CodeGenerator-riscv64.h
2183 +new file mode 100644
2184 +index 0000000000..db30b32283
2185 +--- /dev/null
2186 ++++ b/js/src/jit/riscv64/CodeGenerator-riscv64.h
2187 +@@ -0,0 +1,78 @@
2188 ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2189 ++ * vim: set ts=8 sts=2 et sw=2 tw=80:
2190 ++ * This Source Code Form is subject to the terms of the Mozilla Public
2191 ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
2192 ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
2193 ++
2194 ++#ifndef jit_riscv64_CodeGenerator_riscv64_h
2195 ++#define jit_riscv64_CodeGenerator_riscv64_h
2196 ++
2197 ++#include "jit/shared/CodeGenerator-shared.h"
2198 ++
2199 ++namespace js {
2200 ++namespace jit {
2201 ++
2202 ++class CodeGeneratorRiscv64 : public CodeGeneratorShared {
2203 ++ protected:
2204 ++ CodeGeneratorRiscv64(MIRGenerator* gen, LIRGraph* graph, MacroAssembler* masm)
2205 ++ : CodeGeneratorShared(gen, graph, masm) {
2206 ++ MOZ_CRASH();
2207 ++ }
2208 ++
2209 ++ MoveOperand toMoveOperand(LAllocation) const { MOZ_CRASH(); }
2210 ++ template <typename T1, typename T2>
2211 ++ void bailoutCmp32(Assembler::Condition, T1, T2, LSnapshot*) {
2212 ++ MOZ_CRASH();
2213 ++ }
2214 ++ template <typename T1, typename T2>
2215 ++ void bailoutTest32(Assembler::Condition, T1, T2, LSnapshot*) {
2216 ++ MOZ_CRASH();
2217 ++ }
2218 ++ template <typename T1, typename T2>
2219 ++ void bailoutCmpPtr(Assembler::Condition, T1, T2, LSnapshot*) {
2220 ++ MOZ_CRASH();
2221 ++ }
2222 ++ void bailoutTestPtr(Assembler::Condition, Register, Register, LSnapshot*) {
2223 ++ MOZ_CRASH();
2224 ++ }
2225 ++ void bailoutIfFalseBool(Register, LSnapshot*) { MOZ_CRASH(); }
2226 ++ void bailoutFrom(Label*, LSnapshot*) { MOZ_CRASH(); }
2227 ++ void bailout(LSnapshot*) { MOZ_CRASH(); }
2228 ++ void bailoutIf(Assembler::Condition, LSnapshot*) { MOZ_CRASH(); }
2229 ++ bool generateOutOfLineCode() { MOZ_CRASH(); }
2230 ++ void testNullEmitBranch(Assembler::Condition, ValueOperand, MBasicBlock*,
2231 ++ MBasicBlock*) {
2232 ++ MOZ_CRASH();
2233 ++ }
2234 ++ void testUndefinedEmitBranch(Assembler::Condition, ValueOperand, MBasicBlock*,
2235 ++ MBasicBlock*) {
2236 ++ MOZ_CRASH();
2237 ++ }
2238 ++ void testObjectEmitBranch(Assembler::Condition, ValueOperand, MBasicBlock*,
2239 ++ MBasicBlock*) {
2240 ++ MOZ_CRASH();
2241 ++ }
2242 ++ void testZeroEmitBranch(Assembler::Condition, Register, MBasicBlock*,
2243 ++ MBasicBlock*) {
2244 ++ MOZ_CRASH();
2245 ++ }
2246 ++ void emitTableSwitchDispatch(MTableSwitch*, Register, Register) {
2247 ++ MOZ_CRASH();
2248 ++ }
2249 ++ void emitBigIntDiv(LBigIntDiv*, Register, Register, Register, Label*) {
2250 ++ MOZ_CRASH();
2251 ++ }
2252 ++ void emitBigIntMod(LBigIntMod*, Register, Register, Register, Label*) {
2253 ++ MOZ_CRASH();
2254 ++ }
2255 ++ ValueOperand ToValue(LInstruction*, size_t) { MOZ_CRASH(); }
2256 ++ ValueOperand ToTempValue(LInstruction*, size_t) { MOZ_CRASH(); }
2257 ++ void generateInvalidateEpilogue() { MOZ_CRASH(); }
2258 ++};
2259 ++
2260 ++typedef CodeGeneratorRiscv64 CodeGeneratorSpecific;
2261 ++
2262 ++} // namespace jit
2263 ++} // namespace js
2264 ++
2265 ++#endif /* jit_riscv64_CodeGenerator_riscv64_h */
2266 +diff --git a/js/src/jit/riscv64/LIR-riscv64.h b/js/src/jit/riscv64/LIR-riscv64.h
2267 +new file mode 100644
2268 +index 0000000000..59d42c6c75
2269 +--- /dev/null
2270 ++++ b/js/src/jit/riscv64/LIR-riscv64.h
2271 +@@ -0,0 +1,111 @@
2272 ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2273 ++ * vim: set ts=8 sts=2 et sw=2 tw=80:
2274 ++ * This Source Code Form is subject to the terms of the Mozilla Public
2275 ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
2276 ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
2277 ++
2278 ++#ifndef jit_riscv64_LIR_riscv64_h
2279 ++#define jit_riscv64_LIR_riscv64_h
2280 ++
2281 ++namespace js {
2282 ++namespace jit {
2283 ++
2284 ++class LUnboxFloatingPoint : public LInstruction {
2285 ++ public:
2286 ++ LIR_HEADER(UnboxFloatingPoint)
2287 ++ static const size_t Input = 0;
2288 ++
2289 ++ MUnbox* mir() const { MOZ_CRASH(); }
2290 ++
2291 ++ const LDefinition* output() const { MOZ_CRASH(); }
2292 ++ MIRType type() const { MOZ_CRASH(); }
2293 ++};
2294 ++
2295 ++class LTableSwitch : public LInstruction {
2296 ++ public:
2297 ++ LIR_HEADER(TableSwitch)
2298 ++ MTableSwitch* mir() { MOZ_CRASH(); }
2299 ++
2300 ++ const LAllocation* index() { MOZ_CRASH(); }
2301 ++ const LDefinition* tempInt() { MOZ_CRASH(); }
2302 ++ const LDefinition* tempPointer() { MOZ_CRASH(); }
2303 ++};
2304 ++
2305 ++class LTableSwitchV : public LInstruction {
2306 ++ public:
2307 ++ LIR_HEADER(TableSwitchV)
2308 ++ MTableSwitch* mir() { MOZ_CRASH(); }
2309 ++
2310 ++ const LDefinition* tempInt() { MOZ_CRASH(); }
2311 ++ const LDefinition* tempFloat() { MOZ_CRASH(); }
2312 ++ const LDefinition* tempPointer() { MOZ_CRASH(); }
2313 ++
2314 ++ static const size_t InputValue = 0;
2315 ++};
2316 ++
2317 ++class LWasmUint32ToFloat32 : public LInstructionHelper<1, 1, 0> {
2318 ++ public:
2319 ++ explicit LWasmUint32ToFloat32(const LAllocation&)
2320 ++ : LInstructionHelper(Opcode::Invalid) {
2321 ++ MOZ_CRASH();
2322 ++ }
2323 ++};
2324 ++
2325 ++class LUnbox : public LInstructionHelper<1, 2, 0> {
2326 ++ public:
2327 ++ MUnbox* mir() const { MOZ_CRASH(); }
2328 ++ const LAllocation* payload() { MOZ_CRASH(); }
2329 ++ const LAllocation* type() { MOZ_CRASH(); }
2330 ++ const char* extraName() const { MOZ_CRASH(); }
2331 ++};
2332 ++class LDivI : public LBinaryMath<1> {
2333 ++ public:
2334 ++ LDivI(const LAllocation&, const LAllocation&, const LDefinition&)
2335 ++ : LBinaryMath(Opcode::Invalid) {
2336 ++ MOZ_CRASH();
2337 ++ }
2338 ++ MDiv* mir() const { MOZ_CRASH(); }
2339 ++};
2340 ++class LDivPowTwoI : public LInstructionHelper<1, 1, 0> {
2341 ++ public:
2342 ++ LDivPowTwoI(const LAllocation&, int32_t)
2343 ++ : LInstructionHelper(Opcode::Invalid) {
2344 ++ MOZ_CRASH();
2345 ++ }
2346 ++ const LAllocation* numerator() { MOZ_CRASH(); }
2347 ++ int32_t shift() { MOZ_CRASH(); }
2348 ++ MDiv* mir() const { MOZ_CRASH(); }
2349 ++};
2350 ++class LModI : public LBinaryMath<1> {
2351 ++ public:
2352 ++ LModI(const LAllocation&, const LAllocation&, const LDefinition&)
2353 ++ : LBinaryMath(Opcode::Invalid) {
2354 ++ MOZ_CRASH();
2355 ++ }
2356 ++
2357 ++ const LDefinition* callTemp() { MOZ_CRASH(); }
2358 ++ MMod* mir() const { MOZ_CRASH(); }
2359 ++};
2360 ++class LWasmUint32ToDouble : public LInstructionHelper<1, 1, 0> {
2361 ++ public:
2362 ++ explicit LWasmUint32ToDouble(const LAllocation&)
2363 ++ : LInstructionHelper(Opcode::Invalid) {
2364 ++ MOZ_CRASH();
2365 ++ }
2366 ++};
2367 ++class LModPowTwoI : public LInstructionHelper<1, 1, 0> {
2368 ++ public:
2369 ++ int32_t shift() { MOZ_CRASH(); }
2370 ++ LModPowTwoI(const LAllocation& lhs, int32_t shift)
2371 ++ : LInstructionHelper(Opcode::Invalid) {
2372 ++ MOZ_CRASH();
2373 ++ }
2374 ++ MMod* mir() const { MOZ_CRASH(); }
2375 ++};
2376 ++
2377 ++class LMulI : public LInstruction {};
2378 ++
2379 ++} // namespace jit
2380 ++} // namespace js
2381 ++
2382 ++#endif /* jit_riscv64_LIR_riscv64_h */
2383 +diff --git a/js/src/jit/riscv64/Lowering-riscv64.h b/js/src/jit/riscv64/Lowering-riscv64.h
2384 +new file mode 100644
2385 +index 0000000000..a68e52b872
2386 +--- /dev/null
2387 ++++ b/js/src/jit/riscv64/Lowering-riscv64.h
2388 +@@ -0,0 +1,130 @@
2389 ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2390 ++ * vim: set ts=8 sts=2 et sw=2 tw=80:
2391 ++ * This Source Code Form is subject to the terms of the Mozilla Public
2392 ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
2393 ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
2394 ++
2395 ++#ifndef jit_riscv64_Lowering_riscv64_h
2396 ++#define jit_riscv64_Lowering_riscv64_h
2397 ++
2398 ++#include "jit/shared/Lowering-shared.h"
2399 ++
2400 ++namespace js {
2401 ++namespace jit {
2402 ++
2403 ++class LIRGeneratorRiscv64 : public LIRGeneratorShared {
2404 ++ protected:
2405 ++ LIRGeneratorRiscv64(MIRGenerator* gen, MIRGraph& graph, LIRGraph& lirGraph)
2406 ++ : LIRGeneratorShared(gen, graph, lirGraph) {
2407 ++ MOZ_CRASH();
2408 ++ }
2409 ++
2410 ++ LBoxAllocation useBoxFixed(MDefinition*, Register, Register,
2411 ++ bool useAtStart = false) {
2412 ++ MOZ_CRASH();
2413 ++ }
2414 ++
2415 ++ LAllocation useByteOpRegister(MDefinition*) { MOZ_CRASH(); }
2416 ++ LAllocation useByteOpRegisterAtStart(MDefinition*) { MOZ_CRASH(); }
2417 ++ LAllocation useByteOpRegisterOrNonDoubleConstant(MDefinition*) {
2418 ++ MOZ_CRASH();
2419 ++ }
2420 ++ LDefinition tempByteOpRegister() { MOZ_CRASH(); }
2421 ++ LDefinition tempToUnbox() { MOZ_CRASH(); }
2422 ++ bool needTempForPostBarrier() { MOZ_CRASH(); }
2423 ++ void lowerUntypedPhiInput(MPhi*, uint32_t, LBlock*, size_t) { MOZ_CRASH(); }
2424 ++ void lowerInt64PhiInput(MPhi*, uint32_t, LBlock*, size_t) { MOZ_CRASH(); }
2425 ++ void defineInt64Phi(MPhi*, size_t) { MOZ_CRASH(); }
2426 ++ void lowerForShift(LInstructionHelper<1, 2, 0>*, MDefinition*, MDefinition*,
2427 ++ MDefinition*) {
2428 ++ MOZ_CRASH();
2429 ++ }
2430 ++ void lowerUrshD(MUrsh*) { MOZ_CRASH(); }
2431 ++ void lowerPowOfTwoI(MPow*) { MOZ_CRASH(); }
2432 ++ template <typename T>
2433 ++ void lowerForALU(T, MDefinition*, MDefinition*, MDefinition* v = nullptr) {
2434 ++ MOZ_CRASH();
2435 ++ }
2436 ++ template <typename T>
2437 ++ void lowerForFPU(T, MDefinition*, MDefinition*, MDefinition* v = nullptr) {
2438 ++ MOZ_CRASH();
2439 ++ }
2440 ++ template <typename T>
2441 ++ void lowerForALUInt64(T, MDefinition*, MDefinition*,
2442 ++ MDefinition* v = nullptr) {
2443 ++ MOZ_CRASH();
2444 ++ }
2445 ++ void lowerForMulInt64(LMulI64*, MMul*, MDefinition*,
2446 ++ MDefinition* v = nullptr) {
2447 ++ MOZ_CRASH();
2448 ++ }
2449 ++ template <typename T>
2450 ++ void lowerForShiftInt64(T, MDefinition*, MDefinition*,
2451 ++ MDefinition* v = nullptr) {
2452 ++ MOZ_CRASH();
2453 ++ }
2454 ++ void lowerForBitAndAndBranch(LBitAndAndBranch*, MInstruction*, MDefinition*,
2455 ++ MDefinition*) {
2456 ++ MOZ_CRASH();
2457 ++ }
2458 ++ void lowerForCompareI64AndBranch(MTest*, MCompare*, JSOp, MDefinition*,
2459 ++ MDefinition*, MBasicBlock*, MBasicBlock*) {
2460 ++ MOZ_CRASH();
2461 ++ }
2462 ++
2463 ++ void lowerConstantDouble(double, MInstruction*) { MOZ_CRASH(); }
2464 ++ void lowerConstantFloat32(float, MInstruction*) { MOZ_CRASH(); }
2465 ++ void lowerTruncateDToInt32(MTruncateToInt32*) { MOZ_CRASH(); }
2466 ++ void lowerTruncateFToInt32(MTruncateToInt32*) { MOZ_CRASH(); }
2467 ++ void lowerBuiltinInt64ToFloatingPoint(MBuiltinInt64ToFloatingPoint* ins) {
2468 ++ MOZ_CRASH();
2469 ++ }
2470 ++ void lowerWasmBuiltinTruncateToInt64(MWasmBuiltinTruncateToInt64* ins) {
2471 ++ MOZ_CRASH();
2472 ++ }
2473 ++ void lowerWasmBuiltinTruncateToInt32(MWasmBuiltinTruncateToInt32* ins) {
2474 ++ MOZ_CRASH();
2475 ++ }
2476 ++ void lowerDivI(MDiv*) { MOZ_CRASH(); }
2477 ++ void lowerModI(MMod*) { MOZ_CRASH(); }
2478 ++ void lowerDivI64(MDiv*) { MOZ_CRASH(); }
2479 ++ void lowerWasmBuiltinDivI64(MWasmBuiltinDivI64* div) { MOZ_CRASH(); }
2480 ++ void lowerModI64(MMod*) { MOZ_CRASH(); }
2481 ++ void lowerWasmBuiltinModI64(MWasmBuiltinModI64* mod) { MOZ_CRASH(); }
2482 ++ void lowerNegI(MInstruction*, MDefinition*) { MOZ_CRASH(); }
2483 ++ void lowerNegI64(MInstruction*, MDefinition*) { MOZ_CRASH(); }
2484 ++ void lowerMulI(MMul*, MDefinition*, MDefinition*) { MOZ_CRASH(); }
2485 ++ void lowerUDiv(MDiv*) { MOZ_CRASH(); }
2486 ++ void lowerUMod(MMod*) { MOZ_CRASH(); }
2487 ++ void lowerWasmSelectI(MWasmSelect* select) { MOZ_CRASH(); }
2488 ++ void lowerWasmSelectI64(MWasmSelect* select) { MOZ_CRASH(); }
2489 ++ void lowerWasmCompareAndSelect(MWasmSelect* ins, MDefinition* lhs,
2490 ++ MDefinition* rhs, MCompare::CompareType compTy,
2491 ++ JSOp jsop) {
2492 ++ MOZ_CRASH();
2493 ++ }
2494 ++ bool canSpecializeWasmCompareAndSelect(MCompare::CompareType compTy,
2495 ++ MIRType insTy) {
2496 ++ MOZ_CRASH();
2497 ++ }
2498 ++
2499 ++ void lowerBigIntLsh(MBigIntLsh*) { MOZ_CRASH(); }
2500 ++ void lowerBigIntRsh(MBigIntRsh*) { MOZ_CRASH(); }
2501 ++ void lowerBigIntDiv(MBigIntDiv*) { MOZ_CRASH(); }
2502 ++ void lowerBigIntMod(MBigIntMod*) { MOZ_CRASH(); }
2503 ++
2504 ++ void lowerAtomicLoad64(MLoadUnboxedScalar*) { MOZ_CRASH(); }
2505 ++ void lowerAtomicStore64(MStoreUnboxedScalar*) { MOZ_CRASH(); }
2506 ++
2507 ++ LTableSwitch* newLTableSwitch(LAllocation, LDefinition, MTableSwitch*) {
2508 ++ MOZ_CRASH();
2509 ++ }
2510 ++ LTableSwitchV* newLTableSwitchV(MTableSwitch*) { MOZ_CRASH(); }
2511 ++};
2512 ++
2513 ++typedef LIRGeneratorRiscv64 LIRGeneratorSpecific;
2514 ++
2515 ++} // namespace jit
2516 ++} // namespace js
2517 ++
2518 ++#endif /* jit_riscv64_Lowering_riscv64_h */
2519 +diff --git a/js/src/jit/riscv64/MacroAssembler-riscv64-inl.h b/js/src/jit/riscv64/MacroAssembler-riscv64-inl.h
2520 +new file mode 100644
2521 +index 0000000000..3dd6273d0f
2522 +--- /dev/null
2523 ++++ b/js/src/jit/riscv64/MacroAssembler-riscv64-inl.h
2524 +@@ -0,0 +1,18 @@
2525 ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2526 ++ * vim: set ts=8 sts=2 et sw=2 tw=80:
2527 ++ * This Source Code Form is subject to the terms of the Mozilla Public
2528 ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
2529 ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
2530 ++
2531 ++#ifndef jit_riscv64_MacroAssembler_riscv64_inl_h
2532 ++#define jit_riscv64_MacroAssembler_riscv64_inl_h
2533 ++
2534 ++#include "jit/riscv64/MacroAssembler-riscv64.h"
2535 ++
2536 ++namespace js {
2537 ++namespace jit {
2538 ++
2539 ++} // namespace jit
2540 ++} // namespace js
2541 ++
2542 ++#endif
2543 +diff --git a/js/src/jit/riscv64/MacroAssembler-riscv64.h b/js/src/jit/riscv64/MacroAssembler-riscv64.h
2544 +new file mode 100644
2545 +index 0000000000..30ca17d359
2546 +--- /dev/null
2547 ++++ b/js/src/jit/riscv64/MacroAssembler-riscv64.h
2548 +@@ -0,0 +1,458 @@
2549 ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2550 ++ * vim: set ts=8 sts=2 et sw=2 tw=80:
2551 ++ * This Source Code Form is subject to the terms of the Mozilla Public
2552 ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
2553 ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
2554 ++
2555 ++#ifndef jit_riscv64_MacroAssembler_riscv64_h
2556 ++#define jit_riscv64_MacroAssembler_riscv64_h
2557 ++
2558 ++#include "jit/riscv64/Assembler-riscv64.h"
2559 ++#include "jit/MoveResolver.h"
2560 ++#include "wasm/WasmBuiltins.h"
2561 ++
2562 ++namespace js {
2563 ++namespace jit {
2564 ++
2565 ++static constexpr ValueOperand JSReturnOperand{JSReturnReg};
2566 ++
2567 ++class ScratchTagScope : public SecondScratchRegisterScope {
2568 ++ public:
2569 ++ ScratchTagScope(MacroAssembler& masm, const js::jit::ValueOperand&)
2570 ++ : SecondScratchRegisterScope(masm) {}
2571 ++};
2572 ++
2573 ++class ScratchTagScopeRelease {
2574 ++ ScratchTagScope* ts_;
2575 ++
2576 ++ public:
2577 ++ explicit ScratchTagScopeRelease(ScratchTagScope* ts) : ts_(ts) {
2578 ++ ts_->release();
2579 ++ }
2580 ++
2581 ++ ~ScratchTagScopeRelease() { ts_->reacquire(); }
2582 ++};
2583 ++
2584 ++class MacroAssemblerRiscv64 : public Assembler {
2585 ++ protected:
2586 ++ // Perform a downcast. Should be removed by Bug 996602.
2587 ++ MacroAssembler& asMasm();
2588 ++ const MacroAssembler& asMasm() const;
2589 ++
2590 ++ public:
2591 ++ MacroAssemblerRiscv64() { MOZ_CRASH(); }
2592 ++
2593 ++ MoveResolver moveResolver_;
2594 ++
2595 ++ size_t size() const { MOZ_CRASH(); }
2596 ++ size_t bytesNeeded() const { MOZ_CRASH(); }
2597 ++ size_t jumpRelocationTableBytes() const { MOZ_CRASH(); }
2598 ++ size_t dataRelocationTableBytes() const { MOZ_CRASH(); }
2599 ++ size_t preBarrierTableBytes() const { MOZ_CRASH(); }
2600 ++
2601 ++ size_t numCodeLabels() const { MOZ_CRASH(); }
2602 ++ CodeLabel codeLabel(size_t) { MOZ_CRASH(); }
2603 ++
2604 ++ bool reserve(size_t size) { MOZ_CRASH(); }
2605 ++ bool appendRawCode(const uint8_t* code, size_t numBytes) { MOZ_CRASH(); }
2606 ++ bool swapBuffer(wasm::Bytes& bytes) { MOZ_CRASH(); }
2607 ++
2608 ++ void assertNoGCThings() const { MOZ_CRASH(); }
2609 ++
2610 ++ static bool SupportsFloatingPoint() { return false; }
2611 ++ static bool SupportsUnalignedAccesses() { return false; }
2612 ++ static bool SupportsFastUnalignedFPAccesses() { return false; }
2613 ++
2614 ++ void executableCopy(void*, bool = true) { MOZ_CRASH(); }
2615 ++ void copyJumpRelocationTable(uint8_t*) { MOZ_CRASH(); }
2616 ++ void copyDataRelocationTable(uint8_t*) { MOZ_CRASH(); }
2617 ++ void copyPreBarrierTable(uint8_t*) { MOZ_CRASH(); }
2618 ++ void processCodeLabels(uint8_t*) { MOZ_CRASH(); }
2619 ++
2620 ++ void flushBuffer() {}
2621 ++
2622 ++ template <typename T>
2623 ++ void bind(T) {
2624 ++ MOZ_CRASH();
2625 ++ }
2626 ++ template <typename T>
2627 ++ void j(Condition, T) {
2628 ++ MOZ_CRASH();
2629 ++ }
2630 ++ template <typename T>
2631 ++ void jump(T) {
2632 ++ MOZ_CRASH();
2633 ++ }
2634 ++ void writeCodePointer(CodeLabel* label) {
2635 ++ MOZ_CRASH();
2636 ++ }
2637 ++ void haltingAlign(size_t) { MOZ_CRASH(); }
2638 ++ void nopAlign(size_t) { MOZ_CRASH(); }
2639 ++ void checkStackAlignment() { MOZ_CRASH(); }
2640 ++ uint32_t currentOffset() { return nextOffset().getOffset(); }
2641 ++
2642 ++ void nop() { MOZ_CRASH(); }
2643 ++ void breakpoint() { MOZ_CRASH(); }
2644 ++ void abiret() { MOZ_CRASH(); }
2645 ++ void ret() { MOZ_CRASH(); }
2646 ++
2647 ++ CodeOffset toggledJump(Label*) { MOZ_CRASH(); }
2648 ++ CodeOffset toggledCall(JitCode*, bool) { MOZ_CRASH(); }
2649 ++ static size_t ToggledCallSize(uint8_t*) { MOZ_CRASH(); }
2650 ++
2651 ++ void finish() { MOZ_CRASH(); }
2652 ++
2653 ++ template <typename T, typename S>
2654 ++ void moveValue(T, S) {
2655 ++ MOZ_CRASH();
2656 ++ }
2657 ++ template <typename T, typename S, typename U>
2658 ++ void moveValue(T, S, U) {
2659 ++ MOZ_CRASH();
2660 ++ }
2661 ++ template <typename T, typename S>
2662 ++ void storeValue(const T&, const S&) {
2663 ++ MOZ_CRASH();
2664 ++ }
2665 ++ template <typename T, typename S, typename U>
2666 ++ void storeValue(T, S, U) {
2667 ++ MOZ_CRASH();
2668 ++ }
2669 ++ template <typename T, typename S>
2670 ++ void storePrivateValue(const T&, const S&) {
2671 ++ MOZ_CRASH();
2672 ++ }
2673 ++ template <typename T, typename S>
2674 ++ void loadValue(T, S) {
2675 ++ MOZ_CRASH();
2676 ++ }
2677 ++ template <typename T, typename S>
2678 ++ void loadUnalignedValue(T, S) {
2679 ++ MOZ_CRASH();
2680 ++ }
2681 ++ template <typename T>
2682 ++ void pushValue(const T&) {
2683 ++ MOZ_CRASH();
2684 ++ }
2685 ++ template <typename T, typename S>
2686 ++ void pushValue(T, S) {
2687 ++ MOZ_CRASH();
2688 ++ }
2689 ++ void popValue(ValueOperand) { MOZ_CRASH(); }
2690 ++ void tagValue(JSValueType, Register, ValueOperand) { MOZ_CRASH(); }
2691 ++ void retn(Imm32 n) { MOZ_CRASH(); }
2692 ++ template <typename T>
2693 ++ void push(const T&) {
2694 ++ MOZ_CRASH();
2695 ++ }
2696 ++ template <typename T>
2697 ++ void Push(T) {
2698 ++ MOZ_CRASH();
2699 ++ }
2700 ++ template <typename T>
2701 ++ void pop(T) {
2702 ++ MOZ_CRASH();
2703 ++ }
2704 ++ template <typename T>
2705 ++ void Pop(T) {
2706 ++ MOZ_CRASH();
2707 ++ }
2708 ++ template <typename T>
2709 ++ CodeOffset pushWithPatch(T) {
2710 ++ MOZ_CRASH();
2711 ++ }
2712 ++
2713 ++ void testNullSet(Condition, ValueOperand, Register) { MOZ_CRASH(); }
2714 ++ void testObjectSet(Condition, ValueOperand, Register) { MOZ_CRASH(); }
2715 ++ void testUndefinedSet(Condition, ValueOperand, Register) { MOZ_CRASH(); }
2716 ++
2717 ++ template <typename T, typename S>
2718 ++ void cmpPtrSet(Condition, T, S, Register) {
2719 ++ MOZ_CRASH();
2720 ++ }
2721 ++ void cmp8Set(Condition, Address, Imm32, Register) { MOZ_CRASH(); }
2722 ++ void cmp16Set(Condition, Address, Imm32, Register) { MOZ_CRASH(); }
2723 ++ template <typename T, typename S>
2724 ++ void cmp32Set(Condition, T, S, Register) {
2725 ++ MOZ_CRASH();
2726 ++ }
2727 ++ void cmp64Set(Condition, Address, Imm64, Register) { MOZ_CRASH(); }
2728 ++
2729 ++ template <typename T>
2730 ++ void mov(T, Register) {
2731 ++ MOZ_CRASH();
2732 ++ }
2733 ++ template <typename T>
2734 ++ void movePtr(T, Register) {
2735 ++ MOZ_CRASH();
2736 ++ }
2737 ++ template <typename T>
2738 ++ void move32(const T&, Register) {
2739 ++ MOZ_CRASH();
2740 ++ }
2741 ++ template <typename T, typename S>
2742 ++ void movq(T, S) {
2743 ++ MOZ_CRASH();
2744 ++ }
2745 ++ template <typename T, typename S>
2746 ++ void moveFloat32(T, S) {
2747 ++ MOZ_CRASH();
2748 ++ }
2749 ++ template <typename T, typename S>
2750 ++ void moveDouble(T, S) {
2751 ++ MOZ_CRASH();
2752 ++ }
2753 ++ template <typename T, typename S>
2754 ++ void move64(T, S) {
2755 ++ MOZ_CRASH();
2756 ++ }
2757 ++ template <typename T>
2758 ++ CodeOffset movWithPatch(T, Register) {
2759 ++ MOZ_CRASH();
2760 ++ }
2761 ++
2762 ++ template <typename T>
2763 ++ void loadPtr(T, Register) {
2764 ++ MOZ_CRASH();
2765 ++ }
2766 ++ template <typename T>
2767 ++ void load32(T, Register) {
2768 ++ MOZ_CRASH();
2769 ++ }
2770 ++ template <typename T>
2771 ++ void load32Unaligned(T, Register) {
2772 ++ MOZ_CRASH();
2773 ++ }
2774 ++ template <typename T>
2775 ++ void loadFloat32(T, FloatRegister) {
2776 ++ MOZ_CRASH();
2777 ++ }
2778 ++ template <typename T>
2779 ++ void loadDouble(T, FloatRegister) {
2780 ++ MOZ_CRASH();
2781 ++ }
2782 ++ template <typename T>
2783 ++ void loadPrivate(T, Register) {
2784 ++ MOZ_CRASH();
2785 ++ }
2786 ++ template <typename T>
2787 ++ void load8SignExtend(T, Register) {
2788 ++ MOZ_CRASH();
2789 ++ }
2790 ++ template <typename T>
2791 ++ void load8ZeroExtend(T, Register) {
2792 ++ MOZ_CRASH();
2793 ++ }
2794 ++ template <typename T>
2795 ++ void load16SignExtend(T, Register) {
2796 ++ MOZ_CRASH();
2797 ++ }
2798 ++ template <typename T>
2799 ++ void load16UnalignedSignExtend(T, Register) {
2800 ++ MOZ_CRASH();
2801 ++ }
2802 ++ template <typename T>
2803 ++ void load16ZeroExtend(T, Register) {
2804 ++ MOZ_CRASH();
2805 ++ }
2806 ++ template <typename T>
2807 ++ void load16UnalignedZeroExtend(T, Register) {
2808 ++ MOZ_CRASH();
2809 ++ }
2810 ++ template <typename T>
2811 ++ void load64(T, Register64) {
2812 ++ MOZ_CRASH();
2813 ++ }
2814 ++ template <typename T>
2815 ++ void load64Unaligned(T, Register64) {
2816 ++ MOZ_CRASH();
2817 ++ }
2818 ++
2819 ++ template <typename T, typename S>
2820 ++ void storePtr(const T&, S) {
2821 ++ MOZ_CRASH();
2822 ++ }
2823 ++ template <typename T, typename S>
2824 ++ void store32(T, S) {
2825 ++ MOZ_CRASH();
2826 ++ }
2827 ++ template <typename T, typename S>
2828 ++ void store32_NoSecondScratch(T, S) {
2829 ++ MOZ_CRASH();
2830 ++ }
2831 ++ template <typename T, typename S>
2832 ++ void store32Unaligned(T, S) {
2833 ++ MOZ_CRASH();
2834 ++ }
2835 ++ template <typename T, typename S>
2836 ++ void storeFloat32(T, S) {
2837 ++ MOZ_CRASH();
2838 ++ }
2839 ++ template <typename T, typename S>
2840 ++ void storeDouble(T, S) {
2841 ++ MOZ_CRASH();
2842 ++ }
2843 ++ template <typename T, typename S>
2844 ++ void store8(T, S) {
2845 ++ MOZ_CRASH();
2846 ++ }
2847 ++ template <typename T, typename S>
2848 ++ void store16(T, S) {
2849 ++ MOZ_CRASH();
2850 ++ }
2851 ++ template <typename T, typename S>
2852 ++ void store16Unaligned(T, S) {
2853 ++ MOZ_CRASH();
2854 ++ }
2855 ++ template <typename T, typename S>
2856 ++ void store64(T, S) {
2857 ++ MOZ_CRASH();
2858 ++ }
2859 ++ template <typename T, typename S>
2860 ++ void store64Unaligned(T, S) {
2861 ++ MOZ_CRASH();
2862 ++ }
2863 ++
2864 ++ template <typename T>
2865 ++ void computeEffectiveAddress(T, Register) {
2866 ++ MOZ_CRASH();
2867 ++ }
2868 ++
2869 ++ void splitTagForTest(ValueOperand, ScratchTagScope&) { MOZ_CRASH(); }
2870 ++
2871 ++ void boxDouble(FloatRegister, ValueOperand, FloatRegister) { MOZ_CRASH(); }
2872 ++ void boxNonDouble(JSValueType, Register, ValueOperand) { MOZ_CRASH(); }
2873 ++ template <typename T>
2874 ++ void boxDouble(FloatRegister src, const T& dest) {
2875 ++ MOZ_CRASH();
2876 ++ }
2877 ++ template <typename T>
2878 ++ void unboxInt32(T, Register) {
2879 ++ MOZ_CRASH();
2880 ++ }
2881 ++ template <typename T>
2882 ++ void unboxBoolean(T, Register) {
2883 ++ MOZ_CRASH();
2884 ++ }
2885 ++ template <typename T>
2886 ++ void unboxString(T, Register) {
2887 ++ MOZ_CRASH();
2888 ++ }
2889 ++ template <typename T>
2890 ++ void unboxSymbol(T, Register) {
2891 ++ MOZ_CRASH();
2892 ++ }
2893 ++ template <typename T>
2894 ++ void unboxBigInt(T, Register) {
2895 ++ MOZ_CRASH();
2896 ++ }
2897 ++ template <typename T>
2898 ++ void unboxObject(T, Register) {
2899 ++ MOZ_CRASH();
2900 ++ }
2901 ++ template <typename T>
2902 ++ void unboxDouble(T, FloatRegister) {
2903 ++ MOZ_CRASH();
2904 ++ }
2905 ++ void unboxValue(const ValueOperand&, AnyRegister, JSValueType) {
2906 ++ MOZ_CRASH();
2907 ++ }
2908 ++ void unboxNonDouble(const ValueOperand&, Register, JSValueType) {
2909 ++ MOZ_CRASH();
2910 ++ }
2911 ++ void unboxNonDouble(const Address&, Register, JSValueType) { MOZ_CRASH(); }
2912 ++ template <typename T>
2913 ++ void unboxGCThingForGCBarrier(const T&, Register) {
2914 ++ MOZ_CRASH();
2915 ++ }
2916 ++ template <typename T>
2917 ++ void unboxObjectOrNull(const T& src, Register dest) {
2918 ++ MOZ_CRASH();
2919 ++ }
2920 ++ void notBoolean(ValueOperand) { MOZ_CRASH(); }
2921 ++ [[nodiscard]] Register extractObject(Address, Register) { MOZ_CRASH(); }
2922 ++ [[nodiscard]] Register extractObject(ValueOperand, Register) { MOZ_CRASH(); }
2923 ++ [[nodiscard]] Register extractSymbol(ValueOperand, Register) { MOZ_CRASH(); }
2924 ++ [[nodiscard]] Register extractInt32(ValueOperand, Register) { MOZ_CRASH(); }
2925 ++ [[nodiscard]] Register extractBoolean(ValueOperand, Register) { MOZ_CRASH(); }
2926 ++ template <typename T>
2927 ++ [[nodiscard]] Register extractTag(T, Register) {
2928 ++ MOZ_CRASH();
2929 ++ }
2930 ++
2931 ++ void convertFloat32ToInt32(FloatRegister, Register, Label*, bool v = true) {
2932 ++ MOZ_CRASH();
2933 ++ }
2934 ++ void convertDoubleToInt32(FloatRegister, Register, Label*, bool v = true) {
2935 ++ MOZ_CRASH();
2936 ++ }
2937 ++ void convertDoubleToPtr(FloatRegister, Register, Label*, bool v = true) {
2938 ++ MOZ_CRASH();
2939 ++ }
2940 ++ void convertBoolToInt32(Register, Register) { MOZ_CRASH(); }
2941 ++
2942 ++ void convertDoubleToFloat32(FloatRegister, FloatRegister) { MOZ_CRASH(); }
2943 ++ void convertInt32ToFloat32(Register, FloatRegister) { MOZ_CRASH(); }
2944 ++
2945 ++ template <typename T>
2946 ++ void convertInt32ToDouble(T, FloatRegister) {
2947 ++ MOZ_CRASH();
2948 ++ }
2949 ++ void convertFloat32ToDouble(FloatRegister, FloatRegister) { MOZ_CRASH(); }
2950 ++
2951 ++ void boolValueToDouble(ValueOperand, FloatRegister) { MOZ_CRASH(); }
2952 ++ void boolValueToFloat32(ValueOperand, FloatRegister) { MOZ_CRASH(); }
2953 ++ void int32ValueToDouble(ValueOperand, FloatRegister) { MOZ_CRASH(); }
2954 ++ void int32ValueToFloat32(ValueOperand, FloatRegister) { MOZ_CRASH(); }
2955 ++
2956 ++ void loadConstantDouble(double, FloatRegister) { MOZ_CRASH(); }
2957 ++ void loadConstantFloat32(float, FloatRegister) { MOZ_CRASH(); }
2958 ++ Condition testInt32Truthy(bool, ValueOperand) { MOZ_CRASH(); }
2959 ++ Condition testStringTruthy(bool, ValueOperand) { MOZ_CRASH(); }
2960 ++ Condition testBigIntTruthy(bool, ValueOperand) { MOZ_CRASH(); }
2961 ++
2962 ++ template <typename T>
2963 ++ void loadUnboxedValue(T, MIRType, AnyRegister) {
2964 ++ MOZ_CRASH();
2965 ++ }
2966 ++ template <typename T>
2967 ++ void storeUnboxedValue(const ConstantOrRegister&, MIRType, T, MIRType) {
2968 ++ MOZ_CRASH();
2969 ++ }
2970 ++ template <typename T>
2971 ++ void storeUnboxedPayload(ValueOperand value, T, size_t, JSValueType) {
2972 ++ MOZ_CRASH();
2973 ++ }
2974 ++
2975 ++ void convertUInt32ToDouble(Register, FloatRegister) { MOZ_CRASH(); }
2976 ++ void convertUInt32ToFloat32(Register, FloatRegister) { MOZ_CRASH(); }
2977 ++ void incrementInt32Value(Address) { MOZ_CRASH(); }
2978 ++ void ensureDouble(ValueOperand, FloatRegister, Label*) { MOZ_CRASH(); }
2979 ++
2980 ++ void buildFakeExitFrame(Register, uint32_t*) { MOZ_CRASH(); }
2981 ++ bool buildOOLFakeExitFrame(void*) { MOZ_CRASH(); }
2982 ++
2983 ++ void setPrinter(Sprinter*) { MOZ_CRASH(); }
2984 ++ Operand ToPayload(Operand base) { MOZ_CRASH(); }
2985 ++ Address ToPayload(Address) { MOZ_CRASH(); }
2986 ++
2987 ++ Register getStackPointer() const { MOZ_CRASH(); }
2988 ++
2989 ++ void handleFailureWithHandlerTail(Label* profilerExitTail,
2990 ++ Label* bailoutTail) { MOZ_CRASH(); }
2991 ++
2992 ++ // Instrumentation for entering and leaving the profiler.
2993 ++ void profilerEnterFrame(Register, Register) { MOZ_CRASH(); }
2994 ++ void profilerExitFrame() { MOZ_CRASH(); }
2995 ++};
2996 ++
2997 ++typedef MacroAssemblerRiscv64 MacroAssemblerSpecific;
2998 ++
2999 ++static inline bool GetTempRegForIntArg(uint32_t, uint32_t, Register*) {
3000 ++ MOZ_CRASH();
3001 ++}
3002 ++
3003 ++} // namespace jit
3004 ++} // namespace js
3005 ++
3006 ++#endif /* jit_riscv64_MacroAssembler_riscv64_h */
3007 +diff --git a/js/src/jit/riscv64/MoveEmitter-riscv64.h b/js/src/jit/riscv64/MoveEmitter-riscv64.h
3008 +new file mode 100644
3009 +index 0000000000..24ca3aebb2
3010 +--- /dev/null
3011 ++++ b/js/src/jit/riscv64/MoveEmitter-riscv64.h
3012 +@@ -0,0 +1,32 @@
3013 ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3014 ++ * vim: set ts=8 sts=2 et sw=2 tw=80:
3015 ++ * This Source Code Form is subject to the terms of the Mozilla Public
3016 ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
3017 ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
3018 ++
3019 ++#ifndef jit_riscv64_MoveEmitter_riscv64_h
3020 ++#define jit_riscv64_MoveEmitter_riscv64_h
3021 ++
3022 ++#include "mozilla/Assertions.h"
3023 ++
3024 ++namespace js {
3025 ++namespace jit {
3026 ++
3027 ++class MacroAssemblerRiscv64;
3028 ++class MoveResolver;
3029 ++struct Register;
3030 ++
3031 ++class MoveEmitterRiscv64 {
3032 ++ public:
3033 ++ explicit MoveEmitterRiscv64(MacroAssemblerRiscv64&) { MOZ_CRASH(); }
3034 ++ void emit(const MoveResolver&) { MOZ_CRASH(); }
3035 ++ void finish() { MOZ_CRASH(); }
3036 ++ void setScratchRegister(Register) { MOZ_CRASH(); }
3037 ++};
3038 ++
3039 ++typedef MoveEmitterRiscv64 MoveEmitter;
3040 ++
3041 ++} // namespace jit
3042 ++} // namespace js
3043 ++
3044 ++#endif /* jit_riscv64_MoveEmitter_riscv64_h */
3045 +diff --git a/js/src/jit/riscv64/SharedICHelpers-riscv64-inl.h b/js/src/jit/riscv64/SharedICHelpers-riscv64-inl.h
3046 +new file mode 100644
3047 +index 0000000000..7c6f7b7c20
3048 +--- /dev/null
3049 ++++ b/js/src/jit/riscv64/SharedICHelpers-riscv64-inl.h
3050 +@@ -0,0 +1,34 @@
3051 ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3052 ++ * vim: set ts=8 sts=2 et sw=2 tw=80:
3053 ++ * This Source Code Form is subject to the terms of the Mozilla Public
3054 ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
3055 ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
3056 ++
3057 ++#ifndef jit_riscv64_SharedICHelpers_riscv64_inl_h
3058 ++#define jit_riscv64_SharedICHelpers_riscv64_inl_h
3059 ++
3060 ++#include "jit/SharedICHelpers.h"
3061 ++
3062 ++namespace js {
3063 ++namespace jit {
3064 ++
3065 ++inline void EmitBaselineTailCallVM(TrampolinePtr, MacroAssembler&, uint32_t) {
3066 ++ MOZ_CRASH();
3067 ++}
3068 ++inline void EmitBaselineCreateStubFrameDescriptor(MacroAssembler&, Register,
3069 ++ uint32_t) {
3070 ++ MOZ_CRASH();
3071 ++}
3072 ++inline void EmitBaselineCallVM(TrampolinePtr, MacroAssembler&) { MOZ_CRASH(); }
3073 ++
3074 ++static const uint32_t STUB_FRAME_SIZE = 0;
3075 ++static const uint32_t STUB_FRAME_SAVED_STUB_OFFSET = 0;
3076 ++
3077 ++inline void EmitBaselineEnterStubFrame(MacroAssembler&, Register) {
3078 ++ MOZ_CRASH();
3079 ++}
3080 ++
3081 ++} // namespace jit
3082 ++} // namespace js
3083 ++
3084 ++#endif /* jit_riscv64_SharedICHelpers_riscv64_inl_h */
3085 +diff --git a/js/src/jit/riscv64/SharedICHelpers-riscv64.h b/js/src/jit/riscv64/SharedICHelpers-riscv64.h
3086 +new file mode 100644
3087 +index 0000000000..205b6615da
3088 +--- /dev/null
3089 ++++ b/js/src/jit/riscv64/SharedICHelpers-riscv64.h
3090 +@@ -0,0 +1,35 @@
3091 ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3092 ++ * vim: set ts=8 sts=2 et sw=2 tw=80:
3093 ++ * This Source Code Form is subject to the terms of the Mozilla Public
3094 ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
3095 ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
3096 ++
3097 ++#ifndef jit_riscv64_SharedICHelpers_riscv64_h
3098 ++#define jit_riscv64_SharedICHelpers_riscv64_h
3099 ++
3100 ++#include "jit/MacroAssembler.h"
3101 ++#include "jit/SharedICRegisters.h"
3102 ++
3103 ++namespace js {
3104 ++namespace jit {
3105 ++
3106 ++static const size_t ICStackValueOffset = 0;
3107 ++
3108 ++inline void EmitRestoreTailCallReg(MacroAssembler&) { MOZ_CRASH(); }
3109 ++inline void EmitRepushTailCallReg(MacroAssembler&) { MOZ_CRASH(); }
3110 ++inline void EmitCallIC(MacroAssembler&, CodeOffset*) { MOZ_CRASH(); }
3111 ++inline void EmitReturnFromIC(MacroAssembler&) { MOZ_CRASH(); }
3112 ++inline void EmitBaselineLeaveStubFrame(MacroAssembler&, bool v = false) {
3113 ++ MOZ_CRASH();
3114 ++}
3115 ++inline void EmitStubGuardFailure(MacroAssembler&) { MOZ_CRASH(); }
3116 ++
3117 ++template <typename T>
3118 ++inline void EmitPreBarrier(MacroAssembler&, T, MIRType) {
3119 ++ MOZ_CRASH();
3120 ++}
3121 ++
3122 ++} // namespace jit
3123 ++} // namespace js
3124 ++
3125 ++#endif /* jit_riscv64_SharedICHelpers_riscv64_h */
3126 +diff --git a/js/src/jit/riscv64/SharedICRegisters-riscv64.h b/js/src/jit/riscv64/SharedICRegisters-riscv64.h
3127 +new file mode 100644
3128 +index 0000000000..f1d5f165d8
3129 +--- /dev/null
3130 ++++ b/js/src/jit/riscv64/SharedICRegisters-riscv64.h
3131 +@@ -0,0 +1,38 @@
3132 ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3133 ++ * vim: set ts=8 sts=2 et sw=2 tw=80:
3134 ++ * This Source Code Form is subject to the terms of the Mozilla Public
3135 ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
3136 ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
3137 ++
3138 ++#ifndef jit_riscv64_SharedICRegisters_riscv64_h
3139 ++#define jit_riscv64_SharedICRegisters_riscv64_h
3140 ++
3141 ++#include "jit/riscv64/Assembler-riscv64.h"
3142 ++#include "jit/Registers.h"
3143 ++#include "jit/RegisterSets.h"
3144 ++
3145 ++namespace js {
3146 ++namespace jit {
3147 ++
3148 ++static constexpr Register BaselineFrameReg{Registers::invalid_reg};
3149 ++static constexpr Register BaselineStackReg{Registers::invalid_reg};
3150 ++
3151 ++static constexpr ValueOperand R0 = JSReturnOperand;
3152 ++static constexpr ValueOperand R1 = JSReturnOperand;
3153 ++static constexpr ValueOperand R2 = JSReturnOperand;
3154 ++
3155 ++static constexpr Register ICTailCallReg{Registers::invalid_reg};
3156 ++static constexpr Register ICStubReg{Registers::invalid_reg};
3157 ++
3158 ++static constexpr Register ExtractTemp0{Registers::invalid_reg};
3159 ++static constexpr Register ExtractTemp1{Registers::invalid_reg};
3160 ++
3161 ++static constexpr FloatRegister FloatReg0;
3162 ++static constexpr FloatRegister FloatReg1;
3163 ++static constexpr FloatRegister FloatReg2;
3164 ++static constexpr FloatRegister FloatReg3;
3165 ++
3166 ++} // namespace jit
3167 ++} // namespace js
3168 ++
3169 ++#endif /* jit_riscv64_SharedICRegisters_riscv64_h */
3170 +diff --git a/js/src/jit/riscv64/Trampoline-riscv64.cpp b/js/src/jit/riscv64/Trampoline-riscv64.cpp
3171 +new file mode 100644
3172 +index 0000000000..0774254cf4
3173 +--- /dev/null
3174 ++++ b/js/src/jit/riscv64/Trampoline-riscv64.cpp
3175 +@@ -0,0 +1,67 @@
3176 ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3177 ++ * vim: set ts=8 sts=2 et sw=2 tw=80:
3178 ++ * This Source Code Form is subject to the terms of the Mozilla Public
3179 ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
3180 ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
3181 ++
3182 ++#include "jit/Bailouts.h"
3183 ++#include "jit/BaselineIC.h"
3184 ++#include "jit/JitRuntime.h"
3185 ++#include "vm/Realm.h"
3186 ++
3187 ++using namespace js;
3188 ++using namespace js::jit;
3189 ++
3190 ++// This file includes stubs for generating the JIT trampolines when there is no
3191 ++// JIT backend, and also includes implementations for assorted random things
3192 ++// which can't be implemented in headers.
3193 ++
3194 ++void JitRuntime::generateEnterJIT(JSContext*, MacroAssembler&) { MOZ_CRASH(); }
3195 ++// static
3196 ++mozilla::Maybe<::JS::ProfilingFrameIterator::RegisterState>
3197 ++JitRuntime::getCppEntryRegisters(JitFrameLayout* frameStackAddress) {
3198 ++ return mozilla::Nothing{};
3199 ++}
3200 ++void JitRuntime::generateInvalidator(MacroAssembler&, Label*) { MOZ_CRASH(); }
3201 ++void JitRuntime::generateArgumentsRectifier(MacroAssembler&,
3202 ++ ArgumentsRectifierKind kind) {
3203 ++ MOZ_CRASH();
3204 ++}
3205 ++JitRuntime::BailoutTable JitRuntime::generateBailoutTable(MacroAssembler&,
3206 ++ Label*, uint32_t) {
3207 ++ MOZ_CRASH();
3208 ++}
3209 ++void JitRuntime::generateBailoutHandler(MacroAssembler&, Label*) {
3210 ++ MOZ_CRASH();
3211 ++}
3212 ++uint32_t JitRuntime::generatePreBarrier(JSContext*, MacroAssembler&, MIRType) {
3213 ++ MOZ_CRASH();
3214 ++}
3215 ++void JitRuntime::generateExceptionTailStub(MacroAssembler&, Label*) {
3216 ++ MOZ_CRASH();
3217 ++}
3218 ++void JitRuntime::generateBailoutTailStub(MacroAssembler&, Label*) {
3219 ++ MOZ_CRASH();
3220 ++}
3221 ++void JitRuntime::generateProfilerExitFrameTailStub(MacroAssembler&, Label*) {
3222 ++ MOZ_CRASH();
3223 ++}
3224 ++
3225 ++bool JitRuntime::generateVMWrapper(JSContext*, MacroAssembler&,
3226 ++ const VMFunctionData&, DynFn, uint32_t*) {
3227 ++ MOZ_CRASH();
3228 ++}
3229 ++
3230 ++FrameSizeClass FrameSizeClass::FromDepth(uint32_t) { MOZ_CRASH(); }
3231 ++FrameSizeClass FrameSizeClass::ClassLimit() { MOZ_CRASH(); }
3232 ++uint32_t FrameSizeClass::frameSize() const { MOZ_CRASH(); }
3233 ++
3234 ++BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator& iter,
3235 ++ BailoutStack* bailout) {
3236 ++ MOZ_CRASH();
3237 ++}
3238 ++
3239 ++BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator& iter,
3240 ++ InvalidationBailoutStack* bailout) {
3241 ++ MOZ_CRASH();
3242 ++}
3243 +diff --git a/js/src/jit/shared/Assembler-shared.h b/js/src/jit/shared/Assembler-shared.h
3244 +index fcabddd98b..19cf397df1 100644
3245 +--- a/js/src/jit/shared/Assembler-shared.h
3246 ++++ b/js/src/jit/shared/Assembler-shared.h
3247 +@@ -26,13 +26,14 @@
3248 +
3249 + #if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || \
3250 + defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) || \
3251 +- defined(JS_CODEGEN_LOONG64)
3252 ++ defined(JS_CODEGEN_LOONG64) || defined(JS_CODEGEN_RISCV64)
3253 + // Push return addresses callee-side.
3254 + # define JS_USE_LINK_REGISTER
3255 + #endif
3256 +
3257 + #if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) || \
3258 +- defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_LOONG64)
3259 ++ defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_LOONG64) || \
3260 ++ defined(JS_CODEGEN_RISCV64)
3261 + // JS_CODELABEL_LINKMODE gives labels additional metadata
3262 + // describing how Bind() should patch them.
3263 + # define JS_CODELABEL_LINKMODE
3264 +diff --git a/js/src/util/Poison.h b/js/src/util/Poison.h
3265 +index cb8e1abc64..a6a2d2f12b 100644
3266 +--- a/js/src/util/Poison.h
3267 ++++ b/js/src/util/Poison.h
3268 +@@ -95,6 +95,8 @@ const uint8_t JS_SCOPE_DATA_TRAILING_NAMES_PATTERN = 0xCC;
3269 + # define JS_SWEPT_CODE_PATTERN 0x01 // undefined instruction
3270 + #elif defined(JS_CODEGEN_LOONG64)
3271 + # define JS_SWEPT_CODE_PATTERN 0x01 // undefined instruction
3272 ++#elif defined(JS_CODEGEN_RISCV64)
3273 ++# define JS_SWEPT_CODE_PATTERN 0x01 // undefined instruction
3274 + #else
3275 + # error "JS_SWEPT_CODE_PATTERN not defined for this platform"
3276 + #endif
3277 +diff --git a/js/src/wasm/WasmBCMemory.cpp b/js/src/wasm/WasmBCMemory.cpp
3278 +index 94e739090b..2c226dadd5 100644
3279 +--- a/js/src/wasm/WasmBCMemory.cpp
3280 ++++ b/js/src/wasm/WasmBCMemory.cpp
3281 +@@ -1214,6 +1214,22 @@ static void Deallocate(BaseCompiler* bc, RegI32 rv, const Temps& temps) {
3282 + bc->maybeFree(temps.t2);
3283 + }
3284 +
3285 ++#elif defined(JS_CODEGEN_RISCV64)
3286 ++
3287 ++struct Temps {
3288 ++ RegI32 t0;
3289 ++};
3290 ++
3291 ++static void PopAndAllocate(BaseCompiler* bc, ValType type,
3292 ++ Scalar::Type viewType, AtomicOp op, RegI32* rd,
3293 ++ RegI32* rv, Temps* temps) {}
3294 ++
3295 ++static void Perform(BaseCompiler* bc, const MemoryAccessDesc& access,
3296 ++ BaseIndex srcAddr, AtomicOp op, RegI32 rv, RegI32 rd,
3297 ++ const Temps& temps) {}
3298 ++
3299 ++static void Deallocate(BaseCompiler*, RegI32, const Temps&) {}
3300 ++
3301 + #elif defined(JS_CODEGEN_NONE)
3302 +
3303 + using Temps = Nothing;
3304 +@@ -1375,6 +1391,17 @@ static void Deallocate(BaseCompiler* bc, AtomicOp op, RegI64 rv, RegI64 temp) {
3305 + bc->freeI64(temp);
3306 + }
3307 +
3308 ++#elif defined(JS_CODEGEN_RISCV64)
3309 ++
3310 ++static void PopAndAllocate(BaseCompiler* bc, AtomicOp op, RegI64* rd,
3311 ++ RegI64* rv, RegI64* temp) {}
3312 ++
3313 ++static void Perform(BaseCompiler* bc, const MemoryAccessDesc& access,
3314 ++ BaseIndex srcAddr, AtomicOp op, RegI64 rv, RegI64 temp,
3315 ++ RegI64 rd) {}
3316 ++
3317 ++static void Deallocate(BaseCompiler* bc, AtomicOp op, RegI64 rv, RegI64 temp) {}
3318 ++
3319 + #elif defined(JS_CODEGEN_NONE)
3320 +
3321 + static void PopAndAllocate(BaseCompiler*, AtomicOp, RegI64*, RegI64*, RegI64*) {
3322 +diff --git a/js/src/wasm/WasmCompile.cpp b/js/src/wasm/WasmCompile.cpp
3323 +index 26534bca4e..403e26414b 100644
3324 +--- a/js/src/wasm/WasmCompile.cpp
3325 ++++ b/js/src/wasm/WasmCompile.cpp
3326 +@@ -74,6 +74,8 @@ uint32_t wasm::ObservedCPUFeatures() {
3327 + #elif defined(JS_CODEGEN_LOONG64)
3328 + MOZ_ASSERT(jit::GetLOONG64Flags() <= (UINT32_MAX >> ARCH_BITS));
3329 + return LOONG64 | (jit::GetLOONG64Flags() << ARCH_BITS);
3330 ++#elif defined(JS_CODEGEN_RISCV64)
3331 ++ return 0;
3332 + #elif defined(JS_CODEGEN_NONE)
3333 + return 0;
3334 + #else
3335 +diff --git a/js/src/wasm/WasmFrameIter.cpp b/js/src/wasm/WasmFrameIter.cpp
3336 +index e612e05704..0ce3453287 100644
3337 +--- a/js/src/wasm/WasmFrameIter.cpp
3338 ++++ b/js/src/wasm/WasmFrameIter.cpp
3339 +@@ -384,6 +384,12 @@ static const unsigned PushedFP = 16;
3340 + static const unsigned SetFP = 20;
3341 + static const unsigned PoppedFP = 4;
3342 + static const unsigned PoppedFPJitEntry = 0;
3343 ++#elif defined(JS_CODEGEN_RISCV64)
3344 ++static const unsigned PushedRetAddr = 0;
3345 ++static const unsigned PushedFP = 1;
3346 ++static const unsigned SetFP = 2;
3347 ++static const unsigned PoppedFP = 3;
3348 ++static const unsigned PoppedFPJitEntry = 4;
3349 + #elif defined(JS_CODEGEN_NONE)
3350 + // Synthetic values to satisfy asserts and avoid compiler warnings.
3351 + static const unsigned PushedRetAddr = 0;
3352 +diff --git a/js/src/wasm/WasmSignalHandlers.cpp b/js/src/wasm/WasmSignalHandlers.cpp
3353 +index f74368b954..9521441f02 100644
3354 +--- a/js/src/wasm/WasmSignalHandlers.cpp
3355 ++++ b/js/src/wasm/WasmSignalHandlers.cpp
3356 +@@ -157,6 +157,11 @@ using mozilla::DebugOnly;
3357 + # define R01_sig(p) ((p)->uc_mcontext.gp_regs[1])
3358 + # define R32_sig(p) ((p)->uc_mcontext.gp_regs[32])
3359 + # endif
3360 ++# if defined(__linux__) && defined(__riscv) && __riscv_xlen == 64
3361 ++# define EPC_sig(p) ((p)->uc_mcontext.__gregs[0])
3362 ++# define X02_sig(p) ((p)->uc_mcontext.__gregs[2])
3363 ++# define X08_sig(p) ((p)->uc_mcontext.__gregs[8])
3364 ++# endif
3365 + # if defined(__linux__) && defined(__loongarch__)
3366 + # define EPC_sig(p) ((p)->uc_mcontext.pc)
3367 + # define RRA_sig(p) ((p)->uc_mcontext.gregs[1])
3368 +@@ -405,6 +410,10 @@ struct macos_aarch64_context {
3369 + # define FP_sig(p) RFP_sig(p)
3370 + # define SP_sig(p) RSP_sig(p)
3371 + # define LR_sig(p) RRA_sig(p)
3372 ++# elif defined(__riscv) && __riscv_xlen == 64
3373 ++# define PC_sig(p) EPC_sig(p)
3374 ++# define SP_sig(p) X02_sig(p)
3375 ++# define FP_sig(p) X08_sig(p)
3376 + # endif
3377 +
3378 + static void SetContextPC(CONTEXT* context, uint8_t* pc) {
3379 +diff --git a/python/mozbuild/mozbuild/vendor/vendor_rust.py b/python/mozbuild/mozbuild/vendor/vendor_rust.py
3380 +index 31baea4290..7394ccaf40 100644
3381 +--- a/python/mozbuild/mozbuild/vendor/vendor_rust.py
3382 ++++ b/python/mozbuild/mozbuild/vendor/vendor_rust.py
3383 +@@ -98,6 +98,7 @@ TOLERATED_DUPES = {
3384 + "libloading": 2,
3385 + "memoffset": 2,
3386 + "mio": 2,
3387 ++ "nix": 2,
3388 + # Transition from time 0.1 to 0.3 underway, but chrono is stuck on 0.1
3389 + # and hasn't been updated in 1.5 years (an hypothetical update is
3390 + # expected to remove the dependency on time altogether).
3391 +diff --git a/supply-chain/config.toml b/supply-chain/config.toml
3392 +index bb3dd733e8..371cbca809 100644
3393 +--- a/supply-chain/config.toml
3394 ++++ b/supply-chain/config.toml
3395 +@@ -1,6 +1,10 @@
3396 +
3397 + # cargo-vet config file
3398 +
3399 ++[policy.viaduct]
3400 ++audit-as-crates-io = true
3401 ++notes = "I don't know, do as what rust-vet tells me to do"
3402 ++
3403 + [policy.async-task]
3404 + audit-as-crates-io = true
3405 + notes = "This is the upstream code plus an extra fix that hasn't been released yet, see bug 1746533."
3406 +diff --git a/toolkit/library/rust/shared/Cargo.toml b/toolkit/library/rust/shared/Cargo.toml
3407 +index dbd7770326..ffbadcb14c 100644
3408 +--- a/toolkit/library/rust/shared/Cargo.toml
3409 ++++ b/toolkit/library/rust/shared/Cargo.toml
3410 +@@ -38,7 +38,7 @@ tokio-reactor = { version = "=0.1.3", optional = true }
3411 + # audioipc2-client and audioipc2-server.
3412 + tokio-threadpool = { version = "=0.1.17", optional = true }
3413 + encoding_glue = { path = "../../../../intl/encoding_glue" }
3414 +-authenticator = "0.3.1"
3415 ++authenticator = { git = "https://github.com/mozilla/authenticator-rs", rev = "b85bccf0527e42c877573029e8d35ff13ef06f9d" }
3416 + gkrust_utils = { path = "../../../../xpcom/rust/gkrust_utils" }
3417 + gecko_logger = { path = "../../../../xpcom/rust/gecko_logger" }
3418 + rsdparsa_capi = { path = "../../../../dom/media/webrtc/sdp/rsdparsa_capi" }
3419 +@@ -72,6 +72,7 @@ midir_impl = { path = "../../../../dom/midi/midir_impl", optional = true }
3420 + dom = { path = "../../../../dom/base/rust" }
3421 + origin-trials-ffi = { path = "../../../../dom/origin-trials/ffi" }
3422 + jog = { path = "../../../components/glean/bindings/jog" }
3423 ++midir = { version = "0.8.0" }
3424 +
3425 + # Note: `modern_sqlite` means rusqlite's bindings file be for a sqlite with
3426 + # version less than or equal to what we link to. This isn't a problem because we
3427
3428 diff --git a/www-client/firefox/files/firefox-wayland.sh b/www-client/firefox/files/firefox-wayland.sh
3429 deleted file mode 100644
3430 index 4428025..0000000
3431 --- a/www-client/firefox/files/firefox-wayland.sh
3432 +++ /dev/null
3433 @@ -1,7 +0,0 @@
3434 -#!/bin/sh
3435 -
3436 -#
3437 -# Run Mozilla Firefox under Wayland
3438 -#
3439 -export MOZ_ENABLE_WAYLAND=1
3440 -exec @PREFIX@/bin/firefox "$@"
3441
3442 diff --git a/www-client/firefox/files/firefox-x11.sh b/www-client/firefox/files/firefox-x11.sh
3443 deleted file mode 100644
3444 index 7565566..0000000
3445 --- a/www-client/firefox/files/firefox-x11.sh
3446 +++ /dev/null
3447 @@ -1,7 +0,0 @@
3448 -#!/bin/sh
3449 -
3450 -#
3451 -# Run Mozilla Firefox on X11
3452 -#
3453 -export MOZ_DISABLE_WAYLAND=1
3454 -exec @PREFIX@/bin/firefox "$@"
3455
3456 diff --git a/www-client/firefox/files/firefox.sh b/www-client/firefox/files/firefox.sh
3457 deleted file mode 100644
3458 index c08d555..0000000
3459 --- a/www-client/firefox/files/firefox.sh
3460 +++ /dev/null
3461 @@ -1,128 +0,0 @@
3462 -#!/bin/bash
3463 -
3464 -##
3465 -## Usage:
3466 -##
3467 -## $ firefox
3468 -##
3469 -## This script is meant to run Mozilla Firefox in Gentoo.
3470 -
3471 -cmdname=$(basename "$0")
3472 -
3473 -##
3474 -## Variables
3475 -##
3476 -MOZ_ARCH=$(uname -m)
3477 -case ${MOZ_ARCH} in
3478 - x86_64|s390x|sparc64)
3479 - MOZ_LIB_DIR="@PREFIX@/lib64"
3480 - SECONDARY_LIB_DIR="@PREFIX@/lib"
3481 - ;;
3482 - *)
3483 - MOZ_LIB_DIR="@PREFIX@/lib"
3484 - SECONDARY_LIB_DIR="@PREFIX@/lib64"
3485 - ;;
3486 -esac
3487 -
3488 -MOZ_FIREFOX_FILE="firefox"
3489 -
3490 -if [[ ! -r ${MOZ_LIB_DIR}/firefox/${MOZ_FIREFOX_FILE} ]]; then
3491 - if [[ ! -r ${SECONDARY_LIB_DIR}/firefox/${MOZ_FIREFOX_FILE} ]]; then
3492 - echo "Error: ${MOZ_LIB_DIR}/firefox/${MOZ_FIREFOX_FILE} not found" >&2
3493 - if [[ -d $SECONDARY_LIB_DIR ]]; then
3494 - echo " ${SECONDARY_LIB_DIR}/firefox/${MOZ_FIREFOX_FILE} not found" >&2
3495 - fi
3496 - exit 1
3497 - fi
3498 - MOZ_LIB_DIR="$SECONDARY_LIB_DIR"
3499 -fi
3500 -MOZILLA_FIVE_HOME="${MOZ_LIB_DIR}/firefox"
3501 -MOZ_EXTENSIONS_PROFILE_DIR="${HOME}/.mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
3502 -MOZ_PROGRAM="${MOZILLA_FIVE_HOME}/${MOZ_FIREFOX_FILE}"
3503 -DESKTOP_FILE="firefox"
3504 -
3505 -##
3506 -## Enable Wayland backend?
3507 -##
3508 -if @DEFAULT_WAYLAND@ && [[ -z ${MOZ_DISABLE_WAYLAND} ]]; then
3509 - if [[ -n "$WAYLAND_DISPLAY" ]]; then
3510 - DESKTOP_FILE="firefox-wayland"
3511 - export MOZ_ENABLE_WAYLAND=1
3512 - fi
3513 -elif [[ -n ${MOZ_DISABLE_WAYLAND} ]]; then
3514 - DESKTOP_FILE="firefox-x11"
3515 -fi
3516 -
3517 -##
3518 -## Use D-Bus remote exclusively when there's Wayland display.
3519 -##
3520 -if [[ -n "${WAYLAND_DISPLAY}" ]]; then
3521 - export MOZ_DBUS_REMOTE=1
3522 -fi
3523 -
3524 -##
3525 -## Make sure that we set the plugin path
3526 -##
3527 -MOZ_PLUGIN_DIR="plugins"
3528 -
3529 -if [[ -n "${MOZ_PLUGIN_PATH}" ]]; then
3530 - MOZ_PLUGIN_PATH=${MOZ_PLUGIN_PATH}:${MOZ_LIB_DIR}/mozilla/${MOZ_PLUGIN_DIR}
3531 -else
3532 - MOZ_PLUGIN_PATH=${MOZ_LIB_DIR}/mozilla/${MOZ_PLUGIN_DIR}
3533 -fi
3534 -
3535 -if [[ -d "${SECONDARY_LIB_DIR}/mozilla/${MOZ_PLUGIN_DIR}" ]]; then
3536 - MOZ_PLUGIN_PATH=${MOZ_PLUGIN_PATH}:${SECONDARY_LIB_DIR}/mozilla/${MOZ_PLUGIN_DIR}
3537 -fi
3538 -
3539 -export MOZ_PLUGIN_PATH
3540 -
3541 -##
3542 -## Set MOZ_APP_LAUNCHER for gnome-session
3543 -##
3544 -export MOZ_APP_LAUNCHER="@PREFIX@/bin/${cmdname}"
3545 -
3546 -##
3547 -## Disable the GNOME crash dialog, Moz has it's own
3548 -##
3549 -if [[ "$XDG_CURRENT_DESKTOP" == "GNOME" ]]; then
3550 - GNOME_DISABLE_CRASH_DIALOG=1
3551 - export GNOME_DISABLE_CRASH_DIALOG
3552 -fi
3553 -
3554 -##
3555 -## Enable Xinput2 (#617344)
3556 -##
3557 -
3558 -# respect user settings
3559 -MOZ_USE_XINPUT2=${MOZ_USE_XINPUT2:-auto}
3560 -
3561 -if [[ ${MOZ_USE_XINPUT2} == auto && -n ${WAYLAND_DISPLAY} ]]; then
3562 - # enabling XINPUT2 should be safe for all wayland users
3563 - MOZ_USE_XINPUT2=1
3564 -elif [[ ${MOZ_USE_XINPUT2} == auto && ${XDG_CURRENT_DESKTOP^^} == KDE ]]; then
3565 - # XINPUT2 is known to cause problems for KWin users
3566 - MOZ_USE_XINPUT2=0
3567 -elif [[ ${MOZ_USE_XINPUT2} == auto && ${XDG_CURRENT_DESKTOP^^} == LXQT ]]; then
3568 - # LXQt uses KWin
3569 - MOZ_USE_XINPUT2=0
3570 -elif [[ ${MOZ_USE_XINPUT2} == auto ]]; then
3571 - # should work on Mate, Xfce, FluxBox, OpenBox and all the others ...
3572 - MOZ_USE_XINPUT2=1
3573 -fi
3574 -
3575 -[[ ${MOZ_USE_XINPUT2} != 0 ]] && export MOZ_USE_XINPUT2=${MOZ_USE_XINPUT2}
3576 -
3577 -# Don't throw "old profile" dialog box.
3578 -export MOZ_ALLOW_DOWNGRADE=1
3579 -
3580 -##
3581 -## Route to the correct .desktop file to get proper
3582 -## name and actions
3583 -##
3584 -if [[ $@ != *"--name "* ]]; then
3585 - set -- --name "${DESKTOP_FILE}" "$@"
3586 -fi
3587 -
3588 -# Run the browser
3589 -exec ${MOZ_PROGRAM} "$@"
3590
3591 diff --git a/www-client/firefox/files/gentoo-hwaccel-prefs.js-r2 b/www-client/firefox/files/gentoo-hwaccel-prefs.js-r2
3592 new file mode 100644
3593 index 0000000..48025ca
3594 --- /dev/null
3595 +++ b/www-client/firefox/files/gentoo-hwaccel-prefs.js-r2
3596 @@ -0,0 +1,5 @@
3597 +/* Force hardware accelerated rendering due to USE=hwaccel */
3598 +pref("gfx.webrender.all", true);
3599 +pref("layers.acceleration.force-enabled", true);
3600 +pref("media.hardware-video-decoding.enabled", true);
3601 +pref("webgl.force-enabled", true);
3602
3603 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
3604 deleted file mode 100644
3605 index 39ebd6a..0000000
3606 --- a/www-client/firefox/files/makotokato-riscv64-support-and-zenithal-backported.patch
3607 +++ /dev/null
3608 @@ -1,47126 +0,0 @@
3609 -From: Zenithal <i@××××××××.me>
3610 -
3611 -Some changes would be rejected/ignored when patching firefox 92 src,
3612 -so I commented out some blocks, see these #-leading block below
3613 -
3614 -From be9cbd86b4c121dbdb626f8c373fd809f25bc23e Mon Sep 17 00:00:00 2001
3615 -From: Makoto Kato <m_kato@×××××××××××××.jp>
3616 -Date: Sun, 13 Jun 2021 04:06:39 +0000
3617 -Subject: [PATCH] Update authenticator-rs
3618 -
3619 ----
3620 - .cargo/config.in | 5 +
3621 - Cargo.lock | 3 +-
3622 - .../rust/authenticator/.cargo-checksum.json | 2 +-
3623 - third_party/rust/authenticator/.clippy.toml | 2 +
3624 - third_party/rust/authenticator/.flake8 | 4 +
3625 - .../authenticator/.pre-commit-config.yaml | 42 +
3626 - third_party/rust/authenticator/.travis.yml | 42 +
3627 - third_party/rust/authenticator/Cargo.lock | 1603 -----------------
3628 - third_party/rust/authenticator/Cargo.toml | 131 +-
3629 - third_party/rust/authenticator/build.rs | 2 +
3630 - .../authenticator/src/linux/hidwrapper.rs | 3 +
3631 - .../authenticator/src/linux/ioctl_riscv64.rs | 5 +
3632 - toolkit/library/rust/shared/Cargo.toml | 2 +-
3633 - 13 files changed, 154 insertions(+), 1692 deletions(-)
3634 - create mode 100644 third_party/rust/authenticator/.clippy.toml
3635 - create mode 100644 third_party/rust/authenticator/.flake8
3636 - create mode 100644 third_party/rust/authenticator/.pre-commit-config.yaml
3637 - create mode 100644 third_party/rust/authenticator/.travis.yml
3638 - delete mode 100644 third_party/rust/authenticator/Cargo.lock
3639 - create mode 100644 third_party/rust/authenticator/src/linux/ioctl_riscv64.rs
3640 -
3641 -diff --unified --recursive --text a/.cargo/config.in b/.cargo/config.in
3642 ---- a/.cargo/config.in 2022-03-10 14:19:43.020478706 +0800
3643 -+++ b/.cargo/config.in 2022-03-10 14:21:21.873044017 +0800
3644 -@@ -22,11 +22,6 @@
3645 - replace-with = "vendored-sources"
3646 - rev = "3bfc47d9a571d0842676043ba60716318e946c06"
3647 -
3648 --[source."https://github.com/mozilla/midir.git"]
3649 --git = "https://github.com/mozilla/midir.git"
3650 --replace-with = "vendored-sources"
3651 --rev = "4c11f0ffb5d6a10de4aff40a7b81218b33b94e6f"
3652 --
3653 - [source."https://github.com/mozilla/l10nregistry-rs.git"]
3654 - git = "https://github.com/mozilla/l10nregistry-rs.git"
3655 - replace-with = "vendored-sources"
3656 -@@ -57,6 +52,16 @@
3657 - replace-with = "vendored-sources"
3658 - rev = "a1a6ba41f0c610ebe751639f25f037474ca52941"
3659 -
3660 -+[source."https://github.com/makotokato/midir.git"]
3661 -+git = "https://github.com/makotokato/midir.git"
3662 -+replace-with = "vendored-sources"
3663 -+rev = "6140b2825dd4dc2b40e49e154ca7596e7b9a131a"
3664 -+
3665 -+[source."https://github.com/makotokato/authenticator-rs"]
3666 -+git = "https://github.com/makotokato/authenticator-rs"
3667 -+replace-with = "vendored-sources"
3668 -+rev = "eed8919d50559f4959e2d7d2af7b4d48869b5366"
3669 -+
3670 - [source."https://github.com/kinetiknz/mio-named-pipes"]
3671 - git = "https://github.com/kinetiknz/mio-named-pipes"
3672 - replace-with = "vendored-sources"
3673 -diff --git a/Cargo.lock b/Cargo.lock
3674 -index 7e17939fad48b..8519d3d0e95a6 100644
3675 ---- a/Cargo.lock
3676 -+++ b/Cargo.lock
3677 -@@ -316,8 +316,7 @@ dependencies = [
3678 - [[package]]
3679 - name = "authenticator"
3680 - version = "0.3.1"
3681 --source = "registry+https://github.com/rust-lang/crates.io-index"
3682 --checksum = "08cee7a0952628fde958e149507c2bb321ab4fccfafd225da0b20adc956ef88a"
3683 -+source = "git+https://github.com/makotokato/authenticator-rs?rev=eed8919d50559f4959e2d7d2af7b4d48869b5366#eed8919d50559f4959e2d7d2af7b4d48869b5366"
3684 - dependencies = [
3685 - "bitflags",
3686 - "core-foundation",
3687 -diff --git a/third_party/rust/authenticator/.cargo-checksum.json b/third_party/rust/authenticator/.cargo-checksum.json
3688 -index ce451ad09df4f..9791345c9de54 100644
3689 ---- a/third_party/rust/authenticator/.cargo-checksum.json
3690 -+++ b/third_party/rust/authenticator/.cargo-checksum.json
3691 -@@ -1 +1 @@
3692 --{"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",
3693 "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/io
3694 ctl_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":"2d8b265cd39a9f46
3695 816f83d5a5df0701c13eb842bc609325bad42ce50add3bf0","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":"260f1a8ae04896c0eb35ab0914e11ca9291e
3696 7317a086c94328aa219c0e1fc1d2","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":"5e378147e113e20160a45d395b717bd3deecb3
3697 27247c24b6735035f7d50861b7","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/virtu
3698 almanager.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
3699 /requirements.txt":"8236aa3dedad886f213c9b778fec80b037212d30e640b458984110211d546005","webdriver-tools/webdriver-driver.py":"82327c26ba271d1689acc87b612ab8436cb5475f0a3c0dba7baa06e7f6f5e19c"},"package":"08cee7a0952628fde958e149507c2bb321ab4fccfafd225da0b20adc956ef88a"}
3700 -\ No newline at end of file
3701 -+{"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":"9fc5bcdd1e4f32e58ae920f96f40619a870b0a1b8d05db650803b2402a37
3702 fbf9","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":"ed55caa40fd
3703 518d67bb67d5af08f9adcab34f89e0ca591142d45b87f172926dd","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":"fbda309934ad8bda689cd4fb5c0ca696fe26dedb493fe9
3704 d5a5322c3047d474fd","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":"d059861b4739c9272fa305b6dd91ebeb08530bd0e
3705 70a013dd999565d6f06fb30","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":"5eb071dd3719ea305eac21ec20596463f63790f8cd1f908a59e3
3706 f9cb0b71b5ad","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/v
3707 irtualdevices/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",
3708 "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}
3709 -\ No newline at end of file
3710 -diff --git a/third_party/rust/authenticator/.clippy.toml b/third_party/rust/authenticator/.clippy.toml
3711 -new file mode 100644
3712 -index 0000000000000..844d0757e91f4
3713 ---- /dev/null
3714 -+++ b/third_party/rust/authenticator/.clippy.toml
3715 -@@ -0,0 +1,2 @@
3716 -+type-complexity-threshold = 384
3717 -+too-many-arguments-threshold = 8
3718 -diff --git a/third_party/rust/authenticator/.flake8 b/third_party/rust/authenticator/.flake8
3719 -new file mode 100644
3720 -index 0000000000000..5a725c9b4ce65
3721 ---- /dev/null
3722 -+++ b/third_party/rust/authenticator/.flake8
3723 -@@ -0,0 +1,4 @@
3724 -+[flake8]
3725 -+# See http://pep8.readthedocs.io/en/latest/intro.html#configuration
3726 -+ignore = E121, E123, E126, E129, E133, E203, E226, E241, E242, E704, W503, E402, E741
3727 -+max-line-length = 99
3728 -diff --git a/third_party/rust/authenticator/.pre-commit-config.yaml b/third_party/rust/authenticator/.pre-commit-config.yaml
3729 -new file mode 100644
3730 -index 0000000000000..e0ceb8ea5473c
3731 ---- /dev/null
3732 -+++ b/third_party/rust/authenticator/.pre-commit-config.yaml
3733 -@@ -0,0 +1,42 @@
3734 -+- repo: git://github.com/pre-commit/pre-commit-hooks
3735 -+ rev: HEAD
3736 -+ hooks:
3737 -+ - id: flake8
3738 -+ - id: check-ast
3739 -+ - id: detect-private-key
3740 -+ - id: detect-aws-credentials
3741 -+ - id: check-merge-conflict
3742 -+ - id: end-of-file-fixer
3743 -+ - id: requirements-txt-fixer
3744 -+ - id: trailing-whitespace
3745 -+- repo: local
3746 -+ hooks:
3747 -+ - id: rustfmt
3748 -+ name: Check rustfmt
3749 -+ language: system
3750 -+ entry: cargo fmt -- --check
3751 -+ pass_filenames: false
3752 -+ files: '.rs$'
3753 -+- repo: local
3754 -+ hooks:
3755 -+ - id: tests
3756 -+ name: Run tests
3757 -+ language: system
3758 -+ entry: cargo test --all-targets --all-features
3759 -+ pass_filenames: false
3760 -+ files: '.rs$'
3761 -+- repo: local
3762 -+ hooks:
3763 -+ - id: clippy
3764 -+ name: Check clippy
3765 -+ language: system
3766 -+ entry: cargo clippy --all-targets -- -A renamed_and_removed_lints -A clippy::new-ret-no-self -D warnings
3767 -+ pass_filenames: false
3768 -+ files: '.rs$'
3769 -+- repo: local
3770 -+ hooks:
3771 -+ - id: black
3772 -+ name: Check black
3773 -+ language: system
3774 -+ entry: black
3775 -+ files: '.py$'
3776 -diff --git a/third_party/rust/authenticator/.travis.yml b/third_party/rust/authenticator/.travis.yml
3777 -new file mode 100644
3778 -index 0000000000000..70ea5c5581af2
3779 ---- /dev/null
3780 -+++ b/third_party/rust/authenticator/.travis.yml
3781 -@@ -0,0 +1,42 @@
3782 -+os:
3783 -+ - linux
3784 -+ - windows
3785 -+
3786 -+language: rust
3787 -+rust:
3788 -+ - stable
3789 -+ - nightly
3790 -+cache: cargo
3791 -+
3792 -+jobs:
3793 -+ allow_failures:
3794 -+ - rust: nightly
3795 -+
3796 -+addons:
3797 -+ apt:
3798 -+ packages:
3799 -+ - build-essential
3800 -+ - libudev-dev
3801 -+
3802 -+install:
3803 -+ - rustup component add rustfmt
3804 -+ - rustup component add clippy
3805 -+
3806 -+script:
3807 -+- |
3808 -+ if [ "$TRAVIS_RUST_VERSION" == "nightly" ] && [ "$TRAVIS_OS_NAME" == "linux" ] ; then
3809 -+ export ASAN_OPTIONS="detect_odr_violation=1:leak_check_at_exit=0:detect_leaks=0"
3810 -+ export RUSTFLAGS="-Z sanitizer=address"
3811 -+ fi
3812 -+- |
3813 -+ if [ "$TRAVIS_RUST_VERSION" == "stable" ] && [ "$TRAVIS_OS_NAME" == "linux" ] ; then
3814 -+ echo "Running rustfmt"
3815 -+ cargo fmt --all -- --check
3816 -+ echo "Running clippy"
3817 -+ cargo clippy --all-targets --all-features -- -A renamed_and_removed_lints -A clippy::new-ret-no-self -D warnings
3818 -+
3819 -+ rustup install nightly
3820 -+ cargo install cargo-fuzz
3821 -+ cargo +nightly fuzz build
3822 -+ fi
3823 -+- cargo test --all-targets --all-features
3824 -diff --git a/third_party/rust/authenticator/Cargo.lock b/third_party/rust/authenticator/Cargo.lock
3825 -deleted file mode 100644
3826 -index 9f284b468deaa..0000000000000
3827 ---- a/third_party/rust/authenticator/Cargo.lock
3828 -+++ /dev/null
3829 -@@ -1,1603 +0,0 @@
3830 --# This file is automatically @generated by Cargo.
3831 --# It is not intended for manual editing.
3832 --[[package]]
3833 --name = "aho-corasick"
3834 --version = "0.7.13"
3835 --source = "registry+https://github.com/rust-lang/crates.io-index"
3836 --dependencies = [
3837 -- "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
3838 --]
3839 --
3840 --[[package]]
3841 --name = "ansi_term"
3842 --version = "0.11.0"
3843 --source = "registry+https://github.com/rust-lang/crates.io-index"
3844 --dependencies = [
3845 -- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
3846 --]
3847 --
3848 --[[package]]
3849 --name = "assert_matches"
3850 --version = "1.3.0"
3851 --source = "registry+https://github.com/rust-lang/crates.io-index"
3852 --
3853 --[[package]]
3854 --name = "atty"
3855 --version = "0.2.14"
3856 --source = "registry+https://github.com/rust-lang/crates.io-index"
3857 --dependencies = [
3858 -- "hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
3859 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
3860 -- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
3861 --]
3862 --
3863 --[[package]]
3864 --name = "authenticator"
3865 --version = "0.3.1"
3866 --dependencies = [
3867 -- "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
3868 -- "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
3869 -- "bindgen 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)",
3870 -- "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
3871 -- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
3872 -- "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
3873 -- "devd-rs 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
3874 -- "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
3875 -- "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
3876 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
3877 -- "libudev 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
3878 -- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
3879 -- "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
3880 -- "runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
3881 -- "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)",
3882 -- "serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
3883 -- "sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
3884 -- "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
3885 -- "warp 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
3886 -- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
3887 --]
3888 --
3889 --[[package]]
3890 --name = "autocfg"
3891 --version = "0.1.7"
3892 --source = "registry+https://github.com/rust-lang/crates.io-index"
3893 --
3894 --[[package]]
3895 --name = "autocfg"
3896 --version = "1.0.1"
3897 --source = "registry+https://github.com/rust-lang/crates.io-index"
3898 --
3899 --[[package]]
3900 --name = "base64"
3901 --version = "0.10.1"
3902 --source = "registry+https://github.com/rust-lang/crates.io-index"
3903 --dependencies = [
3904 -- "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
3905 --]
3906 --
3907 --[[package]]
3908 --name = "base64"
3909 --version = "0.12.3"
3910 --source = "registry+https://github.com/rust-lang/crates.io-index"
3911 --
3912 --[[package]]
3913 --name = "bindgen"
3914 --version = "0.51.1"
3915 --source = "registry+https://github.com/rust-lang/crates.io-index"
3916 --dependencies = [
3917 -- "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
3918 -- "cexpr 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
3919 -- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
3920 -- "clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)",
3921 -- "clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)",
3922 -- "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
3923 -- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
3924 -- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
3925 -- "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
3926 -- "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
3927 -- "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
3928 -- "regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
3929 -- "rustc-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
3930 -- "shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
3931 -- "which 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
3932 --]
3933 --
3934 --[[package]]
3935 --name = "bitflags"
3936 --version = "1.2.1"
3937 --source = "registry+https://github.com/rust-lang/crates.io-index"
3938 --
3939 --[[package]]
3940 --name = "block-buffer"
3941 --version = "0.7.3"
3942 --source = "registry+https://github.com/rust-lang/crates.io-index"
3943 --dependencies = [
3944 -- "block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
3945 -- "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
3946 -- "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
3947 -- "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
3948 --]
3949 --
3950 --[[package]]
3951 --name = "block-buffer"
3952 --version = "0.9.0"
3953 --source = "registry+https://github.com/rust-lang/crates.io-index"
3954 --dependencies = [
3955 -- "generic-array 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)",
3956 --]
3957 --
3958 --[[package]]
3959 --name = "block-padding"
3960 --version = "0.1.5"
3961 --source = "registry+https://github.com/rust-lang/crates.io-index"
3962 --dependencies = [
3963 -- "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
3964 --]
3965 --
3966 --[[package]]
3967 --name = "buf_redux"
3968 --version = "0.8.4"
3969 --source = "registry+https://github.com/rust-lang/crates.io-index"
3970 --dependencies = [
3971 -- "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
3972 -- "safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
3973 --]
3974 --
3975 --[[package]]
3976 --name = "byte-tools"
3977 --version = "0.3.1"
3978 --source = "registry+https://github.com/rust-lang/crates.io-index"
3979 --
3980 --[[package]]
3981 --name = "byteorder"
3982 --version = "1.3.4"
3983 --source = "registry+https://github.com/rust-lang/crates.io-index"
3984 --
3985 --[[package]]
3986 --name = "bytes"
3987 --version = "0.5.6"
3988 --source = "registry+https://github.com/rust-lang/crates.io-index"
3989 --dependencies = [
3990 -- "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)",
3991 --]
3992 --
3993 --[[package]]
3994 --name = "cc"
3995 --version = "1.0.58"
3996 --source = "registry+https://github.com/rust-lang/crates.io-index"
3997 --
3998 --[[package]]
3999 --name = "cexpr"
4000 --version = "0.3.6"
4001 --source = "registry+https://github.com/rust-lang/crates.io-index"
4002 --dependencies = [
4003 -- "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
4004 --]
4005 --
4006 --[[package]]
4007 --name = "cfg-if"
4008 --version = "0.1.10"
4009 --source = "registry+https://github.com/rust-lang/crates.io-index"
4010 --
4011 --[[package]]
4012 --name = "clang-sys"
4013 --version = "0.28.1"
4014 --source = "registry+https://github.com/rust-lang/crates.io-index"
4015 --dependencies = [
4016 -- "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
4017 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
4018 -- "libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
4019 --]
4020 --
4021 --[[package]]
4022 --name = "clap"
4023 --version = "2.33.1"
4024 --source = "registry+https://github.com/rust-lang/crates.io-index"
4025 --dependencies = [
4026 -- "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
4027 -- "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
4028 -- "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
4029 -- "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
4030 -- "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
4031 -- "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
4032 -- "vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
4033 --]
4034 --
4035 --[[package]]
4036 --name = "cloudabi"
4037 --version = "0.0.3"
4038 --source = "registry+https://github.com/rust-lang/crates.io-index"
4039 --dependencies = [
4040 -- "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
4041 --]
4042 --
4043 --[[package]]
4044 --name = "core-foundation"
4045 --version = "0.9.0"
4046 --source = "registry+https://github.com/rust-lang/crates.io-index"
4047 --dependencies = [
4048 -- "core-foundation-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
4049 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
4050 --]
4051 --
4052 --[[package]]
4053 --name = "core-foundation-sys"
4054 --version = "0.8.0"
4055 --source = "registry+https://github.com/rust-lang/crates.io-index"
4056 --
4057 --[[package]]
4058 --name = "cpuid-bool"
4059 --version = "0.1.2"
4060 --source = "registry+https://github.com/rust-lang/crates.io-index"
4061 --
4062 --[[package]]
4063 --name = "devd-rs"
4064 --version = "0.3.1"
4065 --source = "registry+https://github.com/rust-lang/crates.io-index"
4066 --dependencies = [
4067 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
4068 -- "nom 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
4069 --]
4070 --
4071 --[[package]]
4072 --name = "digest"
4073 --version = "0.8.1"
4074 --source = "registry+https://github.com/rust-lang/crates.io-index"
4075 --dependencies = [
4076 -- "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
4077 --]
4078 --
4079 --[[package]]
4080 --name = "digest"
4081 --version = "0.9.0"
4082 --source = "registry+https://github.com/rust-lang/crates.io-index"
4083 --dependencies = [
4084 -- "generic-array 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)",
4085 --]
4086 --
4087 --[[package]]
4088 --name = "dtoa"
4089 --version = "0.4.6"
4090 --source = "registry+https://github.com/rust-lang/crates.io-index"
4091 --
4092 --[[package]]
4093 --name = "env_logger"
4094 --version = "0.6.2"
4095 --source = "registry+https://github.com/rust-lang/crates.io-index"
4096 --dependencies = [
4097 -- "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
4098 -- "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
4099 -- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
4100 -- "regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
4101 -- "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
4102 --]
4103 --
4104 --[[package]]
4105 --name = "fake-simd"
4106 --version = "0.1.2"
4107 --source = "registry+https://github.com/rust-lang/crates.io-index"
4108 --
4109 --[[package]]
4110 --name = "fnv"
4111 --version = "1.0.7"
4112 --source = "registry+https://github.com/rust-lang/crates.io-index"
4113 --
4114 --[[package]]
4115 --name = "fuchsia-cprng"
4116 --version = "0.1.1"
4117 --source = "registry+https://github.com/rust-lang/crates.io-index"
4118 --
4119 --[[package]]
4120 --name = "fuchsia-zircon"
4121 --version = "0.3.3"
4122 --source = "registry+https://github.com/rust-lang/crates.io-index"
4123 --dependencies = [
4124 -- "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
4125 -- "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
4126 --]
4127 --
4128 --[[package]]
4129 --name = "fuchsia-zircon-sys"
4130 --version = "0.3.3"
4131 --source = "registry+https://github.com/rust-lang/crates.io-index"
4132 --
4133 --[[package]]
4134 --name = "futures"
4135 --version = "0.3.5"
4136 --source = "registry+https://github.com/rust-lang/crates.io-index"
4137 --dependencies = [
4138 -- "futures-channel 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4139 -- "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4140 -- "futures-io 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4141 -- "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4142 -- "futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4143 -- "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4144 --]
4145 --
4146 --[[package]]
4147 --name = "futures-channel"
4148 --version = "0.3.5"
4149 --source = "registry+https://github.com/rust-lang/crates.io-index"
4150 --dependencies = [
4151 -- "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4152 -- "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4153 --]
4154 --
4155 --[[package]]
4156 --name = "futures-core"
4157 --version = "0.3.5"
4158 --source = "registry+https://github.com/rust-lang/crates.io-index"
4159 --
4160 --[[package]]
4161 --name = "futures-io"
4162 --version = "0.3.5"
4163 --source = "registry+https://github.com/rust-lang/crates.io-index"
4164 --
4165 --[[package]]
4166 --name = "futures-sink"
4167 --version = "0.3.5"
4168 --source = "registry+https://github.com/rust-lang/crates.io-index"
4169 --
4170 --[[package]]
4171 --name = "futures-task"
4172 --version = "0.3.5"
4173 --source = "registry+https://github.com/rust-lang/crates.io-index"
4174 --dependencies = [
4175 -- "once_cell 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
4176 --]
4177 --
4178 --[[package]]
4179 --name = "futures-util"
4180 --version = "0.3.5"
4181 --source = "registry+https://github.com/rust-lang/crates.io-index"
4182 --dependencies = [
4183 -- "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4184 -- "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4185 -- "futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4186 -- "pin-project 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
4187 -- "pin-utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
4188 -- "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
4189 --]
4190 --
4191 --[[package]]
4192 --name = "generic-array"
4193 --version = "0.12.3"
4194 --source = "registry+https://github.com/rust-lang/crates.io-index"
4195 --dependencies = [
4196 -- "typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
4197 --]
4198 --
4199 --[[package]]
4200 --name = "generic-array"
4201 --version = "0.14.4"
4202 --source = "registry+https://github.com/rust-lang/crates.io-index"
4203 --dependencies = [
4204 -- "typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
4205 -- "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
4206 --]
4207 --
4208 --[[package]]
4209 --name = "getopts"
4210 --version = "0.2.21"
4211 --source = "registry+https://github.com/rust-lang/crates.io-index"
4212 --dependencies = [
4213 -- "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
4214 --]
4215 --
4216 --[[package]]
4217 --name = "getrandom"
4218 --version = "0.1.14"
4219 --source = "registry+https://github.com/rust-lang/crates.io-index"
4220 --dependencies = [
4221 -- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
4222 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
4223 -- "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
4224 --]
4225 --
4226 --[[package]]
4227 --name = "glob"
4228 --version = "0.3.0"
4229 --source = "registry+https://github.com/rust-lang/crates.io-index"
4230 --
4231 --[[package]]
4232 --name = "h2"
4233 --version = "0.2.6"
4234 --source = "registry+https://github.com/rust-lang/crates.io-index"
4235 --dependencies = [
4236 -- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
4237 -- "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
4238 -- "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4239 -- "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4240 -- "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4241 -- "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
4242 -- "indexmap 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
4243 -- "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
4244 -- "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
4245 -- "tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
4246 -- "tracing 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
4247 --]
4248 --
4249 --[[package]]
4250 --name = "hashbrown"
4251 --version = "0.9.0"
4252 --source = "registry+https://github.com/rust-lang/crates.io-index"
4253 --
4254 --[[package]]
4255 --name = "headers"
4256 --version = "0.3.2"
4257 --source = "registry+https://github.com/rust-lang/crates.io-index"
4258 --dependencies = [
4259 -- "base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
4260 -- "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
4261 -- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
4262 -- "headers-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
4263 -- "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
4264 -- "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
4265 -- "sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
4266 -- "time 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)",
4267 --]
4268 --
4269 --[[package]]
4270 --name = "headers-core"
4271 --version = "0.2.0"
4272 --source = "registry+https://github.com/rust-lang/crates.io-index"
4273 --dependencies = [
4274 -- "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
4275 --]
4276 --
4277 --[[package]]
4278 --name = "hermit-abi"
4279 --version = "0.1.15"
4280 --source = "registry+https://github.com/rust-lang/crates.io-index"
4281 --dependencies = [
4282 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
4283 --]
4284 --
4285 --[[package]]
4286 --name = "http"
4287 --version = "0.2.1"
4288 --source = "registry+https://github.com/rust-lang/crates.io-index"
4289 --dependencies = [
4290 -- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
4291 -- "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
4292 -- "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
4293 --]
4294 --
4295 --[[package]]
4296 --name = "http-body"
4297 --version = "0.3.1"
4298 --source = "registry+https://github.com/rust-lang/crates.io-index"
4299 --dependencies = [
4300 -- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
4301 -- "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
4302 --]
4303 --
4304 --[[package]]
4305 --name = "httparse"
4306 --version = "1.3.4"
4307 --source = "registry+https://github.com/rust-lang/crates.io-index"
4308 --
4309 --[[package]]
4310 --name = "humantime"
4311 --version = "1.3.0"
4312 --source = "registry+https://github.com/rust-lang/crates.io-index"
4313 --dependencies = [
4314 -- "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
4315 --]
4316 --
4317 --[[package]]
4318 --name = "hyper"
4319 --version = "0.13.7"
4320 --source = "registry+https://github.com/rust-lang/crates.io-index"
4321 --dependencies = [
4322 -- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
4323 -- "futures-channel 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4324 -- "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4325 -- "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4326 -- "h2 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
4327 -- "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
4328 -- "http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
4329 -- "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
4330 -- "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
4331 -- "pin-project 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
4332 -- "socket2 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
4333 -- "time 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)",
4334 -- "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
4335 -- "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
4336 -- "tracing 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
4337 -- "want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
4338 --]
4339 --
4340 --[[package]]
4341 --name = "idna"
4342 --version = "0.2.0"
4343 --source = "registry+https://github.com/rust-lang/crates.io-index"
4344 --dependencies = [
4345 -- "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
4346 -- "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
4347 -- "unicode-normalization 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
4348 --]
4349 --
4350 --[[package]]
4351 --name = "indexmap"
4352 --version = "1.6.0"
4353 --source = "registry+https://github.com/rust-lang/crates.io-index"
4354 --dependencies = [
4355 -- "autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
4356 -- "hashbrown 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
4357 --]
4358 --
4359 --[[package]]
4360 --name = "input_buffer"
4361 --version = "0.3.1"
4362 --source = "registry+https://github.com/rust-lang/crates.io-index"
4363 --dependencies = [
4364 -- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
4365 --]
4366 --
4367 --[[package]]
4368 --name = "iovec"
4369 --version = "0.1.4"
4370 --source = "registry+https://github.com/rust-lang/crates.io-index"
4371 --dependencies = [
4372 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
4373 --]
4374 --
4375 --[[package]]
4376 --name = "itoa"
4377 --version = "0.4.6"
4378 --source = "registry+https://github.com/rust-lang/crates.io-index"
4379 --
4380 --[[package]]
4381 --name = "kernel32-sys"
4382 --version = "0.2.2"
4383 --source = "registry+https://github.com/rust-lang/crates.io-index"
4384 --dependencies = [
4385 -- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
4386 -- "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
4387 --]
4388 --
4389 --[[package]]
4390 --name = "lazy_static"
4391 --version = "1.4.0"
4392 --source = "registry+https://github.com/rust-lang/crates.io-index"
4393 --
4394 --[[package]]
4395 --name = "libc"
4396 --version = "0.2.73"
4397 --source = "registry+https://github.com/rust-lang/crates.io-index"
4398 --
4399 --[[package]]
4400 --name = "libloading"
4401 --version = "0.5.2"
4402 --source = "registry+https://github.com/rust-lang/crates.io-index"
4403 --dependencies = [
4404 -- "cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
4405 -- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
4406 --]
4407 --
4408 --[[package]]
4409 --name = "libudev"
4410 --version = "0.2.0"
4411 --source = "registry+https://github.com/rust-lang/crates.io-index"
4412 --dependencies = [
4413 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
4414 -- "libudev-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
4415 --]
4416 --
4417 --[[package]]
4418 --name = "libudev-sys"
4419 --version = "0.1.4"
4420 --source = "registry+https://github.com/rust-lang/crates.io-index"
4421 --dependencies = [
4422 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
4423 -- "pkg-config 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
4424 --]
4425 --
4426 --[[package]]
4427 --name = "log"
4428 --version = "0.4.11"
4429 --source = "registry+https://github.com/rust-lang/crates.io-index"
4430 --dependencies = [
4431 -- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
4432 --]
4433 --
4434 --[[package]]
4435 --name = "matches"
4436 --version = "0.1.8"
4437 --source = "registry+https://github.com/rust-lang/crates.io-index"
4438 --
4439 --[[package]]
4440 --name = "memchr"
4441 --version = "2.3.3"
4442 --source = "registry+https://github.com/rust-lang/crates.io-index"
4443 --
4444 --[[package]]
4445 --name = "mime"
4446 --version = "0.3.16"
4447 --source = "registry+https://github.com/rust-lang/crates.io-index"
4448 --
4449 --[[package]]
4450 --name = "mime_guess"
4451 --version = "2.0.3"
4452 --source = "registry+https://github.com/rust-lang/crates.io-index"
4453 --dependencies = [
4454 -- "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
4455 -- "unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
4456 --]
4457 --
4458 --[[package]]
4459 --name = "mio"
4460 --version = "0.6.22"
4461 --source = "registry+https://github.com/rust-lang/crates.io-index"
4462 --dependencies = [
4463 -- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
4464 -- "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
4465 -- "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
4466 -- "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
4467 -- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
4468 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
4469 -- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
4470 -- "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
4471 -- "net2 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
4472 -- "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
4473 -- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
4474 --]
4475 --
4476 --[[package]]
4477 --name = "miow"
4478 --version = "0.2.1"
4479 --source = "registry+https://github.com/rust-lang/crates.io-index"
4480 --dependencies = [
4481 -- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
4482 -- "net2 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
4483 -- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
4484 -- "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
4485 --]
4486 --
4487 --[[package]]
4488 --name = "multipart"
4489 --version = "0.17.0"
4490 --source = "registry+https://github.com/rust-lang/crates.io-index"
4491 --dependencies = [
4492 -- "buf_redux 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
4493 -- "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
4494 -- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
4495 -- "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
4496 -- "mime_guess 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
4497 -- "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
4498 -- "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
4499 -- "safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
4500 -- "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
4501 -- "twoway 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
4502 --]
4503 --
4504 --[[package]]
4505 --name = "net2"
4506 --version = "0.2.35"
4507 --source = "registry+https://github.com/rust-lang/crates.io-index"
4508 --dependencies = [
4509 -- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
4510 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
4511 -- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
4512 --]
4513 --
4514 --[[package]]
4515 --name = "nom"
4516 --version = "4.2.3"
4517 --source = "registry+https://github.com/rust-lang/crates.io-index"
4518 --dependencies = [
4519 -- "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
4520 -- "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
4521 --]
4522 --
4523 --[[package]]
4524 --name = "nom"
4525 --version = "5.1.2"
4526 --source = "registry+https://github.com/rust-lang/crates.io-index"
4527 --dependencies = [
4528 -- "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
4529 -- "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
4530 --]
4531 --
4532 --[[package]]
4533 --name = "once_cell"
4534 --version = "1.4.1"
4535 --source = "registry+https://github.com/rust-lang/crates.io-index"
4536 --
4537 --[[package]]
4538 --name = "opaque-debug"
4539 --version = "0.2.3"
4540 --source = "registry+https://github.com/rust-lang/crates.io-index"
4541 --
4542 --[[package]]
4543 --name = "opaque-debug"
4544 --version = "0.3.0"
4545 --source = "registry+https://github.com/rust-lang/crates.io-index"
4546 --
4547 --[[package]]
4548 --name = "peeking_take_while"
4549 --version = "0.1.2"
4550 --source = "registry+https://github.com/rust-lang/crates.io-index"
4551 --
4552 --[[package]]
4553 --name = "percent-encoding"
4554 --version = "2.1.0"
4555 --source = "registry+https://github.com/rust-lang/crates.io-index"
4556 --
4557 --[[package]]
4558 --name = "pin-project"
4559 --version = "0.4.23"
4560 --source = "registry+https://github.com/rust-lang/crates.io-index"
4561 --dependencies = [
4562 -- "pin-project-internal 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
4563 --]
4564 --
4565 --[[package]]
4566 --name = "pin-project-internal"
4567 --version = "0.4.23"
4568 --source = "registry+https://github.com/rust-lang/crates.io-index"
4569 --dependencies = [
4570 -- "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
4571 -- "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
4572 -- "syn 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
4573 --]
4574 --
4575 --[[package]]
4576 --name = "pin-project-lite"
4577 --version = "0.1.7"
4578 --source = "registry+https://github.com/rust-lang/crates.io-index"
4579 --
4580 --[[package]]
4581 --name = "pin-utils"
4582 --version = "0.1.0"
4583 --source = "registry+https://github.com/rust-lang/crates.io-index"
4584 --
4585 --[[package]]
4586 --name = "pkg-config"
4587 --version = "0.3.18"
4588 --source = "registry+https://github.com/rust-lang/crates.io-index"
4589 --
4590 --[[package]]
4591 --name = "ppv-lite86"
4592 --version = "0.2.8"
4593 --source = "registry+https://github.com/rust-lang/crates.io-index"
4594 --
4595 --[[package]]
4596 --name = "proc-macro2"
4597 --version = "1.0.19"
4598 --source = "registry+https://github.com/rust-lang/crates.io-index"
4599 --dependencies = [
4600 -- "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
4601 --]
4602 --
4603 --[[package]]
4604 --name = "quick-error"
4605 --version = "1.2.3"
4606 --source = "registry+https://github.com/rust-lang/crates.io-index"
4607 --
4608 --[[package]]
4609 --name = "quote"
4610 --version = "1.0.7"
4611 --source = "registry+https://github.com/rust-lang/crates.io-index"
4612 --dependencies = [
4613 -- "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
4614 --]
4615 --
4616 --[[package]]
4617 --name = "rand"
4618 --version = "0.6.5"
4619 --source = "registry+https://github.com/rust-lang/crates.io-index"
4620 --dependencies = [
4621 -- "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
4622 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
4623 -- "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
4624 -- "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
4625 -- "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
4626 -- "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
4627 -- "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
4628 -- "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
4629 -- "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
4630 -- "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
4631 -- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
4632 --]
4633 --
4634 --[[package]]
4635 --name = "rand"
4636 --version = "0.7.3"
4637 --source = "registry+https://github.com/rust-lang/crates.io-index"
4638 --dependencies = [
4639 -- "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
4640 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
4641 -- "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
4642 -- "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
4643 -- "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
4644 --]
4645 --
4646 --[[package]]
4647 --name = "rand_chacha"
4648 --version = "0.1.1"
4649 --source = "registry+https://github.com/rust-lang/crates.io-index"
4650 --dependencies = [
4651 -- "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
4652 -- "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
4653 --]
4654 --
4655 --[[package]]
4656 --name = "rand_chacha"
4657 --version = "0.2.2"
4658 --source = "registry+https://github.com/rust-lang/crates.io-index"
4659 --dependencies = [
4660 -- "ppv-lite86 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
4661 -- "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
4662 --]
4663 --
4664 --[[package]]
4665 --name = "rand_core"
4666 --version = "0.3.1"
4667 --source = "registry+https://github.com/rust-lang/crates.io-index"
4668 --dependencies = [
4669 -- "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
4670 --]
4671 --
4672 --[[package]]
4673 --name = "rand_core"
4674 --version = "0.4.2"
4675 --source = "registry+https://github.com/rust-lang/crates.io-index"
4676 --
4677 --[[package]]
4678 --name = "rand_core"
4679 --version = "0.5.1"
4680 --source = "registry+https://github.com/rust-lang/crates.io-index"
4681 --dependencies = [
4682 -- "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
4683 --]
4684 --
4685 --[[package]]
4686 --name = "rand_hc"
4687 --version = "0.1.0"
4688 --source = "registry+https://github.com/rust-lang/crates.io-index"
4689 --dependencies = [
4690 -- "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
4691 --]
4692 --
4693 --[[package]]
4694 --name = "rand_hc"
4695 --version = "0.2.0"
4696 --source = "registry+https://github.com/rust-lang/crates.io-index"
4697 --dependencies = [
4698 -- "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
4699 --]
4700 --
4701 --[[package]]
4702 --name = "rand_isaac"
4703 --version = "0.1.1"
4704 --source = "registry+https://github.com/rust-lang/crates.io-index"
4705 --dependencies = [
4706 -- "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
4707 --]
4708 --
4709 --[[package]]
4710 --name = "rand_jitter"
4711 --version = "0.1.4"
4712 --source = "registry+https://github.com/rust-lang/crates.io-index"
4713 --dependencies = [
4714 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
4715 -- "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
4716 -- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
4717 --]
4718 --
4719 --[[package]]
4720 --name = "rand_os"
4721 --version = "0.1.3"
4722 --source = "registry+https://github.com/rust-lang/crates.io-index"
4723 --dependencies = [
4724 -- "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
4725 -- "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
4726 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
4727 -- "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
4728 -- "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
4729 -- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
4730 --]
4731 --
4732 --[[package]]
4733 --name = "rand_pcg"
4734 --version = "0.1.2"
4735 --source = "registry+https://github.com/rust-lang/crates.io-index"
4736 --dependencies = [
4737 -- "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
4738 -- "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
4739 --]
4740 --
4741 --[[package]]
4742 --name = "rand_xorshift"
4743 --version = "0.1.1"
4744 --source = "registry+https://github.com/rust-lang/crates.io-index"
4745 --dependencies = [
4746 -- "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
4747 --]
4748 --
4749 --[[package]]
4750 --name = "rdrand"
4751 --version = "0.4.0"
4752 --source = "registry+https://github.com/rust-lang/crates.io-index"
4753 --dependencies = [
4754 -- "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
4755 --]
4756 --
4757 --[[package]]
4758 --name = "redox_syscall"
4759 --version = "0.1.57"
4760 --source = "registry+https://github.com/rust-lang/crates.io-index"
4761 --
4762 --[[package]]
4763 --name = "regex"
4764 --version = "1.3.9"
4765 --source = "registry+https://github.com/rust-lang/crates.io-index"
4766 --dependencies = [
4767 -- "aho-corasick 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
4768 -- "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
4769 -- "regex-syntax 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
4770 -- "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
4771 --]
4772 --
4773 --[[package]]
4774 --name = "regex-syntax"
4775 --version = "0.6.18"
4776 --source = "registry+https://github.com/rust-lang/crates.io-index"
4777 --
4778 --[[package]]
4779 --name = "remove_dir_all"
4780 --version = "0.5.3"
4781 --source = "registry+https://github.com/rust-lang/crates.io-index"
4782 --dependencies = [
4783 -- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
4784 --]
4785 --
4786 --[[package]]
4787 --name = "runloop"
4788 --version = "0.1.0"
4789 --source = "registry+https://github.com/rust-lang/crates.io-index"
4790 --
4791 --[[package]]
4792 --name = "rustc-hash"
4793 --version = "1.1.0"
4794 --source = "registry+https://github.com/rust-lang/crates.io-index"
4795 --
4796 --[[package]]
4797 --name = "ryu"
4798 --version = "1.0.5"
4799 --source = "registry+https://github.com/rust-lang/crates.io-index"
4800 --
4801 --[[package]]
4802 --name = "safemem"
4803 --version = "0.3.3"
4804 --source = "registry+https://github.com/rust-lang/crates.io-index"
4805 --
4806 --[[package]]
4807 --name = "scoped-tls"
4808 --version = "1.0.0"
4809 --source = "registry+https://github.com/rust-lang/crates.io-index"
4810 --
4811 --[[package]]
4812 --name = "serde"
4813 --version = "1.0.116"
4814 --source = "registry+https://github.com/rust-lang/crates.io-index"
4815 --dependencies = [
4816 -- "serde_derive 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)",
4817 --]
4818 --
4819 --[[package]]
4820 --name = "serde_derive"
4821 --version = "1.0.116"
4822 --source = "registry+https://github.com/rust-lang/crates.io-index"
4823 --dependencies = [
4824 -- "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
4825 -- "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
4826 -- "syn 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
4827 --]
4828 --
4829 --[[package]]
4830 --name = "serde_json"
4831 --version = "1.0.57"
4832 --source = "registry+https://github.com/rust-lang/crates.io-index"
4833 --dependencies = [
4834 -- "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
4835 -- "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
4836 -- "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)",
4837 --]
4838 --
4839 --[[package]]
4840 --name = "serde_urlencoded"
4841 --version = "0.6.1"
4842 --source = "registry+https://github.com/rust-lang/crates.io-index"
4843 --dependencies = [
4844 -- "dtoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
4845 -- "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
4846 -- "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)",
4847 -- "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
4848 --]
4849 --
4850 --[[package]]
4851 --name = "sha-1"
4852 --version = "0.8.2"
4853 --source = "registry+https://github.com/rust-lang/crates.io-index"
4854 --dependencies = [
4855 -- "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
4856 -- "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
4857 -- "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
4858 -- "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
4859 --]
4860 --
4861 --[[package]]
4862 --name = "sha-1"
4863 --version = "0.9.1"
4864 --source = "registry+https://github.com/rust-lang/crates.io-index"
4865 --dependencies = [
4866 -- "block-buffer 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
4867 -- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
4868 -- "cpuid-bool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
4869 -- "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
4870 -- "opaque-debug 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
4871 --]
4872 --
4873 --[[package]]
4874 --name = "sha2"
4875 --version = "0.8.2"
4876 --source = "registry+https://github.com/rust-lang/crates.io-index"
4877 --dependencies = [
4878 -- "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
4879 -- "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
4880 -- "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
4881 -- "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
4882 --]
4883 --
4884 --[[package]]
4885 --name = "shlex"
4886 --version = "0.1.1"
4887 --source = "registry+https://github.com/rust-lang/crates.io-index"
4888 --
4889 --[[package]]
4890 --name = "slab"
4891 --version = "0.4.2"
4892 --source = "registry+https://github.com/rust-lang/crates.io-index"
4893 --
4894 --[[package]]
4895 --name = "socket2"
4896 --version = "0.3.15"
4897 --source = "registry+https://github.com/rust-lang/crates.io-index"
4898 --dependencies = [
4899 -- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
4900 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
4901 -- "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)",
4902 -- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
4903 --]
4904 --
4905 --[[package]]
4906 --name = "strsim"
4907 --version = "0.8.0"
4908 --source = "registry+https://github.com/rust-lang/crates.io-index"
4909 --
4910 --[[package]]
4911 --name = "syn"
4912 --version = "1.0.41"
4913 --source = "registry+https://github.com/rust-lang/crates.io-index"
4914 --dependencies = [
4915 -- "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
4916 -- "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
4917 -- "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
4918 --]
4919 --
4920 --[[package]]
4921 --name = "tempfile"
4922 --version = "3.1.0"
4923 --source = "registry+https://github.com/rust-lang/crates.io-index"
4924 --dependencies = [
4925 -- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
4926 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
4927 -- "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
4928 -- "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)",
4929 -- "remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
4930 -- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
4931 --]
4932 --
4933 --[[package]]
4934 --name = "termcolor"
4935 --version = "1.1.0"
4936 --source = "registry+https://github.com/rust-lang/crates.io-index"
4937 --dependencies = [
4938 -- "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
4939 --]
4940 --
4941 --[[package]]
4942 --name = "textwrap"
4943 --version = "0.11.0"
4944 --source = "registry+https://github.com/rust-lang/crates.io-index"
4945 --dependencies = [
4946 -- "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
4947 --]
4948 --
4949 --[[package]]
4950 --name = "thread_local"
4951 --version = "1.0.1"
4952 --source = "registry+https://github.com/rust-lang/crates.io-index"
4953 --dependencies = [
4954 -- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
4955 --]
4956 --
4957 --[[package]]
4958 --name = "time"
4959 --version = "0.1.44"
4960 --source = "registry+https://github.com/rust-lang/crates.io-index"
4961 --dependencies = [
4962 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
4963 -- "wasi 0.10.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
4964 -- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
4965 --]
4966 --
4967 --[[package]]
4968 --name = "tinyvec"
4969 --version = "0.3.4"
4970 --source = "registry+https://github.com/rust-lang/crates.io-index"
4971 --
4972 --[[package]]
4973 --name = "tokio"
4974 --version = "0.2.22"
4975 --source = "registry+https://github.com/rust-lang/crates.io-index"
4976 --dependencies = [
4977 -- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
4978 -- "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
4979 -- "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
4980 -- "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
4981 -- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
4982 -- "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
4983 -- "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)",
4984 -- "pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
4985 -- "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
4986 -- "tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
4987 --]
4988 --
4989 --[[package]]
4990 --name = "tokio-macros"
4991 --version = "0.2.5"
4992 --source = "registry+https://github.com/rust-lang/crates.io-index"
4993 --dependencies = [
4994 -- "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
4995 -- "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
4996 -- "syn 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
4997 --]
4998 --
4999 --[[package]]
5000 --name = "tokio-tungstenite"
5001 --version = "0.11.0"
5002 --source = "registry+https://github.com/rust-lang/crates.io-index"
5003 --dependencies = [
5004 -- "futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
5005 -- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
5006 -- "pin-project 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
5007 -- "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
5008 -- "tungstenite 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
5009 --]
5010 --
5011 --[[package]]
5012 --name = "tokio-util"
5013 --version = "0.3.1"
5014 --source = "registry+https://github.com/rust-lang/crates.io-index"
5015 --dependencies = [
5016 -- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
5017 -- "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
5018 -- "futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
5019 -- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
5020 -- "pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
5021 -- "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
5022 --]
5023 --
5024 --[[package]]
5025 --name = "tower-service"
5026 --version = "0.3.0"
5027 --source = "registry+https://github.com/rust-lang/crates.io-index"
5028 --
5029 --[[package]]
5030 --name = "tracing"
5031 --version = "0.1.19"
5032 --source = "registry+https://github.com/rust-lang/crates.io-index"
5033 --dependencies = [
5034 -- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
5035 -- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
5036 -- "tracing-core 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
5037 --]
5038 --
5039 --[[package]]
5040 --name = "tracing-core"
5041 --version = "0.1.16"
5042 --source = "registry+https://github.com/rust-lang/crates.io-index"
5043 --dependencies = [
5044 -- "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
5045 --]
5046 --
5047 --[[package]]
5048 --name = "tracing-futures"
5049 --version = "0.2.4"
5050 --source = "registry+https://github.com/rust-lang/crates.io-index"
5051 --dependencies = [
5052 -- "pin-project 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
5053 -- "tracing 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
5054 --]
5055 --
5056 --[[package]]
5057 --name = "try-lock"
5058 --version = "0.2.3"
5059 --source = "registry+https://github.com/rust-lang/crates.io-index"
5060 --
5061 --[[package]]
5062 --name = "tungstenite"
5063 --version = "0.11.1"
5064 --source = "registry+https://github.com/rust-lang/crates.io-index"
5065 --dependencies = [
5066 -- "base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
5067 -- "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
5068 -- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
5069 -- "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
5070 -- "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
5071 -- "input_buffer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
5072 -- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
5073 -- "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
5074 -- "sha-1 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
5075 -- "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
5076 -- "utf-8 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
5077 --]
5078 --
5079 --[[package]]
5080 --name = "twoway"
5081 --version = "0.1.8"
5082 --source = "registry+https://github.com/rust-lang/crates.io-index"
5083 --dependencies = [
5084 -- "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
5085 --]
5086 --
5087 --[[package]]
5088 --name = "typenum"
5089 --version = "1.12.0"
5090 --source = "registry+https://github.com/rust-lang/crates.io-index"
5091 --
5092 --[[package]]
5093 --name = "unicase"
5094 --version = "2.6.0"
5095 --source = "registry+https://github.com/rust-lang/crates.io-index"
5096 --dependencies = [
5097 -- "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
5098 --]
5099 --
5100 --[[package]]
5101 --name = "unicode-bidi"
5102 --version = "0.3.4"
5103 --source = "registry+https://github.com/rust-lang/crates.io-index"
5104 --dependencies = [
5105 -- "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
5106 --]
5107 --
5108 --[[package]]
5109 --name = "unicode-normalization"
5110 --version = "0.1.13"
5111 --source = "registry+https://github.com/rust-lang/crates.io-index"
5112 --dependencies = [
5113 -- "tinyvec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
5114 --]
5115 --
5116 --[[package]]
5117 --name = "unicode-width"
5118 --version = "0.1.8"
5119 --source = "registry+https://github.com/rust-lang/crates.io-index"
5120 --
5121 --[[package]]
5122 --name = "unicode-xid"
5123 --version = "0.2.1"
5124 --source = "registry+https://github.com/rust-lang/crates.io-index"
5125 --
5126 --[[package]]
5127 --name = "url"
5128 --version = "2.1.1"
5129 --source = "registry+https://github.com/rust-lang/crates.io-index"
5130 --dependencies = [
5131 -- "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
5132 -- "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
5133 -- "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
5134 --]
5135 --
5136 --[[package]]
5137 --name = "urlencoding"
5138 --version = "1.1.1"
5139 --source = "registry+https://github.com/rust-lang/crates.io-index"
5140 --
5141 --[[package]]
5142 --name = "utf-8"
5143 --version = "0.7.5"
5144 --source = "registry+https://github.com/rust-lang/crates.io-index"
5145 --
5146 --[[package]]
5147 --name = "vec_map"
5148 --version = "0.8.2"
5149 --source = "registry+https://github.com/rust-lang/crates.io-index"
5150 --
5151 --[[package]]
5152 --name = "version_check"
5153 --version = "0.1.5"
5154 --source = "registry+https://github.com/rust-lang/crates.io-index"
5155 --
5156 --[[package]]
5157 --name = "version_check"
5158 --version = "0.9.2"
5159 --source = "registry+https://github.com/rust-lang/crates.io-index"
5160 --
5161 --[[package]]
5162 --name = "want"
5163 --version = "0.3.0"
5164 --source = "registry+https://github.com/rust-lang/crates.io-index"
5165 --dependencies = [
5166 -- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
5167 -- "try-lock 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
5168 --]
5169 --
5170 --[[package]]
5171 --name = "warp"
5172 --version = "0.2.5"
5173 --source = "registry+https://github.com/rust-lang/crates.io-index"
5174 --dependencies = [
5175 -- "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
5176 -- "futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
5177 -- "headers 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
5178 -- "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
5179 -- "hyper 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)",
5180 -- "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
5181 -- "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
5182 -- "mime_guess 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
5183 -- "multipart 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
5184 -- "pin-project 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
5185 -- "scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
5186 -- "serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)",
5187 -- "serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
5188 -- "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
5189 -- "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
5190 -- "tokio-tungstenite 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
5191 -- "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
5192 -- "tracing 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
5193 -- "tracing-futures 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
5194 -- "urlencoding 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
5195 --]
5196 --
5197 --[[package]]
5198 --name = "wasi"
5199 --version = "0.9.0+wasi-snapshot-preview1"
5200 --source = "registry+https://github.com/rust-lang/crates.io-index"
5201 --
5202 --[[package]]
5203 --name = "wasi"
5204 --version = "0.10.0+wasi-snapshot-preview1"
5205 --source = "registry+https://github.com/rust-lang/crates.io-index"
5206 --
5207 --[[package]]
5208 --name = "which"
5209 --version = "3.1.1"
5210 --source = "registry+https://github.com/rust-lang/crates.io-index"
5211 --dependencies = [
5212 -- "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
5213 --]
5214 --
5215 --[[package]]
5216 --name = "winapi"
5217 --version = "0.2.8"
5218 --source = "registry+https://github.com/rust-lang/crates.io-index"
5219 --
5220 --[[package]]
5221 --name = "winapi"
5222 --version = "0.3.9"
5223 --source = "registry+https://github.com/rust-lang/crates.io-index"
5224 --dependencies = [
5225 -- "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
5226 -- "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
5227 --]
5228 --
5229 --[[package]]
5230 --name = "winapi-build"
5231 --version = "0.1.1"
5232 --source = "registry+https://github.com/rust-lang/crates.io-index"
5233 --
5234 --[[package]]
5235 --name = "winapi-i686-pc-windows-gnu"
5236 --version = "0.4.0"
5237 --source = "registry+https://github.com/rust-lang/crates.io-index"
5238 --
5239 --[[package]]
5240 --name = "winapi-util"
5241 --version = "0.1.5"
5242 --source = "registry+https://github.com/rust-lang/crates.io-index"
5243 --dependencies = [
5244 -- "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
5245 --]
5246 --
5247 --[[package]]
5248 --name = "winapi-x86_64-pc-windows-gnu"
5249 --version = "0.4.0"
5250 --source = "registry+https://github.com/rust-lang/crates.io-index"
5251 --
5252 --[[package]]
5253 --name = "ws2_32-sys"
5254 --version = "0.2.1"
5255 --source = "registry+https://github.com/rust-lang/crates.io-index"
5256 --dependencies = [
5257 -- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
5258 -- "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
5259 --]
5260 --
5261 --[metadata]
5262 --"checksum aho-corasick 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)" = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86"
5263 --"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
5264 --"checksum assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7deb0a829ca7bcfaf5da70b073a8d128619259a7be8216a355e23f00763059e5"
5265 --"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
5266 --"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
5267 --"checksum autocfg 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
5268 --"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
5269 --"checksum base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
5270 --"checksum bindgen 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ebd71393f1ec0509b553aa012b9b58e81dadbdff7130bd3b8cba576e69b32f75"
5271 --"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
5272 --"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
5273 --"checksum block-buffer 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
5274 --"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
5275 --"checksum buf_redux 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f"
5276 --"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
5277 --"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
5278 --"checksum bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
5279 --"checksum cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)" = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518"
5280 --"checksum cexpr 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d"
5281 --"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
5282 --"checksum clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853"
5283 --"checksum clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129"
5284 --"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
5285 --"checksum core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b5ed8e7e76c45974e15e41bfa8d5b0483cd90191639e01d8f5f1e606299d3fb"
5286 --"checksum core-foundation-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9a21fa21941700a3cd8fcb4091f361a6a712fac632f85d9f487cc892045d55c6"
5287 --"checksum cpuid-bool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
5288 --"checksum devd-rs 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1945ccb7caedabdfb9347766ead740fb1e0582b7425598325f546adbd832cce1"
5289 --"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
5290 --"checksum digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
5291 --"checksum dtoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
5292 --"checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3"
5293 --"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
5294 --"checksum fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
5295 --"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
5296 --"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
5297 --"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
5298 --"checksum futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613"
5299 --"checksum futures-channel 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5"
5300 --"checksum futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399"
5301 --"checksum futures-io 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
5302 --"checksum futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc"
5303 --"checksum futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626"
5304 --"checksum futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"
5305 --"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
5306 --"checksum generic-array 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
5307 --"checksum getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
5308 --"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
5309 --"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
5310 --"checksum h2 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "993f9e0baeed60001cf565546b0d3dbe6a6ad23f2bd31644a133c641eccf6d53"
5311 --"checksum hashbrown 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "00d63df3d41950fb462ed38308eea019113ad1508da725bbedcd0fa5a85ef5f7"
5312 --"checksum headers 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ed18eb2459bf1a09ad2d6b1547840c3e5e62882fa09b9a6a20b1de8e3228848f"
5313 --"checksum headers-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
5314 --"checksum hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9"
5315 --"checksum http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9"
5316 --"checksum http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b"
5317 --"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
5318 --"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
5319 --"checksum hyper 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3e68a8dd9716185d9e64ea473ea6ef63529252e3e27623295a0378a19665d5eb"
5320 --"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
5321 --"checksum indexmap 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2"
5322 --"checksum input_buffer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "19a8a95243d5a0398cae618ec29477c6e3cb631152be5c19481f80bc71559754"
5323 --"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
5324 --"checksum itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
5325 --"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
5326 --"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
5327 --"checksum libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)" = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9"
5328 --"checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
5329 --"checksum libudev 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea626d3bdf40a1c5aee3bcd4f40826970cae8d80a8fec934c82a63840094dcfe"
5330 --"checksum libudev-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324"
5331 --"checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
5332 --"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
5333 --"checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
5334 --"checksum mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
5335 --"checksum mime_guess 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212"
5336 --"checksum mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)" = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430"
5337 --"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
5338 --"checksum multipart 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8209c33c951f07387a8497841122fc6f712165e3f9bda3e6be4645b58188f676"
5339 --"checksum net2 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3ebc3ec692ed7c9a255596c67808dee269f64655d8baf7b4f0638e51ba1d6853"
5340 --"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
5341 --"checksum nom 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
5342 --"checksum once_cell 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad"
5343 --"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
5344 --"checksum opaque-debug 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
5345 --"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
5346 --"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
5347 --"checksum pin-project 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)" = "ca4433fff2ae79342e497d9f8ee990d174071408f28f726d6d83af93e58e48aa"
5348 --"checksum pin-project-internal 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)" = "2c0e815c3ee9a031fdf5af21c10aa17c573c9c6a566328d99e3936c34e36461f"
5349 --"checksum pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715"
5350 --"checksum pin-utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
5351 --"checksum pkg-config 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33"
5352 --"checksum ppv-lite86 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
5353 --"checksum proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12"
5354 --"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
5355 --"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
5356 --"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
5357 --"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
5358 --"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
5359 --"checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
5360 --"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
5361 --"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
5362 --"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
5363 --"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
5364 --"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
5365 --"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
5366 --"checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
5367 --"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
5368 --"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
5369 --"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
5370 --"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
5371 --"checksum redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)" = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
5372 --"checksum regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
5373 --"checksum regex-syntax 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)" = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
5374 --"checksum remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
5375 --"checksum runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d79b4b604167921892e84afbbaad9d5ad74e091bf6c511d9dbfb0593f09fabd"
5376 --"checksum rustc-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
5377 --"checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
5378 --"checksum safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
5379 --"checksum scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
5380 --"checksum serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)" = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5"
5381 --"checksum serde_derive 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)" = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8"
5382 --"checksum serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)" = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c"
5383 --"checksum serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"
5384 --"checksum sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
5385 --"checksum sha-1 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "170a36ea86c864a3f16dd2687712dd6646f7019f301e57537c7f4dc9f5916770"
5386 --"checksum sha2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
5387 --"checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
5388 --"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
5389 --"checksum socket2 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "b1fa70dc5c8104ec096f4fe7ede7a221d35ae13dcd19ba1ad9a81d2cab9a1c44"
5390 --"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
5391 --"checksum syn 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b"
5392 --"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
5393 --"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
5394 --"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
5395 --"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
5396 --"checksum time 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
5397 --"checksum tinyvec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117"
5398 --"checksum tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd"
5399 --"checksum tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389"
5400 --"checksum tokio-tungstenite 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d9e878ad426ca286e4dcae09cbd4e1973a7f8987d97570e2469703dd7f5720c"
5401 --"checksum tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499"
5402 --"checksum tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860"
5403 --"checksum tracing 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6d79ca061b032d6ce30c660fded31189ca0b9922bf483cd70759f13a2d86786c"
5404 --"checksum tracing-core 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5bcf46c1f1f06aeea2d6b81f3c863d0930a596c86ad1920d4e5bad6dd1d7119a"
5405 --"checksum tracing-futures 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c"
5406 --"checksum try-lock 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
5407 --"checksum tungstenite 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f0308d80d86700c5878b9ef6321f020f29b1bb9d5ff3cab25e75e23f3a492a23"
5408 --"checksum twoway 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1"
5409 --"checksum typenum 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
5410 --"checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
5411 --"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
5412 --"checksum unicode-normalization 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977"
5413 --"checksum unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
5414 --"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
5415 --"checksum url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb"
5416 --"checksum urlencoding 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c9232eb53352b4442e40d7900465dfc534e8cb2dc8f18656fcb2ac16112b5593"
5417 --"checksum utf-8 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7"
5418 --"checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
5419 --"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
5420 --"checksum version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
5421 --"checksum want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
5422 --"checksum warp 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f41be6df54c97904af01aa23e613d4521eed7ab23537cede692d4058f6449407"
5423 --"checksum wasi 0.10.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
5424 --"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
5425 --"checksum which 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
5426 --"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
5427 --"checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
5428 --"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
5429 --"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
5430 --"checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
5431 --"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
5432 --"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
5433 -diff --git a/third_party/rust/authenticator/Cargo.toml b/third_party/rust/authenticator/Cargo.toml
5434 -index 57d24bd66b948..c49befae2178c 100644
5435 ---- a/third_party/rust/authenticator/Cargo.toml
5436 -+++ b/third_party/rust/authenticator/Cargo.toml
5437 -@@ -1,99 +1,60 @@
5438 --# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
5439 --#
5440 --# When uploading crates to the registry Cargo will automatically
5441 --# "normalize" Cargo.toml files for maximal compatibility
5442 --# with all versions of Cargo and also rewrite `path` dependencies
5443 --# to registry (e.g., crates.io) dependencies
5444 --#
5445 --# If you believe there's an error in this file please file an
5446 --# issue against the rust-lang/cargo repository. If you're
5447 --# editing this file be aware that the upstream Cargo.toml
5448 --# will likely look very different (and much more reasonable)
5449 --
5450 - [package]
5451 --edition = "2018"
5452 - name = "authenticator"
5453 - version = "0.3.1"
5454 - authors = ["J.C. Jones <jc@×××××××.com>", "Tim Taubert <ttaubert@×××××××.com>", "Kyle Machulis <kyle@×××××××××××××.com>"]
5455 --description = "Library for interacting with CTAP1/2 security keys for Web Authentication. Used by Firefox."
5456 - keywords = ["ctap2", "u2f", "fido", "webauthn"]
5457 - categories = ["cryptography", "hardware-support", "os"]
5458 --license = "MPL-2.0"
5459 - repository = "https://github.com/mozilla/authenticator-rs/"
5460 --[dependencies.base64]
5461 --version = "^0.10"
5462 --optional = true
5463 --
5464 --[dependencies.bitflags]
5465 --version = "1.0"
5466 --
5467 --[dependencies.bytes]
5468 --version = "0.5"
5469 --features = ["serde"]
5470 --optional = true
5471 --
5472 --[dependencies.libc]
5473 --version = "0.2"
5474 --
5475 --[dependencies.log]
5476 --version = "0.4"
5477 --
5478 --[dependencies.rand]
5479 --version = "0.7"
5480 --
5481 --[dependencies.runloop]
5482 --version = "0.1.0"
5483 --
5484 --[dependencies.serde]
5485 --version = "1.0"
5486 --features = ["derive"]
5487 --optional = true
5488 --
5489 --[dependencies.serde_json]
5490 --version = "1.0"
5491 --optional = true
5492 --
5493 --[dependencies.tokio]
5494 --version = "0.2"
5495 --features = ["macros"]
5496 --optional = true
5497 -+license = "MPL-2.0"
5498 -+description = "Library for interacting with CTAP1/2 security keys for Web Authentication. Used by Firefox."
5499 -+edition = "2018"
5500 -
5501 --[dependencies.warp]
5502 --version = "0.2.4"
5503 --optional = true
5504 --[dev-dependencies.assert_matches]
5505 --version = "1.2"
5506 -+[badges]
5507 -+travis-ci = { repository = "mozilla/authenticator-rs", branch = "master" }
5508 -+maintenance = { status = "actively-developed" }
5509 -
5510 --[dev-dependencies.base64]
5511 --version = "^0.10"
5512 -+[features]
5513 -+binding-recompile = ["bindgen"]
5514 -+webdriver = ["base64", "bytes", "warp", "tokio", "serde", "serde_json"]
5515 -
5516 --[dev-dependencies.env_logger]
5517 --version = "^0.6"
5518 -+[target.'cfg(target_os = "linux")'.dependencies]
5519 -+libudev = "^0.2"
5520 -
5521 --[dev-dependencies.getopts]
5522 --version = "^0.2"
5523 -+[target.'cfg(target_os = "freebsd")'.dependencies]
5524 -+devd-rs = "0.3"
5525 -
5526 --[dev-dependencies.sha2]
5527 --version = "^0.8.2"
5528 --[build-dependencies.bindgen]
5529 --version = "^0.51"
5530 --optional = true
5531 -+[target.'cfg(target_os = "macos")'.dependencies]
5532 -+core-foundation = "0.9"
5533 -
5534 --[features]
5535 --binding-recompile = ["bindgen"]
5536 --webdriver = ["base64", "bytes", "warp", "tokio", "serde", "serde_json"]
5537 --[target."cfg(target_os = \"freebsd\")".dependencies.devd-rs]
5538 --version = "0.3"
5539 --[target."cfg(target_os = \"linux\")".dependencies.libudev]
5540 --version = "^0.2"
5541 --[target."cfg(target_os = \"macos\")".dependencies.core-foundation]
5542 --version = "0.9"
5543 --[target."cfg(target_os = \"windows\")".dependencies.winapi]
5544 -+[target.'cfg(target_os = "windows")'.dependencies.winapi]
5545 - version = "^0.3"
5546 --features = ["handleapi", "hidclass", "hidpi", "hidusage", "setupapi"]
5547 --[badges.maintenance]
5548 --status = "actively-developed"
5549 --
5550 --[badges.travis-ci]
5551 --branch = "master"
5552 --repository = "mozilla/authenticator-rs"
5553 -+features = [
5554 -+ "handleapi",
5555 -+ "hidclass",
5556 -+ "hidpi",
5557 -+ "hidusage",
5558 -+ "setupapi",
5559 -+]
5560 -+
5561 -+[build-dependencies]
5562 -+bindgen = { version = "^0.58.1", optional = true }
5563 -+
5564 -+[dependencies]
5565 -+rand = "0.7"
5566 -+log = "0.4"
5567 -+libc = "0.2"
5568 -+runloop = "0.1.0"
5569 -+bitflags = "1.0"
5570 -+tokio = { version = "0.2", optional = true, features = ["macros"] }
5571 -+warp = { version = "0.2.4", optional = true }
5572 -+serde = { version = "1.0", optional = true, features = ["derive"] }
5573 -+serde_json = { version = "1.0", optional = true }
5574 -+bytes = { version = "0.5", optional = true, features = ["serde"] }
5575 -+base64 = { version = "^0.10", optional = true }
5576 -+
5577 -+[dev-dependencies]
5578 -+sha2 = "^0.8.2"
5579 -+base64 = "^0.10"
5580 -+env_logger = "^0.6"
5581 -+getopts = "^0.2"
5582 -+assert_matches = "1.2"
5583 -diff --git a/third_party/rust/authenticator/build.rs b/third_party/rust/authenticator/build.rs
5584 -index 299e4df6d7331..c972d85b898ea 100644
5585 ---- a/third_party/rust/authenticator/build.rs
5586 -+++ b/third_party/rust/authenticator/build.rs
5587 -@@ -45,6 +45,8 @@ fn main() {
5588 - "ioctl_aarch64be.rs"
5589 - } else if cfg!(all(target_arch = "s390x", target_endian = "big")) {
5590 - "ioctl_s390xbe.rs"
5591 -+ } else if cfg!(all(target_arch = "riscv64", target_endian = "little")) {
5592 -+ "ioctl_riscv64.rs"
5593 - } else {
5594 - panic!("architecture not supported");
5595 - };
5596 -diff --git a/third_party/rust/authenticator/src/linux/hidwrapper.rs b/third_party/rust/authenticator/src/linux/hidwrapper.rs
5597 -index ea1a39051b63a..82aabc6301017 100644
5598 ---- a/third_party/rust/authenticator/src/linux/hidwrapper.rs
5599 -+++ b/third_party/rust/authenticator/src/linux/hidwrapper.rs
5600 -@@ -46,3 +46,6 @@ include!("ioctl_aarch64be.rs");
5601 -
5602 - #[cfg(all(target_arch = "s390x", target_endian = "big"))]
5603 - include!("ioctl_s390xbe.rs");
5604 -+
5605 -+#[cfg(all(target_arch = "riscv64", target_endian = "little"))]
5606 -+include!("ioctl_riscv64.rs");
5607 -diff --git a/third_party/rust/authenticator/src/linux/ioctl_riscv64.rs b/third_party/rust/authenticator/src/linux/ioctl_riscv64.rs
5608 -new file mode 100644
5609 -index 0000000000000..a784e9bf4600b
5610 ---- /dev/null
5611 -+++ b/third_party/rust/authenticator/src/linux/ioctl_riscv64.rs
5612 -@@ -0,0 +1,5 @@
5613 -+/* automatically generated by rust-bindgen */
5614 -+
5615 -+pub type __u32 = ::std::os::raw::c_uint;
5616 -+pub const _HIDIOCGRDESCSIZE: __u32 = 2147764225;
5617 -+pub const _HIDIOCGRDESC: __u32 = 2416199682;
5618 ---- a/toolkit/library/rust/shared/Cargo.toml 2022-02-10 20:41:52.387673027 +0800
5619 -+++ b/toolkit/library/rust/shared/Cargo.toml 2022-02-12 17:34:42.861720793 +0800
5620 -@@ -24,7 +24,7 @@
5621 - cubeb-pulse = { git = "https://github.com/mozilla/cubeb-pulse-rs", rev="f2456201dbfdc467b80f0ff6bbb1b8a6faf7df02", optional = true, features=["pulse-dlopen"] }
5622 - cubeb-sys = { version = "0.9", optional = true, features=["gecko-in-tree"] }
5623 - encoding_glue = { path = "../../../../intl/encoding_glue" }
5624 --authenticator = "0.3.1"
5625 -+authenticator = { git = "https://github.com/makotokato/authenticator-rs", rev = "eed8919d50559f4959e2d7d2af7b4d48869b5366" }
5626 - gkrust_utils = { path = "../../../../xpcom/rust/gkrust_utils" }
5627 - gecko_logger = { path = "../../../../xpcom/rust/gecko_logger" }
5628 - rsdparsa_capi = { path = "../../../../dom/media/webrtc/sdp/rsdparsa_capi" }
5629 -From a418c651c88cd2682c4cfe61e9f57b5389078c09 Mon Sep 17 00:00:00 2001
5630 -From: Makoto Kato <m_kato@×××××××××××××.jp>
5631 -Date: Thu, 17 Jun 2021 21:50:49 +0900
5632 -Subject: [PATCH] signal handler
5633 -
5634 ----
5635 - js/src/wasm/WasmSignalHandlers.cpp | 9 +++++++++
5636 - 1 file changed, 9 insertions(+)
5637 ---- a/js/src/wasm/WasmSignalHandlers.cpp 2022-02-12 19:29:33.566924464 +0800
5638 -+++ b/js/src/wasm/WasmSignalHandlers.cpp 2022-02-12 19:50:29.499985612 +0800
5639 -@@ -156,6 +156,11 @@
5640 - # define R01_sig(p) ((p)->uc_mcontext.gp_regs[1])
5641 - # define R32_sig(p) ((p)->uc_mcontext.gp_regs[32])
5642 - # endif
5643 -+# if defined(__linux__) && defined(__riscv) && __riscv_xlen == 64
5644 -+# define EPC_sig(p) ((p)->uc_mcontext.__gregs[0])
5645 -+# define X02_sig(p) ((p)->uc_mcontext.__gregs[2])
5646 -+# define X08_sig(p) ((p)->uc_mcontext.__gregs[8])
5647 -+# endif
5648 - # elif defined(__NetBSD__)
5649 - # define EIP_sig(p) ((p)->uc_mcontext.__gregs[_REG_EIP])
5650 - # define EBP_sig(p) ((p)->uc_mcontext.__gregs[_REG_EBP])
5651 -@@ -376,6 +381,10 @@
5652 - # define PC_sig(p) R32_sig(p)
5653 - # define SP_sig(p) R01_sig(p)
5654 - # define FP_sig(p) R01_sig(p)
5655 -+#elif defined(__riscv) && __riscv_xlen == 64
5656 -+# define PC_sig(p) EPC_sig(p)
5657 -+# define SP_sig(p) X02_sig(p)
5658 -+# define FP_sig(p) X08_sig(p)
5659 - # endif
5660 -
5661 - static void SetContextPC(CONTEXT* context, uint8_t* pc) {
5662 -From b6be52755af09f55e78d86bdd02a99efa0d16f9f Mon Sep 17 00:00:00 2001
5663 -From: Makoto Kato <m_kato@×××××××××××××.jp>
5664 -Date: Fri, 28 Jan 2022 12:21:06 +0900
5665 -Subject: [PATCH] mach vendor rust
5666 -
5667 ----
5668 - .cargo/config.in | 10 +-
5669 - Cargo.lock | 29 +-
5670 - Cargo.toml | 3 +-
5671 - .../mozbuild/mozbuild/vendor/vendor_rust.py | 1 +
5672 - third_party/rust/alsa/.cargo-checksum.json | 2 +-
5673 - third_party/rust/alsa/Cargo.toml | 8 +-
5674 - third_party/rust/alsa/src/direct/pcm.rs | 2 +-
5675 - third_party/rust/alsa/src/error.rs | 1 -
5676 - third_party/rust/alsa/src/lib.rs | 8 +-
5677 - third_party/rust/alsa/src/mixer.rs | 8 +
5678 - third_party/rust/alsa/src/pcm.rs | 78 +-
5679 - .../rust/bitflags/.cargo-checksum.json | 2 +-
5680 - third_party/rust/bitflags/CHANGELOG.md | 57 -
5681 - third_party/rust/bitflags/Cargo.toml | 34 +-
5682 - third_party/rust/bitflags/README.md | 12 +-
5683 - third_party/rust/bitflags/build.rs | 44 +
5684 - third_party/rust/bitflags/src/lib.rs | 873 ++----
5685 - third_party/rust/bitflags/tests/basic.rs | 20 -
5686 - .../bitflags/tests/compile-fail/impls/copy.rs | 10 -
5687 - .../tests/compile-fail/impls/copy.stderr.beta | 27 -
5688 - .../bitflags/tests/compile-fail/impls/eq.rs | 10 -
5689 - .../tests/compile-fail/impls/eq.stderr.beta | 55 -
5690 - .../non_integer_base/all_defined.rs | 123 -
5691 - .../non_integer_base/all_defined.stderr.beta | 27 -
5692 - .../non_integer_base/all_missing.rs | 13 -
5693 - .../non_integer_base/all_missing.stderr.beta | 13 -
5694 - .../compile-fail/visibility/private_field.rs | 13 -
5695 - .../visibility/private_field.stderr.beta | 10 -
5696 - .../compile-fail/visibility/private_flags.rs | 18 -
5697 - .../visibility/private_flags.stderr.beta | 18 -
5698 - .../compile-fail/visibility/pub_const.rs | 9 -
5699 - .../visibility/pub_const.stderr.beta | 5 -
5700 - .../tests/compile-pass/impls/convert.rs | 17 -
5701 - .../tests/compile-pass/impls/default.rs | 10 -
5702 - .../compile-pass/impls/inherent_methods.rs | 15 -
5703 - .../tests/compile-pass/redefinition/core.rs | 14 -
5704 - .../compile-pass/redefinition/stringify.rs | 19 -
5705 - .../bitflags/tests/compile-pass/repr/c.rs | 10 -
5706 - .../tests/compile-pass/repr/transparent.rs | 10 -
5707 - .../compile-pass/visibility/bits_field.rs | 11 -
5708 - .../tests/compile-pass/visibility/pub_in.rs | 19 -
5709 - third_party/rust/bitflags/tests/compile.rs | 63 -
5710 - third_party/rust/midir/.cargo-checksum.json | 2 +-
5711 - third_party/rust/midir/Cargo.toml | 4 +-
5712 - .../rust/nix-0.15.0/.cargo-checksum.json | 1 +
5713 - third_party/rust/nix-0.15.0/CHANGELOG.md | 742 +++++
5714 - third_party/rust/nix-0.15.0/CONTRIBUTING.md | 114 +
5715 - third_party/rust/nix-0.15.0/CONVENTIONS.md | 87 +
5716 - third_party/rust/nix-0.15.0/Cargo.toml | 71 +
5717 - third_party/rust/nix-0.15.0/LICENSE | 21 +
5718 - third_party/rust/nix-0.15.0/README.md | 111 +
5719 - third_party/rust/{nix => nix-0.15.0}/build.rs | 0
5720 - third_party/rust/nix-0.15.0/src/dir.rs | 193 ++
5721 - third_party/rust/nix-0.15.0/src/errno.rs | 1963 ++++++++++++++
5722 - .../{nix => nix-0.15.0}/src/errno_dragonfly.c | 0
5723 - third_party/rust/nix-0.15.0/src/fcntl.rs | 506 ++++
5724 - third_party/rust/nix-0.15.0/src/features.rs | 103 +
5725 - third_party/rust/nix-0.15.0/src/ifaddrs.rs | 146 +
5726 - third_party/rust/nix-0.15.0/src/kmod.rs | 123 +
5727 - third_party/rust/nix-0.15.0/src/lib.rs | 284 ++
5728 - third_party/rust/nix-0.15.0/src/macros.rs | 264 ++
5729 - third_party/rust/nix-0.15.0/src/mount.rs | 98 +
5730 - third_party/rust/nix-0.15.0/src/mqueue.rs | 162 ++
5731 - third_party/rust/nix-0.15.0/src/net/if_.rs | 268 ++
5732 - third_party/rust/nix-0.15.0/src/net/mod.rs | 4 +
5733 - third_party/rust/nix-0.15.0/src/poll.rs | 143 +
5734 - third_party/rust/nix-0.15.0/src/pty.rs | 326 +++
5735 - third_party/rust/nix-0.15.0/src/sched.rs | 147 +
5736 - third_party/rust/nix-0.15.0/src/sys/aio.rs | 1280 +++++++++
5737 - third_party/rust/nix-0.15.0/src/sys/epoll.rs | 109 +
5738 - third_party/rust/nix-0.15.0/src/sys/event.rs | 351 +++
5739 - .../rust/nix-0.15.0/src/sys/eventfd.rs | 18 +
5740 - .../rust/nix-0.15.0/src/sys/inotify.rs | 230 ++
5741 - .../rust/nix-0.15.0/src/sys/ioctl/bsd.rs | 102 +
5742 - .../rust/nix-0.15.0/src/sys/ioctl/linux.rs | 140 +
5743 - .../rust/nix-0.15.0/src/sys/ioctl/mod.rs | 778 ++++++
5744 - third_party/rust/nix-0.15.0/src/sys/memfd.rs | 20 +
5745 - third_party/rust/nix-0.15.0/src/sys/mman.rs | 325 +++
5746 - third_party/rust/nix-0.15.0/src/sys/mod.rs | 100 +
5747 - .../rust/nix-0.15.0/src/sys/pthread.rs | 13 +
5748 - .../rust/nix-0.15.0/src/sys/ptrace/bsd.rs | 170 ++
5749 - .../rust/nix-0.15.0/src/sys/ptrace/linux.rs | 402 +++
5750 - .../rust/nix-0.15.0/src/sys/ptrace/mod.rs | 22 +
5751 - third_party/rust/nix-0.15.0/src/sys/quota.rs | 273 ++
5752 - third_party/rust/nix-0.15.0/src/sys/reboot.rs | 45 +
5753 - third_party/rust/nix-0.15.0/src/sys/select.rs | 334 +++
5754 - .../rust/nix-0.15.0/src/sys/sendfile.rs | 200 ++
5755 - third_party/rust/nix-0.15.0/src/sys/signal.rs | 966 +++++++
5756 - .../rust/nix-0.15.0/src/sys/signalfd.rs | 170 ++
5757 - .../rust/nix-0.15.0/src/sys/socket/addr.rs | 1278 +++++++++
5758 - .../rust/nix-0.15.0/src/sys/socket/mod.rs | 1294 +++++++++
5759 - .../rust/nix-0.15.0/src/sys/socket/sockopt.rs | 680 +++++
5760 - third_party/rust/nix-0.15.0/src/sys/stat.rs | 294 ++
5761 - third_party/rust/nix-0.15.0/src/sys/statfs.rs | 548 ++++
5762 - .../rust/nix-0.15.0/src/sys/statvfs.rs | 160 ++
5763 - .../rust/nix-0.15.0/src/sys/sysinfo.rs | 72 +
5764 - .../rust/nix-0.15.0/src/sys/termios.rs | 1107 ++++++++
5765 - third_party/rust/nix-0.15.0/src/sys/time.rs | 542 ++++
5766 - third_party/rust/nix-0.15.0/src/sys/uio.rs | 194 ++
5767 - .../rust/nix-0.15.0/src/sys/utsname.rs | 67 +
5768 - third_party/rust/nix-0.15.0/src/sys/wait.rs | 239 ++
5769 - third_party/rust/nix-0.15.0/src/ucontext.rs | 39 +
5770 - third_party/rust/nix-0.15.0/src/unistd.rs | 2394 +++++++++++++++++
5771 - third_party/rust/nix-0.15.0/test/sys/mod.rs | 38 +
5772 - .../rust/nix-0.15.0/test/sys/test_aio.rs | 654 +++++
5773 - .../rust/nix-0.15.0/test/sys/test_aio_drop.rs | 32 +
5774 - .../rust/nix-0.15.0/test/sys/test_epoll.rs | 24 +
5775 - .../rust/nix-0.15.0/test/sys/test_inotify.rs | 65 +
5776 - .../rust/nix-0.15.0/test/sys/test_ioctl.rs | 334 +++
5777 - .../test/sys/test_lio_listio_resubmit.rs | 111 +
5778 - .../rust/nix-0.15.0/test/sys/test_pthread.rs | 15 +
5779 - .../rust/nix-0.15.0/test/sys/test_ptrace.rs | 107 +
5780 - .../rust/nix-0.15.0/test/sys/test_select.rs | 54 +
5781 - .../rust/nix-0.15.0/test/sys/test_signal.rs | 104 +
5782 - .../rust/nix-0.15.0/test/sys/test_signalfd.rs | 25 +
5783 - .../rust/nix-0.15.0/test/sys/test_socket.rs | 1066 ++++++++
5784 - .../rust/nix-0.15.0/test/sys/test_sockopt.rs | 53 +
5785 - .../rust/nix-0.15.0/test/sys/test_sysinfo.rs | 18 +
5786 - .../rust/nix-0.15.0/test/sys/test_termios.rs | 136 +
5787 - .../rust/nix-0.15.0/test/sys/test_uio.rs | 241 ++
5788 - .../rust/nix-0.15.0/test/sys/test_wait.rs | 104 +
5789 - third_party/rust/nix-0.15.0/test/test.rs | 149 +
5790 - third_party/rust/nix-0.15.0/test/test_dir.rs | 46 +
5791 - .../rust/nix-0.15.0/test/test_fcntl.rs | 234 ++
5792 - .../test/test_kmod/hello_mod/Makefile | 7 +
5793 - .../test/test_kmod/hello_mod/hello.c | 26 +
5794 - .../rust/nix-0.15.0/test/test_kmod/mod.rs | 166 ++
5795 - .../rust/nix-0.15.0/test/test_mount.rs | 238 ++
5796 - third_party/rust/nix-0.15.0/test/test_mq.rs | 152 ++
5797 - third_party/rust/nix-0.15.0/test/test_net.rs | 12 +
5798 - .../rust/nix-0.15.0/test/test_nix_path.rs | 0
5799 - third_party/rust/nix-0.15.0/test/test_poll.rs | 50 +
5800 - third_party/rust/nix-0.15.0/test/test_pty.rs | 235 ++
5801 - .../nix-0.15.0/test/test_ptymaster_drop.rs | 21 +
5802 - .../rust/nix-0.15.0/test/test_sendfile.rs | 129 +
5803 - third_party/rust/nix-0.15.0/test/test_stat.rs | 296 ++
5804 - .../rust/nix-0.15.0/test/test_unistd.rs | 669 +++++
5805 - third_party/rust/nix/.cargo-checksum.json | 2 +-
5806 - third_party/rust/nix/CHANGELOG.md | 306 ++-
5807 - third_party/rust/nix/CONTRIBUTING.md | 10 +-
5808 - third_party/rust/nix/CONVENTIONS.md | 9 +-
5809 - third_party/rust/nix/Cargo.toml | 40 +-
5810 - third_party/rust/nix/README.md | 22 +-
5811 - third_party/rust/nix/src/dir.rs | 99 +-
5812 - third_party/rust/nix/src/env.rs | 53 +
5813 - third_party/rust/nix/src/errno.rs | 480 +++-
5814 - third_party/rust/nix/src/fcntl.rs | 268 +-
5815 - third_party/rust/nix/src/features.rs | 7 +-
5816 - third_party/rust/nix/src/ifaddrs.rs | 29 +-
5817 - third_party/rust/nix/src/kmod.rs | 4 +-
5818 - third_party/rust/nix/src/lib.rs | 74 +-
5819 - third_party/rust/nix/src/macros.rs | 79 +-
5820 - third_party/rust/nix/src/mount.rs | 43 +-
5821 - third_party/rust/nix/src/mqueue.rs | 65 +-
5822 - third_party/rust/nix/src/net/if_.rs | 3 +-
5823 - third_party/rust/nix/src/poll.rs | 29 +-
5824 - third_party/rust/nix/src/pty.rs | 80 +-
5825 - third_party/rust/nix/src/sched.rs | 104 +-
5826 - third_party/rust/nix/src/sys/aio.rs | 44 +-
5827 - third_party/rust/nix/src/sys/epoll.rs | 8 +-
5828 - third_party/rust/nix/src/sys/event.rs | 45 +-
5829 - third_party/rust/nix/src/sys/eventfd.rs | 4 +-
5830 - third_party/rust/nix/src/sys/inotify.rs | 37 +-
5831 - third_party/rust/nix/src/sys/ioctl/bsd.rs | 4 +-
5832 - third_party/rust/nix/src/sys/ioctl/linux.rs | 3 +-
5833 - third_party/rust/nix/src/sys/ioctl/mod.rs | 12 +-
5834 - third_party/rust/nix/src/sys/memfd.rs | 4 +-
5835 - third_party/rust/nix/src/sys/mman.rs | 136 +-
5836 - third_party/rust/nix/src/sys/mod.rs | 10 +
5837 - third_party/rust/nix/src/sys/personality.rs | 70 +
5838 - third_party/rust/nix/src/sys/ptrace/bsd.rs | 25 +-
5839 - third_party/rust/nix/src/sys/ptrace/linux.rs | 164 +-
5840 - third_party/rust/nix/src/sys/quota.rs | 16 +-
5841 - third_party/rust/nix/src/sys/reboot.rs | 8 +-
5842 - third_party/rust/nix/src/sys/select.rs | 140 +-
5843 - third_party/rust/nix/src/sys/sendfile.rs | 11 +-
5844 - third_party/rust/nix/src/sys/signal.rs | 300 ++-
5845 - third_party/rust/nix/src/sys/signalfd.rs | 28 +-
5846 - third_party/rust/nix/src/sys/socket/addr.rs | 205 +-
5847 - third_party/rust/nix/src/sys/socket/mod.rs | 930 +++++--
5848 - .../rust/nix/src/sys/socket/sockopt.rs | 117 +-
5849 - third_party/rust/nix/src/sys/stat.rs | 39 +-
5850 - third_party/rust/nix/src/sys/statfs.rs | 216 +-
5851 - third_party/rust/nix/src/sys/statvfs.rs | 21 +-
5852 - third_party/rust/nix/src/sys/sysinfo.rs | 19 +-
5853 - third_party/rust/nix/src/sys/termios.rs | 217 +-
5854 - third_party/rust/nix/src/sys/time.rs | 79 +-
5855 - third_party/rust/nix/src/sys/timerfd.rs | 285 ++
5856 - third_party/rust/nix/src/sys/uio.rs | 18 +-
5857 - third_party/rust/nix/src/sys/utsname.rs | 8 +-
5858 - third_party/rust/nix/src/sys/wait.rs | 43 +-
5859 - third_party/rust/nix/src/time.rs | 260 ++
5860 - third_party/rust/nix/src/ucontext.rs | 25 +-
5861 - third_party/rust/nix/src/unistd.rs | 809 ++++--
5862 - third_party/rust/nix/test/common/mod.rs | 127 +
5863 - third_party/rust/nix/test/sys/mod.rs | 7 +
5864 - third_party/rust/nix/test/sys/test_aio.rs | 104 +-
5865 - .../rust/nix/test/sys/test_aio_drop.rs | 4 +-
5866 - third_party/rust/nix/test/sys/test_ioctl.rs | 55 +-
5867 - .../nix/test/sys/test_lio_listio_resubmit.rs | 4 -
5868 - third_party/rust/nix/test/sys/test_mman.rs | 80 +
5869 - third_party/rust/nix/test/sys/test_pthread.rs | 4 +-
5870 - third_party/rust/nix/test/sys/test_ptrace.rs | 79 +-
5871 - third_party/rust/nix/test/sys/test_select.rs | 2 +-
5872 - third_party/rust/nix/test/sys/test_signal.rs | 25 +-
5873 - .../rust/nix/test/sys/test_signalfd.rs | 6 +-
5874 - third_party/rust/nix/test/sys/test_socket.rs | 555 +++-
5875 - third_party/rust/nix/test/sys/test_sockopt.rs | 43 +
5876 - third_party/rust/nix/test/sys/test_termios.rs | 22 +-
5877 - third_party/rust/nix/test/sys/test_timerfd.rs | 61 +
5878 - third_party/rust/nix/test/sys/test_uio.rs | 12 +-
5879 - third_party/rust/nix/test/sys/test_wait.rs | 21 +-
5880 - third_party/rust/nix/test/test.rs | 71 +-
5881 - third_party/rust/nix/test/test_clearenv.rs | 9 +
5882 - third_party/rust/nix/test/test_dir.rs | 7 +-
5883 - third_party/rust/nix/test/test_fcntl.rs | 199 +-
5884 - third_party/rust/nix/test/test_kmod/mod.rs | 31 +-
5885 - third_party/rust/nix/test/test_mount.rs | 7 +-
5886 - third_party/rust/nix/test/test_mq.rs | 28 +-
5887 - third_party/rust/nix/test/test_poll.rs | 27 +-
5888 - third_party/rust/nix/test/test_pty.rs | 104 +-
5889 - .../rust/nix/test/test_ptymaster_drop.rs | 41 +-
5890 - third_party/rust/nix/test/test_sched.rs | 32 +
5891 - third_party/rust/nix/test/test_stat.rs | 61 +-
5892 - third_party/rust/nix/test/test_time.rs | 56 +
5893 - third_party/rust/nix/test/test_unistd.rs | 575 +++-
5894 - 226 files changed, 33484 insertions(+), 3322 deletions(-)
5895 - create mode 100644 third_party/rust/bitflags/build.rs
5896 - delete mode 100644 third_party/rust/bitflags/tests/basic.rs
5897 - delete mode 100644 third_party/rust/bitflags/tests/compile-fail/impls/copy.rs
5898 - delete mode 100644 third_party/rust/bitflags/tests/compile-fail/impls/copy.stderr.beta
5899 - delete mode 100644 third_party/rust/bitflags/tests/compile-fail/impls/eq.rs
5900 - delete mode 100644 third_party/rust/bitflags/tests/compile-fail/impls/eq.stderr.beta
5901 - delete mode 100644 third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_defined.rs
5902 - delete mode 100644 third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_defined.stderr.beta
5903 - delete mode 100644 third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_missing.rs
5904 - delete mode 100644 third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_missing.stderr.beta
5905 - delete mode 100644 third_party/rust/bitflags/tests/compile-fail/visibility/private_field.rs
5906 - delete mode 100644 third_party/rust/bitflags/tests/compile-fail/visibility/private_field.stderr.beta
5907 - delete mode 100644 third_party/rust/bitflags/tests/compile-fail/visibility/private_flags.rs
5908 - delete mode 100644 third_party/rust/bitflags/tests/compile-fail/visibility/private_flags.stderr.beta
5909 - delete mode 100644 third_party/rust/bitflags/tests/compile-fail/visibility/pub_const.rs
5910 - delete mode 100644 third_party/rust/bitflags/tests/compile-fail/visibility/pub_const.stderr.beta
5911 - delete mode 100644 third_party/rust/bitflags/tests/compile-pass/impls/convert.rs
5912 - delete mode 100644 third_party/rust/bitflags/tests/compile-pass/impls/default.rs
5913 - delete mode 100644 third_party/rust/bitflags/tests/compile-pass/impls/inherent_methods.rs
5914 - delete mode 100644 third_party/rust/bitflags/tests/compile-pass/redefinition/core.rs
5915 - delete mode 100644 third_party/rust/bitflags/tests/compile-pass/redefinition/stringify.rs
5916 - delete mode 100644 third_party/rust/bitflags/tests/compile-pass/repr/c.rs
5917 - delete mode 100644 third_party/rust/bitflags/tests/compile-pass/repr/transparent.rs
5918 - delete mode 100644 third_party/rust/bitflags/tests/compile-pass/visibility/bits_field.rs
5919 - delete mode 100644 third_party/rust/bitflags/tests/compile-pass/visibility/pub_in.rs
5920 - delete mode 100644 third_party/rust/bitflags/tests/compile.rs
5921 - create mode 100644 third_party/rust/nix-0.15.0/.cargo-checksum.json
5922 - create mode 100644 third_party/rust/nix-0.15.0/CHANGELOG.md
5923 - create mode 100644 third_party/rust/nix-0.15.0/CONTRIBUTING.md
5924 - create mode 100644 third_party/rust/nix-0.15.0/CONVENTIONS.md
5925 - create mode 100644 third_party/rust/nix-0.15.0/Cargo.toml
5926 - create mode 100644 third_party/rust/nix-0.15.0/LICENSE
5927 - create mode 100644 third_party/rust/nix-0.15.0/README.md
5928 - rename third_party/rust/{nix => nix-0.15.0}/build.rs (100%)
5929 - create mode 100644 third_party/rust/nix-0.15.0/src/dir.rs
5930 - create mode 100644 third_party/rust/nix-0.15.0/src/errno.rs
5931 - rename third_party/rust/{nix => nix-0.15.0}/src/errno_dragonfly.c (100%)
5932 - create mode 100644 third_party/rust/nix-0.15.0/src/fcntl.rs
5933 - create mode 100644 third_party/rust/nix-0.15.0/src/features.rs
5934 - create mode 100644 third_party/rust/nix-0.15.0/src/ifaddrs.rs
5935 - create mode 100644 third_party/rust/nix-0.15.0/src/kmod.rs
5936 - create mode 100644 third_party/rust/nix-0.15.0/src/lib.rs
5937 - create mode 100644 third_party/rust/nix-0.15.0/src/macros.rs
5938 - create mode 100644 third_party/rust/nix-0.15.0/src/mount.rs
5939 - create mode 100644 third_party/rust/nix-0.15.0/src/mqueue.rs
5940 - create mode 100644 third_party/rust/nix-0.15.0/src/net/if_.rs
5941 - create mode 100644 third_party/rust/nix-0.15.0/src/net/mod.rs
5942 - create mode 100644 third_party/rust/nix-0.15.0/src/poll.rs
5943 - create mode 100644 third_party/rust/nix-0.15.0/src/pty.rs
5944 - create mode 100644 third_party/rust/nix-0.15.0/src/sched.rs
5945 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/aio.rs
5946 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/epoll.rs
5947 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/event.rs
5948 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/eventfd.rs
5949 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/inotify.rs
5950 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/ioctl/bsd.rs
5951 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/ioctl/linux.rs
5952 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/ioctl/mod.rs
5953 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/memfd.rs
5954 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/mman.rs
5955 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/mod.rs
5956 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/pthread.rs
5957 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/ptrace/bsd.rs
5958 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/ptrace/linux.rs
5959 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/ptrace/mod.rs
5960 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/quota.rs
5961 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/reboot.rs
5962 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/select.rs
5963 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/sendfile.rs
5964 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/signal.rs
5965 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/signalfd.rs
5966 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/socket/addr.rs
5967 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/socket/mod.rs
5968 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/socket/sockopt.rs
5969 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/stat.rs
5970 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/statfs.rs
5971 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/statvfs.rs
5972 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/sysinfo.rs
5973 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/termios.rs
5974 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/time.rs
5975 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/uio.rs
5976 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/utsname.rs
5977 - create mode 100644 third_party/rust/nix-0.15.0/src/sys/wait.rs
5978 - create mode 100644 third_party/rust/nix-0.15.0/src/ucontext.rs
5979 - create mode 100644 third_party/rust/nix-0.15.0/src/unistd.rs
5980 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/mod.rs
5981 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_aio.rs
5982 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_aio_drop.rs
5983 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_epoll.rs
5984 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_inotify.rs
5985 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_ioctl.rs
5986 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_lio_listio_resubmit.rs
5987 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_pthread.rs
5988 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_ptrace.rs
5989 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_select.rs
5990 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_signal.rs
5991 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_signalfd.rs
5992 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_socket.rs
5993 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_sockopt.rs
5994 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_sysinfo.rs
5995 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_termios.rs
5996 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_uio.rs
5997 - create mode 100644 third_party/rust/nix-0.15.0/test/sys/test_wait.rs
5998 - create mode 100644 third_party/rust/nix-0.15.0/test/test.rs
5999 - create mode 100644 third_party/rust/nix-0.15.0/test/test_dir.rs
6000 - create mode 100644 third_party/rust/nix-0.15.0/test/test_fcntl.rs
6001 - create mode 100644 third_party/rust/nix-0.15.0/test/test_kmod/hello_mod/Makefile
6002 - create mode 100644 third_party/rust/nix-0.15.0/test/test_kmod/hello_mod/hello.c
6003 - create mode 100644 third_party/rust/nix-0.15.0/test/test_kmod/mod.rs
6004 - create mode 100644 third_party/rust/nix-0.15.0/test/test_mount.rs
6005 - create mode 100644 third_party/rust/nix-0.15.0/test/test_mq.rs
6006 - create mode 100644 third_party/rust/nix-0.15.0/test/test_net.rs
6007 - create mode 100644 third_party/rust/nix-0.15.0/test/test_nix_path.rs
6008 - create mode 100644 third_party/rust/nix-0.15.0/test/test_poll.rs
6009 - create mode 100644 third_party/rust/nix-0.15.0/test/test_pty.rs
6010 - create mode 100644 third_party/rust/nix-0.15.0/test/test_ptymaster_drop.rs
6011 - create mode 100644 third_party/rust/nix-0.15.0/test/test_sendfile.rs
6012 - create mode 100644 third_party/rust/nix-0.15.0/test/test_stat.rs
6013 - create mode 100644 third_party/rust/nix-0.15.0/test/test_unistd.rs
6014 - create mode 100644 third_party/rust/nix/src/env.rs
6015 - create mode 100644 third_party/rust/nix/src/sys/personality.rs
6016 - create mode 100644 third_party/rust/nix/src/sys/timerfd.rs
6017 - create mode 100644 third_party/rust/nix/src/time.rs
6018 - create mode 100644 third_party/rust/nix/test/common/mod.rs
6019 - create mode 100644 third_party/rust/nix/test/sys/test_mman.rs
6020 - create mode 100644 third_party/rust/nix/test/sys/test_timerfd.rs
6021 - create mode 100644 third_party/rust/nix/test/test_clearenv.rs
6022 - create mode 100644 third_party/rust/nix/test/test_sched.rs
6023 - create mode 100644 third_party/rust/nix/test/test_time.rs
6024 -
6025 -diff --git a/Cargo.lock b/Cargo.lock
6026 -index edc5ef5ff2d98..f6240163e1440 100644
6027 ---- a/Cargo.lock
6028 -+++ b/Cargo.lock
6029 -@@ -25,14 +25,14 @@ dependencies = [
6030 -
6031 - [[package]]
6032 - name = "alsa"
6033 --version = "0.4.3"
6034 -+version = "0.5.0"
6035 - source = "registry+https://github.com/rust-lang/crates.io-index"
6036 --checksum = "eb213f6b3e4b1480a60931ca2035794aa67b73103d254715b1db7b70dcb3c934"
6037 -+checksum = "75c4da790adcb2ce5e758c064b4f3ec17a30349f9961d3e5e6c9688b052a9e18"
6038 - dependencies = [
6039 - "alsa-sys",
6040 - "bitflags",
6041 - "libc",
6042 -- "nix",
6043 -+ "nix 0.20.2",
6044 - ]
6045 -
6046 - [[package]]
6047 -@@ -427,9 +427,9 @@ checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
6048 -
6049 - [[package]]
6050 - name = "bitflags"
6051 --version = "1.3.2"
6052 -+version = "1.2.1"
6053 - source = "registry+https://github.com/rust-lang/crates.io-index"
6054 --checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
6055 -+checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
6056 -
6057 - [[package]]
6058 - name = "bitflags_serde_shim"
6059 -@@ -3073,7 +3073,7 @@ dependencies = [
6060 - [[package]]
6061 - name = "midir"
6062 - version = "0.7.0"
6063 --source = "git+https://github.com/mozilla/midir.git?rev=4c11f0ffb5d6a10de4aff40a7b81218b33b94e6f#4c11f0ffb5d6a10de4aff40a7b81218b33b94e6f"
6064 -+source = "git+https://github.com/makotokato/midir.git?rev=6140b2825dd4dc2b40e49e154ca7596e7b9a131a#6140b2825dd4dc2b40e49e154ca7596e7b9a131a"
6065 - dependencies = [
6066 - "alsa",
6067 - "bitflags",
6068 -@@ -3081,7 +3081,7 @@ dependencies = [
6069 - "js-sys",
6070 - "libc",
6071 - "memalloc",
6072 -- "nix",
6073 -+ "nix 0.20.2",
6074 - "wasm-bindgen",
6075 - "web-sys",
6076 - "winapi",
6077 -@@ -3123,7 +3123,7 @@ dependencies = [
6078 - "libc",
6079 - "memmap2 0.2.3",
6080 - "memoffset 0.5.6",
6081 -- "nix",
6082 -+ "nix 0.15.0",
6083 - "tempfile",
6084 - "thiserror",
6085 - ]
6086 -@@ -3535,6 +3535,19 @@ dependencies = [
6087 - "void",
6088 - ]
6089 -
6090 -+[[package]]
6091 -+name = "nix"
6092 -+version = "0.20.2"
6093 -+source = "registry+https://github.com/rust-lang/crates.io-index"
6094 -+checksum = "f5e06129fb611568ef4e868c14b326274959aa70ff7776e9d55323531c374945"
6095 -+dependencies = [
6096 -+ "bitflags",
6097 -+ "cc",
6098 -+ "cfg-if 1.0.0",
6099 -+ "libc",
6100 -+ "memoffset 0.6.5",
6101 -+]
6102 -+
6103 - [[package]]
6104 - name = "nom"
6105 - version = "5.1.2"
6106 -diff --git a/Cargo.toml b/Cargo.toml
6107 -index 1c2437f1f5675..2923c7e5ea9bf 100644
6108 ---- a/Cargo.toml 2022-03-10 14:19:47.963772765 +0800
6109 -+++ b/Cargo.toml 2022-03-10 14:33:46.354649188 +0800
6110 -@@ -103,13 +103,14 @@
6111 - moz_asserts = { path = "mozglue/static/rust/moz_asserts" }
6112 -
6113 - # Other overrides
6114 -+authenticator = { git = "https://github.com/makotokato/authenticator-rs", rev="eed8919d50559f4959e2d7d2af7b4d48869b5366" }
6115 - async-task = { git = "https://github.com/smol-rs/async-task", rev="f6488e35beccb26eb6e85847b02aa78a42cd3d0e" }
6116 - chardetng = { git = "https://github.com/hsivonen/chardetng", rev="3484d3e3ebdc8931493aa5df4d7ee9360a90e76b" }
6117 - chardetng_c = { git = "https://github.com/hsivonen/chardetng_c", rev="ed8a4c6f900a90d4dbc1d64b856e61490a1c3570" }
6118 - coremidi = { git = "https://github.com/chris-zen/coremidi.git", rev="fc68464b5445caf111e41f643a2e69ccce0b4f83" }
6119 - libudev-sys = { path = "dom/webauthn/libudev-sys" }
6120 - packed_simd = { git = "https://github.com/hsivonen/packed_simd", rev="8b4bd7d8229660a749dbe419a57ea01df9de5453" }
6121 --midir = { git = "https://github.com/mozilla/midir.git", rev = "4c11f0ffb5d6a10de4aff40a7b81218b33b94e6f" }
6122 -+midir = { git = "https://github.com/makotokato/midir.git", rev = "6140b2825dd4dc2b40e49e154ca7596e7b9a131a" }
6123 - minidump_writer_linux = { git = "https://github.com/msirringhaus/minidump_writer_linux.git", rev = "029ac0d54b237f27dc7d8d4e51bc0fb076e5e852" }
6124 -
6125 - # Patch mio 0.6 to use winapi 0.3 and miow 0.3, getting rid of winapi 0.2.
6126 -
6127 -diff --git a/third_party/rust/alsa/.cargo-checksum.json b/third_party/rust/alsa/.cargo-checksum.json
6128 -index 17227c0a74d16..2bd6b2e2ce47b 100644
6129 ---- a/third_party/rust/alsa/.cargo-checksum.json
6130 -+++ b/third_party/rust/alsa/.cargo-checksum.json
6131 -@@ -1 +1 @@
6132 --{"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":"cc33947cb0810d3edeec7b71686f0231d06c88b421
6133 4994605de7f4fd0f6de1a1","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"}
6134 -\ No newline at end of file
6135 -+{"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":"cc33947cb0810d3edeec7b71686f0231d06c88b421
6136 4994605de7f4fd0f6de1a1","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"}
6137 -\ No newline at end of file
6138 -diff --git a/third_party/rust/alsa/Cargo.toml b/third_party/rust/alsa/Cargo.toml
6139 -index c7578fb0785b9..b4af1a6dae284 100644
6140 ---- a/third_party/rust/alsa/Cargo.toml
6141 -+++ b/third_party/rust/alsa/Cargo.toml
6142 -@@ -13,7 +13,7 @@
6143 - [package]
6144 - edition = "2018"
6145 - name = "alsa"
6146 --version = "0.4.3"
6147 -+version = "0.5.0"
6148 - authors = ["David Henningsson <diwic@××××××.com>"]
6149 - description = "Thin but safe wrappers for ALSA (Linux sound API)"
6150 - documentation = "http://docs.rs/alsa"
6151 -@@ -23,16 +23,16 @@ categories = ["multimedia::audio", "api-bindings"]
6152 - license = "Apache-2.0/MIT"
6153 - repository = "https://github.com/diwic/alsa-rs"
6154 - [dependencies.alsa-sys]
6155 --version = "0.3.0"
6156 -+version = "0.3.1"
6157 -
6158 - [dependencies.bitflags]
6159 - version = "1.2.1"
6160 -
6161 - [dependencies.libc]
6162 --version = "0.2.65"
6163 -+version = "0.2.88"
6164 -
6165 - [dependencies.nix]
6166 --version = "0.15"
6167 -+version = "0.20"
6168 - [badges.is-it-maintained-issue-resolution]
6169 - repository = "diwic/alsa-rs"
6170 -
6171 -diff --git a/third_party/rust/alsa/src/direct/pcm.rs b/third_party/rust/alsa/src/direct/pcm.rs
6172 -index 13a16a993b030..f248a70c67031 100644
6173 ---- a/third_party/rust/alsa/src/direct/pcm.rs
6174 -+++ b/third_party/rust/alsa/src/direct/pcm.rs
6175 -@@ -19,7 +19,7 @@ don't expect it to work with, e g, the PulseAudio plugin or so.
6176 - For an example of how to use this mode, look in the "synth-example" directory.
6177 - */
6178 -
6179 --use {libc, nix};
6180 -+use libc;
6181 - use std::{mem, ptr, fmt, cmp};
6182 - use crate::error::{Error, Result};
6183 - use std::os::unix::io::RawFd;
6184 -diff --git a/third_party/rust/alsa/src/error.rs b/third_party/rust/alsa/src/error.rs
6185 -index 4711b0fd2016d..25089c4cbd1d7 100644
6186 ---- a/third_party/rust/alsa/src/error.rs
6187 -+++ b/third_party/rust/alsa/src/error.rs
6188 -@@ -3,7 +3,6 @@
6189 - use libc::{c_void, c_int, c_char, free};
6190 - use std::{fmt, ptr, str};
6191 - use std::ffi::CStr;
6192 --use nix;
6193 - use std::error::Error as StdError;
6194 -
6195 - /// ALSA error
6196 -diff --git a/third_party/rust/alsa/src/lib.rs b/third_party/rust/alsa/src/lib.rs
6197 -index cf172cb6c60c6..b1a98df7804f3 100644
6198 ---- a/third_party/rust/alsa/src/lib.rs
6199 -+++ b/third_party/rust/alsa/src/lib.rs
6200 -@@ -18,7 +18,7 @@ extern crate libc;
6201 - #[macro_use]
6202 - extern crate bitflags;
6203 - #[macro_use]
6204 --extern crate nix;
6205 -+extern crate nix as nix_the_crate;
6206 -
6207 - macro_rules! alsa_enum {
6208 - ($(#[$attr:meta])+ $name:ident, $static_name:ident [$count:expr], $( $a:ident = $b:ident),* ,) =>
6209 -@@ -125,3 +125,9 @@ pub use crate::io::Output;
6210 - mod chmap;
6211 -
6212 - pub mod direct;
6213 -+
6214 -+/// Re-exports from the nix crate.
6215 -+pub mod nix {
6216 -+ pub use nix_the_crate::Error;
6217 -+ pub use nix_the_crate::errno;
6218 -+}
6219 -diff --git a/third_party/rust/alsa/src/mixer.rs b/third_party/rust/alsa/src/mixer.rs
6220 -index cb16247a85b62..834aafaf35c18 100644
6221 ---- a/third_party/rust/alsa/src/mixer.rs
6222 -+++ b/third_party/rust/alsa/src/mixer.rs
6223 -@@ -112,11 +112,19 @@ impl ops::Add for MilliBel {
6224 - fn add(self, rhs: Self) -> Self { MilliBel(self.0 + rhs.0) }
6225 - }
6226 -
6227 -+impl ops::AddAssign for MilliBel {
6228 -+ fn add_assign(&mut self, rhs: Self) { self.0 += rhs.0 }
6229 -+}
6230 -+
6231 - impl ops::Sub for MilliBel {
6232 - type Output = MilliBel;
6233 - fn sub(self, rhs: Self) -> Self { MilliBel(self.0 - rhs.0) }
6234 - }
6235 -
6236 -+impl ops::SubAssign for MilliBel {
6237 -+ fn sub_assign(&mut self, rhs: Self) { self.0 -= rhs.0 }
6238 -+}
6239 -+
6240 - /// Wraps [snd_mixer_elem_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___mixer.html)
6241 - #[derive(Copy, Clone, Debug)]
6242 - pub struct Elem<'a>{
6243 -diff --git a/third_party/rust/alsa/src/pcm.rs b/third_party/rust/alsa/src/pcm.rs
6244 -index 359b44c6db2cb..5696df9dc691e 100644
6245 ---- a/third_party/rust/alsa/src/pcm.rs
6246 -+++ b/third_party/rust/alsa/src/pcm.rs
6247 -@@ -174,8 +174,7 @@ impl PCM {
6248 - }
6249 -
6250 - pub fn status(&self) -> Result<Status> {
6251 -- let z = Status::new();
6252 -- acheck!(snd_pcm_status(self.0, z.ptr())).map(|_| z)
6253 -+ StatusBuilder::new().build(self)
6254 - }
6255 -
6256 - fn verify_format(&self, f: Format) -> Result<()> {
6257 -@@ -416,6 +415,7 @@ alsa_enum!(
6258 - );
6259 -
6260 - alsa_enum!(
6261 -+ #[non_exhaustive]
6262 - /// [SND_PCM_FORMAT_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants
6263 - Format, ALL_FORMATS[48],
6264 -
6265 -@@ -470,21 +470,21 @@ alsa_enum!(
6266 - );
6267 -
6268 - impl Format {
6269 -- pub fn s16() -> Format { <i16 as IoFormat>::FORMAT }
6270 -- pub fn u16() -> Format { <u16 as IoFormat>::FORMAT }
6271 -- pub fn s32() -> Format { <i32 as IoFormat>::FORMAT }
6272 -- pub fn u32() -> Format { <u32 as IoFormat>::FORMAT }
6273 -- pub fn float() -> Format { <f32 as IoFormat>::FORMAT }
6274 -- pub fn float64() -> Format { <f64 as IoFormat>::FORMAT }
6275 -+ pub const fn s16() -> Format { <i16 as IoFormat>::FORMAT }
6276 -+ pub const fn u16() -> Format { <u16 as IoFormat>::FORMAT }
6277 -+ pub const fn s32() -> Format { <i32 as IoFormat>::FORMAT }
6278 -+ pub const fn u32() -> Format { <u32 as IoFormat>::FORMAT }
6279 -+ pub const fn float() -> Format { <f32 as IoFormat>::FORMAT }
6280 -+ pub const fn float64() -> Format { <f64 as IoFormat>::FORMAT }
6281 -
6282 -- #[cfg(target_endian = "little")] pub fn s24() -> Format { Format::S24LE }
6283 -- #[cfg(target_endian = "big")] pub fn s24() -> Format { Format::S24BE }
6284 -+ #[cfg(target_endian = "little")] pub const fn s24() -> Format { Format::S24LE }
6285 -+ #[cfg(target_endian = "big")] pub const fn s24() -> Format { Format::S24BE }
6286 -
6287 -- #[cfg(target_endian = "little")] pub fn u24() -> Format { Format::U24LE }
6288 -- #[cfg(target_endian = "big")] pub fn u24() -> Format { Format::U24BE }
6289 -+ #[cfg(target_endian = "little")] pub const fn u24() -> Format { Format::U24LE }
6290 -+ #[cfg(target_endian = "big")] pub const fn u24() -> Format { Format::U24BE }
6291 -
6292 -- #[cfg(target_endian = "little")] pub fn iec958_subframe() -> Format { Format::IEC958SubframeLE }
6293 -- #[cfg(target_endian = "big")] pub fn iec958_subframe() -> Format { Format::IEC958SubframeBE }
6294 -+ #[cfg(target_endian = "little")] pub const fn iec958_subframe() -> Format { Format::IEC958SubframeLE }
6295 -+ #[cfg(target_endian = "big")] pub const fn iec958_subframe() -> Format { Format::IEC958SubframeBE }
6296 - }
6297 -
6298 -
6299 -@@ -769,6 +769,15 @@ impl<'a> HwParams<'a> {
6300 - unsafe { alsa::snd_pcm_hw_params_can_resume(self.0) != 0 }
6301 - }
6302 -
6303 -+ /// Returns true if the alsa stream supports the provided `AudioTstampType`, false if not.
6304 -+ ///
6305 -+ /// This function should only be called when the configuration space contains a single
6306 -+ /// configuration. Call `PCM::hw_params` to choose a single configuration from the
6307 -+ /// configuration space.
6308 -+ pub fn supports_audio_ts_type(&self, type_: AudioTstampType) -> bool {
6309 -+ unsafe { alsa::snd_pcm_hw_params_supports_audio_ts_type(self.0, type_ as libc::c_int) != 0 }
6310 -+ }
6311 -+
6312 - pub fn dump(&self, o: &mut Output) -> Result<()> {
6313 - acheck!(snd_pcm_hw_params_dump(self.0, super::io::output_handle(o))).map(|_| ())
6314 - }
6315 -@@ -923,6 +932,47 @@ impl Status {
6316 - }
6317 - }
6318 -
6319 -+/// Builder for [`Status`].
6320 -+///
6321 -+/// Allows setting the audio timestamp configuration before retrieving the
6322 -+/// status from the stream.
6323 -+pub struct StatusBuilder(Status);
6324 -+
6325 -+impl StatusBuilder {
6326 -+ pub fn new() -> Self {
6327 -+ StatusBuilder(Status::new())
6328 -+ }
6329 -+
6330 -+ pub fn audio_htstamp_config(
6331 -+ self,
6332 -+ type_requested: AudioTstampType,
6333 -+ report_delay: bool,
6334 -+ ) -> Self {
6335 -+ let mut cfg: alsa::snd_pcm_audio_tstamp_config_t = unsafe { std::mem::zeroed() };
6336 -+ cfg.set_type_requested(type_requested as _);
6337 -+ cfg.set_report_delay(report_delay as _);
6338 -+ unsafe { alsa::snd_pcm_status_set_audio_htstamp_config(self.0.ptr(), &mut cfg) };
6339 -+ self
6340 -+ }
6341 -+
6342 -+ pub fn build(self, pcm: &PCM) -> Result<Status> {
6343 -+ acheck!(snd_pcm_status(pcm.0, self.0.ptr())).map(|_| self.0)
6344 -+ }
6345 -+}
6346 -+
6347 -+alsa_enum!(
6348 -+ #[non_exhaustive]
6349 -+ /// [SND_PCM_AUDIO_TSTAMP_TYPE_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html) constants
6350 -+ AudioTstampType, ALL_AUDIO_TSTAMP_TYPES[6],
6351 -+
6352 -+ Compat = SND_PCM_AUDIO_TSTAMP_TYPE_COMPAT,
6353 -+ Default = SND_PCM_AUDIO_TSTAMP_TYPE_DEFAULT,
6354 -+ Link = SND_PCM_AUDIO_TSTAMP_TYPE_LINK,
6355 -+ LinkAbsolute = SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE,
6356 -+ LinkEstimated = SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED,
6357 -+ LinkSynchronized = SND_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED,
6358 -+);
6359 -+
6360 - #[test]
6361 - fn info_from_default() {
6362 - use std::ffi::CString;
6363 -diff --git a/third_party/rust/bitflags/.cargo-checksum.json b/third_party/rust/bitflags/.cargo-checksum.json
6364 -index 7e8d470b53a37..a8b031c6517a2 100644
6365 ---- a/third_party/rust/bitflags/.cargo-checksum.json
6366 -+++ b/third_party/rust/bitflags/.cargo-checksum.json
6367 -@@ -1 +1 @@
6368 --{"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/i
6369 mpls/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":"2ce4235802aa4e9c96c4
6370 e77d9e31d8401ef58dcda4741325184f0764ab1fe393","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":"6fda17f7c2edfc
6371 d155314579e83d0fc8a16209e400f1f9a5ca77bd9a799041f2","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"}
6372 -\ No newline at end of file
6373 -+{"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"}
6374 -\ No newline at end of file
6375 -diff --git a/third_party/rust/bitflags/CHANGELOG.md b/third_party/rust/bitflags/CHANGELOG.md
6376 -index 12fea1673ac30..0d4910153d909 100644
6377 ---- a/third_party/rust/bitflags/CHANGELOG.md
6378 -+++ b/third_party/rust/bitflags/CHANGELOG.md
6379 -@@ -1,60 +1,3 @@
6380 --# 1.3.2
6381 --
6382 --- Allow `non_snake_case` in generated flags types ([#256])
6383 --
6384 --[#252]: https://github.com/bitflags/bitflags/pull/256
6385 --
6386 --# 1.3.1
6387 --
6388 --- Revert unconditional `#[repr(transparent)]` ([#252])
6389 --
6390 --[#252]: https://github.com/bitflags/bitflags/pull/252
6391 --
6392 --# 1.3.0 (yanked)
6393 --
6394 --- Add `#[repr(transparent)]` ([#187])
6395 --
6396 --- End `empty` doc comment with full stop ([#202])
6397 --
6398 --- Fix typo in crate root docs ([#206])
6399 --
6400 --- Document from_bits_unchecked unsafety ([#207])
6401 --
6402 --- Let `is_all` ignore extra bits ([#211])
6403 --
6404 --- Allows empty flag definition ([#225])
6405 --
6406 --- Making crate accessible from std ([#227])
6407 --
6408 --- Make `from_bits` a const fn ([#229])
6409 --
6410 --- Allow multiple bitflags structs in one macro invocation ([#235])
6411 --
6412 --- Add named functions to perform set operations ([#244])
6413 --
6414 --- Fix typos in method docs ([#245])
6415 --
6416 --- Modernization of the `bitflags` macro to take advantage of newer features and 2018 idioms ([#246])
6417 --
6418 --- Fix regression (in an unreleased feature) and simplify tests ([#247])
6419 --
6420 --- Use `Self` and fix bug when overriding `stringify!` ([#249])
6421 --
6422 --[#187]: https://github.com/bitflags/bitflags/pull/187
6423 --[#202]: https://github.com/bitflags/bitflags/pull/202
6424 --[#206]: https://github.com/bitflags/bitflags/pull/206
6425 --[#207]: https://github.com/bitflags/bitflags/pull/207
6426 --[#211]: https://github.com/bitflags/bitflags/pull/211
6427 --[#225]: https://github.com/bitflags/bitflags/pull/225
6428 --[#227]: https://github.com/bitflags/bitflags/pull/227
6429 --[#229]: https://github.com/bitflags/bitflags/pull/229
6430 --[#235]: https://github.com/bitflags/bitflags/pull/235
6431 --[#244]: https://github.com/bitflags/bitflags/pull/244
6432 --[#245]: https://github.com/bitflags/bitflags/pull/245
6433 --[#246]: https://github.com/bitflags/bitflags/pull/246
6434 --[#247]: https://github.com/bitflags/bitflags/pull/247
6435 --[#249]: https://github.com/bitflags/bitflags/pull/249
6436 --
6437 - # 1.2.1
6438 -
6439 - - Remove extraneous `#[inline]` attributes ([#194])
6440 -diff --git a/third_party/rust/bitflags/Cargo.toml b/third_party/rust/bitflags/Cargo.toml
6441 -index 9d54c725a1c5d..b803644d44753 100644
6442 ---- a/third_party/rust/bitflags/Cargo.toml
6443 -+++ b/third_party/rust/bitflags/Cargo.toml
6444 -@@ -11,11 +11,11 @@
6445 - # will likely look very different (and much more reasonable)
6446 -
6447 - [package]
6448 --edition = "2018"
6449 - name = "bitflags"
6450 --version = "1.3.2"
6451 -+version = "1.2.1"
6452 - authors = ["The Rust Project Developers"]
6453 --exclude = ["bors.toml"]
6454 -+build = "build.rs"
6455 -+exclude = [".travis.yml", "appveyor.yml", "bors.toml"]
6456 - description = "A macro to generate structures which behave like bitflags.\n"
6457 - homepage = "https://github.com/bitflags/bitflags"
6458 - documentation = "https://docs.rs/bitflags"
6459 -@@ -26,33 +26,9 @@ license = "MIT/Apache-2.0"
6460 - repository = "https://github.com/bitflags/bitflags"
6461 - [package.metadata.docs.rs]
6462 - features = ["example_generated"]
6463 --[dependencies.compiler_builtins]
6464 --version = "0.1.2"
6465 --optional = true
6466 --
6467 --[dependencies.core]
6468 --version = "1.0.0"
6469 --optional = true
6470 --package = "rustc-std-workspace-core"
6471 --[dev-dependencies.rustversion]
6472 --version = "1.0"
6473 --
6474 --[dev-dependencies.serde]
6475 --version = "1.0"
6476 --
6477 --[dev-dependencies.serde_derive]
6478 --version = "1.0"
6479 --
6480 --[dev-dependencies.serde_json]
6481 --version = "1.0"
6482 --
6483 --[dev-dependencies.trybuild]
6484 --version = "1.0"
6485 --
6486 --[dev-dependencies.walkdir]
6487 --version = "2.3"
6488 -
6489 - [features]
6490 - default = []
6491 - example_generated = []
6492 --rustc-dep-of-std = ["core", "compiler_builtins"]
6493 -+[badges.travis-ci]
6494 -+repository = "bitflags/bitflags"
6495 -diff --git a/third_party/rust/bitflags/README.md b/third_party/rust/bitflags/README.md
6496 -index 0da0f853661b0..df12934c3e28a 100644
6497 ---- a/third_party/rust/bitflags/README.md
6498 -+++ b/third_party/rust/bitflags/README.md
6499 -@@ -1,10 +1,11 @@
6500 - bitflags
6501 - ========
6502 -
6503 --[![Rust](https://github.com/bitflags/bitflags/workflows/Rust/badge.svg)](https://github.com/bitflags/bitflags/actions)
6504 -+[![Build Status](https://travis-ci.com/bitflags/bitflags.svg?branch=master)](https://travis-ci.com/bitflags/bitflags)
6505 - [![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)
6506 - [![Latest version](https://img.shields.io/crates/v/bitflags.svg)](https://crates.io/crates/bitflags)
6507 - [![Documentation](https://docs.rs/bitflags/badge.svg)](https://docs.rs/bitflags)
6508 -+![Minimum rustc version](https://img.shields.io/badge/rustc-1.20+-yellow.svg)
6509 - ![License](https://img.shields.io/crates/l/bitflags.svg)
6510 -
6511 - A Rust macro to generate structures which behave like a set of bitflags
6512 -@@ -18,15 +19,16 @@ Add this to your `Cargo.toml`:
6513 -
6514 - ```toml
6515 - [dependencies]
6516 --bitflags = "1.3"
6517 -+bitflags = "1.0"
6518 - ```
6519 -
6520 --and this to your source code:
6521 -+and this to your crate root:
6522 -
6523 - ```rust
6524 --use bitflags::bitflags;
6525 -+#[macro_use]
6526 -+extern crate bitflags;
6527 - ```
6528 -
6529 - ## Rust Version Support
6530 -
6531 --The minimum supported Rust version is 1.46 due to use of associated constants and const functions.
6532 -+The minimum supported Rust version is 1.20 due to use of associated constants.
6533 -diff --git a/third_party/rust/bitflags/build.rs b/third_party/rust/bitflags/build.rs
6534 -new file mode 100644
6535 -index 0000000000000..985757a6f6126
6536 ---- /dev/null
6537 -+++ b/third_party/rust/bitflags/build.rs
6538 -@@ -0,0 +1,44 @@
6539 -+use std::env;
6540 -+use std::process::Command;
6541 -+use std::str::{self, FromStr};
6542 -+
6543 -+fn main(){
6544 -+ let minor = match rustc_minor_version() {
6545 -+ Some(minor) => minor,
6546 -+ None => return,
6547 -+ };
6548 -+
6549 -+ // const fn stabilized in Rust 1.31:
6550 -+ if minor >= 31 {
6551 -+ println!("cargo:rustc-cfg=bitflags_const_fn");
6552 -+ }
6553 -+}
6554 -+
6555 -+fn rustc_minor_version() -> Option<u32> {
6556 -+ let rustc = match env::var_os("RUSTC") {
6557 -+ Some(rustc) => rustc,
6558 -+ None => return None,
6559 -+ };
6560 -+
6561 -+ let output = match Command::new(rustc).arg("--version").output() {
6562 -+ Ok(output) => output,
6563 -+ Err(_) => return None,
6564 -+ };
6565 -+
6566 -+ let version = match str::from_utf8(&output.stdout) {
6567 -+ Ok(version) => version,
6568 -+ Err(_) => return None,
6569 -+ };
6570 -+
6571 -+ let mut pieces = version.split('.');
6572 -+ if pieces.next() != Some("rustc 1") {
6573 -+ return None;
6574 -+ }
6575 -+
6576 -+ let next = match pieces.next() {
6577 -+ Some(next) => next,
6578 -+ None => return None,
6579 -+ };
6580 -+
6581 -+ u32::from_str(next).ok()
6582 -+}
6583 -\ No newline at end of file
6584 -diff --git a/third_party/rust/bitflags/src/lib.rs b/third_party/rust/bitflags/src/lib.rs
6585 -index 935e432f1701e..3929b02ac10d7 100644
6586 ---- a/third_party/rust/bitflags/src/lib.rs
6587 -+++ b/third_party/rust/bitflags/src/lib.rs
6588 -@@ -11,14 +11,15 @@
6589 - //! A typesafe bitmask flag generator useful for sets of C-style bitmask flags.
6590 - //! It can be used for creating typesafe wrappers around C APIs.
6591 - //!
6592 --//! The `bitflags!` macro generates `struct`s that manage a set of flags. The
6593 -+//! The `bitflags!` macro generates a `struct` that manages a set of flags. The
6594 - //! flags should only be defined for integer types, otherwise unexpected type
6595 - //! errors may occur at compile time.
6596 - //!
6597 - //! # Example
6598 - //!
6599 - //! ```
6600 --//! use bitflags::bitflags;
6601 -+//! #[macro_use]
6602 -+//! extern crate bitflags;
6603 - //!
6604 - //! bitflags! {
6605 - //! struct Flags: u32 {
6606 -@@ -46,9 +47,10 @@
6607 - //! implementations:
6608 - //!
6609 - //! ```
6610 --//! use std::fmt;
6611 -+//! #[macro_use]
6612 -+//! extern crate bitflags;
6613 - //!
6614 --//! use bitflags::bitflags;
6615 -+//! use std::fmt;
6616 - //!
6617 - //! bitflags! {
6618 - //! struct Flags: u32 {
6619 -@@ -82,19 +84,21 @@
6620 - //!
6621 - //! # Visibility
6622 - //!
6623 --//! The generated structs and their associated flag constants are not exported
6624 -+//! The generated struct and its associated flag constants are not exported
6625 - //! out of the current module by default. A definition can be exported out of
6626 --//! the current module by adding `pub` before `struct`:
6627 -+//! the current module by adding `pub` before `flags`:
6628 - //!
6629 - //! ```
6630 --//! mod example {
6631 --//! use bitflags::bitflags;
6632 -+//! #[macro_use]
6633 -+//! extern crate bitflags;
6634 - //!
6635 -+//! mod example {
6636 - //! bitflags! {
6637 - //! pub struct Flags1: u32 {
6638 - //! const A = 0b00000001;
6639 - //! }
6640 --//!
6641 -+//! }
6642 -+//! bitflags! {
6643 - //! # pub
6644 - //! struct Flags2: u32 {
6645 - //! const B = 0b00000010;
6646 -@@ -110,44 +114,26 @@
6647 - //!
6648 - //! # Attributes
6649 - //!
6650 --//! Attributes can be attached to the generated `struct`s by placing them
6651 --//! before the `struct` keyword.
6652 --//!
6653 --//! ## Representations
6654 --//!
6655 --//! It's valid to add a `#[repr(C)]` or `#[repr(transparent)]` attribute to a type
6656 --//! generated by `bitflags!`. In these cases, the type is guaranteed to be a newtype.
6657 --//!
6658 --//! ```
6659 --//! use bitflags::bitflags;
6660 --//!
6661 --//! bitflags! {
6662 --//! #[repr(transparent)]
6663 --//! struct Flags: u32 {
6664 --//! const A = 0b00000001;
6665 --//! const B = 0b00000010;
6666 --//! const C = 0b00000100;
6667 --//! }
6668 --//! }
6669 --//! ```
6670 -+//! Attributes can be attached to the generated `struct` by placing them
6671 -+//! before the `flags` keyword.
6672 - //!
6673 - //! # Trait implementations
6674 - //!
6675 - //! The `Copy`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord` and `Hash`
6676 --//! traits are automatically derived for the `struct`s using the `derive` attribute.
6677 -+//! traits automatically derived for the `struct` using the `derive` attribute.
6678 - //! Additional traits can be derived by providing an explicit `derive`
6679 --//! attribute on `struct`.
6680 -+//! attribute on `flags`.
6681 - //!
6682 --//! The `Extend` and `FromIterator` traits are implemented for the `struct`s,
6683 -+//! The `Extend` and `FromIterator` traits are implemented for the `struct`,
6684 - //! too: `Extend` adds the union of the instances of the `struct` iterated over,
6685 - //! while `FromIterator` calculates the union.
6686 - //!
6687 --//! The `Binary`, `Debug`, `LowerHex`, `Octal` and `UpperHex` traits are also
6688 -+//! The `Binary`, `Debug`, `LowerHex`, `Octal` and `UpperHex` trait is also
6689 - //! implemented by displaying the bits value of the internal struct.
6690 - //!
6691 - //! ## Operators
6692 - //!
6693 --//! The following operator traits are implemented for the generated `struct`s:
6694 -+//! The following operator traits are implemented for the generated `struct`:
6695 - //!
6696 - //! - `BitOr` and `BitOrAssign`: union
6697 - //! - `BitAnd` and `BitAndAssign`: intersection
6698 -@@ -157,7 +143,7 @@
6699 - //!
6700 - //! # Methods
6701 - //!
6702 --//! The following methods are defined for the generated `struct`s:
6703 -+//! The following methods are defined for the generated `struct`:
6704 - //!
6705 - //! - `empty`: an empty set of flags
6706 - //! - `all`: the set of all defined flags
6707 -@@ -173,34 +159,23 @@
6708 - //! - `is_empty`: `true` if no flags are currently stored
6709 - //! - `is_all`: `true` if currently set flags exactly equal all defined flags
6710 - //! - `intersects`: `true` if there are flags common to both `self` and `other`
6711 --//! - `contains`: `true` if all of the flags in `other` are contained within `self`
6712 -+//! - `contains`: `true` all of the flags in `other` are contained within `self`
6713 - //! - `insert`: inserts the specified flags in-place
6714 - //! - `remove`: removes the specified flags in-place
6715 - //! - `toggle`: the specified flags will be inserted if not present, and removed
6716 - //! if they are.
6717 - //! - `set`: inserts or removes the specified flags depending on the passed value
6718 --//! - `intersection`: returns a new set of flags, containing only the flags present
6719 --//! in both `self` and `other` (the argument to the function).
6720 --//! - `union`: returns a new set of flags, containing any flags present in
6721 --//! either `self` or `other` (the argument to the function).
6722 --//! - `difference`: returns a new set of flags, containing all flags present in
6723 --//! `self` without any of the flags present in `other` (the
6724 --//! argument to the function).
6725 --//! - `symmetric_difference`: returns a new set of flags, containing all flags
6726 --//! present in either `self` or `other` (the argument
6727 --//! to the function), but not both.
6728 --//! - `complement`: returns a new set of flags, containing all flags which are
6729 --//! not set in `self`, but which are allowed for this type.
6730 - //!
6731 - //! ## Default
6732 - //!
6733 --//! The `Default` trait is not automatically implemented for the generated structs.
6734 -+//! The `Default` trait is not automatically implemented for the generated struct.
6735 - //!
6736 - //! If your default value is equal to `0` (which is the same value as calling `empty()`
6737 - //! on the generated struct), you can simply derive `Default`:
6738 - //!
6739 - //! ```
6740 --//! use bitflags::bitflags;
6741 -+//! #[macro_use]
6742 -+//! extern crate bitflags;
6743 - //!
6744 - //! bitflags! {
6745 - //! // Results in default value with bits: 0
6746 -@@ -221,7 +196,8 @@
6747 - //! If your default value is not equal to `0` you need to implement `Default` yourself:
6748 - //!
6749 - //! ```
6750 --//! use bitflags::bitflags;
6751 -+//! #[macro_use]
6752 -+//! extern crate bitflags;
6753 - //!
6754 - //! bitflags! {
6755 - //! struct Flags: u32 {
6756 -@@ -249,7 +225,8 @@
6757 - //! Flags with a value equal to zero will have some strange behavior that one should be aware of.
6758 - //!
6759 - //! ```
6760 --//! use bitflags::bitflags;
6761 -+//! #[macro_use]
6762 -+//! extern crate bitflags;
6763 - //!
6764 - //! bitflags! {
6765 - //! struct Flags: u32 {
6766 -@@ -272,23 +249,28 @@
6767 - //! assert!(none.is_empty());
6768 - //! }
6769 - //! ```
6770 --//!
6771 --//! Users should generally avoid defining a flag with a value of zero.
6772 -
6773 --#![cfg_attr(not(test), no_std)]
6774 --#![doc(html_root_url = "https://docs.rs/bitflags/1.3.2")]
6775 -+#![no_std]
6776 -+#![doc(html_root_url = "https://docs.rs/bitflags/1.2.1")]
6777 -+
6778 -+#[cfg(test)]
6779 -+#[macro_use]
6780 -+extern crate std;
6781 -
6782 -+// Re-export libcore using an alias so that the macros can work without
6783 -+// requiring `extern crate core` downstream.
6784 - #[doc(hidden)]
6785 - pub extern crate core as _core;
6786 -
6787 --/// The macro used to generate the flag structures.
6788 -+/// The macro used to generate the flag structure.
6789 - ///
6790 - /// See the [crate level docs](../bitflags/index.html) for complete documentation.
6791 - ///
6792 - /// # Example
6793 - ///
6794 - /// ```
6795 --/// use bitflags::bitflags;
6796 -+/// #[macro_use]
6797 -+/// extern crate bitflags;
6798 - ///
6799 - /// bitflags! {
6800 - /// struct Flags: u32 {
6801 -@@ -313,9 +295,10 @@ pub extern crate core as _core;
6802 - /// implementations:
6803 - ///
6804 - /// ```
6805 --/// use std::fmt;
6806 -+/// #[macro_use]
6807 -+/// extern crate bitflags;
6808 - ///
6809 --/// use bitflags::bitflags;
6810 -+/// use std::fmt;
6811 - ///
6812 - /// bitflags! {
6813 - /// struct Flags: u32 {
6814 -@@ -350,18 +333,78 @@ pub extern crate core as _core;
6815 - macro_rules! bitflags {
6816 - (
6817 - $(#[$outer:meta])*
6818 -- $vis:vis struct $BitFlags:ident: $T:ty {
6819 -+ pub struct $BitFlags:ident: $T:ty {
6820 -+ $(
6821 -+ $(#[$inner:ident $($args:tt)*])*
6822 -+ const $Flag:ident = $value:expr;
6823 -+ )+
6824 -+ }
6825 -+ ) => {
6826 -+ __bitflags! {
6827 -+ $(#[$outer])*
6828 -+ (pub) $BitFlags: $T {
6829 -+ $(
6830 -+ $(#[$inner $($args)*])*
6831 -+ $Flag = $value;
6832 -+ )+
6833 -+ }
6834 -+ }
6835 -+ };
6836 -+ (
6837 -+ $(#[$outer:meta])*
6838 -+ struct $BitFlags:ident: $T:ty {
6839 -+ $(
6840 -+ $(#[$inner:ident $($args:tt)*])*
6841 -+ const $Flag:ident = $value:expr;
6842 -+ )+
6843 -+ }
6844 -+ ) => {
6845 -+ __bitflags! {
6846 -+ $(#[$outer])*
6847 -+ () $BitFlags: $T {
6848 -+ $(
6849 -+ $(#[$inner $($args)*])*
6850 -+ $Flag = $value;
6851 -+ )+
6852 -+ }
6853 -+ }
6854 -+ };
6855 -+ (
6856 -+ $(#[$outer:meta])*
6857 -+ pub ($($vis:tt)+) struct $BitFlags:ident: $T:ty {
6858 - $(
6859 - $(#[$inner:ident $($args:tt)*])*
6860 - const $Flag:ident = $value:expr;
6861 -- )*
6862 -+ )+
6863 -+ }
6864 -+ ) => {
6865 -+ __bitflags! {
6866 -+ $(#[$outer])*
6867 -+ (pub ($($vis)+)) $BitFlags: $T {
6868 -+ $(
6869 -+ $(#[$inner $($args)*])*
6870 -+ $Flag = $value;
6871 -+ )+
6872 -+ }
6873 - }
6874 -+ };
6875 -+}
6876 -
6877 -- $($t:tt)*
6878 -+#[macro_export(local_inner_macros)]
6879 -+#[doc(hidden)]
6880 -+macro_rules! __bitflags {
6881 -+ (
6882 -+ $(#[$outer:meta])*
6883 -+ ($($vis:tt)*) $BitFlags:ident: $T:ty {
6884 -+ $(
6885 -+ $(#[$inner:ident $($args:tt)*])*
6886 -+ $Flag:ident = $value:expr;
6887 -+ )+
6888 -+ }
6889 - ) => {
6890 - $(#[$outer])*
6891 - #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
6892 -- $vis struct $BitFlags {
6893 -+ $($vis)* struct $BitFlags {
6894 - bits: $T,
6895 - }
6896 -
6897 -@@ -370,52 +413,63 @@ macro_rules! bitflags {
6898 - $(
6899 - $(#[$inner $($args)*])*
6900 - $Flag = $value;
6901 -- )*
6902 -+ )+
6903 - }
6904 - }
6905 -+ };
6906 -+}
6907 -
6908 -- bitflags! {
6909 -- $($t)*
6910 -- }
6911 -+#[macro_export(local_inner_macros)]
6912 -+#[doc(hidden)]
6913 -+#[cfg(bitflags_const_fn)]
6914 -+macro_rules! __fn_bitflags {
6915 -+ (
6916 -+ $(# $attr_args:tt)*
6917 -+ const fn $($item:tt)*
6918 -+ ) => {
6919 -+ $(# $attr_args)*
6920 -+ const fn $($item)*
6921 -+ };
6922 -+ (
6923 -+ $(# $attr_args:tt)*
6924 -+ pub const fn $($item:tt)*
6925 -+ ) => {
6926 -+ $(# $attr_args)*
6927 -+ pub const fn $($item)*
6928 -+ };
6929 -+ (
6930 -+ $(# $attr_args:tt)*
6931 -+ pub const unsafe fn $($item:tt)*
6932 -+ ) => {
6933 -+ $(# $attr_args)*
6934 -+ pub const unsafe fn $($item)*
6935 - };
6936 -- () => {};
6937 - }
6938 -
6939 --// A helper macro to implement the `all` function.
6940 - #[macro_export(local_inner_macros)]
6941 - #[doc(hidden)]
6942 --macro_rules! __impl_all_bitflags {
6943 -+#[cfg(not(bitflags_const_fn))]
6944 -+macro_rules! __fn_bitflags {
6945 - (
6946 -- $BitFlags:ident: $T:ty {
6947 -- $(
6948 -- $(#[$attr:ident $($args:tt)*])*
6949 -- $Flag:ident = $value:expr;
6950 -- )+
6951 -- }
6952 -+ $(# $attr_args:tt)*
6953 -+ const fn $($item:tt)*
6954 - ) => {
6955 -- // See `Debug::fmt` for why this approach is taken.
6956 -- #[allow(non_snake_case)]
6957 -- trait __BitFlags {
6958 -- $(
6959 -- const $Flag: $T = 0;
6960 -- )+
6961 -- }
6962 -- #[allow(non_snake_case)]
6963 -- impl __BitFlags for $BitFlags {
6964 -- $(
6965 -- __impl_bitflags! {
6966 -- #[allow(deprecated)]
6967 -- $(? #[$attr $($args)*])*
6968 -- const $Flag: $T = Self::$Flag.bits;
6969 -- }
6970 -- )+
6971 -- }
6972 -- Self { bits: $(<Self as __BitFlags>::$Flag)|+ }
6973 -+ $(# $attr_args)*
6974 -+ fn $($item)*
6975 -+ };
6976 -+ (
6977 -+ $(# $attr_args:tt)*
6978 -+ pub const fn $($item:tt)*
6979 -+ ) => {
6980 -+ $(# $attr_args)*
6981 -+ pub fn $($item)*
6982 - };
6983 - (
6984 -- $BitFlags:ident: $T:ty { }
6985 -+ $(# $attr_args:tt)*
6986 -+ pub const unsafe fn $($item:tt)*
6987 - ) => {
6988 -- Self { bits: 0 }
6989 -+ $(# $attr_args)*
6990 -+ pub unsafe fn $($item)*
6991 - };
6992 - }
6993 -
6994 -@@ -427,7 +481,7 @@ macro_rules! __impl_bitflags {
6995 - $(
6996 - $(#[$attr:ident $($args:tt)*])*
6997 - $Flag:ident = $value:expr;
6998 -- )*
6999 -+ )+
7000 - }
7001 - ) => {
7002 - impl $crate::_core::fmt::Debug for $BitFlags {
7003 -@@ -445,12 +499,11 @@ macro_rules! __impl_bitflags {
7004 - $(
7005 - #[inline]
7006 - fn $Flag(&self) -> bool { false }
7007 -- )*
7008 -+ )+
7009 - }
7010 -
7011 - // Conditionally override the check for just those flags that
7012 - // are not #[cfg]ed away.
7013 -- #[allow(non_snake_case)]
7014 - impl __BitFlags for $BitFlags {
7015 - $(
7016 - __impl_bitflags! {
7017 -@@ -465,20 +518,20 @@ macro_rules! __impl_bitflags {
7018 - }
7019 - }
7020 - }
7021 -- )*
7022 -+ )+
7023 - }
7024 -
7025 - let mut first = true;
7026 - $(
7027 -- if <Self as __BitFlags>::$Flag(self) {
7028 -+ if <$BitFlags as __BitFlags>::$Flag(self) {
7029 - if !first {
7030 - f.write_str(" | ")?;
7031 - }
7032 - first = false;
7033 -- f.write_str($crate::_core::stringify!($Flag))?;
7034 -+ f.write_str(__bitflags_stringify!($Flag))?;
7035 - }
7036 -- )*
7037 -- let extra_bits = self.bits & !Self::all().bits();
7038 -+ )+
7039 -+ let extra_bits = self.bits & !$BitFlags::all().bits();
7040 - if extra_bits != 0 {
7041 - if !first {
7042 - f.write_str(" | ")?;
7043 -@@ -518,295 +571,227 @@ macro_rules! __impl_bitflags {
7044 - impl $BitFlags {
7045 - $(
7046 - $(#[$attr $($args)*])*
7047 -- pub const $Flag: Self = Self { bits: $value };
7048 -- )*
7049 -+ pub const $Flag: $BitFlags = $BitFlags { bits: $value };
7050 -+ )+
7051 -
7052 -- /// Returns an empty set of flags.
7053 -- #[inline]
7054 -- pub const fn empty() -> Self {
7055 -- Self { bits: 0 }
7056 -+ __fn_bitflags! {
7057 -+ /// Returns an empty set of flags
7058 -+ #[inline]
7059 -+ pub const fn empty() -> $BitFlags {
7060 -+ $BitFlags { bits: 0 }
7061 -+ }
7062 - }
7063 -
7064 -- /// Returns the set containing all flags.
7065 -- #[inline]
7066 -- pub const fn all() -> Self {
7067 -- __impl_all_bitflags! {
7068 -- $BitFlags: $T {
7069 -+ __fn_bitflags! {
7070 -+ /// Returns the set containing all flags.
7071 -+ #[inline]
7072 -+ pub const fn all() -> $BitFlags {
7073 -+ // See `Debug::fmt` for why this approach is taken.
7074 -+ #[allow(non_snake_case)]
7075 -+ trait __BitFlags {
7076 - $(
7077 -- $(#[$attr $($args)*])*
7078 -- $Flag = $value;
7079 -- )*
7080 -+ const $Flag: $T = 0;
7081 -+ )+
7082 - }
7083 -+ impl __BitFlags for $BitFlags {
7084 -+ $(
7085 -+ __impl_bitflags! {
7086 -+ #[allow(deprecated)]
7087 -+ $(? #[$attr $($args)*])*
7088 -+ const $Flag: $T = Self::$Flag.bits;
7089 -+ }
7090 -+ )+
7091 -+ }
7092 -+ $BitFlags { bits: $(<$BitFlags as __BitFlags>::$Flag)|+ }
7093 - }
7094 - }
7095 -
7096 -- /// Returns the raw value of the flags currently stored.
7097 -- #[inline]
7098 -- pub const fn bits(&self) -> $T {
7099 -- self.bits
7100 -+ __fn_bitflags! {
7101 -+ /// Returns the raw value of the flags currently stored.
7102 -+ #[inline]
7103 -+ pub const fn bits(&self) -> $T {
7104 -+ self.bits
7105 -+ }
7106 - }
7107 -
7108 - /// Convert from underlying bit representation, unless that
7109 - /// representation contains bits that do not correspond to a flag.
7110 - #[inline]
7111 -- pub const fn from_bits(bits: $T) -> $crate::_core::option::Option<Self> {
7112 -- if (bits & !Self::all().bits()) == 0 {
7113 -- $crate::_core::option::Option::Some(Self { bits })
7114 -+ pub fn from_bits(bits: $T) -> $crate::_core::option::Option<$BitFlags> {
7115 -+ if (bits & !$BitFlags::all().bits()) == 0 {
7116 -+ $crate::_core::option::Option::Some($BitFlags { bits })
7117 - } else {
7118 - $crate::_core::option::Option::None
7119 - }
7120 - }
7121 -
7122 -- /// Convert from underlying bit representation, dropping any bits
7123 -- /// that do not correspond to flags.
7124 -- #[inline]
7125 -- pub const fn from_bits_truncate(bits: $T) -> Self {
7126 -- Self { bits: bits & Self::all().bits }
7127 -+ __fn_bitflags! {
7128 -+ /// Convert from underlying bit representation, dropping any bits
7129 -+ /// that do not correspond to flags.
7130 -+ #[inline]
7131 -+ pub const fn from_bits_truncate(bits: $T) -> $BitFlags {
7132 -+ $BitFlags { bits: bits & $BitFlags::all().bits }
7133 -+ }
7134 - }
7135 -
7136 -- /// Convert from underlying bit representation, preserving all
7137 -- /// bits (even those not corresponding to a defined flag).
7138 -- ///
7139 -- /// # Safety
7140 -- ///
7141 -- /// The caller of the `bitflags!` macro can chose to allow or
7142 -- /// disallow extra bits for their bitflags type.
7143 -- ///
7144 -- /// The caller of `from_bits_unchecked()` has to ensure that
7145 -- /// all bits correspond to a defined flag or that extra bits
7146 -- /// are valid for this bitflags type.
7147 -- #[inline]
7148 -- pub const unsafe fn from_bits_unchecked(bits: $T) -> Self {
7149 -- Self { bits }
7150 -+ __fn_bitflags! {
7151 -+ /// Convert from underlying bit representation, preserving all
7152 -+ /// bits (even those not corresponding to a defined flag).
7153 -+ #[inline]
7154 -+ pub const unsafe fn from_bits_unchecked(bits: $T) -> $BitFlags {
7155 -+ $BitFlags { bits }
7156 -+ }
7157 - }
7158 -
7159 -- /// Returns `true` if no flags are currently stored.
7160 -- #[inline]
7161 -- pub const fn is_empty(&self) -> bool {
7162 -- self.bits() == Self::empty().bits()
7163 -+ __fn_bitflags! {
7164 -+ /// Returns `true` if no flags are currently stored.
7165 -+ #[inline]
7166 -+ pub const fn is_empty(&self) -> bool {
7167 -+ self.bits() == $BitFlags::empty().bits()
7168 -+ }
7169 - }
7170 -
7171 -- /// Returns `true` if all flags are currently set.
7172 -- #[inline]
7173 -- pub const fn is_all(&self) -> bool {
7174 -- Self::all().bits | self.bits == self.bits
7175 -+ __fn_bitflags! {
7176 -+ /// Returns `true` if all flags are currently set.
7177 -+ #[inline]
7178 -+ pub const fn is_all(&self) -> bool {
7179 -+ self.bits == $BitFlags::all().bits
7180 -+ }
7181 - }
7182 -
7183 -- /// Returns `true` if there are flags common to both `self` and `other`.
7184 -- #[inline]
7185 -- pub const fn intersects(&self, other: Self) -> bool {
7186 -- !(Self { bits: self.bits & other.bits}).is_empty()
7187 -+ __fn_bitflags! {
7188 -+ /// Returns `true` if there are flags common to both `self` and `other`.
7189 -+ #[inline]
7190 -+ pub const fn intersects(&self, other: $BitFlags) -> bool {
7191 -+ !$BitFlags{ bits: self.bits & other.bits}.is_empty()
7192 -+ }
7193 - }
7194 -
7195 -- /// Returns `true` if all of the flags in `other` are contained within `self`.
7196 -- #[inline]
7197 -- pub const fn contains(&self, other: Self) -> bool {
7198 -- (self.bits & other.bits) == other.bits
7199 -+ __fn_bitflags! {
7200 -+ /// Returns `true` all of the flags in `other` are contained within `self`.
7201 -+ #[inline]
7202 -+ pub const fn contains(&self, other: $BitFlags) -> bool {
7203 -+ (self.bits & other.bits) == other.bits
7204 -+ }
7205 - }
7206 -
7207 - /// Inserts the specified flags in-place.
7208 - #[inline]
7209 -- pub fn insert(&mut self, other: Self) {
7210 -+ pub fn insert(&mut self, other: $BitFlags) {
7211 - self.bits |= other.bits;
7212 - }
7213 -
7214 - /// Removes the specified flags in-place.
7215 - #[inline]
7216 -- pub fn remove(&mut self, other: Self) {
7217 -+ pub fn remove(&mut self, other: $BitFlags) {
7218 - self.bits &= !other.bits;
7219 - }
7220 -
7221 - /// Toggles the specified flags in-place.
7222 - #[inline]
7223 -- pub fn toggle(&mut self, other: Self) {
7224 -+ pub fn toggle(&mut self, other: $BitFlags) {
7225 - self.bits ^= other.bits;
7226 - }
7227 -
7228 - /// Inserts or removes the specified flags depending on the passed value.
7229 - #[inline]
7230 -- pub fn set(&mut self, other: Self, value: bool) {
7231 -+ pub fn set(&mut self, other: $BitFlags, value: bool) {
7232 - if value {
7233 - self.insert(other);
7234 - } else {
7235 - self.remove(other);
7236 - }
7237 - }
7238 --
7239 -- /// Returns the intersection between the flags in `self` and
7240 -- /// `other`.
7241 -- ///
7242 -- /// Specifically, the returned set contains only the flags which are
7243 -- /// present in *both* `self` *and* `other`.
7244 -- ///
7245 -- /// This is equivalent to using the `&` operator (e.g.
7246 -- /// [`ops::BitAnd`]), as in `flags & other`.
7247 -- ///
7248 -- /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html
7249 -- #[inline]
7250 -- #[must_use]
7251 -- pub const fn intersection(self, other: Self) -> Self {
7252 -- Self { bits: self.bits & other.bits }
7253 -- }
7254 --
7255 -- /// Returns the union of between the flags in `self` and `other`.
7256 -- ///
7257 -- /// Specifically, the returned set contains all flags which are
7258 -- /// present in *either* `self` *or* `other`, including any which are
7259 -- /// present in both (see [`Self::symmetric_difference`] if that
7260 -- /// is undesirable).
7261 -- ///
7262 -- /// This is equivalent to using the `|` operator (e.g.
7263 -- /// [`ops::BitOr`]), as in `flags | other`.
7264 -- ///
7265 -- /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html
7266 -- #[inline]
7267 -- #[must_use]
7268 -- pub const fn union(self, other: Self) -> Self {
7269 -- Self { bits: self.bits | other.bits }
7270 -- }
7271 --
7272 -- /// Returns the difference between the flags in `self` and `other`.
7273 -- ///
7274 -- /// Specifically, the returned set contains all flags present in
7275 -- /// `self`, except for the ones present in `other`.
7276 -- ///
7277 -- /// It is also conceptually equivalent to the "bit-clear" operation:
7278 -- /// `flags & !other` (and this syntax is also supported).
7279 -- ///
7280 -- /// This is equivalent to using the `-` operator (e.g.
7281 -- /// [`ops::Sub`]), as in `flags - other`.
7282 -- ///
7283 -- /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html
7284 -- #[inline]
7285 -- #[must_use]
7286 -- pub const fn difference(self, other: Self) -> Self {
7287 -- Self { bits: self.bits & !other.bits }
7288 -- }
7289 --
7290 -- /// Returns the [symmetric difference][sym-diff] between the flags
7291 -- /// in `self` and `other`.
7292 -- ///
7293 -- /// Specifically, the returned set contains the flags present which
7294 -- /// are present in `self` or `other`, but that are not present in
7295 -- /// both. Equivalently, it contains the flags present in *exactly
7296 -- /// one* of the sets `self` and `other`.
7297 -- ///
7298 -- /// This is equivalent to using the `^` operator (e.g.
7299 -- /// [`ops::BitXor`]), as in `flags ^ other`.
7300 -- ///
7301 -- /// [sym-diff]: https://en.wikipedia.org/wiki/Symmetric_difference
7302 -- /// [`ops::BitXor`]: https://doc.rust-lang.org/std/ops/trait.BitXor.html
7303 -- #[inline]
7304 -- #[must_use]
7305 -- pub const fn symmetric_difference(self, other: Self) -> Self {
7306 -- Self { bits: self.bits ^ other.bits }
7307 -- }
7308 --
7309 -- /// Returns the complement of this set of flags.
7310 -- ///
7311 -- /// Specifically, the returned set contains all the flags which are
7312 -- /// not set in `self`, but which are allowed for this type.
7313 -- ///
7314 -- /// Alternatively, it can be thought of as the set difference
7315 -- /// between [`Self::all()`] and `self` (e.g. `Self::all() - self`)
7316 -- ///
7317 -- /// This is equivalent to using the `!` operator (e.g.
7318 -- /// [`ops::Not`]), as in `!flags`.
7319 -- ///
7320 -- /// [`Self::all()`]: Self::all
7321 -- /// [`ops::Not`]: https://doc.rust-lang.org/std/ops/trait.Not.html
7322 -- #[inline]
7323 -- #[must_use]
7324 -- pub const fn complement(self) -> Self {
7325 -- Self::from_bits_truncate(!self.bits)
7326 -- }
7327 --
7328 - }
7329 -
7330 - impl $crate::_core::ops::BitOr for $BitFlags {
7331 -- type Output = Self;
7332 -+ type Output = $BitFlags;
7333 -
7334 - /// Returns the union of the two sets of flags.
7335 - #[inline]
7336 -- fn bitor(self, other: $BitFlags) -> Self {
7337 -- Self { bits: self.bits | other.bits }
7338 -+ fn bitor(self, other: $BitFlags) -> $BitFlags {
7339 -+ $BitFlags { bits: self.bits | other.bits }
7340 - }
7341 - }
7342 -
7343 - impl $crate::_core::ops::BitOrAssign for $BitFlags {
7344 -+
7345 - /// Adds the set of flags.
7346 - #[inline]
7347 -- fn bitor_assign(&mut self, other: Self) {
7348 -+ fn bitor_assign(&mut self, other: $BitFlags) {
7349 - self.bits |= other.bits;
7350 - }
7351 - }
7352 -
7353 - impl $crate::_core::ops::BitXor for $BitFlags {
7354 -- type Output = Self;
7355 -+ type Output = $BitFlags;
7356 -
7357 - /// Returns the left flags, but with all the right flags toggled.
7358 - #[inline]
7359 -- fn bitxor(self, other: Self) -> Self {
7360 -- Self { bits: self.bits ^ other.bits }
7361 -+ fn bitxor(self, other: $BitFlags) -> $BitFlags {
7362 -+ $BitFlags { bits: self.bits ^ other.bits }
7363 - }
7364 - }
7365 -
7366 - impl $crate::_core::ops::BitXorAssign for $BitFlags {
7367 -+
7368 - /// Toggles the set of flags.
7369 - #[inline]
7370 -- fn bitxor_assign(&mut self, other: Self) {
7371 -+ fn bitxor_assign(&mut self, other: $BitFlags) {
7372 - self.bits ^= other.bits;
7373 - }
7374 - }
7375 -
7376 - impl $crate::_core::ops::BitAnd for $BitFlags {
7377 -- type Output = Self;
7378 -+ type Output = $BitFlags;
7379 -
7380 - /// Returns the intersection between the two sets of flags.
7381 - #[inline]
7382 -- fn bitand(self, other: Self) -> Self {
7383 -- Self { bits: self.bits & other.bits }
7384 -+ fn bitand(self, other: $BitFlags) -> $BitFlags {
7385 -+ $BitFlags { bits: self.bits & other.bits }
7386 - }
7387 - }
7388 -
7389 - impl $crate::_core::ops::BitAndAssign for $BitFlags {
7390 -+
7391 - /// Disables all flags disabled in the set.
7392 - #[inline]
7393 -- fn bitand_assign(&mut self, other: Self) {
7394 -+ fn bitand_assign(&mut self, other: $BitFlags) {
7395 - self.bits &= other.bits;
7396 - }
7397 - }
7398 -
7399 - impl $crate::_core::ops::Sub for $BitFlags {
7400 -- type Output = Self;
7401 -+ type Output = $BitFlags;
7402 -
7403 - /// Returns the set difference of the two sets of flags.
7404 - #[inline]
7405 -- fn sub(self, other: Self) -> Self {
7406 -- Self { bits: self.bits & !other.bits }
7407 -+ fn sub(self, other: $BitFlags) -> $BitFlags {
7408 -+ $BitFlags { bits: self.bits & !other.bits }
7409 - }
7410 - }
7411 -
7412 - impl $crate::_core::ops::SubAssign for $BitFlags {
7413 -+
7414 - /// Disables all flags enabled in the set.
7415 - #[inline]
7416 -- fn sub_assign(&mut self, other: Self) {
7417 -+ fn sub_assign(&mut self, other: $BitFlags) {
7418 - self.bits &= !other.bits;
7419 - }
7420 - }
7421 -
7422 - impl $crate::_core::ops::Not for $BitFlags {
7423 -- type Output = Self;
7424 -+ type Output = $BitFlags;
7425 -
7426 - /// Returns the complement of this set of flags.
7427 - #[inline]
7428 -- fn not(self) -> Self {
7429 -- Self { bits: !self.bits } & Self::all()
7430 -+ fn not(self) -> $BitFlags {
7431 -+ $BitFlags { bits: !self.bits } & $BitFlags::all()
7432 - }
7433 - }
7434 -
7435 - impl $crate::_core::iter::Extend<$BitFlags> for $BitFlags {
7436 -- fn extend<T: $crate::_core::iter::IntoIterator<Item=Self>>(&mut self, iterator: T) {
7437 -+ fn extend<T: $crate::_core::iter::IntoIterator<Item=$BitFlags>>(&mut self, iterator: T) {
7438 - for item in iterator {
7439 - self.insert(item)
7440 - }
7441 -@@ -814,7 +799,7 @@ macro_rules! __impl_bitflags {
7442 - }
7443 -
7444 - impl $crate::_core::iter::FromIterator<$BitFlags> for $BitFlags {
7445 -- fn from_iter<T: $crate::_core::iter::IntoIterator<Item=Self>>(iterator: T) -> Self {
7446 -+ fn from_iter<T: $crate::_core::iter::IntoIterator<Item=$BitFlags>>(iterator: T) -> $BitFlags {
7447 - let mut result = Self::empty();
7448 - result.extend(iterator);
7449 - result
7450 -@@ -832,7 +817,7 @@ macro_rules! __impl_bitflags {
7451 - // Input:
7452 - //
7453 - // ? #[cfg(feature = "advanced")]
7454 -- // ? #[deprecated(note = "Use something else.")]
7455 -+ // ? #[deprecated(note = "Use somthing else.")]
7456 - // ? #[doc = r"High quality documentation."]
7457 - // fn f() -> i32 { /* ... */ }
7458 - //
7459 -@@ -887,7 +872,7 @@ macro_rules! __impl_bitflags {
7460 - // Input:
7461 - //
7462 - // ? #[cfg(feature = "advanced")]
7463 -- // ? #[deprecated(note = "Use something else.")]
7464 -+ // ? #[deprecated(note = "Use somthing else.")]
7465 - // ? #[doc = r"High quality documentation."]
7466 - // const f: i32 { /* ... */ }
7467 - //
7468 -@@ -931,6 +916,16 @@ macro_rules! __impl_bitflags {
7469 - };
7470 - }
7471 -
7472 -+// Same as std::stringify but callable from __impl_bitflags, which needs to use
7473 -+// local_inner_macros so can only directly call macros from this crate.
7474 -+#[macro_export]
7475 -+#[doc(hidden)]
7476 -+macro_rules! __bitflags_stringify {
7477 -+ ($s:ident) => {
7478 -+ stringify!($s)
7479 -+ };
7480 -+}
7481 -+
7482 - #[cfg(feature = "example_generated")]
7483 - pub mod example_generated;
7484 -
7485 -@@ -944,7 +939,6 @@ mod tests {
7486 - #[doc = "> you are the easiest person to fool."]
7487 - #[doc = "> "]
7488 - #[doc = "> - Richard Feynman"]
7489 -- #[derive(Default)]
7490 - struct Flags: u32 {
7491 - const A = 0b00000001;
7492 - #[doc = "<pcwalton> macros are way better at generating code than trans is"]
7493 -@@ -955,7 +949,9 @@ mod tests {
7494 - #[doc = "<strcat> wait what?"]
7495 - const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
7496 - }
7497 -+ }
7498 -
7499 -+ bitflags! {
7500 - struct _CfgFlags: u32 {
7501 - #[cfg(unix)]
7502 - const _CFG_A = 0b01;
7503 -@@ -964,18 +960,17 @@ mod tests {
7504 - #[cfg(unix)]
7505 - const _CFG_C = Self::_CFG_A.bits | 0b10;
7506 - }
7507 -+ }
7508 -
7509 -+ bitflags! {
7510 - struct AnotherSetOfFlags: i8 {
7511 - const ANOTHER_FLAG = -1_i8;
7512 - }
7513 --
7514 -- struct LongFlags: u32 {
7515 -- const LONG_A = 0b1111111111111111;
7516 -- }
7517 - }
7518 -
7519 - bitflags! {
7520 -- struct EmptyFlags: u32 {
7521 -+ struct LongFlags: u32 {
7522 -+ const LONG_A = 0b1111111111111111;
7523 - }
7524 - }
7525 -
7526 -@@ -987,8 +982,6 @@ mod tests {
7527 -
7528 - assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00);
7529 - assert_eq!(AnotherSetOfFlags::ANOTHER_FLAG.bits(), !0_i8);
7530 --
7531 -- assert_eq!(EmptyFlags::empty().bits(), 0b00000000);
7532 - }
7533 -
7534 - #[test]
7535 -@@ -1003,9 +996,6 @@ mod tests {
7536 - AnotherSetOfFlags::from_bits(!0_i8),
7537 - Some(AnotherSetOfFlags::ANOTHER_FLAG)
7538 - );
7539 --
7540 -- assert_eq!(EmptyFlags::from_bits(0), Some(EmptyFlags::empty()));
7541 -- assert_eq!(EmptyFlags::from_bits(0b1), None);
7542 - }
7543 -
7544 - #[test]
7545 -@@ -1021,9 +1011,6 @@ mod tests {
7546 - AnotherSetOfFlags::from_bits_truncate(0_i8),
7547 - AnotherSetOfFlags::empty()
7548 - );
7549 --
7550 -- assert_eq!(EmptyFlags::from_bits_truncate(0), EmptyFlags::empty());
7551 -- assert_eq!(EmptyFlags::from_bits_truncate(0b1), EmptyFlags::empty());
7552 - }
7553 -
7554 - #[test]
7555 -@@ -1032,25 +1019,9 @@ mod tests {
7556 - assert_eq!(unsafe { Flags::from_bits_unchecked(0) }, Flags::empty());
7557 - assert_eq!(unsafe { Flags::from_bits_unchecked(0b1) }, Flags::A);
7558 - assert_eq!(unsafe { Flags::from_bits_unchecked(0b10) }, Flags::B);
7559 --
7560 -- assert_eq!(
7561 -- unsafe { Flags::from_bits_unchecked(0b11) },
7562 -- (Flags::A | Flags::B)
7563 -- );
7564 -- assert_eq!(
7565 -- unsafe { Flags::from_bits_unchecked(0b1000) },
7566 -- (extra | Flags::empty())
7567 -- );
7568 -- assert_eq!(
7569 -- unsafe { Flags::from_bits_unchecked(0b1001) },
7570 -- (extra | Flags::A)
7571 -- );
7572 --
7573 -- let extra = unsafe { EmptyFlags::from_bits_unchecked(0b1000) };
7574 -- assert_eq!(
7575 -- unsafe { EmptyFlags::from_bits_unchecked(0b1000) },
7576 -- (extra | EmptyFlags::empty())
7577 -- );
7578 -+ assert_eq!(unsafe { Flags::from_bits_unchecked(0b11) }, (Flags::A | Flags::B));
7579 -+ assert_eq!(unsafe { Flags::from_bits_unchecked(0b1000) }, (extra | Flags::empty()));
7580 -+ assert_eq!(unsafe { Flags::from_bits_unchecked(0b1001) }, (extra | Flags::A));
7581 - }
7582 -
7583 - #[test]
7584 -@@ -1060,9 +1031,6 @@ mod tests {
7585 - assert!(!Flags::ABC.is_empty());
7586 -
7587 - assert!(!AnotherSetOfFlags::ANOTHER_FLAG.is_empty());
7588 --
7589 -- assert!(EmptyFlags::empty().is_empty());
7590 -- assert!(EmptyFlags::all().is_empty());
7591 - }
7592 -
7593 - #[test]
7594 -@@ -1071,15 +1039,7 @@ mod tests {
7595 - assert!(!Flags::A.is_all());
7596 - assert!(Flags::ABC.is_all());
7597 -
7598 -- let extra = unsafe { Flags::from_bits_unchecked(0b1000) };
7599 -- assert!(!extra.is_all());
7600 -- assert!(!(Flags::A | extra).is_all());
7601 -- assert!((Flags::ABC | extra).is_all());
7602 --
7603 - assert!(AnotherSetOfFlags::ANOTHER_FLAG.is_all());
7604 --
7605 -- assert!(EmptyFlags::all().is_all());
7606 -- assert!(EmptyFlags::empty().is_all());
7607 - }
7608 -
7609 - #[test]
7610 -@@ -1121,8 +1081,6 @@ mod tests {
7611 - assert!(Flags::ABC.contains(e2));
7612 -
7613 - assert!(AnotherSetOfFlags::ANOTHER_FLAG.contains(AnotherSetOfFlags::ANOTHER_FLAG));
7614 --
7615 -- assert!(EmptyFlags::empty().contains(EmptyFlags::empty()));
7616 - }
7617 -
7618 - #[test]
7619 -@@ -1183,188 +1141,6 @@ mod tests {
7620 - assert_eq!(e3, Flags::A | Flags::B | extra);
7621 - }
7622 -
7623 -- #[test]
7624 -- fn test_set_ops_basic() {
7625 -- let ab = Flags::A.union(Flags::B);
7626 -- let ac = Flags::A.union(Flags::C);
7627 -- let bc = Flags::B.union(Flags::C);
7628 -- assert_eq!(ab.bits, 0b011);
7629 -- assert_eq!(bc.bits, 0b110);
7630 -- assert_eq!(ac.bits, 0b101);
7631 --
7632 -- assert_eq!(ab, Flags::B.union(Flags::A));
7633 -- assert_eq!(ac, Flags::C.union(Flags::A));
7634 -- assert_eq!(bc, Flags::C.union(Flags::B));
7635 --
7636 -- assert_eq!(ac, Flags::A | Flags::C);
7637 -- assert_eq!(bc, Flags::B | Flags::C);
7638 -- assert_eq!(ab.union(bc), Flags::ABC);
7639 --
7640 -- assert_eq!(ac, Flags::A | Flags::C);
7641 -- assert_eq!(bc, Flags::B | Flags::C);
7642 --
7643 -- assert_eq!(ac.union(bc), ac | bc);
7644 -- assert_eq!(ac.union(bc), Flags::ABC);
7645 -- assert_eq!(bc.union(ac), Flags::ABC);
7646 --
7647 -- assert_eq!(ac.intersection(bc), ac & bc);
7648 -- assert_eq!(ac.intersection(bc), Flags::C);
7649 -- assert_eq!(bc.intersection(ac), Flags::C);
7650 --
7651 -- assert_eq!(ac.difference(bc), ac - bc);
7652 -- assert_eq!(bc.difference(ac), bc - ac);
7653 -- assert_eq!(ac.difference(bc), Flags::A);
7654 -- assert_eq!(bc.difference(ac), Flags::B);
7655 --
7656 -- assert_eq!(bc.complement(), !bc);
7657 -- assert_eq!(bc.complement(), Flags::A);
7658 -- assert_eq!(ac.symmetric_difference(bc), Flags::A.union(Flags::B));
7659 -- assert_eq!(bc.symmetric_difference(ac), Flags::A.union(Flags::B));
7660 -- }
7661 --
7662 -- #[test]
7663 -- fn test_set_ops_const() {
7664 -- // These just test that these compile and don't cause use-site panics
7665 -- // (would be possible if we had some sort of UB)
7666 -- const INTERSECT: Flags = Flags::all().intersection(Flags::C);
7667 -- const UNION: Flags = Flags::A.union(Flags::C);
7668 -- const DIFFERENCE: Flags = Flags::all().difference(Flags::A);
7669 -- const COMPLEMENT: Flags = Flags::C.complement();
7670 -- const SYM_DIFFERENCE: Flags = UNION.symmetric_difference(DIFFERENCE);
7671 -- assert_eq!(INTERSECT, Flags::C);
7672 -- assert_eq!(UNION, Flags::A | Flags::C);
7673 -- assert_eq!(DIFFERENCE, Flags::all() - Flags::A);
7674 -- assert_eq!(COMPLEMENT, !Flags::C);
7675 -- assert_eq!(SYM_DIFFERENCE, (Flags::A | Flags::C) ^ (Flags::all() - Flags::A));
7676 -- }
7677 --
7678 -- #[test]
7679 -- fn test_set_ops_unchecked() {
7680 -- let extra = unsafe { Flags::from_bits_unchecked(0b1000) };
7681 -- let e1 = Flags::A.union(Flags::C).union(extra);
7682 -- let e2 = Flags::B.union(Flags::C);
7683 -- assert_eq!(e1.bits, 0b1101);
7684 -- assert_eq!(e1.union(e2), (Flags::ABC | extra));
7685 -- assert_eq!(e1.intersection(e2), Flags::C);
7686 -- assert_eq!(e1.difference(e2), Flags::A | extra);
7687 -- assert_eq!(e2.difference(e1), Flags::B);
7688 -- assert_eq!(e2.complement(), Flags::A);
7689 -- assert_eq!(e1.complement(), Flags::B);
7690 -- assert_eq!(e1.symmetric_difference(e2), Flags::A | Flags::B | extra); // toggle
7691 -- }
7692 --
7693 -- #[test]
7694 -- fn test_set_ops_exhaustive() {
7695 -- // Define a flag that contains gaps to help exercise edge-cases,
7696 -- // especially around "unknown" flags (e.g. ones outside of `all()`
7697 -- // `from_bits_unchecked`).
7698 -- // - when lhs and rhs both have different sets of unknown flags.
7699 -- // - unknown flags at both ends, and in the middle
7700 -- // - cases with "gaps".
7701 -- bitflags! {
7702 -- struct Test: u16 {
7703 -- // Intentionally no `A`
7704 -- const B = 0b000000010;
7705 -- // Intentionally no `C`
7706 -- const D = 0b000001000;
7707 -- const E = 0b000010000;
7708 -- const F = 0b000100000;
7709 -- const G = 0b001000000;
7710 -- // Intentionally no `H`
7711 -- const I = 0b100000000;
7712 -- }
7713 -- }
7714 -- let iter_test_flags =
7715 -- || (0..=0b111_1111_1111).map(|bits| unsafe { Test::from_bits_unchecked(bits) });
7716 --
7717 -- for a in iter_test_flags() {
7718 -- assert_eq!(
7719 -- a.complement(),
7720 -- Test::from_bits_truncate(!a.bits),
7721 -- "wrong result: !({:?})",
7722 -- a,
7723 -- );
7724 -- assert_eq!(a.complement(), !a, "named != op: !({:?})", a);
7725 -- for b in iter_test_flags() {
7726 -- // Check that the named operations produce the expected bitwise
7727 -- // values.
7728 -- assert_eq!(
7729 -- a.union(b).bits,
7730 -- a.bits | b.bits,
7731 -- "wrong result: `{:?}` | `{:?}`",
7732 -- a,
7733 -- b,
7734 -- );
7735 -- assert_eq!(
7736 -- a.intersection(b).bits,
7737 -- a.bits & b.bits,
7738 -- "wrong result: `{:?}` & `{:?}`",
7739 -- a,
7740 -- b,
7741 -- );
7742 -- assert_eq!(
7743 -- a.symmetric_difference(b).bits,
7744 -- a.bits ^ b.bits,
7745 -- "wrong result: `{:?}` ^ `{:?}`",
7746 -- a,
7747 -- b,
7748 -- );
7749 -- assert_eq!(
7750 -- a.difference(b).bits,
7751 -- a.bits & !b.bits,
7752 -- "wrong result: `{:?}` - `{:?}`",
7753 -- a,
7754 -- b,
7755 -- );
7756 -- // Note: Difference is checked as both `a - b` and `b - a`
7757 -- assert_eq!(
7758 -- b.difference(a).bits,
7759 -- b.bits & !a.bits,
7760 -- "wrong result: `{:?}` - `{:?}`",
7761 -- b,
7762 -- a,
7763 -- );
7764 -- // Check that the named set operations are equivalent to the
7765 -- // bitwise equivalents
7766 -- assert_eq!(a.union(b), a | b, "named != op: `{:?}` | `{:?}`", a, b,);
7767 -- assert_eq!(
7768 -- a.intersection(b),
7769 -- a & b,
7770 -- "named != op: `{:?}` & `{:?}`",
7771 -- a,
7772 -- b,
7773 -- );
7774 -- assert_eq!(
7775 -- a.symmetric_difference(b),
7776 -- a ^ b,
7777 -- "named != op: `{:?}` ^ `{:?}`",
7778 -- a,
7779 -- b,
7780 -- );
7781 -- assert_eq!(a.difference(b), a - b, "named != op: `{:?}` - `{:?}`", a, b,);
7782 -- // Note: Difference is checked as both `a - b` and `b - a`
7783 -- assert_eq!(b.difference(a), b - a, "named != op: `{:?}` - `{:?}`", b, a,);
7784 -- // Verify that the operations which should be symmetric are
7785 -- // actually symmetric.
7786 -- assert_eq!(a.union(b), b.union(a), "asymmetry: `{:?}` | `{:?}`", a, b,);
7787 -- assert_eq!(
7788 -- a.intersection(b),
7789 -- b.intersection(a),
7790 -- "asymmetry: `{:?}` & `{:?}`",
7791 -- a,
7792 -- b,
7793 -- );
7794 -- assert_eq!(
7795 -- a.symmetric_difference(b),
7796 -- b.symmetric_difference(a),
7797 -- "asymmetry: `{:?}` ^ `{:?}`",
7798 -- a,
7799 -- b,
7800 -- );
7801 -- }
7802 -- }
7803 -- }
7804 --
7805 - #[test]
7806 - fn test_set() {
7807 - let mut e1 = Flags::A | Flags::C;
7808 -@@ -1392,6 +1168,8 @@ mod tests {
7809 - assert_eq!(m1, e1);
7810 - }
7811 -
7812 -+
7813 -+ #[cfg(bitflags_const_fn)]
7814 - #[test]
7815 - fn test_const_fn() {
7816 - const _M1: Flags = Flags::empty();
7817 -@@ -1481,11 +1259,6 @@ mod tests {
7818 - assert_eq!(hash(&x), hash(&y));
7819 - }
7820 -
7821 -- #[test]
7822 -- fn test_default() {
7823 -- assert_eq!(Flags::empty(), Flags::default());
7824 -- }
7825 --
7826 - #[test]
7827 - fn test_debug() {
7828 - assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B");
7829 -@@ -1494,13 +1267,7 @@ mod tests {
7830 - let extra = unsafe { Flags::from_bits_unchecked(0xb8) };
7831 - assert_eq!(format!("{:?}", extra), "0xb8");
7832 - assert_eq!(format!("{:?}", Flags::A | extra), "A | 0xb8");
7833 --
7834 -- assert_eq!(
7835 -- format!("{:?}", Flags::ABC | extra),
7836 -- "A | B | C | ABC | 0xb8"
7837 -- );
7838 --
7839 -- assert_eq!(format!("{:?}", EmptyFlags::empty()), "(empty)");
7840 -+ assert_eq!(format!("{:?}", Flags::ABC | extra), "A | B | C | ABC | 0xb8");
7841 - }
7842 -
7843 - #[test]
7844 -@@ -1544,7 +1311,8 @@ mod tests {
7845 - pub struct PublicFlags: i8 {
7846 - const X = 0;
7847 - }
7848 --
7849 -+ }
7850 -+ bitflags! {
7851 - struct PrivateFlags: i8 {
7852 - const Y = 0;
7853 - }
7854 -@@ -1659,71 +1427,4 @@ mod tests {
7855 - assert_eq!(format!("{:?}", Flags::empty()), "NONE");
7856 - assert_eq!(format!("{:?}", Flags::SOME), "SOME");
7857 - }
7858 --
7859 -- #[test]
7860 -- fn test_empty_bitflags() {
7861 -- bitflags! {}
7862 -- }
7863 --
7864 -- #[test]
7865 -- fn test_u128_bitflags() {
7866 -- bitflags! {
7867 -- struct Flags128: u128 {
7868 -- const A = 0x0000_0000_0000_0000_0000_0000_0000_0001;
7869 -- const B = 0x0000_0000_0000_1000_0000_0000_0000_0000;
7870 -- const C = 0x8000_0000_0000_0000_0000_0000_0000_0000;
7871 -- const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
7872 -- }
7873 -- }
7874 --
7875 -- assert_eq!(Flags128::ABC, Flags128::A | Flags128::B | Flags128::C);
7876 -- assert_eq!(Flags128::A.bits, 0x0000_0000_0000_0000_0000_0000_0000_0001);
7877 -- assert_eq!(Flags128::B.bits, 0x0000_0000_0000_1000_0000_0000_0000_0000);
7878 -- assert_eq!(Flags128::C.bits, 0x8000_0000_0000_0000_0000_0000_0000_0000);
7879 -- assert_eq!(
7880 -- Flags128::ABC.bits,
7881 -- 0x8000_0000_0000_1000_0000_0000_0000_0001
7882 -- );
7883 -- assert_eq!(format!("{:?}", Flags128::A), "A");
7884 -- assert_eq!(format!("{:?}", Flags128::B), "B");
7885 -- assert_eq!(format!("{:?}", Flags128::C), "C");
7886 -- assert_eq!(format!("{:?}", Flags128::ABC), "A | B | C | ABC");
7887 -- }
7888 --
7889 -- #[test]
7890 -- fn test_serde_bitflags_serialize() {
7891 -- let flags = SerdeFlags::A | SerdeFlags::B;
7892 --
7893 -- let serialized = serde_json::to_string(&flags).unwrap();
7894 --
7895 -- assert_eq!(serialized, r#"{"bits":3}"#);
7896 -- }
7897 --
7898 -- #[test]
7899 -- fn test_serde_bitflags_deserialize() {
7900 -- let deserialized: SerdeFlags = serde_json::from_str(r#"{"bits":12}"#).unwrap();
7901 --
7902 -- let expected = SerdeFlags::C | SerdeFlags::D;
7903 --
7904 -- assert_eq!(deserialized.bits, expected.bits);
7905 -- }
7906 --
7907 -- #[test]
7908 -- fn test_serde_bitflags_roundtrip() {
7909 -- let flags = SerdeFlags::A | SerdeFlags::B;
7910 --
7911 -- let deserialized: SerdeFlags = serde_json::from_str(&serde_json::to_string(&flags).unwrap()).unwrap();
7912 --
7913 -- assert_eq!(deserialized.bits, flags.bits);
7914 -- }
7915 --
7916 -- bitflags! {
7917 -- #[derive(serde::Serialize, serde::Deserialize)]
7918 -- struct SerdeFlags: u32 {
7919 -- const A = 1;
7920 -- const B = 2;
7921 -- const C = 4;
7922 -- const D = 8;
7923 -- }
7924 -- }
7925 - }
7926 -diff --git a/third_party/rust/bitflags/tests/basic.rs b/third_party/rust/bitflags/tests/basic.rs
7927 -deleted file mode 100644
7928 -index 73a52bec50b60..0000000000000
7929 ---- a/third_party/rust/bitflags/tests/basic.rs
7930 -+++ /dev/null
7931 -@@ -1,20 +0,0 @@
7932 --#![no_std]
7933 --
7934 --use bitflags::bitflags;
7935 --
7936 --bitflags! {
7937 -- /// baz
7938 -- struct Flags: u32 {
7939 -- const A = 0b00000001;
7940 -- #[doc = "bar"]
7941 -- const B = 0b00000010;
7942 -- const C = 0b00000100;
7943 -- #[doc = "foo"]
7944 -- const ABC = Flags::A.bits | Flags::B.bits | Flags::C.bits;
7945 -- }
7946 --}
7947 --
7948 --#[test]
7949 --fn basic() {
7950 -- assert_eq!(Flags::ABC, Flags::A | Flags::B | Flags::C);
7951 --}
7952 -diff --git a/third_party/rust/bitflags/tests/compile-fail/impls/copy.rs b/third_party/rust/bitflags/tests/compile-fail/impls/copy.rs
7953 -deleted file mode 100644
7954 -index 38f4822f5a5f2..0000000000000
7955 ---- a/third_party/rust/bitflags/tests/compile-fail/impls/copy.rs
7956 -+++ /dev/null
7957 -@@ -1,10 +0,0 @@
7958 --use bitflags::bitflags;
7959 --
7960 --bitflags! {
7961 -- #[derive(Clone, Copy)]
7962 -- struct Flags: u32 {
7963 -- const A = 0b00000001;
7964 -- }
7965 --}
7966 --
7967 --fn main() {}
7968 -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
7969 -deleted file mode 100644
7970 -index 0c13aa5024197..0000000000000
7971 ---- a/third_party/rust/bitflags/tests/compile-fail/impls/copy.stderr.beta
7972 -+++ /dev/null
7973 -@@ -1,27 +0,0 @@
7974 --error[E0119]: conflicting implementations of trait `std::clone::Clone` for type `Flags`
7975 -- --> $DIR/copy.rs:3:1
7976 -- |
7977 --3 | / bitflags! {
7978 --4 | | #[derive(Clone, Copy)]
7979 -- | | ----- first implementation here
7980 --5 | | struct Flags: u32 {
7981 --6 | | const A = 0b00000001;
7982 --7 | | }
7983 --8 | | }
7984 -- | |_^ conflicting implementation for `Flags`
7985 -- |
7986 -- = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
7987 --
7988 --error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `Flags`
7989 -- --> $DIR/copy.rs:3:1
7990 -- |
7991 --3 | / bitflags! {
7992 --4 | | #[derive(Clone, Copy)]
7993 -- | | ---- first implementation here
7994 --5 | | struct Flags: u32 {
7995 --6 | | const A = 0b00000001;
7996 --7 | | }
7997 --8 | | }
7998 -- | |_^ conflicting implementation for `Flags`
7999 -- |
8000 -- = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
8001 -diff --git a/third_party/rust/bitflags/tests/compile-fail/impls/eq.rs b/third_party/rust/bitflags/tests/compile-fail/impls/eq.rs
8002 -deleted file mode 100644
8003 -index 4abbd630c6e12..0000000000000
8004 ---- a/third_party/rust/bitflags/tests/compile-fail/impls/eq.rs
8005 -+++ /dev/null
8006 -@@ -1,10 +0,0 @@
8007 --use bitflags::bitflags;
8008 --
8009 --bitflags! {
8010 -- #[derive(PartialEq, Eq)]
8011 -- struct Flags: u32 {
8012 -- const A = 0b00000001;
8013 -- }
8014 --}
8015 --
8016 --fn main() {}
8017 -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
8018 -deleted file mode 100644
8019 -index 8a1a3b410a0e0..0000000000000
8020 ---- a/third_party/rust/bitflags/tests/compile-fail/impls/eq.stderr.beta
8021 -+++ /dev/null
8022 -@@ -1,55 +0,0 @@
8023 --error[E0119]: conflicting implementations of trait `std::cmp::PartialEq` for type `Flags`
8024 -- --> $DIR/eq.rs:3:1
8025 -- |
8026 --3 | / bitflags! {
8027 --4 | | #[derive(PartialEq, Eq)]
8028 -- | | --------- first implementation here
8029 --5 | | struct Flags: u32 {
8030 --6 | | const A = 0b00000001;
8031 --7 | | }
8032 --8 | | }
8033 -- | |_^ conflicting implementation for `Flags`
8034 -- |
8035 -- = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
8036 --
8037 --error[E0119]: conflicting implementations of trait `std::cmp::Eq` for type `Flags`
8038 -- --> $DIR/eq.rs:3:1
8039 -- |
8040 --3 | / bitflags! {
8041 --4 | | #[derive(PartialEq, Eq)]
8042 -- | | -- first implementation here
8043 --5 | | struct Flags: u32 {
8044 --6 | | const A = 0b00000001;
8045 --7 | | }
8046 --8 | | }
8047 -- | |_^ conflicting implementation for `Flags`
8048 -- |
8049 -- = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info)
8050 --
8051 --error[E0119]: conflicting implementations of trait `std::marker::StructuralPartialEq` for type `Flags`
8052 -- --> $DIR/eq.rs:3:1
8053 -- |
8054 --3 | / bitflags! {
8055 --4 | | #[derive(PartialEq, Eq)]
8056 -- | | --------- first implementation here
8057 --5 | | struct Flags: u32 {
8058 --6 | | const A = 0b00000001;
8059 --7 | | }
8060 --8 | | }
8061 -- | |_^ conflicting implementation for `Flags`
8062 -- |
8063 -- = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
8064 --
8065 --error[E0119]: conflicting implementations of trait `std::marker::StructuralEq` for type `Flags`
8066 -- --> $DIR/eq.rs:3:1
8067 -- |
8068 --3 | / bitflags! {
8069 --4 | | #[derive(PartialEq, Eq)]
8070 -- | | -- first implementation here
8071 --5 | | struct Flags: u32 {
8072 --6 | | const A = 0b00000001;
8073 --7 | | }
8074 --8 | | }
8075 -- | |_^ conflicting implementation for `Flags`
8076 -- |
8077 -- = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info)
8078 -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
8079 -deleted file mode 100644
8080 -index c2856b10830d3..0000000000000
8081 ---- a/third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_defined.rs
8082 -+++ /dev/null
8083 -@@ -1,123 +0,0 @@
8084 --use std::{
8085 -- fmt::{
8086 -- self,
8087 -- Debug,
8088 -- Display,
8089 -- LowerHex,
8090 -- UpperHex,
8091 -- Octal,
8092 -- Binary,
8093 -- },
8094 -- ops::{
8095 -- BitAnd,
8096 -- BitOr,
8097 -- BitXor,
8098 -- BitAndAssign,
8099 -- BitOrAssign,
8100 -- BitXorAssign,
8101 -- Not,
8102 -- },
8103 --};
8104 --
8105 --use bitflags::bitflags;
8106 --
8107 --// Ideally we'd actually want this to work, but currently need something like `num`'s `Zero`
8108 --// With some design work it could be made possible
8109 --#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
8110 --struct MyInt(u8);
8111 --
8112 --impl BitAnd for MyInt {
8113 -- type Output = Self;
8114 --
8115 -- fn bitand(self, other: Self) -> Self {
8116 -- MyInt(self.0 & other.0)
8117 -- }
8118 --}
8119 --
8120 --impl BitOr for MyInt {
8121 -- type Output = Self;
8122 --
8123 -- fn bitor(self, other: Self) -> Self {
8124 -- MyInt(self.0 | other.0)
8125 -- }
8126 --}
8127 --
8128 --impl BitXor for MyInt {
8129 -- type Output = Self;
8130 --
8131 -- fn bitxor(self, other: Self) -> Self {
8132 -- MyInt(self.0 ^ other.0)
8133 -- }
8134 --}
8135 --
8136 --impl BitAndAssign for MyInt {
8137 -- fn bitand_assign(&mut self, other: Self) {
8138 -- self.0 &= other.0
8139 -- }
8140 --}
8141 --
8142 --impl BitOrAssign for MyInt {
8143 -- fn bitor_assign(&mut self, other: Self) {
8144 -- self.0 |= other.0
8145 -- }
8146 --}
8147 --
8148 --impl BitXorAssign for MyInt {
8149 -- fn bitxor_assign(&mut self, other: Self) {
8150 -- self.0 ^= other.0
8151 -- }
8152 --}
8153 --
8154 --impl Debug for MyInt {
8155 -- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8156 -- Debug::fmt(&self.0, f)
8157 -- }
8158 --}
8159 --
8160 --impl Display for MyInt {
8161 -- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8162 -- Display::fmt(&self.0, f)
8163 -- }
8164 --}
8165 --
8166 --impl LowerHex for MyInt {
8167 -- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8168 -- LowerHex::fmt(&self.0, f)
8169 -- }
8170 --}
8171 --
8172 --impl UpperHex for MyInt {
8173 -- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8174 -- UpperHex::fmt(&self.0, f)
8175 -- }
8176 --}
8177 --
8178 --impl Octal for MyInt {
8179 -- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8180 -- Octal::fmt(&self.0, f)
8181 -- }
8182 --}
8183 --
8184 --impl Binary for MyInt {
8185 -- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8186 -- Binary::fmt(&self.0, f)
8187 -- }
8188 --}
8189 --
8190 --impl Not for MyInt {
8191 -- type Output = MyInt;
8192 --
8193 -- fn not(self) -> Self {
8194 -- MyInt(!self.0)
8195 -- }
8196 --}
8197 --
8198 --bitflags! {
8199 -- struct Flags128: MyInt {
8200 -- const A = MyInt(0b0000_0001u8);
8201 -- const B = MyInt(0b0000_0010u8);
8202 -- const C = MyInt(0b0000_0100u8);
8203 -- }
8204 --}
8205 --
8206 --fn main() {}
8207 -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
8208 -deleted file mode 100644
8209 -index 1f0fb5cf7ad0b..0000000000000
8210 ---- a/third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_defined.stderr.beta
8211 -+++ /dev/null
8212 -@@ -1,27 +0,0 @@
8213 --error[E0308]: mismatched types
8214 -- --> $DIR/all_defined.rs:115:1
8215 -- |
8216 --115 | / bitflags! {
8217 --116 | | struct Flags128: MyInt {
8218 --117 | | const A = MyInt(0b0000_0001u8);
8219 --118 | | const B = MyInt(0b0000_0010u8);
8220 --119 | | const C = MyInt(0b0000_0100u8);
8221 --120 | | }
8222 --121 | | }
8223 -- | |_^ expected struct `MyInt`, found integer
8224 -- |
8225 -- = note: this error originates in the macro `__impl_all_bitflags` (in Nightly builds, run with -Z macro-backtrace for more info)
8226 --
8227 --error[E0308]: mismatched types
8228 -- --> $DIR/all_defined.rs:115:1
8229 -- |
8230 --115 | / bitflags! {
8231 --116 | | struct Flags128: MyInt {
8232 --117 | | const A = MyInt(0b0000_0001u8);
8233 --118 | | const B = MyInt(0b0000_0010u8);
8234 --119 | | const C = MyInt(0b0000_0100u8);
8235 --120 | | }
8236 --121 | | }
8237 -- | |_^ expected struct `MyInt`, found integer
8238 -- |
8239 -- = note: this error originates in the macro `__impl_bitflags` (in Nightly builds, run with -Z macro-backtrace for more info)
8240 -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
8241 -deleted file mode 100644
8242 -index fff6b2cc13062..0000000000000
8243 ---- a/third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_missing.rs
8244 -+++ /dev/null
8245 -@@ -1,13 +0,0 @@
8246 --use bitflags::bitflags;
8247 --
8248 --struct MyInt(u8);
8249 --
8250 --bitflags! {
8251 -- struct Flags128: MyInt {
8252 -- const A = MyInt(0b0000_0001);
8253 -- const B = MyInt(0b0000_0010);
8254 -- const C = MyInt(0b0000_0100);
8255 -- }
8256 --}
8257 --
8258 --fn main() {}
8259 -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
8260 -deleted file mode 100644
8261 -index ee95f8365e33e..0000000000000
8262 ---- a/third_party/rust/bitflags/tests/compile-fail/non_integer_base/all_missing.stderr.beta
8263 -+++ /dev/null
8264 -@@ -1,13 +0,0 @@
8265 --error[E0204]: the trait `Copy` may not be implemented for this type
8266 -- --> $DIR/all_missing.rs:5:1
8267 -- |
8268 --5 | / bitflags! {
8269 --6 | | struct Flags128: MyInt {
8270 --7 | | const A = MyInt(0b0000_0001);
8271 --8 | | const B = MyInt(0b0000_0010);
8272 --9 | | const C = MyInt(0b0000_0100);
8273 --10 | | }
8274 --11 | | }
8275 -- | |_^ this field does not implement `Copy`
8276 -- |
8277 -- = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
8278 -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
8279 -deleted file mode 100644
8280 -index a6a3912aea30a..0000000000000
8281 ---- a/third_party/rust/bitflags/tests/compile-fail/visibility/private_field.rs
8282 -+++ /dev/null
8283 -@@ -1,13 +0,0 @@
8284 --mod example {
8285 -- use bitflags::bitflags;
8286 --
8287 -- bitflags! {
8288 -- pub struct Flags1: u32 {
8289 -- const FLAG_A = 0b00000001;
8290 -- }
8291 -- }
8292 --}
8293 --
8294 --fn main() {
8295 -- let flag1 = example::Flags1::FLAG_A.bits;
8296 --}
8297 -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
8298 -deleted file mode 100644
8299 -index 58a04660166a8..0000000000000
8300 ---- a/third_party/rust/bitflags/tests/compile-fail/visibility/private_field.stderr.beta
8301 -+++ /dev/null
8302 -@@ -1,10 +0,0 @@
8303 --error[E0616]: field `bits` of struct `Flags1` is private
8304 -- --> $DIR/private_field.rs:12:41
8305 -- |
8306 --12 | let flag1 = example::Flags1::FLAG_A.bits;
8307 -- | ^^^^ private field
8308 -- |
8309 --help: a method `bits` also exists, call it with parentheses
8310 -- |
8311 --12 | let flag1 = example::Flags1::FLAG_A.bits();
8312 -- | ^^
8313 -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
8314 -deleted file mode 100644
8315 -index 85a5b1863dd43..0000000000000
8316 ---- a/third_party/rust/bitflags/tests/compile-fail/visibility/private_flags.rs
8317 -+++ /dev/null
8318 -@@ -1,18 +0,0 @@
8319 --mod example {
8320 -- use bitflags::bitflags;
8321 --
8322 -- bitflags! {
8323 -- pub struct Flags1: u32 {
8324 -- const FLAG_A = 0b00000001;
8325 -- }
8326 --
8327 -- struct Flags2: u32 {
8328 -- const FLAG_B = 0b00000010;
8329 -- }
8330 -- }
8331 --}
8332 --
8333 --fn main() {
8334 -- let flag1 = example::Flags1::FLAG_A;
8335 -- let flag2 = example::Flags2::FLAG_B;
8336 --}
8337 -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
8338 -deleted file mode 100644
8339 -index d23f83209ba90..0000000000000
8340 ---- a/third_party/rust/bitflags/tests/compile-fail/visibility/private_flags.stderr.beta
8341 -+++ /dev/null
8342 -@@ -1,18 +0,0 @@
8343 --error[E0603]: struct `Flags2` is private
8344 -- --> $DIR/private_flags.rs:17:26
8345 -- |
8346 --17 | let flag2 = example::Flags2::FLAG_B;
8347 -- | ^^^^^^ private struct
8348 -- |
8349 --note: the struct `Flags2` is defined here
8350 -- --> $DIR/private_flags.rs:4:5
8351 -- |
8352 --4 | / bitflags! {
8353 --5 | | pub struct Flags1: u32 {
8354 --6 | | const FLAG_A = 0b00000001;
8355 --7 | | }
8356 --... |
8357 --11 | | }
8358 --12 | | }
8359 -- | |_____^
8360 -- = note: this error originates in the macro `bitflags` (in Nightly builds, run with -Z macro-backtrace for more info)
8361 -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
8362 -deleted file mode 100644
8363 -index b90f0ce92d1e6..0000000000000
8364 ---- a/third_party/rust/bitflags/tests/compile-fail/visibility/pub_const.rs
8365 -+++ /dev/null
8366 -@@ -1,9 +0,0 @@
8367 --use bitflags::bitflags;
8368 --
8369 --bitflags! {
8370 -- pub struct Flags1: u32 {
8371 -- pub const FLAG_A = 0b00000001;
8372 -- }
8373 --}
8374 --
8375 --fn main() {}
8376 -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
8377 -deleted file mode 100644
8378 -index b01122c7ad879..0000000000000
8379 ---- a/third_party/rust/bitflags/tests/compile-fail/visibility/pub_const.stderr.beta
8380 -+++ /dev/null
8381 -@@ -1,5 +0,0 @@
8382 --error: no rules expected the token `pub`
8383 -- --> $DIR/pub_const.rs:5:9
8384 -- |
8385 --5 | pub const FLAG_A = 0b00000001;
8386 -- | ^^^ no rules expected this token in macro call
8387 -diff --git a/third_party/rust/bitflags/tests/compile-pass/impls/convert.rs b/third_party/rust/bitflags/tests/compile-pass/impls/convert.rs
8388 -deleted file mode 100644
8389 -index 1f02982a8fa24..0000000000000
8390 ---- a/third_party/rust/bitflags/tests/compile-pass/impls/convert.rs
8391 -+++ /dev/null
8392 -@@ -1,17 +0,0 @@
8393 --use bitflags::bitflags;
8394 --
8395 --bitflags! {
8396 -- struct Flags: u32 {
8397 -- const A = 0b00000001;
8398 -- }
8399 --}
8400 --
8401 --impl From<u32> for Flags {
8402 -- fn from(v: u32) -> Flags {
8403 -- Flags::from_bits_truncate(v)
8404 -- }
8405 --}
8406 --
8407 --fn main() {
8408 --
8409 --}
8410 -diff --git a/third_party/rust/bitflags/tests/compile-pass/impls/default.rs b/third_party/rust/bitflags/tests/compile-pass/impls/default.rs
8411 -deleted file mode 100644
8412 -index a97b6536f2b58..0000000000000
8413 ---- a/third_party/rust/bitflags/tests/compile-pass/impls/default.rs
8414 -+++ /dev/null
8415 -@@ -1,10 +0,0 @@
8416 --use bitflags::bitflags;
8417 --
8418 --bitflags! {
8419 -- #[derive(Default)]
8420 -- struct Flags: u32 {
8421 -- const A = 0b00000001;
8422 -- }
8423 --}
8424 --
8425 --fn main() {}
8426 -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
8427 -deleted file mode 100644
8428 -index 3052c460ec33a..0000000000000
8429 ---- a/third_party/rust/bitflags/tests/compile-pass/impls/inherent_methods.rs
8430 -+++ /dev/null
8431 -@@ -1,15 +0,0 @@
8432 --use bitflags::bitflags;
8433 --
8434 --bitflags! {
8435 -- struct Flags: u32 {
8436 -- const A = 0b00000001;
8437 -- }
8438 --}
8439 --
8440 --impl Flags {
8441 -- pub fn new() -> Flags {
8442 -- Flags::A
8443 -- }
8444 --}
8445 --
8446 --fn main() {}
8447 -diff --git a/third_party/rust/bitflags/tests/compile-pass/redefinition/core.rs b/third_party/rust/bitflags/tests/compile-pass/redefinition/core.rs
8448 -deleted file mode 100644
8449 -index 47549215948d1..0000000000000
8450 ---- a/third_party/rust/bitflags/tests/compile-pass/redefinition/core.rs
8451 -+++ /dev/null
8452 -@@ -1,14 +0,0 @@
8453 --use bitflags::bitflags;
8454 --
8455 --// Checks for possible errors caused by overriding names used by `bitflags!` internally.
8456 --
8457 --mod core {}
8458 --mod _core {}
8459 --
8460 --bitflags! {
8461 -- struct Test: u8 {
8462 -- const A = 1;
8463 -- }
8464 --}
8465 --
8466 --fn main() {}
8467 -diff --git a/third_party/rust/bitflags/tests/compile-pass/redefinition/stringify.rs b/third_party/rust/bitflags/tests/compile-pass/redefinition/stringify.rs
8468 -deleted file mode 100644
8469 -index b04f2f6a49332..0000000000000
8470 ---- a/third_party/rust/bitflags/tests/compile-pass/redefinition/stringify.rs
8471 -+++ /dev/null
8472 -@@ -1,19 +0,0 @@
8473 --use bitflags::bitflags;
8474 --
8475 --// Checks for possible errors caused by overriding names used by `bitflags!` internally.
8476 --
8477 --#[allow(unused_macros)]
8478 --macro_rules! stringify {
8479 -- ($($t:tt)*) => { "..." };
8480 --}
8481 --
8482 --bitflags! {
8483 -- struct Test: u8 {
8484 -- const A = 1;
8485 -- }
8486 --}
8487 --
8488 --fn main() {
8489 -- // Just make sure we don't call the redefined `stringify` macro
8490 -- assert_eq!(format!("{:?}", Test::A), "A");
8491 --}
8492 -diff --git a/third_party/rust/bitflags/tests/compile-pass/repr/c.rs b/third_party/rust/bitflags/tests/compile-pass/repr/c.rs
8493 -deleted file mode 100644
8494 -index 6feba36ed82c1..0000000000000
8495 ---- a/third_party/rust/bitflags/tests/compile-pass/repr/c.rs
8496 -+++ /dev/null
8497 -@@ -1,10 +0,0 @@
8498 --use bitflags::bitflags;
8499 --
8500 --bitflags! {
8501 -- #[repr(C)]
8502 -- struct Flags: u32 {
8503 -- const A = 0b00000001;
8504 -- }
8505 --}
8506 --
8507 --fn main() {}
8508 -diff --git a/third_party/rust/bitflags/tests/compile-pass/repr/transparent.rs b/third_party/rust/bitflags/tests/compile-pass/repr/transparent.rs
8509 -deleted file mode 100644
8510 -index e38db4dd11b99..0000000000000
8511 ---- a/third_party/rust/bitflags/tests/compile-pass/repr/transparent.rs
8512 -+++ /dev/null
8513 -@@ -1,10 +0,0 @@
8514 --use bitflags::bitflags;
8515 --
8516 --bitflags! {
8517 -- #[repr(transparent)]
8518 -- struct Flags: u32 {
8519 -- const A = 0b00000001;
8520 -- }
8521 --}
8522 --
8523 --fn main() {}
8524 -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
8525 -deleted file mode 100644
8526 -index 33a7967e629ef..0000000000000
8527 ---- a/third_party/rust/bitflags/tests/compile-pass/visibility/bits_field.rs
8528 -+++ /dev/null
8529 -@@ -1,11 +0,0 @@
8530 --use bitflags::bitflags;
8531 --
8532 --bitflags! {
8533 -- pub struct Flags1: u32 {
8534 -- const FLAG_A = 0b00000001;
8535 -- }
8536 --}
8537 --
8538 --fn main() {
8539 -- assert_eq!(0b00000001, Flags1::FLAG_A.bits);
8540 --}
8541 -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
8542 -deleted file mode 100644
8543 -index c11050e3baf0c..0000000000000
8544 ---- a/third_party/rust/bitflags/tests/compile-pass/visibility/pub_in.rs
8545 -+++ /dev/null
8546 -@@ -1,19 +0,0 @@
8547 --mod a {
8548 -- mod b {
8549 -- use bitflags::bitflags;
8550 --
8551 -- bitflags! {
8552 -- pub(in crate::a) struct Flags: u32 {
8553 -- const FLAG_A = 0b00000001;
8554 -- }
8555 -- }
8556 -- }
8557 --
8558 -- pub fn flags() -> u32 {
8559 -- b::Flags::FLAG_A.bits()
8560 -- }
8561 --}
8562 --
8563 --fn main() {
8564 -- assert_eq!(0b00000001, a::flags());
8565 --}
8566 -diff --git a/third_party/rust/bitflags/tests/compile.rs b/third_party/rust/bitflags/tests/compile.rs
8567 -deleted file mode 100644
8568 -index ed02d01e9ca1b..0000000000000
8569 ---- a/third_party/rust/bitflags/tests/compile.rs
8570 -+++ /dev/null
8571 -@@ -1,63 +0,0 @@
8572 --use std::{
8573 -- fs,
8574 -- ffi::OsStr,
8575 -- io,
8576 -- path::Path,
8577 --};
8578 --
8579 --use walkdir::WalkDir;
8580 --
8581 --#[test]
8582 --fn fail() {
8583 -- prepare_stderr_files("tests/compile-fail").unwrap();
8584 --
8585 -- let t = trybuild::TestCases::new();
8586 -- t.compile_fail("tests/compile-fail/**/*.rs");
8587 --}
8588 --
8589 --#[test]
8590 --fn pass() {
8591 -- let t = trybuild::TestCases::new();
8592 -- t.pass("tests/compile-pass/**/*.rs");
8593 --}
8594 --
8595 --// Compiler messages may change between versions
8596 --// We don't want to have to track these too closely for `bitflags`, but
8597 --// having some message to check makes sure user-facing errors are sensical.
8598 --//
8599 --// The approach we use is to run the test on all compilers, but only check stderr
8600 --// output on beta (which is the next stable release). We do this by default ignoring
8601 --// any `.stderr` files in the `compile-fail` directory, and copying `.stderr.beta` files
8602 --// when we happen to be running on a beta compiler.
8603 --fn prepare_stderr_files(path: impl AsRef<Path>) -> io::Result<()> {
8604 -- for entry in WalkDir::new(path) {
8605 -- let entry = entry?;
8606 --
8607 -- if entry.path().extension().and_then(OsStr::to_str) == Some("beta") {
8608 -- let renamed = entry.path().with_extension("");
8609 --
8610 -- // Unconditionally remove a corresponding `.stderr` file for a `.stderr.beta`
8611 -- // file if it exists. On `beta` compilers, we'll recreate it. On other compilers,
8612 -- // we don't want to end up checking it anyways.
8613 -- if renamed.exists() {
8614 -- fs::remove_file(&renamed)?;
8615 -- }
8616 --
8617 -- rename_beta_stderr(entry.path(), renamed)?;
8618 -- }
8619 -- }
8620 --
8621 -- Ok(())
8622 --}
8623 --
8624 --#[rustversion::beta]
8625 --fn rename_beta_stderr(from: impl AsRef<Path>, to: impl AsRef<Path>) -> io::Result<()> {
8626 -- fs::copy(from, to)?;
8627 --
8628 -- Ok(())
8629 --}
8630 --
8631 --#[rustversion::not(beta)]
8632 --fn rename_beta_stderr(_: impl AsRef<Path>, _: impl AsRef<Path>) -> io::Result<()> {
8633 -- Ok(())
8634 --}
8635 -diff --git a/third_party/rust/midir/.cargo-checksum.json b/third_party/rust/midir/.cargo-checksum.json
8636 -index 390b25b1e0118..34b17c2c5c548 100644
8637 ---- a/third_party/rust/midir/.cargo-checksum.json
8638 -+++ b/third_party/rust/midir/.cargo-checksum.json
8639 -@@ -1 +1 @@
8640 --{"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/
8641 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":"2cab2e987428522ca601544b516b64b858859730fbd1be0
8642 e53c828e82025319d","src/errors.rs":"495ba80f9dcfeefd343b460b74549b12cb1825c3e1b315848f859d0b4d66ddbe","src/lib.rs":"ecde030ca02a90a99577cd71446857a2c00aee8ff1bc7890c54a5d0d22d2be2c","src/os/mod.rs":"507dfa95e57805c489a883dcf9efddcb718d5178267f296294f72b3c397c12c7","src/os/unix.rs":"a1977659d270fcf31111d4446b949d2760d76e2077639e6008d634800861b77b","tests/virtual.rs":"b47501eeb313f3e255d2d1888c333ff994d958865272929fe7bf116be45b6805"},"package":null}
8643 -\ No newline at end of file
8644 -+{"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/
8645 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":"2cab2e987428522ca601544b516b64b858859730fbd1be0
8646 e53c828e82025319d","src/errors.rs":"495ba80f9dcfeefd343b460b74549b12cb1825c3e1b315848f859d0b4d66ddbe","src/lib.rs":"ecde030ca02a90a99577cd71446857a2c00aee8ff1bc7890c54a5d0d22d2be2c","src/os/mod.rs":"507dfa95e57805c489a883dcf9efddcb718d5178267f296294f72b3c397c12c7","src/os/unix.rs":"a1977659d270fcf31111d4446b949d2760d76e2077639e6008d634800861b77b","tests/virtual.rs":"b47501eeb313f3e255d2d1888c333ff994d958865272929fe7bf116be45b6805"},"package":null}
8647 -\ No newline at end of file
8648 -diff --git a/third_party/rust/midir/Cargo.toml b/third_party/rust/midir/Cargo.toml
8649 -index 49089e0ffe86e..ac48aab304db9 100644
8650 ---- a/third_party/rust/midir/Cargo.toml
8651 -+++ b/third_party/rust/midir/Cargo.toml
8652 -@@ -28,8 +28,8 @@ libc = { version = "0.2.21", optional = true }
8653 - winrt = { version = "0.7.0", optional = true}
8654 -
8655 - [target.'cfg(target_os = "linux")'.dependencies]
8656 --alsa = "0.4.3"
8657 --nix = "0.15"
8658 -+alsa = "0.5.0"
8659 -+nix = "0.20"
8660 - libc = "0.2.21"
8661 -
8662 - [target.'cfg(target_os = "macos")'.dependencies]
8663 -diff --git a/third_party/rust/nix-0.15.0/.cargo-checksum.json b/third_party/rust/nix-0.15.0/.cargo-checksum.json
8664 -new file mode 100644
8665 -index 0000000000000..e5f2bc789185a
8666 ---- /dev/null
8667 -+++ b/third_party/rust/nix-0.15.0/.cargo-checksum.json
8668 -@@ -0,0 +1 @@
8669 -+{"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","
8670 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/e
8671 poll.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":"8a7eacfc172b55763ae
8672 32109bf9b252669ba68b72cd5122f7504eb35c0c08345","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":"c663505d6a7a7ae9d76e03fbc17e5
8673 3d308ea6b1eae92212812e1d76b2bf2916f","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.
8674 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":"84ae63c2baa49eebeabe5bbd347b9c5417e14ba97f342719d7
8675 53dc1c1c768d60","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":"0219f7bce0603f97d997fb377ca071966c903
8676 33ecc665e78a54dfeb97a9c811b","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":"1dc420d3119bf4d863a7ae0ba63efa7f1416f6e46e4
8677 100ea161003fe1c3f66ba","test/test_unistd.rs":"0325c998acca1e826e9e2b3d351d55ab9723a6cb2ca2072245978e7f5a9acee8"},"package":"3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229"}
8678 -\ No newline at end of file
8679 -diff --git a/third_party/rust/nix-0.15.0/CHANGELOG.md b/third_party/rust/nix-0.15.0/CHANGELOG.md
8680 -new file mode 100644
8681 -index 0000000000000..d93a5ce6bbfc9
8682 ---- /dev/null
8683 -+++ b/third_party/rust/nix-0.15.0/CHANGELOG.md
8684 -@@ -0,0 +1,742 @@
8685 -+# Change Log
8686 -+
8687 -+All notable changes to this project will be documented in this file.
8688 -+This project adheres to [Semantic Versioning](http://semver.org/).
8689 -+
8690 -+## [Unreleased] - ReleaseDate
8691 -+### Added
8692 -+### Changed
8693 -+### Fixed
8694 -+### Removed
8695 -+
8696 -+## [0.15.0] - 10 August 2019
8697 -+### Added
8698 -+- Added `MSG_WAITALL` to `MsgFlags` in `sys::socket`.
8699 -+ ([#1079](https://github.com/nix-rust/nix/pull/1079))
8700 -+- Implemented `Clone`, `Copy`, `Debug`, `Eq`, `Hash`, and `PartialEq` for most
8701 -+ types that support them. ([#1035](https://github.com/nix-rust/nix/pull/1035))
8702 -+- Added `copy_file_range` wrapper
8703 -+ ([#1069](https://github.com/nix-rust/nix/pull/1069))
8704 -+- Add `mkdirat`.
8705 -+ ([#1084](https://github.com/nix-rust/nix/pull/1084))
8706 -+- Add `posix_fadvise`.
8707 -+ ([#1089](https://github.com/nix-rust/nix/pull/1089))
8708 -+- Added `AF_VSOCK` to `AddressFamily`.
8709 -+ ([#1091](https://github.com/nix-rust/nix/pull/1091))
8710 -+- Add `unlinkat`
8711 -+ ([#1058](https://github.com/nix-rust/nix/pull/1058))
8712 -+- Add `renameat`.
8713 -+ ([#1097](https://github.com/nix-rust/nix/pull/1097))
8714 -+
8715 -+### Changed
8716 -+- Support for `ifaddrs` now present when building for Android.
8717 -+ ([#1077](https://github.com/nix-rust/nix/pull/1077))
8718 -+- Minimum supported Rust version is now 1.31.0
8719 -+ ([#1035](https://github.com/nix-rust/nix/pull/1035))
8720 -+ ([#1095](https://github.com/nix-rust/nix/pull/1095))
8721 -+- Now functions `statfs()` and `fstatfs()` return result with `Statfs` wrapper
8722 -+ ([#928](https://github.com/nix-rust/nix/pull/928))
8723 -+
8724 -+### Fixed
8725 -+- Enabled `sched_yield` for all nix hosts.
8726 -+ ([#1090](https://github.com/nix-rust/nix/pull/1090))
8727 -+
8728 -+### Removed
8729 -+
8730 -+## [0.14.1] - 2019-06-06
8731 -+### Added
8732 -+- Macros exported by `nix` may now be imported via `use` on the Rust 2018
8733 -+ edition without importing helper macros on Linux targets.
8734 -+ ([#1066](https://github.com/nix-rust/nix/pull/1066))
8735 -+
8736 -+ For example, in Rust 2018, the `ioctl_read_bad!` macro can now be imported
8737 -+ without importing the `convert_ioctl_res!` macro.
8738 -+
8739 -+ ```rust
8740 -+ use nix::ioctl_read_bad;
8741 -+
8742 -+ ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios);
8743 -+ ```
8744 -+
8745 -+### Changed
8746 -+- Changed some public types from reexports of libc types like `uint32_t` to the
8747 -+ native equivalents like `u32.`
8748 -+ ([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
8749 -+
8750 -+### Fixed
8751 -+- Fix the build on Android and Linux/mips with recent versions of libc.
8752 -+ ([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
8753 -+
8754 -+### Removed
8755 -+
8756 -+## [0.14.0] - 2019-05-21
8757 -+### Added
8758 -+- Add IP_RECVIF & IP_RECVDSTADDR. Enable IP_PKTINFO and IP6_PKTINFO on netbsd/openbsd.
8759 -+ ([#1002](https://github.com/nix-rust/nix/pull/1002))
8760 -+- Added `inotify_init1`, `inotify_add_watch` and `inotify_rm_watch` wrappers for
8761 -+ Android and Linux. ([#1016](https://github.com/nix-rust/nix/pull/1016))
8762 -+- Add `ALG_SET_IV`, `ALG_SET_OP` and `ALG_SET_AEAD_ASSOCLEN` control messages and `AF_ALG`
8763 -+ socket types on Linux and Android ([#1031](https://github.com/nix-rust/nix/pull/1031))
8764 -+- Add killpg
8765 -+ ([#1034](https://github.com/nix-rust/nix/pull/1034))
8766 -+- Added ENOTSUP errno support for Linux and Android.
8767 -+ ([#969](https://github.com/nix-rust/nix/pull/969))
8768 -+- Add several errno constants from OpenBSD 6.2
8769 -+ ([#1036](https://github.com/nix-rust/nix/pull/1036))
8770 -+- Added `from_std` and `to_std` methods for `sys::socket::IpAddr`
8771 -+ ([#1043](https://github.com/nix-rust/nix/pull/1043))
8772 -+- Added `nix::unistd:seteuid` and `nix::unistd::setegid` for those platforms that do
8773 -+ not support `setresuid` nor `setresgid` respectively.
8774 -+ ([#1044](https://github.com/nix-rust/nix/pull/1044))
8775 -+- Added a `access` wrapper
8776 -+ ([#1045](https://github.com/nix-rust/nix/pull/1045))
8777 -+- Add `forkpty`
8778 -+ ([#1042](https://github.com/nix-rust/nix/pull/1042))
8779 -+- Add `sched_yield`
8780 -+ ([#1050](https://github.com/nix-rust/nix/pull/1050))
8781 -+
8782 -+### Changed
8783 -+- `PollFd` event flags renamed to `PollFlags` ([#1024](https://github.com/nix-rust/nix/pull/1024/))
8784 -+- `recvmsg` now returns an Iterator over `ControlMessageOwned` objects rather
8785 -+ than `ControlMessage` objects. This is sadly not backwards-compatible. Fix
8786 -+ code like this:
8787 -+ ```rust
8788 -+ if let ControlMessage::ScmRights(&fds) = cmsg {
8789 -+ ```
8790 -+
8791 -+ By replacing it with code like this:
8792 -+ ```rust
8793 -+ if let ControlMessageOwned::ScmRights(fds) = cmsg {
8794 -+ ```
8795 -+ ([#1020](https://github.com/nix-rust/nix/pull/1020))
8796 -+- Replaced `CmsgSpace` with the `cmsg_space` macro.
8797 -+ ([#1020](https://github.com/nix-rust/nix/pull/1020))
8798 -+
8799 -+### Fixed
8800 -+- Fixed multiple bugs when using `sendmsg` and `recvmsg` with ancillary control messages
8801 -+ ([#1020](https://github.com/nix-rust/nix/pull/1020))
8802 -+- Macros exported by `nix` may now be imported via `use` on the Rust 2018
8803 -+ edition without importing helper macros for BSD targets.
8804 -+ ([#1041](https://github.com/nix-rust/nix/pull/1041))
8805 -+
8806 -+ For example, in Rust 2018, the `ioctl_read_bad!` macro can now be imported
8807 -+ without importing the `convert_ioctl_res!` macro.
8808 -+
8809 -+ ```rust
8810 -+ use nix::ioctl_read_bad;
8811 -+
8812 -+ ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios);
8813 -+ ```
8814 -+
8815 -+### Removed
8816 -+- `Daemon`, `NOTE_REAP`, and `NOTE_EXIT_REPARENTED` are now deprecated on OSX
8817 -+ and iOS.
8818 -+ ([#1033](https://github.com/nix-rust/nix/pull/1033))
8819 -+- `PTRACE_GETREGS`, `PTRACE_SETREGS`, `PTRACE_GETFPREGS`, and
8820 -+ `PTRACE_SETFPREGS` have been removed from some platforms where they never
8821 -+ should've been defined in the first place.
8822 -+ ([#1055](https://github.com/nix-rust/nix/pull/1055))
8823 -+
8824 -+## [0.13.0] - 2019-01-15
8825 -+### Added
8826 -+- Added PKTINFO(V4) & V6PKTINFO cmsg support - Android/FreeBSD/iOS/Linux/MacOS.
8827 -+ ([#990](https://github.com/nix-rust/nix/pull/990))
8828 -+- Added support of CString type in `setsockopt`.
8829 -+ ([#972](https://github.com/nix-rust/nix/pull/972))
8830 -+- Added option `TCP_CONGESTION` in `setsockopt`.
8831 -+ ([#972](https://github.com/nix-rust/nix/pull/972))
8832 -+- Added `symlinkat` wrapper.
8833 -+ ([#997](https://github.com/nix-rust/nix/pull/997))
8834 -+- Added `ptrace::{getregs, setregs}`.
8835 -+ ([#1010](https://github.com/nix-rust/nix/pull/1010))
8836 -+- Added `nix::sys::signal::signal`.
8837 -+ ([#817](https://github.com/nix-rust/nix/pull/817))
8838 -+- Added an `mprotect` wrapper.
8839 -+ ([#991](https://github.com/nix-rust/nix/pull/991))
8840 -+
8841 -+### Changed
8842 -+### Fixed
8843 -+- `lutimes` never worked on OpenBSD as it is not implemented on OpenBSD. It has
8844 -+ been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000))
8845 -+- `fexecve` never worked on NetBSD or on OpenBSD as it is not implemented on
8846 -+ either OS. It has been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000))
8847 -+
8848 -+### Removed
8849 -+
8850 -+## [0.12.0] 2018-11-28
8851 -+
8852 -+### Added
8853 -+- Added `FromStr` and `Display` impls for `nix::sys::Signal`
8854 -+ ([#884](https://github.com/nix-rust/nix/pull/884))
8855 -+- Added a `sync` wrapper.
8856 -+ ([#961](https://github.com/nix-rust/nix/pull/961))
8857 -+- Added a `sysinfo` wrapper.
8858 -+ ([#922](https://github.com/nix-rust/nix/pull/922))
8859 -+- Support the `SO_PEERCRED` socket option and the `UnixCredentials` type on all Linux and Android targets.
8860 -+ ([#921](https://github.com/nix-rust/nix/pull/921))
8861 -+- Added support for `SCM_CREDENTIALS`, allowing to send process credentials over Unix sockets.
8862 -+ ([#923](https://github.com/nix-rust/nix/pull/923))
8863 -+- Added a `dir` module for reading directories (wraps `fdopendir`, `readdir`, and `rewinddir`).
8864 -+ ([#916](https://github.com/nix-rust/nix/pull/916))
8865 -+- Added `kmod` module that allows loading and unloading kernel modules on Linux.
8866 -+ ([#930](https://github.com/nix-rust/nix/pull/930))
8867 -+- Added `futimens` and `utimesat` wrappers ([#944](https://github.com/nix-rust/nix/pull/944)),
8868 -+ an `lutimes` wrapper ([#967](https://github.com/nix-rust/nix/pull/967)),
8869 -+ and a `utimes` wrapper ([#946](https://github.com/nix-rust/nix/pull/946)).
8870 -+- Added `AF_UNSPEC` wrapper to `AddressFamily` ([#948](https://github.com/nix-rust/nix/pull/948))
8871 -+- Added the `mode_t` public alias within `sys::stat`.
8872 -+ ([#954](https://github.com/nix-rust/nix/pull/954))
8873 -+- Added a `truncate` wrapper.
8874 -+ ([#956](https://github.com/nix-rust/nix/pull/956))
8875 -+- Added a `fchownat` wrapper.
8876 -+ ([#955](https://github.com/nix-rust/nix/pull/955))
8877 -+- Added support for `ptrace` on BSD operating systems ([#949](https://github.com/nix-rust/nix/pull/949))
8878 -+- Added `ptrace` functions for reads and writes to tracee memory and ptrace kill
8879 -+ ([#949](https://github.com/nix-rust/nix/pull/949)) ([#958](https://github.com/nix-rust/nix/pull/958))
8880 -+- Added a `acct` wrapper module for enabling and disabling process accounting
8881 -+ ([#952](https://github.com/nix-rust/nix/pull/952))
8882 -+- Added the `time_t` and `suseconds_t` public aliases within `sys::time`.
8883 -+ ([#968](https://github.com/nix-rust/nix/pull/968))
8884 -+- Added `unistd::execvpe` for Haiku, Linux and OpenBSD
8885 -+ ([#975](https://github.com/nix-rust/nix/pull/975))
8886 -+- Added `Error::as_errno`.
8887 -+ ([#977](https://github.com/nix-rust/nix/pull/977))
8888 -+
8889 -+### Changed
8890 -+- Increased required Rust version to 1.24.1
8891 -+ ([#900](https://github.com/nix-rust/nix/pull/900))
8892 -+ ([#966](https://github.com/nix-rust/nix/pull/966))
8893 -+
8894 -+### Fixed
8895 -+- Made `preadv` take immutable slice of IoVec.
8896 -+ ([#914](https://github.com/nix-rust/nix/pull/914))
8897 -+- Fixed passing multiple file descriptors over Unix Sockets.
8898 -+ ([#918](https://github.com/nix-rust/nix/pull/918))
8899 -+
8900 -+### Removed
8901 -+
8902 -+## [0.11.0] 2018-06-01
8903 -+
8904 -+### Added
8905 -+- Added `sendfile` on FreeBSD and Darwin.
8906 -+ ([#901](https://github.com/nix-rust/nix/pull/901))
8907 -+- Added `pselect`
8908 -+ ([#894](https://github.com/nix-rust/nix/pull/894))
8909 -+- Exposed `preadv` and `pwritev` on the BSDs.
8910 -+ ([#883](https://github.com/nix-rust/nix/pull/883))
8911 -+- Added `mlockall` and `munlockall`
8912 -+ ([#876](https://github.com/nix-rust/nix/pull/876))
8913 -+- Added `SO_MARK` on Linux.
8914 -+ ([#873](https://github.com/nix-rust/nix/pull/873))
8915 -+- Added safe support for nearly any buffer type in the `sys::aio` module.
8916 -+ ([#872](https://github.com/nix-rust/nix/pull/872))
8917 -+- Added `sys::aio::LioCb` as a wrapper for `libc::lio_listio`.
8918 -+ ([#872](https://github.com/nix-rust/nix/pull/872))
8919 -+- Added `unistd::getsid`
8920 -+ ([#850](https://github.com/nix-rust/nix/pull/850))
8921 -+- Added `alarm`. ([#830](https://github.com/nix-rust/nix/pull/830))
8922 -+- Added interface flags `IFF_NO_PI, IFF_TUN, IFF_TAP` on linux-like systems.
8923 -+ ([#853](https://github.com/nix-rust/nix/pull/853))
8924 -+- Added `statvfs` module to all MacOS and Linux architectures.
8925 -+ ([#832](https://github.com/nix-rust/nix/pull/832))
8926 -+- Added `EVFILT_EMPTY`, `EVFILT_PROCDESC`, and `EVFILT_SENDFILE` on FreeBSD.
8927 -+ ([#825](https://github.com/nix-rust/nix/pull/825))
8928 -+- Exposed `termios::cfmakesane` on FreeBSD.
8929 -+ ([#825](https://github.com/nix-rust/nix/pull/825))
8930 -+- Exposed `MSG_CMSG_CLOEXEC` on *BSD.
8931 -+ ([#825](https://github.com/nix-rust/nix/pull/825))
8932 -+- Added `fchmod`, `fchmodat`.
8933 -+ ([#857](https://github.com/nix-rust/nix/pull/857))
8934 -+- Added `request_code_write_int!` on FreeBSD/DragonFlyBSD
8935 -+ ([#833](https://github.com/nix-rust/nix/pull/833))
8936 -+
8937 -+### Changed
8938 -+- `Display` and `Debug` for `SysControlAddr` now includes all fields.
8939 -+ ([#837](https://github.com/nix-rust/nix/pull/837))
8940 -+- `ioctl!` has been replaced with a family of `ioctl_*!` macros.
8941 -+ ([#833](https://github.com/nix-rust/nix/pull/833))
8942 -+- `io!`, `ior!`, `iow!`, and `iorw!` has been renamed to `request_code_none!`, `request_code_read!`,
8943 -+ `request_code_write!`, and `request_code_readwrite!` respectively. These have also now been exposed
8944 -+ in the documentation.
8945 -+ ([#833](https://github.com/nix-rust/nix/pull/833))
8946 -+- Enabled more `ptrace::Request` definitions for uncommon Linux platforms
8947 -+ ([#892](https://github.com/nix-rust/nix/pull/892))
8948 -+- Emulation of `FD_CLOEXEC` and `O_NONBLOCK` was removed from `socket()`, `accept4()`, and
8949 -+ `socketpair()`.
8950 -+ ([#907](https://github.com/nix-rust/nix/pull/907))
8951 -+
8952 -+### Fixed
8953 -+- Fixed possible panics when using `SigAction::flags` on Linux
8954 -+ ([#869](https://github.com/nix-rust/nix/pull/869))
8955 -+- Properly exposed 460800 and 921600 baud rates on NetBSD
8956 -+ ([#837](https://github.com/nix-rust/nix/pull/837))
8957 -+- Fixed `ioctl_write_int!` on FreeBSD/DragonFlyBSD
8958 -+ ([#833](https://github.com/nix-rust/nix/pull/833))
8959 -+- `ioctl_write_int!` now properly supports passing a `c_ulong` as the parameter on Linux non-musl targets
8960 -+ ([#833](https://github.com/nix-rust/nix/pull/833))
8961 -+
8962 -+### Removed
8963 -+- Removed explicit support for the `bytes` crate from the `sys::aio` module.
8964 -+ See `sys::aio::AioCb::from_boxed_slice` examples for alternatives.
8965 -+ ([#872](https://github.com/nix-rust/nix/pull/872))
8966 -+- Removed `sys::aio::lio_listio`. Use `sys::aio::LioCb::listio` instead.
8967 -+ ([#872](https://github.com/nix-rust/nix/pull/872))
8968 -+- Removed emulated `accept4()` from macos, ios, and netbsd targets
8969 -+ ([#907](https://github.com/nix-rust/nix/pull/907))
8970 -+- Removed `IFF_NOTRAILERS` on OpenBSD, as it has been removed in OpenBSD 6.3
8971 -+ ([#893](https://github.com/nix-rust/nix/pull/893))
8972 -+
8973 -+## [0.10.0] 2018-01-26
8974 -+
8975 -+### Added
8976 -+- Added specialized wrapper: `sys::ptrace::step`
8977 -+ ([#852](https://github.com/nix-rust/nix/pull/852))
8978 -+- Added `AioCb::from_ptr` and `AioCb::from_mut_ptr`
8979 -+ ([#820](https://github.com/nix-rust/nix/pull/820))
8980 -+- Added specialized wrappers: `sys::ptrace::{traceme, syscall, cont, attach}`. Using the matching routines
8981 -+ with `sys::ptrace::ptrace` is now deprecated.
8982 -+- Added `nix::poll` module for all platforms
8983 -+ ([#672](https://github.com/nix-rust/nix/pull/672))
8984 -+- Added `nix::ppoll` function for FreeBSD and DragonFly
8985 -+ ([#672](https://github.com/nix-rust/nix/pull/672))
8986 -+- Added protocol families in `AddressFamily` enum.
8987 -+ ([#647](https://github.com/nix-rust/nix/pull/647))
8988 -+- Added the `pid()` method to `WaitStatus` for extracting the PID.
8989 -+ ([#722](https://github.com/nix-rust/nix/pull/722))
8990 -+- Added `nix::unistd:fexecve`.
8991 -+ ([#727](https://github.com/nix-rust/nix/pull/727))
8992 -+- Expose `uname()` on all platforms.
8993 -+ ([#739](https://github.com/nix-rust/nix/pull/739))
8994 -+- Expose `signalfd` module on Android as well.
8995 -+ ([#739](https://github.com/nix-rust/nix/pull/739))
8996 -+- Added `nix::sys::ptrace::detach`.
8997 -+ ([#749](https://github.com/nix-rust/nix/pull/749))
8998 -+- Added timestamp socket control message variant:
8999 -+ `nix::sys::socket::ControlMessage::ScmTimestamp`
9000 -+ ([#663](https://github.com/nix-rust/nix/pull/663))
9001 -+- Added socket option variant that enables the timestamp socket
9002 -+ control message: `nix::sys::socket::sockopt::ReceiveTimestamp`
9003 -+ ([#663](https://github.com/nix-rust/nix/pull/663))
9004 -+- Added more accessor methods for `AioCb`
9005 -+ ([#773](https://github.com/nix-rust/nix/pull/773))
9006 -+- Add `nix::sys::fallocate`
9007 -+ ([#768](https:://github.com/nix-rust/nix/pull/768))
9008 -+- Added `nix::unistd::mkfifo`.
9009 -+ ([#602](https://github.com/nix-rust/nix/pull/774))
9010 -+- Added `ptrace::Options::PTRACE_O_EXITKILL` on Linux and Android.
9011 -+ ([#771](https://github.com/nix-rust/nix/pull/771))
9012 -+- Added `nix::sys::uio::{process_vm_readv, process_vm_writev}` on Linux
9013 -+ ([#568](https://github.com/nix-rust/nix/pull/568))
9014 -+- Added `nix::unistd::{getgroups, setgroups, getgrouplist, initgroups}`. ([#733](https://github.com/nix-rust/nix/pull/733))
9015 -+- Added `nix::sys::socket::UnixAddr::as_abstract` on Linux and Android.
9016 -+ ([#785](https://github.com/nix-rust/nix/pull/785))
9017 -+- Added `nix::unistd::execveat` on Linux and Android.
9018 -+ ([#800](https://github.com/nix-rust/nix/pull/800))
9019 -+- Added the `from_raw()` method to `WaitStatus` for converting raw status values
9020 -+ to `WaitStatus` independent of syscalls.
9021 -+ ([#741](https://github.com/nix-rust/nix/pull/741))
9022 -+- Added more standard trait implementations for various types.
9023 -+ ([#814](https://github.com/nix-rust/nix/pull/814))
9024 -+- Added `sigprocmask` to the signal module.
9025 -+ ([#826](https://github.com/nix-rust/nix/pull/826))
9026 -+- Added `nix::sys::socket::LinkAddr` on Linux and all bsdlike system.
9027 -+ ([#813](https://github.com/nix-rust/nix/pull/813))
9028 -+- Add socket options for `IP_TRANSPARENT` / `BIND_ANY`.
9029 -+ ([#835](https://github.com/nix-rust/nix/pull/835))
9030 -+
9031 -+### Changed
9032 -+- Exposed the `mqueue` module for all supported operating systems.
9033 -+ ([#834](https://github.com/nix-rust/nix/pull/834))
9034 -+- Use native `pipe2` on all BSD targets. Users should notice no difference.
9035 -+ ([#777](https://github.com/nix-rust/nix/pull/777))
9036 -+- Renamed existing `ptrace` wrappers to encourage namespacing ([#692](https://github.com/nix-rust/nix/pull/692))
9037 -+- Marked `sys::ptrace::ptrace` as `unsafe`.
9038 -+- Changed function signature of `socket()` and `socketpair()`. The `protocol` argument
9039 -+ has changed type from `c_int` to `SockProtocol`.
9040 -+ It accepts a `None` value for default protocol that was specified with zero using `c_int`.
9041 -+ ([#647](https://github.com/nix-rust/nix/pull/647))
9042 -+- Made `select` easier to use, adding the ability to automatically calculate the `nfds` parameter using the new
9043 -+ `FdSet::highest` ([#701](https://github.com/nix-rust/nix/pull/701))
9044 -+- Exposed `unistd::setresuid` and `unistd::setresgid` on FreeBSD and OpenBSD
9045 -+ ([#721](https://github.com/nix-rust/nix/pull/721))
9046 -+- Refactored the `statvfs` module removing extraneous API functions and the
9047 -+ `statvfs::vfs` module. Additionally `(f)statvfs()` now return the struct
9048 -+ directly. And the returned `Statvfs` struct now exposes its data through
9049 -+ accessor methods. ([#729](https://github.com/nix-rust/nix/pull/729))
9050 -+- The `addr` argument to `madvise` and `msync` is now `*mut` to better match the
9051 -+ libc API. ([#731](https://github.com/nix-rust/nix/pull/731))
9052 -+- `shm_open` and `shm_unlink` are no longer exposed on Android targets, where
9053 -+ they are not officially supported. ([#731](https://github.com/nix-rust/nix/pull/731))
9054 -+- `MapFlags`, `MmapAdvise`, and `MsFlags` expose some more variants and only
9055 -+ officially-supported variants are provided for each target.
9056 -+ ([#731](https://github.com/nix-rust/nix/pull/731))
9057 -+- Marked `pty::ptsname` function as `unsafe`
9058 -+ ([#744](https://github.com/nix-rust/nix/pull/744))
9059 -+- Moved constants ptrace request, event and options to enums and updated ptrace functions and argument types accordingly.
9060 -+ ([#749](https://github.com/nix-rust/nix/pull/749))
9061 -+- `AioCb::Drop` will now panic if the `AioCb` is still in-progress ([#715](https://github.com/nix-rust/nix/pull/715))
9062 -+- Restricted `nix::sys::socket::UnixAddr::new_abstract` to Linux and Android only.
9063 -+ ([#785](https://github.com/nix-rust/nix/pull/785))
9064 -+- The `ucred` struct has been removed in favor of a `UserCredentials` struct that
9065 -+ contains only getters for its fields.
9066 -+ ([#814](https://github.com/nix-rust/nix/pull/814))
9067 -+- Both `ip_mreq` and `ipv6_mreq` have been replaced with `IpMembershipRequest` and
9068 -+ `Ipv6MembershipRequest`.
9069 -+ ([#814](https://github.com/nix-rust/nix/pull/814))
9070 -+- Removed return type from `pause`.
9071 -+ ([#829](https://github.com/nix-rust/nix/pull/829))
9072 -+- Changed the termios APIs to allow for using a `u32` instead of the `BaudRate`
9073 -+ enum on BSD platforms to support arbitrary baud rates. See the module docs for
9074 -+ `nix::sys::termios` for more details.
9075 -+ ([#843](https://github.com/nix-rust/nix/pull/843))
9076 -+
9077 -+### Fixed
9078 -+- Fix compilation and tests for OpenBSD targets
9079 -+ ([#688](https://github.com/nix-rust/nix/pull/688))
9080 -+- Fixed error handling in `AioCb::fsync`, `AioCb::read`, and `AioCb::write`.
9081 -+ It is no longer an error to drop an `AioCb` that failed to enqueue in the OS.
9082 -+ ([#715](https://github.com/nix-rust/nix/pull/715))
9083 -+- Fix potential memory corruption on non-Linux platforms when using
9084 -+ `sendmsg`/`recvmsg`, caused by mismatched `msghdr` definition.
9085 -+ ([#648](https://github.com/nix-rust/nix/pull/648))
9086 -+
9087 -+### Removed
9088 -+- `AioCb::from_boxed_slice` has been removed. It was never actually safe. Use
9089 -+ `from_bytes` or `from_bytes_mut` instead.
9090 -+ ([#820](https://github.com/nix-rust/nix/pull/820))
9091 -+- The syscall module has been removed. This only exposed enough functionality for
9092 -+ `memfd_create()` and `pivot_root()`, which are still exposed as separate functions.
9093 -+ ([#747](https://github.com/nix-rust/nix/pull/747))
9094 -+- The `Errno` variants are no longer reexported from the `errno` module. `Errno` itself is no longer reexported from the
9095 -+ crate root and instead must be accessed using the `errno` module. ([#696](https://github.com/nix-rust/nix/pull/696))
9096 -+- Removed `MS_VERBOSE`, `MS_NOSEC`, and `MS_BORN` from `MsFlags`. These
9097 -+ are internal kernel flags and should never have been exposed.
9098 -+ ([#814](https://github.com/nix-rust/nix/pull/814))
9099 -+
9100 -+
9101 -+## [0.9.0] 2017-07-23
9102 -+
9103 -+### Added
9104 -+- Added `sysconf`, `pathconf`, and `fpathconf`
9105 -+ ([#630](https://github.com/nix-rust/nix/pull/630)
9106 -+- Added `sys::signal::SigAction::{ flags, mask, handler}`
9107 -+ ([#611](https://github.com/nix-rust/nix/pull/609)
9108 -+- Added `nix::sys::pthread::pthread_self`
9109 -+ ([#591](https://github.com/nix-rust/nix/pull/591)
9110 -+- Added `AioCb::from_boxed_slice`
9111 -+ ([#582](https://github.com/nix-rust/nix/pull/582)
9112 -+- Added `nix::unistd::{openat, fstatat, readlink, readlinkat}`
9113 -+ ([#551](https://github.com/nix-rust/nix/pull/551))
9114 -+- Added `nix::pty::{grantpt, posix_openpt, ptsname/ptsname_r, unlockpt}`
9115 -+ ([#556](https://github.com/nix-rust/nix/pull/556)
9116 -+- Added `nix::ptr::openpty`
9117 -+ ([#456](https://github.com/nix-rust/nix/pull/456))
9118 -+- Added `nix::ptrace::{ptrace_get_data, ptrace_getsiginfo, ptrace_setsiginfo
9119 -+ and nix::Error::UnsupportedOperation}`
9120 -+ ([#614](https://github.com/nix-rust/nix/pull/614))
9121 -+- Added `cfmakeraw`, `cfsetspeed`, and `tcgetsid`. ([#527](https://github.com/nix-rust/nix/pull/527))
9122 -+- Added "bad none", "bad write_ptr", "bad write_int", and "bad readwrite" variants to the `ioctl!`
9123 -+ macro. ([#670](https://github.com/nix-rust/nix/pull/670))
9124 -+- On Linux and Android, added support for receiving `PTRACE_O_TRACESYSGOOD`
9125 -+ events from `wait` and `waitpid` using `WaitStatus::PtraceSyscall`
9126 -+ ([#566](https://github.com/nix-rust/nix/pull/566)).
9127 -+
9128 -+### Changed
9129 -+- The `ioctl!` macro and its variants now allow the generated functions to have
9130 -+ doccomments. ([#661](https://github.com/nix-rust/nix/pull/661))
9131 -+- Changed `ioctl!(write ...)` into `ioctl!(write_ptr ...)` and `ioctl!(write_int ..)` variants
9132 -+ to more clearly separate those use cases. ([#670](https://github.com/nix-rust/nix/pull/670))
9133 -+- Marked `sys::mman::{ mmap, munmap, madvise, munlock, msync }` as unsafe.
9134 -+ ([#559](https://github.com/nix-rust/nix/pull/559))
9135 -+- Minimum supported Rust version is now 1.13.
9136 -+- Removed `revents` argument from `PollFd::new()` as it's an output argument and
9137 -+ will be overwritten regardless of value.
9138 -+ ([#542](https://github.com/nix-rust/nix/pull/542))
9139 -+- Changed type signature of `sys::select::FdSet::contains` to make `self`
9140 -+ immutable ([#564](https://github.com/nix-rust/nix/pull/564))
9141 -+- Introduced wrapper types for `gid_t`, `pid_t`, and `uid_t` as `Gid`, `Pid`, and `Uid`
9142 -+ respectively. Various functions have been changed to use these new types as
9143 -+ arguments. ([#629](https://github.com/nix-rust/nix/pull/629))
9144 -+- Fixed compilation on all Android and iOS targets ([#527](https://github.com/nix-rust/nix/pull/527))
9145 -+ and promoted them to Tier 2 support.
9146 -+- `nix::sys::statfs::{statfs,fstatfs}` uses statfs definition from `libc::statfs` instead of own linux specific type `nix::sys::Statfs`.
9147 -+ Also file system type constants like `nix::sys::statfs::ADFS_SUPER_MAGIC` were removed in favor of the libc equivalent.
9148 -+ ([#561](https://github.com/nix-rust/nix/pull/561))
9149 -+- Revised the termios API including additional tests and documentation and exposed it on iOS. ([#527](https://github.com/nix-rust/nix/pull/527))
9150 -+- `eventfd`, `signalfd`, and `pwritev`/`preadv` functionality is now included by default for all
9151 -+ supported platforms. ([#681](https://github.com/nix-rust/nix/pull/561))
9152 -+- The `ioctl!` macro's plain variants has been replaced with "bad read" to be consistent with
9153 -+ other variants. The generated functions also have more strict types for their arguments. The
9154 -+ "*_buf" variants also now calculate total array size and take slice references for improved type
9155 -+ safety. The documentation has also been dramatically improved.
9156 -+ ([#670](https://github.com/nix-rust/nix/pull/670))
9157 -+
9158 -+### Removed
9159 -+- Removed `io::Error` from `nix::Error` and the conversion from `nix::Error` to `Errno`
9160 -+ ([#614](https://github.com/nix-rust/nix/pull/614))
9161 -+- All feature flags have been removed in favor of conditional compilation on supported platforms.
9162 -+ `execvpe` is no longer supported, but this was already broken and will be added back in the next
9163 -+ release. ([#681](https://github.com/nix-rust/nix/pull/561))
9164 -+- Removed `ioc_*` functions and many helper constants and macros within the `ioctl` module. These
9165 -+ should always have been private and only the `ioctl!` should be used in public code.
9166 -+ ([#670](https://github.com/nix-rust/nix/pull/670))
9167 -+
9168 -+### Fixed
9169 -+- Fixed multiple issues compiling under different archetectures and OSes.
9170 -+ Now compiles on Linux/MIPS ([#538](https://github.com/nix-rust/nix/pull/538)),
9171 -+ `Linux/PPC` ([#553](https://github.com/nix-rust/nix/pull/553)),
9172 -+ `MacOS/x86_64,i686` ([#553](https://github.com/nix-rust/nix/pull/553)),
9173 -+ `NetBSD/x64_64` ([#538](https://github.com/nix-rust/nix/pull/538)),
9174 -+ `FreeBSD/x86_64,i686` ([#536](https://github.com/nix-rust/nix/pull/536)), and
9175 -+ `Android` ([#631](https://github.com/nix-rust/nix/pull/631)).
9176 -+- `bind` and `errno_location` now work correctly on `Android`
9177 -+ ([#631](https://github.com/nix-rust/nix/pull/631))
9178 -+- Added `nix::ptrace` on all Linux-kernel-based platforms
9179 -+ [#624](https://github.com/nix-rust/nix/pull/624). Previously it was
9180 -+ only available on x86, x86-64, and ARM, and also not on Android.
9181 -+- Fixed `sys::socket::sendmsg` with zero entry `cmsgs` parameter.
9182 -+ ([#623](https://github.com/nix-rust/nix/pull/623))
9183 -+- Multiple constants related to the termios API have now been properly defined for
9184 -+ all supported platforms. ([#527](https://github.com/nix-rust/nix/pull/527))
9185 -+- `ioctl!` macro now supports working with non-int datatypes and properly supports all platforms.
9186 -+ ([#670](https://github.com/nix-rust/nix/pull/670))
9187 -+
9188 -+## [0.8.1] 2017-04-16
9189 -+
9190 -+### Fixed
9191 -+- Fixed build on FreeBSD. (Cherry-picked
9192 -+ [a859ee3c](https://github.com/nix-rust/nix/commit/a859ee3c9396dfdb118fcc2c8ecc697e2d303467))
9193 -+
9194 -+## [0.8.0] 2017-03-02
9195 -+
9196 -+### Added
9197 -+- Added `::nix::sys::termios::BaudRate` enum to provide portable baudrate
9198 -+ values. ([#518](https://github.com/nix-rust/nix/pull/518))
9199 -+- Added a new `WaitStatus::PtraceEvent` to support ptrace events on Linux
9200 -+ and Android ([#438](https://github.com/nix-rust/nix/pull/438))
9201 -+- Added support for POSIX AIO
9202 -+ ([#483](https://github.com/nix-rust/nix/pull/483))
9203 -+ ([#506](https://github.com/nix-rust/nix/pull/506))
9204 -+- Added support for XNU system control sockets
9205 -+ ([#478](https://github.com/nix-rust/nix/pull/478))
9206 -+- Added support for `ioctl` calls on BSD platforms
9207 -+ ([#478](https://github.com/nix-rust/nix/pull/478))
9208 -+- Added struct `TimeSpec`
9209 -+ ([#475](https://github.com/nix-rust/nix/pull/475))
9210 -+ ([#483](https://github.com/nix-rust/nix/pull/483))
9211 -+- Added complete definitions for all kqueue-related constants on all supported
9212 -+ OSes
9213 -+ ([#415](https://github.com/nix-rust/nix/pull/415))
9214 -+- Added function `epoll_create1` and bitflags `EpollCreateFlags` in
9215 -+ `::nix::sys::epoll` in order to support `::libc::epoll_create1`.
9216 -+ ([#410](https://github.com/nix-rust/nix/pull/410))
9217 -+- Added `setresuid` and `setresgid` for Linux in `::nix::unistd`
9218 -+ ([#448](https://github.com/nix-rust/nix/pull/448))
9219 -+- Added `getpgid` in `::nix::unistd`
9220 -+ ([#433](https://github.com/nix-rust/nix/pull/433))
9221 -+- Added `tcgetpgrp` and `tcsetpgrp` in `::nix::unistd`
9222 -+ ([#451](https://github.com/nix-rust/nix/pull/451))
9223 -+- Added `CLONE_NEWCGROUP` in `::nix::sched`
9224 -+ ([#457](https://github.com/nix-rust/nix/pull/457))
9225 -+- Added `getpgrp` in `::nix::unistd`
9226 -+ ([#491](https://github.com/nix-rust/nix/pull/491))
9227 -+- Added `fchdir` in `::nix::unistd`
9228 -+ ([#497](https://github.com/nix-rust/nix/pull/497))
9229 -+- Added `major` and `minor` in `::nix::sys::stat` for decomposing `dev_t`
9230 -+ ([#508](https://github.com/nix-rust/nix/pull/508))
9231 -+- Fixed the style of many bitflags and use `libc` in more places.
9232 -+ ([#503](https://github.com/nix-rust/nix/pull/503))
9233 -+- Added `ppoll` in `::nix::poll`
9234 -+ ([#520](https://github.com/nix-rust/nix/pull/520))
9235 -+- Added support for getting and setting pipe size with fcntl(2) on Linux
9236 -+ ([#540](https://github.com/nix-rust/nix/pull/540))
9237 -+
9238 -+### Changed
9239 -+- `::nix::sys::termios::{cfgetispeed, cfsetispeed, cfgetospeed, cfsetospeed}`
9240 -+ switched to use `BaudRate` enum from `speed_t`.
9241 -+ ([#518](https://github.com/nix-rust/nix/pull/518))
9242 -+- `epoll_ctl` now could accept None as argument `event`
9243 -+ when op is `EpollOp::EpollCtlDel`.
9244 -+ ([#480](https://github.com/nix-rust/nix/pull/480))
9245 -+- Removed the `bad` keyword from the `ioctl!` macro
9246 -+ ([#478](https://github.com/nix-rust/nix/pull/478))
9247 -+- Changed `TimeVal` into an opaque Newtype
9248 -+ ([#475](https://github.com/nix-rust/nix/pull/475))
9249 -+- `kill`'s signature, defined in `::nix::sys::signal`, changed, so that the
9250 -+ signal parameter has type `T: Into<Option<Signal>>`. `None` as an argument
9251 -+ for that parameter will result in a 0 passed to libc's `kill`, while a
9252 -+ `Some`-argument will result in the previous behavior for the contained
9253 -+ `Signal`.
9254 -+ ([#445](https://github.com/nix-rust/nix/pull/445))
9255 -+- The minimum supported version of rustc is now 1.7.0.
9256 -+ ([#444](https://github.com/nix-rust/nix/pull/444))
9257 -+- Changed `KEvent` to an opaque structure that may only be modified by its
9258 -+ constructor and the `ev_set` method.
9259 -+ ([#415](https://github.com/nix-rust/nix/pull/415))
9260 -+ ([#442](https://github.com/nix-rust/nix/pull/442))
9261 -+ ([#463](https://github.com/nix-rust/nix/pull/463))
9262 -+- `pipe2` now calls `libc::pipe2` where available. Previously it was emulated
9263 -+ using `pipe`, which meant that setting `O_CLOEXEC` was not atomic.
9264 -+ ([#427](https://github.com/nix-rust/nix/pull/427))
9265 -+- Renamed `EpollEventKind` to `EpollFlags` in `::nix::sys::epoll` in order for
9266 -+ it to conform with our conventions.
9267 -+ ([#410](https://github.com/nix-rust/nix/pull/410))
9268 -+- `EpollEvent` in `::nix::sys::epoll` is now an opaque proxy for
9269 -+ `::libc::epoll_event`. The formerly public field `events` is now be read-only
9270 -+ accessible with the new method `events()` of `EpollEvent`. Instances of
9271 -+ `EpollEvent` can be constructed using the new method `new()` of EpollEvent.
9272 -+ ([#410](https://github.com/nix-rust/nix/pull/410))
9273 -+- `SigFlags` in `::nix::sys::signal` has be renamed to `SigmaskHow` and its type
9274 -+ has changed from `bitflags` to `enum` in order to conform to our conventions.
9275 -+ ([#460](https://github.com/nix-rust/nix/pull/460))
9276 -+- `sethostname` now takes a `&str` instead of a `&[u8]` as this provides an API
9277 -+ that makes more sense in normal, correct usage of the API.
9278 -+- `gethostname` previously did not expose the actual length of the hostname
9279 -+ written from the underlying system call at all. This has been updated to
9280 -+ return a `&CStr` within the provided buffer that is always properly
9281 -+ NUL-terminated (this is not guaranteed by the call with all platforms/libc
9282 -+ implementations).
9283 -+- Exposed all fcntl(2) operations at the module level, so they can be
9284 -+ imported direclty instead of via `FcntlArg` enum.
9285 -+ ([#541](https://github.com/nix-rust/nix/pull/541))
9286 -+
9287 -+### Fixed
9288 -+- Fixed multiple issues with Unix domain sockets on non-Linux OSes
9289 -+ ([#474](https://github.com/nix-rust/nix/pull/415))
9290 -+- Fixed using kqueue with `EVFILT_USER` on FreeBSD
9291 -+ ([#415](https://github.com/nix-rust/nix/pull/415))
9292 -+- Fixed the build on FreeBSD, and fixed the getsockopt, sendmsg, and recvmsg
9293 -+ functions on that same OS.
9294 -+ ([#397](https://github.com/nix-rust/nix/pull/397))
9295 -+- Fixed an off-by-one bug in `UnixAddr::new_abstract` in `::nix::sys::socket`.
9296 -+ ([#429](https://github.com/nix-rust/nix/pull/429))
9297 -+- Fixed clone passing a potentially unaligned stack.
9298 -+ ([#490](https://github.com/nix-rust/nix/pull/490))
9299 -+- Fixed mkdev not creating a `dev_t` the same way as libc.
9300 -+ ([#508](https://github.com/nix-rust/nix/pull/508))
9301 -+
9302 -+## [0.7.0] 2016-09-09
9303 -+
9304 -+### Added
9305 -+- Added `lseek` and `lseek64` in `::nix::unistd`
9306 -+ ([#377](https://github.com/nix-rust/nix/pull/377))
9307 -+- Added `mkdir` and `getcwd` in `::nix::unistd`
9308 -+ ([#416](https://github.com/nix-rust/nix/pull/416))
9309 -+- Added accessors `sigmask_mut` and `sigmask` to `UContext` in
9310 -+ `::nix::ucontext`.
9311 -+ ([#370](https://github.com/nix-rust/nix/pull/370))
9312 -+- Added `WUNTRACED` to `WaitPidFlag` in `::nix::sys::wait` for non-_linux_
9313 -+ targets.
9314 -+ ([#379](https://github.com/nix-rust/nix/pull/379))
9315 -+- Added new module `::nix::sys::reboot` with enumeration `RebootMode` and
9316 -+ functions `reboot` and `set_cad_enabled`. Currently for _linux_ only.
9317 -+ ([#386](https://github.com/nix-rust/nix/pull/386))
9318 -+- `FdSet` in `::nix::sys::select` now also implements `Clone`.
9319 -+ ([#405](https://github.com/nix-rust/nix/pull/405))
9320 -+- Added `F_FULLFSYNC` to `FcntlArg` in `::nix::fcntl` for _apple_ targets.
9321 -+ ([#407](https://github.com/nix-rust/nix/pull/407))
9322 -+- Added `CpuSet::unset` in `::nix::sched`.
9323 -+ ([#402](https://github.com/nix-rust/nix/pull/402))
9324 -+- Added constructor method `new()` to `PollFd` in `::nix::poll`, in order to
9325 -+ allow creation of objects, after removing public access to members.
9326 -+ ([#399](https://github.com/nix-rust/nix/pull/399))
9327 -+- Added method `revents()` to `PollFd` in `::nix::poll`, in order to provide
9328 -+ read access to formerly public member `revents`.
9329 -+ ([#399](https://github.com/nix-rust/nix/pull/399))
9330 -+- Added `MSG_CMSG_CLOEXEC` to `MsgFlags` in `::nix::sys::socket` for _linux_ only.
9331 -+ ([#422](https://github.com/nix-rust/nix/pull/422))
9332 -+
9333 -+### Changed
9334 -+- Replaced the reexported integer constants for signals by the enumeration
9335 -+ `Signal` in `::nix::sys::signal`.
9336 -+ ([#362](https://github.com/nix-rust/nix/pull/362))
9337 -+- Renamed `EventFdFlag` to `EfdFlags` in `::nix::sys::eventfd`.
9338 -+ ([#383](https://github.com/nix-rust/nix/pull/383))
9339 -+- Changed the result types of `CpuSet::is_set` and `CpuSet::set` in
9340 -+ `::nix::sched` to `Result<bool>` and `Result<()>`, respectively. They now
9341 -+ return `EINVAL`, if an invalid argument for the `field` parameter is passed.
9342 -+ ([#402](https://github.com/nix-rust/nix/pull/402))
9343 -+- `MqAttr` in `::nix::mqueue` is now an opaque proxy for `::libc::mq_attr`,
9344 -+ which has the same structure as the old `MqAttr`. The field `mq_flags` of
9345 -+ `::libc::mq_attr` is readable using the new method `flags()` of `MqAttr`.
9346 -+ `MqAttr` also no longer implements `Debug`.
9347 -+ ([#392](https://github.com/nix-rust/nix/pull/392))
9348 -+- The parameter `msq_prio` of `mq_receive` with type `u32` in `::nix::mqueue`
9349 -+ was replaced by a parameter named `msg_prio` with type `&mut u32`, so that
9350 -+ the message priority can be obtained by the caller.
9351 -+ ([#392](https://github.com/nix-rust/nix/pull/392))
9352 -+- The type alias `MQd` in `::nix::queue` was replaced by the type alias
9353 -+ `libc::mqd_t`, both of which are aliases for the same type.
9354 -+ ([#392](https://github.com/nix-rust/nix/pull/392))
9355 -+
9356 -+### Removed
9357 -+- Type alias `SigNum` from `::nix::sys::signal`.
9358 -+ ([#362](https://github.com/nix-rust/nix/pull/362))
9359 -+- Type alias `CpuMask` from `::nix::shed`.
9360 -+ ([#402](https://github.com/nix-rust/nix/pull/402))
9361 -+- Removed public fields from `PollFd` in `::nix::poll`. (See also added method
9362 -+ `revents()`.
9363 -+ ([#399](https://github.com/nix-rust/nix/pull/399))
9364 -+
9365 -+### Fixed
9366 -+- Fixed the build problem for NetBSD (Note, that we currently do not support
9367 -+ it, so it might already be broken again).
9368 -+ ([#389](https://github.com/nix-rust/nix/pull/389))
9369 -+- Fixed the build on FreeBSD, and fixed the getsockopt, sendmsg, and recvmsg
9370 -+ functions on that same OS.
9371 -+ ([#397](https://github.com/nix-rust/nix/pull/397))
9372 -+
9373 -+## [0.6.0] 2016-06-10
9374 -+
9375 -+### Added
9376 -+- Added `gettid` in `::nix::unistd` for _linux_ and _android_.
9377 -+ ([#293](https://github.com/nix-rust/nix/pull/293))
9378 -+- Some _mips_ support in `::nix::sched` and `::nix::sys::syscall`.
9379 -+ ([#301](https://github.com/nix-rust/nix/pull/301))
9380 -+- Added `SIGNALFD_SIGINFO_SIZE` in `::nix::sys::signalfd`.
9381 -+ ([#309](https://github.com/nix-rust/nix/pull/309))
9382 -+- Added new module `::nix::ucontext` with struct `UContext`. Currently for
9383 -+ _linux_ only.
9384 -+ ([#311](https://github.com/nix-rust/nix/pull/311))
9385 -+- Added `EPOLLEXCLUSIVE` to `EpollEventKind` in `::nix::sys::epoll`.
9386 -+ ([#330](https://github.com/nix-rust/nix/pull/330))
9387 -+- Added `pause` to `::nix::unistd`.
9388 -+ ([#336](https://github.com/nix-rust/nix/pull/336))
9389 -+- Added `sleep` to `::nix::unistd`.
9390 -+ ([#351](https://github.com/nix-rust/nix/pull/351))
9391 -+- Added `S_IFDIR`, `S_IFLNK`, `S_IFMT` to `SFlag` in `::nix::sys::stat`.
9392 -+ ([#359](https://github.com/nix-rust/nix/pull/359))
9393 -+- Added `clear` and `extend` functions to `SigSet`'s implementation in
9394 -+ `::nix::sys::signal`.
9395 -+ ([#347](https://github.com/nix-rust/nix/pull/347))
9396 -+- `sockaddr_storage_to_addr` in `::nix::sys::socket` now supports `sockaddr_nl`
9397 -+ on _linux_ and _android_.
9398 -+ ([#366](https://github.com/nix-rust/nix/pull/366))
9399 -+- Added support for `SO_ORIGINAL_DST` in `::nix::sys::socket` on _linux_.
9400 -+ ([#367](https://github.com/nix-rust/nix/pull/367))
9401 -+- Added `SIGINFO` in `::nix::sys::signal` for the _macos_ target as well as
9402 -+ `SIGPWR` and `SIGSTKFLT` in `::nix::sys::signal` for non-_macos_ targets.
9403 -+ ([#361](https://github.com/nix-rust/nix/pull/361))
9404 -+
9405 -+### Changed
9406 -+- Changed the structure `IoVec` in `::nix::sys::uio`.
9407 -+ ([#304](https://github.com/nix-rust/nix/pull/304))
9408 -+- Replaced `CREATE_NEW_FD` by `SIGNALFD_NEW` in `::nix::sys::signalfd`.
9409 -+ ([#309](https://github.com/nix-rust/nix/pull/309))
9410 -+- Renamed `SaFlag` to `SaFlags` and `SigFlag` to `SigFlags` in
9411 -+ `::nix::sys::signal`.
9412 -+ ([#314](https://github.com/nix-rust/nix/pull/314))
9413 -+- Renamed `Fork` to `ForkResult` and changed its fields in `::nix::unistd`.
9414 -+ ([#332](https://github.com/nix-rust/nix/pull/332))
9415 -+- Added the `signal` parameter to `clone`'s signature in `::nix::sched`.
9416 -+ ([#344](https://github.com/nix-rust/nix/pull/344))
9417 -+- `execv`, `execve`, and `execvp` now return `Result<Void>` instead of
9418 -+ `Result<()>` in `::nix::unistd`.
9419 -+ ([#357](https://github.com/nix-rust/nix/pull/357))
9420 -+
9421 -+### Fixed
9422 -+- Improved the conversion from `std::net::SocketAddr` to `InetAddr` in
9423 -+ `::nix::sys::socket::addr`.
9424 -+ ([#335](https://github.com/nix-rust/nix/pull/335))
9425 -+
9426 -+## [0.5.0] 2016-03-01
9427 -diff --git a/third_party/rust/nix-0.15.0/CONTRIBUTING.md b/third_party/rust/nix-0.15.0/CONTRIBUTING.md
9428 -new file mode 100644
9429 -index 0000000000000..03a1f630dbb06
9430 ---- /dev/null
9431 -+++ b/third_party/rust/nix-0.15.0/CONTRIBUTING.md
9432 -@@ -0,0 +1,114 @@
9433 -+# Contributing to nix
9434 -+
9435 -+We're really glad you're interested in contributing to nix! This
9436 -+document has a few pointers and guidelines to help get you started.
9437 -+
9438 -+To have a welcoming and inclusive project, nix uses the Rust project's
9439 -+[Code of Conduct][conduct]. All contributors are expected to follow it.
9440 -+
9441 -+[conduct]: https://www.rust-lang.org/conduct.html
9442 -+
9443 -+
9444 -+# Issues
9445 -+
9446 -+We use GitHub's [issue tracker][issues].
9447 -+
9448 -+[issues]: https://github.com/nix-rust/nix/issues
9449 -+
9450 -+
9451 -+## Bug reports
9452 -+
9453 -+Before submitting a new bug report, please [search existing
9454 -+issues][issue-search] to see if there's something related. If not, just
9455 -+[open a new issue][new-issue]!
9456 -+
9457 -+As a reminder, the more information you can give in your issue, the
9458 -+easier it is to figure out how to fix it. For nix, this will likely
9459 -+include the OS and version, and the architecture.
9460 -+
9461 -+[issue-search]: https://github.com/nix-rust/nix/search?utf8=%E2%9C%93&q=is%3Aissue&type=Issues
9462 -+[new-issue]: https://github.com/nix-rust/nix/issues/new
9463 -+
9464 -+
9465 -+## Feature / API requests
9466 -+
9467 -+If you'd like a new API or feature added, please [open a new
9468 -+issue][new-issue] requesting it. As with reporting a bug, the more
9469 -+information you can provide, the better.
9470 -+
9471 -+
9472 -+## Labels
9473 -+
9474 -+We use labels to help manage issues. The structure is modeled after
9475 -+[Rust's issue labeling scheme][rust-labels]:
9476 -+- **A-**prefixed labels state which area of the project the issue
9477 -+ relates to
9478 -+- **E-**prefixed labels explain the level of experience necessary to fix the
9479 -+ issue
9480 -+- **O-**prefixed labels specify the OS for issues that are OS-specific
9481 -+- **R-**prefixed labels specify the architecture for issues that are
9482 -+ architecture-specific
9483 -+
9484 -+[rust-labels]: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#issue-triage
9485 -+
9486 -+
9487 -+# Pull requests
9488 -+
9489 -+GitHub pull requests are the primary mechanism we use to change nix. GitHub itself has
9490 -+some [great documentation][pr-docs] on using the Pull Request feature. We use the 'fork and
9491 -+pull' model described there.
9492 -+
9493 -+Please make pull requests against the `master` branch.
9494 -+
9495 -+If you change the API by way of adding, removing or changing something or if
9496 -+you fix a bug, please add an appropriate note to the [change log][cl]. We
9497 -+follow the conventions of [Keep A CHANGELOG][kacl].
9498 -+
9499 -+[cl]: https://github.com/nix-rust/nix/blob/master/CHANGELOG.md
9500 -+[kacl]: https://github.com/olivierlacan/keep-a-changelog/tree/18adb5f5be7a898d046f6a4acb93e39dcf40c4ad
9501 -+[pr-docs]: https://help.github.com/articles/using-pull-requests/
9502 -+
9503 -+## Testing
9504 -+
9505 -+nix has a test suite that you can run with `cargo test`. Ideally, we'd like pull
9506 -+requests to include tests where they make sense. For example, when fixing a bug,
9507 -+add a test that would have failed without the fix.
9508 -+
9509 -+After you've made your change, make sure the tests pass in your development
9510 -+environment. We also have [continuous integration set up on
9511 -+Travis-CI][travis-ci], which might find some issues on other platforms. The CI
9512 -+will run once you open a pull request.
9513 -+
9514 -+There is also infrastructure for running tests for other targets
9515 -+locally. More information is available in the [CI Readme][ci-readme].
9516 -+
9517 -+[travis-ci]: https://travis-ci.org/nix-rust/nix
9518 -+[ci-readme]: ci/README.md
9519 -+
9520 -+### Disabling a test in the CI environment
9521 -+
9522 -+Sometimes there are features that cannot be tested in the CI environment.
9523 -+To stop a test from running under CI, add `#[cfg_attr(travis, ignore)]`
9524 -+to it. Please include a comment describing the reason it shouldn't run
9525 -+under CI, and a link to an upstream issue if possible!
9526 -+
9527 -+## bors, the bot who merges all the PRs
9528 -+
9529 -+All pull requests are merged via [bors], an integration bot. After the
9530 -+pull request has been reviewed, the reviewer will leave a comment like
9531 -+
9532 -+> bors r+
9533 -+
9534 -+to let bors know that it was approved. Then bors will check that it passes
9535 -+tests when merged with the latest changes in the `master` branch, and
9536 -+merge if the tests succeed.
9537 -+
9538 -+[bors]: https://bors-ng.github.io/
9539 -+
9540 -+
9541 -+## API conventions
9542 -+
9543 -+If you're adding a new API, we have a [document with
9544 -+conventions][conventions] to use throughout the nix project.
9545 -+
9546 -+[conventions]: https://github.com/nix-rust/nix/blob/master/CONVENTIONS.md
9547 -diff --git a/third_party/rust/nix-0.15.0/CONVENTIONS.md b/third_party/rust/nix-0.15.0/CONVENTIONS.md
9548 -new file mode 100644
9549 -index 0000000000000..48daa937345d2
9550 ---- /dev/null
9551 -+++ b/third_party/rust/nix-0.15.0/CONVENTIONS.md
9552 -@@ -0,0 +1,87 @@
9553 -+# Conventions
9554 -+
9555 -+In order to achieve our goal of wrapping [libc][libc] code in idiomatic rust
9556 -+constructs with minimal performance overhead, we follow the following
9557 -+conventions.
9558 -+
9559 -+Note that, thus far, not all the code follows these conventions and not all
9560 -+conventions we try to follow have been documented here. If you find an instance
9561 -+of either, feel free to remedy the flaw by opening a pull request with
9562 -+appropriate changes or additions.
9563 -+
9564 -+## Change Log
9565 -+
9566 -+We follow the conventions laid out in [Keep A CHANGELOG][kacl].
9567 -+
9568 -+[kacl]: https://github.com/olivierlacan/keep-a-changelog/tree/18adb5f5be7a898d046f6a4acb93e39dcf40c4ad
9569 -+
9570 -+## libc constants, functions and structs
9571 -+
9572 -+We do not define integer constants ourselves, but use or reexport them from the
9573 -+[libc crate][libc].
9574 -+
9575 -+We use the functions exported from [libc][libc] instead of writing our own
9576 -+`extern` declarations.
9577 -+
9578 -+We use the `struct` definitions from [libc][libc] internally instead of writing
9579 -+our own. If we want to add methods to a libc type, we use the newtype pattern.
9580 -+For example,
9581 -+
9582 -+```rust
9583 -+pub struct SigSet(libc::sigset_t);
9584 -+
9585 -+impl SigSet {
9586 -+ ...
9587 -+}
9588 -+```
9589 -+
9590 -+When creating newtypes, we use Rust's `CamelCase` type naming convention.
9591 -+
9592 -+## Bitflags
9593 -+
9594 -+Many C functions have flags parameters that are combined from constants using
9595 -+bitwise operations. We represent the types of these parameters by types defined
9596 -+using our `libc_bitflags!` macro, which is a convenience wrapper around the
9597 -+`bitflags!` macro from the [bitflags crate][bitflags] that brings in the
9598 -+constant value from `libc`.
9599 -+
9600 -+We name the type for a set of constants whose element's names start with `FOO_`
9601 -+`FooFlags`.
9602 -+
9603 -+For example,
9604 -+
9605 -+```rust
9606 -+libc_bitflags!{
9607 -+ pub struct ProtFlags: libc::c_int {
9608 -+ PROT_NONE;
9609 -+ PROT_READ;
9610 -+ PROT_WRITE;
9611 -+ PROT_EXEC;
9612 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
9613 -+ PROT_GROWSDOWN;
9614 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
9615 -+ PROT_GROWSUP;
9616 -+ }
9617 -+}
9618 -+```
9619 -+
9620 -+
9621 -+## Enumerations
9622 -+
9623 -+We represent sets of constants that are intended as mutually exclusive arguments
9624 -+to parameters of functions by [enumerations][enum].
9625 -+
9626 -+
9627 -+## Structures Initialized by libc Functions
9628 -+
9629 -+Whenever we need to use a [libc][libc] function to properly initialize a
9630 -+variable and said function allows us to use uninitialized memory, we use
9631 -+[`std::mem::uninitialized`][std_uninitialized] (or [`core::mem::uninitialized`][core_uninitialized])
9632 -+when defining the variable. This allows us to avoid the overhead incurred by
9633 -+zeroing or otherwise initializing the variable.
9634 -+
9635 -+[bitflags]: https://crates.io/crates/bitflags/
9636 -+[core_uninitialized]: https://doc.rust-lang.org/core/mem/fn.uninitialized.html
9637 -+[enum]: https://doc.rust-lang.org/reference.html#enumerations
9638 -+[libc]: https://crates.io/crates/libc/
9639 -+[std_uninitialized]: https://doc.rust-lang.org/std/mem/fn.uninitialized.html
9640 -diff --git a/third_party/rust/nix-0.15.0/Cargo.toml b/third_party/rust/nix-0.15.0/Cargo.toml
9641 -new file mode 100644
9642 -index 0000000000000..555b99020d68f
9643 ---- /dev/null
9644 -+++ b/third_party/rust/nix-0.15.0/Cargo.toml
9645 -@@ -0,0 +1,71 @@
9646 -+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
9647 -+#
9648 -+# When uploading crates to the registry Cargo will automatically
9649 -+# "normalize" Cargo.toml files for maximal compatibility
9650 -+# with all versions of Cargo and also rewrite `path` dependencies
9651 -+# to registry (e.g., crates.io) dependencies
9652 -+#
9653 -+# If you believe there's an error in this file please file an
9654 -+# issue against the rust-lang/cargo repository. If you're
9655 -+# editing this file be aware that the upstream Cargo.toml
9656 -+# will likely look very different (and much more reasonable)
9657 -+
9658 -+[package]
9659 -+name = "nix"
9660 -+version = "0.15.0"
9661 -+authors = ["The nix-rust Project Developers"]
9662 -+exclude = ["/.gitignore", "/.travis.yml", "/ci/*", "/Cross.toml", "/RELEASE_PROCEDURE.md", "/bors.toml"]
9663 -+description = "Rust friendly bindings to *nix APIs"
9664 -+categories = ["os::unix-apis"]
9665 -+license = "MIT"
9666 -+repository = "https://github.com/nix-rust/nix"
9667 -+
9668 -+[[test]]
9669 -+name = "test"
9670 -+path = "test/test.rs"
9671 -+
9672 -+[[test]]
9673 -+name = "test-aio-drop"
9674 -+path = "test/sys/test_aio_drop.rs"
9675 -+
9676 -+[[test]]
9677 -+name = "test-lio-listio-resubmit"
9678 -+path = "test/sys/test_lio_listio_resubmit.rs"
9679 -+
9680 -+[[test]]
9681 -+name = "test-mount"
9682 -+path = "test/test_mount.rs"
9683 -+harness = false
9684 -+
9685 -+[[test]]
9686 -+name = "test-ptymaster-drop"
9687 -+path = "test/test_ptymaster_drop.rs"
9688 -+[dependencies.bitflags]
9689 -+version = "1.0"
9690 -+
9691 -+[dependencies.cfg-if]
9692 -+version = "0.1.2"
9693 -+
9694 -+[dependencies.libc]
9695 -+version = "0.2.60"
9696 -+features = ["extra_traits"]
9697 -+
9698 -+[dependencies.void]
9699 -+version = "1.0.2"
9700 -+[dev-dependencies.bytes]
9701 -+version = "0.4.8"
9702 -+
9703 -+[dev-dependencies.lazy_static]
9704 -+version = "1.2"
9705 -+
9706 -+[dev-dependencies.rand]
9707 -+version = ">= 0.6, < 0.7"
9708 -+
9709 -+[dev-dependencies.tempfile]
9710 -+version = ">= 3.0.5, < 3.0.9"
9711 -+[target."cfg(any(target_os = \"android\", target_os = \"linux\"))".dev-dependencies.caps]
9712 -+version = "0.3.1"
9713 -+[target."cfg(target_os = \"dragonfly\")".build-dependencies.cc]
9714 -+version = "1"
9715 -+[target."cfg(target_os = \"freebsd\")".dev-dependencies.sysctl]
9716 -+version = "0.1"
9717 -diff --git a/third_party/rust/nix-0.15.0/LICENSE b/third_party/rust/nix-0.15.0/LICENSE
9718 -new file mode 100644
9719 -index 0000000000000..aff9096fdf11d
9720 ---- /dev/null
9721 -+++ b/third_party/rust/nix-0.15.0/LICENSE
9722 -@@ -0,0 +1,21 @@
9723 -+The MIT License (MIT)
9724 -+
9725 -+Copyright (c) 2015 Carl Lerche + nix-rust Authors
9726 -+
9727 -+Permission is hereby granted, free of charge, to any person obtaining a copy
9728 -+of this software and associated documentation files (the "Software"), to deal
9729 -+in the Software without restriction, including without limitation the rights
9730 -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9731 -+copies of the Software, and to permit persons to whom the Software is
9732 -+furnished to do so, subject to the following conditions:
9733 -+
9734 -+The above copyright notice and this permission notice shall be included in
9735 -+all copies or substantial portions of the Software.
9736 -+
9737 -+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9738 -+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9739 -+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
9740 -+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9741 -+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
9742 -+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
9743 -+THE SOFTWARE.
9744 -diff --git a/third_party/rust/nix-0.15.0/README.md b/third_party/rust/nix-0.15.0/README.md
9745 -new file mode 100644
9746 -index 0000000000000..0e540ba5b968e
9747 ---- /dev/null
9748 -+++ b/third_party/rust/nix-0.15.0/README.md
9749 -@@ -0,0 +1,111 @@
9750 -+# Rust bindings to *nix APIs
9751 -+
9752 -+[![Build Status](https://travis-ci.org/nix-rust/nix.svg?branch=master)](https://travis-ci.org/nix-rust/nix)
9753 -+[![crates.io](http://meritbadge.herokuapp.com/nix)](https://crates.io/crates/nix)
9754 -+
9755 -+[Documentation (Releases)](https://docs.rs/nix/)
9756 -+
9757 -+Nix seeks to provide friendly bindings to various *nix platform APIs (Linux, Darwin,
9758 -+...). The goal is to not provide a 100% unified interface, but to unify
9759 -+what can be while still providing platform specific APIs.
9760 -+
9761 -+For many system APIs, Nix provides a safe alternative to the unsafe APIs
9762 -+exposed by the [libc crate](https://github.com/rust-lang/libc). This is done by
9763 -+wrapping the libc functionality with types/abstractions that enforce legal/safe
9764 -+usage.
9765 -+
9766 -+
9767 -+As an example of what Nix provides, examine the differences between what is
9768 -+exposed by libc and nix for the
9769 -+[gethostname](http://man7.org/linux/man-pages/man2/gethostname.2.html) system
9770 -+call:
9771 -+
9772 -+```rust,ignore
9773 -+// libc api (unsafe, requires handling return code/errno)
9774 -+pub unsafe extern fn gethostname(name: *mut c_char, len: size_t) -> c_int;
9775 -+
9776 -+// nix api (returns a nix::Result<CStr>)
9777 -+pub fn gethostname<'a>(buffer: &'a mut [u8]) -> Result<&'a CStr>;
9778 -+```
9779 -+
9780 -+## Supported Platforms
9781 -+
9782 -+nix target support consists of two tiers. While nix attempts to support all
9783 -+platforms supported by [libc](https://github.com/rust-lang/libc), only some
9784 -+platforms are actively supported due to either technical or manpower
9785 -+limitations. Support for platforms is split into three tiers:
9786 -+
9787 -+ * Tier 1 - Builds and tests for this target are run in CI. Failures of either
9788 -+ block the inclusion of new code.
9789 -+ * Tier 2 - Builds for this target are run in CI. Failures during the build
9790 -+ blocks the inclusion of new code. Tests may be run, but failures
9791 -+ in tests don't block the inclusion of new code.
9792 -+ * Tier 3 - Builds for this target are run in CI. Failures during the build
9793 -+ *do not* block the inclusion of new code. Testing may be run, but
9794 -+ failures in tests don't block the inclusion of new code.
9795 -+
9796 -+The following targets are supported by `nix`:
9797 -+
9798 -+Tier 1:
9799 -+ * aarch64-unknown-linux-gnu
9800 -+ * arm-unknown-linux-gnueabi
9801 -+ * armv7-unknown-linux-gnueabihf
9802 -+ * i686-apple-darwin
9803 -+ * i686-unknown-freebsd
9804 -+ * i686-unknown-linux-gnu
9805 -+ * i686-unknown-linux-musl
9806 -+ * mips-unknown-linux-gnu
9807 -+ * mips64-unknown-linux-gnuabi64
9808 -+ * mips64el-unknown-linux-gnuabi64
9809 -+ * mipsel-unknown-linux-gnu
9810 -+ * powerpc64-unknown-linux-gnu
9811 -+ * powerpc64le-unknown-linux-gnu
9812 -+ * x86_64-apple-darwin
9813 -+ * x86_64-unknown-freebsd
9814 -+ * x86_64-unknown-linux-gnu
9815 -+ * x86_64-unknown-linux-musl
9816 -+
9817 -+Tier 2:
9818 -+ * aarch64-apple-ios
9819 -+ * aarch64-linux-android
9820 -+ * arm-linux-androideabi
9821 -+ * arm-unknown-linux-musleabi
9822 -+ * armv7-apple-ios
9823 -+ * armv7-linux-androideabi
9824 -+ * armv7s-apple-ios
9825 -+ * i386-apple-ios
9826 -+ * i686-linux-android
9827 -+ * powerpc-unknown-linux-gnu
9828 -+ * s390x-unknown-linux-gnu
9829 -+ * x86_64-apple-ios
9830 -+ * x86_64-linux-android
9831 -+ * x86_64-unknown-netbsd
9832 -+
9833 -+## Usage
9834 -+
9835 -+`nix` requires Rust 1.31.0 or newer.
9836 -+
9837 -+To use `nix`, first add this to your `Cargo.toml`:
9838 -+
9839 -+```toml
9840 -+[dependencies]
9841 -+nix = "0.15.0"
9842 -+```
9843 -+
9844 -+Then, add this to your crate root:
9845 -+
9846 -+```rust,ignore
9847 -+extern crate nix;
9848 -+```
9849 -+
9850 -+## Contributing
9851 -+
9852 -+Contributions are very welcome. Please See [CONTRIBUTING](CONTRIBUTING.md) for
9853 -+additional details.
9854 -+
9855 -+Feel free to join us in [the nix-rust/nix](https://gitter.im/nix-rust/nix) channel on Gitter to
9856 -+discuss `nix` development.
9857 -+
9858 -+## License
9859 -+
9860 -+Nix is licensed under the MIT license. See [LICENSE](LICENSE) for more details.
9861 -diff --git a/third_party/rust/nix/build.rs b/third_party/rust/nix-0.15.0/build.rs
9862 -similarity index 100%
9863 -rename from third_party/rust/nix/build.rs
9864 -rename to third_party/rust/nix-0.15.0/build.rs
9865 -diff --git a/third_party/rust/nix-0.15.0/src/dir.rs b/third_party/rust/nix-0.15.0/src/dir.rs
9866 -new file mode 100644
9867 -index 0000000000000..1820b5330ff60
9868 ---- /dev/null
9869 -+++ b/third_party/rust/nix-0.15.0/src/dir.rs
9870 -@@ -0,0 +1,193 @@
9871 -+use {Error, NixPath, Result};
9872 -+use errno::Errno;
9873 -+use fcntl::{self, OFlag};
9874 -+use libc;
9875 -+use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
9876 -+use std::{ffi, ptr};
9877 -+use sys;
9878 -+
9879 -+#[cfg(target_os = "linux")]
9880 -+use libc::{dirent64 as dirent, readdir64_r as readdir_r};
9881 -+
9882 -+#[cfg(not(target_os = "linux"))]
9883 -+use libc::{dirent, readdir_r};
9884 -+
9885 -+/// An open directory.
9886 -+///
9887 -+/// This is a lower-level interface than `std::fs::ReadDir`. Notable differences:
9888 -+/// * can be opened from a file descriptor (as returned by `openat`, perhaps before knowing
9889 -+/// if the path represents a file or directory).
9890 -+/// * implements `AsRawFd`, so it can be passed to `fstat`, `openat`, etc.
9891 -+/// The file descriptor continues to be owned by the `Dir`, so callers must not keep a `RawFd`
9892 -+/// after the `Dir` is dropped.
9893 -+/// * can be iterated through multiple times without closing and reopening the file
9894 -+/// descriptor. Each iteration rewinds when finished.
9895 -+/// * returns entries for `.` (current directory) and `..` (parent directory).
9896 -+/// * returns entries' names as a `CStr` (no allocation or conversion beyond whatever libc
9897 -+/// does).
9898 -+#[derive(Clone, Debug, Eq, Hash, PartialEq)]
9899 -+pub struct Dir(
9900 -+ ptr::NonNull<libc::DIR>
9901 -+);
9902 -+
9903 -+impl Dir {
9904 -+ /// Opens the given path as with `fcntl::open`.
9905 -+ pub fn open<P: ?Sized + NixPath>(path: &P, oflag: OFlag,
9906 -+ mode: sys::stat::Mode) -> Result<Self> {
9907 -+ let fd = fcntl::open(path, oflag, mode)?;
9908 -+ Dir::from_fd(fd)
9909 -+ }
9910 -+
9911 -+ /// Opens the given path as with `fcntl::openat`.
9912 -+ pub fn openat<P: ?Sized + NixPath>(dirfd: RawFd, path: &P, oflag: OFlag,
9913 -+ mode: sys::stat::Mode) -> Result<Self> {
9914 -+ let fd = fcntl::openat(dirfd, path, oflag, mode)?;
9915 -+ Dir::from_fd(fd)
9916 -+ }
9917 -+
9918 -+ /// Converts from a descriptor-based object, closing the descriptor on success or failure.
9919 -+ #[inline]
9920 -+ pub fn from<F: IntoRawFd>(fd: F) -> Result<Self> {
9921 -+ Dir::from_fd(fd.into_raw_fd())
9922 -+ }
9923 -+
9924 -+ /// Converts from a file descriptor, closing it on success or failure.
9925 -+ pub fn from_fd(fd: RawFd) -> Result<Self> {
9926 -+ let d = unsafe { libc::fdopendir(fd) };
9927 -+ if d.is_null() {
9928 -+ let e = Error::last();
9929 -+ unsafe { libc::close(fd) };
9930 -+ return Err(e);
9931 -+ };
9932 -+ // Always guaranteed to be non-null by the previous check
9933 -+ Ok(Dir(ptr::NonNull::new(d).unwrap()))
9934 -+ }
9935 -+
9936 -+ /// Returns an iterator of `Result<Entry>` which rewinds when finished.
9937 -+ pub fn iter(&mut self) -> Iter {
9938 -+ Iter(self)
9939 -+ }
9940 -+}
9941 -+
9942 -+// `Dir` is not `Sync`. With the current implementation, it could be, but according to
9943 -+// https://www.gnu.org/software/libc/manual/html_node/Reading_002fClosing-Directory.html,
9944 -+// future versions of POSIX are likely to obsolete `readdir_r` and specify that it's unsafe to
9945 -+// call `readdir` simultaneously from multiple threads.
9946 -+//
9947 -+// `Dir` is safe to pass from one thread to another, as it's not reference-counted.
9948 -+unsafe impl Send for Dir {}
9949 -+
9950 -+impl AsRawFd for Dir {
9951 -+ fn as_raw_fd(&self) -> RawFd {
9952 -+ unsafe { libc::dirfd(self.0.as_ptr()) }
9953 -+ }
9954 -+}
9955 -+
9956 -+impl Drop for Dir {
9957 -+ fn drop(&mut self) {
9958 -+ unsafe { libc::closedir(self.0.as_ptr()) };
9959 -+ }
9960 -+}
9961 -+
9962 -+#[derive(Debug, Eq, Hash, PartialEq)]
9963 -+pub struct Iter<'d>(&'d mut Dir);
9964 -+
9965 -+impl<'d> Iterator for Iter<'d> {
9966 -+ type Item = Result<Entry>;
9967 -+
9968 -+ fn next(&mut self) -> Option<Self::Item> {
9969 -+ unsafe {
9970 -+ // Note: POSIX specifies that portable applications should dynamically allocate a
9971 -+ // buffer with room for a `d_name` field of size `pathconf(..., _PC_NAME_MAX)` plus 1
9972 -+ // for the NUL byte. It doesn't look like the std library does this; it just uses
9973 -+ // fixed-sized buffers (and libc's dirent seems to be sized so this is appropriate).
9974 -+ // Probably fine here too then.
9975 -+ let mut ent: Entry = Entry(::std::mem::uninitialized());
9976 -+ let mut result = ptr::null_mut();
9977 -+ if let Err(e) = Errno::result(readdir_r((self.0).0.as_ptr(), &mut ent.0, &mut result)) {
9978 -+ return Some(Err(e));
9979 -+ }
9980 -+ if result == ptr::null_mut() {
9981 -+ return None;
9982 -+ }
9983 -+ assert_eq!(result, &mut ent.0 as *mut dirent);
9984 -+ return Some(Ok(ent));
9985 -+ }
9986 -+ }
9987 -+}
9988 -+
9989 -+impl<'d> Drop for Iter<'d> {
9990 -+ fn drop(&mut self) {
9991 -+ unsafe { libc::rewinddir((self.0).0.as_ptr()) }
9992 -+ }
9993 -+}
9994 -+
9995 -+/// A directory entry, similar to `std::fs::DirEntry`.
9996 -+///
9997 -+/// Note that unlike the std version, this may represent the `.` or `..` entries.
9998 -+#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
9999 -+pub struct Entry(dirent);
10000 -+
10001 -+#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
10002 -+pub enum Type {
10003 -+ Fifo,
10004 -+ CharacterDevice,
10005 -+ Directory,
10006 -+ BlockDevice,
10007 -+ File,
10008 -+ Symlink,
10009 -+ Socket,
10010 -+}
10011 -+
10012 -+impl Entry {
10013 -+ /// Returns the inode number (`d_ino`) of the underlying `dirent`.
10014 -+ #[cfg(any(target_os = "android",
10015 -+ target_os = "emscripten",
10016 -+ target_os = "fuchsia",
10017 -+ target_os = "haiku",
10018 -+ target_os = "ios",
10019 -+ target_os = "l4re",
10020 -+ target_os = "linux",
10021 -+ target_os = "macos",
10022 -+ target_os = "solaris"))]
10023 -+ pub fn ino(&self) -> u64 {
10024 -+ self.0.d_ino as u64
10025 -+ }
10026 -+
10027 -+ /// Returns the inode number (`d_fileno`) of the underlying `dirent`.
10028 -+ #[cfg(not(any(target_os = "android",
10029 -+ target_os = "emscripten",
10030 -+ target_os = "fuchsia",
10031 -+ target_os = "haiku",
10032 -+ target_os = "ios",
10033 -+ target_os = "l4re",
10034 -+ target_os = "linux",
10035 -+ target_os = "macos",
10036 -+ target_os = "solaris")))]
10037 -+ pub fn ino(&self) -> u64 {
10038 -+ self.0.d_fileno as u64
10039 -+ }
10040 -+
10041 -+ /// Returns the bare file name of this directory entry without any other leading path component.
10042 -+ pub fn file_name(&self) -> &ffi::CStr {
10043 -+ unsafe { ::std::ffi::CStr::from_ptr(self.0.d_name.as_ptr()) }
10044 -+ }
10045 -+
10046 -+ /// Returns the type of this directory entry, if known.
10047 -+ ///
10048 -+ /// See platform `readdir(3)` or `dirent(5)` manpage for when the file type is known;
10049 -+ /// notably, some Linux filesystems don't implement this. The caller should use `stat` or
10050 -+ /// `fstat` if this returns `None`.
10051 -+ pub fn file_type(&self) -> Option<Type> {
10052 -+ match self.0.d_type {
10053 -+ libc::DT_FIFO => Some(Type::Fifo),
10054 -+ libc::DT_CHR => Some(Type::CharacterDevice),
10055 -+ libc::DT_DIR => Some(Type::Directory),
10056 -+ libc::DT_BLK => Some(Type::BlockDevice),
10057 -+ libc::DT_REG => Some(Type::File),
10058 -+ libc::DT_LNK => Some(Type::Symlink),
10059 -+ libc::DT_SOCK => Some(Type::Socket),
10060 -+ /* libc::DT_UNKNOWN | */ _ => None,
10061 -+ }
10062 -+ }
10063 -+}
10064 -diff --git a/third_party/rust/nix-0.15.0/src/errno.rs b/third_party/rust/nix-0.15.0/src/errno.rs
10065 -new file mode 100644
10066 -index 0000000000000..6a2447bc52675
10067 ---- /dev/null
10068 -+++ b/third_party/rust/nix-0.15.0/src/errno.rs
10069 -@@ -0,0 +1,1963 @@
10070 -+#[cfg(not(target_os = "dragonfly"))]
10071 -+use libc;
10072 -+use libc::{c_int, c_void};
10073 -+use std::{fmt, io, error};
10074 -+use {Error, Result};
10075 -+
10076 -+pub use self::consts::*;
10077 -+
10078 -+cfg_if! {
10079 -+ if #[cfg(any(target_os = "freebsd",
10080 -+ target_os = "ios",
10081 -+ target_os = "macos"))] {
10082 -+ unsafe fn errno_location() -> *mut c_int {
10083 -+ libc::__error()
10084 -+ }
10085 -+ } else if #[cfg(target_os = "dragonfly")] {
10086 -+ // DragonFly uses a thread-local errno variable, but #[thread_local] is
10087 -+ // feature-gated and not available in stable Rust as of this writing
10088 -+ // (Rust 1.21.0). We have to use a C extension to access it
10089 -+ // (src/errno_dragonfly.c).
10090 -+ //
10091 -+ // Tracking issue for `thread_local` stabilization:
10092 -+ //
10093 -+ // https://github.com/rust-lang/rust/issues/29594
10094 -+ //
10095 -+ // Once this becomes stable, we can remove build.rs,
10096 -+ // src/errno_dragonfly.c, and use:
10097 -+ //
10098 -+ // extern { #[thread_local] static errno: c_int; }
10099 -+ //
10100 -+ #[link(name="errno_dragonfly", kind="static")]
10101 -+ extern {
10102 -+ pub fn errno_location() -> *mut c_int;
10103 -+ }
10104 -+ } else if #[cfg(any(target_os = "android",
10105 -+ target_os = "netbsd",
10106 -+ target_os = "openbsd"))] {
10107 -+ unsafe fn errno_location() -> *mut c_int {
10108 -+ libc::__errno()
10109 -+ }
10110 -+ } else if #[cfg(target_os = "linux")] {
10111 -+ unsafe fn errno_location() -> *mut c_int {
10112 -+ libc::__errno_location()
10113 -+ }
10114 -+ }
10115 -+}
10116 -+
10117 -+/// Sets the platform-specific errno to no-error
10118 -+unsafe fn clear() -> () {
10119 -+ *errno_location() = 0;
10120 -+}
10121 -+
10122 -+/// Returns the platform-specific value of errno
10123 -+pub fn errno() -> i32 {
10124 -+ unsafe {
10125 -+ (*errno_location()) as i32
10126 -+ }
10127 -+}
10128 -+
10129 -+impl Errno {
10130 -+ pub fn last() -> Self {
10131 -+ last()
10132 -+ }
10133 -+
10134 -+ pub fn desc(self) -> &'static str {
10135 -+ desc(self)
10136 -+ }
10137 -+
10138 -+ pub fn from_i32(err: i32) -> Errno {
10139 -+ from_i32(err)
10140 -+ }
10141 -+
10142 -+ pub unsafe fn clear() -> () {
10143 -+ clear()
10144 -+ }
10145 -+
10146 -+ /// Returns `Ok(value)` if it does not contain the sentinel value. This
10147 -+ /// should not be used when `-1` is not the errno sentinel value.
10148 -+ pub fn result<S: ErrnoSentinel + PartialEq<S>>(value: S) -> Result<S> {
10149 -+ if value == S::sentinel() {
10150 -+ Err(Error::Sys(Self::last()))
10151 -+ } else {
10152 -+ Ok(value)
10153 -+ }
10154 -+ }
10155 -+}
10156 -+
10157 -+/// The sentinel value indicates that a function failed and more detailed
10158 -+/// information about the error can be found in `errno`
10159 -+pub trait ErrnoSentinel: Sized {
10160 -+ fn sentinel() -> Self;
10161 -+}
10162 -+
10163 -+impl ErrnoSentinel for isize {
10164 -+ fn sentinel() -> Self { -1 }
10165 -+}
10166 -+
10167 -+impl ErrnoSentinel for i32 {
10168 -+ fn sentinel() -> Self { -1 }
10169 -+}
10170 -+
10171 -+impl ErrnoSentinel for i64 {
10172 -+ fn sentinel() -> Self { -1 }
10173 -+}
10174 -+
10175 -+impl ErrnoSentinel for *mut c_void {
10176 -+ fn sentinel() -> Self { (-1 as isize) as *mut c_void }
10177 -+}
10178 -+
10179 -+impl ErrnoSentinel for libc::sighandler_t {
10180 -+ fn sentinel() -> Self { libc::SIG_ERR }
10181 -+}
10182 -+
10183 -+impl error::Error for Errno {
10184 -+ fn description(&self) -> &str {
10185 -+ self.desc()
10186 -+ }
10187 -+}
10188 -+
10189 -+impl fmt::Display for Errno {
10190 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10191 -+ write!(f, "{:?}: {}", self, self.desc())
10192 -+ }
10193 -+}
10194 -+
10195 -+impl From<Errno> for io::Error {
10196 -+ fn from(err: Errno) -> Self {
10197 -+ io::Error::from_raw_os_error(err as i32)
10198 -+ }
10199 -+}
10200 -+
10201 -+fn last() -> Errno {
10202 -+ Errno::from_i32(errno())
10203 -+}
10204 -+
10205 -+fn desc(errno: Errno) -> &'static str {
10206 -+ use self::Errno::*;
10207 -+ match errno {
10208 -+ UnknownErrno => "Unknown errno",
10209 -+ EPERM => "Operation not permitted",
10210 -+ ENOENT => "No such file or directory",
10211 -+ ESRCH => "No such process",
10212 -+ EINTR => "Interrupted system call",
10213 -+ EIO => "I/O error",
10214 -+ ENXIO => "No such device or address",
10215 -+ E2BIG => "Argument list too long",
10216 -+ ENOEXEC => "Exec format error",
10217 -+ EBADF => "Bad file number",
10218 -+ ECHILD => "No child processes",
10219 -+ EAGAIN => "Try again",
10220 -+ ENOMEM => "Out of memory",
10221 -+ EACCES => "Permission denied",
10222 -+ EFAULT => "Bad address",
10223 -+ ENOTBLK => "Block device required",
10224 -+ EBUSY => "Device or resource busy",
10225 -+ EEXIST => "File exists",
10226 -+ EXDEV => "Cross-device link",
10227 -+ ENODEV => "No such device",
10228 -+ ENOTDIR => "Not a directory",
10229 -+ EISDIR => "Is a directory",
10230 -+ EINVAL => "Invalid argument",
10231 -+ ENFILE => "File table overflow",
10232 -+ EMFILE => "Too many open files",
10233 -+ ENOTTY => "Not a typewriter",
10234 -+ ETXTBSY => "Text file busy",
10235 -+ EFBIG => "File too large",
10236 -+ ENOSPC => "No space left on device",
10237 -+ ESPIPE => "Illegal seek",
10238 -+ EROFS => "Read-only file system",
10239 -+ EMLINK => "Too many links",
10240 -+ EPIPE => "Broken pipe",
10241 -+ EDOM => "Math argument out of domain of func",
10242 -+ ERANGE => "Math result not representable",
10243 -+ EDEADLK => "Resource deadlock would occur",
10244 -+ ENAMETOOLONG => "File name too long",
10245 -+ ENOLCK => "No record locks available",
10246 -+ ENOSYS => "Function not implemented",
10247 -+ ENOTEMPTY => "Directory not empty",
10248 -+ ELOOP => "Too many symbolic links encountered",
10249 -+ ENOMSG => "No message of desired type",
10250 -+ EIDRM => "Identifier removed",
10251 -+ EINPROGRESS => "Operation now in progress",
10252 -+ EALREADY => "Operation already in progress",
10253 -+ ENOTSOCK => "Socket operation on non-socket",
10254 -+ EDESTADDRREQ => "Destination address required",
10255 -+ EMSGSIZE => "Message too long",
10256 -+ EPROTOTYPE => "Protocol wrong type for socket",
10257 -+ ENOPROTOOPT => "Protocol not available",
10258 -+ EPROTONOSUPPORT => "Protocol not supported",
10259 -+ ESOCKTNOSUPPORT => "Socket type not supported",
10260 -+ EPFNOSUPPORT => "Protocol family not supported",
10261 -+ EAFNOSUPPORT => "Address family not supported by protocol",
10262 -+ EADDRINUSE => "Address already in use",
10263 -+ EADDRNOTAVAIL => "Cannot assign requested address",
10264 -+ ENETDOWN => "Network is down",
10265 -+ ENETUNREACH => "Network is unreachable",
10266 -+ ENETRESET => "Network dropped connection because of reset",
10267 -+ ECONNABORTED => "Software caused connection abort",
10268 -+ ECONNRESET => "Connection reset by peer",
10269 -+ ENOBUFS => "No buffer space available",
10270 -+ EISCONN => "Transport endpoint is already connected",
10271 -+ ENOTCONN => "Transport endpoint is not connected",
10272 -+ ESHUTDOWN => "Cannot send after transport endpoint shutdown",
10273 -+ ETOOMANYREFS => "Too many references: cannot splice",
10274 -+ ETIMEDOUT => "Connection timed out",
10275 -+ ECONNREFUSED => "Connection refused",
10276 -+ EHOSTDOWN => "Host is down",
10277 -+ EHOSTUNREACH => "No route to host",
10278 -+
10279 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10280 -+ ECHRNG => "Channel number out of range",
10281 -+
10282 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10283 -+ EL2NSYNC => "Level 2 not synchronized",
10284 -+
10285 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10286 -+ EL3HLT => "Level 3 halted",
10287 -+
10288 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10289 -+ EL3RST => "Level 3 reset",
10290 -+
10291 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10292 -+ ELNRNG => "Link number out of range",
10293 -+
10294 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10295 -+ EUNATCH => "Protocol driver not attached",
10296 -+
10297 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10298 -+ ENOCSI => "No CSI structure available",
10299 -+
10300 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10301 -+ EL2HLT => "Level 2 halted",
10302 -+
10303 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10304 -+ EBADE => "Invalid exchange",
10305 -+
10306 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10307 -+ EBADR => "Invalid request descriptor",
10308 -+
10309 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10310 -+ EXFULL => "Exchange full",
10311 -+
10312 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10313 -+ ENOANO => "No anode",
10314 -+
10315 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10316 -+ EBADRQC => "Invalid request code",
10317 -+
10318 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10319 -+ EBADSLT => "Invalid slot",
10320 -+
10321 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10322 -+ EBFONT => "Bad font file format",
10323 -+
10324 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10325 -+ ENOSTR => "Device not a stream",
10326 -+
10327 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10328 -+ ENODATA => "No data available",
10329 -+
10330 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10331 -+ ETIME => "Timer expired",
10332 -+
10333 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10334 -+ ENOSR => "Out of streams resources",
10335 -+
10336 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10337 -+ ENONET => "Machine is not on the network",
10338 -+
10339 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10340 -+ ENOPKG => "Package not installed",
10341 -+
10342 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10343 -+ EREMOTE => "Object is remote",
10344 -+
10345 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10346 -+ ENOLINK => "Link has been severed",
10347 -+
10348 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10349 -+ EADV => "Advertise error",
10350 -+
10351 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10352 -+ ESRMNT => "Srmount error",
10353 -+
10354 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10355 -+ ECOMM => "Communication error on send",
10356 -+
10357 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10358 -+ EPROTO => "Protocol error",
10359 -+
10360 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10361 -+ EMULTIHOP => "Multihop attempted",
10362 -+
10363 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10364 -+ EDOTDOT => "RFS specific error",
10365 -+
10366 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10367 -+ EBADMSG => "Not a data message",
10368 -+
10369 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10370 -+ EOVERFLOW => "Value too large for defined data type",
10371 -+
10372 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10373 -+ ENOTUNIQ => "Name not unique on network",
10374 -+
10375 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10376 -+ EBADFD => "File descriptor in bad state",
10377 -+
10378 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10379 -+ EREMCHG => "Remote address changed",
10380 -+
10381 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10382 -+ ELIBACC => "Can not access a needed shared library",
10383 -+
10384 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10385 -+ ELIBBAD => "Accessing a corrupted shared library",
10386 -+
10387 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10388 -+ ELIBSCN => ".lib section in a.out corrupted",
10389 -+
10390 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10391 -+ ELIBMAX => "Attempting to link in too many shared libraries",
10392 -+
10393 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10394 -+ ELIBEXEC => "Cannot exec a shared library directly",
10395 -+
10396 -+ #[cfg(any(target_os = "linux", target_os = "android", target_os = "openbsd"))]
10397 -+ EILSEQ => "Illegal byte sequence",
10398 -+
10399 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10400 -+ ERESTART => "Interrupted system call should be restarted",
10401 -+
10402 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10403 -+ ESTRPIPE => "Streams pipe error",
10404 -+
10405 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10406 -+ EUSERS => "Too many users",
10407 -+
10408 -+ #[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))]
10409 -+ EOPNOTSUPP => "Operation not supported on transport endpoint",
10410 -+
10411 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10412 -+ ESTALE => "Stale file handle",
10413 -+
10414 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10415 -+ EUCLEAN => "Structure needs cleaning",
10416 -+
10417 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10418 -+ ENOTNAM => "Not a XENIX named type file",
10419 -+
10420 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10421 -+ ENAVAIL => "No XENIX semaphores available",
10422 -+
10423 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10424 -+ EISNAM => "Is a named type file",
10425 -+
10426 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10427 -+ EREMOTEIO => "Remote I/O error",
10428 -+
10429 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10430 -+ EDQUOT => "Quota exceeded",
10431 -+
10432 -+ #[cfg(any(target_os = "linux", target_os = "android",
10433 -+ target_os = "openbsd", target_os = "dragonfly"))]
10434 -+ ENOMEDIUM => "No medium found",
10435 -+
10436 -+ #[cfg(any(target_os = "linux", target_os = "android", target_os = "openbsd"))]
10437 -+ EMEDIUMTYPE => "Wrong medium type",
10438 -+
10439 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10440 -+ ECANCELED => "Operation canceled",
10441 -+
10442 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10443 -+ ENOKEY => "Required key not available",
10444 -+
10445 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10446 -+ EKEYEXPIRED => "Key has expired",
10447 -+
10448 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10449 -+ EKEYREVOKED => "Key has been revoked",
10450 -+
10451 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10452 -+ EKEYREJECTED => "Key was rejected by service",
10453 -+
10454 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10455 -+ EOWNERDEAD => "Owner died",
10456 -+
10457 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
10458 -+ ENOTRECOVERABLE => "State not recoverable",
10459 -+
10460 -+ #[cfg(all(target_os = "linux", not(target_arch="mips")))]
10461 -+ ERFKILL => "Operation not possible due to RF-kill",
10462 -+
10463 -+ #[cfg(all(target_os = "linux", not(target_arch="mips")))]
10464 -+ EHWPOISON => "Memory page has hardware error",
10465 -+
10466 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
10467 -+ EDOOFUS => "Programming error",
10468 -+
10469 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
10470 -+ EMULTIHOP => "Multihop attempted",
10471 -+
10472 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
10473 -+ ENOLINK => "Link has been severed",
10474 -+
10475 -+ #[cfg(target_os = "freebsd")]
10476 -+ ENOTCAPABLE => "Capabilities insufficient",
10477 -+
10478 -+ #[cfg(target_os = "freebsd")]
10479 -+ ECAPMODE => "Not permitted in capability mode",
10480 -+
10481 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10482 -+ target_os = "dragonfly", target_os = "ios",
10483 -+ target_os = "openbsd", target_os = "netbsd"))]
10484 -+ ENEEDAUTH => "Need authenticator",
10485 -+
10486 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10487 -+ target_os = "dragonfly", target_os = "ios",
10488 -+ target_os = "openbsd", target_os = "netbsd"))]
10489 -+ EOVERFLOW => "Value too large to be stored in data type",
10490 -+
10491 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10492 -+ target_os = "dragonfly", target_os = "ios",
10493 -+ target_os = "netbsd"))]
10494 -+ EILSEQ => "Illegal byte sequence",
10495 -+
10496 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10497 -+ target_os = "dragonfly", target_os = "ios",
10498 -+ target_os = "openbsd", target_os = "netbsd"))]
10499 -+ ENOATTR => "Attribute not found",
10500 -+
10501 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10502 -+ target_os = "dragonfly", target_os = "ios",
10503 -+ target_os = "openbsd", target_os = "netbsd"))]
10504 -+ EBADMSG => "Bad message",
10505 -+
10506 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10507 -+ target_os = "dragonfly", target_os = "ios",
10508 -+ target_os = "openbsd", target_os = "netbsd"))]
10509 -+ EPROTO => "Protocol error",
10510 -+
10511 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10512 -+ target_os = "ios", target_os = "openbsd", ))]
10513 -+ ENOTRECOVERABLE => "State not recoverable",
10514 -+
10515 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10516 -+ target_os = "ios", target_os = "openbsd"))]
10517 -+ EOWNERDEAD => "Previous owner died",
10518 -+
10519 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10520 -+ target_os = "dragonfly", target_os = "ios",
10521 -+ target_os = "openbsd", target_os = "netbsd"))]
10522 -+ ENOTSUP => "Operation not supported",
10523 -+
10524 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10525 -+ target_os = "dragonfly", target_os = "ios",
10526 -+ target_os = "openbsd", target_os = "netbsd"))]
10527 -+ EPROCLIM => "Too many processes",
10528 -+
10529 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10530 -+ target_os = "dragonfly", target_os = "ios",
10531 -+ target_os = "openbsd", target_os = "netbsd"))]
10532 -+ EUSERS => "Too many users",
10533 -+
10534 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10535 -+ target_os = "dragonfly", target_os = "ios",
10536 -+ target_os = "openbsd", target_os = "netbsd"))]
10537 -+ EDQUOT => "Disc quota exceeded",
10538 -+
10539 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10540 -+ target_os = "dragonfly", target_os = "ios",
10541 -+ target_os = "openbsd", target_os = "netbsd"))]
10542 -+ ESTALE => "Stale NFS file handle",
10543 -+
10544 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10545 -+ target_os = "dragonfly", target_os = "ios",
10546 -+ target_os = "openbsd", target_os = "netbsd"))]
10547 -+ EREMOTE => "Too many levels of remote in path",
10548 -+
10549 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10550 -+ target_os = "dragonfly", target_os = "ios",
10551 -+ target_os = "openbsd", target_os = "netbsd"))]
10552 -+ EBADRPC => "RPC struct is bad",
10553 -+
10554 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10555 -+ target_os = "dragonfly", target_os = "ios",
10556 -+ target_os = "openbsd", target_os = "netbsd"))]
10557 -+ ERPCMISMATCH => "RPC version wrong",
10558 -+
10559 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10560 -+ target_os = "dragonfly", target_os = "ios",
10561 -+ target_os = "openbsd", target_os = "netbsd"))]
10562 -+ EPROGUNAVAIL => "RPC prog. not avail",
10563 -+
10564 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10565 -+ target_os = "dragonfly", target_os = "ios",
10566 -+ target_os = "openbsd", target_os = "netbsd"))]
10567 -+ EPROGMISMATCH => "Program version wrong",
10568 -+
10569 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10570 -+ target_os = "dragonfly", target_os = "ios",
10571 -+ target_os = "openbsd", target_os = "netbsd"))]
10572 -+ EPROCUNAVAIL => "Bad procedure for program",
10573 -+
10574 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10575 -+ target_os = "dragonfly", target_os = "ios",
10576 -+ target_os = "openbsd", target_os = "netbsd"))]
10577 -+ EFTYPE => "Inappropriate file type or format",
10578 -+
10579 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10580 -+ target_os = "dragonfly", target_os = "ios",
10581 -+ target_os = "openbsd", target_os = "netbsd"))]
10582 -+ EAUTH => "Authentication error",
10583 -+
10584 -+ #[cfg(any(target_os = "macos", target_os = "freebsd",
10585 -+ target_os = "dragonfly", target_os = "ios",
10586 -+ target_os = "openbsd", target_os = "netbsd"))]
10587 -+ ECANCELED => "Operation canceled",
10588 -+
10589 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
10590 -+ EPWROFF => "Device power is off",
10591 -+
10592 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
10593 -+ EDEVERR => "Device error, e.g. paper out",
10594 -+
10595 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
10596 -+ EBADEXEC => "Bad executable",
10597 -+
10598 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
10599 -+ EBADARCH => "Bad CPU type in executable",
10600 -+
10601 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
10602 -+ ESHLIBVERS => "Shared library version mismatch",
10603 -+
10604 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
10605 -+ EBADMACHO => "Malformed Macho file",
10606 -+
10607 -+ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
10608 -+ EMULTIHOP => "Reserved",
10609 -+
10610 -+ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
10611 -+ ENODATA => "No message available on STREAM",
10612 -+
10613 -+ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
10614 -+ ENOLINK => "Reserved",
10615 -+
10616 -+ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
10617 -+ ENOSR => "No STREAM resources",
10618 -+
10619 -+ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
10620 -+ ENOSTR => "Not a STREAM",
10621 -+
10622 -+ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
10623 -+ ETIME => "STREAM ioctl timeout",
10624 -+
10625 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
10626 -+ EOPNOTSUPP => "Operation not supported on socket",
10627 -+
10628 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
10629 -+ ENOPOLICY => "No such policy registered",
10630 -+
10631 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
10632 -+ EQFULL => "Interface output queue is full",
10633 -+
10634 -+ #[cfg(target_os = "openbsd")]
10635 -+ EOPNOTSUPP => "Operation not supported",
10636 -+
10637 -+ #[cfg(target_os = "openbsd")]
10638 -+ EIPSEC => "IPsec processing failure",
10639 -+
10640 -+ #[cfg(target_os = "dragonfly")]
10641 -+ EASYNC => "Async",
10642 -+ }
10643 -+}
10644 -+
10645 -+#[cfg(any(target_os = "linux", target_os = "android"))]
10646 -+mod consts {
10647 -+ use libc;
10648 -+
10649 -+ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
10650 -+ #[repr(i32)]
10651 -+ pub enum Errno {
10652 -+ UnknownErrno = 0,
10653 -+ EPERM = libc::EPERM,
10654 -+ ENOENT = libc::ENOENT,
10655 -+ ESRCH = libc::ESRCH,
10656 -+ EINTR = libc::EINTR,
10657 -+ EIO = libc::EIO,
10658 -+ ENXIO = libc::ENXIO,
10659 -+ E2BIG = libc::E2BIG,
10660 -+ ENOEXEC = libc::ENOEXEC,
10661 -+ EBADF = libc::EBADF,
10662 -+ ECHILD = libc::ECHILD,
10663 -+ EAGAIN = libc::EAGAIN,
10664 -+ ENOMEM = libc::ENOMEM,
10665 -+ EACCES = libc::EACCES,
10666 -+ EFAULT = libc::EFAULT,
10667 -+ ENOTBLK = libc::ENOTBLK,
10668 -+ EBUSY = libc::EBUSY,
10669 -+ EEXIST = libc::EEXIST,
10670 -+ EXDEV = libc::EXDEV,
10671 -+ ENODEV = libc::ENODEV,
10672 -+ ENOTDIR = libc::ENOTDIR,
10673 -+ EISDIR = libc::EISDIR,
10674 -+ EINVAL = libc::EINVAL,
10675 -+ ENFILE = libc::ENFILE,
10676 -+ EMFILE = libc::EMFILE,
10677 -+ ENOTTY = libc::ENOTTY,
10678 -+ ETXTBSY = libc::ETXTBSY,
10679 -+ EFBIG = libc::EFBIG,
10680 -+ ENOSPC = libc::ENOSPC,
10681 -+ ESPIPE = libc::ESPIPE,
10682 -+ EROFS = libc::EROFS,
10683 -+ EMLINK = libc::EMLINK,
10684 -+ EPIPE = libc::EPIPE,
10685 -+ EDOM = libc::EDOM,
10686 -+ ERANGE = libc::ERANGE,
10687 -+ EDEADLK = libc::EDEADLK,
10688 -+ ENAMETOOLONG = libc::ENAMETOOLONG,
10689 -+ ENOLCK = libc::ENOLCK,
10690 -+ ENOSYS = libc::ENOSYS,
10691 -+ ENOTEMPTY = libc::ENOTEMPTY,
10692 -+ ELOOP = libc::ELOOP,
10693 -+ ENOMSG = libc::ENOMSG,
10694 -+ EIDRM = libc::EIDRM,
10695 -+ ECHRNG = libc::ECHRNG,
10696 -+ EL2NSYNC = libc::EL2NSYNC,
10697 -+ EL3HLT = libc::EL3HLT,
10698 -+ EL3RST = libc::EL3RST,
10699 -+ ELNRNG = libc::ELNRNG,
10700 -+ EUNATCH = libc::EUNATCH,
10701 -+ ENOCSI = libc::ENOCSI,
10702 -+ EL2HLT = libc::EL2HLT,
10703 -+ EBADE = libc::EBADE,
10704 -+ EBADR = libc::EBADR,
10705 -+ EXFULL = libc::EXFULL,
10706 -+ ENOANO = libc::ENOANO,
10707 -+ EBADRQC = libc::EBADRQC,
10708 -+ EBADSLT = libc::EBADSLT,
10709 -+ EBFONT = libc::EBFONT,
10710 -+ ENOSTR = libc::ENOSTR,
10711 -+ ENODATA = libc::ENODATA,
10712 -+ ETIME = libc::ETIME,
10713 -+ ENOSR = libc::ENOSR,
10714 -+ ENONET = libc::ENONET,
10715 -+ ENOPKG = libc::ENOPKG,
10716 -+ EREMOTE = libc::EREMOTE,
10717 -+ ENOLINK = libc::ENOLINK,
10718 -+ EADV = libc::EADV,
10719 -+ ESRMNT = libc::ESRMNT,
10720 -+ ECOMM = libc::ECOMM,
10721 -+ EPROTO = libc::EPROTO,
10722 -+ EMULTIHOP = libc::EMULTIHOP,
10723 -+ EDOTDOT = libc::EDOTDOT,
10724 -+ EBADMSG = libc::EBADMSG,
10725 -+ EOVERFLOW = libc::EOVERFLOW,
10726 -+ ENOTUNIQ = libc::ENOTUNIQ,
10727 -+ EBADFD = libc::EBADFD,
10728 -+ EREMCHG = libc::EREMCHG,
10729 -+ ELIBACC = libc::ELIBACC,
10730 -+ ELIBBAD = libc::ELIBBAD,
10731 -+ ELIBSCN = libc::ELIBSCN,
10732 -+ ELIBMAX = libc::ELIBMAX,
10733 -+ ELIBEXEC = libc::ELIBEXEC,
10734 -+ EILSEQ = libc::EILSEQ,
10735 -+ ERESTART = libc::ERESTART,
10736 -+ ESTRPIPE = libc::ESTRPIPE,
10737 -+ EUSERS = libc::EUSERS,
10738 -+ ENOTSOCK = libc::ENOTSOCK,
10739 -+ EDESTADDRREQ = libc::EDESTADDRREQ,
10740 -+ EMSGSIZE = libc::EMSGSIZE,
10741 -+ EPROTOTYPE = libc::EPROTOTYPE,
10742 -+ ENOPROTOOPT = libc::ENOPROTOOPT,
10743 -+ EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
10744 -+ ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
10745 -+ EOPNOTSUPP = libc::EOPNOTSUPP,
10746 -+ EPFNOSUPPORT = libc::EPFNOSUPPORT,
10747 -+ EAFNOSUPPORT = libc::EAFNOSUPPORT,
10748 -+ EADDRINUSE = libc::EADDRINUSE,
10749 -+ EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
10750 -+ ENETDOWN = libc::ENETDOWN,
10751 -+ ENETUNREACH = libc::ENETUNREACH,
10752 -+ ENETRESET = libc::ENETRESET,
10753 -+ ECONNABORTED = libc::ECONNABORTED,
10754 -+ ECONNRESET = libc::ECONNRESET,
10755 -+ ENOBUFS = libc::ENOBUFS,
10756 -+ EISCONN = libc::EISCONN,
10757 -+ ENOTCONN = libc::ENOTCONN,
10758 -+ ESHUTDOWN = libc::ESHUTDOWN,
10759 -+ ETOOMANYREFS = libc::ETOOMANYREFS,
10760 -+ ETIMEDOUT = libc::ETIMEDOUT,
10761 -+ ECONNREFUSED = libc::ECONNREFUSED,
10762 -+ EHOSTDOWN = libc::EHOSTDOWN,
10763 -+ EHOSTUNREACH = libc::EHOSTUNREACH,
10764 -+ EALREADY = libc::EALREADY,
10765 -+ EINPROGRESS = libc::EINPROGRESS,
10766 -+ ESTALE = libc::ESTALE,
10767 -+ EUCLEAN = libc::EUCLEAN,
10768 -+ ENOTNAM = libc::ENOTNAM,
10769 -+ ENAVAIL = libc::ENAVAIL,
10770 -+ EISNAM = libc::EISNAM,
10771 -+ EREMOTEIO = libc::EREMOTEIO,
10772 -+ EDQUOT = libc::EDQUOT,
10773 -+ ENOMEDIUM = libc::ENOMEDIUM,
10774 -+ EMEDIUMTYPE = libc::EMEDIUMTYPE,
10775 -+ ECANCELED = libc::ECANCELED,
10776 -+ ENOKEY = libc::ENOKEY,
10777 -+ EKEYEXPIRED = libc::EKEYEXPIRED,
10778 -+ EKEYREVOKED = libc::EKEYREVOKED,
10779 -+ EKEYREJECTED = libc::EKEYREJECTED,
10780 -+ EOWNERDEAD = libc::EOWNERDEAD,
10781 -+ ENOTRECOVERABLE = libc::ENOTRECOVERABLE,
10782 -+ #[cfg(not(any(target_os = "android", target_arch="mips")))]
10783 -+ ERFKILL = libc::ERFKILL,
10784 -+ #[cfg(not(any(target_os = "android", target_arch="mips")))]
10785 -+ EHWPOISON = libc::EHWPOISON,
10786 -+ }
10787 -+
10788 -+ pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
10789 -+ pub const EDEADLOCK: Errno = Errno::EDEADLK;
10790 -+ pub const ENOTSUP: Errno = Errno::EOPNOTSUPP;
10791 -+
10792 -+ pub fn from_i32(e: i32) -> Errno {
10793 -+ use self::Errno::*;
10794 -+
10795 -+ match e {
10796 -+ libc::EPERM => EPERM,
10797 -+ libc::ENOENT => ENOENT,
10798 -+ libc::ESRCH => ESRCH,
10799 -+ libc::EINTR => EINTR,
10800 -+ libc::EIO => EIO,
10801 -+ libc::ENXIO => ENXIO,
10802 -+ libc::E2BIG => E2BIG,
10803 -+ libc::ENOEXEC => ENOEXEC,
10804 -+ libc::EBADF => EBADF,
10805 -+ libc::ECHILD => ECHILD,
10806 -+ libc::EAGAIN => EAGAIN,
10807 -+ libc::ENOMEM => ENOMEM,
10808 -+ libc::EACCES => EACCES,
10809 -+ libc::EFAULT => EFAULT,
10810 -+ libc::ENOTBLK => ENOTBLK,
10811 -+ libc::EBUSY => EBUSY,
10812 -+ libc::EEXIST => EEXIST,
10813 -+ libc::EXDEV => EXDEV,
10814 -+ libc::ENODEV => ENODEV,
10815 -+ libc::ENOTDIR => ENOTDIR,
10816 -+ libc::EISDIR => EISDIR,
10817 -+ libc::EINVAL => EINVAL,
10818 -+ libc::ENFILE => ENFILE,
10819 -+ libc::EMFILE => EMFILE,
10820 -+ libc::ENOTTY => ENOTTY,
10821 -+ libc::ETXTBSY => ETXTBSY,
10822 -+ libc::EFBIG => EFBIG,
10823 -+ libc::ENOSPC => ENOSPC,
10824 -+ libc::ESPIPE => ESPIPE,
10825 -+ libc::EROFS => EROFS,
10826 -+ libc::EMLINK => EMLINK,
10827 -+ libc::EPIPE => EPIPE,
10828 -+ libc::EDOM => EDOM,
10829 -+ libc::ERANGE => ERANGE,
10830 -+ libc::EDEADLK => EDEADLK,
10831 -+ libc::ENAMETOOLONG => ENAMETOOLONG,
10832 -+ libc::ENOLCK => ENOLCK,
10833 -+ libc::ENOSYS => ENOSYS,
10834 -+ libc::ENOTEMPTY => ENOTEMPTY,
10835 -+ libc::ELOOP => ELOOP,
10836 -+ libc::ENOMSG => ENOMSG,
10837 -+ libc::EIDRM => EIDRM,
10838 -+ libc::ECHRNG => ECHRNG,
10839 -+ libc::EL2NSYNC => EL2NSYNC,
10840 -+ libc::EL3HLT => EL3HLT,
10841 -+ libc::EL3RST => EL3RST,
10842 -+ libc::ELNRNG => ELNRNG,
10843 -+ libc::EUNATCH => EUNATCH,
10844 -+ libc::ENOCSI => ENOCSI,
10845 -+ libc::EL2HLT => EL2HLT,
10846 -+ libc::EBADE => EBADE,
10847 -+ libc::EBADR => EBADR,
10848 -+ libc::EXFULL => EXFULL,
10849 -+ libc::ENOANO => ENOANO,
10850 -+ libc::EBADRQC => EBADRQC,
10851 -+ libc::EBADSLT => EBADSLT,
10852 -+ libc::EBFONT => EBFONT,
10853 -+ libc::ENOSTR => ENOSTR,
10854 -+ libc::ENODATA => ENODATA,
10855 -+ libc::ETIME => ETIME,
10856 -+ libc::ENOSR => ENOSR,
10857 -+ libc::ENONET => ENONET,
10858 -+ libc::ENOPKG => ENOPKG,
10859 -+ libc::EREMOTE => EREMOTE,
10860 -+ libc::ENOLINK => ENOLINK,
10861 -+ libc::EADV => EADV,
10862 -+ libc::ESRMNT => ESRMNT,
10863 -+ libc::ECOMM => ECOMM,
10864 -+ libc::EPROTO => EPROTO,
10865 -+ libc::EMULTIHOP => EMULTIHOP,
10866 -+ libc::EDOTDOT => EDOTDOT,
10867 -+ libc::EBADMSG => EBADMSG,
10868 -+ libc::EOVERFLOW => EOVERFLOW,
10869 -+ libc::ENOTUNIQ => ENOTUNIQ,
10870 -+ libc::EBADFD => EBADFD,
10871 -+ libc::EREMCHG => EREMCHG,
10872 -+ libc::ELIBACC => ELIBACC,
10873 -+ libc::ELIBBAD => ELIBBAD,
10874 -+ libc::ELIBSCN => ELIBSCN,
10875 -+ libc::ELIBMAX => ELIBMAX,
10876 -+ libc::ELIBEXEC => ELIBEXEC,
10877 -+ libc::EILSEQ => EILSEQ,
10878 -+ libc::ERESTART => ERESTART,
10879 -+ libc::ESTRPIPE => ESTRPIPE,
10880 -+ libc::EUSERS => EUSERS,
10881 -+ libc::ENOTSOCK => ENOTSOCK,
10882 -+ libc::EDESTADDRREQ => EDESTADDRREQ,
10883 -+ libc::EMSGSIZE => EMSGSIZE,
10884 -+ libc::EPROTOTYPE => EPROTOTYPE,
10885 -+ libc::ENOPROTOOPT => ENOPROTOOPT,
10886 -+ libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
10887 -+ libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
10888 -+ libc::EOPNOTSUPP => EOPNOTSUPP,
10889 -+ libc::EPFNOSUPPORT => EPFNOSUPPORT,
10890 -+ libc::EAFNOSUPPORT => EAFNOSUPPORT,
10891 -+ libc::EADDRINUSE => EADDRINUSE,
10892 -+ libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
10893 -+ libc::ENETDOWN => ENETDOWN,
10894 -+ libc::ENETUNREACH => ENETUNREACH,
10895 -+ libc::ENETRESET => ENETRESET,
10896 -+ libc::ECONNABORTED => ECONNABORTED,
10897 -+ libc::ECONNRESET => ECONNRESET,
10898 -+ libc::ENOBUFS => ENOBUFS,
10899 -+ libc::EISCONN => EISCONN,
10900 -+ libc::ENOTCONN => ENOTCONN,
10901 -+ libc::ESHUTDOWN => ESHUTDOWN,
10902 -+ libc::ETOOMANYREFS => ETOOMANYREFS,
10903 -+ libc::ETIMEDOUT => ETIMEDOUT,
10904 -+ libc::ECONNREFUSED => ECONNREFUSED,
10905 -+ libc::EHOSTDOWN => EHOSTDOWN,
10906 -+ libc::EHOSTUNREACH => EHOSTUNREACH,
10907 -+ libc::EALREADY => EALREADY,
10908 -+ libc::EINPROGRESS => EINPROGRESS,
10909 -+ libc::ESTALE => ESTALE,
10910 -+ libc::EUCLEAN => EUCLEAN,
10911 -+ libc::ENOTNAM => ENOTNAM,
10912 -+ libc::ENAVAIL => ENAVAIL,
10913 -+ libc::EISNAM => EISNAM,
10914 -+ libc::EREMOTEIO => EREMOTEIO,
10915 -+ libc::EDQUOT => EDQUOT,
10916 -+ libc::ENOMEDIUM => ENOMEDIUM,
10917 -+ libc::EMEDIUMTYPE => EMEDIUMTYPE,
10918 -+ libc::ECANCELED => ECANCELED,
10919 -+ libc::ENOKEY => ENOKEY,
10920 -+ libc::EKEYEXPIRED => EKEYEXPIRED,
10921 -+ libc::EKEYREVOKED => EKEYREVOKED,
10922 -+ libc::EKEYREJECTED => EKEYREJECTED,
10923 -+ libc::EOWNERDEAD => EOWNERDEAD,
10924 -+ libc::ENOTRECOVERABLE => ENOTRECOVERABLE,
10925 -+ #[cfg(not(any(target_os = "android", target_arch="mips")))]
10926 -+ libc::ERFKILL => ERFKILL,
10927 -+ #[cfg(not(any(target_os = "android", target_arch="mips")))]
10928 -+ libc::EHWPOISON => EHWPOISON,
10929 -+ _ => UnknownErrno,
10930 -+ }
10931 -+ }
10932 -+}
10933 -+
10934 -+#[cfg(any(target_os = "macos", target_os = "ios"))]
10935 -+mod consts {
10936 -+ use libc;
10937 -+
10938 -+ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
10939 -+ #[repr(i32)]
10940 -+ pub enum Errno {
10941 -+ UnknownErrno = 0,
10942 -+ EPERM = libc::EPERM,
10943 -+ ENOENT = libc::ENOENT,
10944 -+ ESRCH = libc::ESRCH,
10945 -+ EINTR = libc::EINTR,
10946 -+ EIO = libc::EIO,
10947 -+ ENXIO = libc::ENXIO,
10948 -+ E2BIG = libc::E2BIG,
10949 -+ ENOEXEC = libc::ENOEXEC,
10950 -+ EBADF = libc::EBADF,
10951 -+ ECHILD = libc::ECHILD,
10952 -+ EDEADLK = libc::EDEADLK,
10953 -+ ENOMEM = libc::ENOMEM,
10954 -+ EACCES = libc::EACCES,
10955 -+ EFAULT = libc::EFAULT,
10956 -+ ENOTBLK = libc::ENOTBLK,
10957 -+ EBUSY = libc::EBUSY,
10958 -+ EEXIST = libc::EEXIST,
10959 -+ EXDEV = libc::EXDEV,
10960 -+ ENODEV = libc::ENODEV,
10961 -+ ENOTDIR = libc::ENOTDIR,
10962 -+ EISDIR = libc::EISDIR,
10963 -+ EINVAL = libc::EINVAL,
10964 -+ ENFILE = libc::ENFILE,
10965 -+ EMFILE = libc::EMFILE,
10966 -+ ENOTTY = libc::ENOTTY,
10967 -+ ETXTBSY = libc::ETXTBSY,
10968 -+ EFBIG = libc::EFBIG,
10969 -+ ENOSPC = libc::ENOSPC,
10970 -+ ESPIPE = libc::ESPIPE,
10971 -+ EROFS = libc::EROFS,
10972 -+ EMLINK = libc::EMLINK,
10973 -+ EPIPE = libc::EPIPE,
10974 -+ EDOM = libc::EDOM,
10975 -+ ERANGE = libc::ERANGE,
10976 -+ EAGAIN = libc::EAGAIN,
10977 -+ EINPROGRESS = libc::EINPROGRESS,
10978 -+ EALREADY = libc::EALREADY,
10979 -+ ENOTSOCK = libc::ENOTSOCK,
10980 -+ EDESTADDRREQ = libc::EDESTADDRREQ,
10981 -+ EMSGSIZE = libc::EMSGSIZE,
10982 -+ EPROTOTYPE = libc::EPROTOTYPE,
10983 -+ ENOPROTOOPT = libc::ENOPROTOOPT,
10984 -+ EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
10985 -+ ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
10986 -+ ENOTSUP = libc::ENOTSUP,
10987 -+ EPFNOSUPPORT = libc::EPFNOSUPPORT,
10988 -+ EAFNOSUPPORT = libc::EAFNOSUPPORT,
10989 -+ EADDRINUSE = libc::EADDRINUSE,
10990 -+ EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
10991 -+ ENETDOWN = libc::ENETDOWN,
10992 -+ ENETUNREACH = libc::ENETUNREACH,
10993 -+ ENETRESET = libc::ENETRESET,
10994 -+ ECONNABORTED = libc::ECONNABORTED,
10995 -+ ECONNRESET = libc::ECONNRESET,
10996 -+ ENOBUFS = libc::ENOBUFS,
10997 -+ EISCONN = libc::EISCONN,
10998 -+ ENOTCONN = libc::ENOTCONN,
10999 -+ ESHUTDOWN = libc::ESHUTDOWN,
11000 -+ ETOOMANYREFS = libc::ETOOMANYREFS,
11001 -+ ETIMEDOUT = libc::ETIMEDOUT,
11002 -+ ECONNREFUSED = libc::ECONNREFUSED,
11003 -+ ELOOP = libc::ELOOP,
11004 -+ ENAMETOOLONG = libc::ENAMETOOLONG,
11005 -+ EHOSTDOWN = libc::EHOSTDOWN,
11006 -+ EHOSTUNREACH = libc::EHOSTUNREACH,
11007 -+ ENOTEMPTY = libc::ENOTEMPTY,
11008 -+ EPROCLIM = libc::EPROCLIM,
11009 -+ EUSERS = libc::EUSERS,
11010 -+ EDQUOT = libc::EDQUOT,
11011 -+ ESTALE = libc::ESTALE,
11012 -+ EREMOTE = libc::EREMOTE,
11013 -+ EBADRPC = libc::EBADRPC,
11014 -+ ERPCMISMATCH = libc::ERPCMISMATCH,
11015 -+ EPROGUNAVAIL = libc::EPROGUNAVAIL,
11016 -+ EPROGMISMATCH = libc::EPROGMISMATCH,
11017 -+ EPROCUNAVAIL = libc::EPROCUNAVAIL,
11018 -+ ENOLCK = libc::ENOLCK,
11019 -+ ENOSYS = libc::ENOSYS,
11020 -+ EFTYPE = libc::EFTYPE,
11021 -+ EAUTH = libc::EAUTH,
11022 -+ ENEEDAUTH = libc::ENEEDAUTH,
11023 -+ EPWROFF = libc::EPWROFF,
11024 -+ EDEVERR = libc::EDEVERR,
11025 -+ EOVERFLOW = libc::EOVERFLOW,
11026 -+ EBADEXEC = libc::EBADEXEC,
11027 -+ EBADARCH = libc::EBADARCH,
11028 -+ ESHLIBVERS = libc::ESHLIBVERS,
11029 -+ EBADMACHO = libc::EBADMACHO,
11030 -+ ECANCELED = libc::ECANCELED,
11031 -+ EIDRM = libc::EIDRM,
11032 -+ ENOMSG = libc::ENOMSG,
11033 -+ EILSEQ = libc::EILSEQ,
11034 -+ ENOATTR = libc::ENOATTR,
11035 -+ EBADMSG = libc::EBADMSG,
11036 -+ EMULTIHOP = libc::EMULTIHOP,
11037 -+ ENODATA = libc::ENODATA,
11038 -+ ENOLINK = libc::ENOLINK,
11039 -+ ENOSR = libc::ENOSR,
11040 -+ ENOSTR = libc::ENOSTR,
11041 -+ EPROTO = libc::EPROTO,
11042 -+ ETIME = libc::ETIME,
11043 -+ EOPNOTSUPP = libc::EOPNOTSUPP,
11044 -+ ENOPOLICY = libc::ENOPOLICY,
11045 -+ ENOTRECOVERABLE = libc::ENOTRECOVERABLE,
11046 -+ EOWNERDEAD = libc::EOWNERDEAD,
11047 -+ EQFULL = libc::EQFULL,
11048 -+ }
11049 -+
11050 -+ pub const ELAST: Errno = Errno::EQFULL;
11051 -+ pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
11052 -+ pub const EDEADLOCK: Errno = Errno::EDEADLK;
11053 -+
11054 -+ pub const EL2NSYNC: Errno = Errno::UnknownErrno;
11055 -+
11056 -+ pub fn from_i32(e: i32) -> Errno {
11057 -+ use self::Errno::*;
11058 -+
11059 -+ match e {
11060 -+ libc::EPERM => EPERM,
11061 -+ libc::ENOENT => ENOENT,
11062 -+ libc::ESRCH => ESRCH,
11063 -+ libc::EINTR => EINTR,
11064 -+ libc::EIO => EIO,
11065 -+ libc::ENXIO => ENXIO,
11066 -+ libc::E2BIG => E2BIG,
11067 -+ libc::ENOEXEC => ENOEXEC,
11068 -+ libc::EBADF => EBADF,
11069 -+ libc::ECHILD => ECHILD,
11070 -+ libc::EDEADLK => EDEADLK,
11071 -+ libc::ENOMEM => ENOMEM,
11072 -+ libc::EACCES => EACCES,
11073 -+ libc::EFAULT => EFAULT,
11074 -+ libc::ENOTBLK => ENOTBLK,
11075 -+ libc::EBUSY => EBUSY,
11076 -+ libc::EEXIST => EEXIST,
11077 -+ libc::EXDEV => EXDEV,
11078 -+ libc::ENODEV => ENODEV,
11079 -+ libc::ENOTDIR => ENOTDIR,
11080 -+ libc::EISDIR => EISDIR,
11081 -+ libc::EINVAL => EINVAL,
11082 -+ libc::ENFILE => ENFILE,
11083 -+ libc::EMFILE => EMFILE,
11084 -+ libc::ENOTTY => ENOTTY,
11085 -+ libc::ETXTBSY => ETXTBSY,
11086 -+ libc::EFBIG => EFBIG,
11087 -+ libc::ENOSPC => ENOSPC,
11088 -+ libc::ESPIPE => ESPIPE,
11089 -+ libc::EROFS => EROFS,
11090 -+ libc::EMLINK => EMLINK,
11091 -+ libc::EPIPE => EPIPE,
11092 -+ libc::EDOM => EDOM,
11093 -+ libc::ERANGE => ERANGE,
11094 -+ libc::EAGAIN => EAGAIN,
11095 -+ libc::EINPROGRESS => EINPROGRESS,
11096 -+ libc::EALREADY => EALREADY,
11097 -+ libc::ENOTSOCK => ENOTSOCK,
11098 -+ libc::EDESTADDRREQ => EDESTADDRREQ,
11099 -+ libc::EMSGSIZE => EMSGSIZE,
11100 -+ libc::EPROTOTYPE => EPROTOTYPE,
11101 -+ libc::ENOPROTOOPT => ENOPROTOOPT,
11102 -+ libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
11103 -+ libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
11104 -+ libc::ENOTSUP => ENOTSUP,
11105 -+ libc::EPFNOSUPPORT => EPFNOSUPPORT,
11106 -+ libc::EAFNOSUPPORT => EAFNOSUPPORT,
11107 -+ libc::EADDRINUSE => EADDRINUSE,
11108 -+ libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
11109 -+ libc::ENETDOWN => ENETDOWN,
11110 -+ libc::ENETUNREACH => ENETUNREACH,
11111 -+ libc::ENETRESET => ENETRESET,
11112 -+ libc::ECONNABORTED => ECONNABORTED,
11113 -+ libc::ECONNRESET => ECONNRESET,
11114 -+ libc::ENOBUFS => ENOBUFS,
11115 -+ libc::EISCONN => EISCONN,
11116 -+ libc::ENOTCONN => ENOTCONN,
11117 -+ libc::ESHUTDOWN => ESHUTDOWN,
11118 -+ libc::ETOOMANYREFS => ETOOMANYREFS,
11119 -+ libc::ETIMEDOUT => ETIMEDOUT,
11120 -+ libc::ECONNREFUSED => ECONNREFUSED,
11121 -+ libc::ELOOP => ELOOP,
11122 -+ libc::ENAMETOOLONG => ENAMETOOLONG,
11123 -+ libc::EHOSTDOWN => EHOSTDOWN,
11124 -+ libc::EHOSTUNREACH => EHOSTUNREACH,
11125 -+ libc::ENOTEMPTY => ENOTEMPTY,
11126 -+ libc::EPROCLIM => EPROCLIM,
11127 -+ libc::EUSERS => EUSERS,
11128 -+ libc::EDQUOT => EDQUOT,
11129 -+ libc::ESTALE => ESTALE,
11130 -+ libc::EREMOTE => EREMOTE,
11131 -+ libc::EBADRPC => EBADRPC,
11132 -+ libc::ERPCMISMATCH => ERPCMISMATCH,
11133 -+ libc::EPROGUNAVAIL => EPROGUNAVAIL,
11134 -+ libc::EPROGMISMATCH => EPROGMISMATCH,
11135 -+ libc::EPROCUNAVAIL => EPROCUNAVAIL,
11136 -+ libc::ENOLCK => ENOLCK,
11137 -+ libc::ENOSYS => ENOSYS,
11138 -+ libc::EFTYPE => EFTYPE,
11139 -+ libc::EAUTH => EAUTH,
11140 -+ libc::ENEEDAUTH => ENEEDAUTH,
11141 -+ libc::EPWROFF => EPWROFF,
11142 -+ libc::EDEVERR => EDEVERR,
11143 -+ libc::EOVERFLOW => EOVERFLOW,
11144 -+ libc::EBADEXEC => EBADEXEC,
11145 -+ libc::EBADARCH => EBADARCH,
11146 -+ libc::ESHLIBVERS => ESHLIBVERS,
11147 -+ libc::EBADMACHO => EBADMACHO,
11148 -+ libc::ECANCELED => ECANCELED,
11149 -+ libc::EIDRM => EIDRM,
11150 -+ libc::ENOMSG => ENOMSG,
11151 -+ libc::EILSEQ => EILSEQ,
11152 -+ libc::ENOATTR => ENOATTR,
11153 -+ libc::EBADMSG => EBADMSG,
11154 -+ libc::EMULTIHOP => EMULTIHOP,
11155 -+ libc::ENODATA => ENODATA,
11156 -+ libc::ENOLINK => ENOLINK,
11157 -+ libc::ENOSR => ENOSR,
11158 -+ libc::ENOSTR => ENOSTR,
11159 -+ libc::EPROTO => EPROTO,
11160 -+ libc::ETIME => ETIME,
11161 -+ libc::EOPNOTSUPP => EOPNOTSUPP,
11162 -+ libc::ENOPOLICY => ENOPOLICY,
11163 -+ libc::ENOTRECOVERABLE => ENOTRECOVERABLE,
11164 -+ libc::EOWNERDEAD => EOWNERDEAD,
11165 -+ libc::EQFULL => EQFULL,
11166 -+ _ => UnknownErrno,
11167 -+ }
11168 -+ }
11169 -+}
11170 -+
11171 -+#[cfg(target_os = "freebsd")]
11172 -+mod consts {
11173 -+ use libc;
11174 -+
11175 -+ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
11176 -+ #[repr(i32)]
11177 -+ pub enum Errno {
11178 -+ UnknownErrno = 0,
11179 -+ EPERM = libc::EPERM,
11180 -+ ENOENT = libc::ENOENT,
11181 -+ ESRCH = libc::ESRCH,
11182 -+ EINTR = libc::EINTR,
11183 -+ EIO = libc::EIO,
11184 -+ ENXIO = libc::ENXIO,
11185 -+ E2BIG = libc::E2BIG,
11186 -+ ENOEXEC = libc::ENOEXEC,
11187 -+ EBADF = libc::EBADF,
11188 -+ ECHILD = libc::ECHILD,
11189 -+ EDEADLK = libc::EDEADLK,
11190 -+ ENOMEM = libc::ENOMEM,
11191 -+ EACCES = libc::EACCES,
11192 -+ EFAULT = libc::EFAULT,
11193 -+ ENOTBLK = libc::ENOTBLK,
11194 -+ EBUSY = libc::EBUSY,
11195 -+ EEXIST = libc::EEXIST,
11196 -+ EXDEV = libc::EXDEV,
11197 -+ ENODEV = libc::ENODEV,
11198 -+ ENOTDIR = libc::ENOTDIR,
11199 -+ EISDIR = libc::EISDIR,
11200 -+ EINVAL = libc::EINVAL,
11201 -+ ENFILE = libc::ENFILE,
11202 -+ EMFILE = libc::EMFILE,
11203 -+ ENOTTY = libc::ENOTTY,
11204 -+ ETXTBSY = libc::ETXTBSY,
11205 -+ EFBIG = libc::EFBIG,
11206 -+ ENOSPC = libc::ENOSPC,
11207 -+ ESPIPE = libc::ESPIPE,
11208 -+ EROFS = libc::EROFS,
11209 -+ EMLINK = libc::EMLINK,
11210 -+ EPIPE = libc::EPIPE,
11211 -+ EDOM = libc::EDOM,
11212 -+ ERANGE = libc::ERANGE,
11213 -+ EAGAIN = libc::EAGAIN,
11214 -+ EINPROGRESS = libc::EINPROGRESS,
11215 -+ EALREADY = libc::EALREADY,
11216 -+ ENOTSOCK = libc::ENOTSOCK,
11217 -+ EDESTADDRREQ = libc::EDESTADDRREQ,
11218 -+ EMSGSIZE = libc::EMSGSIZE,
11219 -+ EPROTOTYPE = libc::EPROTOTYPE,
11220 -+ ENOPROTOOPT = libc::ENOPROTOOPT,
11221 -+ EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
11222 -+ ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
11223 -+ ENOTSUP = libc::ENOTSUP,
11224 -+ EPFNOSUPPORT = libc::EPFNOSUPPORT,
11225 -+ EAFNOSUPPORT = libc::EAFNOSUPPORT,
11226 -+ EADDRINUSE = libc::EADDRINUSE,
11227 -+ EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
11228 -+ ENETDOWN = libc::ENETDOWN,
11229 -+ ENETUNREACH = libc::ENETUNREACH,
11230 -+ ENETRESET = libc::ENETRESET,
11231 -+ ECONNABORTED = libc::ECONNABORTED,
11232 -+ ECONNRESET = libc::ECONNRESET,
11233 -+ ENOBUFS = libc::ENOBUFS,
11234 -+ EISCONN = libc::EISCONN,
11235 -+ ENOTCONN = libc::ENOTCONN,
11236 -+ ESHUTDOWN = libc::ESHUTDOWN,
11237 -+ ETOOMANYREFS = libc::ETOOMANYREFS,
11238 -+ ETIMEDOUT = libc::ETIMEDOUT,
11239 -+ ECONNREFUSED = libc::ECONNREFUSED,
11240 -+ ELOOP = libc::ELOOP,
11241 -+ ENAMETOOLONG = libc::ENAMETOOLONG,
11242 -+ EHOSTDOWN = libc::EHOSTDOWN,
11243 -+ EHOSTUNREACH = libc::EHOSTUNREACH,
11244 -+ ENOTEMPTY = libc::ENOTEMPTY,
11245 -+ EPROCLIM = libc::EPROCLIM,
11246 -+ EUSERS = libc::EUSERS,
11247 -+ EDQUOT = libc::EDQUOT,
11248 -+ ESTALE = libc::ESTALE,
11249 -+ EREMOTE = libc::EREMOTE,
11250 -+ EBADRPC = libc::EBADRPC,
11251 -+ ERPCMISMATCH = libc::ERPCMISMATCH,
11252 -+ EPROGUNAVAIL = libc::EPROGUNAVAIL,
11253 -+ EPROGMISMATCH = libc::EPROGMISMATCH,
11254 -+ EPROCUNAVAIL = libc::EPROCUNAVAIL,
11255 -+ ENOLCK = libc::ENOLCK,
11256 -+ ENOSYS = libc::ENOSYS,
11257 -+ EFTYPE = libc::EFTYPE,
11258 -+ EAUTH = libc::EAUTH,
11259 -+ ENEEDAUTH = libc::ENEEDAUTH,
11260 -+ EIDRM = libc::EIDRM,
11261 -+ ENOMSG = libc::ENOMSG,
11262 -+ EOVERFLOW = libc::EOVERFLOW,
11263 -+ ECANCELED = libc::ECANCELED,
11264 -+ EILSEQ = libc::EILSEQ,
11265 -+ ENOATTR = libc::ENOATTR,
11266 -+ EDOOFUS = libc::EDOOFUS,
11267 -+ EBADMSG = libc::EBADMSG,
11268 -+ EMULTIHOP = libc::EMULTIHOP,
11269 -+ ENOLINK = libc::ENOLINK,
11270 -+ EPROTO = libc::EPROTO,
11271 -+ ENOTCAPABLE = libc::ENOTCAPABLE,
11272 -+ ECAPMODE = libc::ECAPMODE,
11273 -+ ENOTRECOVERABLE = libc::ENOTRECOVERABLE,
11274 -+ EOWNERDEAD = libc::EOWNERDEAD,
11275 -+ }
11276 -+
11277 -+ pub const ELAST: Errno = Errno::EOWNERDEAD;
11278 -+ pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
11279 -+ pub const EDEADLOCK: Errno = Errno::EDEADLK;
11280 -+
11281 -+ pub const EL2NSYNC: Errno = Errno::UnknownErrno;
11282 -+
11283 -+ pub fn from_i32(e: i32) -> Errno {
11284 -+ use self::Errno::*;
11285 -+
11286 -+ match e {
11287 -+ libc::EPERM => EPERM,
11288 -+ libc::ENOENT => ENOENT,
11289 -+ libc::ESRCH => ESRCH,
11290 -+ libc::EINTR => EINTR,
11291 -+ libc::EIO => EIO,
11292 -+ libc::ENXIO => ENXIO,
11293 -+ libc::E2BIG => E2BIG,
11294 -+ libc::ENOEXEC => ENOEXEC,
11295 -+ libc::EBADF => EBADF,
11296 -+ libc::ECHILD => ECHILD,
11297 -+ libc::EDEADLK => EDEADLK,
11298 -+ libc::ENOMEM => ENOMEM,
11299 -+ libc::EACCES => EACCES,
11300 -+ libc::EFAULT => EFAULT,
11301 -+ libc::ENOTBLK => ENOTBLK,
11302 -+ libc::EBUSY => EBUSY,
11303 -+ libc::EEXIST => EEXIST,
11304 -+ libc::EXDEV => EXDEV,
11305 -+ libc::ENODEV => ENODEV,
11306 -+ libc::ENOTDIR => ENOTDIR,
11307 -+ libc::EISDIR => EISDIR,
11308 -+ libc::EINVAL => EINVAL,
11309 -+ libc::ENFILE => ENFILE,
11310 -+ libc::EMFILE => EMFILE,
11311 -+ libc::ENOTTY => ENOTTY,
11312 -+ libc::ETXTBSY => ETXTBSY,
11313 -+ libc::EFBIG => EFBIG,
11314 -+ libc::ENOSPC => ENOSPC,
11315 -+ libc::ESPIPE => ESPIPE,
11316 -+ libc::EROFS => EROFS,
11317 -+ libc::EMLINK => EMLINK,
11318 -+ libc::EPIPE => EPIPE,
11319 -+ libc::EDOM => EDOM,
11320 -+ libc::ERANGE => ERANGE,
11321 -+ libc::EAGAIN => EAGAIN,
11322 -+ libc::EINPROGRESS => EINPROGRESS,
11323 -+ libc::EALREADY => EALREADY,
11324 -+ libc::ENOTSOCK => ENOTSOCK,
11325 -+ libc::EDESTADDRREQ => EDESTADDRREQ,
11326 -+ libc::EMSGSIZE => EMSGSIZE,
11327 -+ libc::EPROTOTYPE => EPROTOTYPE,
11328 -+ libc::ENOPROTOOPT => ENOPROTOOPT,
11329 -+ libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
11330 -+ libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
11331 -+ libc::ENOTSUP => ENOTSUP,
11332 -+ libc::EPFNOSUPPORT => EPFNOSUPPORT,
11333 -+ libc::EAFNOSUPPORT => EAFNOSUPPORT,
11334 -+ libc::EADDRINUSE => EADDRINUSE,
11335 -+ libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
11336 -+ libc::ENETDOWN => ENETDOWN,
11337 -+ libc::ENETUNREACH => ENETUNREACH,
11338 -+ libc::ENETRESET => ENETRESET,
11339 -+ libc::ECONNABORTED => ECONNABORTED,
11340 -+ libc::ECONNRESET => ECONNRESET,
11341 -+ libc::ENOBUFS => ENOBUFS,
11342 -+ libc::EISCONN => EISCONN,
11343 -+ libc::ENOTCONN => ENOTCONN,
11344 -+ libc::ESHUTDOWN => ESHUTDOWN,
11345 -+ libc::ETOOMANYREFS => ETOOMANYREFS,
11346 -+ libc::ETIMEDOUT => ETIMEDOUT,
11347 -+ libc::ECONNREFUSED => ECONNREFUSED,
11348 -+ libc::ELOOP => ELOOP,
11349 -+ libc::ENAMETOOLONG => ENAMETOOLONG,
11350 -+ libc::EHOSTDOWN => EHOSTDOWN,
11351 -+ libc::EHOSTUNREACH => EHOSTUNREACH,
11352 -+ libc::ENOTEMPTY => ENOTEMPTY,
11353 -+ libc::EPROCLIM => EPROCLIM,
11354 -+ libc::EUSERS => EUSERS,
11355 -+ libc::EDQUOT => EDQUOT,
11356 -+ libc::ESTALE => ESTALE,
11357 -+ libc::EREMOTE => EREMOTE,
11358 -+ libc::EBADRPC => EBADRPC,
11359 -+ libc::ERPCMISMATCH => ERPCMISMATCH,
11360 -+ libc::EPROGUNAVAIL => EPROGUNAVAIL,
11361 -+ libc::EPROGMISMATCH => EPROGMISMATCH,
11362 -+ libc::EPROCUNAVAIL => EPROCUNAVAIL,
11363 -+ libc::ENOLCK => ENOLCK,
11364 -+ libc::ENOSYS => ENOSYS,
11365 -+ libc::EFTYPE => EFTYPE,
11366 -+ libc::EAUTH => EAUTH,
11367 -+ libc::ENEEDAUTH => ENEEDAUTH,
11368 -+ libc::EIDRM => EIDRM,
11369 -+ libc::ENOMSG => ENOMSG,
11370 -+ libc::EOVERFLOW => EOVERFLOW,
11371 -+ libc::ECANCELED => ECANCELED,
11372 -+ libc::EILSEQ => EILSEQ,
11373 -+ libc::ENOATTR => ENOATTR,
11374 -+ libc::EDOOFUS => EDOOFUS,
11375 -+ libc::EBADMSG => EBADMSG,
11376 -+ libc::EMULTIHOP => EMULTIHOP,
11377 -+ libc::ENOLINK => ENOLINK,
11378 -+ libc::EPROTO => EPROTO,
11379 -+ libc::ENOTCAPABLE => ENOTCAPABLE,
11380 -+ libc::ECAPMODE => ECAPMODE,
11381 -+ libc::ENOTRECOVERABLE => ENOTRECOVERABLE,
11382 -+ libc::EOWNERDEAD => EOWNERDEAD,
11383 -+ _ => UnknownErrno,
11384 -+ }
11385 -+ }
11386 -+}
11387 -+
11388 -+
11389 -+#[cfg(target_os = "dragonfly")]
11390 -+mod consts {
11391 -+ use libc;
11392 -+
11393 -+ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
11394 -+ #[repr(i32)]
11395 -+ pub enum Errno {
11396 -+ UnknownErrno = 0,
11397 -+ EPERM = libc::EPERM,
11398 -+ ENOENT = libc::ENOENT,
11399 -+ ESRCH = libc::ESRCH,
11400 -+ EINTR = libc::EINTR,
11401 -+ EIO = libc::EIO,
11402 -+ ENXIO = libc::ENXIO,
11403 -+ E2BIG = libc::E2BIG,
11404 -+ ENOEXEC = libc::ENOEXEC,
11405 -+ EBADF = libc::EBADF,
11406 -+ ECHILD = libc::ECHILD,
11407 -+ EDEADLK = libc::EDEADLK,
11408 -+ ENOMEM = libc::ENOMEM,
11409 -+ EACCES = libc::EACCES,
11410 -+ EFAULT = libc::EFAULT,
11411 -+ ENOTBLK = libc::ENOTBLK,
11412 -+ EBUSY = libc::EBUSY,
11413 -+ EEXIST = libc::EEXIST,
11414 -+ EXDEV = libc::EXDEV,
11415 -+ ENODEV = libc::ENODEV,
11416 -+ ENOTDIR = libc::ENOTDIR,
11417 -+ EISDIR = libc::EISDIR,
11418 -+ EINVAL = libc::EINVAL,
11419 -+ ENFILE = libc::ENFILE,
11420 -+ EMFILE = libc::EMFILE,
11421 -+ ENOTTY = libc::ENOTTY,
11422 -+ ETXTBSY = libc::ETXTBSY,
11423 -+ EFBIG = libc::EFBIG,
11424 -+ ENOSPC = libc::ENOSPC,
11425 -+ ESPIPE = libc::ESPIPE,
11426 -+ EROFS = libc::EROFS,
11427 -+ EMLINK = libc::EMLINK,
11428 -+ EPIPE = libc::EPIPE,
11429 -+ EDOM = libc::EDOM,
11430 -+ ERANGE = libc::ERANGE,
11431 -+ EAGAIN = libc::EAGAIN,
11432 -+ EINPROGRESS = libc::EINPROGRESS,
11433 -+ EALREADY = libc::EALREADY,
11434 -+ ENOTSOCK = libc::ENOTSOCK,
11435 -+ EDESTADDRREQ = libc::EDESTADDRREQ,
11436 -+ EMSGSIZE = libc::EMSGSIZE,
11437 -+ EPROTOTYPE = libc::EPROTOTYPE,
11438 -+ ENOPROTOOPT = libc::ENOPROTOOPT,
11439 -+ EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
11440 -+ ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
11441 -+ ENOTSUP = libc::ENOTSUP,
11442 -+ EPFNOSUPPORT = libc::EPFNOSUPPORT,
11443 -+ EAFNOSUPPORT = libc::EAFNOSUPPORT,
11444 -+ EADDRINUSE = libc::EADDRINUSE,
11445 -+ EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
11446 -+ ENETDOWN = libc::ENETDOWN,
11447 -+ ENETUNREACH = libc::ENETUNREACH,
11448 -+ ENETRESET = libc::ENETRESET,
11449 -+ ECONNABORTED = libc::ECONNABORTED,
11450 -+ ECONNRESET = libc::ECONNRESET,
11451 -+ ENOBUFS = libc::ENOBUFS,
11452 -+ EISCONN = libc::EISCONN,
11453 -+ ENOTCONN = libc::ENOTCONN,
11454 -+ ESHUTDOWN = libc::ESHUTDOWN,
11455 -+ ETOOMANYREFS = libc::ETOOMANYREFS,
11456 -+ ETIMEDOUT = libc::ETIMEDOUT,
11457 -+ ECONNREFUSED = libc::ECONNREFUSED,
11458 -+ ELOOP = libc::ELOOP,
11459 -+ ENAMETOOLONG = libc::ENAMETOOLONG,
11460 -+ EHOSTDOWN = libc::EHOSTDOWN,
11461 -+ EHOSTUNREACH = libc::EHOSTUNREACH,
11462 -+ ENOTEMPTY = libc::ENOTEMPTY,
11463 -+ EPROCLIM = libc::EPROCLIM,
11464 -+ EUSERS = libc::EUSERS,
11465 -+ EDQUOT = libc::EDQUOT,
11466 -+ ESTALE = libc::ESTALE,
11467 -+ EREMOTE = libc::EREMOTE,
11468 -+ EBADRPC = libc::EBADRPC,
11469 -+ ERPCMISMATCH = libc::ERPCMISMATCH,
11470 -+ EPROGUNAVAIL = libc::EPROGUNAVAIL,
11471 -+ EPROGMISMATCH = libc::EPROGMISMATCH,
11472 -+ EPROCUNAVAIL = libc::EPROCUNAVAIL,
11473 -+ ENOLCK = libc::ENOLCK,
11474 -+ ENOSYS = libc::ENOSYS,
11475 -+ EFTYPE = libc::EFTYPE,
11476 -+ EAUTH = libc::EAUTH,
11477 -+ ENEEDAUTH = libc::ENEEDAUTH,
11478 -+ EIDRM = libc::EIDRM,
11479 -+ ENOMSG = libc::ENOMSG,
11480 -+ EOVERFLOW = libc::EOVERFLOW,
11481 -+ ECANCELED = libc::ECANCELED,
11482 -+ EILSEQ = libc::EILSEQ,
11483 -+ ENOATTR = libc::ENOATTR,
11484 -+ EDOOFUS = libc::EDOOFUS,
11485 -+ EBADMSG = libc::EBADMSG,
11486 -+ EMULTIHOP = libc::EMULTIHOP,
11487 -+ ENOLINK = libc::ENOLINK,
11488 -+ EPROTO = libc::EPROTO,
11489 -+ ENOMEDIUM = libc::ENOMEDIUM,
11490 -+ EASYNC = libc::EASYNC,
11491 -+ }
11492 -+
11493 -+ pub const ELAST: Errno = Errno::EASYNC;
11494 -+ pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
11495 -+ pub const EDEADLOCK: Errno = Errno::EDEADLK;
11496 -+ pub const EOPNOTSUPP: Errno = Errno::ENOTSUP;
11497 -+
11498 -+ pub const EL2NSYNC: Errno = Errno::UnknownErrno;
11499 -+
11500 -+ pub fn from_i32(e: i32) -> Errno {
11501 -+ use self::Errno::*;
11502 -+
11503 -+ match e {
11504 -+ libc::EPERM => EPERM,
11505 -+ libc::ENOENT => ENOENT,
11506 -+ libc::ESRCH => ESRCH,
11507 -+ libc::EINTR => EINTR,
11508 -+ libc::EIO => EIO,
11509 -+ libc::ENXIO => ENXIO,
11510 -+ libc::E2BIG => E2BIG,
11511 -+ libc::ENOEXEC => ENOEXEC,
11512 -+ libc::EBADF => EBADF,
11513 -+ libc::ECHILD => ECHILD,
11514 -+ libc::EDEADLK => EDEADLK,
11515 -+ libc::ENOMEM => ENOMEM,
11516 -+ libc::EACCES => EACCES,
11517 -+ libc::EFAULT => EFAULT,
11518 -+ libc::ENOTBLK => ENOTBLK,
11519 -+ libc::EBUSY => EBUSY,
11520 -+ libc::EEXIST => EEXIST,
11521 -+ libc::EXDEV => EXDEV,
11522 -+ libc::ENODEV => ENODEV,
11523 -+ libc::ENOTDIR => ENOTDIR,
11524 -+ libc::EISDIR=> EISDIR,
11525 -+ libc::EINVAL => EINVAL,
11526 -+ libc::ENFILE => ENFILE,
11527 -+ libc::EMFILE => EMFILE,
11528 -+ libc::ENOTTY => ENOTTY,
11529 -+ libc::ETXTBSY => ETXTBSY,
11530 -+ libc::EFBIG => EFBIG,
11531 -+ libc::ENOSPC => ENOSPC,
11532 -+ libc::ESPIPE => ESPIPE,
11533 -+ libc::EROFS => EROFS,
11534 -+ libc::EMLINK => EMLINK,
11535 -+ libc::EPIPE => EPIPE,
11536 -+ libc::EDOM => EDOM,
11537 -+ libc::ERANGE => ERANGE,
11538 -+ libc::EAGAIN => EAGAIN,
11539 -+ libc::EINPROGRESS => EINPROGRESS,
11540 -+ libc::EALREADY => EALREADY,
11541 -+ libc::ENOTSOCK => ENOTSOCK,
11542 -+ libc::EDESTADDRREQ => EDESTADDRREQ,
11543 -+ libc::EMSGSIZE => EMSGSIZE,
11544 -+ libc::EPROTOTYPE => EPROTOTYPE,
11545 -+ libc::ENOPROTOOPT => ENOPROTOOPT,
11546 -+ libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
11547 -+ libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
11548 -+ libc::ENOTSUP => ENOTSUP,
11549 -+ libc::EPFNOSUPPORT => EPFNOSUPPORT,
11550 -+ libc::EAFNOSUPPORT => EAFNOSUPPORT,
11551 -+ libc::EADDRINUSE => EADDRINUSE,
11552 -+ libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
11553 -+ libc::ENETDOWN => ENETDOWN,
11554 -+ libc::ENETUNREACH => ENETUNREACH,
11555 -+ libc::ENETRESET => ENETRESET,
11556 -+ libc::ECONNABORTED => ECONNABORTED,
11557 -+ libc::ECONNRESET => ECONNRESET,
11558 -+ libc::ENOBUFS => ENOBUFS,
11559 -+ libc::EISCONN => EISCONN,
11560 -+ libc::ENOTCONN => ENOTCONN,
11561 -+ libc::ESHUTDOWN => ESHUTDOWN,
11562 -+ libc::ETOOMANYREFS => ETOOMANYREFS,
11563 -+ libc::ETIMEDOUT => ETIMEDOUT,
11564 -+ libc::ECONNREFUSED => ECONNREFUSED,
11565 -+ libc::ELOOP => ELOOP,
11566 -+ libc::ENAMETOOLONG => ENAMETOOLONG,
11567 -+ libc::EHOSTDOWN => EHOSTDOWN,
11568 -+ libc::EHOSTUNREACH => EHOSTUNREACH,
11569 -+ libc::ENOTEMPTY => ENOTEMPTY,
11570 -+ libc::EPROCLIM => EPROCLIM,
11571 -+ libc::EUSERS => EUSERS,
11572 -+ libc::EDQUOT => EDQUOT,
11573 -+ libc::ESTALE => ESTALE,
11574 -+ libc::EREMOTE => EREMOTE,
11575 -+ libc::EBADRPC => EBADRPC,
11576 -+ libc::ERPCMISMATCH => ERPCMISMATCH,
11577 -+ libc::EPROGUNAVAIL => EPROGUNAVAIL,
11578 -+ libc::EPROGMISMATCH => EPROGMISMATCH,
11579 -+ libc::EPROCUNAVAIL => EPROCUNAVAIL,
11580 -+ libc::ENOLCK => ENOLCK,
11581 -+ libc::ENOSYS => ENOSYS,
11582 -+ libc::EFTYPE => EFTYPE,
11583 -+ libc::EAUTH => EAUTH,
11584 -+ libc::ENEEDAUTH => ENEEDAUTH,
11585 -+ libc::EIDRM => EIDRM,
11586 -+ libc::ENOMSG => ENOMSG,
11587 -+ libc::EOVERFLOW => EOVERFLOW,
11588 -+ libc::ECANCELED => ECANCELED,
11589 -+ libc::EILSEQ => EILSEQ,
11590 -+ libc::ENOATTR => ENOATTR,
11591 -+ libc::EDOOFUS => EDOOFUS,
11592 -+ libc::EBADMSG => EBADMSG,
11593 -+ libc::EMULTIHOP => EMULTIHOP,
11594 -+ libc::ENOLINK => ENOLINK,
11595 -+ libc::EPROTO => EPROTO,
11596 -+ libc::ENOMEDIUM => ENOMEDIUM,
11597 -+ libc::EASYNC => EASYNC,
11598 -+ _ => UnknownErrno,
11599 -+ }
11600 -+ }
11601 -+}
11602 -+
11603 -+
11604 -+#[cfg(target_os = "openbsd")]
11605 -+mod consts {
11606 -+ use libc;
11607 -+
11608 -+ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
11609 -+ #[repr(i32)]
11610 -+ pub enum Errno {
11611 -+ UnknownErrno = 0,
11612 -+ EPERM = libc::EPERM,
11613 -+ ENOENT = libc::ENOENT,
11614 -+ ESRCH = libc::ESRCH,
11615 -+ EINTR = libc::EINTR,
11616 -+ EIO = libc::EIO,
11617 -+ ENXIO = libc::ENXIO,
11618 -+ E2BIG = libc::E2BIG,
11619 -+ ENOEXEC = libc::ENOEXEC,
11620 -+ EBADF = libc::EBADF,
11621 -+ ECHILD = libc::ECHILD,
11622 -+ EDEADLK = libc::EDEADLK,
11623 -+ ENOMEM = libc::ENOMEM,
11624 -+ EACCES = libc::EACCES,
11625 -+ EFAULT = libc::EFAULT,
11626 -+ ENOTBLK = libc::ENOTBLK,
11627 -+ EBUSY = libc::EBUSY,
11628 -+ EEXIST = libc::EEXIST,
11629 -+ EXDEV = libc::EXDEV,
11630 -+ ENODEV = libc::ENODEV,
11631 -+ ENOTDIR = libc::ENOTDIR,
11632 -+ EISDIR = libc::EISDIR,
11633 -+ EINVAL = libc::EINVAL,
11634 -+ ENFILE = libc::ENFILE,
11635 -+ EMFILE = libc::EMFILE,
11636 -+ ENOTTY = libc::ENOTTY,
11637 -+ ETXTBSY = libc::ETXTBSY,
11638 -+ EFBIG = libc::EFBIG,
11639 -+ ENOSPC = libc::ENOSPC,
11640 -+ ESPIPE = libc::ESPIPE,
11641 -+ EROFS = libc::EROFS,
11642 -+ EMLINK = libc::EMLINK,
11643 -+ EPIPE = libc::EPIPE,
11644 -+ EDOM = libc::EDOM,
11645 -+ ERANGE = libc::ERANGE,
11646 -+ EAGAIN = libc::EAGAIN,
11647 -+ EINPROGRESS = libc::EINPROGRESS,
11648 -+ EALREADY = libc::EALREADY,
11649 -+ ENOTSOCK = libc::ENOTSOCK,
11650 -+ EDESTADDRREQ = libc::EDESTADDRREQ,
11651 -+ EMSGSIZE = libc::EMSGSIZE,
11652 -+ EPROTOTYPE = libc::EPROTOTYPE,
11653 -+ ENOPROTOOPT = libc::ENOPROTOOPT,
11654 -+ EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
11655 -+ ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
11656 -+ EOPNOTSUPP = libc::EOPNOTSUPP,
11657 -+ EPFNOSUPPORT = libc::EPFNOSUPPORT,
11658 -+ EAFNOSUPPORT = libc::EAFNOSUPPORT,
11659 -+ EADDRINUSE = libc::EADDRINUSE,
11660 -+ EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
11661 -+ ENETDOWN = libc::ENETDOWN,
11662 -+ ENETUNREACH = libc::ENETUNREACH,
11663 -+ ENETRESET = libc::ENETRESET,
11664 -+ ECONNABORTED = libc::ECONNABORTED,
11665 -+ ECONNRESET = libc::ECONNRESET,
11666 -+ ENOBUFS = libc::ENOBUFS,
11667 -+ EISCONN = libc::EISCONN,
11668 -+ ENOTCONN = libc::ENOTCONN,
11669 -+ ESHUTDOWN = libc::ESHUTDOWN,
11670 -+ ETOOMANYREFS = libc::ETOOMANYREFS,
11671 -+ ETIMEDOUT = libc::ETIMEDOUT,
11672 -+ ECONNREFUSED = libc::ECONNREFUSED,
11673 -+ ELOOP = libc::ELOOP,
11674 -+ ENAMETOOLONG = libc::ENAMETOOLONG,
11675 -+ EHOSTDOWN = libc::EHOSTDOWN,
11676 -+ EHOSTUNREACH = libc::EHOSTUNREACH,
11677 -+ ENOTEMPTY = libc::ENOTEMPTY,
11678 -+ EPROCLIM = libc::EPROCLIM,
11679 -+ EUSERS = libc::EUSERS,
11680 -+ EDQUOT = libc::EDQUOT,
11681 -+ ESTALE = libc::ESTALE,
11682 -+ EREMOTE = libc::EREMOTE,
11683 -+ EBADRPC = libc::EBADRPC,
11684 -+ ERPCMISMATCH = libc::ERPCMISMATCH,
11685 -+ EPROGUNAVAIL = libc::EPROGUNAVAIL,
11686 -+ EPROGMISMATCH = libc::EPROGMISMATCH,
11687 -+ EPROCUNAVAIL = libc::EPROCUNAVAIL,
11688 -+ ENOLCK = libc::ENOLCK,
11689 -+ ENOSYS = libc::ENOSYS,
11690 -+ EFTYPE = libc::EFTYPE,
11691 -+ EAUTH = libc::EAUTH,
11692 -+ ENEEDAUTH = libc::ENEEDAUTH,
11693 -+ EIPSEC = libc::EIPSEC,
11694 -+ ENOATTR = libc::ENOATTR,
11695 -+ EILSEQ = libc::EILSEQ,
11696 -+ ENOMEDIUM = libc::ENOMEDIUM,
11697 -+ EMEDIUMTYPE = libc::EMEDIUMTYPE,
11698 -+ EOVERFLOW = libc::EOVERFLOW,
11699 -+ ECANCELED = libc::ECANCELED,
11700 -+ EIDRM = libc::EIDRM,
11701 -+ ENOMSG = libc::ENOMSG,
11702 -+ ENOTSUP = libc::ENOTSUP,
11703 -+ EBADMSG = libc::EBADMSG,
11704 -+ ENOTRECOVERABLE = libc::ENOTRECOVERABLE,
11705 -+ EOWNERDEAD = libc::EOWNERDEAD,
11706 -+ EPROTO = libc::EPROTO,
11707 -+ }
11708 -+
11709 -+ pub const ELAST: Errno = Errno::ENOTSUP;
11710 -+ pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
11711 -+
11712 -+ pub const EL2NSYNC: Errno = Errno::UnknownErrno;
11713 -+
11714 -+ pub fn from_i32(e: i32) -> Errno {
11715 -+ use self::Errno::*;
11716 -+
11717 -+ match e {
11718 -+ libc::EPERM => EPERM,
11719 -+ libc::ENOENT => ENOENT,
11720 -+ libc::ESRCH => ESRCH,
11721 -+ libc::EINTR => EINTR,
11722 -+ libc::EIO => EIO,
11723 -+ libc::ENXIO => ENXIO,
11724 -+ libc::E2BIG => E2BIG,
11725 -+ libc::ENOEXEC => ENOEXEC,
11726 -+ libc::EBADF => EBADF,
11727 -+ libc::ECHILD => ECHILD,
11728 -+ libc::EDEADLK => EDEADLK,
11729 -+ libc::ENOMEM => ENOMEM,
11730 -+ libc::EACCES => EACCES,
11731 -+ libc::EFAULT => EFAULT,
11732 -+ libc::ENOTBLK => ENOTBLK,
11733 -+ libc::EBUSY => EBUSY,
11734 -+ libc::EEXIST => EEXIST,
11735 -+ libc::EXDEV => EXDEV,
11736 -+ libc::ENODEV => ENODEV,
11737 -+ libc::ENOTDIR => ENOTDIR,
11738 -+ libc::EISDIR => EISDIR,
11739 -+ libc::EINVAL => EINVAL,
11740 -+ libc::ENFILE => ENFILE,
11741 -+ libc::EMFILE => EMFILE,
11742 -+ libc::ENOTTY => ENOTTY,
11743 -+ libc::ETXTBSY => ETXTBSY,
11744 -+ libc::EFBIG => EFBIG,
11745 -+ libc::ENOSPC => ENOSPC,
11746 -+ libc::ESPIPE => ESPIPE,
11747 -+ libc::EROFS => EROFS,
11748 -+ libc::EMLINK => EMLINK,
11749 -+ libc::EPIPE => EPIPE,
11750 -+ libc::EDOM => EDOM,
11751 -+ libc::ERANGE => ERANGE,
11752 -+ libc::EAGAIN => EAGAIN,
11753 -+ libc::EINPROGRESS => EINPROGRESS,
11754 -+ libc::EALREADY => EALREADY,
11755 -+ libc::ENOTSOCK => ENOTSOCK,
11756 -+ libc::EDESTADDRREQ => EDESTADDRREQ,
11757 -+ libc::EMSGSIZE => EMSGSIZE,
11758 -+ libc::EPROTOTYPE => EPROTOTYPE,
11759 -+ libc::ENOPROTOOPT => ENOPROTOOPT,
11760 -+ libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
11761 -+ libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
11762 -+ libc::EOPNOTSUPP => EOPNOTSUPP,
11763 -+ libc::EPFNOSUPPORT => EPFNOSUPPORT,
11764 -+ libc::EAFNOSUPPORT => EAFNOSUPPORT,
11765 -+ libc::EADDRINUSE => EADDRINUSE,
11766 -+ libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
11767 -+ libc::ENETDOWN => ENETDOWN,
11768 -+ libc::ENETUNREACH => ENETUNREACH,
11769 -+ libc::ENETRESET => ENETRESET,
11770 -+ libc::ECONNABORTED => ECONNABORTED,
11771 -+ libc::ECONNRESET => ECONNRESET,
11772 -+ libc::ENOBUFS => ENOBUFS,
11773 -+ libc::EISCONN => EISCONN,
11774 -+ libc::ENOTCONN => ENOTCONN,
11775 -+ libc::ESHUTDOWN => ESHUTDOWN,
11776 -+ libc::ETOOMANYREFS => ETOOMANYREFS,
11777 -+ libc::ETIMEDOUT => ETIMEDOUT,
11778 -+ libc::ECONNREFUSED => ECONNREFUSED,
11779 -+ libc::ELOOP => ELOOP,
11780 -+ libc::ENAMETOOLONG => ENAMETOOLONG,
11781 -+ libc::EHOSTDOWN => EHOSTDOWN,
11782 -+ libc::EHOSTUNREACH => EHOSTUNREACH,
11783 -+ libc::ENOTEMPTY => ENOTEMPTY,
11784 -+ libc::EPROCLIM => EPROCLIM,
11785 -+ libc::EUSERS => EUSERS,
11786 -+ libc::EDQUOT => EDQUOT,
11787 -+ libc::ESTALE => ESTALE,
11788 -+ libc::EREMOTE => EREMOTE,
11789 -+ libc::EBADRPC => EBADRPC,
11790 -+ libc::ERPCMISMATCH => ERPCMISMATCH,
11791 -+ libc::EPROGUNAVAIL => EPROGUNAVAIL,
11792 -+ libc::EPROGMISMATCH => EPROGMISMATCH,
11793 -+ libc::EPROCUNAVAIL => EPROCUNAVAIL,
11794 -+ libc::ENOLCK => ENOLCK,
11795 -+ libc::ENOSYS => ENOSYS,
11796 -+ libc::EFTYPE => EFTYPE,
11797 -+ libc::EAUTH => EAUTH,
11798 -+ libc::ENEEDAUTH => ENEEDAUTH,
11799 -+ libc::EIPSEC => EIPSEC,
11800 -+ libc::ENOATTR => ENOATTR,
11801 -+ libc::EILSEQ => EILSEQ,
11802 -+ libc::ENOMEDIUM => ENOMEDIUM,
11803 -+ libc::EMEDIUMTYPE => EMEDIUMTYPE,
11804 -+ libc::EOVERFLOW => EOVERFLOW,
11805 -+ libc::ECANCELED => ECANCELED,
11806 -+ libc::EIDRM => EIDRM,
11807 -+ libc::ENOMSG => ENOMSG,
11808 -+ libc::ENOTSUP => ENOTSUP,
11809 -+ libc::EBADMSG => EBADMSG,
11810 -+ libc::ENOTRECOVERABLE => ENOTRECOVERABLE,
11811 -+ libc::EOWNERDEAD => EOWNERDEAD,
11812 -+ libc::EPROTO => EPROTO,
11813 -+ _ => UnknownErrno,
11814 -+ }
11815 -+ }
11816 -+}
11817 -+
11818 -+#[cfg(target_os = "netbsd")]
11819 -+mod consts {
11820 -+ use libc;
11821 -+
11822 -+ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
11823 -+ #[repr(i32)]
11824 -+ pub enum Errno {
11825 -+ UnknownErrno = 0,
11826 -+ EPERM = libc::EPERM,
11827 -+ ENOENT = libc::ENOENT,
11828 -+ ESRCH = libc::ESRCH,
11829 -+ EINTR = libc::EINTR,
11830 -+ EIO = libc::EIO,
11831 -+ ENXIO = libc::ENXIO,
11832 -+ E2BIG = libc::E2BIG,
11833 -+ ENOEXEC = libc::ENOEXEC,
11834 -+ EBADF = libc::EBADF,
11835 -+ ECHILD = libc::ECHILD,
11836 -+ EDEADLK = libc::EDEADLK,
11837 -+ ENOMEM = libc::ENOMEM,
11838 -+ EACCES = libc::EACCES,
11839 -+ EFAULT = libc::EFAULT,
11840 -+ ENOTBLK = libc::ENOTBLK,
11841 -+ EBUSY = libc::EBUSY,
11842 -+ EEXIST = libc::EEXIST,
11843 -+ EXDEV = libc::EXDEV,
11844 -+ ENODEV = libc::ENODEV,
11845 -+ ENOTDIR = libc::ENOTDIR,
11846 -+ EISDIR = libc::EISDIR,
11847 -+ EINVAL = libc::EINVAL,
11848 -+ ENFILE = libc::ENFILE,
11849 -+ EMFILE = libc::EMFILE,
11850 -+ ENOTTY = libc::ENOTTY,
11851 -+ ETXTBSY = libc::ETXTBSY,
11852 -+ EFBIG = libc::EFBIG,
11853 -+ ENOSPC = libc::ENOSPC,
11854 -+ ESPIPE = libc::ESPIPE,
11855 -+ EROFS = libc::EROFS,
11856 -+ EMLINK = libc::EMLINK,
11857 -+ EPIPE = libc::EPIPE,
11858 -+ EDOM = libc::EDOM,
11859 -+ ERANGE = libc::ERANGE,
11860 -+ EAGAIN = libc::EAGAIN,
11861 -+ EINPROGRESS = libc::EINPROGRESS,
11862 -+ EALREADY = libc::EALREADY,
11863 -+ ENOTSOCK = libc::ENOTSOCK,
11864 -+ EDESTADDRREQ = libc::EDESTADDRREQ,
11865 -+ EMSGSIZE = libc::EMSGSIZE,
11866 -+ EPROTOTYPE = libc::EPROTOTYPE,
11867 -+ ENOPROTOOPT = libc::ENOPROTOOPT,
11868 -+ EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
11869 -+ ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
11870 -+ EOPNOTSUPP = libc::EOPNOTSUPP,
11871 -+ EPFNOSUPPORT = libc::EPFNOSUPPORT,
11872 -+ EAFNOSUPPORT = libc::EAFNOSUPPORT,
11873 -+ EADDRINUSE = libc::EADDRINUSE,
11874 -+ EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
11875 -+ ENETDOWN = libc::ENETDOWN,
11876 -+ ENETUNREACH = libc::ENETUNREACH,
11877 -+ ENETRESET = libc::ENETRESET,
11878 -+ ECONNABORTED = libc::ECONNABORTED,
11879 -+ ECONNRESET = libc::ECONNRESET,
11880 -+ ENOBUFS = libc::ENOBUFS,
11881 -+ EISCONN = libc::EISCONN,
11882 -+ ENOTCONN = libc::ENOTCONN,
11883 -+ ESHUTDOWN = libc::ESHUTDOWN,
11884 -+ ETOOMANYREFS = libc::ETOOMANYREFS,
11885 -+ ETIMEDOUT = libc::ETIMEDOUT,
11886 -+ ECONNREFUSED = libc::ECONNREFUSED,
11887 -+ ELOOP = libc::ELOOP,
11888 -+ ENAMETOOLONG = libc::ENAMETOOLONG,
11889 -+ EHOSTDOWN = libc::EHOSTDOWN,
11890 -+ EHOSTUNREACH = libc::EHOSTUNREACH,
11891 -+ ENOTEMPTY = libc::ENOTEMPTY,
11892 -+ EPROCLIM = libc::EPROCLIM,
11893 -+ EUSERS = libc::EUSERS,
11894 -+ EDQUOT = libc::EDQUOT,
11895 -+ ESTALE = libc::ESTALE,
11896 -+ EREMOTE = libc::EREMOTE,
11897 -+ EBADRPC = libc::EBADRPC,
11898 -+ ERPCMISMATCH = libc::ERPCMISMATCH,
11899 -+ EPROGUNAVAIL = libc::EPROGUNAVAIL,
11900 -+ EPROGMISMATCH = libc::EPROGMISMATCH,
11901 -+ EPROCUNAVAIL = libc::EPROCUNAVAIL,
11902 -+ ENOLCK = libc::ENOLCK,
11903 -+ ENOSYS = libc::ENOSYS,
11904 -+ EFTYPE = libc::EFTYPE,
11905 -+ EAUTH = libc::EAUTH,
11906 -+ ENEEDAUTH = libc::ENEEDAUTH,
11907 -+ EIDRM = libc::EIDRM,
11908 -+ ENOMSG = libc::ENOMSG,
11909 -+ EOVERFLOW = libc::EOVERFLOW,
11910 -+ EILSEQ = libc::EILSEQ,
11911 -+ ENOTSUP = libc::ENOTSUP,
11912 -+ ECANCELED = libc::ECANCELED,
11913 -+ EBADMSG = libc::EBADMSG,
11914 -+ ENODATA = libc::ENODATA,
11915 -+ ENOSR = libc::ENOSR,
11916 -+ ENOSTR = libc::ENOSTR,
11917 -+ ETIME = libc::ETIME,
11918 -+ ENOATTR = libc::ENOATTR,
11919 -+ EMULTIHOP = libc::EMULTIHOP,
11920 -+ ENOLINK = libc::ENOLINK,
11921 -+ EPROTO = libc::EPROTO,
11922 -+ }
11923 -+
11924 -+ pub const ELAST: Errno = Errno::ENOTSUP;
11925 -+ pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
11926 -+
11927 -+ pub const EL2NSYNC: Errno = Errno::UnknownErrno;
11928 -+
11929 -+ pub fn from_i32(e: i32) -> Errno {
11930 -+ use self::Errno::*;
11931 -+
11932 -+ match e {
11933 -+ libc::EPERM => EPERM,
11934 -+ libc::ENOENT => ENOENT,
11935 -+ libc::ESRCH => ESRCH,
11936 -+ libc::EINTR => EINTR,
11937 -+ libc::EIO => EIO,
11938 -+ libc::ENXIO => ENXIO,
11939 -+ libc::E2BIG => E2BIG,
11940 -+ libc::ENOEXEC => ENOEXEC,
11941 -+ libc::EBADF => EBADF,
11942 -+ libc::ECHILD => ECHILD,
11943 -+ libc::EDEADLK => EDEADLK,
11944 -+ libc::ENOMEM => ENOMEM,
11945 -+ libc::EACCES => EACCES,
11946 -+ libc::EFAULT => EFAULT,
11947 -+ libc::ENOTBLK => ENOTBLK,
11948 -+ libc::EBUSY => EBUSY,
11949 -+ libc::EEXIST => EEXIST,
11950 -+ libc::EXDEV => EXDEV,
11951 -+ libc::ENODEV => ENODEV,
11952 -+ libc::ENOTDIR => ENOTDIR,
11953 -+ libc::EISDIR => EISDIR,
11954 -+ libc::EINVAL => EINVAL,
11955 -+ libc::ENFILE => ENFILE,
11956 -+ libc::EMFILE => EMFILE,
11957 -+ libc::ENOTTY => ENOTTY,
11958 -+ libc::ETXTBSY => ETXTBSY,
11959 -+ libc::EFBIG => EFBIG,
11960 -+ libc::ENOSPC => ENOSPC,
11961 -+ libc::ESPIPE => ESPIPE,
11962 -+ libc::EROFS => EROFS,
11963 -+ libc::EMLINK => EMLINK,
11964 -+ libc::EPIPE => EPIPE,
11965 -+ libc::EDOM => EDOM,
11966 -+ libc::ERANGE => ERANGE,
11967 -+ libc::EAGAIN => EAGAIN,
11968 -+ libc::EINPROGRESS => EINPROGRESS,
11969 -+ libc::EALREADY => EALREADY,
11970 -+ libc::ENOTSOCK => ENOTSOCK,
11971 -+ libc::EDESTADDRREQ => EDESTADDRREQ,
11972 -+ libc::EMSGSIZE => EMSGSIZE,
11973 -+ libc::EPROTOTYPE => EPROTOTYPE,
11974 -+ libc::ENOPROTOOPT => ENOPROTOOPT,
11975 -+ libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
11976 -+ libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
11977 -+ libc::EOPNOTSUPP => EOPNOTSUPP,
11978 -+ libc::EPFNOSUPPORT => EPFNOSUPPORT,
11979 -+ libc::EAFNOSUPPORT => EAFNOSUPPORT,
11980 -+ libc::EADDRINUSE => EADDRINUSE,
11981 -+ libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
11982 -+ libc::ENETDOWN => ENETDOWN,
11983 -+ libc::ENETUNREACH => ENETUNREACH,
11984 -+ libc::ENETRESET => ENETRESET,
11985 -+ libc::ECONNABORTED => ECONNABORTED,
11986 -+ libc::ECONNRESET => ECONNRESET,
11987 -+ libc::ENOBUFS => ENOBUFS,
11988 -+ libc::EISCONN => EISCONN,
11989 -+ libc::ENOTCONN => ENOTCONN,
11990 -+ libc::ESHUTDOWN => ESHUTDOWN,
11991 -+ libc::ETOOMANYREFS => ETOOMANYREFS,
11992 -+ libc::ETIMEDOUT => ETIMEDOUT,
11993 -+ libc::ECONNREFUSED => ECONNREFUSED,
11994 -+ libc::ELOOP => ELOOP,
11995 -+ libc::ENAMETOOLONG => ENAMETOOLONG,
11996 -+ libc::EHOSTDOWN => EHOSTDOWN,
11997 -+ libc::EHOSTUNREACH => EHOSTUNREACH,
11998 -+ libc::ENOTEMPTY => ENOTEMPTY,
11999 -+ libc::EPROCLIM => EPROCLIM,
12000 -+ libc::EUSERS => EUSERS,
12001 -+ libc::EDQUOT => EDQUOT,
12002 -+ libc::ESTALE => ESTALE,
12003 -+ libc::EREMOTE => EREMOTE,
12004 -+ libc::EBADRPC => EBADRPC,
12005 -+ libc::ERPCMISMATCH => ERPCMISMATCH,
12006 -+ libc::EPROGUNAVAIL => EPROGUNAVAIL,
12007 -+ libc::EPROGMISMATCH => EPROGMISMATCH,
12008 -+ libc::EPROCUNAVAIL => EPROCUNAVAIL,
12009 -+ libc::ENOLCK => ENOLCK,
12010 -+ libc::ENOSYS => ENOSYS,
12011 -+ libc::EFTYPE => EFTYPE,
12012 -+ libc::EAUTH => EAUTH,
12013 -+ libc::ENEEDAUTH => ENEEDAUTH,
12014 -+ libc::EIDRM => EIDRM,
12015 -+ libc::ENOMSG => ENOMSG,
12016 -+ libc::EOVERFLOW => EOVERFLOW,
12017 -+ libc::EILSEQ => EILSEQ,
12018 -+ libc::ENOTSUP => ENOTSUP,
12019 -+ libc::ECANCELED => ECANCELED,
12020 -+ libc::EBADMSG => EBADMSG,
12021 -+ libc::ENODATA => ENODATA,
12022 -+ libc::ENOSR => ENOSR,
12023 -+ libc::ENOSTR => ENOSTR,
12024 -+ libc::ETIME => ETIME,
12025 -+ libc::ENOATTR => ENOATTR,
12026 -+ libc::EMULTIHOP => EMULTIHOP,
12027 -+ libc::ENOLINK => ENOLINK,
12028 -+ libc::EPROTO => EPROTO,
12029 -+ _ => UnknownErrno,
12030 -+ }
12031 -+ }
12032 -+}
12033 -diff --git a/third_party/rust/nix/src/errno_dragonfly.c b/third_party/rust/nix-0.15.0/src/errno_dragonfly.c
12034 -similarity index 100%
12035 -rename from third_party/rust/nix/src/errno_dragonfly.c
12036 -rename to third_party/rust/nix-0.15.0/src/errno_dragonfly.c
12037 -diff --git a/third_party/rust/nix-0.15.0/src/fcntl.rs b/third_party/rust/nix-0.15.0/src/fcntl.rs
12038 -new file mode 100644
12039 -index 0000000000000..be6ee0f73a8be
12040 ---- /dev/null
12041 -+++ b/third_party/rust/nix-0.15.0/src/fcntl.rs
12042 -@@ -0,0 +1,506 @@
12043 -+use {Error, Result, NixPath};
12044 -+use errno::Errno;
12045 -+use libc::{self, c_int, c_uint, c_char, size_t, ssize_t};
12046 -+use sys::stat::Mode;
12047 -+use std::os::raw;
12048 -+use std::os::unix::io::RawFd;
12049 -+use std::ffi::OsStr;
12050 -+use std::os::unix::ffi::OsStrExt;
12051 -+
12052 -+#[cfg(any(target_os = "android", target_os = "linux"))]
12053 -+use std::ptr; // For splice and copy_file_range
12054 -+#[cfg(any(target_os = "android", target_os = "linux"))]
12055 -+use sys::uio::IoVec; // For vmsplice
12056 -+
12057 -+#[cfg(any(target_os = "linux",
12058 -+ target_os = "android",
12059 -+ target_os = "emscripten",
12060 -+ target_os = "fuchsia",
12061 -+ any(target_os = "wasi", target_env = "wasi"),
12062 -+ target_env = "uclibc",
12063 -+ target_env = "freebsd"))]
12064 -+pub use self::posix_fadvise::*;
12065 -+
12066 -+libc_bitflags!{
12067 -+ pub struct AtFlags: c_int {
12068 -+ AT_REMOVEDIR;
12069 -+ AT_SYMLINK_NOFOLLOW;
12070 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
12071 -+ AT_NO_AUTOMOUNT;
12072 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
12073 -+ AT_EMPTY_PATH;
12074 -+ }
12075 -+}
12076 -+
12077 -+libc_bitflags!(
12078 -+ /// Configuration options for opened files.
12079 -+ pub struct OFlag: c_int {
12080 -+ /// Mask for the access mode of the file.
12081 -+ O_ACCMODE;
12082 -+ /// Use alternate I/O semantics.
12083 -+ #[cfg(target_os = "netbsd")]
12084 -+ O_ALT_IO;
12085 -+ /// Open the file in append-only mode.
12086 -+ O_APPEND;
12087 -+ /// Generate a signal when input or output becomes possible.
12088 -+ O_ASYNC;
12089 -+ /// Closes the file descriptor once an `execve` call is made.
12090 -+ ///
12091 -+ /// Also sets the file offset to the beginning of the file.
12092 -+ O_CLOEXEC;
12093 -+ /// Create the file if it does not exist.
12094 -+ O_CREAT;
12095 -+ /// Try to minimize cache effects of the I/O for this file.
12096 -+ #[cfg(any(target_os = "android",
12097 -+ target_os = "dragonfly",
12098 -+ target_os = "freebsd",
12099 -+ target_os = "linux",
12100 -+ target_os = "netbsd"))]
12101 -+ O_DIRECT;
12102 -+ /// If the specified path isn't a directory, fail.
12103 -+ O_DIRECTORY;
12104 -+ /// Implicitly follow each `write()` with an `fdatasync()`.
12105 -+ #[cfg(any(target_os = "android",
12106 -+ target_os = "ios",
12107 -+ target_os = "linux",
12108 -+ target_os = "macos",
12109 -+ target_os = "netbsd",
12110 -+ target_os = "openbsd"))]
12111 -+ O_DSYNC;
12112 -+ /// Error out if a file was not created.
12113 -+ O_EXCL;
12114 -+ /// Open for execute only.
12115 -+ #[cfg(target_os = "freebsd")]
12116 -+ O_EXEC;
12117 -+ /// Open with an exclusive file lock.
12118 -+ #[cfg(any(target_os = "dragonfly",
12119 -+ target_os = "freebsd",
12120 -+ target_os = "ios",
12121 -+ target_os = "macos",
12122 -+ target_os = "netbsd",
12123 -+ target_os = "openbsd"))]
12124 -+ O_EXLOCK;
12125 -+ /// Same as `O_SYNC`.
12126 -+ #[cfg(any(target_os = "dragonfly",
12127 -+ target_os = "freebsd",
12128 -+ target_os = "ios",
12129 -+ all(target_os = "linux", not(target_env = "musl")),
12130 -+ target_os = "macos",
12131 -+ target_os = "netbsd",
12132 -+ target_os = "openbsd"))]
12133 -+ O_FSYNC;
12134 -+ /// Allow files whose sizes can't be represented in an `off_t` to be opened.
12135 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
12136 -+ O_LARGEFILE;
12137 -+ /// Do not update the file last access time during `read(2)`s.
12138 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
12139 -+ O_NOATIME;
12140 -+ /// Don't attach the device as the process' controlling terminal.
12141 -+ O_NOCTTY;
12142 -+ /// Same as `O_NONBLOCK`.
12143 -+ O_NDELAY;
12144 -+ /// `open()` will fail if the given path is a symbolic link.
12145 -+ O_NOFOLLOW;
12146 -+ /// When possible, open the file in nonblocking mode.
12147 -+ O_NONBLOCK;
12148 -+ /// Don't deliver `SIGPIPE`.
12149 -+ #[cfg(target_os = "netbsd")]
12150 -+ O_NOSIGPIPE;
12151 -+ /// Obtain a file descriptor for low-level access.
12152 -+ ///
12153 -+ /// The file itself is not opened and other file operations will fail.
12154 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
12155 -+ O_PATH;
12156 -+ /// Only allow reading.
12157 -+ ///
12158 -+ /// This should not be combined with `O_WRONLY` or `O_RDWR`.
12159 -+ O_RDONLY;
12160 -+ /// Allow both reading and writing.
12161 -+ ///
12162 -+ /// This should not be combined with `O_WRONLY` or `O_RDONLY`.
12163 -+ O_RDWR;
12164 -+ /// Similar to `O_DSYNC` but applies to `read`s instead.
12165 -+ #[cfg(any(target_os = "linux", target_os = "netbsd", target_os = "openbsd"))]
12166 -+ O_RSYNC;
12167 -+ /// Skip search permission checks.
12168 -+ #[cfg(target_os = "netbsd")]
12169 -+ O_SEARCH;
12170 -+ /// Open with a shared file lock.
12171 -+ #[cfg(any(target_os = "dragonfly",
12172 -+ target_os = "freebsd",
12173 -+ target_os = "ios",
12174 -+ target_os = "macos",
12175 -+ target_os = "netbsd",
12176 -+ target_os = "openbsd"))]
12177 -+ O_SHLOCK;
12178 -+ /// Implicitly follow each `write()` with an `fsync()`.
12179 -+ O_SYNC;
12180 -+ /// Create an unnamed temporary file.
12181 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
12182 -+ O_TMPFILE;
12183 -+ /// Truncate an existing regular file to 0 length if it allows writing.
12184 -+ O_TRUNC;
12185 -+ /// Restore default TTY attributes.
12186 -+ #[cfg(target_os = "freebsd")]
12187 -+ O_TTY_INIT;
12188 -+ /// Only allow writing.
12189 -+ ///
12190 -+ /// This should not be combined with `O_RDONLY` or `O_RDWR`.
12191 -+ O_WRONLY;
12192 -+ }
12193 -+);
12194 -+
12195 -+pub fn open<P: ?Sized + NixPath>(path: &P, oflag: OFlag, mode: Mode) -> Result<RawFd> {
12196 -+ let fd = path.with_nix_path(|cstr| {
12197 -+ unsafe { libc::open(cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
12198 -+ })?;
12199 -+
12200 -+ Errno::result(fd)
12201 -+}
12202 -+
12203 -+pub fn openat<P: ?Sized + NixPath>(dirfd: RawFd, path: &P, oflag: OFlag, mode: Mode) -> Result<RawFd> {
12204 -+ let fd = path.with_nix_path(|cstr| {
12205 -+ unsafe { libc::openat(dirfd, cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
12206 -+ })?;
12207 -+ Errno::result(fd)
12208 -+}
12209 -+
12210 -+pub fn renameat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(old_dirfd: Option<RawFd>, old_path: &P1,
12211 -+ new_dirfd: Option<RawFd>, new_path: &P2)
12212 -+ -> Result<()> {
12213 -+ let res = old_path.with_nix_path(|old_cstr| {
12214 -+ new_path.with_nix_path(|new_cstr| unsafe {
12215 -+ libc::renameat(at_rawfd(old_dirfd), old_cstr.as_ptr(),
12216 -+ at_rawfd(new_dirfd), new_cstr.as_ptr())
12217 -+ })
12218 -+ })??;
12219 -+ Errno::result(res).map(drop)
12220 -+}
12221 -+
12222 -+fn wrap_readlink_result(buffer: &mut[u8], res: ssize_t) -> Result<&OsStr> {
12223 -+ match Errno::result(res) {
12224 -+ Err(err) => Err(err),
12225 -+ Ok(len) => {
12226 -+ if (len as usize) >= buffer.len() {
12227 -+ Err(Error::Sys(Errno::ENAMETOOLONG))
12228 -+ } else {
12229 -+ Ok(OsStr::from_bytes(&buffer[..(len as usize)]))
12230 -+ }
12231 -+ }
12232 -+ }
12233 -+}
12234 -+
12235 -+pub fn readlink<'a, P: ?Sized + NixPath>(path: &P, buffer: &'a mut [u8]) -> Result<&'a OsStr> {
12236 -+ let res = path.with_nix_path(|cstr| {
12237 -+ unsafe { libc::readlink(cstr.as_ptr(), buffer.as_mut_ptr() as *mut c_char, buffer.len() as size_t) }
12238 -+ })?;
12239 -+
12240 -+ wrap_readlink_result(buffer, res)
12241 -+}
12242 -+
12243 -+
12244 -+pub fn readlinkat<'a, P: ?Sized + NixPath>(dirfd: RawFd, path: &P, buffer: &'a mut [u8]) -> Result<&'a OsStr> {
12245 -+ let res = path.with_nix_path(|cstr| {
12246 -+ unsafe { libc::readlinkat(dirfd, cstr.as_ptr(), buffer.as_mut_ptr() as *mut c_char, buffer.len() as size_t) }
12247 -+ })?;
12248 -+
12249 -+ wrap_readlink_result(buffer, res)
12250 -+}
12251 -+
12252 -+/// Computes the raw fd consumed by a function of the form `*at`.
12253 -+pub(crate) fn at_rawfd(fd: Option<RawFd>) -> raw::c_int {
12254 -+ match fd {
12255 -+ None => libc::AT_FDCWD,
12256 -+ Some(fd) => fd,
12257 -+ }
12258 -+}
12259 -+
12260 -+#[cfg(any(target_os = "android", target_os = "linux"))]
12261 -+libc_bitflags!(
12262 -+ /// Additional flags for file sealing, which allows for limiting operations on a file.
12263 -+ pub struct SealFlag: c_int {
12264 -+ /// Prevents further calls to `fcntl()` with `F_ADD_SEALS`.
12265 -+ F_SEAL_SEAL;
12266 -+ /// The file cannot be reduced in size.
12267 -+ F_SEAL_SHRINK;
12268 -+ /// The size of the file cannot be increased.
12269 -+ F_SEAL_GROW;
12270 -+ /// The file contents cannot be modified.
12271 -+ F_SEAL_WRITE;
12272 -+ }
12273 -+);
12274 -+
12275 -+libc_bitflags!(
12276 -+ /// Additional configuration flags for `fcntl`'s `F_SETFD`.
12277 -+ pub struct FdFlag: c_int {
12278 -+ /// The file descriptor will automatically be closed during a successful `execve(2)`.
12279 -+ FD_CLOEXEC;
12280 -+ }
12281 -+);
12282 -+
12283 -+#[derive(Debug, Eq, Hash, PartialEq)]
12284 -+pub enum FcntlArg<'a> {
12285 -+ F_DUPFD(RawFd),
12286 -+ F_DUPFD_CLOEXEC(RawFd),
12287 -+ F_GETFD,
12288 -+ F_SETFD(FdFlag), // FD_FLAGS
12289 -+ F_GETFL,
12290 -+ F_SETFL(OFlag), // O_NONBLOCK
12291 -+ F_SETLK(&'a libc::flock),
12292 -+ F_SETLKW(&'a libc::flock),
12293 -+ F_GETLK(&'a mut libc::flock),
12294 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
12295 -+ F_OFD_SETLK(&'a libc::flock),
12296 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
12297 -+ F_OFD_SETLKW(&'a libc::flock),
12298 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
12299 -+ F_OFD_GETLK(&'a mut libc::flock),
12300 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
12301 -+ F_ADD_SEALS(SealFlag),
12302 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
12303 -+ F_GET_SEALS,
12304 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
12305 -+ F_FULLFSYNC,
12306 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
12307 -+ F_GETPIPE_SZ,
12308 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
12309 -+ F_SETPIPE_SZ(c_int),
12310 -+
12311 -+ // TODO: Rest of flags
12312 -+}
12313 -+pub use self::FcntlArg::*;
12314 -+
12315 -+// TODO: Figure out how to handle value fcntl returns
12316 -+pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
12317 -+ let res = unsafe {
12318 -+ match arg {
12319 -+ F_DUPFD(rawfd) => libc::fcntl(fd, libc::F_DUPFD, rawfd),
12320 -+ F_DUPFD_CLOEXEC(rawfd) => libc::fcntl(fd, libc::F_DUPFD_CLOEXEC, rawfd),
12321 -+ F_GETFD => libc::fcntl(fd, libc::F_GETFD),
12322 -+ F_SETFD(flag) => libc::fcntl(fd, libc::F_SETFD, flag.bits()),
12323 -+ F_GETFL => libc::fcntl(fd, libc::F_GETFL),
12324 -+ F_SETFL(flag) => libc::fcntl(fd, libc::F_SETFL, flag.bits()),
12325 -+ F_SETLK(flock) => libc::fcntl(fd, libc::F_SETLK, flock),
12326 -+ F_SETLKW(flock) => libc::fcntl(fd, libc::F_SETLKW, flock),
12327 -+ F_GETLK(flock) => libc::fcntl(fd, libc::F_GETLK, flock),
12328 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
12329 -+ F_ADD_SEALS(flag) => libc::fcntl(fd, libc::F_ADD_SEALS, flag.bits()),
12330 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
12331 -+ F_GET_SEALS => libc::fcntl(fd, libc::F_GET_SEALS),
12332 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
12333 -+ F_FULLFSYNC => libc::fcntl(fd, libc::F_FULLFSYNC),
12334 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
12335 -+ F_GETPIPE_SZ => libc::fcntl(fd, libc::F_GETPIPE_SZ),
12336 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
12337 -+ F_SETPIPE_SZ(size) => libc::fcntl(fd, libc::F_SETPIPE_SZ, size),
12338 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
12339 -+ _ => unimplemented!()
12340 -+ }
12341 -+ };
12342 -+
12343 -+ Errno::result(res)
12344 -+}
12345 -+
12346 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
12347 -+pub enum FlockArg {
12348 -+ LockShared,
12349 -+ LockExclusive,
12350 -+ Unlock,
12351 -+ LockSharedNonblock,
12352 -+ LockExclusiveNonblock,
12353 -+ UnlockNonblock,
12354 -+}
12355 -+
12356 -+pub fn flock(fd: RawFd, arg: FlockArg) -> Result<()> {
12357 -+ use self::FlockArg::*;
12358 -+
12359 -+ let res = unsafe {
12360 -+ match arg {
12361 -+ LockShared => libc::flock(fd, libc::LOCK_SH),
12362 -+ LockExclusive => libc::flock(fd, libc::LOCK_EX),
12363 -+ Unlock => libc::flock(fd, libc::LOCK_UN),
12364 -+ LockSharedNonblock => libc::flock(fd, libc::LOCK_SH | libc::LOCK_NB),
12365 -+ LockExclusiveNonblock => libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB),
12366 -+ UnlockNonblock => libc::flock(fd, libc::LOCK_UN | libc::LOCK_NB),
12367 -+ }
12368 -+ };
12369 -+
12370 -+ Errno::result(res).map(drop)
12371 -+}
12372 -+
12373 -+#[cfg(any(target_os = "android", target_os = "linux"))]
12374 -+libc_bitflags! {
12375 -+ /// Additional flags to `splice` and friends.
12376 -+ pub struct SpliceFFlags: c_uint {
12377 -+ /// Request that pages be moved instead of copied.
12378 -+ ///
12379 -+ /// Not applicable to `vmsplice`.
12380 -+ SPLICE_F_MOVE;
12381 -+ /// Do not block on I/O.
12382 -+ SPLICE_F_NONBLOCK;
12383 -+ /// Hint that more data will be coming in a subsequent splice.
12384 -+ ///
12385 -+ /// Not applicable to `vmsplice`.
12386 -+ SPLICE_F_MORE;
12387 -+ /// Gift the user pages to the kernel.
12388 -+ ///
12389 -+ /// Not applicable to `splice`.
12390 -+ SPLICE_F_GIFT;
12391 -+ }
12392 -+}
12393 -+
12394 -+/// Copy a range of data from one file to another
12395 -+///
12396 -+/// The `copy_file_range` system call performs an in-kernel copy between
12397 -+/// file descriptors `fd_in` and `fd_out` without the additional cost of
12398 -+/// transferring data from the kernel to user space and then back into the
12399 -+/// kernel. It copies up to `len` bytes of data from file descriptor `fd_in` to
12400 -+/// file descriptor `fd_out`, overwriting any data that exists within the
12401 -+/// requested range of the target file.
12402 -+///
12403 -+/// If the `off_in` and/or `off_out` arguments are used, the values
12404 -+/// will be mutated to reflect the new position within the file after
12405 -+/// copying. If they are not used, the relevant filedescriptors will be seeked
12406 -+/// to the new position.
12407 -+///
12408 -+/// On successful completion the number of bytes actually copied will be
12409 -+/// returned.
12410 -+#[cfg(any(target_os = "android", target_os = "linux"))]
12411 -+pub fn copy_file_range(
12412 -+ fd_in: RawFd,
12413 -+ off_in: Option<&mut libc::loff_t>,
12414 -+ fd_out: RawFd,
12415 -+ off_out: Option<&mut libc::loff_t>,
12416 -+ len: usize,
12417 -+) -> Result<usize> {
12418 -+ let off_in = off_in
12419 -+ .map(|offset| offset as *mut libc::loff_t)
12420 -+ .unwrap_or(ptr::null_mut());
12421 -+ let off_out = off_out
12422 -+ .map(|offset| offset as *mut libc::loff_t)
12423 -+ .unwrap_or(ptr::null_mut());
12424 -+
12425 -+ let ret = unsafe {
12426 -+ libc::syscall(
12427 -+ libc::SYS_copy_file_range,
12428 -+ fd_in,
12429 -+ off_in,
12430 -+ fd_out,
12431 -+ off_out,
12432 -+ len,
12433 -+ 0,
12434 -+ )
12435 -+ };
12436 -+ Errno::result(ret).map(|r| r as usize)
12437 -+}
12438 -+
12439 -+#[cfg(any(target_os = "linux", target_os = "android"))]
12440 -+pub fn splice(
12441 -+ fd_in: RawFd,
12442 -+ off_in: Option<&mut libc::loff_t>,
12443 -+ fd_out: RawFd,
12444 -+ off_out: Option<&mut libc::loff_t>,
12445 -+ len: usize,
12446 -+ flags: SpliceFFlags,
12447 -+) -> Result<usize> {
12448 -+ let off_in = off_in
12449 -+ .map(|offset| offset as *mut libc::loff_t)
12450 -+ .unwrap_or(ptr::null_mut());
12451 -+ let off_out = off_out
12452 -+ .map(|offset| offset as *mut libc::loff_t)
12453 -+ .unwrap_or(ptr::null_mut());
12454 -+
12455 -+ let ret = unsafe {
12456 -+ libc::splice(fd_in, off_in, fd_out, off_out, len, flags.bits())
12457 -+ };
12458 -+ Errno::result(ret).map(|r| r as usize)
12459 -+}
12460 -+
12461 -+#[cfg(any(target_os = "linux", target_os = "android"))]
12462 -+pub fn tee(fd_in: RawFd, fd_out: RawFd, len: usize, flags: SpliceFFlags) -> Result<usize> {
12463 -+ let ret = unsafe { libc::tee(fd_in, fd_out, len, flags.bits()) };
12464 -+ Errno::result(ret).map(|r| r as usize)
12465 -+}
12466 -+
12467 -+#[cfg(any(target_os = "linux", target_os = "android"))]
12468 -+pub fn vmsplice(fd: RawFd, iov: &[IoVec<&[u8]>], flags: SpliceFFlags) -> Result<usize> {
12469 -+ let ret = unsafe {
12470 -+ libc::vmsplice(fd, iov.as_ptr() as *const libc::iovec, iov.len(), flags.bits())
12471 -+ };
12472 -+ Errno::result(ret).map(|r| r as usize)
12473 -+}
12474 -+
12475 -+#[cfg(any(target_os = "linux"))]
12476 -+libc_bitflags!(
12477 -+ /// Mode argument flags for fallocate determining operation performed on a given range.
12478 -+ pub struct FallocateFlags: c_int {
12479 -+ /// File size is not changed.
12480 -+ ///
12481 -+ /// offset + len can be greater than file size.
12482 -+ FALLOC_FL_KEEP_SIZE;
12483 -+ /// Deallocates space by creating a hole.
12484 -+ ///
12485 -+ /// Must be ORed with FALLOC_FL_KEEP_SIZE. Byte range starts at offset and continues for len bytes.
12486 -+ FALLOC_FL_PUNCH_HOLE;
12487 -+ /// Removes byte range from a file without leaving a hole.
12488 -+ ///
12489 -+ /// Byte range to collapse starts at offset and continues for len bytes.
12490 -+ FALLOC_FL_COLLAPSE_RANGE;
12491 -+ /// Zeroes space in specified byte range.
12492 -+ ///
12493 -+ /// Byte range starts at offset and continues for len bytes.
12494 -+ FALLOC_FL_ZERO_RANGE;
12495 -+ /// Increases file space by inserting a hole within the file size.
12496 -+ ///
12497 -+ /// Does not overwrite existing data. Hole starts at offset and continues for len bytes.
12498 -+ FALLOC_FL_INSERT_RANGE;
12499 -+ /// Shared file data extants are made private to the file.
12500 -+ ///
12501 -+ /// Gaurantees that a subsequent write will not fail due to lack of space.
12502 -+ FALLOC_FL_UNSHARE_RANGE;
12503 -+ }
12504 -+);
12505 -+
12506 -+/// Manipulates file space.
12507 -+///
12508 -+/// Allows the caller to directly manipulate the allocated disk space for the
12509 -+/// file referred to by fd.
12510 -+#[cfg(any(target_os = "linux"))]
12511 -+pub fn fallocate(fd: RawFd, mode: FallocateFlags, offset: libc::off_t, len: libc::off_t) -> Result<c_int> {
12512 -+ let res = unsafe { libc::fallocate(fd, mode.bits(), offset, len) };
12513 -+ Errno::result(res)
12514 -+}
12515 -+
12516 -+#[cfg(any(target_os = "linux",
12517 -+ target_os = "android",
12518 -+ target_os = "emscripten",
12519 -+ target_os = "fuchsia",
12520 -+ any(target_os = "wasi", target_env = "wasi"),
12521 -+ target_env = "uclibc",
12522 -+ target_env = "freebsd"))]
12523 -+mod posix_fadvise {
12524 -+ use Result;
12525 -+ use libc;
12526 -+ use errno::Errno;
12527 -+ use std::os::unix::io::RawFd;
12528 -+
12529 -+ libc_enum! {
12530 -+ #[repr(i32)]
12531 -+ pub enum PosixFadviseAdvice {
12532 -+ POSIX_FADV_NORMAL,
12533 -+ POSIX_FADV_SEQUENTIAL,
12534 -+ POSIX_FADV_RANDOM,
12535 -+ POSIX_FADV_NOREUSE,
12536 -+ POSIX_FADV_WILLNEED,
12537 -+ POSIX_FADV_DONTNEED,
12538 -+ }
12539 -+ }
12540 -+
12541 -+ pub fn posix_fadvise(fd: RawFd,
12542 -+ offset: libc::off_t,
12543 -+ len: libc::off_t,
12544 -+ advice: PosixFadviseAdvice) -> Result<libc::c_int> {
12545 -+ let res = unsafe { libc::posix_fadvise(fd, offset, len, advice as libc::c_int) };
12546 -+ Errno::result(res)
12547 -+ }
12548 -+}
12549 -diff --git a/third_party/rust/nix-0.15.0/src/features.rs b/third_party/rust/nix-0.15.0/src/features.rs
12550 -new file mode 100644
12551 -index 0000000000000..76cdfd3a1a6f1
12552 ---- /dev/null
12553 -+++ b/third_party/rust/nix-0.15.0/src/features.rs
12554 -@@ -0,0 +1,103 @@
12555 -+//! Feature tests for OS functionality
12556 -+pub use self::os::*;
12557 -+
12558 -+#[cfg(any(target_os = "linux", target_os = "android"))]
12559 -+mod os {
12560 -+ use sys::utsname::uname;
12561 -+
12562 -+ // Features:
12563 -+ // * atomic cloexec on socket: 2.6.27
12564 -+ // * pipe2: 2.6.27
12565 -+ // * accept4: 2.6.28
12566 -+
12567 -+ static VERS_UNKNOWN: usize = 1;
12568 -+ static VERS_2_6_18: usize = 2;
12569 -+ static VERS_2_6_27: usize = 3;
12570 -+ static VERS_2_6_28: usize = 4;
12571 -+ static VERS_3: usize = 5;
12572 -+
12573 -+ #[inline]
12574 -+ fn digit(dst: &mut usize, b: u8) {
12575 -+ *dst *= 10;
12576 -+ *dst += (b - b'0') as usize;
12577 -+ }
12578 -+
12579 -+ fn parse_kernel_version() -> usize {
12580 -+ let u = uname();
12581 -+
12582 -+ let mut curr: usize = 0;
12583 -+ let mut major: usize = 0;
12584 -+ let mut minor: usize = 0;
12585 -+ let mut patch: usize = 0;
12586 -+
12587 -+ for b in u.release().bytes() {
12588 -+ if curr >= 3 {
12589 -+ break;
12590 -+ }
12591 -+
12592 -+ match b {
12593 -+ b'.' | b'-' => {
12594 -+ curr += 1;
12595 -+ }
12596 -+ b'0'..=b'9' => {
12597 -+ match curr {
12598 -+ 0 => digit(&mut major, b),
12599 -+ 1 => digit(&mut minor, b),
12600 -+ _ => digit(&mut patch, b),
12601 -+ }
12602 -+ }
12603 -+ _ => break,
12604 -+ }
12605 -+ }
12606 -+
12607 -+ if major >= 3 {
12608 -+ VERS_3
12609 -+ } else if major >= 2 {
12610 -+ if minor >= 7 {
12611 -+ VERS_UNKNOWN
12612 -+ } else if minor >= 6 {
12613 -+ if patch >= 28 {
12614 -+ VERS_2_6_28
12615 -+ } else if patch >= 27 {
12616 -+ VERS_2_6_27
12617 -+ } else {
12618 -+ VERS_2_6_18
12619 -+ }
12620 -+ } else {
12621 -+ VERS_UNKNOWN
12622 -+ }
12623 -+ } else {
12624 -+ VERS_UNKNOWN
12625 -+ }
12626 -+ }
12627 -+
12628 -+ fn kernel_version() -> usize {
12629 -+ static mut KERNEL_VERS: usize = 0;
12630 -+
12631 -+ unsafe {
12632 -+ if KERNEL_VERS == 0 {
12633 -+ KERNEL_VERS = parse_kernel_version();
12634 -+ }
12635 -+
12636 -+ KERNEL_VERS
12637 -+ }
12638 -+ }
12639 -+
12640 -+ /// Check if the OS supports atomic close-on-exec for sockets
12641 -+ pub fn socket_atomic_cloexec() -> bool {
12642 -+ kernel_version() >= VERS_2_6_27
12643 -+ }
12644 -+
12645 -+ #[test]
12646 -+ pub fn test_parsing_kernel_version() {
12647 -+ assert!(kernel_version() > 0);
12648 -+ }
12649 -+}
12650 -+
12651 -+#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "dragonfly", target_os = "ios", target_os = "openbsd", target_os = "netbsd"))]
12652 -+mod os {
12653 -+ /// Check if the OS supports atomic close-on-exec for sockets
12654 -+ pub fn socket_atomic_cloexec() -> bool {
12655 -+ false
12656 -+ }
12657 -+}
12658 -diff --git a/third_party/rust/nix-0.15.0/src/ifaddrs.rs b/third_party/rust/nix-0.15.0/src/ifaddrs.rs
12659 -new file mode 100644
12660 -index 0000000000000..12b59bcc92bef
12661 ---- /dev/null
12662 -+++ b/third_party/rust/nix-0.15.0/src/ifaddrs.rs
12663 -@@ -0,0 +1,146 @@
12664 -+//! Query network interface addresses
12665 -+//!
12666 -+//! Uses the Linux and/or BSD specific function `getifaddrs` to query the list
12667 -+//! of interfaces and their associated addresses.
12668 -+
12669 -+use std::ffi;
12670 -+use std::iter::Iterator;
12671 -+use std::mem;
12672 -+use std::option::Option;
12673 -+
12674 -+use libc;
12675 -+
12676 -+use {Result, Errno};
12677 -+use sys::socket::SockAddr;
12678 -+use net::if_::*;
12679 -+
12680 -+/// Describes a single address for an interface as returned by `getifaddrs`.
12681 -+#[derive(Clone, Debug, Eq, Hash, PartialEq)]
12682 -+pub struct InterfaceAddress {
12683 -+ /// Name of the network interface
12684 -+ pub interface_name: String,
12685 -+ /// Flags as from `SIOCGIFFLAGS` ioctl
12686 -+ pub flags: InterfaceFlags,
12687 -+ /// Network address of this interface
12688 -+ pub address: Option<SockAddr>,
12689 -+ /// Netmask of this interface
12690 -+ pub netmask: Option<SockAddr>,
12691 -+ /// Broadcast address of this interface, if applicable
12692 -+ pub broadcast: Option<SockAddr>,
12693 -+ /// Point-to-point destination address
12694 -+ pub destination: Option<SockAddr>,
12695 -+}
12696 -+
12697 -+cfg_if! {
12698 -+ if #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "fuchsia", target_os = "linux"))] {
12699 -+ fn get_ifu_from_sockaddr(info: &libc::ifaddrs) -> *const libc::sockaddr {
12700 -+ info.ifa_ifu
12701 -+ }
12702 -+ } else {
12703 -+ fn get_ifu_from_sockaddr(info: &libc::ifaddrs) -> *const libc::sockaddr {
12704 -+ info.ifa_dstaddr
12705 -+ }
12706 -+ }
12707 -+}
12708 -+
12709 -+impl InterfaceAddress {
12710 -+ /// Create an `InterfaceAddress` from the libc struct.
12711 -+ fn from_libc_ifaddrs(info: &libc::ifaddrs) -> InterfaceAddress {
12712 -+ let ifname = unsafe { ffi::CStr::from_ptr(info.ifa_name) };
12713 -+ let address = unsafe { SockAddr::from_libc_sockaddr(info.ifa_addr) };
12714 -+ let netmask = unsafe { SockAddr::from_libc_sockaddr(info.ifa_netmask) };
12715 -+ let mut addr = InterfaceAddress {
12716 -+ interface_name: ifname.to_string_lossy().to_string(),
12717 -+ flags: InterfaceFlags::from_bits_truncate(info.ifa_flags as i32),
12718 -+ address: address,
12719 -+ netmask: netmask,
12720 -+ broadcast: None,
12721 -+ destination: None,
12722 -+ };
12723 -+
12724 -+ let ifu = get_ifu_from_sockaddr(info);
12725 -+ if addr.flags.contains(InterfaceFlags::IFF_POINTOPOINT) {
12726 -+ addr.destination = unsafe { SockAddr::from_libc_sockaddr(ifu) };
12727 -+ } else if addr.flags.contains(InterfaceFlags::IFF_BROADCAST) {
12728 -+ addr.broadcast = unsafe { SockAddr::from_libc_sockaddr(ifu) };
12729 -+ }
12730 -+
12731 -+ addr
12732 -+ }
12733 -+}
12734 -+
12735 -+/// Holds the results of `getifaddrs`.
12736 -+///
12737 -+/// Use the function `getifaddrs` to create this Iterator. Note that the
12738 -+/// actual list of interfaces can be iterated once and will be freed as
12739 -+/// soon as the Iterator goes out of scope.
12740 -+#[derive(Debug, Eq, Hash, PartialEq)]
12741 -+pub struct InterfaceAddressIterator {
12742 -+ base: *mut libc::ifaddrs,
12743 -+ next: *mut libc::ifaddrs,
12744 -+}
12745 -+
12746 -+impl Drop for InterfaceAddressIterator {
12747 -+ fn drop(&mut self) {
12748 -+ unsafe { libc::freeifaddrs(self.base) };
12749 -+ }
12750 -+}
12751 -+
12752 -+impl Iterator for InterfaceAddressIterator {
12753 -+ type Item = InterfaceAddress;
12754 -+ fn next(&mut self) -> Option<<Self as Iterator>::Item> {
12755 -+ match unsafe { self.next.as_ref() } {
12756 -+ Some(ifaddr) => {
12757 -+ self.next = ifaddr.ifa_next;
12758 -+ Some(InterfaceAddress::from_libc_ifaddrs(ifaddr))
12759 -+ }
12760 -+ None => None,
12761 -+ }
12762 -+ }
12763 -+}
12764 -+
12765 -+/// Get interface addresses using libc's `getifaddrs`
12766 -+///
12767 -+/// Note that the underlying implementation differs between OSes. Only the
12768 -+/// most common address families are supported by the nix crate (due to
12769 -+/// lack of time and complexity of testing). The address family is encoded
12770 -+/// in the specific variant of `SockAddr` returned for the fields `address`,
12771 -+/// `netmask`, `broadcast`, and `destination`. For any entry not supported,
12772 -+/// the returned list will contain a `None` entry.
12773 -+///
12774 -+/// # Example
12775 -+/// ```
12776 -+/// let addrs = nix::ifaddrs::getifaddrs().unwrap();
12777 -+/// for ifaddr in addrs {
12778 -+/// match ifaddr.address {
12779 -+/// Some(address) => {
12780 -+/// println!("interface {} address {}",
12781 -+/// ifaddr.interface_name, address);
12782 -+/// },
12783 -+/// None => {
12784 -+/// println!("interface {} with unsupported address family",
12785 -+/// ifaddr.interface_name);
12786 -+/// }
12787 -+/// }
12788 -+/// }
12789 -+/// ```
12790 -+pub fn getifaddrs() -> Result<InterfaceAddressIterator> {
12791 -+ let mut addrs: *mut libc::ifaddrs = unsafe { mem::uninitialized() };
12792 -+ Errno::result(unsafe { libc::getifaddrs(&mut addrs) }).map(|_| {
12793 -+ InterfaceAddressIterator {
12794 -+ base: addrs,
12795 -+ next: addrs,
12796 -+ }
12797 -+ })
12798 -+}
12799 -+
12800 -+#[cfg(test)]
12801 -+mod tests {
12802 -+ use super::*;
12803 -+
12804 -+ // Only checks if `getifaddrs` can be invoked without panicking.
12805 -+ #[test]
12806 -+ fn test_getifaddrs() {
12807 -+ let _ = getifaddrs();
12808 -+ }
12809 -+}
12810 -diff --git a/third_party/rust/nix-0.15.0/src/kmod.rs b/third_party/rust/nix-0.15.0/src/kmod.rs
12811 -new file mode 100644
12812 -index 0000000000000..e853261b14f9d
12813 ---- /dev/null
12814 -+++ b/third_party/rust/nix-0.15.0/src/kmod.rs
12815 -@@ -0,0 +1,123 @@
12816 -+//! Load and unload kernel modules.
12817 -+//!
12818 -+//! For more details see
12819 -+
12820 -+use libc;
12821 -+use std::ffi::CStr;
12822 -+use std::os::unix::io::AsRawFd;
12823 -+
12824 -+use errno::Errno;
12825 -+use Result;
12826 -+
12827 -+/// Loads a kernel module from a buffer.
12828 -+///
12829 -+/// It loads an ELF image into kernel space,
12830 -+/// performs any necessary symbol relocations,
12831 -+/// initializes module parameters to values provided by the caller,
12832 -+/// and then runs the module's init function.
12833 -+///
12834 -+/// This function requires `CAP_SYS_MODULE` privilege.
12835 -+///
12836 -+/// The `module_image` argument points to a buffer containing the binary image
12837 -+/// to be loaded. The buffer should contain a valid ELF image
12838 -+/// built for the running kernel.
12839 -+///
12840 -+/// The `param_values` argument is a string containing space-delimited specifications
12841 -+/// of the values for module parameters.
12842 -+/// Each of the parameter specifications has the form:
12843 -+///
12844 -+/// `name[=value[,value...]]`
12845 -+///
12846 -+/// # Example
12847 -+///
12848 -+/// ```no_run
12849 -+/// use std::fs::File;
12850 -+/// use std::io::Read;
12851 -+/// use std::ffi::CString;
12852 -+/// use nix::kmod::init_module;
12853 -+///
12854 -+/// let mut f = File::open("mykernel.ko").unwrap();
12855 -+/// let mut contents: Vec<u8> = Vec::new();
12856 -+/// f.read_to_end(&mut contents).unwrap();
12857 -+/// init_module(&mut contents, &CString::new("who=Rust when=Now,12").unwrap()).unwrap();
12858 -+/// ```
12859 -+///
12860 -+/// See [`man init_module(2)`](http://man7.org/linux/man-pages/man2/init_module.2.html) for more information.
12861 -+pub fn init_module(module_image: &[u8], param_values: &CStr) -> Result<()> {
12862 -+ let res = unsafe {
12863 -+ libc::syscall(
12864 -+ libc::SYS_init_module,
12865 -+ module_image.as_ptr(),
12866 -+ module_image.len(),
12867 -+ param_values.as_ptr(),
12868 -+ )
12869 -+ };
12870 -+
12871 -+ Errno::result(res).map(drop)
12872 -+}
12873 -+
12874 -+libc_bitflags!(
12875 -+ /// Flags used by the `finit_module` function.
12876 -+ pub struct ModuleInitFlags: libc::c_uint {
12877 -+ /// Ignore symbol version hashes.
12878 -+ MODULE_INIT_IGNORE_MODVERSIONS;
12879 -+ /// Ignore kernel version magic.
12880 -+ MODULE_INIT_IGNORE_VERMAGIC;
12881 -+ }
12882 -+);
12883 -+
12884 -+/// Loads a kernel module from a given file descriptor.
12885 -+///
12886 -+/// # Example
12887 -+///
12888 -+/// ```no_run
12889 -+/// use std::fs::File;
12890 -+/// use std::ffi::CString;
12891 -+/// use nix::kmod::{finit_module, ModuleInitFlags};
12892 -+///
12893 -+/// let f = File::open("mymod.ko").unwrap();
12894 -+/// finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()).unwrap();
12895 -+/// ```
12896 -+///
12897 -+/// See [`man init_module(2)`](http://man7.org/linux/man-pages/man2/init_module.2.html) for more information.
12898 -+pub fn finit_module<T: AsRawFd>(fd: &T, param_values: &CStr, flags: ModuleInitFlags) -> Result<()> {
12899 -+ let res = unsafe {
12900 -+ libc::syscall(
12901 -+ libc::SYS_finit_module,
12902 -+ fd.as_raw_fd(),
12903 -+ param_values.as_ptr(),
12904 -+ flags.bits(),
12905 -+ )
12906 -+ };
12907 -+
12908 -+ Errno::result(res).map(drop)
12909 -+}
12910 -+
12911 -+libc_bitflags!(
12912 -+ /// Flags used by `delete_module`.
12913 -+ ///
12914 -+ /// See [`man delete_module(2)`](http://man7.org/linux/man-pages/man2/delete_module.2.html)
12915 -+ /// for a detailed description how these flags work.
12916 -+ pub struct DeleteModuleFlags: libc::c_int {
12917 -+ O_NONBLOCK;
12918 -+ O_TRUNC;
12919 -+ }
12920 -+);
12921 -+
12922 -+/// Unloads the kernel module with the given name.
12923 -+///
12924 -+/// # Example
12925 -+///
12926 -+/// ```no_run
12927 -+/// use std::ffi::CString;
12928 -+/// use nix::kmod::{delete_module, DeleteModuleFlags};
12929 -+///
12930 -+/// delete_module(&CString::new("mymod").unwrap(), DeleteModuleFlags::O_NONBLOCK).unwrap();
12931 -+/// ```
12932 -+///
12933 -+/// See [`man delete_module(2)`](http://man7.org/linux/man-pages/man2/delete_module.2.html) for more information.
12934 -+pub fn delete_module(name: &CStr, flags: DeleteModuleFlags) -> Result<()> {
12935 -+ let res = unsafe { libc::syscall(libc::SYS_delete_module, name.as_ptr(), flags.bits()) };
12936 -+
12937 -+ Errno::result(res).map(drop)
12938 -+}
12939 -diff --git a/third_party/rust/nix-0.15.0/src/lib.rs b/third_party/rust/nix-0.15.0/src/lib.rs
12940 -new file mode 100644
12941 -index 0000000000000..71485d2af1824
12942 ---- /dev/null
12943 -+++ b/third_party/rust/nix-0.15.0/src/lib.rs
12944 -@@ -0,0 +1,284 @@
12945 -+//! Rust friendly bindings to the various *nix system functions.
12946 -+//!
12947 -+//! Modules are structured according to the C header file that they would be
12948 -+//! defined in.
12949 -+#![crate_name = "nix"]
12950 -+#![cfg(unix)]
12951 -+#![allow(non_camel_case_types)]
12952 -+// latest bitflags triggers a rustc bug with cross-crate macro expansions causing dead_code
12953 -+// warnings even though the macro expands into something with allow(dead_code)
12954 -+#![allow(dead_code)]
12955 -+#![cfg_attr(test, deny(warnings))]
12956 -+#![recursion_limit = "500"]
12957 -+#![deny(unused)]
12958 -+#![deny(unstable_features)]
12959 -+#![deny(missing_copy_implementations)]
12960 -+#![deny(missing_debug_implementations)]
12961 -+// XXX Allow deprecated items until release 0.16.0. See issue #1096.
12962 -+#![allow(deprecated)]
12963 -+
12964 -+// External crates
12965 -+#[macro_use]
12966 -+extern crate bitflags;
12967 -+#[macro_use]
12968 -+extern crate cfg_if;
12969 -+extern crate void;
12970 -+
12971 -+// Re-exported external crates
12972 -+pub extern crate libc;
12973 -+
12974 -+// Private internal modules
12975 -+#[macro_use] mod macros;
12976 -+
12977 -+// Public crates
12978 -+pub mod dir;
12979 -+pub mod errno;
12980 -+#[deny(missing_docs)]
12981 -+pub mod features;
12982 -+pub mod fcntl;
12983 -+#[deny(missing_docs)]
12984 -+#[cfg(any(target_os = "android",
12985 -+ target_os = "dragonfly",
12986 -+ target_os = "freebsd",
12987 -+ target_os = "ios",
12988 -+ target_os = "linux",
12989 -+ target_os = "macos",
12990 -+ target_os = "netbsd",
12991 -+ target_os = "openbsd"))]
12992 -+pub mod ifaddrs;
12993 -+#[cfg(any(target_os = "android",
12994 -+ target_os = "linux"))]
12995 -+pub mod kmod;
12996 -+#[cfg(any(target_os = "android",
12997 -+ target_os = "linux"))]
12998 -+pub mod mount;
12999 -+#[cfg(any(target_os = "dragonfly",
13000 -+ target_os = "freebsd",
13001 -+ target_os = "fushsia",
13002 -+ target_os = "linux",
13003 -+ target_os = "netbsd"))]
13004 -+pub mod mqueue;
13005 -+#[deny(missing_docs)]
13006 -+pub mod net;
13007 -+#[deny(missing_docs)]
13008 -+pub mod poll;
13009 -+#[deny(missing_docs)]
13010 -+pub mod pty;
13011 -+pub mod sched;
13012 -+pub mod sys;
13013 -+// This can be implemented for other platforms as soon as libc
13014 -+// provides bindings for them.
13015 -+#[cfg(all(target_os = "linux",
13016 -+ any(target_arch = "x86", target_arch = "x86_64")))]
13017 -+pub mod ucontext;
13018 -+pub mod unistd;
13019 -+
13020 -+/*
13021 -+ *
13022 -+ * ===== Result / Error =====
13023 -+ *
13024 -+ */
13025 -+
13026 -+use libc::{c_char, PATH_MAX};
13027 -+
13028 -+use std::{error, fmt, ptr, result};
13029 -+use std::ffi::{CStr, OsStr};
13030 -+use std::os::unix::ffi::OsStrExt;
13031 -+use std::path::{Path, PathBuf};
13032 -+
13033 -+use errno::Errno;
13034 -+
13035 -+/// Nix Result Type
13036 -+pub type Result<T> = result::Result<T, Error>;
13037 -+
13038 -+/// Nix Error Type
13039 -+///
13040 -+/// The nix error type provides a common way of dealing with
13041 -+/// various system system/libc calls that might fail. Each
13042 -+/// error has a corresponding errno (usually the one from the
13043 -+/// underlying OS) to which it can be mapped in addition to
13044 -+/// implementing other common traits.
13045 -+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
13046 -+pub enum Error {
13047 -+ Sys(Errno),
13048 -+ InvalidPath,
13049 -+ /// The operation involved a conversion to Rust's native String type, which failed because the
13050 -+ /// string did not contain all valid UTF-8.
13051 -+ InvalidUtf8,
13052 -+ /// The operation is not supported by Nix, in this instance either use the libc bindings or
13053 -+ /// consult the module documentation to see if there is a more appropriate interface available.
13054 -+ UnsupportedOperation,
13055 -+}
13056 -+
13057 -+impl Error {
13058 -+ /// Convert this `Error` to an [`Errno`](enum.Errno.html).
13059 -+ ///
13060 -+ /// # Example
13061 -+ ///
13062 -+ /// ```
13063 -+ /// # use nix::Error;
13064 -+ /// # use nix::errno::Errno;
13065 -+ /// let e = Error::from(Errno::EPERM);
13066 -+ /// assert_eq!(Some(Errno::EPERM), e.as_errno());
13067 -+ /// ```
13068 -+ pub fn as_errno(&self) -> Option<Errno> {
13069 -+ if let &Error::Sys(ref e) = self {
13070 -+ Some(*e)
13071 -+ } else {
13072 -+ None
13073 -+ }
13074 -+ }
13075 -+
13076 -+ /// Create a nix Error from a given errno
13077 -+ pub fn from_errno(errno: Errno) -> Error {
13078 -+ Error::Sys(errno)
13079 -+ }
13080 -+
13081 -+ /// Get the current errno and convert it to a nix Error
13082 -+ pub fn last() -> Error {
13083 -+ Error::Sys(Errno::last())
13084 -+ }
13085 -+
13086 -+ /// Create a new invalid argument error (`EINVAL`)
13087 -+ pub fn invalid_argument() -> Error {
13088 -+ Error::Sys(Errno::EINVAL)
13089 -+ }
13090 -+
13091 -+}
13092 -+
13093 -+impl From<Errno> for Error {
13094 -+ fn from(errno: Errno) -> Error { Error::from_errno(errno) }
13095 -+}
13096 -+
13097 -+impl From<std::string::FromUtf8Error> for Error {
13098 -+ fn from(_: std::string::FromUtf8Error) -> Error { Error::InvalidUtf8 }
13099 -+}
13100 -+
13101 -+impl error::Error for Error {
13102 -+ fn description(&self) -> &str {
13103 -+ match *self {
13104 -+ Error::InvalidPath => "Invalid path",
13105 -+ Error::InvalidUtf8 => "Invalid UTF-8 string",
13106 -+ Error::UnsupportedOperation => "Unsupported Operation",
13107 -+ Error::Sys(ref errno) => errno.desc(),
13108 -+ }
13109 -+ }
13110 -+}
13111 -+
13112 -+impl fmt::Display for Error {
13113 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
13114 -+ match *self {
13115 -+ Error::InvalidPath => write!(f, "Invalid path"),
13116 -+ Error::InvalidUtf8 => write!(f, "Invalid UTF-8 string"),
13117 -+ Error::UnsupportedOperation => write!(f, "Unsupported Operation"),
13118 -+ Error::Sys(errno) => write!(f, "{:?}: {}", errno, errno.desc()),
13119 -+ }
13120 -+ }
13121 -+}
13122 -+
13123 -+pub trait NixPath {
13124 -+ fn len(&self) -> usize;
13125 -+
13126 -+ fn with_nix_path<T, F>(&self, f: F) -> Result<T>
13127 -+ where F: FnOnce(&CStr) -> T;
13128 -+}
13129 -+
13130 -+impl NixPath for str {
13131 -+ fn len(&self) -> usize {
13132 -+ NixPath::len(OsStr::new(self))
13133 -+ }
13134 -+
13135 -+ fn with_nix_path<T, F>(&self, f: F) -> Result<T>
13136 -+ where F: FnOnce(&CStr) -> T {
13137 -+ OsStr::new(self).with_nix_path(f)
13138 -+ }
13139 -+}
13140 -+
13141 -+impl NixPath for OsStr {
13142 -+ fn len(&self) -> usize {
13143 -+ self.as_bytes().len()
13144 -+ }
13145 -+
13146 -+ fn with_nix_path<T, F>(&self, f: F) -> Result<T>
13147 -+ where F: FnOnce(&CStr) -> T {
13148 -+ self.as_bytes().with_nix_path(f)
13149 -+ }
13150 -+}
13151 -+
13152 -+impl NixPath for CStr {
13153 -+ fn len(&self) -> usize {
13154 -+ self.to_bytes().len()
13155 -+ }
13156 -+
13157 -+ fn with_nix_path<T, F>(&self, f: F) -> Result<T>
13158 -+ where F: FnOnce(&CStr) -> T {
13159 -+ // Equivalence with the [u8] impl.
13160 -+ if self.len() >= PATH_MAX as usize {
13161 -+ return Err(Error::InvalidPath);
13162 -+ }
13163 -+
13164 -+ Ok(f(self))
13165 -+ }
13166 -+}
13167 -+
13168 -+impl NixPath for [u8] {
13169 -+ fn len(&self) -> usize {
13170 -+ self.len()
13171 -+ }
13172 -+
13173 -+ fn with_nix_path<T, F>(&self, f: F) -> Result<T>
13174 -+ where F: FnOnce(&CStr) -> T {
13175 -+ let mut buf = [0u8; PATH_MAX as usize];
13176 -+
13177 -+ if self.len() >= PATH_MAX as usize {
13178 -+ return Err(Error::InvalidPath);
13179 -+ }
13180 -+
13181 -+ match self.iter().position(|b| *b == 0) {
13182 -+ Some(_) => Err(Error::InvalidPath),
13183 -+ None => {
13184 -+ unsafe {
13185 -+ // TODO: Replace with bytes::copy_memory. rust-lang/rust#24028
13186 -+ ptr::copy_nonoverlapping(self.as_ptr(), buf.as_mut_ptr(), self.len());
13187 -+ Ok(f(CStr::from_ptr(buf.as_ptr() as *const c_char)))
13188 -+ }
13189 -+
13190 -+ }
13191 -+ }
13192 -+ }
13193 -+}
13194 -+
13195 -+impl NixPath for Path {
13196 -+ fn len(&self) -> usize {
13197 -+ NixPath::len(self.as_os_str())
13198 -+ }
13199 -+
13200 -+ fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
13201 -+ self.as_os_str().with_nix_path(f)
13202 -+ }
13203 -+}
13204 -+
13205 -+impl NixPath for PathBuf {
13206 -+ fn len(&self) -> usize {
13207 -+ NixPath::len(self.as_os_str())
13208 -+ }
13209 -+
13210 -+ fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
13211 -+ self.as_os_str().with_nix_path(f)
13212 -+ }
13213 -+}
13214 -+
13215 -+/// Treats `None` as an empty string.
13216 -+impl<'a, NP: ?Sized + NixPath> NixPath for Option<&'a NP> {
13217 -+ fn len(&self) -> usize {
13218 -+ self.map_or(0, NixPath::len)
13219 -+ }
13220 -+
13221 -+ fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
13222 -+ if let Some(nix_path) = *self {
13223 -+ nix_path.with_nix_path(f)
13224 -+ } else {
13225 -+ unsafe { CStr::from_ptr("\0".as_ptr() as *const _).with_nix_path(f) }
13226 -+ }
13227 -+ }
13228 -+}
13229 -diff --git a/third_party/rust/nix-0.15.0/src/macros.rs b/third_party/rust/nix-0.15.0/src/macros.rs
13230 -new file mode 100644
13231 -index 0000000000000..3d1b0e4b7699c
13232 ---- /dev/null
13233 -+++ b/third_party/rust/nix-0.15.0/src/macros.rs
13234 -@@ -0,0 +1,264 @@
13235 -+/// The `libc_bitflags!` macro helps with a common use case of defining a public bitflags type
13236 -+/// with values from the libc crate. It is used the same way as the `bitflags!` macro, except
13237 -+/// that only the name of the flag value has to be given.
13238 -+///
13239 -+/// The `libc` crate must be in scope with the name `libc`.
13240 -+///
13241 -+/// # Example
13242 -+/// ```
13243 -+/// libc_bitflags!{
13244 -+/// pub struct ProtFlags: libc::c_int {
13245 -+/// PROT_NONE;
13246 -+/// PROT_READ;
13247 -+/// /// PROT_WRITE enables write protect
13248 -+/// PROT_WRITE;
13249 -+/// PROT_EXEC;
13250 -+/// #[cfg(any(target_os = "linux", target_os = "android"))]
13251 -+/// PROT_GROWSDOWN;
13252 -+/// #[cfg(any(target_os = "linux", target_os = "android"))]
13253 -+/// PROT_GROWSUP;
13254 -+/// }
13255 -+/// }
13256 -+/// ```
13257 -+///
13258 -+/// Example with casting, due to a mistake in libc. In this example, the
13259 -+/// various flags have different types, so we cast the broken ones to the right
13260 -+/// type.
13261 -+///
13262 -+/// ```
13263 -+/// libc_bitflags!{
13264 -+/// pub struct SaFlags: libc::c_ulong {
13265 -+/// SA_NOCLDSTOP as libc::c_ulong;
13266 -+/// SA_NOCLDWAIT;
13267 -+/// SA_NODEFER as libc::c_ulong;
13268 -+/// SA_ONSTACK;
13269 -+/// SA_RESETHAND as libc::c_ulong;
13270 -+/// SA_RESTART as libc::c_ulong;
13271 -+/// SA_SIGINFO;
13272 -+/// }
13273 -+/// }
13274 -+/// ```
13275 -+macro_rules! libc_bitflags {
13276 -+ (
13277 -+ $(#[$outer:meta])*
13278 -+ pub struct $BitFlags:ident: $T:ty {
13279 -+ $(
13280 -+ $(#[$inner:ident $($args:tt)*])*
13281 -+ $Flag:ident $(as $cast:ty)*;
13282 -+ )+
13283 -+ }
13284 -+ ) => {
13285 -+ bitflags! {
13286 -+ $(#[$outer])*
13287 -+ pub struct $BitFlags: $T {
13288 -+ $(
13289 -+ $(#[$inner $($args)*])*
13290 -+ const $Flag = libc::$Flag $(as $cast)*;
13291 -+ )+
13292 -+ }
13293 -+ }
13294 -+ };
13295 -+}
13296 -+
13297 -+/// The `libc_enum!` macro helps with a common use case of defining an enum exclusively using
13298 -+/// values from the `libc` crate. This macro supports both `pub` and private `enum`s.
13299 -+///
13300 -+/// The `libc` crate must be in scope with the name `libc`.
13301 -+///
13302 -+/// # Example
13303 -+/// ```
13304 -+/// libc_enum!{
13305 -+/// pub enum ProtFlags {
13306 -+/// PROT_NONE,
13307 -+/// PROT_READ,
13308 -+/// PROT_WRITE,
13309 -+/// PROT_EXEC,
13310 -+/// #[cfg(any(target_os = "linux", target_os = "android"))]
13311 -+/// PROT_GROWSDOWN,
13312 -+/// #[cfg(any(target_os = "linux", target_os = "android"))]
13313 -+/// PROT_GROWSUP,
13314 -+/// }
13315 -+/// }
13316 -+/// ```
13317 -+macro_rules! libc_enum {
13318 -+ // (non-pub) Exit rule.
13319 -+ (@make_enum
13320 -+ {
13321 -+ name: $BitFlags:ident,
13322 -+ attrs: [$($attrs:tt)*],
13323 -+ entries: [$($entries:tt)*],
13324 -+ }
13325 -+ ) => {
13326 -+ $($attrs)*
13327 -+ #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
13328 -+ enum $BitFlags {
13329 -+ $($entries)*
13330 -+ }
13331 -+ };
13332 -+
13333 -+ // (pub) Exit rule.
13334 -+ (@make_enum
13335 -+ {
13336 -+ pub,
13337 -+ name: $BitFlags:ident,
13338 -+ attrs: [$($attrs:tt)*],
13339 -+ entries: [$($entries:tt)*],
13340 -+ }
13341 -+ ) => {
13342 -+ $($attrs)*
13343 -+ #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
13344 -+ pub enum $BitFlags {
13345 -+ $($entries)*
13346 -+ }
13347 -+ };
13348 -+
13349 -+ // (non-pub) Done accumulating.
13350 -+ (@accumulate_entries
13351 -+ {
13352 -+ name: $BitFlags:ident,
13353 -+ attrs: $attrs:tt,
13354 -+ },
13355 -+ $entries:tt;
13356 -+ ) => {
13357 -+ libc_enum! {
13358 -+ @make_enum
13359 -+ {
13360 -+ name: $BitFlags,
13361 -+ attrs: $attrs,
13362 -+ entries: $entries,
13363 -+ }
13364 -+ }
13365 -+ };
13366 -+
13367 -+ // (pub) Done accumulating.
13368 -+ (@accumulate_entries
13369 -+ {
13370 -+ pub,
13371 -+ name: $BitFlags:ident,
13372 -+ attrs: $attrs:tt,
13373 -+ },
13374 -+ $entries:tt;
13375 -+ ) => {
13376 -+ libc_enum! {
13377 -+ @make_enum
13378 -+ {
13379 -+ pub,
13380 -+ name: $BitFlags,
13381 -+ attrs: $attrs,
13382 -+ entries: $entries,
13383 -+ }
13384 -+ }
13385 -+ };
13386 -+
13387 -+ // Munch an attr.
13388 -+ (@accumulate_entries
13389 -+ $prefix:tt,
13390 -+ [$($entries:tt)*];
13391 -+ #[$attr:meta] $($tail:tt)*
13392 -+ ) => {
13393 -+ libc_enum! {
13394 -+ @accumulate_entries
13395 -+ $prefix,
13396 -+ [
13397 -+ $($entries)*
13398 -+ #[$attr]
13399 -+ ];
13400 -+ $($tail)*
13401 -+ }
13402 -+ };
13403 -+
13404 -+ // Munch last ident if not followed by a comma.
13405 -+ (@accumulate_entries
13406 -+ $prefix:tt,
13407 -+ [$($entries:tt)*];
13408 -+ $entry:ident
13409 -+ ) => {
13410 -+ libc_enum! {
13411 -+ @accumulate_entries
13412 -+ $prefix,
13413 -+ [
13414 -+ $($entries)*
13415 -+ $entry = libc::$entry,
13416 -+ ];
13417 -+ }
13418 -+ };
13419 -+
13420 -+ // Munch an ident; covers terminating comma case.
13421 -+ (@accumulate_entries
13422 -+ $prefix:tt,
13423 -+ [$($entries:tt)*];
13424 -+ $entry:ident, $($tail:tt)*
13425 -+ ) => {
13426 -+ libc_enum! {
13427 -+ @accumulate_entries
13428 -+ $prefix,
13429 -+ [
13430 -+ $($entries)*
13431 -+ $entry = libc::$entry,
13432 -+ ];
13433 -+ $($tail)*
13434 -+ }
13435 -+ };
13436 -+
13437 -+ // Munch an ident and cast it to the given type; covers terminating comma.
13438 -+ (@accumulate_entries
13439 -+ $prefix:tt,
13440 -+ [$($entries:tt)*];
13441 -+ $entry:ident as $ty:ty, $($tail:tt)*
13442 -+ ) => {
13443 -+ libc_enum! {
13444 -+ @accumulate_entries
13445 -+ $prefix,
13446 -+ [
13447 -+ $($entries)*
13448 -+ $entry = libc::$entry as $ty,
13449 -+ ];
13450 -+ $($tail)*
13451 -+ }
13452 -+ };
13453 -+
13454 -+ // (non-pub) Entry rule.
13455 -+ (
13456 -+ $(#[$attr:meta])*
13457 -+ enum $BitFlags:ident {
13458 -+ $($vals:tt)*
13459 -+ }
13460 -+ ) => {
13461 -+ libc_enum! {
13462 -+ @accumulate_entries
13463 -+ {
13464 -+ name: $BitFlags,
13465 -+ attrs: [$(#[$attr])*],
13466 -+ },
13467 -+ [];
13468 -+ $($vals)*
13469 -+ }
13470 -+ };
13471 -+
13472 -+ // (pub) Entry rule.
13473 -+ (
13474 -+ $(#[$attr:meta])*
13475 -+ pub enum $BitFlags:ident {
13476 -+ $($vals:tt)*
13477 -+ }
13478 -+ ) => {
13479 -+ libc_enum! {
13480 -+ @accumulate_entries
13481 -+ {
13482 -+ pub,
13483 -+ name: $BitFlags,
13484 -+ attrs: [$(#[$attr])*],
13485 -+ },
13486 -+ [];
13487 -+ $($vals)*
13488 -+ }
13489 -+ };
13490 -+}
13491 -+
13492 -+/// A Rust version of the familiar C `offset_of` macro. It returns the byte
13493 -+/// offset of `field` within struct `ty`
13494 -+macro_rules! offset_of {
13495 -+ ($ty:ty, $field:ident) => {
13496 -+ &(*(0 as *const $ty)).$field as *const _ as usize
13497 -+ }
13498 -+}
13499 -diff --git a/third_party/rust/nix-0.15.0/src/mount.rs b/third_party/rust/nix-0.15.0/src/mount.rs
13500 -new file mode 100644
13501 -index 0000000000000..a9902b170ace8
13502 ---- /dev/null
13503 -+++ b/third_party/rust/nix-0.15.0/src/mount.rs
13504 -@@ -0,0 +1,98 @@
13505 -+use libc::{self, c_ulong, c_int};
13506 -+use {Result, NixPath};
13507 -+use errno::Errno;
13508 -+
13509 -+libc_bitflags!(
13510 -+ pub struct MsFlags: c_ulong {
13511 -+ /// Mount read-only
13512 -+ MS_RDONLY;
13513 -+ /// Ignore suid and sgid bits
13514 -+ MS_NOSUID;
13515 -+ /// Disallow access to device special files
13516 -+ MS_NODEV;
13517 -+ /// Disallow program execution
13518 -+ MS_NOEXEC;
13519 -+ /// Writes are synced at once
13520 -+ MS_SYNCHRONOUS;
13521 -+ /// Alter flags of a mounted FS
13522 -+ MS_REMOUNT;
13523 -+ /// Allow mandatory locks on a FS
13524 -+ MS_MANDLOCK;
13525 -+ /// Directory modifications are synchronous
13526 -+ MS_DIRSYNC;
13527 -+ /// Do not update access times
13528 -+ MS_NOATIME;
13529 -+ /// Do not update directory access times
13530 -+ MS_NODIRATIME;
13531 -+ /// Linux 2.4.0 - Bind directory at different place
13532 -+ MS_BIND;
13533 -+ MS_MOVE;
13534 -+ MS_REC;
13535 -+ MS_SILENT;
13536 -+ MS_POSIXACL;
13537 -+ MS_UNBINDABLE;
13538 -+ MS_PRIVATE;
13539 -+ MS_SLAVE;
13540 -+ MS_SHARED;
13541 -+ MS_RELATIME;
13542 -+ MS_KERNMOUNT;
13543 -+ MS_I_VERSION;
13544 -+ MS_STRICTATIME;
13545 -+ MS_ACTIVE;
13546 -+ MS_NOUSER;
13547 -+ MS_RMT_MASK;
13548 -+ MS_MGC_VAL;
13549 -+ MS_MGC_MSK;
13550 -+ }
13551 -+);
13552 -+
13553 -+libc_bitflags!(
13554 -+ pub struct MntFlags: c_int {
13555 -+ MNT_FORCE;
13556 -+ MNT_DETACH;
13557 -+ MNT_EXPIRE;
13558 -+ }
13559 -+);
13560 -+
13561 -+pub fn mount<P1: ?Sized + NixPath, P2: ?Sized + NixPath, P3: ?Sized + NixPath, P4: ?Sized + NixPath>(
13562 -+ source: Option<&P1>,
13563 -+ target: &P2,
13564 -+ fstype: Option<&P3>,
13565 -+ flags: MsFlags,
13566 -+ data: Option<&P4>) -> Result<()> {
13567 -+
13568 -+ let res =
13569 -+ source.with_nix_path(|source| {
13570 -+ target.with_nix_path(|target| {
13571 -+ fstype.with_nix_path(|fstype| {
13572 -+ data.with_nix_path(|data| {
13573 -+ unsafe {
13574 -+ libc::mount(source.as_ptr(),
13575 -+ target.as_ptr(),
13576 -+ fstype.as_ptr(),
13577 -+ flags.bits,
13578 -+ data.as_ptr() as *const libc::c_void)
13579 -+ }
13580 -+ })
13581 -+ })
13582 -+ })
13583 -+ })????;
13584 -+
13585 -+ Errno::result(res).map(drop)
13586 -+}
13587 -+
13588 -+pub fn umount<P: ?Sized + NixPath>(target: &P) -> Result<()> {
13589 -+ let res = target.with_nix_path(|cstr| {
13590 -+ unsafe { libc::umount(cstr.as_ptr()) }
13591 -+ })?;
13592 -+
13593 -+ Errno::result(res).map(drop)
13594 -+}
13595 -+
13596 -+pub fn umount2<P: ?Sized + NixPath>(target: &P, flags: MntFlags) -> Result<()> {
13597 -+ let res = target.with_nix_path(|cstr| {
13598 -+ unsafe { libc::umount2(cstr.as_ptr(), flags.bits) }
13599 -+ })?;
13600 -+
13601 -+ Errno::result(res).map(drop)
13602 -+}
13603 -diff --git a/third_party/rust/nix-0.15.0/src/mqueue.rs b/third_party/rust/nix-0.15.0/src/mqueue.rs
13604 -new file mode 100644
13605 -index 0000000000000..b958b71cddb46
13606 ---- /dev/null
13607 -+++ b/third_party/rust/nix-0.15.0/src/mqueue.rs
13608 -@@ -0,0 +1,162 @@
13609 -+//! Posix Message Queue functions
13610 -+//!
13611 -+//! [Further reading and details on the C API](http://man7.org/linux/man-pages/man7/mq_overview.7.html)
13612 -+
13613 -+use Result;
13614 -+use errno::Errno;
13615 -+
13616 -+use libc::{self, c_char, c_long, mqd_t, size_t};
13617 -+use std::ffi::CString;
13618 -+use sys::stat::Mode;
13619 -+use std::mem;
13620 -+
13621 -+libc_bitflags!{
13622 -+ pub struct MQ_OFlag: libc::c_int {
13623 -+ O_RDONLY;
13624 -+ O_WRONLY;
13625 -+ O_RDWR;
13626 -+ O_CREAT;
13627 -+ O_EXCL;
13628 -+ O_NONBLOCK;
13629 -+ O_CLOEXEC;
13630 -+ }
13631 -+}
13632 -+
13633 -+libc_bitflags!{
13634 -+ pub struct FdFlag: libc::c_int {
13635 -+ FD_CLOEXEC;
13636 -+ }
13637 -+}
13638 -+
13639 -+#[repr(C)]
13640 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
13641 -+pub struct MqAttr {
13642 -+ mq_attr: libc::mq_attr,
13643 -+}
13644 -+
13645 -+impl MqAttr {
13646 -+ pub fn new(mq_flags: c_long,
13647 -+ mq_maxmsg: c_long,
13648 -+ mq_msgsize: c_long,
13649 -+ mq_curmsgs: c_long)
13650 -+ -> MqAttr {
13651 -+ let mut attr = unsafe { mem::uninitialized::<libc::mq_attr>() };
13652 -+ attr.mq_flags = mq_flags;
13653 -+ attr.mq_maxmsg = mq_maxmsg;
13654 -+ attr.mq_msgsize = mq_msgsize;
13655 -+ attr.mq_curmsgs = mq_curmsgs;
13656 -+ MqAttr { mq_attr: attr }
13657 -+ }
13658 -+
13659 -+ pub fn flags(&self) -> c_long {
13660 -+ self.mq_attr.mq_flags
13661 -+ }
13662 -+}
13663 -+
13664 -+
13665 -+/// Open a message queue
13666 -+///
13667 -+/// See also [`mq_open(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_open.html)
13668 -+pub fn mq_open(name: &CString,
13669 -+ oflag: MQ_OFlag,
13670 -+ mode: Mode,
13671 -+ attr: Option<&MqAttr>)
13672 -+ -> Result<mqd_t> {
13673 -+ let res = match attr {
13674 -+ Some(mq_attr) => unsafe {
13675 -+ libc::mq_open(name.as_ptr(),
13676 -+ oflag.bits(),
13677 -+ mode.bits() as libc::c_int,
13678 -+ &mq_attr.mq_attr as *const libc::mq_attr)
13679 -+ },
13680 -+ None => unsafe { libc::mq_open(name.as_ptr(), oflag.bits()) },
13681 -+ };
13682 -+ Errno::result(res)
13683 -+}
13684 -+
13685 -+/// Remove a message queue
13686 -+///
13687 -+/// See also [`mq_unlink(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_unlink.html)
13688 -+pub fn mq_unlink(name: &CString) -> Result<()> {
13689 -+ let res = unsafe { libc::mq_unlink(name.as_ptr()) };
13690 -+ Errno::result(res).map(drop)
13691 -+}
13692 -+
13693 -+/// Close a message queue
13694 -+///
13695 -+/// See also [`mq_close(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_close.html)
13696 -+pub fn mq_close(mqdes: mqd_t) -> Result<()> {
13697 -+ let res = unsafe { libc::mq_close(mqdes) };
13698 -+ Errno::result(res).map(drop)
13699 -+}
13700 -+
13701 -+/// Receive a message from a message queue
13702 -+///
13703 -+/// See also [`mq_receive(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html)
13704 -+pub fn mq_receive(mqdes: mqd_t, message: &mut [u8], msg_prio: &mut u32) -> Result<usize> {
13705 -+ let len = message.len() as size_t;
13706 -+ let res = unsafe {
13707 -+ libc::mq_receive(mqdes,
13708 -+ message.as_mut_ptr() as *mut c_char,
13709 -+ len,
13710 -+ msg_prio as *mut u32)
13711 -+ };
13712 -+ Errno::result(res).map(|r| r as usize)
13713 -+}
13714 -+
13715 -+/// Send a message to a message queue
13716 -+///
13717 -+/// See also [`mq_send(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html)
13718 -+pub fn mq_send(mqdes: mqd_t, message: &[u8], msq_prio: u32) -> Result<()> {
13719 -+ let res = unsafe {
13720 -+ libc::mq_send(mqdes,
13721 -+ message.as_ptr() as *const c_char,
13722 -+ message.len(),
13723 -+ msq_prio)
13724 -+ };
13725 -+ Errno::result(res).map(drop)
13726 -+}
13727 -+
13728 -+/// Get message queue attributes
13729 -+///
13730 -+/// See also [`mq_getattr(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_getattr.html)
13731 -+pub fn mq_getattr(mqd: mqd_t) -> Result<MqAttr> {
13732 -+ let mut attr = unsafe { mem::uninitialized::<libc::mq_attr>() };
13733 -+ let res = unsafe { libc::mq_getattr(mqd, &mut attr) };
13734 -+ Errno::result(res).map(|_| MqAttr { mq_attr: attr })
13735 -+}
13736 -+
13737 -+/// Set the attributes of the message queue. Only `O_NONBLOCK` can be set, everything else will be ignored
13738 -+/// Returns the old attributes
13739 -+/// It is recommend to use the `mq_set_nonblock()` and `mq_remove_nonblock()` convenience functions as they are easier to use
13740 -+///
13741 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_setattr.html)
13742 -+pub fn mq_setattr(mqd: mqd_t, newattr: &MqAttr) -> Result<MqAttr> {
13743 -+ let mut attr = unsafe { mem::uninitialized::<libc::mq_attr>() };
13744 -+ let res = unsafe { libc::mq_setattr(mqd, &newattr.mq_attr as *const libc::mq_attr, &mut attr) };
13745 -+ Errno::result(res).map(|_| MqAttr { mq_attr: attr })
13746 -+}
13747 -+
13748 -+/// Convenience function.
13749 -+/// Sets the `O_NONBLOCK` attribute for a given message queue descriptor
13750 -+/// Returns the old attributes
13751 -+pub fn mq_set_nonblock(mqd: mqd_t) -> Result<(MqAttr)> {
13752 -+ let oldattr = mq_getattr(mqd)?;
13753 -+ let newattr = MqAttr::new(MQ_OFlag::O_NONBLOCK.bits() as c_long,
13754 -+ oldattr.mq_attr.mq_maxmsg,
13755 -+ oldattr.mq_attr.mq_msgsize,
13756 -+ oldattr.mq_attr.mq_curmsgs);
13757 -+ mq_setattr(mqd, &newattr)
13758 -+}
13759 -+
13760 -+/// Convenience function.
13761 -+/// Removes `O_NONBLOCK` attribute for a given message queue descriptor
13762 -+/// Returns the old attributes
13763 -+pub fn mq_remove_nonblock(mqd: mqd_t) -> Result<(MqAttr)> {
13764 -+ let oldattr = mq_getattr(mqd)?;
13765 -+ let newattr = MqAttr::new(0,
13766 -+ oldattr.mq_attr.mq_maxmsg,
13767 -+ oldattr.mq_attr.mq_msgsize,
13768 -+ oldattr.mq_attr.mq_curmsgs);
13769 -+ mq_setattr(mqd, &newattr)
13770 -+}
13771 -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
13772 -new file mode 100644
13773 -index 0000000000000..58d677ae343d1
13774 ---- /dev/null
13775 -+++ b/third_party/rust/nix-0.15.0/src/net/if_.rs
13776 -@@ -0,0 +1,268 @@
13777 -+//! Network interface name resolution.
13778 -+//!
13779 -+//! Uses Linux and/or POSIX functions to resolve interface names like "eth0"
13780 -+//! or "socan1" into device numbers.
13781 -+
13782 -+use libc;
13783 -+use libc::c_uint;
13784 -+use {Result, Error, NixPath};
13785 -+
13786 -+/// Resolve an interface into a interface number.
13787 -+pub fn if_nametoindex<P: ?Sized + NixPath>(name: &P) -> Result<c_uint> {
13788 -+ let if_index = name.with_nix_path(|name| unsafe { libc::if_nametoindex(name.as_ptr()) })?;
13789 -+
13790 -+ if if_index == 0 {
13791 -+ Err(Error::last())
13792 -+ } else {
13793 -+ Ok(if_index)
13794 -+ }
13795 -+}
13796 -+
13797 -+libc_bitflags!(
13798 -+ /// Standard interface flags, used by `getifaddrs`
13799 -+ pub struct InterfaceFlags: libc::c_int {
13800 -+ /// Interface is running. (see
13801 -+ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
13802 -+ IFF_UP;
13803 -+ /// Valid broadcast address set. (see
13804 -+ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
13805 -+ IFF_BROADCAST;
13806 -+ /// Internal debugging flag. (see
13807 -+ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
13808 -+ IFF_DEBUG;
13809 -+ /// Interface is a loopback interface. (see
13810 -+ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
13811 -+ IFF_LOOPBACK;
13812 -+ /// Interface is a point-to-point link. (see
13813 -+ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
13814 -+ IFF_POINTOPOINT;
13815 -+ /// Avoid use of trailers. (see
13816 -+ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
13817 -+ #[cfg(any(target_os = "android",
13818 -+ target_os = "fuchsia",
13819 -+ target_os = "ios",
13820 -+ target_os = "linux",
13821 -+ target_os = "macos",
13822 -+ target_os = "netbsd",
13823 -+ target_os = "solaris"))]
13824 -+ IFF_NOTRAILERS;
13825 -+ /// Interface manages own routes.
13826 -+ #[cfg(any(target_os = "dragonfly"))]
13827 -+ IFF_SMART;
13828 -+ /// Resources allocated. (see
13829 -+ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
13830 -+ #[cfg(any(target_os = "android",
13831 -+ target_os = "dragonfly",
13832 -+ target_os = "freebsd",
13833 -+ target_os = "fuchsia",
13834 -+ target_os = "ios",
13835 -+ target_os = "linux",
13836 -+ target_os = "macos",
13837 -+ target_os = "netbsd",
13838 -+ target_os = "openbsd",
13839 -+ target_os = "solaris"))]
13840 -+ IFF_RUNNING;
13841 -+ /// No arp protocol, L2 destination address not set. (see
13842 -+ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
13843 -+ IFF_NOARP;
13844 -+ /// Interface is in promiscuous mode. (see
13845 -+ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
13846 -+ IFF_PROMISC;
13847 -+ /// Receive all multicast packets. (see
13848 -+ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
13849 -+ IFF_ALLMULTI;
13850 -+ /// Master of a load balancing bundle. (see
13851 -+ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
13852 -+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
13853 -+ IFF_MASTER;
13854 -+ /// transmission in progress, tx hardware queue is full
13855 -+ #[cfg(any(target_os = "freebsd",
13856 -+ target_os = "macos",
13857 -+ target_os = "netbsd",
13858 -+ target_os = "openbsd",
13859 -+ target_os = "ios"))]
13860 -+ IFF_OACTIVE;
13861 -+ /// Protocol code on board.
13862 -+ #[cfg(target_os = "solaris")]
13863 -+ IFF_INTELLIGENT;
13864 -+ /// Slave of a load balancing bundle. (see
13865 -+ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
13866 -+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
13867 -+ IFF_SLAVE;
13868 -+ /// Can't hear own transmissions.
13869 -+ #[cfg(any(target_os = "dragonfly",
13870 -+ target_os = "freebsd",
13871 -+ target_os = "macos",
13872 -+ target_os = "netbsd",
13873 -+ target_os = "openbsd",
13874 -+ target_os = "osx"))]
13875 -+ IFF_SIMPLEX;
13876 -+ /// Supports multicast. (see
13877 -+ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
13878 -+ IFF_MULTICAST;
13879 -+ /// Per link layer defined bit.
13880 -+ #[cfg(any(target_os = "dragonfly",
13881 -+ target_os = "freebsd",
13882 -+ target_os = "macos",
13883 -+ target_os = "netbsd",
13884 -+ target_os = "openbsd",
13885 -+ target_os = "ios"))]
13886 -+ IFF_LINK0;
13887 -+ /// Multicast using broadcast.
13888 -+ #[cfg(any(target_os = "solaris"))]
13889 -+ IFF_MULTI_BCAST;
13890 -+ /// Is able to select media type via ifmap. (see
13891 -+ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
13892 -+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
13893 -+ IFF_PORTSEL;
13894 -+ /// Per link layer defined bit.
13895 -+ #[cfg(any(target_os = "dragonfly",
13896 -+ target_os = "freebsd",
13897 -+ target_os = "macos",
13898 -+ target_os = "netbsd",
13899 -+ target_os = "openbsd",
13900 -+ target_os = "ios"))]
13901 -+ IFF_LINK1;
13902 -+ /// Non-unique address.
13903 -+ #[cfg(any(target_os = "solaris"))]
13904 -+ IFF_UNNUMBERED;
13905 -+ /// Auto media selection active. (see
13906 -+ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
13907 -+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
13908 -+ IFF_AUTOMEDIA;
13909 -+ /// Per link layer defined bit.
13910 -+ #[cfg(any(target_os = "dragonfly",
13911 -+ target_os = "freebsd",
13912 -+ target_os = "macos",
13913 -+ target_os = "netbsd",
13914 -+ target_os = "openbsd",
13915 -+ target_os = "ios"))]
13916 -+ IFF_LINK2;
13917 -+ /// Use alternate physical connection.
13918 -+ #[cfg(any(target_os = "dragonfly",
13919 -+ target_os = "freebsd",
13920 -+ target_os = "macos",
13921 -+ target_os = "ios"))]
13922 -+ IFF_ALTPHYS;
13923 -+ /// DHCP controlls interface.
13924 -+ #[cfg(any(target_os = "solaris"))]
13925 -+ IFF_DHCPRUNNING;
13926 -+ /// The addresses are lost when the interface goes down. (see
13927 -+ /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html))
13928 -+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
13929 -+ IFF_DYNAMIC;
13930 -+ /// Do not advertise.
13931 -+ #[cfg(any(target_os = "solaris"))]
13932 -+ IFF_PRIVATE;
13933 -+ /// Driver signals L1 up. Volatile.
13934 -+ #[cfg(any(target_os = "fuchsia", target_os = "linux"))]
13935 -+ IFF_LOWER_UP;
13936 -+ /// Interface is in polling mode.
13937 -+ #[cfg(any(target_os = "dragonfly"))]
13938 -+ IFF_POLLING_COMPAT;
13939 -+ /// Unconfigurable using ioctl(2).
13940 -+ #[cfg(any(target_os = "freebsd"))]
13941 -+ IFF_CANTCONFIG;
13942 -+ /// Do not transmit packets.
13943 -+ #[cfg(any(target_os = "solaris"))]
13944 -+ IFF_NOXMIT;
13945 -+ /// Driver signals dormant. Volatile.
13946 -+ #[cfg(any(target_os = "fuchsia", target_os = "linux"))]
13947 -+ IFF_DORMANT;
13948 -+ /// User-requested promisc mode.
13949 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
13950 -+ IFF_PPROMISC;
13951 -+ /// Just on-link subnet.
13952 -+ #[cfg(any(target_os = "solaris"))]
13953 -+ IFF_NOLOCAL;
13954 -+ /// Echo sent packets. Volatile.
13955 -+ #[cfg(any(target_os = "fuchsia", target_os = "linux"))]
13956 -+ IFF_ECHO;
13957 -+ /// User-requested monitor mode.
13958 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
13959 -+ IFF_MONITOR;
13960 -+ /// Address is deprecated.
13961 -+ #[cfg(any(target_os = "solaris"))]
13962 -+ IFF_DEPRECATED;
13963 -+ /// Static ARP.
13964 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
13965 -+ IFF_STATICARP;
13966 -+ /// Address from stateless addrconf.
13967 -+ #[cfg(any(target_os = "solaris"))]
13968 -+ IFF_ADDRCONF;
13969 -+ /// Interface is in polling mode.
13970 -+ #[cfg(any(target_os = "dragonfly"))]
13971 -+ IFF_NPOLLING;
13972 -+ /// Router on interface.
13973 -+ #[cfg(any(target_os = "solaris"))]
13974 -+ IFF_ROUTER;
13975 -+ /// Interface is in polling mode.
13976 -+ #[cfg(any(target_os = "dragonfly"))]
13977 -+ IFF_IDIRECT;
13978 -+ /// Interface is winding down
13979 -+ #[cfg(any(target_os = "freebsd"))]
13980 -+ IFF_DYING;
13981 -+ /// No NUD on interface.
13982 -+ #[cfg(any(target_os = "solaris"))]
13983 -+ IFF_NONUD;
13984 -+ /// Interface is being renamed
13985 -+ #[cfg(any(target_os = "freebsd"))]
13986 -+ IFF_RENAMING;
13987 -+ /// Anycast address.
13988 -+ #[cfg(any(target_os = "solaris"))]
13989 -+ IFF_ANYCAST;
13990 -+ /// Don't exchange routing info.
13991 -+ #[cfg(any(target_os = "solaris"))]
13992 -+ IFF_NORTEXCH;
13993 -+ /// Do not provide packet information
13994 -+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
13995 -+ IFF_NO_PI as libc::c_int;
13996 -+ /// TUN device (no Ethernet headers)
13997 -+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
13998 -+ IFF_TUN as libc::c_int;
13999 -+ /// TAP device
14000 -+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
14001 -+ IFF_TAP as libc::c_int;
14002 -+ /// IPv4 interface.
14003 -+ #[cfg(any(target_os = "solaris"))]
14004 -+ IFF_IPV4;
14005 -+ /// IPv6 interface.
14006 -+ #[cfg(any(target_os = "solaris"))]
14007 -+ IFF_IPV6;
14008 -+ /// in.mpathd test address
14009 -+ #[cfg(any(target_os = "solaris"))]
14010 -+ IFF_NOFAILOVER;
14011 -+ /// Interface has failed
14012 -+ #[cfg(any(target_os = "solaris"))]
14013 -+ IFF_FAILED;
14014 -+ /// Interface is a hot-spare
14015 -+ #[cfg(any(target_os = "solaris"))]
14016 -+ IFF_STANDBY;
14017 -+ /// Functioning but not used
14018 -+ #[cfg(any(target_os = "solaris"))]
14019 -+ IFF_INACTIVE;
14020 -+ /// Interface is offline
14021 -+ #[cfg(any(target_os = "solaris"))]
14022 -+ IFF_OFFLINE;
14023 -+ #[cfg(any(target_os = "solaris"))]
14024 -+ IFF_COS_ENABLED;
14025 -+ /// Prefer as source addr.
14026 -+ #[cfg(any(target_os = "solaris"))]
14027 -+ IFF_PREFERRED;
14028 -+ /// RFC3041
14029 -+ #[cfg(any(target_os = "solaris"))]
14030 -+ IFF_TEMPORARY;
14031 -+ /// MTU set with SIOCSLIFMTU
14032 -+ #[cfg(any(target_os = "solaris"))]
14033 -+ IFF_FIXEDMTU;
14034 -+ /// Cannot send / receive packets
14035 -+ #[cfg(any(target_os = "solaris"))]
14036 -+ IFF_VIRTUAL;
14037 -+ /// Local address in use
14038 -+ #[cfg(any(target_os = "solaris"))]
14039 -+ IFF_DUPLICATE;
14040 -+ /// IPMP IP interface
14041 -+ #[cfg(any(target_os = "solaris"))]
14042 -+ IFF_IPMP;
14043 -+ }
14044 -+);
14045 -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
14046 -new file mode 100644
14047 -index 0000000000000..079fcfde6fd44
14048 ---- /dev/null
14049 -+++ b/third_party/rust/nix-0.15.0/src/net/mod.rs
14050 -@@ -0,0 +1,4 @@
14051 -+//! Functionality involving network interfaces
14052 -+// To avoid clashing with the keyword "if", we use "if_" as the module name.
14053 -+// The original header is called "net/if.h".
14054 -+pub mod if_;
14055 -diff --git a/third_party/rust/nix-0.15.0/src/poll.rs b/third_party/rust/nix-0.15.0/src/poll.rs
14056 -new file mode 100644
14057 -index 0000000000000..c603611e3176f
14058 ---- /dev/null
14059 -+++ b/third_party/rust/nix-0.15.0/src/poll.rs
14060 -@@ -0,0 +1,143 @@
14061 -+//! Wait for events to trigger on specific file descriptors
14062 -+#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
14063 -+use sys::time::TimeSpec;
14064 -+#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
14065 -+use sys::signal::SigSet;
14066 -+use std::os::unix::io::RawFd;
14067 -+
14068 -+use libc;
14069 -+use Result;
14070 -+use errno::Errno;
14071 -+
14072 -+/// This is a wrapper around `libc::pollfd`.
14073 -+///
14074 -+/// It's meant to be used as an argument to the [`poll`](fn.poll.html) and
14075 -+/// [`ppoll`](fn.ppoll.html) functions to specify the events of interest
14076 -+/// for a specific file descriptor.
14077 -+///
14078 -+/// After a call to `poll` or `ppoll`, the events that occured can be
14079 -+/// retrieved by calling [`revents()`](#method.revents) on the `PollFd`.
14080 -+#[repr(C)]
14081 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
14082 -+pub struct PollFd {
14083 -+ pollfd: libc::pollfd,
14084 -+}
14085 -+
14086 -+impl PollFd {
14087 -+ /// Creates a new `PollFd` specifying the events of interest
14088 -+ /// for a given file descriptor.
14089 -+ pub fn new(fd: RawFd, events: PollFlags) -> PollFd {
14090 -+ PollFd {
14091 -+ pollfd: libc::pollfd {
14092 -+ fd: fd,
14093 -+ events: events.bits(),
14094 -+ revents: PollFlags::empty().bits(),
14095 -+ },
14096 -+ }
14097 -+ }
14098 -+
14099 -+ /// Returns the events that occured in the last call to `poll` or `ppoll`.
14100 -+ pub fn revents(&self) -> Option<PollFlags> {
14101 -+ PollFlags::from_bits(self.pollfd.revents)
14102 -+ }
14103 -+}
14104 -+
14105 -+libc_bitflags! {
14106 -+ /// These flags define the different events that can be monitored by `poll` and `ppoll`
14107 -+ pub struct PollFlags: libc::c_short {
14108 -+ /// There is data to read.
14109 -+ POLLIN;
14110 -+ /// There is some exceptional condition on the file descriptor.
14111 -+ ///
14112 -+ /// Possibilities include:
14113 -+ ///
14114 -+ /// * There is out-of-band data on a TCP socket (see
14115 -+ /// [tcp(7)](http://man7.org/linux/man-pages/man7/tcp.7.html)).
14116 -+ /// * A pseudoterminal master in packet mode has seen a state
14117 -+ /// change on the slave (see
14118 -+ /// [ioctl_tty(2)](http://man7.org/linux/man-pages/man2/ioctl_tty.2.html)).
14119 -+ /// * A cgroup.events file has been modified (see
14120 -+ /// [cgroups(7)](http://man7.org/linux/man-pages/man7/cgroups.7.html)).
14121 -+ POLLPRI;
14122 -+ /// Writing is now possible, though a write larger that the
14123 -+ /// available space in a socket or pipe will still block (unless
14124 -+ /// `O_NONBLOCK` is set).
14125 -+ POLLOUT;
14126 -+ /// Equivalent to [`POLLIN`](constant.POLLIN.html)
14127 -+ POLLRDNORM;
14128 -+ /// Equivalent to [`POLLOUT`](constant.POLLOUT.html)
14129 -+ POLLWRNORM;
14130 -+ /// Priority band data can be read (generally unused on Linux).
14131 -+ POLLRDBAND;
14132 -+ /// Priority data may be written.
14133 -+ POLLWRBAND;
14134 -+ /// Error condition (only returned in
14135 -+ /// [`PollFd::revents`](struct.PollFd.html#method.revents);
14136 -+ /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
14137 -+ /// This bit is also set for a file descriptor referring to the
14138 -+ /// write end of a pipe when the read end has been closed.
14139 -+ POLLERR;
14140 -+ /// Hang up (only returned in [`PollFd::revents`](struct.PollFd.html#method.revents);
14141 -+ /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
14142 -+ /// Note that when reading from a channel such as a pipe or a stream
14143 -+ /// socket, this event merely indicates that the peer closed its
14144 -+ /// end of the channel. Subsequent reads from the channel will
14145 -+ /// return 0 (end of file) only after all outstanding data in the
14146 -+ /// channel has been consumed.
14147 -+ POLLHUP;
14148 -+ /// Invalid request: `fd` not open (only returned in
14149 -+ /// [`PollFd::revents`](struct.PollFd.html#method.revents);
14150 -+ /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
14151 -+ POLLNVAL;
14152 -+ }
14153 -+}
14154 -+
14155 -+/// `poll` waits for one of a set of file descriptors to become ready to perform I/O.
14156 -+/// ([`poll(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html))
14157 -+///
14158 -+/// `fds` contains all [`PollFd`](struct.PollFd.html) to poll.
14159 -+/// The function will return as soon as any event occur for any of these `PollFd`s.
14160 -+///
14161 -+/// The `timeout` argument specifies the number of milliseconds that `poll()`
14162 -+/// should block waiting for a file descriptor to become ready. The call
14163 -+/// will block until either:
14164 -+///
14165 -+/// * a file descriptor becomes ready;
14166 -+/// * the call is interrupted by a signal handler; or
14167 -+/// * the timeout expires.
14168 -+///
14169 -+/// Note that the timeout interval will be rounded up to the system clock
14170 -+/// granularity, and kernel scheduling delays mean that the blocking
14171 -+/// interval may overrun by a small amount. Specifying a negative value
14172 -+/// in timeout means an infinite timeout. Specifying a timeout of zero
14173 -+/// causes `poll()` to return immediately, even if no file descriptors are
14174 -+/// ready.
14175 -+pub fn poll(fds: &mut [PollFd], timeout: libc::c_int) -> Result<libc::c_int> {
14176 -+ let res = unsafe {
14177 -+ libc::poll(fds.as_mut_ptr() as *mut libc::pollfd,
14178 -+ fds.len() as libc::nfds_t,
14179 -+ timeout)
14180 -+ };
14181 -+
14182 -+ Errno::result(res)
14183 -+}
14184 -+
14185 -+/// `ppoll()` allows an application to safely wait until either a file
14186 -+/// descriptor becomes ready or until a signal is caught.
14187 -+/// ([`poll(2)`](http://man7.org/linux/man-pages/man2/poll.2.html))
14188 -+///
14189 -+/// `ppoll` behaves like `poll`, but let you specify what signals may interrupt it
14190 -+/// with the `sigmask` argument.
14191 -+///
14192 -+#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
14193 -+pub fn ppoll(fds: &mut [PollFd], timeout: TimeSpec, sigmask: SigSet) -> Result<libc::c_int> {
14194 -+
14195 -+
14196 -+ let res = unsafe {
14197 -+ libc::ppoll(fds.as_mut_ptr() as *mut libc::pollfd,
14198 -+ fds.len() as libc::nfds_t,
14199 -+ timeout.as_ref(),
14200 -+ sigmask.as_ref())
14201 -+ };
14202 -+ Errno::result(res)
14203 -+}
14204 -diff --git a/third_party/rust/nix-0.15.0/src/pty.rs b/third_party/rust/nix-0.15.0/src/pty.rs
14205 -new file mode 100644
14206 -index 0000000000000..db012d8158c53
14207 ---- /dev/null
14208 -+++ b/third_party/rust/nix-0.15.0/src/pty.rs
14209 -@@ -0,0 +1,326 @@
14210 -+//! Create master and slave virtual pseudo-terminals (PTYs)
14211 -+
14212 -+use libc;
14213 -+
14214 -+pub use libc::pid_t as SessionId;
14215 -+pub use libc::winsize as Winsize;
14216 -+
14217 -+use std::ffi::CStr;
14218 -+use std::mem;
14219 -+use std::os::unix::prelude::*;
14220 -+
14221 -+use sys::termios::Termios;
14222 -+use unistd::ForkResult;
14223 -+use {Result, Error, fcntl};
14224 -+use errno::Errno;
14225 -+
14226 -+/// Representation of a master/slave pty pair
14227 -+///
14228 -+/// This is returned by `openpty`. Note that this type does *not* implement `Drop`, so the user
14229 -+/// must manually close the file descriptors.
14230 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
14231 -+pub struct OpenptyResult {
14232 -+ /// The master port in a virtual pty pair
14233 -+ pub master: RawFd,
14234 -+ /// The slave port in a virtual pty pair
14235 -+ pub slave: RawFd,
14236 -+}
14237 -+
14238 -+/// Representation of a master with a forked pty
14239 -+///
14240 -+/// This is returned by `forkpty`. Note that this type does *not* implement `Drop`, so the user
14241 -+/// must manually close the file descriptors.
14242 -+#[derive(Clone, Copy, Debug)]
14243 -+pub struct ForkptyResult {
14244 -+ /// The master port in a virtual pty pair
14245 -+ pub master: RawFd,
14246 -+ /// Metadata about forked process
14247 -+ pub fork_result: ForkResult,
14248 -+}
14249 -+
14250 -+
14251 -+/// Representation of the Master device in a master/slave pty pair
14252 -+///
14253 -+/// While this datatype is a thin wrapper around `RawFd`, it enforces that the available PTY
14254 -+/// functions are given the correct file descriptor. Additionally this type implements `Drop`,
14255 -+/// so that when it's consumed or goes out of scope, it's automatically cleaned-up.
14256 -+#[derive(Clone, Debug, Eq, Hash, PartialEq)]
14257 -+pub struct PtyMaster(RawFd);
14258 -+
14259 -+impl AsRawFd for PtyMaster {
14260 -+ fn as_raw_fd(&self) -> RawFd {
14261 -+ self.0
14262 -+ }
14263 -+}
14264 -+
14265 -+impl IntoRawFd for PtyMaster {
14266 -+ fn into_raw_fd(self) -> RawFd {
14267 -+ let fd = self.0;
14268 -+ mem::forget(self);
14269 -+ fd
14270 -+ }
14271 -+}
14272 -+
14273 -+impl Drop for PtyMaster {
14274 -+ fn drop(&mut self) {
14275 -+ // On drop, we ignore errors like EINTR and EIO because there's no clear
14276 -+ // way to handle them, we can't return anything, and (on FreeBSD at
14277 -+ // least) the file descriptor is deallocated in these cases. However,
14278 -+ // we must panic on EBADF, because it is always an error to close an
14279 -+ // invalid file descriptor. That frequently indicates a double-close
14280 -+ // condition, which can cause confusing errors for future I/O
14281 -+ // operations.
14282 -+ let e = ::unistd::close(self.0);
14283 -+ if e == Err(Error::Sys(Errno::EBADF)) {
14284 -+ panic!("Closing an invalid file descriptor!");
14285 -+ };
14286 -+ }
14287 -+}
14288 -+
14289 -+/// Grant access to a slave pseudoterminal (see
14290 -+/// [`grantpt(3)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/grantpt.html))
14291 -+///
14292 -+/// `grantpt()` changes the mode and owner of the slave pseudoterminal device corresponding to the
14293 -+/// master pseudoterminal referred to by `fd`. This is a necessary step towards opening the slave.
14294 -+#[inline]
14295 -+pub fn grantpt(fd: &PtyMaster) -> Result<()> {
14296 -+ if unsafe { libc::grantpt(fd.as_raw_fd()) } < 0 {
14297 -+ return Err(Error::last());
14298 -+ }
14299 -+
14300 -+ Ok(())
14301 -+}
14302 -+
14303 -+/// Open a pseudoterminal device (see
14304 -+/// [`posix_openpt(3)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_openpt.html))
14305 -+///
14306 -+/// `posix_openpt()` returns a file descriptor to an existing unused pseuterminal master device.
14307 -+///
14308 -+/// # Examples
14309 -+///
14310 -+/// A common use case with this function is to open both a master and slave PTY pair. This can be
14311 -+/// done as follows:
14312 -+///
14313 -+/// ```
14314 -+/// use std::path::Path;
14315 -+/// use nix::fcntl::{OFlag, open};
14316 -+/// use nix::pty::{grantpt, posix_openpt, ptsname, unlockpt};
14317 -+/// use nix::sys::stat::Mode;
14318 -+///
14319 -+/// # #[allow(dead_code)]
14320 -+/// # fn run() -> nix::Result<()> {
14321 -+/// // Open a new PTY master
14322 -+/// let master_fd = posix_openpt(OFlag::O_RDWR)?;
14323 -+///
14324 -+/// // Allow a slave to be generated for it
14325 -+/// grantpt(&master_fd)?;
14326 -+/// unlockpt(&master_fd)?;
14327 -+///
14328 -+/// // Get the name of the slave
14329 -+/// let slave_name = unsafe { ptsname(&master_fd) }?;
14330 -+///
14331 -+/// // Try to open the slave
14332 -+/// let _slave_fd = open(Path::new(&slave_name), OFlag::O_RDWR, Mode::empty())?;
14333 -+/// # Ok(())
14334 -+/// # }
14335 -+/// ```
14336 -+#[inline]
14337 -+pub fn posix_openpt(flags: fcntl::OFlag) -> Result<PtyMaster> {
14338 -+ let fd = unsafe {
14339 -+ libc::posix_openpt(flags.bits())
14340 -+ };
14341 -+
14342 -+ if fd < 0 {
14343 -+ return Err(Error::last());
14344 -+ }
14345 -+
14346 -+ Ok(PtyMaster(fd))
14347 -+}
14348 -+
14349 -+/// Get the name of the slave pseudoterminal (see
14350 -+/// [`ptsname(3)`](http://man7.org/linux/man-pages/man3/ptsname.3.html))
14351 -+///
14352 -+/// `ptsname()` returns the name of the slave pseudoterminal device corresponding to the master
14353 -+/// referred to by `fd`.
14354 -+///
14355 -+/// This value is useful for opening the slave pty once the master has already been opened with
14356 -+/// `posix_openpt()`.
14357 -+///
14358 -+/// # Safety
14359 -+///
14360 -+/// `ptsname()` mutates global variables and is *not* threadsafe.
14361 -+/// Mutating global variables is always considered `unsafe` by Rust and this
14362 -+/// function is marked as `unsafe` to reflect that.
14363 -+///
14364 -+/// For a threadsafe and non-`unsafe` alternative on Linux, see `ptsname_r()`.
14365 -+#[inline]
14366 -+pub unsafe fn ptsname(fd: &PtyMaster) -> Result<String> {
14367 -+ let name_ptr = libc::ptsname(fd.as_raw_fd());
14368 -+ if name_ptr.is_null() {
14369 -+ return Err(Error::last());
14370 -+ }
14371 -+
14372 -+ let name = CStr::from_ptr(name_ptr);
14373 -+ Ok(name.to_string_lossy().into_owned())
14374 -+}
14375 -+
14376 -+/// Get the name of the slave pseudoterminal (see
14377 -+/// [`ptsname(3)`](http://man7.org/linux/man-pages/man3/ptsname.3.html))
14378 -+///
14379 -+/// `ptsname_r()` returns the name of the slave pseudoterminal device corresponding to the master
14380 -+/// referred to by `fd`. This is the threadsafe version of `ptsname()`, but it is not part of the
14381 -+/// POSIX standard and is instead a Linux-specific extension.
14382 -+///
14383 -+/// This value is useful for opening the slave ptty once the master has already been opened with
14384 -+/// `posix_openpt()`.
14385 -+#[cfg(any(target_os = "android", target_os = "linux"))]
14386 -+#[inline]
14387 -+pub fn ptsname_r(fd: &PtyMaster) -> Result<String> {
14388 -+ let mut name_buf = vec![0u8; 64];
14389 -+ let name_buf_ptr = name_buf.as_mut_ptr() as *mut libc::c_char;
14390 -+ if unsafe { libc::ptsname_r(fd.as_raw_fd(), name_buf_ptr, name_buf.capacity()) } != 0 {
14391 -+ return Err(Error::last());
14392 -+ }
14393 -+
14394 -+ // Find the first null-character terminating this string. This is guaranteed to succeed if the
14395 -+ // return value of `libc::ptsname_r` is 0.
14396 -+ let null_index = name_buf.iter().position(|c| *c == b'\0').unwrap();
14397 -+ name_buf.truncate(null_index);
14398 -+
14399 -+ let name = String::from_utf8(name_buf)?;
14400 -+ Ok(name)
14401 -+}
14402 -+
14403 -+/// Unlock a pseudoterminal master/slave pseudoterminal pair (see
14404 -+/// [`unlockpt(3)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlockpt.html))
14405 -+///
14406 -+/// `unlockpt()` unlocks the slave pseudoterminal device corresponding to the master pseudoterminal
14407 -+/// referred to by `fd`. This must be called before trying to open the slave side of a
14408 -+/// pseuoterminal.
14409 -+#[inline]
14410 -+pub fn unlockpt(fd: &PtyMaster) -> Result<()> {
14411 -+ if unsafe { libc::unlockpt(fd.as_raw_fd()) } < 0 {
14412 -+ return Err(Error::last());
14413 -+ }
14414 -+
14415 -+ Ok(())
14416 -+}
14417 -+
14418 -+
14419 -+/// Create a new pseudoterminal, returning the slave and master file descriptors
14420 -+/// in `OpenptyResult`
14421 -+/// (see [`openpty`](http://man7.org/linux/man-pages/man3/openpty.3.html)).
14422 -+///
14423 -+/// If `winsize` is not `None`, the window size of the slave will be set to
14424 -+/// the values in `winsize`. If `termios` is not `None`, the pseudoterminal's
14425 -+/// terminal settings of the slave will be set to the values in `termios`.
14426 -+#[inline]
14427 -+pub fn openpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b Termios>>>(winsize: T, termios: U) -> Result<OpenptyResult> {
14428 -+ use std::ptr;
14429 -+
14430 -+ let mut slave: libc::c_int = unsafe { mem::uninitialized() };
14431 -+ let mut master: libc::c_int = unsafe { mem::uninitialized() };
14432 -+ let ret = {
14433 -+ match (termios.into(), winsize.into()) {
14434 -+ (Some(termios), Some(winsize)) => {
14435 -+ let inner_termios = termios.get_libc_termios();
14436 -+ unsafe {
14437 -+ libc::openpty(
14438 -+ &mut master,
14439 -+ &mut slave,
14440 -+ ptr::null_mut(),
14441 -+ &*inner_termios as *const libc::termios as *mut _,
14442 -+ winsize as *const Winsize as *mut _,
14443 -+ )
14444 -+ }
14445 -+ }
14446 -+ (None, Some(winsize)) => {
14447 -+ unsafe {
14448 -+ libc::openpty(
14449 -+ &mut master,
14450 -+ &mut slave,
14451 -+ ptr::null_mut(),
14452 -+ ptr::null_mut(),
14453 -+ winsize as *const Winsize as *mut _,
14454 -+ )
14455 -+ }
14456 -+ }
14457 -+ (Some(termios), None) => {
14458 -+ let inner_termios = termios.get_libc_termios();
14459 -+ unsafe {
14460 -+ libc::openpty(
14461 -+ &mut master,
14462 -+ &mut slave,
14463 -+ ptr::null_mut(),
14464 -+ &*inner_termios as *const libc::termios as *mut _,
14465 -+ ptr::null_mut(),
14466 -+ )
14467 -+ }
14468 -+ }
14469 -+ (None, None) => {
14470 -+ unsafe {
14471 -+ libc::openpty(
14472 -+ &mut master,
14473 -+ &mut slave,
14474 -+ ptr::null_mut(),
14475 -+ ptr::null_mut(),
14476 -+ ptr::null_mut(),
14477 -+ )
14478 -+ }
14479 -+ }
14480 -+ }
14481 -+ };
14482 -+
14483 -+ Errno::result(ret)?;
14484 -+
14485 -+ Ok(OpenptyResult {
14486 -+ master: master,
14487 -+ slave: slave,
14488 -+ })
14489 -+}
14490 -+
14491 -+/// Create a new pseudoterminal, returning the master file descriptor and forked pid.
14492 -+/// in `ForkptyResult`
14493 -+/// (see [`forkpty`](http://man7.org/linux/man-pages/man3/forkpty.3.html)).
14494 -+///
14495 -+/// If `winsize` is not `None`, the window size of the slave will be set to
14496 -+/// the values in `winsize`. If `termios` is not `None`, the pseudoterminal's
14497 -+/// terminal settings of the slave will be set to the values in `termios`.
14498 -+pub fn forkpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b Termios>>>(
14499 -+ winsize: T,
14500 -+ termios: U,
14501 -+) -> Result<ForkptyResult> {
14502 -+ use std::ptr;
14503 -+ use unistd::Pid;
14504 -+ use unistd::ForkResult::*;
14505 -+
14506 -+ let mut master: libc::c_int = unsafe { mem::uninitialized() };
14507 -+
14508 -+ let term = match termios.into() {
14509 -+ Some(termios) => {
14510 -+ let inner_termios = termios.get_libc_termios();
14511 -+ &*inner_termios as *const libc::termios as *mut _
14512 -+ },
14513 -+ None => ptr::null_mut(),
14514 -+ };
14515 -+
14516 -+ let win = winsize
14517 -+ .into()
14518 -+ .map(|ws| ws as *const Winsize as *mut _)
14519 -+ .unwrap_or(ptr::null_mut());
14520 -+
14521 -+ let res = unsafe {
14522 -+ libc::forkpty(&mut master, ptr::null_mut(), term, win)
14523 -+ };
14524 -+
14525 -+ let fork_result = Errno::result(res).map(|res| match res {
14526 -+ 0 => Child,
14527 -+ res => Parent { child: Pid::from_raw(res) },
14528 -+ })?;
14529 -+
14530 -+ Ok(ForkptyResult {
14531 -+ master: master,
14532 -+ fork_result: fork_result,
14533 -+ })
14534 -+}
14535 -+
14536 -diff --git a/third_party/rust/nix-0.15.0/src/sched.rs b/third_party/rust/nix-0.15.0/src/sched.rs
14537 -new file mode 100644
14538 -index 0000000000000..67188c57eef7d
14539 ---- /dev/null
14540 -+++ b/third_party/rust/nix-0.15.0/src/sched.rs
14541 -@@ -0,0 +1,147 @@
14542 -+use libc;
14543 -+use {Errno, Result};
14544 -+
14545 -+#[cfg(any(target_os = "android", target_os = "linux"))]
14546 -+pub use self::sched_linux_like::*;
14547 -+
14548 -+#[cfg(any(target_os = "android", target_os = "linux"))]
14549 -+mod sched_linux_like {
14550 -+ use errno::Errno;
14551 -+ use libc::{self, c_int, c_void};
14552 -+ use std::mem;
14553 -+ use std::option::Option;
14554 -+ use std::os::unix::io::RawFd;
14555 -+ use unistd::Pid;
14556 -+ use {Error, Result};
14557 -+
14558 -+ // For some functions taking with a parameter of type CloneFlags,
14559 -+ // only a subset of these flags have an effect.
14560 -+ libc_bitflags! {
14561 -+ pub struct CloneFlags: c_int {
14562 -+ CLONE_VM;
14563 -+ CLONE_FS;
14564 -+ CLONE_FILES;
14565 -+ CLONE_SIGHAND;
14566 -+ CLONE_PTRACE;
14567 -+ CLONE_VFORK;
14568 -+ CLONE_PARENT;
14569 -+ CLONE_THREAD;
14570 -+ CLONE_NEWNS;
14571 -+ CLONE_SYSVSEM;
14572 -+ CLONE_SETTLS;
14573 -+ CLONE_PARENT_SETTID;
14574 -+ CLONE_CHILD_CLEARTID;
14575 -+ CLONE_DETACHED;
14576 -+ CLONE_UNTRACED;
14577 -+ CLONE_CHILD_SETTID;
14578 -+ CLONE_NEWCGROUP;
14579 -+ CLONE_NEWUTS;
14580 -+ CLONE_NEWIPC;
14581 -+ CLONE_NEWUSER;
14582 -+ CLONE_NEWPID;
14583 -+ CLONE_NEWNET;
14584 -+ CLONE_IO;
14585 -+ }
14586 -+ }
14587 -+
14588 -+ pub type CloneCb<'a> = Box<dyn FnMut() -> isize + 'a>;
14589 -+
14590 -+ #[repr(C)]
14591 -+ #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
14592 -+ pub struct CpuSet {
14593 -+ cpu_set: libc::cpu_set_t,
14594 -+ }
14595 -+
14596 -+ impl CpuSet {
14597 -+ pub fn new() -> CpuSet {
14598 -+ CpuSet {
14599 -+ cpu_set: unsafe { mem::zeroed() },
14600 -+ }
14601 -+ }
14602 -+
14603 -+ pub fn is_set(&self, field: usize) -> Result<bool> {
14604 -+ if field >= 8 * mem::size_of::<libc::cpu_set_t>() {
14605 -+ Err(Error::Sys(Errno::EINVAL))
14606 -+ } else {
14607 -+ Ok(unsafe { libc::CPU_ISSET(field, &self.cpu_set) })
14608 -+ }
14609 -+ }
14610 -+
14611 -+ pub fn set(&mut self, field: usize) -> Result<()> {
14612 -+ if field >= 8 * mem::size_of::<libc::cpu_set_t>() {
14613 -+ Err(Error::Sys(Errno::EINVAL))
14614 -+ } else {
14615 -+ Ok(unsafe { libc::CPU_SET(field, &mut self.cpu_set) })
14616 -+ }
14617 -+ }
14618 -+
14619 -+ pub fn unset(&mut self, field: usize) -> Result<()> {
14620 -+ if field >= 8 * mem::size_of::<libc::cpu_set_t>() {
14621 -+ Err(Error::Sys(Errno::EINVAL))
14622 -+ } else {
14623 -+ Ok(unsafe { libc::CPU_CLR(field, &mut self.cpu_set) })
14624 -+ }
14625 -+ }
14626 -+ }
14627 -+
14628 -+ pub fn sched_setaffinity(pid: Pid, cpuset: &CpuSet) -> Result<()> {
14629 -+ let res = unsafe {
14630 -+ libc::sched_setaffinity(
14631 -+ pid.into(),
14632 -+ mem::size_of::<CpuSet>() as libc::size_t,
14633 -+ &cpuset.cpu_set,
14634 -+ )
14635 -+ };
14636 -+
14637 -+ Errno::result(res).map(drop)
14638 -+ }
14639 -+
14640 -+ pub fn clone(
14641 -+ mut cb: CloneCb,
14642 -+ stack: &mut [u8],
14643 -+ flags: CloneFlags,
14644 -+ signal: Option<c_int>,
14645 -+ ) -> Result<Pid> {
14646 -+ extern "C" fn callback(data: *mut CloneCb) -> c_int {
14647 -+ let cb: &mut CloneCb = unsafe { &mut *data };
14648 -+ (*cb)() as c_int
14649 -+ }
14650 -+
14651 -+ let res = unsafe {
14652 -+ let combined = flags.bits() | signal.unwrap_or(0);
14653 -+ let ptr = stack.as_mut_ptr().offset(stack.len() as isize);
14654 -+ let ptr_aligned = ptr.offset((ptr as usize % 16) as isize * -1);
14655 -+ libc::clone(
14656 -+ mem::transmute(
14657 -+ callback as extern "C" fn(*mut Box<dyn FnMut() -> isize>) -> i32,
14658 -+ ),
14659 -+ ptr_aligned as *mut c_void,
14660 -+ combined,
14661 -+ &mut cb as *mut _ as *mut c_void,
14662 -+ )
14663 -+ };
14664 -+
14665 -+ Errno::result(res).map(Pid::from_raw)
14666 -+ }
14667 -+
14668 -+ pub fn unshare(flags: CloneFlags) -> Result<()> {
14669 -+ let res = unsafe { libc::unshare(flags.bits()) };
14670 -+
14671 -+ Errno::result(res).map(drop)
14672 -+ }
14673 -+
14674 -+ pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> {
14675 -+ let res = unsafe { libc::setns(fd, nstype.bits()) };
14676 -+
14677 -+ Errno::result(res).map(drop)
14678 -+ }
14679 -+}
14680 -+
14681 -+/// Explicitly yield the processor to other threads.
14682 -+///
14683 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_yield.html)
14684 -+pub fn sched_yield() -> Result<()> {
14685 -+ let res = unsafe { libc::sched_yield() };
14686 -+
14687 -+ Errno::result(res).map(drop)
14688 -+}
14689 -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
14690 -new file mode 100644
14691 -index 0000000000000..9258a0657cc8a
14692 ---- /dev/null
14693 -+++ b/third_party/rust/nix-0.15.0/src/sys/aio.rs
14694 -@@ -0,0 +1,1280 @@
14695 -+// vim: tw=80
14696 -+//! POSIX Asynchronous I/O
14697 -+//!
14698 -+//! The POSIX AIO interface is used for asynchronous I/O on files and disk-like
14699 -+//! devices. It supports [`read`](struct.AioCb.html#method.read),
14700 -+//! [`write`](struct.AioCb.html#method.write), and
14701 -+//! [`fsync`](struct.AioCb.html#method.fsync) operations. Completion
14702 -+//! notifications can optionally be delivered via
14703 -+//! [signals](../signal/enum.SigevNotify.html#variant.SigevSignal), via the
14704 -+//! [`aio_suspend`](fn.aio_suspend.html) function, or via polling. Some
14705 -+//! platforms support other completion
14706 -+//! notifications, such as
14707 -+//! [kevent](../signal/enum.SigevNotify.html#variant.SigevKevent).
14708 -+//!
14709 -+//! Multiple operations may be submitted in a batch with
14710 -+//! [`lio_listio`](fn.lio_listio.html), though the standard does not guarantee
14711 -+//! that they will be executed atomically.
14712 -+//!
14713 -+//! Outstanding operations may be cancelled with
14714 -+//! [`cancel`](struct.AioCb.html#method.cancel) or
14715 -+//! [`aio_cancel_all`](fn.aio_cancel_all.html), though the operating system may
14716 -+//! not support this for all filesystems and devices.
14717 -+
14718 -+use {Error, Result};
14719 -+use errno::Errno;
14720 -+use std::os::unix::io::RawFd;
14721 -+use libc::{c_void, off_t, size_t};
14722 -+use libc;
14723 -+use std::borrow::{Borrow, BorrowMut};
14724 -+use std::fmt;
14725 -+use std::fmt::Debug;
14726 -+use std::marker::PhantomData;
14727 -+use std::mem;
14728 -+use std::ptr::{null, null_mut};
14729 -+use sys::signal::*;
14730 -+use std::thread;
14731 -+use sys::time::TimeSpec;
14732 -+
14733 -+libc_enum! {
14734 -+ /// Mode for `AioCb::fsync`. Controls whether only data or both data and
14735 -+ /// metadata are synced.
14736 -+ #[repr(i32)]
14737 -+ pub enum AioFsyncMode {
14738 -+ /// do it like `fsync`
14739 -+ O_SYNC,
14740 -+ /// on supported operating systems only, do it like `fdatasync`
14741 -+ #[cfg(any(target_os = "ios",
14742 -+ target_os = "linux",
14743 -+ target_os = "macos",
14744 -+ target_os = "netbsd",
14745 -+ target_os = "openbsd"))]
14746 -+ O_DSYNC
14747 -+ }
14748 -+}
14749 -+
14750 -+libc_enum! {
14751 -+ /// When used with [`lio_listio`](fn.lio_listio.html), determines whether a
14752 -+ /// given `aiocb` should be used for a read operation, a write operation, or
14753 -+ /// ignored. Has no effect for any other aio functions.
14754 -+ #[repr(i32)]
14755 -+ pub enum LioOpcode {
14756 -+ LIO_NOP,
14757 -+ LIO_WRITE,
14758 -+ LIO_READ,
14759 -+ }
14760 -+}
14761 -+
14762 -+libc_enum! {
14763 -+ /// Mode for [`lio_listio`](fn.lio_listio.html)
14764 -+ #[repr(i32)]
14765 -+ pub enum LioMode {
14766 -+ /// Requests that [`lio_listio`](fn.lio_listio.html) block until all
14767 -+ /// requested operations have been completed
14768 -+ LIO_WAIT,
14769 -+ /// Requests that [`lio_listio`](fn.lio_listio.html) return immediately
14770 -+ LIO_NOWAIT,
14771 -+ }
14772 -+}
14773 -+
14774 -+/// Return values for [`AioCb::cancel`](struct.AioCb.html#method.cancel) and
14775 -+/// [`aio_cancel_all`](fn.aio_cancel_all.html)
14776 -+#[repr(i32)]
14777 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
14778 -+pub enum AioCancelStat {
14779 -+ /// All outstanding requests were canceled
14780 -+ AioCanceled = libc::AIO_CANCELED,
14781 -+ /// Some requests were not canceled. Their status should be checked with
14782 -+ /// `AioCb::error`
14783 -+ AioNotCanceled = libc::AIO_NOTCANCELED,
14784 -+ /// All of the requests have already finished
14785 -+ AioAllDone = libc::AIO_ALLDONE,
14786 -+}
14787 -+
14788 -+/// Owns (uniquely or shared) a memory buffer to keep it from `Drop`ing while
14789 -+/// the kernel has a pointer to it.
14790 -+pub enum Buffer<'a> {
14791 -+ /// No buffer to own.
14792 -+ ///
14793 -+ /// Used for operations like `aio_fsync` that have no data, or for unsafe
14794 -+ /// operations that work with raw pointers.
14795 -+ None,
14796 -+ /// Keeps a reference to a slice
14797 -+ Phantom(PhantomData<&'a mut [u8]>),
14798 -+ /// Generic thing that keeps a buffer from dropping
14799 -+ BoxedSlice(Box<dyn Borrow<[u8]>>),
14800 -+ /// Generic thing that keeps a mutable buffer from dropping
14801 -+ BoxedMutSlice(Box<dyn BorrowMut<[u8]>>),
14802 -+}
14803 -+
14804 -+impl<'a> Debug for Buffer<'a> {
14805 -+ // Note: someday it may be possible to Derive Debug for a trait object, but
14806 -+ // not today.
14807 -+ // https://github.com/rust-lang/rust/issues/1563
14808 -+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
14809 -+ match *self {
14810 -+ Buffer::None => write!(fmt, "None"),
14811 -+ Buffer::Phantom(p) => p.fmt(fmt),
14812 -+ Buffer::BoxedSlice(ref bs) => {
14813 -+ let borrowed : &dyn Borrow<[u8]> = bs.borrow();
14814 -+ write!(fmt, "BoxedSlice({:?})",
14815 -+ borrowed as *const dyn Borrow<[u8]>)
14816 -+ },
14817 -+ Buffer::BoxedMutSlice(ref bms) => {
14818 -+ let borrowed : &dyn BorrowMut<[u8]> = bms.borrow();
14819 -+ write!(fmt, "BoxedMutSlice({:?})",
14820 -+ borrowed as *const dyn BorrowMut<[u8]>)
14821 -+ }
14822 -+ }
14823 -+ }
14824 -+}
14825 -+
14826 -+/// AIO Control Block.
14827 -+///
14828 -+/// The basic structure used by all aio functions. Each `AioCb` represents one
14829 -+/// I/O request.
14830 -+pub struct AioCb<'a> {
14831 -+ aiocb: libc::aiocb,
14832 -+ /// Tracks whether the buffer pointed to by `libc::aiocb.aio_buf` is mutable
14833 -+ mutable: bool,
14834 -+ /// Could this `AioCb` potentially have any in-kernel state?
14835 -+ in_progress: bool,
14836 -+ /// Optionally keeps a reference to the data.
14837 -+ ///
14838 -+ /// Used to keep buffers from `Drop`'ing, and may be returned once the
14839 -+ /// `AioCb` is completed by [`buffer`](#method.buffer).
14840 -+ buffer: Buffer<'a>
14841 -+}
14842 -+
14843 -+impl<'a> AioCb<'a> {
14844 -+ /// Remove the inner `Buffer` and return it
14845 -+ ///
14846 -+ /// It is an error to call this method while the `AioCb` is still in
14847 -+ /// progress.
14848 -+ pub fn buffer(&mut self) -> Buffer<'a> {
14849 -+ assert!(!self.in_progress);
14850 -+ let mut x = Buffer::None;
14851 -+ mem::swap(&mut self.buffer, &mut x);
14852 -+ x
14853 -+ }
14854 -+
14855 -+ /// Remove the inner boxed slice, if any, and return it.
14856 -+ ///
14857 -+ /// The returned value will be the argument that was passed to
14858 -+ /// `from_boxed_slice` when this `AioCb` was created.
14859 -+ ///
14860 -+ /// It is an error to call this method while the `AioCb` is still in
14861 -+ /// progress.
14862 -+ pub fn boxed_slice(&mut self) -> Option<Box<dyn Borrow<[u8]>>> {
14863 -+ assert!(!self.in_progress, "Can't remove the buffer from an AioCb that's still in-progress. Did you forget to call aio_return?");
14864 -+ if let Buffer::BoxedSlice(_) = self.buffer {
14865 -+ let mut oldbuffer = Buffer::None;
14866 -+ mem::swap(&mut self.buffer, &mut oldbuffer);
14867 -+ if let Buffer::BoxedSlice(inner) = oldbuffer {
14868 -+ Some(inner)
14869 -+ } else {
14870 -+ unreachable!();
14871 -+ }
14872 -+ } else {
14873 -+ None
14874 -+ }
14875 -+ }
14876 -+
14877 -+ /// Remove the inner boxed mutable slice, if any, and return it.
14878 -+ ///
14879 -+ /// The returned value will be the argument that was passed to
14880 -+ /// `from_boxed_mut_slice` when this `AioCb` was created.
14881 -+ ///
14882 -+ /// It is an error to call this method while the `AioCb` is still in
14883 -+ /// progress.
14884 -+ pub fn boxed_mut_slice(&mut self) -> Option<Box<dyn BorrowMut<[u8]>>> {
14885 -+ assert!(!self.in_progress, "Can't remove the buffer from an AioCb that's still in-progress. Did you forget to call aio_return?");
14886 -+ if let Buffer::BoxedMutSlice(_) = self.buffer {
14887 -+ let mut oldbuffer = Buffer::None;
14888 -+ mem::swap(&mut self.buffer, &mut oldbuffer);
14889 -+ if let Buffer::BoxedMutSlice(inner) = oldbuffer {
14890 -+ Some(inner)
14891 -+ } else {
14892 -+ unreachable!();
14893 -+ }
14894 -+ } else {
14895 -+ None
14896 -+ }
14897 -+ }
14898 -+
14899 -+ /// Returns the underlying file descriptor associated with the `AioCb`
14900 -+ pub fn fd(&self) -> RawFd {
14901 -+ self.aiocb.aio_fildes
14902 -+ }
14903 -+
14904 -+ /// Constructs a new `AioCb` with no associated buffer.
14905 -+ ///
14906 -+ /// The resulting `AioCb` structure is suitable for use with `AioCb::fsync`.
14907 -+ ///
14908 -+ /// # Parameters
14909 -+ ///
14910 -+ /// * `fd`: File descriptor. Required for all aio functions.
14911 -+ /// * `prio`: If POSIX Prioritized IO is supported, then the
14912 -+ /// operation will be prioritized at the process's
14913 -+ /// priority level minus `prio`.
14914 -+ /// * `sigev_notify`: Determines how you will be notified of event
14915 -+ /// completion.
14916 -+ ///
14917 -+ /// # Examples
14918 -+ ///
14919 -+ /// Create an `AioCb` from a raw file descriptor and use it for an
14920 -+ /// [`fsync`](#method.fsync) operation.
14921 -+ ///
14922 -+ /// ```
14923 -+ /// # extern crate tempfile;
14924 -+ /// # extern crate nix;
14925 -+ /// # use nix::errno::Errno;
14926 -+ /// # use nix::Error;
14927 -+ /// # use nix::sys::aio::*;
14928 -+ /// # use nix::sys::signal::SigevNotify::SigevNone;
14929 -+ /// # use std::{thread, time};
14930 -+ /// # use std::os::unix::io::AsRawFd;
14931 -+ /// # use tempfile::tempfile;
14932 -+ /// # fn main() {
14933 -+ /// let f = tempfile().unwrap();
14934 -+ /// let mut aiocb = AioCb::from_fd( f.as_raw_fd(), 0, SigevNone);
14935 -+ /// aiocb.fsync(AioFsyncMode::O_SYNC).expect("aio_fsync failed early");
14936 -+ /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) {
14937 -+ /// thread::sleep(time::Duration::from_millis(10));
14938 -+ /// }
14939 -+ /// aiocb.aio_return().expect("aio_fsync failed late");
14940 -+ /// # }
14941 -+ /// ```
14942 -+ pub fn from_fd(fd: RawFd, prio: libc::c_int,
14943 -+ sigev_notify: SigevNotify) -> AioCb<'a> {
14944 -+ let mut a = AioCb::common_init(fd, prio, sigev_notify);
14945 -+ a.aio_offset = 0;
14946 -+ a.aio_nbytes = 0;
14947 -+ a.aio_buf = null_mut();
14948 -+
14949 -+ AioCb {
14950 -+ aiocb: a,
14951 -+ mutable: false,
14952 -+ in_progress: false,
14953 -+ buffer: Buffer::None
14954 -+ }
14955 -+ }
14956 -+
14957 -+ /// Constructs a new `AioCb` from a mutable slice.
14958 -+ ///
14959 -+ /// The resulting `AioCb` will be suitable for both read and write
14960 -+ /// operations, but only if the borrow checker can guarantee that the slice
14961 -+ /// will outlive the `AioCb`. That will usually be the case if the `AioCb`
14962 -+ /// is stack-allocated. If the borrow checker gives you trouble, try using
14963 -+ /// [`from_boxed_mut_slice`](#method.from_boxed_mut_slice) instead.
14964 -+ ///
14965 -+ /// # Parameters
14966 -+ ///
14967 -+ /// * `fd`: File descriptor. Required for all aio functions.
14968 -+ /// * `offs`: File offset
14969 -+ /// * `buf`: A memory buffer
14970 -+ /// * `prio`: If POSIX Prioritized IO is supported, then the
14971 -+ /// operation will be prioritized at the process's
14972 -+ /// priority level minus `prio`
14973 -+ /// * `sigev_notify`: Determines how you will be notified of event
14974 -+ /// completion.
14975 -+ /// * `opcode`: This field is only used for `lio_listio`. It
14976 -+ /// determines which operation to use for this individual
14977 -+ /// aiocb
14978 -+ ///
14979 -+ /// # Examples
14980 -+ ///
14981 -+ /// Create an `AioCb` from a mutable slice and read into it.
14982 -+ ///
14983 -+ /// ```
14984 -+ /// # extern crate tempfile;
14985 -+ /// # extern crate nix;
14986 -+ /// # use nix::errno::Errno;
14987 -+ /// # use nix::Error;
14988 -+ /// # use nix::sys::aio::*;
14989 -+ /// # use nix::sys::signal::SigevNotify;
14990 -+ /// # use std::{thread, time};
14991 -+ /// # use std::io::Write;
14992 -+ /// # use std::os::unix::io::AsRawFd;
14993 -+ /// # use tempfile::tempfile;
14994 -+ /// # fn main() {
14995 -+ /// const INITIAL: &[u8] = b"abcdef123456";
14996 -+ /// const LEN: usize = 4;
14997 -+ /// let mut rbuf = vec![0; LEN];
14998 -+ /// let mut f = tempfile().unwrap();
14999 -+ /// f.write_all(INITIAL).unwrap();
15000 -+ /// {
15001 -+ /// let mut aiocb = AioCb::from_mut_slice( f.as_raw_fd(),
15002 -+ /// 2, //offset
15003 -+ /// &mut rbuf,
15004 -+ /// 0, //priority
15005 -+ /// SigevNotify::SigevNone,
15006 -+ /// LioOpcode::LIO_NOP);
15007 -+ /// aiocb.read().unwrap();
15008 -+ /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) {
15009 -+ /// thread::sleep(time::Duration::from_millis(10));
15010 -+ /// }
15011 -+ /// assert_eq!(aiocb.aio_return().unwrap() as usize, LEN);
15012 -+ /// }
15013 -+ /// assert_eq!(rbuf, b"cdef");
15014 -+ /// # }
15015 -+ /// ```
15016 -+ pub fn from_mut_slice(fd: RawFd, offs: off_t, buf: &'a mut [u8],
15017 -+ prio: libc::c_int, sigev_notify: SigevNotify,
15018 -+ opcode: LioOpcode) -> AioCb<'a> {
15019 -+ let mut a = AioCb::common_init(fd, prio, sigev_notify);
15020 -+ a.aio_offset = offs;
15021 -+ a.aio_nbytes = buf.len() as size_t;
15022 -+ a.aio_buf = buf.as_ptr() as *mut c_void;
15023 -+ a.aio_lio_opcode = opcode as libc::c_int;
15024 -+
15025 -+ AioCb {
15026 -+ aiocb: a,
15027 -+ mutable: true,
15028 -+ in_progress: false,
15029 -+ buffer: Buffer::Phantom(PhantomData),
15030 -+ }
15031 -+ }
15032 -+
15033 -+ /// The safest and most flexible way to create an `AioCb`.
15034 -+ ///
15035 -+ /// Unlike [`from_slice`], this method returns a structure suitable for
15036 -+ /// placement on the heap. It may be used for write operations, but not
15037 -+ /// read operations. Unlike `from_ptr`, this method will ensure that the
15038 -+ /// buffer doesn't `drop` while the kernel is still processing it. Any
15039 -+ /// object that can be borrowed as a boxed slice will work.
15040 -+ ///
15041 -+ /// # Parameters
15042 -+ ///
15043 -+ /// * `fd`: File descriptor. Required for all aio functions.
15044 -+ /// * `offs`: File offset
15045 -+ /// * `buf`: A boxed slice-like object
15046 -+ /// * `prio`: If POSIX Prioritized IO is supported, then the
15047 -+ /// operation will be prioritized at the process's
15048 -+ /// priority level minus `prio`
15049 -+ /// * `sigev_notify`: Determines how you will be notified of event
15050 -+ /// completion.
15051 -+ /// * `opcode`: This field is only used for `lio_listio`. It
15052 -+ /// determines which operation to use for this individual
15053 -+ /// aiocb
15054 -+ ///
15055 -+ /// # Examples
15056 -+ ///
15057 -+ /// Create an `AioCb` from a Vector and use it for writing
15058 -+ ///
15059 -+ /// ```
15060 -+ /// # extern crate tempfile;
15061 -+ /// # extern crate nix;
15062 -+ /// # use nix::errno::Errno;
15063 -+ /// # use nix::Error;
15064 -+ /// # use nix::sys::aio::*;
15065 -+ /// # use nix::sys::signal::SigevNotify;
15066 -+ /// # use std::{thread, time};
15067 -+ /// # use std::io::Write;
15068 -+ /// # use std::os::unix::io::AsRawFd;
15069 -+ /// # use tempfile::tempfile;
15070 -+ /// # fn main() {
15071 -+ /// let wbuf = Box::new(Vec::from("CDEF"));
15072 -+ /// let expected_len = wbuf.len();
15073 -+ /// let mut f = tempfile().unwrap();
15074 -+ /// let mut aiocb = AioCb::from_boxed_slice( f.as_raw_fd(),
15075 -+ /// 2, //offset
15076 -+ /// wbuf,
15077 -+ /// 0, //priority
15078 -+ /// SigevNotify::SigevNone,
15079 -+ /// LioOpcode::LIO_NOP);
15080 -+ /// aiocb.write().unwrap();
15081 -+ /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) {
15082 -+ /// thread::sleep(time::Duration::from_millis(10));
15083 -+ /// }
15084 -+ /// assert_eq!(aiocb.aio_return().unwrap() as usize, expected_len);
15085 -+ /// # }
15086 -+ /// ```
15087 -+ ///
15088 -+ /// Create an `AioCb` from a `Bytes` object
15089 -+ ///
15090 -+ /// ```
15091 -+ /// # extern crate bytes;
15092 -+ /// # extern crate tempfile;
15093 -+ /// # extern crate nix;
15094 -+ /// # use bytes::Bytes;
15095 -+ /// # use nix::sys::aio::*;
15096 -+ /// # use nix::sys::signal::SigevNotify;
15097 -+ /// # use std::os::unix::io::AsRawFd;
15098 -+ /// # use tempfile::tempfile;
15099 -+ /// # fn main() {
15100 -+ /// let wbuf = Box::new(Bytes::from(&b"CDEF"[..]));
15101 -+ /// let mut f = tempfile().unwrap();
15102 -+ /// let mut aiocb = AioCb::from_boxed_slice( f.as_raw_fd(),
15103 -+ /// 2, //offset
15104 -+ /// wbuf,
15105 -+ /// 0, //priority
15106 -+ /// SigevNotify::SigevNone,
15107 -+ /// LioOpcode::LIO_NOP);
15108 -+ /// # }
15109 -+ /// ```
15110 -+ ///
15111 -+ /// If a library needs to work with buffers that aren't `Box`ed, it can
15112 -+ /// create a `Box`ed container for use with this method. Here's an example
15113 -+ /// using an un`Box`ed `Bytes` object.
15114 -+ ///
15115 -+ /// ```
15116 -+ /// # extern crate bytes;
15117 -+ /// # extern crate tempfile;
15118 -+ /// # extern crate nix;
15119 -+ /// # use bytes::Bytes;
15120 -+ /// # use nix::sys::aio::*;
15121 -+ /// # use nix::sys::signal::SigevNotify;
15122 -+ /// # use std::borrow::Borrow;
15123 -+ /// # use std::os::unix::io::AsRawFd;
15124 -+ /// # use tempfile::tempfile;
15125 -+ /// struct BytesContainer(Bytes);
15126 -+ /// impl Borrow<[u8]> for BytesContainer {
15127 -+ /// fn borrow(&self) -> &[u8] {
15128 -+ /// self.0.as_ref()
15129 -+ /// }
15130 -+ /// }
15131 -+ /// fn main() {
15132 -+ /// let wbuf = Bytes::from(&b"CDEF"[..]);
15133 -+ /// let boxed_wbuf = Box::new(BytesContainer(wbuf));
15134 -+ /// let mut f = tempfile().unwrap();
15135 -+ /// let mut aiocb = AioCb::from_boxed_slice( f.as_raw_fd(),
15136 -+ /// 2, //offset
15137 -+ /// boxed_wbuf,
15138 -+ /// 0, //priority
15139 -+ /// SigevNotify::SigevNone,
15140 -+ /// LioOpcode::LIO_NOP);
15141 -+ /// }
15142 -+ /// ```
15143 -+ ///
15144 -+ /// [`from_slice`]: #method.from_slice
15145 -+ pub fn from_boxed_slice(fd: RawFd, offs: off_t, buf: Box<dyn Borrow<[u8]>>,
15146 -+ prio: libc::c_int, sigev_notify: SigevNotify,
15147 -+ opcode: LioOpcode) -> AioCb<'a> {
15148 -+ let mut a = AioCb::common_init(fd, prio, sigev_notify);
15149 -+ {
15150 -+ let borrowed : &dyn Borrow<[u8]> = buf.borrow();
15151 -+ let slice : &[u8] = borrowed.borrow();
15152 -+ a.aio_nbytes = slice.len() as size_t;
15153 -+ a.aio_buf = slice.as_ptr() as *mut c_void;
15154 -+ }
15155 -+ a.aio_offset = offs;
15156 -+ a.aio_lio_opcode = opcode as libc::c_int;
15157 -+
15158 -+ AioCb {
15159 -+ aiocb: a,
15160 -+ mutable: false,
15161 -+ in_progress: false,
15162 -+ buffer: Buffer::BoxedSlice(buf),
15163 -+ }
15164 -+ }
15165 -+
15166 -+ /// The safest and most flexible way to create an `AioCb` for reading.
15167 -+ ///
15168 -+ /// Like [`from_boxed_slice`], but the slice is a mutable one. More
15169 -+ /// flexible than [`from_mut_slice`], because a wide range of objects can be
15170 -+ /// used.
15171 -+ ///
15172 -+ /// # Examples
15173 -+ ///
15174 -+ /// Create an `AioCb` from a Vector and use it for reading
15175 -+ ///
15176 -+ /// ```
15177 -+ /// # extern crate tempfile;
15178 -+ /// # extern crate nix;
15179 -+ /// # use nix::errno::Errno;
15180 -+ /// # use nix::Error;
15181 -+ /// # use nix::sys::aio::*;
15182 -+ /// # use nix::sys::signal::SigevNotify;
15183 -+ /// # use std::{thread, time};
15184 -+ /// # use std::io::Write;
15185 -+ /// # use std::os::unix::io::AsRawFd;
15186 -+ /// # use tempfile::tempfile;
15187 -+ /// # fn main() {
15188 -+ /// const INITIAL: &[u8] = b"abcdef123456";
15189 -+ /// const LEN: usize = 4;
15190 -+ /// let rbuf = Box::new(vec![0; LEN]);
15191 -+ /// let mut f = tempfile().unwrap();
15192 -+ /// f.write_all(INITIAL).unwrap();
15193 -+ /// let mut aiocb = AioCb::from_boxed_mut_slice( f.as_raw_fd(),
15194 -+ /// 2, //offset
15195 -+ /// rbuf,
15196 -+ /// 0, //priority
15197 -+ /// SigevNotify::SigevNone,
15198 -+ /// LioOpcode::LIO_NOP);
15199 -+ /// aiocb.read().unwrap();
15200 -+ /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) {
15201 -+ /// thread::sleep(time::Duration::from_millis(10));
15202 -+ /// }
15203 -+ /// assert_eq!(aiocb.aio_return().unwrap() as usize, LEN);
15204 -+ /// let mut buffer = aiocb.boxed_mut_slice().unwrap();
15205 -+ /// const EXPECT: &[u8] = b"cdef";
15206 -+ /// assert_eq!(buffer.borrow_mut(), EXPECT);
15207 -+ /// # }
15208 -+ /// ```
15209 -+ ///
15210 -+ /// [`from_boxed_slice`]: #method.from_boxed_slice
15211 -+ /// [`from_mut_slice`]: #method.from_mut_slice
15212 -+ pub fn from_boxed_mut_slice(fd: RawFd, offs: off_t,
15213 -+ mut buf: Box<dyn BorrowMut<[u8]>>,
15214 -+ prio: libc::c_int, sigev_notify: SigevNotify,
15215 -+ opcode: LioOpcode) -> AioCb<'a> {
15216 -+ let mut a = AioCb::common_init(fd, prio, sigev_notify);
15217 -+ {
15218 -+ let borrowed : &mut dyn BorrowMut<[u8]> = buf.borrow_mut();
15219 -+ let slice : &mut [u8] = borrowed.borrow_mut();
15220 -+ a.aio_nbytes = slice.len() as size_t;
15221 -+ a.aio_buf = slice.as_mut_ptr() as *mut c_void;
15222 -+ }
15223 -+ a.aio_offset = offs;
15224 -+ a.aio_lio_opcode = opcode as libc::c_int;
15225 -+
15226 -+ AioCb {
15227 -+ aiocb: a,
15228 -+ mutable: true,
15229 -+ in_progress: false,
15230 -+ buffer: Buffer::BoxedMutSlice(buf),
15231 -+ }
15232 -+ }
15233 -+
15234 -+ /// Constructs a new `AioCb` from a mutable raw pointer
15235 -+ ///
15236 -+ /// Unlike `from_mut_slice`, this method returns a structure suitable for
15237 -+ /// placement on the heap. It may be used for both reads and writes. Due
15238 -+ /// to its unsafety, this method is not recommended. It is most useful when
15239 -+ /// heap allocation is required but for some reason the data cannot be
15240 -+ /// wrapped in a `struct` that implements `BorrowMut<[u8]>`
15241 -+ ///
15242 -+ /// # Parameters
15243 -+ ///
15244 -+ /// * `fd`: File descriptor. Required for all aio functions.
15245 -+ /// * `offs`: File offset
15246 -+ /// * `buf`: Pointer to the memory buffer
15247 -+ /// * `len`: Length of the buffer pointed to by `buf`
15248 -+ /// * `prio`: If POSIX Prioritized IO is supported, then the
15249 -+ /// operation will be prioritized at the process's
15250 -+ /// priority level minus `prio`
15251 -+ /// * `sigev_notify`: Determines how you will be notified of event
15252 -+ /// completion.
15253 -+ /// * `opcode`: This field is only used for `lio_listio`. It
15254 -+ /// determines which operation to use for this individual
15255 -+ /// aiocb
15256 -+ ///
15257 -+ /// # Safety
15258 -+ ///
15259 -+ /// The caller must ensure that the storage pointed to by `buf` outlives the
15260 -+ /// `AioCb`. The lifetime checker can't help here.
15261 -+ pub unsafe fn from_mut_ptr(fd: RawFd, offs: off_t,
15262 -+ buf: *mut c_void, len: usize,
15263 -+ prio: libc::c_int, sigev_notify: SigevNotify,
15264 -+ opcode: LioOpcode) -> AioCb<'a> {
15265 -+ let mut a = AioCb::common_init(fd, prio, sigev_notify);
15266 -+ a.aio_offset = offs;
15267 -+ a.aio_nbytes = len;
15268 -+ a.aio_buf = buf;
15269 -+ a.aio_lio_opcode = opcode as libc::c_int;
15270 -+
15271 -+ AioCb {
15272 -+ aiocb: a,
15273 -+ mutable: true,
15274 -+ in_progress: false,
15275 -+ buffer: Buffer::None
15276 -+ }
15277 -+ }
15278 -+
15279 -+ /// Constructs a new `AioCb` from a raw pointer.
15280 -+ ///
15281 -+ /// Unlike `from_slice`, this method returns a structure suitable for
15282 -+ /// placement on the heap. Due to its unsafety, this method is not
15283 -+ /// recommended. It is most useful when heap allocation is required but for
15284 -+ /// some reason the data cannot be wrapped in a `struct` that implements
15285 -+ /// `Borrow<[u8]>`
15286 -+ ///
15287 -+ /// # Parameters
15288 -+ ///
15289 -+ /// * `fd`: File descriptor. Required for all aio functions.
15290 -+ /// * `offs`: File offset
15291 -+ /// * `buf`: Pointer to the memory buffer
15292 -+ /// * `len`: Length of the buffer pointed to by `buf`
15293 -+ /// * `prio`: If POSIX Prioritized IO is supported, then the
15294 -+ /// operation will be prioritized at the process's
15295 -+ /// priority level minus `prio`
15296 -+ /// * `sigev_notify`: Determines how you will be notified of event
15297 -+ /// completion.
15298 -+ /// * `opcode`: This field is only used for `lio_listio`. It
15299 -+ /// determines which operation to use for this individual
15300 -+ /// aiocb
15301 -+ ///
15302 -+ /// # Safety
15303 -+ ///
15304 -+ /// The caller must ensure that the storage pointed to by `buf` outlives the
15305 -+ /// `AioCb`. The lifetime checker can't help here.
15306 -+ pub unsafe fn from_ptr(fd: RawFd, offs: off_t,
15307 -+ buf: *const c_void, len: usize,
15308 -+ prio: libc::c_int, sigev_notify: SigevNotify,
15309 -+ opcode: LioOpcode) -> AioCb<'a> {
15310 -+ let mut a = AioCb::common_init(fd, prio, sigev_notify);
15311 -+ a.aio_offset = offs;
15312 -+ a.aio_nbytes = len;
15313 -+ // casting a const ptr to a mutable ptr here is ok, because we set the
15314 -+ // AioCb's mutable field to false
15315 -+ a.aio_buf = buf as *mut c_void;
15316 -+ a.aio_lio_opcode = opcode as libc::c_int;
15317 -+
15318 -+ AioCb {
15319 -+ aiocb: a,
15320 -+ mutable: false,
15321 -+ in_progress: false,
15322 -+ buffer: Buffer::None
15323 -+ }
15324 -+ }
15325 -+
15326 -+ /// Like `from_mut_slice`, but works on constant slices rather than
15327 -+ /// mutable slices.
15328 -+ ///
15329 -+ /// An `AioCb` created this way cannot be used with `read`, and its
15330 -+ /// `LioOpcode` cannot be set to `LIO_READ`. This method is useful when
15331 -+ /// writing a const buffer with `AioCb::write`, since `from_mut_slice` can't
15332 -+ /// work with const buffers.
15333 -+ ///
15334 -+ /// # Examples
15335 -+ ///
15336 -+ /// Construct an `AioCb` from a slice and use it for writing.
15337 -+ ///
15338 -+ /// ```
15339 -+ /// # extern crate tempfile;
15340 -+ /// # extern crate nix;
15341 -+ /// # use nix::errno::Errno;
15342 -+ /// # use nix::Error;
15343 -+ /// # use nix::sys::aio::*;
15344 -+ /// # use nix::sys::signal::SigevNotify;
15345 -+ /// # use std::{thread, time};
15346 -+ /// # use std::os::unix::io::AsRawFd;
15347 -+ /// # use tempfile::tempfile;
15348 -+ /// # fn main() {
15349 -+ /// const WBUF: &[u8] = b"abcdef123456";
15350 -+ /// let mut f = tempfile().unwrap();
15351 -+ /// let mut aiocb = AioCb::from_slice( f.as_raw_fd(),
15352 -+ /// 2, //offset
15353 -+ /// WBUF,
15354 -+ /// 0, //priority
15355 -+ /// SigevNotify::SigevNone,
15356 -+ /// LioOpcode::LIO_NOP);
15357 -+ /// aiocb.write().unwrap();
15358 -+ /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) {
15359 -+ /// thread::sleep(time::Duration::from_millis(10));
15360 -+ /// }
15361 -+ /// assert_eq!(aiocb.aio_return().unwrap() as usize, WBUF.len());
15362 -+ /// # }
15363 -+ /// ```
15364 -+ // Note: another solution to the problem of writing const buffers would be
15365 -+ // to genericize AioCb for both &mut [u8] and &[u8] buffers. AioCb::read
15366 -+ // could take the former and AioCb::write could take the latter. However,
15367 -+ // then lio_listio wouldn't work, because that function needs a slice of
15368 -+ // AioCb, and they must all be of the same type.
15369 -+ pub fn from_slice(fd: RawFd, offs: off_t, buf: &'a [u8],
15370 -+ prio: libc::c_int, sigev_notify: SigevNotify,
15371 -+ opcode: LioOpcode) -> AioCb {
15372 -+ let mut a = AioCb::common_init(fd, prio, sigev_notify);
15373 -+ a.aio_offset = offs;
15374 -+ a.aio_nbytes = buf.len() as size_t;
15375 -+ // casting an immutable buffer to a mutable pointer looks unsafe,
15376 -+ // but technically its only unsafe to dereference it, not to create
15377 -+ // it.
15378 -+ a.aio_buf = buf.as_ptr() as *mut c_void;
15379 -+ assert!(opcode != LioOpcode::LIO_READ, "Can't read into an immutable buffer");
15380 -+ a.aio_lio_opcode = opcode as libc::c_int;
15381 -+
15382 -+ AioCb {
15383 -+ aiocb: a,
15384 -+ mutable: false,
15385 -+ in_progress: false,
15386 -+ buffer: Buffer::None,
15387 -+ }
15388 -+ }
15389 -+
15390 -+ fn common_init(fd: RawFd, prio: libc::c_int,
15391 -+ sigev_notify: SigevNotify) -> libc::aiocb {
15392 -+ // Use mem::zeroed instead of explicitly zeroing each field, because the
15393 -+ // number and name of reserved fields is OS-dependent. On some OSes,
15394 -+ // some reserved fields are used the kernel for state, and must be
15395 -+ // explicitly zeroed when allocated.
15396 -+ let mut a = unsafe { mem::zeroed::<libc::aiocb>()};
15397 -+ a.aio_fildes = fd;
15398 -+ a.aio_reqprio = prio;
15399 -+ a.aio_sigevent = SigEvent::new(sigev_notify).sigevent();
15400 -+ a
15401 -+ }
15402 -+
15403 -+ /// Update the notification settings for an existing `aiocb`
15404 -+ pub fn set_sigev_notify(&mut self, sigev_notify: SigevNotify) {
15405 -+ self.aiocb.aio_sigevent = SigEvent::new(sigev_notify).sigevent();
15406 -+ }
15407 -+
15408 -+ /// Cancels an outstanding AIO request.
15409 -+ ///
15410 -+ /// The operating system is not required to implement cancellation for all
15411 -+ /// file and device types. Even if it does, there is no guarantee that the
15412 -+ /// operation has not already completed. So the caller must check the
15413 -+ /// result and handle operations that were not canceled or that have already
15414 -+ /// completed.
15415 -+ ///
15416 -+ /// # Examples
15417 -+ ///
15418 -+ /// Cancel an outstanding aio operation. Note that we must still call
15419 -+ /// `aio_return` to free resources, even though we don't care about the
15420 -+ /// result.
15421 -+ ///
15422 -+ /// ```
15423 -+ /// # extern crate tempfile;
15424 -+ /// # extern crate nix;
15425 -+ /// # use nix::errno::Errno;
15426 -+ /// # use nix::Error;
15427 -+ /// # use nix::sys::aio::*;
15428 -+ /// # use nix::sys::signal::SigevNotify;
15429 -+ /// # use std::{thread, time};
15430 -+ /// # use std::io::Write;
15431 -+ /// # use std::os::unix::io::AsRawFd;
15432 -+ /// # use tempfile::tempfile;
15433 -+ /// # fn main() {
15434 -+ /// let wbuf = b"CDEF";
15435 -+ /// let mut f = tempfile().unwrap();
15436 -+ /// let mut aiocb = AioCb::from_slice( f.as_raw_fd(),
15437 -+ /// 2, //offset
15438 -+ /// &wbuf[..],
15439 -+ /// 0, //priority
15440 -+ /// SigevNotify::SigevNone,
15441 -+ /// LioOpcode::LIO_NOP);
15442 -+ /// aiocb.write().unwrap();
15443 -+ /// let cs = aiocb.cancel().unwrap();
15444 -+ /// if cs == AioCancelStat::AioNotCanceled {
15445 -+ /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) {
15446 -+ /// thread::sleep(time::Duration::from_millis(10));
15447 -+ /// }
15448 -+ /// }
15449 -+ /// // Must call `aio_return`, but ignore the result
15450 -+ /// let _ = aiocb.aio_return();
15451 -+ /// # }
15452 -+ /// ```
15453 -+ ///
15454 -+ /// # References
15455 -+ ///
15456 -+ /// [aio_cancel](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_cancel.html)
15457 -+ pub fn cancel(&mut self) -> Result<AioCancelStat> {
15458 -+ match unsafe { libc::aio_cancel(self.aiocb.aio_fildes, &mut self.aiocb) } {
15459 -+ libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled),
15460 -+ libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled),
15461 -+ libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone),
15462 -+ -1 => Err(Error::last()),
15463 -+ _ => panic!("unknown aio_cancel return value")
15464 -+ }
15465 -+ }
15466 -+
15467 -+ /// Retrieve error status of an asynchronous operation.
15468 -+ ///
15469 -+ /// If the request has not yet completed, returns `EINPROGRESS`. Otherwise,
15470 -+ /// returns `Ok` or any other error.
15471 -+ ///
15472 -+ /// # Examples
15473 -+ ///
15474 -+ /// Issue an aio operation and use `error` to poll for completion. Polling
15475 -+ /// is an alternative to `aio_suspend`, used by most of the other examples.
15476 -+ ///
15477 -+ /// ```
15478 -+ /// # extern crate tempfile;
15479 -+ /// # extern crate nix;
15480 -+ /// # use nix::errno::Errno;
15481 -+ /// # use nix::Error;
15482 -+ /// # use nix::sys::aio::*;
15483 -+ /// # use nix::sys::signal::SigevNotify;
15484 -+ /// # use std::{thread, time};
15485 -+ /// # use std::os::unix::io::AsRawFd;
15486 -+ /// # use tempfile::tempfile;
15487 -+ /// # fn main() {
15488 -+ /// const WBUF: &[u8] = b"abcdef123456";
15489 -+ /// let mut f = tempfile().unwrap();
15490 -+ /// let mut aiocb = AioCb::from_slice( f.as_raw_fd(),
15491 -+ /// 2, //offset
15492 -+ /// WBUF,
15493 -+ /// 0, //priority
15494 -+ /// SigevNotify::SigevNone,
15495 -+ /// LioOpcode::LIO_NOP);
15496 -+ /// aiocb.write().unwrap();
15497 -+ /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) {
15498 -+ /// thread::sleep(time::Duration::from_millis(10));
15499 -+ /// }
15500 -+ /// assert_eq!(aiocb.aio_return().unwrap() as usize, WBUF.len());
15501 -+ /// # }
15502 -+ /// ```
15503 -+ ///
15504 -+ /// # References
15505 -+ ///
15506 -+ /// [aio_error](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_error.html)
15507 -+ pub fn error(&mut self) -> Result<()> {
15508 -+ match unsafe { libc::aio_error(&mut self.aiocb as *mut libc::aiocb) } {
15509 -+ 0 => Ok(()),
15510 -+ num if num > 0 => Err(Error::from_errno(Errno::from_i32(num))),
15511 -+ -1 => Err(Error::last()),
15512 -+ num => panic!("unknown aio_error return value {:?}", num)
15513 -+ }
15514 -+ }
15515 -+
15516 -+ /// An asynchronous version of `fsync(2)`.
15517 -+ ///
15518 -+ /// # References
15519 -+ ///
15520 -+ /// [aio_fsync](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_fsync.html)
15521 -+ pub fn fsync(&mut self, mode: AioFsyncMode) -> Result<()> {
15522 -+ let p: *mut libc::aiocb = &mut self.aiocb;
15523 -+ Errno::result(unsafe {
15524 -+ libc::aio_fsync(mode as libc::c_int, p)
15525 -+ }).map(|_| {
15526 -+ self.in_progress = true;
15527 -+ })
15528 -+ }
15529 -+
15530 -+ /// Returns the `aiocb`'s `LioOpcode` field
15531 -+ ///
15532 -+ /// If the value cannot be represented as an `LioOpcode`, returns `None`
15533 -+ /// instead.
15534 -+ pub fn lio_opcode(&self) -> Option<LioOpcode> {
15535 -+ match self.aiocb.aio_lio_opcode {
15536 -+ libc::LIO_READ => Some(LioOpcode::LIO_READ),
15537 -+ libc::LIO_WRITE => Some(LioOpcode::LIO_WRITE),
15538 -+ libc::LIO_NOP => Some(LioOpcode::LIO_NOP),
15539 -+ _ => None
15540 -+ }
15541 -+ }
15542 -+
15543 -+ /// Returns the requested length of the aio operation in bytes
15544 -+ ///
15545 -+ /// This method returns the *requested* length of the operation. To get the
15546 -+ /// number of bytes actually read or written by a completed operation, use
15547 -+ /// `aio_return` instead.
15548 -+ pub fn nbytes(&self) -> usize {
15549 -+ self.aiocb.aio_nbytes
15550 -+ }
15551 -+
15552 -+ /// Returns the file offset stored in the `AioCb`
15553 -+ pub fn offset(&self) -> off_t {
15554 -+ self.aiocb.aio_offset
15555 -+ }
15556 -+
15557 -+ /// Returns the priority of the `AioCb`
15558 -+ pub fn priority(&self) -> libc::c_int {
15559 -+ self.aiocb.aio_reqprio
15560 -+ }
15561 -+
15562 -+ /// Asynchronously reads from a file descriptor into a buffer
15563 -+ ///
15564 -+ /// # References
15565 -+ ///
15566 -+ /// [aio_read](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_read.html)
15567 -+ pub fn read(&mut self) -> Result<()> {
15568 -+ assert!(self.mutable, "Can't read into an immutable buffer");
15569 -+ let p: *mut libc::aiocb = &mut self.aiocb;
15570 -+ Errno::result(unsafe {
15571 -+ libc::aio_read(p)
15572 -+ }).map(|_| {
15573 -+ self.in_progress = true;
15574 -+ })
15575 -+ }
15576 -+
15577 -+ /// Returns the `SigEvent` stored in the `AioCb`
15578 -+ pub fn sigevent(&self) -> SigEvent {
15579 -+ SigEvent::from(&self.aiocb.aio_sigevent)
15580 -+ }
15581 -+
15582 -+ /// Retrieve return status of an asynchronous operation.
15583 -+ ///
15584 -+ /// Should only be called once for each `AioCb`, after `AioCb::error`
15585 -+ /// indicates that it has completed. The result is the same as for the
15586 -+ /// synchronous `read(2)`, `write(2)`, of `fsync(2)` functions.
15587 -+ ///
15588 -+ /// # References
15589 -+ ///
15590 -+ /// [aio_return](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_return.html)
15591 -+ // Note: this should be just `return`, but that's a reserved word
15592 -+ pub fn aio_return(&mut self) -> Result<isize> {
15593 -+ let p: *mut libc::aiocb = &mut self.aiocb;
15594 -+ self.in_progress = false;
15595 -+ Errno::result(unsafe { libc::aio_return(p) })
15596 -+ }
15597 -+
15598 -+ /// Asynchronously writes from a buffer to a file descriptor
15599 -+ ///
15600 -+ /// # References
15601 -+ ///
15602 -+ /// [aio_write](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_write.html)
15603 -+ pub fn write(&mut self) -> Result<()> {
15604 -+ let p: *mut libc::aiocb = &mut self.aiocb;
15605 -+ Errno::result(unsafe {
15606 -+ libc::aio_write(p)
15607 -+ }).map(|_| {
15608 -+ self.in_progress = true;
15609 -+ })
15610 -+ }
15611 -+
15612 -+}
15613 -+
15614 -+/// Cancels outstanding AIO requests for a given file descriptor.
15615 -+///
15616 -+/// # Examples
15617 -+///
15618 -+/// Issue an aio operation, then cancel all outstanding operations on that file
15619 -+/// descriptor.
15620 -+///
15621 -+/// ```
15622 -+/// # extern crate tempfile;
15623 -+/// # extern crate nix;
15624 -+/// # use nix::errno::Errno;
15625 -+/// # use nix::Error;
15626 -+/// # use nix::sys::aio::*;
15627 -+/// # use nix::sys::signal::SigevNotify;
15628 -+/// # use std::{thread, time};
15629 -+/// # use std::io::Write;
15630 -+/// # use std::os::unix::io::AsRawFd;
15631 -+/// # use tempfile::tempfile;
15632 -+/// # fn main() {
15633 -+/// let wbuf = b"CDEF";
15634 -+/// let mut f = tempfile().unwrap();
15635 -+/// let mut aiocb = AioCb::from_slice( f.as_raw_fd(),
15636 -+/// 2, //offset
15637 -+/// &wbuf[..],
15638 -+/// 0, //priority
15639 -+/// SigevNotify::SigevNone,
15640 -+/// LioOpcode::LIO_NOP);
15641 -+/// aiocb.write().unwrap();
15642 -+/// let cs = aio_cancel_all(f.as_raw_fd()).unwrap();
15643 -+/// if cs == AioCancelStat::AioNotCanceled {
15644 -+/// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) {
15645 -+/// thread::sleep(time::Duration::from_millis(10));
15646 -+/// }
15647 -+/// }
15648 -+/// // Must call `aio_return`, but ignore the result
15649 -+/// let _ = aiocb.aio_return();
15650 -+/// # }
15651 -+/// ```
15652 -+///
15653 -+/// # References
15654 -+///
15655 -+/// [`aio_cancel`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_cancel.html)
15656 -+pub fn aio_cancel_all(fd: RawFd) -> Result<AioCancelStat> {
15657 -+ match unsafe { libc::aio_cancel(fd, null_mut()) } {
15658 -+ libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled),
15659 -+ libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled),
15660 -+ libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone),
15661 -+ -1 => Err(Error::last()),
15662 -+ _ => panic!("unknown aio_cancel return value")
15663 -+ }
15664 -+}
15665 -+
15666 -+/// Suspends the calling process until at least one of the specified `AioCb`s
15667 -+/// has completed, a signal is delivered, or the timeout has passed.
15668 -+///
15669 -+/// If `timeout` is `None`, `aio_suspend` will block indefinitely.
15670 -+///
15671 -+/// # Examples
15672 -+///
15673 -+/// Use `aio_suspend` to block until an aio operation completes.
15674 -+///
15675 -+// Disable doctest due to a known bug in FreeBSD's 32-bit emulation. The fix
15676 -+// will be included in release 11.2.
15677 -+// FIXME reenable the doc test when the CI machine gets upgraded to that release.
15678 -+// https://svnweb.freebsd.org/base?view=revision&revision=325018
15679 -+/// ```no_run
15680 -+/// # extern crate tempfile;
15681 -+/// # extern crate nix;
15682 -+/// # use nix::sys::aio::*;
15683 -+/// # use nix::sys::signal::SigevNotify;
15684 -+/// # use std::os::unix::io::AsRawFd;
15685 -+/// # use tempfile::tempfile;
15686 -+/// # fn main() {
15687 -+/// const WBUF: &[u8] = b"abcdef123456";
15688 -+/// let mut f = tempfile().unwrap();
15689 -+/// let mut aiocb = AioCb::from_slice( f.as_raw_fd(),
15690 -+/// 2, //offset
15691 -+/// WBUF,
15692 -+/// 0, //priority
15693 -+/// SigevNotify::SigevNone,
15694 -+/// LioOpcode::LIO_NOP);
15695 -+/// aiocb.write().unwrap();
15696 -+/// aio_suspend(&[&aiocb], None).expect("aio_suspend failed");
15697 -+/// assert_eq!(aiocb.aio_return().unwrap() as usize, WBUF.len());
15698 -+/// # }
15699 -+/// ```
15700 -+/// # References
15701 -+///
15702 -+/// [`aio_suspend`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_suspend.html)
15703 -+pub fn aio_suspend(list: &[&AioCb], timeout: Option<TimeSpec>) -> Result<()> {
15704 -+ let plist = list as *const [&AioCb] as *const [*const libc::aiocb];
15705 -+ let p = plist as *const *const libc::aiocb;
15706 -+ let timep = match timeout {
15707 -+ None => null::<libc::timespec>(),
15708 -+ Some(x) => x.as_ref() as *const libc::timespec
15709 -+ };
15710 -+ Errno::result(unsafe {
15711 -+ libc::aio_suspend(p, list.len() as i32, timep)
15712 -+ }).map(drop)
15713 -+}
15714 -+
15715 -+impl<'a> Debug for AioCb<'a> {
15716 -+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
15717 -+ fmt.debug_struct("AioCb")
15718 -+ .field("aiocb", &self.aiocb)
15719 -+ .field("mutable", &self.mutable)
15720 -+ .field("in_progress", &self.in_progress)
15721 -+ .finish()
15722 -+ }
15723 -+}
15724 -+
15725 -+impl<'a> Drop for AioCb<'a> {
15726 -+ /// If the `AioCb` has no remaining state in the kernel, just drop it.
15727 -+ /// Otherwise, dropping constitutes a resource leak, which is an error
15728 -+ fn drop(&mut self) {
15729 -+ assert!(thread::panicking() || !self.in_progress,
15730 -+ "Dropped an in-progress AioCb");
15731 -+ }
15732 -+}
15733 -+
15734 -+/// LIO Control Block.
15735 -+///
15736 -+/// The basic structure used to issue multiple AIO operations simultaneously.
15737 -+#[cfg(not(any(target_os = "ios", target_os = "macos")))]
15738 -+pub struct LioCb<'a> {
15739 -+ /// A collection of [`AioCb`]s. All of these will be issued simultaneously
15740 -+ /// by the [`listio`] method.
15741 -+ ///
15742 -+ /// [`AioCb`]: struct.AioCb.html
15743 -+ /// [`listio`]: #method.listio
15744 -+ pub aiocbs: Vec<AioCb<'a>>,
15745 -+
15746 -+ /// The actual list passed to `libc::lio_listio`.
15747 -+ ///
15748 -+ /// It must live for as long as any of the operations are still being
15749 -+ /// processesed, because the aio subsystem uses its address as a unique
15750 -+ /// identifier.
15751 -+ list: Vec<*mut libc::aiocb>,
15752 -+
15753 -+ /// A partial set of results. This field will get populated by
15754 -+ /// `listio_resubmit` when an `LioCb` is resubmitted after an error
15755 -+ results: Vec<Option<Result<isize>>>
15756 -+}
15757 -+
15758 -+#[cfg(not(any(target_os = "ios", target_os = "macos")))]
15759 -+impl<'a> LioCb<'a> {
15760 -+ /// Initialize an empty `LioCb`
15761 -+ pub fn with_capacity(capacity: usize) -> LioCb<'a> {
15762 -+ LioCb {
15763 -+ aiocbs: Vec::with_capacity(capacity),
15764 -+ list: Vec::with_capacity(capacity),
15765 -+ results: Vec::with_capacity(capacity)
15766 -+ }
15767 -+ }
15768 -+
15769 -+ /// Submits multiple asynchronous I/O requests with a single system call.
15770 -+ ///
15771 -+ /// They are not guaranteed to complete atomically, and the order in which
15772 -+ /// the requests are carried out is not specified. Reads, writes, and
15773 -+ /// fsyncs may be freely mixed.
15774 -+ ///
15775 -+ /// This function is useful for reducing the context-switch overhead of
15776 -+ /// submitting many AIO operations. It can also be used with
15777 -+ /// `LioMode::LIO_WAIT` to block on the result of several independent
15778 -+ /// operations. Used that way, it is often useful in programs that
15779 -+ /// otherwise make little use of AIO.
15780 -+ ///
15781 -+ /// # Examples
15782 -+ ///
15783 -+ /// Use `listio` to submit an aio operation and wait for its completion. In
15784 -+ /// this case, there is no need to use [`aio_suspend`] to wait or
15785 -+ /// [`AioCb::error`] to poll.
15786 -+ ///
15787 -+ /// ```
15788 -+ /// # extern crate tempfile;
15789 -+ /// # extern crate nix;
15790 -+ /// # use nix::sys::aio::*;
15791 -+ /// # use nix::sys::signal::SigevNotify;
15792 -+ /// # use std::os::unix::io::AsRawFd;
15793 -+ /// # use tempfile::tempfile;
15794 -+ /// # fn main() {
15795 -+ /// const WBUF: &[u8] = b"abcdef123456";
15796 -+ /// let mut f = tempfile().unwrap();
15797 -+ /// let mut liocb = LioCb::with_capacity(1);
15798 -+ /// liocb.aiocbs.push(AioCb::from_slice( f.as_raw_fd(),
15799 -+ /// 2, //offset
15800 -+ /// WBUF,
15801 -+ /// 0, //priority
15802 -+ /// SigevNotify::SigevNone,
15803 -+ /// LioOpcode::LIO_WRITE));
15804 -+ /// liocb.listio(LioMode::LIO_WAIT,
15805 -+ /// SigevNotify::SigevNone).unwrap();
15806 -+ /// assert_eq!(liocb.aio_return(0).unwrap() as usize, WBUF.len());
15807 -+ /// # }
15808 -+ /// ```
15809 -+ ///
15810 -+ /// # References
15811 -+ ///
15812 -+ /// [`lio_listio`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/lio_listio.html)
15813 -+ ///
15814 -+ /// [`aio_suspend`]: fn.aio_suspend.html
15815 -+ /// [`AioCb::error`]: struct.AioCb.html#method.error
15816 -+ pub fn listio(&mut self, mode: LioMode,
15817 -+ sigev_notify: SigevNotify) -> Result<()> {
15818 -+ let sigev = SigEvent::new(sigev_notify);
15819 -+ let sigevp = &mut sigev.sigevent() as *mut libc::sigevent;
15820 -+ self.list.clear();
15821 -+ for a in &mut self.aiocbs {
15822 -+ a.in_progress = true;
15823 -+ self.list.push(a as *mut AioCb<'a>
15824 -+ as *mut libc::aiocb);
15825 -+ }
15826 -+ let p = self.list.as_ptr();
15827 -+ Errno::result(unsafe {
15828 -+ libc::lio_listio(mode as i32, p, self.list.len() as i32, sigevp)
15829 -+ }).map(drop)
15830 -+ }
15831 -+
15832 -+ /// Resubmits any incomplete operations with [`lio_listio`].
15833 -+ ///
15834 -+ /// Sometimes, due to system resource limitations, an `lio_listio` call will
15835 -+ /// return `EIO`, or `EAGAIN`. Or, if a signal is received, it may return
15836 -+ /// `EINTR`. In any of these cases, only a subset of its constituent
15837 -+ /// operations will actually have been initiated. `listio_resubmit` will
15838 -+ /// resubmit any operations that are still uninitiated.
15839 -+ ///
15840 -+ /// After calling `listio_resubmit`, results should be collected by
15841 -+ /// [`LioCb::aio_return`].
15842 -+ ///
15843 -+ /// # Examples
15844 -+ /// ```no_run
15845 -+ /// # extern crate tempfile;
15846 -+ /// # extern crate nix;
15847 -+ /// # use nix::Error;
15848 -+ /// # use nix::errno::Errno;
15849 -+ /// # use nix::sys::aio::*;
15850 -+ /// # use nix::sys::signal::SigevNotify;
15851 -+ /// # use std::os::unix::io::AsRawFd;
15852 -+ /// # use std::{thread, time};
15853 -+ /// # use tempfile::tempfile;
15854 -+ /// # fn main() {
15855 -+ /// const WBUF: &[u8] = b"abcdef123456";
15856 -+ /// let mut f = tempfile().unwrap();
15857 -+ /// let mut liocb = LioCb::with_capacity(1);
15858 -+ /// liocb.aiocbs.push(AioCb::from_slice( f.as_raw_fd(),
15859 -+ /// 2, //offset
15860 -+ /// WBUF,
15861 -+ /// 0, //priority
15862 -+ /// SigevNotify::SigevNone,
15863 -+ /// LioOpcode::LIO_WRITE));
15864 -+ /// let mut err = liocb.listio(LioMode::LIO_WAIT, SigevNotify::SigevNone);
15865 -+ /// while err == Err(Error::Sys(Errno::EIO)) ||
15866 -+ /// err == Err(Error::Sys(Errno::EAGAIN)) {
15867 -+ /// thread::sleep(time::Duration::from_millis(10));
15868 -+ /// err = liocb.listio_resubmit(LioMode::LIO_WAIT, SigevNotify::SigevNone);
15869 -+ /// }
15870 -+ /// assert_eq!(liocb.aio_return(0).unwrap() as usize, WBUF.len());
15871 -+ /// # }
15872 -+ /// ```
15873 -+ ///
15874 -+ /// # References
15875 -+ ///
15876 -+ /// [`lio_listio`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/lio_listio.html)
15877 -+ ///
15878 -+ /// [`lio_listio`]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/lio_listio.html
15879 -+ /// [`LioCb::aio_return`]: struct.LioCb.html#method.aio_return
15880 -+ // Note: the addresses of any EINPROGRESS or EOK aiocbs _must_ not be
15881 -+ // changed by this method, because the kernel relies on their addresses
15882 -+ // being stable.
15883 -+ // Note: aiocbs that are Ok(()) must be finalized by aio_return, or else the
15884 -+ // sigev_notify will immediately refire.
15885 -+ pub fn listio_resubmit(&mut self, mode:LioMode,
15886 -+ sigev_notify: SigevNotify) -> Result<()> {
15887 -+ let sigev = SigEvent::new(sigev_notify);
15888 -+ let sigevp = &mut sigev.sigevent() as *mut libc::sigevent;
15889 -+ self.list.clear();
15890 -+
15891 -+ while self.results.len() < self.aiocbs.len() {
15892 -+ self.results.push(None);
15893 -+ }
15894 -+
15895 -+ for (i, a) in self.aiocbs.iter_mut().enumerate() {
15896 -+ if self.results[i].is_some() {
15897 -+ // Already collected final status for this operation
15898 -+ continue;
15899 -+ }
15900 -+ match a.error() {
15901 -+ Ok(()) => {
15902 -+ // aiocb is complete; collect its status and don't resubmit
15903 -+ self.results[i] = Some(a.aio_return());
15904 -+ },
15905 -+ Err(Error::Sys(Errno::EAGAIN)) => {
15906 -+ self.list.push(a as *mut AioCb<'a> as *mut libc::aiocb);
15907 -+ },
15908 -+ Err(Error::Sys(Errno::EINPROGRESS)) => {
15909 -+ // aiocb is was successfully queued; no need to do anything
15910 -+ ()
15911 -+ },
15912 -+ Err(Error::Sys(Errno::EINVAL)) => panic!(
15913 -+ "AioCb was never submitted, or already finalized"),
15914 -+ _ => unreachable!()
15915 -+ }
15916 -+ }
15917 -+ let p = self.list.as_ptr();
15918 -+ Errno::result(unsafe {
15919 -+ libc::lio_listio(mode as i32, p, self.list.len() as i32, sigevp)
15920 -+ }).map(drop)
15921 -+ }
15922 -+
15923 -+ /// Collect final status for an individual `AioCb` submitted as part of an
15924 -+ /// `LioCb`.
15925 -+ ///
15926 -+ /// This is just like [`AioCb::aio_return`], except it takes into account
15927 -+ /// operations that were restarted by [`LioCb::listio_resubmit`]
15928 -+ ///
15929 -+ /// [`AioCb::aio_return`]: struct.AioCb.html#method.aio_return
15930 -+ /// [`LioCb::listio_resubmit`]: #method.listio_resubmit
15931 -+ pub fn aio_return(&mut self, i: usize) -> Result<isize> {
15932 -+ if i >= self.results.len() || self.results[i].is_none() {
15933 -+ self.aiocbs[i].aio_return()
15934 -+ } else {
15935 -+ self.results[i].unwrap()
15936 -+ }
15937 -+ }
15938 -+
15939 -+ /// Retrieve error status of an individual `AioCb` submitted as part of an
15940 -+ /// `LioCb`.
15941 -+ ///
15942 -+ /// This is just like [`AioCb::error`], except it takes into account
15943 -+ /// operations that were restarted by [`LioCb::listio_resubmit`]
15944 -+ ///
15945 -+ /// [`AioCb::error`]: struct.AioCb.html#method.error
15946 -+ /// [`LioCb::listio_resubmit`]: #method.listio_resubmit
15947 -+ pub fn error(&mut self, i: usize) -> Result<()> {
15948 -+ if i >= self.results.len() || self.results[i].is_none() {
15949 -+ self.aiocbs[i].error()
15950 -+ } else {
15951 -+ Ok(())
15952 -+ }
15953 -+ }
15954 -+}
15955 -+
15956 -+#[cfg(not(any(target_os = "ios", target_os = "macos")))]
15957 -+impl<'a> Debug for LioCb<'a> {
15958 -+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
15959 -+ fmt.debug_struct("LioCb")
15960 -+ .field("aiocbs", &self.aiocbs)
15961 -+ .finish()
15962 -+ }
15963 -+}
15964 -+
15965 -+#[cfg(not(any(target_os = "ios", target_os = "macos")))]
15966 -+impl<'a> From<Vec<AioCb<'a>>> for LioCb<'a> {
15967 -+ fn from(src: Vec<AioCb<'a>>) -> LioCb<'a> {
15968 -+ LioCb {
15969 -+ list: Vec::with_capacity(src.capacity()),
15970 -+ results: Vec::with_capacity(src.capacity()),
15971 -+ aiocbs: src,
15972 -+ }
15973 -+ }
15974 -+}
15975 -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
15976 -new file mode 100644
15977 -index 0000000000000..fef6f4e3ec92c
15978 ---- /dev/null
15979 -+++ b/third_party/rust/nix-0.15.0/src/sys/epoll.rs
15980 -@@ -0,0 +1,109 @@
15981 -+use Result;
15982 -+use errno::Errno;
15983 -+use libc::{self, c_int};
15984 -+use std::os::unix::io::RawFd;
15985 -+use std::ptr;
15986 -+use std::mem;
15987 -+use ::Error;
15988 -+
15989 -+libc_bitflags!(
15990 -+ pub struct EpollFlags: c_int {
15991 -+ EPOLLIN;
15992 -+ EPOLLPRI;
15993 -+ EPOLLOUT;
15994 -+ EPOLLRDNORM;
15995 -+ EPOLLRDBAND;
15996 -+ EPOLLWRNORM;
15997 -+ EPOLLWRBAND;
15998 -+ EPOLLMSG;
15999 -+ EPOLLERR;
16000 -+ EPOLLHUP;
16001 -+ EPOLLRDHUP;
16002 -+ #[cfg(target_os = "linux")] // Added in 4.5; not in Android.
16003 -+ EPOLLEXCLUSIVE;
16004 -+ #[cfg(not(target_arch = "mips"))]
16005 -+ EPOLLWAKEUP;
16006 -+ EPOLLONESHOT;
16007 -+ EPOLLET;
16008 -+ }
16009 -+);
16010 -+
16011 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
16012 -+#[repr(i32)]
16013 -+pub enum EpollOp {
16014 -+ EpollCtlAdd = libc::EPOLL_CTL_ADD,
16015 -+ EpollCtlDel = libc::EPOLL_CTL_DEL,
16016 -+ EpollCtlMod = libc::EPOLL_CTL_MOD,
16017 -+}
16018 -+
16019 -+libc_bitflags!{
16020 -+ pub struct EpollCreateFlags: c_int {
16021 -+ EPOLL_CLOEXEC;
16022 -+ }
16023 -+}
16024 -+
16025 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
16026 -+#[repr(C)]
16027 -+pub struct EpollEvent {
16028 -+ event: libc::epoll_event,
16029 -+}
16030 -+
16031 -+impl EpollEvent {
16032 -+ pub fn new(events: EpollFlags, data: u64) -> Self {
16033 -+ EpollEvent { event: libc::epoll_event { events: events.bits() as u32, u64: data } }
16034 -+ }
16035 -+
16036 -+ pub fn empty() -> Self {
16037 -+ unsafe { mem::zeroed::<EpollEvent>() }
16038 -+ }
16039 -+
16040 -+ pub fn events(&self) -> EpollFlags {
16041 -+ EpollFlags::from_bits(self.event.events as c_int).unwrap()
16042 -+ }
16043 -+
16044 -+ pub fn data(&self) -> u64 {
16045 -+ self.event.u64
16046 -+ }
16047 -+}
16048 -+
16049 -+#[inline]
16050 -+pub fn epoll_create() -> Result<RawFd> {
16051 -+ let res = unsafe { libc::epoll_create(1024) };
16052 -+
16053 -+ Errno::result(res)
16054 -+}
16055 -+
16056 -+#[inline]
16057 -+pub fn epoll_create1(flags: EpollCreateFlags) -> Result<RawFd> {
16058 -+ let res = unsafe { libc::epoll_create1(flags.bits()) };
16059 -+
16060 -+ Errno::result(res)
16061 -+}
16062 -+
16063 -+#[inline]
16064 -+pub fn epoll_ctl<'a, T>(epfd: RawFd, op: EpollOp, fd: RawFd, event: T) -> Result<()>
16065 -+ where T: Into<Option<&'a mut EpollEvent>>
16066 -+{
16067 -+ let mut event: Option<&mut EpollEvent> = event.into();
16068 -+ if event.is_none() && op != EpollOp::EpollCtlDel {
16069 -+ Err(Error::Sys(Errno::EINVAL))
16070 -+ } else {
16071 -+ let res = unsafe {
16072 -+ if let Some(ref mut event) = event {
16073 -+ libc::epoll_ctl(epfd, op as c_int, fd, &mut event.event)
16074 -+ } else {
16075 -+ libc::epoll_ctl(epfd, op as c_int, fd, ptr::null_mut())
16076 -+ }
16077 -+ };
16078 -+ Errno::result(res).map(drop)
16079 -+ }
16080 -+}
16081 -+
16082 -+#[inline]
16083 -+pub fn epoll_wait(epfd: RawFd, events: &mut [EpollEvent], timeout_ms: isize) -> Result<usize> {
16084 -+ let res = unsafe {
16085 -+ libc::epoll_wait(epfd, events.as_mut_ptr() as *mut libc::epoll_event, events.len() as c_int, timeout_ms as c_int)
16086 -+ };
16087 -+
16088 -+ Errno::result(res).map(|r| r as usize)
16089 -+}
16090 -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
16091 -new file mode 100644
16092 -index 0000000000000..8cd7372f88188
16093 ---- /dev/null
16094 -+++ b/third_party/rust/nix-0.15.0/src/sys/event.rs
16095 -@@ -0,0 +1,351 @@
16096 -+/* TOOD: Implement for other kqueue based systems
16097 -+ */
16098 -+
16099 -+use {Errno, Result};
16100 -+#[cfg(not(target_os = "netbsd"))]
16101 -+use libc::{timespec, time_t, c_int, c_long, intptr_t, uintptr_t};
16102 -+#[cfg(target_os = "netbsd")]
16103 -+use libc::{timespec, time_t, c_long, intptr_t, uintptr_t, size_t};
16104 -+use libc;
16105 -+use std::os::unix::io::RawFd;
16106 -+use std::ptr;
16107 -+use std::mem;
16108 -+
16109 -+// Redefine kevent in terms of programmer-friendly enums and bitfields.
16110 -+#[repr(C)]
16111 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
16112 -+pub struct KEvent {
16113 -+ kevent: libc::kevent,
16114 -+}
16115 -+
16116 -+#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
16117 -+ target_os = "ios", target_os = "macos",
16118 -+ target_os = "openbsd"))]
16119 -+type type_of_udata = *mut libc::c_void;
16120 -+#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
16121 -+ target_os = "ios", target_os = "macos"))]
16122 -+type type_of_data = intptr_t;
16123 -+#[cfg(any(target_os = "netbsd"))]
16124 -+type type_of_udata = intptr_t;
16125 -+#[cfg(any(target_os = "netbsd", target_os = "openbsd"))]
16126 -+type type_of_data = libc::int64_t;
16127 -+
16128 -+#[cfg(target_os = "netbsd")]
16129 -+type type_of_event_filter = u32;
16130 -+#[cfg(not(target_os = "netbsd"))]
16131 -+type type_of_event_filter = i16;
16132 -+libc_enum! {
16133 -+ #[cfg_attr(target_os = "netbsd", repr(u32))]
16134 -+ #[cfg_attr(not(target_os = "netbsd"), repr(i16))]
16135 -+ pub enum EventFilter {
16136 -+ EVFILT_AIO,
16137 -+ /// Returns whenever there is no remaining data in the write buffer
16138 -+ #[cfg(target_os = "freebsd")]
16139 -+ EVFILT_EMPTY,
16140 -+ #[cfg(target_os = "dragonfly")]
16141 -+ EVFILT_EXCEPT,
16142 -+ #[cfg(any(target_os = "dragonfly",
16143 -+ target_os = "freebsd",
16144 -+ target_os = "ios",
16145 -+ target_os = "macos"))]
16146 -+ EVFILT_FS,
16147 -+ #[cfg(target_os = "freebsd")]
16148 -+ EVFILT_LIO,
16149 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
16150 -+ EVFILT_MACHPORT,
16151 -+ EVFILT_PROC,
16152 -+ /// Returns events associated with the process referenced by a given
16153 -+ /// process descriptor, created by `pdfork()`. The events to monitor are:
16154 -+ ///
16155 -+ /// - NOTE_EXIT: the process has exited. The exit status will be stored in data.
16156 -+ #[cfg(target_os = "freebsd")]
16157 -+ EVFILT_PROCDESC,
16158 -+ EVFILT_READ,
16159 -+ /// Returns whenever an asynchronous `sendfile()` call completes.
16160 -+ #[cfg(target_os = "freebsd")]
16161 -+ EVFILT_SENDFILE,
16162 -+ EVFILT_SIGNAL,
16163 -+ EVFILT_TIMER,
16164 -+ #[cfg(any(target_os = "dragonfly",
16165 -+ target_os = "freebsd",
16166 -+ target_os = "ios",
16167 -+ target_os = "macos"))]
16168 -+ EVFILT_USER,
16169 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
16170 -+ EVFILT_VM,
16171 -+ EVFILT_VNODE,
16172 -+ EVFILT_WRITE,
16173 -+ }
16174 -+}
16175 -+
16176 -+#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
16177 -+ target_os = "ios", target_os = "macos",
16178 -+ target_os = "openbsd"))]
16179 -+pub type type_of_event_flag = u16;
16180 -+#[cfg(any(target_os = "netbsd"))]
16181 -+pub type type_of_event_flag = u32;
16182 -+libc_bitflags!{
16183 -+ pub struct EventFlag: type_of_event_flag {
16184 -+ EV_ADD;
16185 -+ EV_CLEAR;
16186 -+ EV_DELETE;
16187 -+ EV_DISABLE;
16188 -+ // No released version of OpenBSD supports EV_DISPATCH or EV_RECEIPT.
16189 -+ // These have been commited to the -current branch though and are
16190 -+ // expected to be part of the OpenBSD 6.2 release in Nov 2017.
16191 -+ // See: https://marc.info/?l=openbsd-tech&m=149621427511219&w=2
16192 -+ // https://github.com/rust-lang/libc/pull/613
16193 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
16194 -+ target_os = "ios", target_os = "macos",
16195 -+ target_os = "netbsd"))]
16196 -+ EV_DISPATCH;
16197 -+ #[cfg(target_os = "freebsd")]
16198 -+ EV_DROP;
16199 -+ EV_ENABLE;
16200 -+ EV_EOF;
16201 -+ EV_ERROR;
16202 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
16203 -+ EV_FLAG0;
16204 -+ EV_FLAG1;
16205 -+ #[cfg(target_os = "dragonfly")]
16206 -+ EV_NODATA;
16207 -+ EV_ONESHOT;
16208 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
16209 -+ EV_OOBAND;
16210 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
16211 -+ EV_POLL;
16212 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
16213 -+ target_os = "ios", target_os = "macos",
16214 -+ target_os = "netbsd"))]
16215 -+ EV_RECEIPT;
16216 -+ EV_SYSFLAGS;
16217 -+ }
16218 -+}
16219 -+
16220 -+libc_bitflags!(
16221 -+ pub struct FilterFlag: u32 {
16222 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
16223 -+ NOTE_ABSOLUTE;
16224 -+ NOTE_ATTRIB;
16225 -+ NOTE_CHILD;
16226 -+ NOTE_DELETE;
16227 -+ #[cfg(target_os = "openbsd")]
16228 -+ NOTE_EOF;
16229 -+ NOTE_EXEC;
16230 -+ NOTE_EXIT;
16231 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
16232 -+ #[deprecated( since="0.14.0", note="Deprecated since OSX 10.9")]
16233 -+ #[allow(deprecated)]
16234 -+ NOTE_EXIT_REPARENTED;
16235 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
16236 -+ NOTE_EXITSTATUS;
16237 -+ NOTE_EXTEND;
16238 -+ #[cfg(any(target_os = "macos",
16239 -+ target_os = "ios",
16240 -+ target_os = "freebsd",
16241 -+ target_os = "dragonfly"))]
16242 -+ NOTE_FFAND;
16243 -+ #[cfg(any(target_os = "macos",
16244 -+ target_os = "ios",
16245 -+ target_os = "freebsd",
16246 -+ target_os = "dragonfly"))]
16247 -+ NOTE_FFCOPY;
16248 -+ #[cfg(any(target_os = "macos",
16249 -+ target_os = "ios",
16250 -+ target_os = "freebsd",
16251 -+ target_os = "dragonfly"))]
16252 -+ NOTE_FFCTRLMASK;
16253 -+ #[cfg(any(target_os = "macos",
16254 -+ target_os = "ios",
16255 -+ target_os = "freebsd",
16256 -+ target_os = "dragonfly"))]
16257 -+ NOTE_FFLAGSMASK;
16258 -+ #[cfg(any(target_os = "macos",
16259 -+ target_os = "ios",
16260 -+ target_os = "freebsd",
16261 -+ target_os = "dragonfly"))]
16262 -+ NOTE_FFNOP;
16263 -+ #[cfg(any(target_os = "macos",
16264 -+ target_os = "ios",
16265 -+ target_os = "freebsd",
16266 -+ target_os = "dragonfly"))]
16267 -+ NOTE_FFOR;
16268 -+ NOTE_FORK;
16269 -+ NOTE_LINK;
16270 -+ NOTE_LOWAT;
16271 -+ #[cfg(target_os = "freebsd")]
16272 -+ NOTE_MSECONDS;
16273 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
16274 -+ NOTE_NONE;
16275 -+ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))]
16276 -+ NOTE_NSECONDS;
16277 -+ #[cfg(target_os = "dragonfly")]
16278 -+ NOTE_OOB;
16279 -+ NOTE_PCTRLMASK;
16280 -+ NOTE_PDATAMASK;
16281 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
16282 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
16283 -+ #[deprecated( since="0.14.0", note="Deprecated since OSX 10.9")]
16284 -+ #[allow(deprecated)]
16285 -+ NOTE_REAP;
16286 -+ NOTE_RENAME;
16287 -+ NOTE_REVOKE;
16288 -+ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))]
16289 -+ NOTE_SECONDS;
16290 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
16291 -+ NOTE_SIGNAL;
16292 -+ NOTE_TRACK;
16293 -+ NOTE_TRACKERR;
16294 -+ #[cfg(any(target_os = "macos",
16295 -+ target_os = "ios",
16296 -+ target_os = "freebsd",
16297 -+ target_os = "dragonfly"))]
16298 -+ NOTE_TRIGGER;
16299 -+ #[cfg(target_os = "openbsd")]
16300 -+ NOTE_TRUNCATE;
16301 -+ #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))]
16302 -+ NOTE_USECONDS;
16303 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
16304 -+ NOTE_VM_ERROR;
16305 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
16306 -+ NOTE_VM_PRESSURE;
16307 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
16308 -+ NOTE_VM_PRESSURE_SUDDEN_TERMINATE;
16309 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
16310 -+ NOTE_VM_PRESSURE_TERMINATE;
16311 -+ NOTE_WRITE;
16312 -+ }
16313 -+);
16314 -+
16315 -+pub fn kqueue() -> Result<RawFd> {
16316 -+ let res = unsafe { libc::kqueue() };
16317 -+
16318 -+ Errno::result(res)
16319 -+}
16320 -+
16321 -+
16322 -+// KEvent can't derive Send because on some operating systems, udata is defined
16323 -+// as a void*. However, KEvent's public API always treats udata as an intptr_t,
16324 -+// which is safe to Send.
16325 -+unsafe impl Send for KEvent {
16326 -+}
16327 -+
16328 -+impl KEvent {
16329 -+ pub fn new(ident: uintptr_t, filter: EventFilter, flags: EventFlag,
16330 -+ fflags:FilterFlag, data: intptr_t, udata: intptr_t) -> KEvent {
16331 -+ KEvent { kevent: libc::kevent {
16332 -+ ident: ident,
16333 -+ filter: filter as type_of_event_filter,
16334 -+ flags: flags.bits(),
16335 -+ fflags: fflags.bits(),
16336 -+ data: data as type_of_data,
16337 -+ udata: udata as type_of_udata
16338 -+ } }
16339 -+ }
16340 -+
16341 -+ pub fn ident(&self) -> uintptr_t {
16342 -+ self.kevent.ident
16343 -+ }
16344 -+
16345 -+ pub fn filter(&self) -> EventFilter {
16346 -+ unsafe { mem::transmute(self.kevent.filter as type_of_event_filter) }
16347 -+ }
16348 -+
16349 -+ pub fn flags(&self) -> EventFlag {
16350 -+ EventFlag::from_bits(self.kevent.flags).unwrap()
16351 -+ }
16352 -+
16353 -+ pub fn fflags(&self) -> FilterFlag {
16354 -+ FilterFlag::from_bits(self.kevent.fflags).unwrap()
16355 -+ }
16356 -+
16357 -+ pub fn data(&self) -> intptr_t {
16358 -+ self.kevent.data as intptr_t
16359 -+ }
16360 -+
16361 -+ pub fn udata(&self) -> intptr_t {
16362 -+ self.kevent.udata as intptr_t
16363 -+ }
16364 -+}
16365 -+
16366 -+pub fn kevent(kq: RawFd,
16367 -+ changelist: &[KEvent],
16368 -+ eventlist: &mut [KEvent],
16369 -+ timeout_ms: usize) -> Result<usize> {
16370 -+
16371 -+ // Convert ms to timespec
16372 -+ let timeout = timespec {
16373 -+ tv_sec: (timeout_ms / 1000) as time_t,
16374 -+ tv_nsec: ((timeout_ms % 1000) * 1_000_000) as c_long
16375 -+ };
16376 -+
16377 -+ kevent_ts(kq, changelist, eventlist, Some(timeout))
16378 -+}
16379 -+
16380 -+#[cfg(any(target_os = "macos",
16381 -+ target_os = "ios",
16382 -+ target_os = "freebsd",
16383 -+ target_os = "dragonfly",
16384 -+ target_os = "openbsd"))]
16385 -+type type_of_nchanges = c_int;
16386 -+#[cfg(target_os = "netbsd")]
16387 -+type type_of_nchanges = size_t;
16388 -+
16389 -+pub fn kevent_ts(kq: RawFd,
16390 -+ changelist: &[KEvent],
16391 -+ eventlist: &mut [KEvent],
16392 -+ timeout_opt: Option<timespec>) -> Result<usize> {
16393 -+
16394 -+ let res = unsafe {
16395 -+ libc::kevent(
16396 -+ kq,
16397 -+ changelist.as_ptr() as *const libc::kevent,
16398 -+ changelist.len() as type_of_nchanges,
16399 -+ eventlist.as_mut_ptr() as *mut libc::kevent,
16400 -+ eventlist.len() as type_of_nchanges,
16401 -+ if let Some(ref timeout) = timeout_opt {timeout as *const timespec} else {ptr::null()})
16402 -+ };
16403 -+
16404 -+ Errno::result(res).map(|r| r as usize)
16405 -+}
16406 -+
16407 -+#[inline]
16408 -+pub fn ev_set(ev: &mut KEvent,
16409 -+ ident: usize,
16410 -+ filter: EventFilter,
16411 -+ flags: EventFlag,
16412 -+ fflags: FilterFlag,
16413 -+ udata: intptr_t) {
16414 -+
16415 -+ ev.kevent.ident = ident as uintptr_t;
16416 -+ ev.kevent.filter = filter as type_of_event_filter;
16417 -+ ev.kevent.flags = flags.bits();
16418 -+ ev.kevent.fflags = fflags.bits();
16419 -+ ev.kevent.data = 0;
16420 -+ ev.kevent.udata = udata as type_of_udata;
16421 -+}
16422 -+
16423 -+#[test]
16424 -+fn test_struct_kevent() {
16425 -+ let udata : intptr_t = 12345;
16426 -+
16427 -+ let expected = libc::kevent{ident: 0xdead_beef,
16428 -+ filter: libc::EVFILT_READ,
16429 -+ flags: libc::EV_ONESHOT | libc::EV_ADD,
16430 -+ fflags: libc::NOTE_CHILD | libc::NOTE_EXIT,
16431 -+ data: 0x1337,
16432 -+ udata: udata as type_of_udata};
16433 -+ let actual = KEvent::new(0xdead_beef,
16434 -+ EventFilter::EVFILT_READ,
16435 -+ EventFlag::EV_ONESHOT | EventFlag::EV_ADD,
16436 -+ FilterFlag::NOTE_CHILD | FilterFlag::NOTE_EXIT,
16437 -+ 0x1337,
16438 -+ udata);
16439 -+ assert!(expected.ident == actual.ident());
16440 -+ assert!(expected.filter == actual.filter() as type_of_event_filter);
16441 -+ assert!(expected.flags == actual.flags().bits());
16442 -+ assert!(expected.fflags == actual.fflags().bits());
16443 -+ assert!(expected.data == actual.data() as type_of_data);
16444 -+ assert!(expected.udata == actual.udata() as type_of_udata);
16445 -+ assert!(mem::size_of::<libc::kevent>() == mem::size_of::<KEvent>());
16446 -+}
16447 -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
16448 -new file mode 100644
16449 -index 0000000000000..c5a54e46a1735
16450 ---- /dev/null
16451 -+++ b/third_party/rust/nix-0.15.0/src/sys/eventfd.rs
16452 -@@ -0,0 +1,18 @@
16453 -+use libc;
16454 -+use std::os::unix::io::RawFd;
16455 -+use Result;
16456 -+use errno::Errno;
16457 -+
16458 -+libc_bitflags! {
16459 -+ pub struct EfdFlags: libc::c_int {
16460 -+ EFD_CLOEXEC; // Since Linux 2.6.27
16461 -+ EFD_NONBLOCK; // Since Linux 2.6.27
16462 -+ EFD_SEMAPHORE; // Since Linux 2.6.30
16463 -+ }
16464 -+}
16465 -+
16466 -+pub fn eventfd(initval: libc::c_uint, flags: EfdFlags) -> Result<RawFd> {
16467 -+ let res = unsafe { libc::eventfd(initval, flags.bits()) };
16468 -+
16469 -+ Errno::result(res).map(|r| r as RawFd)
16470 -+}
16471 -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
16472 -new file mode 100644
16473 -index 0000000000000..e6c2cf64d29dc
16474 ---- /dev/null
16475 -+++ b/third_party/rust/nix-0.15.0/src/sys/inotify.rs
16476 -@@ -0,0 +1,230 @@
16477 -+//! Monitoring API for filesystem events.
16478 -+//!
16479 -+//! Inotify is a Linux-only API to monitor filesystems events.
16480 -+//!
16481 -+//! For more documentation, please read [inotify(7)](http://man7.org/linux/man-pages/man7/inotify.7.html).
16482 -+//!
16483 -+//! # Examples
16484 -+//!
16485 -+//! Monitor all events happening in directory "test":
16486 -+//! ```no_run
16487 -+//! # use nix::sys::inotify::{AddWatchFlags,InitFlags,Inotify};
16488 -+//! #
16489 -+//! // We create a new inotify instance.
16490 -+//! let instance = Inotify::init(InitFlags::empty()).unwrap();
16491 -+//!
16492 -+//! // We add a new watch on directory "test" for all events.
16493 -+//! let wd = instance.add_watch("test", AddWatchFlags::IN_ALL_EVENTS).unwrap();
16494 -+//!
16495 -+//! loop {
16496 -+//! // We read from our inotify instance for events.
16497 -+//! let events = instance.read_events().unwrap();
16498 -+//! println!("Events: {:?}", events);
16499 -+//! }
16500 -+//! ```
16501 -+
16502 -+use libc;
16503 -+use libc::{
16504 -+ c_char,
16505 -+ c_int,
16506 -+};
16507 -+use std::ffi::{OsString,OsStr,CStr};
16508 -+use std::os::unix::ffi::OsStrExt;
16509 -+use std::mem::size_of;
16510 -+use std::os::unix::io::{RawFd,AsRawFd,FromRawFd};
16511 -+use unistd::read;
16512 -+use Result;
16513 -+use NixPath;
16514 -+use errno::Errno;
16515 -+
16516 -+libc_bitflags! {
16517 -+ /// Configuration options for [`inotify_add_watch`](fn.inotify_add_watch.html).
16518 -+ pub struct AddWatchFlags: u32 {
16519 -+ IN_ACCESS;
16520 -+ IN_MODIFY;
16521 -+ IN_ATTRIB;
16522 -+ IN_CLOSE_WRITE;
16523 -+ IN_CLOSE_NOWRITE;
16524 -+ IN_OPEN;
16525 -+ IN_MOVED_FROM;
16526 -+ IN_MOVED_TO;
16527 -+ IN_CREATE;
16528 -+ IN_DELETE;
16529 -+ IN_DELETE_SELF;
16530 -+ IN_MOVE_SELF;
16531 -+
16532 -+ IN_UNMOUNT;
16533 -+ IN_Q_OVERFLOW;
16534 -+ IN_IGNORED;
16535 -+
16536 -+ IN_CLOSE;
16537 -+ IN_MOVE;
16538 -+
16539 -+ IN_ONLYDIR;
16540 -+ IN_DONT_FOLLOW;
16541 -+
16542 -+ IN_ISDIR;
16543 -+ IN_ONESHOT;
16544 -+ IN_ALL_EVENTS;
16545 -+ }
16546 -+}
16547 -+
16548 -+libc_bitflags! {
16549 -+ /// Configuration options for [`inotify_init1`](fn.inotify_init1.html).
16550 -+ pub struct InitFlags: c_int {
16551 -+ IN_CLOEXEC;
16552 -+ IN_NONBLOCK;
16553 -+ }
16554 -+}
16555 -+
16556 -+/// An inotify instance. This is also a file descriptor, you can feed it to
16557 -+/// other interfaces consuming file descriptors, epoll for example.
16558 -+#[derive(Debug, Clone, Copy)]
16559 -+pub struct Inotify {
16560 -+ fd: RawFd
16561 -+}
16562 -+
16563 -+/// This object is returned when you create a new watch on an inotify instance.
16564 -+/// It is then returned as part of an event once triggered. It allows you to
16565 -+/// know which watch triggered which event.
16566 -+#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd)]
16567 -+pub struct WatchDescriptor {
16568 -+ wd: i32
16569 -+}
16570 -+
16571 -+/// A single inotify event.
16572 -+///
16573 -+/// For more documentation see, [inotify(7)](http://man7.org/linux/man-pages/man7/inotify.7.html).
16574 -+#[derive(Debug)]
16575 -+pub struct InotifyEvent {
16576 -+ /// Watch descriptor. This field corresponds to the watch descriptor you
16577 -+ /// were issued when calling add_watch. It allows you to know which watch
16578 -+ /// this event comes from.
16579 -+ pub wd: WatchDescriptor,
16580 -+ /// Event mask. This field is a bitfield describing the exact event that
16581 -+ /// occured.
16582 -+ pub mask: AddWatchFlags,
16583 -+ /// This cookie is a number that allows you to connect related events. For
16584 -+ /// now only IN_MOVED_FROM and IN_MOVED_TO can be connected.
16585 -+ pub cookie: u32,
16586 -+ /// Filename. This field exists only if the event was triggered for a file
16587 -+ /// inside the watched directory.
16588 -+ pub name: Option<OsString>
16589 -+}
16590 -+
16591 -+impl Inotify {
16592 -+ /// Initialize a new inotify instance.
16593 -+ ///
16594 -+ /// Returns a Result containing an inotify instance.
16595 -+ ///
16596 -+ /// For more information see, [inotify_init(2)](http://man7.org/linux/man-pages/man2/inotify_init.2.html).
16597 -+ pub fn init(flags: InitFlags) -> Result<Inotify> {
16598 -+ let res = Errno::result(unsafe {
16599 -+ libc::inotify_init1(flags.bits())
16600 -+ });
16601 -+
16602 -+ res.map(|fd| Inotify { fd })
16603 -+ }
16604 -+
16605 -+ /// Adds a new watch on the target file or directory.
16606 -+ ///
16607 -+ /// Returns a watch descriptor. This is not a File Descriptor!
16608 -+ ///
16609 -+ /// For more information see, [inotify_add_watch(2)](http://man7.org/linux/man-pages/man2/inotify_add_watch.2.html).
16610 -+ pub fn add_watch<P: ?Sized + NixPath>(&self,
16611 -+ path: &P,
16612 -+ mask: AddWatchFlags)
16613 -+ -> Result<WatchDescriptor>
16614 -+ {
16615 -+ let res = path.with_nix_path(|cstr| {
16616 -+ unsafe {
16617 -+ libc::inotify_add_watch(self.fd, cstr.as_ptr(), mask.bits())
16618 -+ }
16619 -+ })?;
16620 -+
16621 -+ Errno::result(res).map(|wd| WatchDescriptor { wd })
16622 -+ }
16623 -+
16624 -+ /// Removes an existing watch using the watch descriptor returned by
16625 -+ /// inotify_add_watch.
16626 -+ ///
16627 -+ /// Returns an EINVAL error if the watch descriptor is invalid.
16628 -+ ///
16629 -+ /// For more information see, [inotify_rm_watch(2)](http://man7.org/linux/man-pages/man2/inotify_rm_watch.2.html).
16630 -+ #[cfg(target_os = "linux")]
16631 -+ pub fn rm_watch(&self, wd: WatchDescriptor) -> Result<()> {
16632 -+ let res = unsafe { libc::inotify_rm_watch(self.fd, wd.wd) };
16633 -+
16634 -+ Errno::result(res).map(drop)
16635 -+ }
16636 -+
16637 -+ #[cfg(target_os = "android")]
16638 -+ pub fn rm_watch(&self, wd: WatchDescriptor) -> Result<()> {
16639 -+ let res = unsafe { libc::inotify_rm_watch(self.fd, wd.wd as u32) };
16640 -+
16641 -+ Errno::result(res).map(drop)
16642 -+ }
16643 -+
16644 -+ /// Reads a collection of events from the inotify file descriptor. This call
16645 -+ /// can either be blocking or non blocking depending on whether IN_NONBLOCK
16646 -+ /// was set at initialization.
16647 -+ ///
16648 -+ /// Returns as many events as available. If the call was non blocking and no
16649 -+ /// events could be read then the EAGAIN error is returned.
16650 -+ pub fn read_events(&self) -> Result<Vec<InotifyEvent>> {
16651 -+ let header_size = size_of::<libc::inotify_event>();
16652 -+ let mut buffer = [0u8; 4096];
16653 -+ let mut events = Vec::new();
16654 -+ let mut offset = 0;
16655 -+
16656 -+ let nread = read(self.fd, &mut buffer)?;
16657 -+
16658 -+ while (nread - offset) >= header_size {
16659 -+ let event = unsafe {
16660 -+ &*(
16661 -+ buffer
16662 -+ .as_ptr()
16663 -+ .offset(offset as isize) as *const libc::inotify_event
16664 -+ )
16665 -+ };
16666 -+
16667 -+ let name = match event.len {
16668 -+ 0 => None,
16669 -+ _ => {
16670 -+ let ptr = unsafe {
16671 -+ buffer
16672 -+ .as_ptr()
16673 -+ .offset(offset as isize + header_size as isize)
16674 -+ as *const c_char
16675 -+ };
16676 -+ let cstr = unsafe { CStr::from_ptr(ptr) };
16677 -+
16678 -+ Some(OsStr::from_bytes(cstr.to_bytes()).to_owned())
16679 -+ }
16680 -+ };
16681 -+
16682 -+ events.push(InotifyEvent {
16683 -+ wd: WatchDescriptor { wd: event.wd },
16684 -+ mask: AddWatchFlags::from_bits_truncate(event.mask),
16685 -+ cookie: event.cookie,
16686 -+ name
16687 -+ });
16688 -+
16689 -+ offset += header_size + event.len as usize;
16690 -+ }
16691 -+
16692 -+ Ok(events)
16693 -+ }
16694 -+}
16695 -+
16696 -+impl AsRawFd for Inotify {
16697 -+ fn as_raw_fd(&self) -> RawFd {
16698 -+ self.fd
16699 -+ }
16700 -+}
16701 -+
16702 -+impl FromRawFd for Inotify {
16703 -+ unsafe fn from_raw_fd(fd: RawFd) -> Self {
16704 -+ Inotify { fd }
16705 -+ }
16706 -+}
16707 -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
16708 -new file mode 100644
16709 -index 0000000000000..9b8b0ff1a155f
16710 ---- /dev/null
16711 -+++ b/third_party/rust/nix-0.15.0/src/sys/ioctl/bsd.rs
16712 -@@ -0,0 +1,102 @@
16713 -+/// The datatype used for the ioctl number
16714 -+#[doc(hidden)]
16715 -+pub type ioctl_num_type = ::libc::c_ulong;
16716 -+/// The datatype used for the 3rd argument
16717 -+#[doc(hidden)]
16718 -+pub type ioctl_param_type = ::libc::c_int;
16719 -+
16720 -+mod consts {
16721 -+ use ::sys::ioctl::ioctl_num_type;
16722 -+ #[doc(hidden)]
16723 -+ pub const VOID: ioctl_num_type = 0x2000_0000;
16724 -+ #[doc(hidden)]
16725 -+ pub const OUT: ioctl_num_type = 0x4000_0000;
16726 -+ #[doc(hidden)]
16727 -+ pub const IN: ioctl_num_type = 0x8000_0000;
16728 -+ #[doc(hidden)]
16729 -+ pub const INOUT: ioctl_num_type = (IN|OUT);
16730 -+ #[doc(hidden)]
16731 -+ pub const IOCPARM_MASK: ioctl_num_type = 0x1fff;
16732 -+}
16733 -+
16734 -+pub use self::consts::*;
16735 -+
16736 -+#[macro_export]
16737 -+#[doc(hidden)]
16738 -+macro_rules! ioc {
16739 -+ ($inout:expr, $group:expr, $num:expr, $len:expr) => (
16740 -+ $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)
16741 -+ )
16742 -+}
16743 -+
16744 -+/// Generate an ioctl request code for a command that passes no data.
16745 -+///
16746 -+/// This is equivalent to the `_IO()` macro exposed by the C ioctl API.
16747 -+///
16748 -+/// You should only use this macro directly if the `ioctl` you're working
16749 -+/// with is "bad" and you cannot use `ioctl_none!()` directly.
16750 -+///
16751 -+/// # Example
16752 -+///
16753 -+/// ```
16754 -+/// # #[macro_use] extern crate nix;
16755 -+/// const KVMIO: u8 = 0xAE;
16756 -+/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
16757 -+/// # fn main() {}
16758 -+/// ```
16759 -+#[macro_export(local_inner_macros)]
16760 -+macro_rules! request_code_none {
16761 -+ ($g:expr, $n:expr) => (ioc!($crate::sys::ioctl::VOID, $g, $n, 0))
16762 -+}
16763 -+
16764 -+/// Generate an ioctl request code for a command that passes an integer
16765 -+///
16766 -+/// This is equivalent to the `_IOWINT()` macro exposed by the C ioctl API.
16767 -+///
16768 -+/// You should only use this macro directly if the `ioctl` you're working
16769 -+/// with is "bad" and you cannot use `ioctl_write_int!()` directly.
16770 -+#[macro_export(local_inner_macros)]
16771 -+macro_rules! request_code_write_int {
16772 -+ ($g:expr, $n:expr) => (ioc!($crate::sys::ioctl::VOID, $g, $n, ::std::mem::size_of::<$crate::libc::c_int>()))
16773 -+}
16774 -+
16775 -+/// Generate an ioctl request code for a command that reads.
16776 -+///
16777 -+/// This is equivalent to the `_IOR()` macro exposed by the C ioctl API.
16778 -+///
16779 -+/// You should only use this macro directly if the `ioctl` you're working
16780 -+/// with is "bad" and you cannot use `ioctl_read!()` directly.
16781 -+///
16782 -+/// The read/write direction is relative to userland, so this
16783 -+/// command would be userland is reading and the kernel is
16784 -+/// writing.
16785 -+#[macro_export(local_inner_macros)]
16786 -+macro_rules! request_code_read {
16787 -+ ($g:expr, $n:expr, $len:expr) => (ioc!($crate::sys::ioctl::OUT, $g, $n, $len))
16788 -+}
16789 -+
16790 -+/// Generate an ioctl request code for a command that writes.
16791 -+///
16792 -+/// This is equivalent to the `_IOW()` macro exposed by the C ioctl API.
16793 -+///
16794 -+/// You should only use this macro directly if the `ioctl` you're working
16795 -+/// with is "bad" and you cannot use `ioctl_write!()` directly.
16796 -+///
16797 -+/// The read/write direction is relative to userland, so this
16798 -+/// command would be userland is writing and the kernel is
16799 -+/// reading.
16800 -+#[macro_export(local_inner_macros)]
16801 -+macro_rules! request_code_write {
16802 -+ ($g:expr, $n:expr, $len:expr) => (ioc!($crate::sys::ioctl::IN, $g, $n, $len))
16803 -+}
16804 -+
16805 -+/// Generate an ioctl request code for a command that reads and writes.
16806 -+///
16807 -+/// This is equivalent to the `_IOWR()` macro exposed by the C ioctl API.
16808 -+///
16809 -+/// You should only use this macro directly if the `ioctl` you're working
16810 -+/// with is "bad" and you cannot use `ioctl_readwrite!()` directly.
16811 -+#[macro_export(local_inner_macros)]
16812 -+macro_rules! request_code_readwrite {
16813 -+ ($g:expr, $n:expr, $len:expr) => (ioc!($crate::sys::ioctl::INOUT, $g, $n, $len))
16814 -+}
16815 -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
16816 -new file mode 100644
16817 -index 0000000000000..9cdac72a4b80b
16818 ---- /dev/null
16819 -+++ b/third_party/rust/nix-0.15.0/src/sys/ioctl/linux.rs
16820 -@@ -0,0 +1,140 @@
16821 -+/// The datatype used for the ioctl number
16822 -+#[cfg(any(target_os = "android", target_env = "musl"))]
16823 -+#[doc(hidden)]
16824 -+pub type ioctl_num_type = ::libc::c_int;
16825 -+#[cfg(not(any(target_os = "android", target_env = "musl")))]
16826 -+#[doc(hidden)]
16827 -+pub type ioctl_num_type = ::libc::c_ulong;
16828 -+/// The datatype used for the 3rd argument
16829 -+#[doc(hidden)]
16830 -+pub type ioctl_param_type = ::libc::c_ulong;
16831 -+
16832 -+#[doc(hidden)]
16833 -+pub const NRBITS: ioctl_num_type = 8;
16834 -+#[doc(hidden)]
16835 -+pub const TYPEBITS: ioctl_num_type = 8;
16836 -+
16837 -+#[cfg(any(target_arch = "mips", target_arch = "mips64", target_arch = "powerpc", target_arch = "powerpc64", target_arch = "sparc64"))]
16838 -+mod consts {
16839 -+ #[doc(hidden)]
16840 -+ pub const NONE: u8 = 1;
16841 -+ #[doc(hidden)]
16842 -+ pub const READ: u8 = 2;
16843 -+ #[doc(hidden)]
16844 -+ pub const WRITE: u8 = 4;
16845 -+ #[doc(hidden)]
16846 -+ pub const SIZEBITS: u8 = 13;
16847 -+ #[doc(hidden)]
16848 -+ pub const DIRBITS: u8 = 3;
16849 -+}
16850 -+
16851 -+// "Generic" ioctl protocol
16852 -+#[cfg(any(target_arch = "x86",
16853 -+ target_arch = "arm",
16854 -+ target_arch = "s390x",
16855 -+ target_arch = "x86_64",
16856 -+ target_arch = "aarch64"))]
16857 -+mod consts {
16858 -+ #[doc(hidden)]
16859 -+ pub const NONE: u8 = 0;
16860 -+ #[doc(hidden)]
16861 -+ pub const READ: u8 = 2;
16862 -+ #[doc(hidden)]
16863 -+ pub const WRITE: u8 = 1;
16864 -+ #[doc(hidden)]
16865 -+ pub const SIZEBITS: u8 = 14;
16866 -+ #[doc(hidden)]
16867 -+ pub const DIRBITS: u8 = 2;
16868 -+}
16869 -+
16870 -+pub use self::consts::*;
16871 -+
16872 -+#[doc(hidden)]
16873 -+pub const NRSHIFT: ioctl_num_type = 0;
16874 -+#[doc(hidden)]
16875 -+pub const TYPESHIFT: ioctl_num_type = NRSHIFT + NRBITS as ioctl_num_type;
16876 -+#[doc(hidden)]
16877 -+pub const SIZESHIFT: ioctl_num_type = TYPESHIFT + TYPEBITS as ioctl_num_type;
16878 -+#[doc(hidden)]
16879 -+pub const DIRSHIFT: ioctl_num_type = SIZESHIFT + SIZEBITS as ioctl_num_type;
16880 -+
16881 -+#[doc(hidden)]
16882 -+pub const NRMASK: ioctl_num_type = (1 << NRBITS) - 1;
16883 -+#[doc(hidden)]
16884 -+pub const TYPEMASK: ioctl_num_type = (1 << TYPEBITS) - 1;
16885 -+#[doc(hidden)]
16886 -+pub const SIZEMASK: ioctl_num_type = (1 << SIZEBITS) - 1;
16887 -+#[doc(hidden)]
16888 -+pub const DIRMASK: ioctl_num_type = (1 << DIRBITS) - 1;
16889 -+
16890 -+/// Encode an ioctl command.
16891 -+#[macro_export]
16892 -+#[doc(hidden)]
16893 -+macro_rules! ioc {
16894 -+ ($dir:expr, $ty:expr, $nr:expr, $sz:expr) => (
16895 -+ (($dir as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::DIRMASK) << $crate::sys::ioctl::DIRSHIFT) |
16896 -+ (($ty as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::TYPEMASK) << $crate::sys::ioctl::TYPESHIFT) |
16897 -+ (($nr as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::NRMASK) << $crate::sys::ioctl::NRSHIFT) |
16898 -+ (($sz as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::SIZEMASK) << $crate::sys::ioctl::SIZESHIFT))
16899 -+}
16900 -+
16901 -+/// Generate an ioctl request code for a command that passes no data.
16902 -+///
16903 -+/// This is equivalent to the `_IO()` macro exposed by the C ioctl API.
16904 -+///
16905 -+/// You should only use this macro directly if the `ioctl` you're working
16906 -+/// with is "bad" and you cannot use `ioctl_none!()` directly.
16907 -+///
16908 -+/// # Example
16909 -+///
16910 -+/// ```
16911 -+/// # #[macro_use] extern crate nix;
16912 -+/// const KVMIO: u8 = 0xAE;
16913 -+/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
16914 -+/// # fn main() {}
16915 -+/// ```
16916 -+#[macro_export(local_inner_macros)]
16917 -+macro_rules! request_code_none {
16918 -+ ($ty:expr, $nr:expr) => (ioc!($crate::sys::ioctl::NONE, $ty, $nr, 0))
16919 -+}
16920 -+
16921 -+/// Generate an ioctl request code for a command that reads.
16922 -+///
16923 -+/// This is equivalent to the `_IOR()` macro exposed by the C ioctl API.
16924 -+///
16925 -+/// You should only use this macro directly if the `ioctl` you're working
16926 -+/// with is "bad" and you cannot use `ioctl_read!()` directly.
16927 -+///
16928 -+/// The read/write direction is relative to userland, so this
16929 -+/// command would be userland is reading and the kernel is
16930 -+/// writing.
16931 -+#[macro_export(local_inner_macros)]
16932 -+macro_rules! request_code_read {
16933 -+ ($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::READ, $ty, $nr, $sz))
16934 -+}
16935 -+
16936 -+/// Generate an ioctl request code for a command that writes.
16937 -+///
16938 -+/// This is equivalent to the `_IOW()` macro exposed by the C ioctl API.
16939 -+///
16940 -+/// You should only use this macro directly if the `ioctl` you're working
16941 -+/// with is "bad" and you cannot use `ioctl_write!()` directly.
16942 -+///
16943 -+/// The read/write direction is relative to userland, so this
16944 -+/// command would be userland is writing and the kernel is
16945 -+/// reading.
16946 -+#[macro_export(local_inner_macros)]
16947 -+macro_rules! request_code_write {
16948 -+ ($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::WRITE, $ty, $nr, $sz))
16949 -+}
16950 -+
16951 -+/// Generate an ioctl request code for a command that reads and writes.
16952 -+///
16953 -+/// This is equivalent to the `_IOWR()` macro exposed by the C ioctl API.
16954 -+///
16955 -+/// You should only use this macro directly if the `ioctl` you're working
16956 -+/// with is "bad" and you cannot use `ioctl_readwrite!()` directly.
16957 -+#[macro_export(local_inner_macros)]
16958 -+macro_rules! request_code_readwrite {
16959 -+ ($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::READ | $crate::sys::ioctl::WRITE, $ty, $nr, $sz))
16960 -+}
16961 -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
16962 -new file mode 100644
16963 -index 0000000000000..4513bf877434a
16964 ---- /dev/null
16965 -+++ b/third_party/rust/nix-0.15.0/src/sys/ioctl/mod.rs
16966 -@@ -0,0 +1,778 @@
16967 -+//! Provide helpers for making ioctl system calls.
16968 -+//!
16969 -+//! This library is pretty low-level and messy. `ioctl` is not fun.
16970 -+//!
16971 -+//! What is an `ioctl`?
16972 -+//! ===================
16973 -+//!
16974 -+//! The `ioctl` syscall is the grab-bag syscall on POSIX systems. Don't want to add a new
16975 -+//! syscall? Make it an `ioctl`! `ioctl` refers to both the syscall, and the commands that can be
16976 -+//! sent with it. `ioctl` stands for "IO control", and the commands are always sent to a file
16977 -+//! descriptor.
16978 -+//!
16979 -+//! It is common to see `ioctl`s used for the following purposes:
16980 -+//!
16981 -+//! * Provide read/write access to out-of-band data related to a device such as configuration
16982 -+//! (for instance, setting serial port options)
16983 -+//! * Provide a mechanism for performing full-duplex data transfers (for instance, xfer on SPI
16984 -+//! devices).
16985 -+//! * Provide access to control functions on a device (for example, on Linux you can send
16986 -+//! commands like pause, resume, and eject to the CDROM device.
16987 -+//! * Do whatever else the device driver creator thought made most sense.
16988 -+//!
16989 -+//! `ioctl`s are synchronous system calls and are similar to read and write calls in that regard.
16990 -+//! They operate on file descriptors and have an identifier that specifies what the ioctl is.
16991 -+//! Additionally they may read or write data and therefore need to pass along a data pointer.
16992 -+//! Besides the semantics of the ioctls being confusing, the generation of this identifer can also
16993 -+//! be difficult.
16994 -+//!
16995 -+//! Historically `ioctl` numbers were arbitrary hard-coded values. In Linux (before 2.6) and some
16996 -+//! unices this has changed to a more-ordered system where the ioctl numbers are partitioned into
16997 -+//! subcomponents (For linux this is documented in
16998 -+//! [`Documentation/ioctl/ioctl-number.txt`](http://elixir.free-electrons.com/linux/latest/source/Documentation/ioctl/ioctl-number.txt)):
16999 -+//!
17000 -+//! * Number: The actual ioctl ID
17001 -+//! * Type: A grouping of ioctls for a common purpose or driver
17002 -+//! * Size: The size in bytes of the data that will be transferred
17003 -+//! * Direction: Whether there is any data and if it's read, write, or both
17004 -+//!
17005 -+//! Newer drivers should not generate complete integer identifiers for their `ioctl`s instead
17006 -+//! preferring to use the 4 components above to generate the final ioctl identifier. Because of
17007 -+//! how old `ioctl`s are, however, there are many hard-coded `ioctl` identifiers. These are
17008 -+//! commonly referred to as "bad" in `ioctl` documentation.
17009 -+//!
17010 -+//! Defining `ioctl`s
17011 -+//! =================
17012 -+//!
17013 -+//! This library provides several `ioctl_*!` macros for binding `ioctl`s. These generate public
17014 -+//! unsafe functions that can then be used for calling the ioctl. This macro has a few different
17015 -+//! ways it can be used depending on the specific ioctl you're working with.
17016 -+//!
17017 -+//! A simple `ioctl` is `SPI_IOC_RD_MODE`. This ioctl works with the SPI interface on Linux. This
17018 -+//! specific `ioctl` reads the mode of the SPI device as a `u8`. It's declared in
17019 -+//! `/include/uapi/linux/spi/spidev.h` as `_IOR(SPI_IOC_MAGIC, 1, __u8)`. Since it uses the `_IOR`
17020 -+//! macro, we know it's a `read` ioctl and can use the `ioctl_read!` macro as follows:
17021 -+//!
17022 -+//! ```
17023 -+//! # #[macro_use] extern crate nix;
17024 -+//! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
17025 -+//! const SPI_IOC_TYPE_MODE: u8 = 1;
17026 -+//! ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8);
17027 -+//! # fn main() {}
17028 -+//! ```
17029 -+//!
17030 -+//! This generates the function:
17031 -+//!
17032 -+//! ```
17033 -+//! # #[macro_use] extern crate nix;
17034 -+//! # use std::mem;
17035 -+//! # use nix::{libc, Result};
17036 -+//! # use nix::errno::Errno;
17037 -+//! # use nix::libc::c_int as c_int;
17038 -+//! # const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
17039 -+//! # const SPI_IOC_TYPE_MODE: u8 = 1;
17040 -+//! pub unsafe fn spi_read_mode(fd: c_int, data: *mut u8) -> Result<c_int> {
17041 -+//! let res = libc::ioctl(fd, request_code_read!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, mem::size_of::<u8>()), data);
17042 -+//! Errno::result(res)
17043 -+//! }
17044 -+//! # fn main() {}
17045 -+//! ```
17046 -+//!
17047 -+//! The return value for the wrapper functions generated by the `ioctl_*!` macros are `nix::Error`s.
17048 -+//! These are generated by assuming the return value of the ioctl is `-1` on error and everything
17049 -+//! else is a valid return value. If this is not the case, `Result::map` can be used to map some
17050 -+//! of the range of "good" values (-Inf..-2, 0..Inf) into a smaller range in a helper function.
17051 -+//!
17052 -+//! Writing `ioctl`s generally use pointers as their data source and these should use the
17053 -+//! `ioctl_write_ptr!`. But in some cases an `int` is passed directly. For these `ioctl`s use the
17054 -+//! `ioctl_write_int!` macro. This variant does not take a type as the last argument:
17055 -+//!
17056 -+//! ```
17057 -+//! # #[macro_use] extern crate nix;
17058 -+//! const HCI_IOC_MAGIC: u8 = b'k';
17059 -+//! const HCI_IOC_HCIDEVUP: u8 = 1;
17060 -+//! ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
17061 -+//! # fn main() {}
17062 -+//! ```
17063 -+//!
17064 -+//! Some `ioctl`s don't transfer any data, and those should use `ioctl_none!`. This macro
17065 -+//! doesn't take a type and so it is declared similar to the `write_int` variant shown above.
17066 -+//!
17067 -+//! The mode for a given `ioctl` should be clear from the documentation if it has good
17068 -+//! documentation. Otherwise it will be clear based on the macro used to generate the `ioctl`
17069 -+//! number where `_IO`, `_IOR`, `_IOW`, and `_IOWR` map to "none", "read", "write_*", and "readwrite"
17070 -+//! respectively. To determine the specific `write_` variant to use you'll need to find
17071 -+//! what the argument type is supposed to be. If it's an `int`, then `write_int` should be used,
17072 -+//! otherwise it should be a pointer and `write_ptr` should be used. On Linux the
17073 -+//! [`ioctl_list` man page](http://man7.org/linux/man-pages/man2/ioctl_list.2.html) describes a
17074 -+//! large number of `ioctl`s and describes their argument data type.
17075 -+//!
17076 -+//! Using "bad" `ioctl`s
17077 -+//! --------------------
17078 -+//!
17079 -+//! As mentioned earlier, there are many old `ioctl`s that do not use the newer method of
17080 -+//! generating `ioctl` numbers and instead use hardcoded values. These can be used with the
17081 -+//! `ioctl_*_bad!` macros. This naming comes from the Linux kernel which refers to these
17082 -+//! `ioctl`s as "bad". These are a different variant as they bypass calling the macro that generates
17083 -+//! the ioctl number and instead use the defined value directly.
17084 -+//!
17085 -+//! For example the `TCGETS` `ioctl` reads a `termios` data structure for a given file descriptor.
17086 -+//! It's defined as `0x5401` in `ioctls.h` on Linux and can be implemented as:
17087 -+//!
17088 -+//! ```
17089 -+//! # #[macro_use] extern crate nix;
17090 -+//! # #[cfg(any(target_os = "android", target_os = "linux"))]
17091 -+//! # use nix::libc::TCGETS as TCGETS;
17092 -+//! # #[cfg(any(target_os = "android", target_os = "linux"))]
17093 -+//! # use nix::libc::termios as termios;
17094 -+//! # #[cfg(any(target_os = "android", target_os = "linux"))]
17095 -+//! ioctl_read_bad!(tcgets, TCGETS, termios);
17096 -+//! # fn main() {}
17097 -+//! ```
17098 -+//!
17099 -+//! The generated function has the same form as that generated by `ioctl_read!`:
17100 -+//!
17101 -+//! ```text
17102 -+//! pub unsafe fn tcgets(fd: c_int, data: *mut termios) -> Result<c_int>;
17103 -+//! ```
17104 -+//!
17105 -+//! Working with Arrays
17106 -+//! -------------------
17107 -+//!
17108 -+//! Some `ioctl`s work with entire arrays of elements. These are supported by the `ioctl_*_buf`
17109 -+//! family of macros: `ioctl_read_buf`, `ioctl_write_buf`, and `ioctl_readwrite_buf`. Note that
17110 -+//! there are no "bad" versions for working with buffers. The generated functions include a `len`
17111 -+//! argument to specify the number of elements (where the type of each element is specified in the
17112 -+//! macro).
17113 -+//!
17114 -+//! Again looking to the SPI `ioctl`s on Linux for an example, there is a `SPI_IOC_MESSAGE` `ioctl`
17115 -+//! that queues up multiple SPI messages by writing an entire array of `spi_ioc_transfer` structs.
17116 -+//! `linux/spi/spidev.h` defines a macro to calculate the `ioctl` number like:
17117 -+//!
17118 -+//! ```C
17119 -+//! #define SPI_IOC_MAGIC 'k'
17120 -+//! #define SPI_MSGSIZE(N) ...
17121 -+//! #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)])
17122 -+//! ```
17123 -+//!
17124 -+//! The `SPI_MSGSIZE(N)` calculation is already handled by the `ioctl_*!` macros, so all that's
17125 -+//! needed to define this `ioctl` is:
17126 -+//!
17127 -+//! ```
17128 -+//! # #[macro_use] extern crate nix;
17129 -+//! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
17130 -+//! const SPI_IOC_TYPE_MESSAGE: u8 = 0;
17131 -+//! # pub struct spi_ioc_transfer(u64);
17132 -+//! ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer);
17133 -+//! # fn main() {}
17134 -+//! ```
17135 -+//!
17136 -+//! This generates a function like:
17137 -+//!
17138 -+//! ```
17139 -+//! # #[macro_use] extern crate nix;
17140 -+//! # use std::mem;
17141 -+//! # use nix::{libc, Result};
17142 -+//! # use nix::errno::Errno;
17143 -+//! # use nix::libc::c_int as c_int;
17144 -+//! # const SPI_IOC_MAGIC: u8 = b'k';
17145 -+//! # const SPI_IOC_TYPE_MESSAGE: u8 = 0;
17146 -+//! # pub struct spi_ioc_transfer(u64);
17147 -+//! pub unsafe fn spi_message(fd: c_int, data: &mut [spi_ioc_transfer]) -> Result<c_int> {
17148 -+//! let res = libc::ioctl(fd,
17149 -+//! request_code_write!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, data.len() * mem::size_of::<spi_ioc_transfer>()),
17150 -+//! data);
17151 -+//! Errno::result(res)
17152 -+//! }
17153 -+//! # fn main() {}
17154 -+//! ```
17155 -+//!
17156 -+//! Finding `ioctl` Documentation
17157 -+//! -----------------------------
17158 -+//!
17159 -+//! For Linux, look at your system's headers. For example, `/usr/include/linux/input.h` has a lot
17160 -+//! of lines defining macros which use `_IO`, `_IOR`, `_IOW`, `_IOC`, and `_IOWR`. Some `ioctl`s are
17161 -+//! documented directly in the headers defining their constants, but others have more extensive
17162 -+//! documentation in man pages (like termios' `ioctl`s which are in `tty_ioctl(4)`).
17163 -+//!
17164 -+//! Documenting the Generated Functions
17165 -+//! ===================================
17166 -+//!
17167 -+//! In many cases, users will wish for the functions generated by the `ioctl`
17168 -+//! macro to be public and documented. For this reason, the generated functions
17169 -+//! are public by default. If you wish to hide the ioctl, you will need to put
17170 -+//! them in a private module.
17171 -+//!
17172 -+//! For documentation, it is possible to use doc comments inside the `ioctl_*!` macros. Here is an
17173 -+//! example :
17174 -+//!
17175 -+//! ```
17176 -+//! # #[macro_use] extern crate nix;
17177 -+//! # use nix::libc::c_int;
17178 -+//! ioctl_read! {
17179 -+//! /// Make the given terminal the controlling terminal of the calling process. The calling
17180 -+//! /// process must be a session leader and not have a controlling terminal already. If the
17181 -+//! /// terminal is already the controlling terminal of a different session group then the
17182 -+//! /// ioctl will fail with **EPERM**, unless the caller is root (more precisely: has the
17183 -+//! /// **CAP_SYS_ADMIN** capability) and arg equals 1, in which case the terminal is stolen
17184 -+//! /// and all processes that had it as controlling terminal lose it.
17185 -+//! tiocsctty, b't', 19, c_int
17186 -+//! }
17187 -+//!
17188 -+//! # fn main() {}
17189 -+//! ```
17190 -+#[cfg(any(target_os = "android", target_os = "linux"))]
17191 -+#[macro_use]
17192 -+mod linux;
17193 -+
17194 -+#[cfg(any(target_os = "android", target_os = "linux"))]
17195 -+pub use self::linux::*;
17196 -+
17197 -+#[cfg(any(target_os = "dragonfly",
17198 -+ target_os = "freebsd",
17199 -+ target_os = "ios",
17200 -+ target_os = "macos",
17201 -+ target_os = "netbsd",
17202 -+ target_os = "openbsd"))]
17203 -+#[macro_use]
17204 -+mod bsd;
17205 -+
17206 -+#[cfg(any(target_os = "dragonfly",
17207 -+ target_os = "freebsd",
17208 -+ target_os = "ios",
17209 -+ target_os = "macos",
17210 -+ target_os = "netbsd",
17211 -+ target_os = "openbsd"))]
17212 -+pub use self::bsd::*;
17213 -+
17214 -+/// Convert raw ioctl return value to a Nix result
17215 -+#[macro_export]
17216 -+#[doc(hidden)]
17217 -+macro_rules! convert_ioctl_res {
17218 -+ ($w:expr) => (
17219 -+ {
17220 -+ $crate::errno::Errno::result($w)
17221 -+ }
17222 -+ );
17223 -+}
17224 -+
17225 -+/// Generates a wrapper function for an ioctl that passes no data to the kernel.
17226 -+///
17227 -+/// The arguments to this macro are:
17228 -+///
17229 -+/// * The function name
17230 -+/// * The ioctl identifier
17231 -+/// * The ioctl sequence number
17232 -+///
17233 -+/// The generated function has the following signature:
17234 -+///
17235 -+/// ```rust,ignore
17236 -+/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int>
17237 -+/// ```
17238 -+///
17239 -+/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
17240 -+///
17241 -+/// # Example
17242 -+///
17243 -+/// The `videodev2` driver on Linux defines the `log_status` `ioctl` as:
17244 -+///
17245 -+/// ```C
17246 -+/// #define VIDIOC_LOG_STATUS _IO('V', 70)
17247 -+/// ```
17248 -+///
17249 -+/// This can be implemented in Rust like:
17250 -+///
17251 -+/// ```no_run
17252 -+/// # #[macro_use] extern crate nix;
17253 -+/// ioctl_none!(log_status, b'V', 70);
17254 -+/// fn main() {}
17255 -+/// ```
17256 -+#[macro_export(local_inner_macros)]
17257 -+macro_rules! ioctl_none {
17258 -+ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
17259 -+ $(#[$attr])*
17260 -+ pub unsafe fn $name(fd: $crate::libc::c_int)
17261 -+ -> $crate::Result<$crate::libc::c_int> {
17262 -+ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_none!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type))
17263 -+ }
17264 -+ )
17265 -+}
17266 -+
17267 -+/// Generates a wrapper function for a "bad" ioctl that passes no data to the kernel.
17268 -+///
17269 -+/// The arguments to this macro are:
17270 -+///
17271 -+/// * The function name
17272 -+/// * The ioctl request code
17273 -+///
17274 -+/// The generated function has the following signature:
17275 -+///
17276 -+/// ```rust,ignore
17277 -+/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int>
17278 -+/// ```
17279 -+///
17280 -+/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
17281 -+///
17282 -+/// # Example
17283 -+///
17284 -+/// ```no_run
17285 -+/// # #[macro_use] extern crate nix;
17286 -+/// # extern crate libc;
17287 -+/// # use libc::TIOCNXCL;
17288 -+/// # use std::fs::File;
17289 -+/// # use std::os::unix::io::AsRawFd;
17290 -+/// ioctl_none_bad!(tiocnxcl, TIOCNXCL);
17291 -+/// fn main() {
17292 -+/// let file = File::open("/dev/ttyUSB0").unwrap();
17293 -+/// unsafe { tiocnxcl(file.as_raw_fd()) }.unwrap();
17294 -+/// }
17295 -+/// ```
17296 -+// TODO: add an example using request_code_*!()
17297 -+#[macro_export(local_inner_macros)]
17298 -+macro_rules! ioctl_none_bad {
17299 -+ ($(#[$attr:meta])* $name:ident, $nr:expr) => (
17300 -+ $(#[$attr])*
17301 -+ pub unsafe fn $name(fd: $crate::libc::c_int)
17302 -+ -> $crate::Result<$crate::libc::c_int> {
17303 -+ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type))
17304 -+ }
17305 -+ )
17306 -+}
17307 -+
17308 -+/// Generates a wrapper function for an ioctl that reads data from the kernel.
17309 -+///
17310 -+/// The arguments to this macro are:
17311 -+///
17312 -+/// * The function name
17313 -+/// * The ioctl identifier
17314 -+/// * The ioctl sequence number
17315 -+/// * The data type passed by this ioctl
17316 -+///
17317 -+/// The generated function has the following signature:
17318 -+///
17319 -+/// ```rust,ignore
17320 -+/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
17321 -+/// ```
17322 -+///
17323 -+/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
17324 -+///
17325 -+/// # Example
17326 -+///
17327 -+/// ```
17328 -+/// # #[macro_use] extern crate nix;
17329 -+/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
17330 -+/// const SPI_IOC_TYPE_MODE: u8 = 1;
17331 -+/// ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8);
17332 -+/// # fn main() {}
17333 -+/// ```
17334 -+#[macro_export(local_inner_macros)]
17335 -+macro_rules! ioctl_read {
17336 -+ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
17337 -+ $(#[$attr])*
17338 -+ pub unsafe fn $name(fd: $crate::libc::c_int,
17339 -+ data: *mut $ty)
17340 -+ -> $crate::Result<$crate::libc::c_int> {
17341 -+ 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))
17342 -+ }
17343 -+ )
17344 -+}
17345 -+
17346 -+/// Generates a wrapper function for a "bad" ioctl that reads data from the kernel.
17347 -+///
17348 -+/// The arguments to this macro are:
17349 -+///
17350 -+/// * The function name
17351 -+/// * The ioctl request code
17352 -+/// * The data type passed by this ioctl
17353 -+///
17354 -+/// The generated function has the following signature:
17355 -+///
17356 -+/// ```rust,ignore
17357 -+/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
17358 -+/// ```
17359 -+///
17360 -+/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
17361 -+///
17362 -+/// # Example
17363 -+///
17364 -+/// ```
17365 -+/// # extern crate libc;
17366 -+/// # #[macro_use] extern crate nix;
17367 -+/// # #[cfg(any(target_os = "android", target_os = "linux"))]
17368 -+/// ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios);
17369 -+/// # fn main() {}
17370 -+/// ```
17371 -+#[macro_export(local_inner_macros)]
17372 -+macro_rules! ioctl_read_bad {
17373 -+ ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
17374 -+ $(#[$attr])*
17375 -+ pub unsafe fn $name(fd: $crate::libc::c_int,
17376 -+ data: *mut $ty)
17377 -+ -> $crate::Result<$crate::libc::c_int> {
17378 -+ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
17379 -+ }
17380 -+ )
17381 -+}
17382 -+
17383 -+/// Generates a wrapper function for an ioctl that writes data through a pointer to the kernel.
17384 -+///
17385 -+/// The arguments to this macro are:
17386 -+///
17387 -+/// * The function name
17388 -+/// * The ioctl identifier
17389 -+/// * The ioctl sequence number
17390 -+/// * The data type passed by this ioctl
17391 -+///
17392 -+/// The generated function has the following signature:
17393 -+///
17394 -+/// ```rust,ignore
17395 -+/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int>
17396 -+/// ```
17397 -+///
17398 -+/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
17399 -+///
17400 -+/// # Example
17401 -+///
17402 -+/// ```
17403 -+/// # #[macro_use] extern crate nix;
17404 -+/// # pub struct v4l2_audio {}
17405 -+/// ioctl_write_ptr!(s_audio, b'V', 34, v4l2_audio);
17406 -+/// # fn main() {}
17407 -+/// ```
17408 -+#[macro_export(local_inner_macros)]
17409 -+macro_rules! ioctl_write_ptr {
17410 -+ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
17411 -+ $(#[$attr])*
17412 -+ pub unsafe fn $name(fd: $crate::libc::c_int,
17413 -+ data: *const $ty)
17414 -+ -> $crate::Result<$crate::libc::c_int> {
17415 -+ 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))
17416 -+ }
17417 -+ )
17418 -+}
17419 -+
17420 -+/// Generates a wrapper function for a "bad" ioctl that writes data through a pointer to the kernel.
17421 -+///
17422 -+/// The arguments to this macro are:
17423 -+///
17424 -+/// * The function name
17425 -+/// * The ioctl request code
17426 -+/// * The data type passed by this ioctl
17427 -+///
17428 -+/// The generated function has the following signature:
17429 -+///
17430 -+/// ```rust,ignore
17431 -+/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int>
17432 -+/// ```
17433 -+///
17434 -+/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
17435 -+///
17436 -+/// # Example
17437 -+///
17438 -+/// ```
17439 -+/// # extern crate libc;
17440 -+/// # #[macro_use] extern crate nix;
17441 -+/// # #[cfg(any(target_os = "android", target_os = "linux"))]
17442 -+/// ioctl_write_ptr_bad!(tcsets, libc::TCSETS, libc::termios);
17443 -+/// # fn main() {}
17444 -+/// ```
17445 -+#[macro_export(local_inner_macros)]
17446 -+macro_rules! ioctl_write_ptr_bad {
17447 -+ ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
17448 -+ $(#[$attr])*
17449 -+ pub unsafe fn $name(fd: $crate::libc::c_int,
17450 -+ data: *const $ty)
17451 -+ -> $crate::Result<$crate::libc::c_int> {
17452 -+ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
17453 -+ }
17454 -+ )
17455 -+}
17456 -+
17457 -+cfg_if!{
17458 -+ if #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] {
17459 -+ /// Generates a wrapper function for a ioctl that writes an integer to the kernel.
17460 -+ ///
17461 -+ /// The arguments to this macro are:
17462 -+ ///
17463 -+ /// * The function name
17464 -+ /// * The ioctl identifier
17465 -+ /// * The ioctl sequence number
17466 -+ ///
17467 -+ /// The generated function has the following signature:
17468 -+ ///
17469 -+ /// ```rust,ignore
17470 -+ /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int>
17471 -+ /// ```
17472 -+ ///
17473 -+ /// `nix::sys::ioctl::ioctl_param_type` depends on the OS:
17474 -+ /// * BSD - `libc::c_int`
17475 -+ /// * Linux - `libc::c_ulong`
17476 -+ ///
17477 -+ /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
17478 -+ ///
17479 -+ /// # Example
17480 -+ ///
17481 -+ /// ```
17482 -+ /// # #[macro_use] extern crate nix;
17483 -+ /// ioctl_write_int!(vt_activate, b'v', 4);
17484 -+ /// # fn main() {}
17485 -+ /// ```
17486 -+ #[macro_export(local_inner_macros)]
17487 -+ macro_rules! ioctl_write_int {
17488 -+ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
17489 -+ $(#[$attr])*
17490 -+ pub unsafe fn $name(fd: $crate::libc::c_int,
17491 -+ data: $crate::sys::ioctl::ioctl_param_type)
17492 -+ -> $crate::Result<$crate::libc::c_int> {
17493 -+ convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write_int!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type, data))
17494 -+ }
17495 -+ )
17496 -+ }
17497 -+ } else {
17498 -+ /// Generates a wrapper function for a ioctl that writes an integer to the kernel.
17499 -+ ///
17500 -+ /// The arguments to this macro are:
17501 -+ ///
17502 -+ /// * The function name
17503 -+ /// * The ioctl identifier
17504 -+ /// * The ioctl sequence number
17505 -+ ///
17506 -+ /// The generated function has the following signature:
17507 -+ ///
17508 -+ /// ```rust,ignore
17509 -+ /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int>
17510 -+ /// ```
17511 -+ ///
17512 -+ /// `nix::sys::ioctl::ioctl_param_type` depends on the OS:
17513 -+ /// * BSD - `libc::c_int`
17514 -+ /// * Linux - `libc::c_ulong`
17515 -+ ///
17516 -+ /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
17517 -+ ///
17518 -+ /// # Example
17519 -+ ///
17520 -+ /// ```
17521 -+ /// # #[macro_use] extern crate nix;
17522 -+ /// const HCI_IOC_MAGIC: u8 = b'k';
17523 -+ /// const HCI_IOC_HCIDEVUP: u8 = 1;
17524 -+ /// ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
17525 -+ /// # fn main() {}
17526 -+ /// ```
17527 -+ #[macro_export(local_inner_macros)]
17528 -+ macro_rules! ioctl_write_int {
17529 -+ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
17530 -+ $(#[$attr])*
17531 -+ pub unsafe fn $name(fd: $crate::libc::c_int,
17532 -+ data: $crate::sys::ioctl::ioctl_param_type)
17533 -+ -> $crate::Result<$crate::libc::c_int> {
17534 -+ 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))
17535 -+ }
17536 -+ )
17537 -+ }
17538 -+ }
17539 -+}
17540 -+
17541 -+/// Generates a wrapper function for a "bad" ioctl that writes an integer to the kernel.
17542 -+///
17543 -+/// The arguments to this macro are:
17544 -+///
17545 -+/// * The function name
17546 -+/// * The ioctl request code
17547 -+///
17548 -+/// The generated function has the following signature:
17549 -+///
17550 -+/// ```rust,ignore
17551 -+/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: libc::c_int) -> Result<libc::c_int>
17552 -+/// ```
17553 -+///
17554 -+/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
17555 -+///
17556 -+/// # Examples
17557 -+///
17558 -+/// ```
17559 -+/// # extern crate libc;
17560 -+/// # #[macro_use] extern crate nix;
17561 -+/// # #[cfg(any(target_os = "android", target_os = "linux"))]
17562 -+/// ioctl_write_int_bad!(tcsbrk, libc::TCSBRK);
17563 -+/// # fn main() {}
17564 -+/// ```
17565 -+///
17566 -+/// ```rust
17567 -+/// # #[macro_use] extern crate nix;
17568 -+/// const KVMIO: u8 = 0xAE;
17569 -+/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
17570 -+/// # fn main() {}
17571 -+/// ```
17572 -+#[macro_export(local_inner_macros)]
17573 -+macro_rules! ioctl_write_int_bad {
17574 -+ ($(#[$attr:meta])* $name:ident, $nr:expr) => (
17575 -+ $(#[$attr])*
17576 -+ pub unsafe fn $name(fd: $crate::libc::c_int,
17577 -+ data: $crate::libc::c_int)
17578 -+ -> $crate::Result<$crate::libc::c_int> {
17579 -+ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
17580 -+ }
17581 -+ )
17582 -+}
17583 -+
17584 -+/// Generates a wrapper function for an ioctl that reads and writes data to the kernel.
17585 -+///
17586 -+/// The arguments to this macro are:
17587 -+///
17588 -+/// * The function name
17589 -+/// * The ioctl identifier
17590 -+/// * The ioctl sequence number
17591 -+/// * The data type passed by this ioctl
17592 -+///
17593 -+/// The generated function has the following signature:
17594 -+///
17595 -+/// ```rust,ignore
17596 -+/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
17597 -+/// ```
17598 -+///
17599 -+/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
17600 -+///
17601 -+/// # Example
17602 -+///
17603 -+/// ```
17604 -+/// # #[macro_use] extern crate nix;
17605 -+/// # pub struct v4l2_audio {}
17606 -+/// ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio);
17607 -+/// # fn main() {}
17608 -+/// ```
17609 -+#[macro_export(local_inner_macros)]
17610 -+macro_rules! ioctl_readwrite {
17611 -+ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
17612 -+ $(#[$attr])*
17613 -+ pub unsafe fn $name(fd: $crate::libc::c_int,
17614 -+ data: *mut $ty)
17615 -+ -> $crate::Result<$crate::libc::c_int> {
17616 -+ 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))
17617 -+ }
17618 -+ )
17619 -+}
17620 -+
17621 -+/// Generates a wrapper function for a "bad" ioctl that reads and writes data to the kernel.
17622 -+///
17623 -+/// The arguments to this macro are:
17624 -+///
17625 -+/// * The function name
17626 -+/// * The ioctl request code
17627 -+/// * The data type passed by this ioctl
17628 -+///
17629 -+/// The generated function has the following signature:
17630 -+///
17631 -+/// ```rust,ignore
17632 -+/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
17633 -+/// ```
17634 -+///
17635 -+/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
17636 -+// TODO: Find an example for ioctl_readwrite_bad
17637 -+#[macro_export(local_inner_macros)]
17638 -+macro_rules! ioctl_readwrite_bad {
17639 -+ ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
17640 -+ $(#[$attr])*
17641 -+ pub unsafe fn $name(fd: $crate::libc::c_int,
17642 -+ data: *mut $ty)
17643 -+ -> $crate::Result<$crate::libc::c_int> {
17644 -+ convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
17645 -+ }
17646 -+ )
17647 -+}
17648 -+
17649 -+/// Generates a wrapper function for an ioctl that reads an array of elements from the kernel.
17650 -+///
17651 -+/// The arguments to this macro are:
17652 -+///
17653 -+/// * The function name
17654 -+/// * The ioctl identifier
17655 -+/// * The ioctl sequence number
17656 -+/// * The data type passed by this ioctl
17657 -+///
17658 -+/// The generated function has the following signature:
17659 -+///
17660 -+/// ```rust,ignore
17661 -+/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int>
17662 -+/// ```
17663 -+///
17664 -+/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
17665 -+// TODO: Find an example for ioctl_read_buf
17666 -+#[macro_export(local_inner_macros)]
17667 -+macro_rules! ioctl_read_buf {
17668 -+ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
17669 -+ $(#[$attr])*
17670 -+ pub unsafe fn $name(fd: $crate::libc::c_int,
17671 -+ data: &mut [$ty])
17672 -+ -> $crate::Result<$crate::libc::c_int> {
17673 -+ 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))
17674 -+ }
17675 -+ )
17676 -+}
17677 -+
17678 -+/// Generates a wrapper function for an ioctl that writes an array of elements to the kernel.
17679 -+///
17680 -+/// The arguments to this macro are:
17681 -+///
17682 -+/// * The function name
17683 -+/// * The ioctl identifier
17684 -+/// * The ioctl sequence number
17685 -+/// * The data type passed by this ioctl
17686 -+///
17687 -+/// The generated function has the following signature:
17688 -+///
17689 -+/// ```rust,ignore
17690 -+/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &[DATA_TYPE]) -> Result<libc::c_int>
17691 -+/// ```
17692 -+///
17693 -+/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
17694 -+///
17695 -+/// # Examples
17696 -+///
17697 -+/// ```
17698 -+/// # #[macro_use] extern crate nix;
17699 -+/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
17700 -+/// const SPI_IOC_TYPE_MESSAGE: u8 = 0;
17701 -+/// # pub struct spi_ioc_transfer(u64);
17702 -+/// ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer);
17703 -+/// # fn main() {}
17704 -+/// ```
17705 -+#[macro_export(local_inner_macros)]
17706 -+macro_rules! ioctl_write_buf {
17707 -+ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
17708 -+ $(#[$attr])*
17709 -+ pub unsafe fn $name(fd: $crate::libc::c_int,
17710 -+ data: &[$ty])
17711 -+ -> $crate::Result<$crate::libc::c_int> {
17712 -+ 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))
17713 -+ }
17714 -+ )
17715 -+}
17716 -+
17717 -+/// Generates a wrapper function for an ioctl that reads and writes an array of elements to the kernel.
17718 -+///
17719 -+/// The arguments to this macro are:
17720 -+///
17721 -+/// * The function name
17722 -+/// * The ioctl identifier
17723 -+/// * The ioctl sequence number
17724 -+/// * The data type passed by this ioctl
17725 -+///
17726 -+/// The generated function has the following signature:
17727 -+///
17728 -+/// ```rust,ignore
17729 -+/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int>
17730 -+/// ```
17731 -+///
17732 -+/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
17733 -+// TODO: Find an example for readwrite_buf
17734 -+#[macro_export(local_inner_macros)]
17735 -+macro_rules! ioctl_readwrite_buf {
17736 -+ ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
17737 -+ $(#[$attr])*
17738 -+ pub unsafe fn $name(fd: $crate::libc::c_int,
17739 -+ data: &mut [$ty])
17740 -+ -> $crate::Result<$crate::libc::c_int> {
17741 -+ 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))
17742 -+ }
17743 -+ )
17744 -+}
17745 -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
17746 -new file mode 100644
17747 -index 0000000000000..9672429b31e7f
17748 ---- /dev/null
17749 -+++ b/third_party/rust/nix-0.15.0/src/sys/memfd.rs
17750 -@@ -0,0 +1,20 @@
17751 -+use libc;
17752 -+use std::os::unix::io::RawFd;
17753 -+use Result;
17754 -+use errno::Errno;
17755 -+use std::ffi::CStr;
17756 -+
17757 -+libc_bitflags!(
17758 -+ pub struct MemFdCreateFlag: libc::c_uint {
17759 -+ MFD_CLOEXEC;
17760 -+ MFD_ALLOW_SEALING;
17761 -+ }
17762 -+);
17763 -+
17764 -+pub fn memfd_create(name: &CStr, flags: MemFdCreateFlag) -> Result<RawFd> {
17765 -+ let res = unsafe {
17766 -+ libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags.bits())
17767 -+ };
17768 -+
17769 -+ Errno::result(res).map(|r| r as RawFd)
17770 -+}
17771 -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
17772 -new file mode 100644
17773 -index 0000000000000..4e250501dd0f0
17774 ---- /dev/null
17775 -+++ b/third_party/rust/nix-0.15.0/src/sys/mman.rs
17776 -@@ -0,0 +1,325 @@
17777 -+use {Error, Result};
17778 -+#[cfg(not(target_os = "android"))]
17779 -+use NixPath;
17780 -+use errno::Errno;
17781 -+#[cfg(not(target_os = "android"))]
17782 -+use fcntl::OFlag;
17783 -+use libc::{self, c_int, c_void, size_t, off_t};
17784 -+#[cfg(not(target_os = "android"))]
17785 -+use sys::stat::Mode;
17786 -+use std::os::unix::io::RawFd;
17787 -+
17788 -+libc_bitflags!{
17789 -+ /// Desired memory protection of a memory mapping.
17790 -+ pub struct ProtFlags: c_int {
17791 -+ /// Pages cannot be accessed.
17792 -+ PROT_NONE;
17793 -+ /// Pages can be read.
17794 -+ PROT_READ;
17795 -+ /// Pages can be written.
17796 -+ PROT_WRITE;
17797 -+ /// Pages can be executed
17798 -+ PROT_EXEC;
17799 -+ /// Apply protection up to the end of a mapping that grows upwards.
17800 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17801 -+ PROT_GROWSDOWN;
17802 -+ /// Apply protection down to the beginning of a mapping that grows downwards.
17803 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17804 -+ PROT_GROWSUP;
17805 -+ }
17806 -+}
17807 -+
17808 -+libc_bitflags!{
17809 -+ /// Additional parameters for `mmap()`.
17810 -+ pub struct MapFlags: c_int {
17811 -+ /// Compatibility flag. Ignored.
17812 -+ MAP_FILE;
17813 -+ /// Share this mapping. Mutually exclusive with `MAP_PRIVATE`.
17814 -+ MAP_SHARED;
17815 -+ /// Create a private copy-on-write mapping. Mutually exclusive with `MAP_SHARED`.
17816 -+ MAP_PRIVATE;
17817 -+ /// Place the mapping at exactly the address specified in `addr`.
17818 -+ MAP_FIXED;
17819 -+ /// Synonym for `MAP_ANONYMOUS`.
17820 -+ MAP_ANON;
17821 -+ /// The mapping is not backed by any file.
17822 -+ #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
17823 -+ MAP_ANONYMOUS;
17824 -+ /// Put the mapping into the first 2GB of the process address space.
17825 -+ #[cfg(any(all(any(target_os = "android", target_os = "linux"),
17826 -+ any(target_arch = "x86", target_arch = "x86_64")),
17827 -+ all(target_os = "linux", target_env = "musl", any(target_arch = "x86", target_arch = "x86_64")),
17828 -+ all(target_os = "freebsd", target_pointer_width = "64")))]
17829 -+ MAP_32BIT;
17830 -+ /// Used for stacks; indicates to the kernel that the mapping should extend downward in memory.
17831 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17832 -+ MAP_GROWSDOWN;
17833 -+ /// Compatibility flag. Ignored.
17834 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17835 -+ MAP_DENYWRITE;
17836 -+ /// Compatibility flag. Ignored.
17837 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17838 -+ MAP_EXECUTABLE;
17839 -+ /// Mark the mmaped region to be locked in the same way as `mlock(2)`.
17840 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17841 -+ MAP_LOCKED;
17842 -+ /// Do not reserve swap space for this mapping.
17843 -+ ///
17844 -+ /// This was removed in FreeBSD 11.
17845 -+ #[cfg(not(target_os = "freebsd"))]
17846 -+ MAP_NORESERVE;
17847 -+ /// Populate page tables for a mapping.
17848 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17849 -+ MAP_POPULATE;
17850 -+ /// Only meaningful when used with `MAP_POPULATE`. Don't perform read-ahead.
17851 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17852 -+ MAP_NONBLOCK;
17853 -+ /// Allocate the mapping using "huge pages."
17854 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17855 -+ MAP_HUGETLB;
17856 -+ /// Lock the mapped region into memory as with `mlock(2)`.
17857 -+ #[cfg(target_os = "netbsd")]
17858 -+ MAP_WIRED;
17859 -+ /// Causes dirtied data in the specified range to be flushed to disk only when necessary.
17860 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
17861 -+ MAP_NOSYNC;
17862 -+ /// Rename private pages to a file.
17863 -+ ///
17864 -+ /// This was removed in FreeBSD 11.
17865 -+ #[cfg(any(target_os = "dragonfly", target_os = "netbsd", target_os = "openbsd"))]
17866 -+ MAP_RENAME;
17867 -+ /// Region may contain semaphores.
17868 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
17869 -+ MAP_HASSEMAPHORE;
17870 -+ /// Region grows down, like a stack.
17871 -+ #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
17872 -+ MAP_STACK;
17873 -+ /// Pages in this mapping are not retained in the kernel's memory cache.
17874 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
17875 -+ MAP_NOCACHE;
17876 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
17877 -+ MAP_JIT;
17878 -+ }
17879 -+}
17880 -+
17881 -+libc_enum!{
17882 -+ /// Usage information for a range of memory to allow for performance optimizations by the kernel.
17883 -+ ///
17884 -+ /// Used by [`madvise`](./fn.madvise.html).
17885 -+ #[repr(i32)]
17886 -+ pub enum MmapAdvise {
17887 -+ /// No further special treatment. This is the default.
17888 -+ MADV_NORMAL,
17889 -+ /// Expect random page references.
17890 -+ MADV_RANDOM,
17891 -+ /// Expect sequential page references.
17892 -+ MADV_SEQUENTIAL,
17893 -+ /// Expect access in the near future.
17894 -+ MADV_WILLNEED,
17895 -+ /// Do not expect access in the near future.
17896 -+ MADV_DONTNEED,
17897 -+ /// Free up a given range of pages and its associated backing store.
17898 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17899 -+ MADV_REMOVE,
17900 -+ /// Do not make pages in this range available to the child after a `fork(2)`.
17901 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17902 -+ MADV_DONTFORK,
17903 -+ /// Undo the effect of `MADV_DONTFORK`.
17904 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17905 -+ MADV_DOFORK,
17906 -+ /// Poison the given pages.
17907 -+ ///
17908 -+ /// Subsequent references to those pages are treated like hardware memory corruption.
17909 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17910 -+ MADV_HWPOISON,
17911 -+ /// Enable Kernel Samepage Merging (KSM) for the given pages.
17912 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17913 -+ MADV_MERGEABLE,
17914 -+ /// Undo the effect of `MADV_MERGEABLE`
17915 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17916 -+ MADV_UNMERGEABLE,
17917 -+ /// Preserve the memory of each page but offline the original page.
17918 -+ #[cfg(any(target_os = "android",
17919 -+ all(target_os = "linux", any(
17920 -+ target_arch = "aarch64",
17921 -+ target_arch = "arm",
17922 -+ target_arch = "ppc",
17923 -+ target_arch = "s390x",
17924 -+ target_arch = "x86",
17925 -+ target_arch = "x86_64",
17926 -+ target_arch = "sparc64"))))]
17927 -+ MADV_SOFT_OFFLINE,
17928 -+ /// Enable Transparent Huge Pages (THP) for pages in the given range.
17929 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17930 -+ MADV_HUGEPAGE,
17931 -+ /// Undo the effect of `MADV_HUGEPAGE`.
17932 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17933 -+ MADV_NOHUGEPAGE,
17934 -+ /// Exclude the given range from a core dump.
17935 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17936 -+ MADV_DONTDUMP,
17937 -+ /// Undo the effect of an earlier `MADV_DONTDUMP`.
17938 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
17939 -+ MADV_DODUMP,
17940 -+ /// Specify that the application no longer needs the pages in the given range.
17941 -+ MADV_FREE,
17942 -+ /// Request that the system not flush the current range to disk unless it needs to.
17943 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
17944 -+ MADV_NOSYNC,
17945 -+ /// Undoes the effects of `MADV_NOSYNC` for any future pages dirtied within the given range.
17946 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
17947 -+ MADV_AUTOSYNC,
17948 -+ /// Region is not included in a core file.
17949 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
17950 -+ MADV_NOCORE,
17951 -+ /// Include region in a core file
17952 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
17953 -+ MADV_CORE,
17954 -+ #[cfg(any(target_os = "freebsd"))]
17955 -+ MADV_PROTECT,
17956 -+ /// Invalidate the hardware page table for the given region.
17957 -+ #[cfg(target_os = "dragonfly")]
17958 -+ MADV_INVAL,
17959 -+ /// Set the offset of the page directory page to `value` for the virtual page table.
17960 -+ #[cfg(target_os = "dragonfly")]
17961 -+ MADV_SETMAP,
17962 -+ /// Indicates that the application will not need the data in the given range.
17963 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
17964 -+ MADV_ZERO_WIRED_PAGES,
17965 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
17966 -+ MADV_FREE_REUSABLE,
17967 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
17968 -+ MADV_FREE_REUSE,
17969 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
17970 -+ MADV_CAN_REUSE,
17971 -+ }
17972 -+}
17973 -+
17974 -+libc_bitflags!{
17975 -+ /// Configuration flags for `msync`.
17976 -+ pub struct MsFlags: c_int {
17977 -+ /// Schedule an update but return immediately.
17978 -+ MS_ASYNC;
17979 -+ /// Invalidate all cached data.
17980 -+ MS_INVALIDATE;
17981 -+ /// Invalidate pages, but leave them mapped.
17982 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
17983 -+ MS_KILLPAGES;
17984 -+ /// Deactivate pages, but leave them mapped.
17985 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
17986 -+ MS_DEACTIVATE;
17987 -+ /// Perform an update and wait for it to complete.
17988 -+ MS_SYNC;
17989 -+ }
17990 -+}
17991 -+
17992 -+libc_bitflags!{
17993 -+ /// Flags for `mlockall`.
17994 -+ pub struct MlockAllFlags: c_int {
17995 -+ /// Lock pages that are currently mapped into the address space of the process.
17996 -+ MCL_CURRENT;
17997 -+ /// Lock pages which will become mapped into the address space of the process in the future.
17998 -+ MCL_FUTURE;
17999 -+ }
18000 -+}
18001 -+
18002 -+/// Locks all memory pages that contain part of the address range with `length` bytes starting at
18003 -+/// `addr`. Locked pages never move to the swap area.
18004 -+pub unsafe fn mlock(addr: *const c_void, length: size_t) -> Result<()> {
18005 -+ Errno::result(libc::mlock(addr, length)).map(drop)
18006 -+}
18007 -+
18008 -+/// Unlocks all memory pages that contain part of the address range with `length` bytes starting at
18009 -+/// `addr`.
18010 -+pub unsafe fn munlock(addr: *const c_void, length: size_t) -> Result<()> {
18011 -+ Errno::result(libc::munlock(addr, length)).map(drop)
18012 -+}
18013 -+
18014 -+/// Locks all memory pages mapped into this process' address space. Locked pages never move to the
18015 -+/// swap area.
18016 -+pub fn mlockall(flags: MlockAllFlags) -> Result<()> {
18017 -+ unsafe { Errno::result(libc::mlockall(flags.bits())) }.map(drop)
18018 -+}
18019 -+
18020 -+/// Unlocks all memory pages mapped into this process' address space.
18021 -+pub fn munlockall() -> Result<()> {
18022 -+ unsafe { Errno::result(libc::munlockall()) }.map(drop)
18023 -+}
18024 -+
18025 -+/// Calls to mmap are inherently unsafe, so they must be made in an unsafe block. Typically
18026 -+/// a higher-level abstraction will hide the unsafe interactions with the mmap'd region.
18027 -+pub unsafe fn mmap(addr: *mut c_void, length: size_t, prot: ProtFlags, flags: MapFlags, fd: RawFd, offset: off_t) -> Result<*mut c_void> {
18028 -+ let ret = libc::mmap(addr, length, prot.bits(), flags.bits(), fd, offset);
18029 -+
18030 -+ if ret == libc::MAP_FAILED {
18031 -+ Err(Error::Sys(Errno::last()))
18032 -+ } else {
18033 -+ Ok(ret)
18034 -+ }
18035 -+}
18036 -+
18037 -+pub unsafe fn munmap(addr: *mut c_void, len: size_t) -> Result<()> {
18038 -+ Errno::result(libc::munmap(addr, len)).map(drop)
18039 -+}
18040 -+
18041 -+pub unsafe fn madvise(addr: *mut c_void, length: size_t, advise: MmapAdvise) -> Result<()> {
18042 -+ Errno::result(libc::madvise(addr, length, advise as i32)).map(drop)
18043 -+}
18044 -+
18045 -+/// Set protection of memory mapping.
18046 -+///
18047 -+/// See [`mprotect(3)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mprotect.html) for
18048 -+/// details.
18049 -+///
18050 -+/// # Safety
18051 -+///
18052 -+/// Calls to `mprotect` are inherently unsafe, as changes to memory protections can lead to
18053 -+/// SIGSEGVs.
18054 -+///
18055 -+/// ```
18056 -+/// # use nix::libc::size_t;
18057 -+/// # use nix::sys::mman::{mmap, mprotect, MapFlags, ProtFlags};
18058 -+/// # use std::ptr;
18059 -+/// const ONE_K: size_t = 1024;
18060 -+/// let mut slice: &mut [u8] = unsafe {
18061 -+/// let mem = mmap(ptr::null_mut(), ONE_K, ProtFlags::PROT_NONE,
18062 -+/// MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE, -1, 0).unwrap();
18063 -+/// mprotect(mem, ONE_K, ProtFlags::PROT_READ | ProtFlags::PROT_WRITE).unwrap();
18064 -+/// std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
18065 -+/// };
18066 -+/// assert_eq!(slice[0], 0x00);
18067 -+/// slice[0] = 0xFF;
18068 -+/// assert_eq!(slice[0], 0xFF);
18069 -+/// ```
18070 -+pub unsafe fn mprotect(addr: *mut c_void, length: size_t, prot: ProtFlags) -> Result<()> {
18071 -+ Errno::result(libc::mprotect(addr, length, prot.bits())).map(drop)
18072 -+}
18073 -+
18074 -+pub unsafe fn msync(addr: *mut c_void, length: size_t, flags: MsFlags) -> Result<()> {
18075 -+ Errno::result(libc::msync(addr, length, flags.bits())).map(drop)
18076 -+}
18077 -+
18078 -+#[cfg(not(target_os = "android"))]
18079 -+pub fn shm_open<P: ?Sized + NixPath>(name: &P, flag: OFlag, mode: Mode) -> Result<RawFd> {
18080 -+ let ret = name.with_nix_path(|cstr| {
18081 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
18082 -+ unsafe {
18083 -+ libc::shm_open(cstr.as_ptr(), flag.bits(), mode.bits() as libc::c_uint)
18084 -+ }
18085 -+ #[cfg(not(any(target_os = "macos", target_os = "ios")))]
18086 -+ unsafe {
18087 -+ libc::shm_open(cstr.as_ptr(), flag.bits(), mode.bits() as libc::mode_t)
18088 -+ }
18089 -+ })?;
18090 -+
18091 -+ Errno::result(ret)
18092 -+}
18093 -+
18094 -+#[cfg(not(target_os = "android"))]
18095 -+pub fn shm_unlink<P: ?Sized + NixPath>(name: &P) -> Result<()> {
18096 -+ let ret = name.with_nix_path(|cstr| {
18097 -+ unsafe { libc::shm_unlink(cstr.as_ptr()) }
18098 -+ })?;
18099 -+
18100 -+ Errno::result(ret).map(drop)
18101 -+}
18102 -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
18103 -new file mode 100644
18104 -index 0000000000000..d3c2f92bbaaea
18105 ---- /dev/null
18106 -+++ b/third_party/rust/nix-0.15.0/src/sys/mod.rs
18107 -@@ -0,0 +1,100 @@
18108 -+#[cfg(any(target_os = "dragonfly",
18109 -+ target_os = "freebsd",
18110 -+ target_os = "ios",
18111 -+ target_os = "linux",
18112 -+ target_os = "macos",
18113 -+ target_os = "netbsd"))]
18114 -+pub mod aio;
18115 -+
18116 -+#[cfg(any(target_os = "android", target_os = "linux"))]
18117 -+pub mod epoll;
18118 -+
18119 -+#[cfg(any(target_os = "dragonfly",
18120 -+ target_os = "freebsd",
18121 -+ target_os = "ios",
18122 -+ target_os = "macos",
18123 -+ target_os = "netbsd",
18124 -+ target_os = "openbsd"))]
18125 -+pub mod event;
18126 -+
18127 -+#[cfg(target_os = "linux")]
18128 -+pub mod eventfd;
18129 -+
18130 -+#[cfg(any(target_os = "android",
18131 -+ target_os = "dragonfly",
18132 -+ target_os = "freebsd",
18133 -+ target_os = "ios",
18134 -+ target_os = "linux",
18135 -+ target_os = "macos",
18136 -+ target_os = "netbsd",
18137 -+ target_os = "openbsd"))]
18138 -+#[macro_use]
18139 -+pub mod ioctl;
18140 -+
18141 -+#[cfg(target_os = "linux")]
18142 -+pub mod memfd;
18143 -+
18144 -+pub mod mman;
18145 -+
18146 -+pub mod pthread;
18147 -+
18148 -+#[cfg(any(target_os = "android",
18149 -+ target_os = "dragonfly",
18150 -+ target_os = "freebsd",
18151 -+ target_os = "linux",
18152 -+ target_os = "macos",
18153 -+ target_os = "netbsd",
18154 -+ target_os = "openbsd"))]
18155 -+pub mod ptrace;
18156 -+
18157 -+#[cfg(target_os = "linux")]
18158 -+pub mod quota;
18159 -+
18160 -+#[cfg(any(target_os = "linux"))]
18161 -+pub mod reboot;
18162 -+
18163 -+pub mod select;
18164 -+
18165 -+#[cfg(any(target_os = "android",
18166 -+ target_os = "freebsd",
18167 -+ target_os = "ios",
18168 -+ target_os = "linux",
18169 -+ target_os = "macos"))]
18170 -+pub mod sendfile;
18171 -+
18172 -+pub mod signal;
18173 -+
18174 -+#[cfg(any(target_os = "android", target_os = "linux"))]
18175 -+pub mod signalfd;
18176 -+
18177 -+pub mod socket;
18178 -+
18179 -+pub mod stat;
18180 -+
18181 -+#[cfg(any(target_os = "android",
18182 -+ target_os = "dragonfly",
18183 -+ target_os = "freebsd",
18184 -+ target_os = "ios",
18185 -+ target_os = "linux",
18186 -+ target_os = "macos",
18187 -+ target_os = "openbsd"
18188 -+))]
18189 -+pub mod statfs;
18190 -+
18191 -+pub mod statvfs;
18192 -+
18193 -+#[cfg(any(target_os = "android", target_os = "linux"))]
18194 -+pub mod sysinfo;
18195 -+
18196 -+pub mod termios;
18197 -+
18198 -+pub mod time;
18199 -+
18200 -+pub mod uio;
18201 -+
18202 -+pub mod utsname;
18203 -+
18204 -+pub mod wait;
18205 -+
18206 -+#[cfg(any(target_os = "android", target_os = "linux"))]
18207 -+pub mod inotify;
18208 -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
18209 -new file mode 100644
18210 -index 0000000000000..a4d98250f2b8b
18211 ---- /dev/null
18212 -+++ b/third_party/rust/nix-0.15.0/src/sys/pthread.rs
18213 -@@ -0,0 +1,13 @@
18214 -+use libc::{self, pthread_t};
18215 -+
18216 -+pub type Pthread = pthread_t;
18217 -+
18218 -+/// Obtain ID of the calling thread (see
18219 -+/// [`pthread_self(3)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_self.html)
18220 -+///
18221 -+/// The thread ID returned by `pthread_self()` is not the same thing as
18222 -+/// the kernel thread ID returned by a call to `gettid(2)`.
18223 -+#[inline]
18224 -+pub fn pthread_self() -> Pthread {
18225 -+ unsafe { libc::pthread_self() }
18226 -+}
18227 -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
18228 -new file mode 100644
18229 -index 0000000000000..7797d10647ef4
18230 ---- /dev/null
18231 -+++ b/third_party/rust/nix-0.15.0/src/sys/ptrace/bsd.rs
18232 -@@ -0,0 +1,170 @@
18233 -+use errno::Errno;
18234 -+use libc::{self, c_int};
18235 -+use std::ptr;
18236 -+use sys::signal::Signal;
18237 -+use unistd::Pid;
18238 -+use Result;
18239 -+
18240 -+pub type RequestType = c_int;
18241 -+
18242 -+cfg_if! {
18243 -+ if #[cfg(any(target_os = "dragonfly",
18244 -+ target_os = "freebsd",
18245 -+ target_os = "macos",
18246 -+ target_os = "openbsd"))] {
18247 -+ #[doc(hidden)]
18248 -+ pub type AddressType = *mut ::libc::c_char;
18249 -+ } else {
18250 -+ #[doc(hidden)]
18251 -+ pub type AddressType = *mut ::libc::c_void;
18252 -+ }
18253 -+}
18254 -+
18255 -+libc_enum! {
18256 -+ #[repr(i32)]
18257 -+ /// Ptrace Request enum defining the action to be taken.
18258 -+ pub enum Request {
18259 -+ PT_TRACE_ME,
18260 -+ PT_READ_I,
18261 -+ PT_READ_D,
18262 -+ #[cfg(target_os = "macos")]
18263 -+ PT_READ_U,
18264 -+ PT_WRITE_I,
18265 -+ PT_WRITE_D,
18266 -+ #[cfg(target_os = "macos")]
18267 -+ PT_WRITE_U,
18268 -+ PT_CONTINUE,
18269 -+ PT_KILL,
18270 -+ #[cfg(any(any(target_os = "dragonfly",
18271 -+ target_os = "freebsd",
18272 -+ target_os = "macos"),
18273 -+ all(target_os = "openbsd", target_arch = "x86_64"),
18274 -+ all(target_os = "netbsd", any(target_arch = "x86_64",
18275 -+ target_arch = "powerpc"))))]
18276 -+ PT_STEP,
18277 -+ PT_ATTACH,
18278 -+ PT_DETACH,
18279 -+ #[cfg(target_os = "macos")]
18280 -+ PT_SIGEXC,
18281 -+ #[cfg(target_os = "macos")]
18282 -+ PT_THUPDATE,
18283 -+ #[cfg(target_os = "macos")]
18284 -+ PT_ATTACHEXC
18285 -+ }
18286 -+}
18287 -+
18288 -+unsafe fn ptrace_other(
18289 -+ request: Request,
18290 -+ pid: Pid,
18291 -+ addr: AddressType,
18292 -+ data: c_int,
18293 -+) -> Result<c_int> {
18294 -+ Errno::result(libc::ptrace(
18295 -+ request as RequestType,
18296 -+ libc::pid_t::from(pid),
18297 -+ addr,
18298 -+ data,
18299 -+ )).map(|_| 0)
18300 -+}
18301 -+
18302 -+/// Sets the process as traceable, as with `ptrace(PT_TRACEME, ...)`
18303 -+///
18304 -+/// Indicates that this process is to be traced by its parent.
18305 -+/// This is the only ptrace request to be issued by the tracee.
18306 -+pub fn traceme() -> Result<()> {
18307 -+ unsafe { ptrace_other(Request::PT_TRACE_ME, Pid::from_raw(0), ptr::null_mut(), 0).map(drop) }
18308 -+}
18309 -+
18310 -+/// Attach to a running process, as with `ptrace(PT_ATTACH, ...)`
18311 -+///
18312 -+/// Attaches to the process specified in pid, making it a tracee of the calling process.
18313 -+pub fn attach(pid: Pid) -> Result<()> {
18314 -+ unsafe { ptrace_other(Request::PT_ATTACH, pid, ptr::null_mut(), 0).map(drop) }
18315 -+}
18316 -+
18317 -+/// Detaches the current running process, as with `ptrace(PT_DETACH, ...)`
18318 -+///
18319 -+/// Detaches from the process specified in pid allowing it to run freely
18320 -+pub fn detach(pid: Pid) -> Result<()> {
18321 -+ unsafe { ptrace_other(Request::PT_DETACH, pid, ptr::null_mut(), 0).map(drop) }
18322 -+}
18323 -+
18324 -+/// Restart the stopped tracee process, as with `ptrace(PTRACE_CONT, ...)`
18325 -+///
18326 -+/// Continues the execution of the process with PID `pid`, optionally
18327 -+/// delivering a signal specified by `sig`.
18328 -+pub fn cont<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
18329 -+ let data = match sig.into() {
18330 -+ Some(s) => s as c_int,
18331 -+ None => 0,
18332 -+ };
18333 -+ unsafe {
18334 -+ // Ignore the useless return value
18335 -+ ptrace_other(Request::PT_CONTINUE, pid, 1 as AddressType, data).map(drop)
18336 -+ }
18337 -+}
18338 -+
18339 -+/// Issues a kill request as with `ptrace(PT_KILL, ...)`
18340 -+///
18341 -+/// This request is equivalent to `ptrace(PT_CONTINUE, ..., SIGKILL);`
18342 -+pub fn kill(pid: Pid) -> Result<()> {
18343 -+ unsafe {
18344 -+ ptrace_other(Request::PT_KILL, pid, 0 as AddressType, 0).map(drop)
18345 -+ }
18346 -+}
18347 -+
18348 -+/// Move the stopped tracee process forward by a single step as with
18349 -+/// `ptrace(PT_STEP, ...)`
18350 -+///
18351 -+/// Advances the execution of the process with PID `pid` by a single step optionally delivering a
18352 -+/// signal specified by `sig`.
18353 -+///
18354 -+/// # Example
18355 -+/// ```rust
18356 -+/// extern crate nix;
18357 -+/// use nix::sys::ptrace::step;
18358 -+/// use nix::unistd::Pid;
18359 -+/// use nix::sys::signal::Signal;
18360 -+/// use nix::sys::wait::*;
18361 -+/// fn main() {
18362 -+/// // If a process changes state to the stopped state because of a SIGUSR1
18363 -+/// // signal, this will step the process forward and forward the user
18364 -+/// // signal to the stopped process
18365 -+/// match waitpid(Pid::from_raw(-1), None) {
18366 -+/// Ok(WaitStatus::Stopped(pid, Signal::SIGUSR1)) => {
18367 -+/// let _ = step(pid, Signal::SIGUSR1);
18368 -+/// }
18369 -+/// _ => {},
18370 -+/// }
18371 -+/// }
18372 -+/// ```
18373 -+#[cfg(
18374 -+ any(
18375 -+ any(target_os = "dragonfly", target_os = "freebsd", target_os = "macos"),
18376 -+ all(target_os = "openbsd", target_arch = "x86_64"),
18377 -+ all(target_os = "netbsd",
18378 -+ any(target_arch = "x86_64", target_arch = "powerpc")
18379 -+ )
18380 -+ )
18381 -+)]
18382 -+pub fn step<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
18383 -+ let data = match sig.into() {
18384 -+ Some(s) => s as c_int,
18385 -+ None => 0,
18386 -+ };
18387 -+ unsafe { ptrace_other(Request::PT_STEP, pid, ptr::null_mut(), data).map(drop) }
18388 -+}
18389 -+
18390 -+/// Reads a word from a processes memory at the given address
18391 -+pub fn read(pid: Pid, addr: AddressType) -> Result<c_int> {
18392 -+ unsafe {
18393 -+ // Traditionally there was a difference between reading data or
18394 -+ // instruction memory but not in modern systems.
18395 -+ ptrace_other(Request::PT_READ_D, pid, addr, 0)
18396 -+ }
18397 -+}
18398 -+
18399 -+/// Writes a word into the processes memory at the given address
18400 -+pub fn write(pid: Pid, addr: AddressType, data: c_int) -> Result<()> {
18401 -+ unsafe { ptrace_other(Request::PT_WRITE_D, pid, addr, data).map(drop) }
18402 -+}
18403 -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
18404 -new file mode 100644
18405 -index 0000000000000..df15e66527562
18406 ---- /dev/null
18407 -+++ b/third_party/rust/nix-0.15.0/src/sys/ptrace/linux.rs
18408 -@@ -0,0 +1,402 @@
18409 -+//! For detailed description of the ptrace requests, consult `man ptrace`.
18410 -+
18411 -+use std::{mem, ptr};
18412 -+use {Error, Result};
18413 -+use errno::Errno;
18414 -+use libc::{self, c_void, c_long, siginfo_t};
18415 -+use ::unistd::Pid;
18416 -+use sys::signal::Signal;
18417 -+
18418 -+pub type AddressType = *mut ::libc::c_void;
18419 -+
18420 -+#[cfg(all(target_os = "linux",
18421 -+ any(target_arch = "x86_64",
18422 -+ target_arch = "x86"),
18423 -+ target_env = "gnu"))]
18424 -+use libc::user_regs_struct;
18425 -+
18426 -+cfg_if! {
18427 -+ if #[cfg(any(all(target_os = "linux", target_arch = "s390x"),
18428 -+ all(target_os = "linux", target_env = "gnu")))] {
18429 -+ #[doc(hidden)]
18430 -+ pub type RequestType = ::libc::c_uint;
18431 -+ } else {
18432 -+ #[doc(hidden)]
18433 -+ pub type RequestType = ::libc::c_int;
18434 -+ }
18435 -+}
18436 -+
18437 -+libc_enum!{
18438 -+ #[cfg_attr(not(any(target_env = "musl", target_os = "android")), repr(u32))]
18439 -+ #[cfg_attr(any(target_env = "musl", target_os = "android"), repr(i32))]
18440 -+ /// Ptrace Request enum defining the action to be taken.
18441 -+ pub enum Request {
18442 -+ PTRACE_TRACEME,
18443 -+ PTRACE_PEEKTEXT,
18444 -+ PTRACE_PEEKDATA,
18445 -+ PTRACE_PEEKUSER,
18446 -+ PTRACE_POKETEXT,
18447 -+ PTRACE_POKEDATA,
18448 -+ PTRACE_POKEUSER,
18449 -+ PTRACE_CONT,
18450 -+ PTRACE_KILL,
18451 -+ PTRACE_SINGLESTEP,
18452 -+ #[cfg(any(all(target_os = "android", target_pointer_width = "32"),
18453 -+ all(target_os = "linux", any(target_env = "musl",
18454 -+ target_arch = "mips",
18455 -+ target_arch = "mips64",
18456 -+ target_arch = "x86_64",
18457 -+ target_pointer_width = "32"))))]
18458 -+ PTRACE_GETREGS,
18459 -+ #[cfg(any(all(target_os = "android", target_pointer_width = "32"),
18460 -+ all(target_os = "linux", any(target_env = "musl",
18461 -+ target_arch = "mips",
18462 -+ target_arch = "mips64",
18463 -+ target_arch = "x86_64",
18464 -+ target_pointer_width = "32"))))]
18465 -+ PTRACE_SETREGS,
18466 -+ #[cfg(any(all(target_os = "android", target_pointer_width = "32"),
18467 -+ all(target_os = "linux", any(target_env = "musl",
18468 -+ target_arch = "mips",
18469 -+ target_arch = "mips64",
18470 -+ target_arch = "x86_64",
18471 -+ target_pointer_width = "32"))))]
18472 -+ PTRACE_GETFPREGS,
18473 -+ #[cfg(any(all(target_os = "android", target_pointer_width = "32"),
18474 -+ all(target_os = "linux", any(target_env = "musl",
18475 -+ target_arch = "mips",
18476 -+ target_arch = "mips64",
18477 -+ target_arch = "x86_64",
18478 -+ target_pointer_width = "32"))))]
18479 -+ PTRACE_SETFPREGS,
18480 -+ PTRACE_ATTACH,
18481 -+ PTRACE_DETACH,
18482 -+ #[cfg(all(target_os = "linux", any(target_env = "musl",
18483 -+ target_arch = "mips",
18484 -+ target_arch = "mips64",
18485 -+ target_arch = "x86",
18486 -+ target_arch = "x86_64")))]
18487 -+ PTRACE_GETFPXREGS,
18488 -+ #[cfg(all(target_os = "linux", any(target_env = "musl",
18489 -+ target_arch = "mips",
18490 -+ target_arch = "mips64",
18491 -+ target_arch = "x86",
18492 -+ target_arch = "x86_64")))]
18493 -+ PTRACE_SETFPXREGS,
18494 -+ PTRACE_SYSCALL,
18495 -+ PTRACE_SETOPTIONS,
18496 -+ PTRACE_GETEVENTMSG,
18497 -+ PTRACE_GETSIGINFO,
18498 -+ PTRACE_SETSIGINFO,
18499 -+ #[cfg(all(target_os = "linux", not(any(target_arch = "mips",
18500 -+ target_arch = "mips64"))))]
18501 -+ PTRACE_GETREGSET,
18502 -+ #[cfg(all(target_os = "linux", not(any(target_arch = "mips",
18503 -+ target_arch = "mips64"))))]
18504 -+ PTRACE_SETREGSET,
18505 -+ #[cfg(all(target_os = "linux", not(any(target_arch = "mips",
18506 -+ target_arch = "mips64"))))]
18507 -+ PTRACE_SEIZE,
18508 -+ #[cfg(all(target_os = "linux", not(any(target_arch = "mips",
18509 -+ target_arch = "mips64"))))]
18510 -+ PTRACE_INTERRUPT,
18511 -+ #[cfg(all(target_os = "linux", not(any(target_arch = "mips",
18512 -+ target_arch = "mips64"))))]
18513 -+ PTRACE_LISTEN,
18514 -+ #[cfg(all(target_os = "linux", not(any(target_arch = "mips",
18515 -+ target_arch = "mips64"))))]
18516 -+ PTRACE_PEEKSIGINFO,
18517 -+ }
18518 -+}
18519 -+
18520 -+libc_enum!{
18521 -+ #[repr(i32)]
18522 -+ /// Using the ptrace options the tracer can configure the tracee to stop
18523 -+ /// at certain events. This enum is used to define those events as defined
18524 -+ /// in `man ptrace`.
18525 -+ pub enum Event {
18526 -+ /// Event that stops before a return from fork or clone.
18527 -+ PTRACE_EVENT_FORK,
18528 -+ /// Event that stops before a return from vfork or clone.
18529 -+ PTRACE_EVENT_VFORK,
18530 -+ /// Event that stops before a return from clone.
18531 -+ PTRACE_EVENT_CLONE,
18532 -+ /// Event that stops before a return from execve.
18533 -+ PTRACE_EVENT_EXEC,
18534 -+ /// Event for a return from vfork.
18535 -+ PTRACE_EVENT_VFORK_DONE,
18536 -+ /// Event for a stop before an exit. Unlike the waitpid Exit status program.
18537 -+ /// registers can still be examined
18538 -+ PTRACE_EVENT_EXIT,
18539 -+ /// STop triggered by a seccomp rule on a tracee.
18540 -+ PTRACE_EVENT_SECCOMP,
18541 -+ // PTRACE_EVENT_STOP not provided by libc because it's defined in glibc 2.26
18542 -+ }
18543 -+}
18544 -+
18545 -+libc_bitflags! {
18546 -+ /// Ptrace options used in conjunction with the PTRACE_SETOPTIONS request.
18547 -+ /// See `man ptrace` for more details.
18548 -+ pub struct Options: libc::c_int {
18549 -+ /// When delivering system call traps set a bit to allow tracer to
18550 -+ /// distinguish between normal stops or syscall stops. May not work on
18551 -+ /// all systems.
18552 -+ PTRACE_O_TRACESYSGOOD;
18553 -+ /// Stop tracee at next fork and start tracing the forked process.
18554 -+ PTRACE_O_TRACEFORK;
18555 -+ /// Stop tracee at next vfork call and trace the vforked process.
18556 -+ PTRACE_O_TRACEVFORK;
18557 -+ /// Stop tracee at next clone call and trace the cloned process.
18558 -+ PTRACE_O_TRACECLONE;
18559 -+ /// Stop tracee at next execve call.
18560 -+ PTRACE_O_TRACEEXEC;
18561 -+ /// Stop tracee at vfork completion.
18562 -+ PTRACE_O_TRACEVFORKDONE;
18563 -+ /// Stop tracee at next exit call. Stops before exit commences allowing
18564 -+ /// tracer to see location of exit and register states.
18565 -+ PTRACE_O_TRACEEXIT;
18566 -+ /// Stop tracee when a SECCOMP_RET_TRACE rule is triggered. See `man seccomp` for more
18567 -+ /// details.
18568 -+ PTRACE_O_TRACESECCOMP;
18569 -+ /// Send a SIGKILL to the tracee if the tracer exits. This is useful
18570 -+ /// for ptrace jailers to prevent tracees from escaping their control.
18571 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
18572 -+ PTRACE_O_EXITKILL;
18573 -+ }
18574 -+}
18575 -+
18576 -+/// Performs a ptrace request. If the request in question is provided by a specialised function
18577 -+/// this function will return an unsupported operation error.
18578 -+#[deprecated(
18579 -+ since="0.10.0",
18580 -+ note="usages of `ptrace()` should be replaced with the specialized helper functions instead"
18581 -+)]
18582 -+pub unsafe fn ptrace(request: Request, pid: Pid, addr: AddressType, data: *mut c_void) -> Result<c_long> {
18583 -+ use self::Request::*;
18584 -+ match request {
18585 -+ PTRACE_PEEKTEXT | PTRACE_PEEKDATA | PTRACE_GETSIGINFO |
18586 -+ PTRACE_GETEVENTMSG | PTRACE_SETSIGINFO | PTRACE_SETOPTIONS |
18587 -+ PTRACE_POKETEXT | PTRACE_POKEDATA | PTRACE_KILL => Err(Error::UnsupportedOperation),
18588 -+ _ => ptrace_other(request, pid, addr, data)
18589 -+ }
18590 -+}
18591 -+
18592 -+fn ptrace_peek(request: Request, pid: Pid, addr: AddressType, data: *mut c_void) -> Result<c_long> {
18593 -+ let ret = unsafe {
18594 -+ Errno::clear();
18595 -+ libc::ptrace(request as RequestType, libc::pid_t::from(pid), addr, data)
18596 -+ };
18597 -+ match Errno::result(ret) {
18598 -+ Ok(..) | Err(Error::Sys(Errno::UnknownErrno)) => Ok(ret),
18599 -+ err @ Err(..) => err,
18600 -+ }
18601 -+}
18602 -+
18603 -+/// Get user registers, as with `ptrace(PTRACE_GETREGS, ...)`
18604 -+#[cfg(all(target_os = "linux",
18605 -+ any(target_arch = "x86_64",
18606 -+ target_arch = "x86"),
18607 -+ target_env = "gnu"))]
18608 -+pub fn getregs(pid: Pid) -> Result<user_regs_struct> {
18609 -+ ptrace_get_data::<user_regs_struct>(Request::PTRACE_GETREGS, pid)
18610 -+}
18611 -+
18612 -+/// Set user registers, as with `ptrace(PTRACE_SETREGS, ...)`
18613 -+#[cfg(all(target_os = "linux",
18614 -+ any(target_arch = "x86_64",
18615 -+ target_arch = "x86"),
18616 -+ target_env = "gnu"))]
18617 -+pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> {
18618 -+ let res = unsafe {
18619 -+ libc::ptrace(Request::PTRACE_SETREGS as RequestType,
18620 -+ libc::pid_t::from(pid),
18621 -+ ptr::null_mut::<c_void>(),
18622 -+ &regs as *const _ as *const c_void)
18623 -+ };
18624 -+ Errno::result(res).map(drop)
18625 -+}
18626 -+
18627 -+/// Function for ptrace requests that return values from the data field.
18628 -+/// Some ptrace get requests populate structs or larger elements than `c_long`
18629 -+/// and therefore use the data field to return values. This function handles these
18630 -+/// requests.
18631 -+fn ptrace_get_data<T>(request: Request, pid: Pid) -> Result<T> {
18632 -+ // Creates an uninitialized pointer to store result in
18633 -+ let data: T = unsafe { mem::uninitialized() };
18634 -+ let res = unsafe {
18635 -+ libc::ptrace(request as RequestType,
18636 -+ libc::pid_t::from(pid),
18637 -+ ptr::null_mut::<T>(),
18638 -+ &data as *const _ as *const c_void)
18639 -+ };
18640 -+ Errno::result(res)?;
18641 -+ Ok(data)
18642 -+}
18643 -+
18644 -+unsafe fn ptrace_other(request: Request, pid: Pid, addr: AddressType, data: *mut c_void) -> Result<c_long> {
18645 -+ Errno::result(libc::ptrace(request as RequestType, libc::pid_t::from(pid), addr, data)).map(|_| 0)
18646 -+}
18647 -+
18648 -+/// Set options, as with `ptrace(PTRACE_SETOPTIONS,...)`.
18649 -+pub fn setoptions(pid: Pid, options: Options) -> Result<()> {
18650 -+ let res = unsafe {
18651 -+ libc::ptrace(Request::PTRACE_SETOPTIONS as RequestType,
18652 -+ libc::pid_t::from(pid),
18653 -+ ptr::null_mut::<c_void>(),
18654 -+ options.bits() as *mut c_void)
18655 -+ };
18656 -+ Errno::result(res).map(drop)
18657 -+}
18658 -+
18659 -+/// Gets a ptrace event as described by `ptrace(PTRACE_GETEVENTMSG,...)`
18660 -+pub fn getevent(pid: Pid) -> Result<c_long> {
18661 -+ ptrace_get_data::<c_long>(Request::PTRACE_GETEVENTMSG, pid)
18662 -+}
18663 -+
18664 -+/// Get siginfo as with `ptrace(PTRACE_GETSIGINFO,...)`
18665 -+pub fn getsiginfo(pid: Pid) -> Result<siginfo_t> {
18666 -+ ptrace_get_data::<siginfo_t>(Request::PTRACE_GETSIGINFO, pid)
18667 -+}
18668 -+
18669 -+/// Set siginfo as with `ptrace(PTRACE_SETSIGINFO,...)`
18670 -+pub fn setsiginfo(pid: Pid, sig: &siginfo_t) -> Result<()> {
18671 -+ let ret = unsafe{
18672 -+ Errno::clear();
18673 -+ libc::ptrace(Request::PTRACE_SETSIGINFO as RequestType,
18674 -+ libc::pid_t::from(pid),
18675 -+ ptr::null_mut::<c_void>(),
18676 -+ sig as *const _ as *const c_void)
18677 -+ };
18678 -+ match Errno::result(ret) {
18679 -+ Ok(_) => Ok(()),
18680 -+ Err(e) => Err(e),
18681 -+ }
18682 -+}
18683 -+
18684 -+/// Sets the process as traceable, as with `ptrace(PTRACE_TRACEME, ...)`
18685 -+///
18686 -+/// Indicates that this process is to be traced by its parent.
18687 -+/// This is the only ptrace request to be issued by the tracee.
18688 -+pub fn traceme() -> Result<()> {
18689 -+ unsafe {
18690 -+ ptrace_other(
18691 -+ Request::PTRACE_TRACEME,
18692 -+ Pid::from_raw(0),
18693 -+ ptr::null_mut(),
18694 -+ ptr::null_mut(),
18695 -+ ).map(drop) // ignore the useless return value
18696 -+ }
18697 -+}
18698 -+
18699 -+/// Ask for next syscall, as with `ptrace(PTRACE_SYSCALL, ...)`
18700 -+///
18701 -+/// Arranges for the tracee to be stopped at the next entry to or exit from a system call.
18702 -+pub fn syscall(pid: Pid) -> Result<()> {
18703 -+ unsafe {
18704 -+ ptrace_other(
18705 -+ Request::PTRACE_SYSCALL,
18706 -+ pid,
18707 -+ ptr::null_mut(),
18708 -+ ptr::null_mut(),
18709 -+ ).map(drop) // ignore the useless return value
18710 -+ }
18711 -+}
18712 -+
18713 -+/// Attach to a running process, as with `ptrace(PTRACE_ATTACH, ...)`
18714 -+///
18715 -+/// Attaches to the process specified in pid, making it a tracee of the calling process.
18716 -+pub fn attach(pid: Pid) -> Result<()> {
18717 -+ unsafe {
18718 -+ ptrace_other(
18719 -+ Request::PTRACE_ATTACH,
18720 -+ pid,
18721 -+ ptr::null_mut(),
18722 -+ ptr::null_mut(),
18723 -+ ).map(drop) // ignore the useless return value
18724 -+ }
18725 -+}
18726 -+
18727 -+/// Detaches the current running process, as with `ptrace(PTRACE_DETACH, ...)`
18728 -+///
18729 -+/// Detaches from the process specified in pid allowing it to run freely
18730 -+pub fn detach(pid: Pid) -> Result<()> {
18731 -+ unsafe {
18732 -+ ptrace_other(
18733 -+ Request::PTRACE_DETACH,
18734 -+ pid,
18735 -+ ptr::null_mut(),
18736 -+ ptr::null_mut()
18737 -+ ).map(drop)
18738 -+ }
18739 -+}
18740 -+
18741 -+/// Restart the stopped tracee process, as with `ptrace(PTRACE_CONT, ...)`
18742 -+///
18743 -+/// Continues the execution of the process with PID `pid`, optionally
18744 -+/// delivering a signal specified by `sig`.
18745 -+pub fn cont<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
18746 -+ let data = match sig.into() {
18747 -+ Some(s) => s as i32 as *mut c_void,
18748 -+ None => ptr::null_mut(),
18749 -+ };
18750 -+ unsafe {
18751 -+ ptrace_other(Request::PTRACE_CONT, pid, ptr::null_mut(), data).map(drop) // ignore the useless return value
18752 -+ }
18753 -+}
18754 -+
18755 -+/// Issues a kill request as with `ptrace(PTRACE_KILL, ...)`
18756 -+///
18757 -+/// This request is equivalent to `ptrace(PTRACE_CONT, ..., SIGKILL);`
18758 -+pub fn kill(pid: Pid) -> Result<()> {
18759 -+ unsafe {
18760 -+ ptrace_other(Request::PTRACE_KILL, pid, ptr::null_mut(), ptr::null_mut()).map(drop)
18761 -+ }
18762 -+}
18763 -+
18764 -+/// Move the stopped tracee process forward by a single step as with
18765 -+/// `ptrace(PTRACE_SINGLESTEP, ...)`
18766 -+///
18767 -+/// Advances the execution of the process with PID `pid` by a single step optionally delivering a
18768 -+/// signal specified by `sig`.
18769 -+///
18770 -+/// # Example
18771 -+/// ```rust
18772 -+/// extern crate nix;
18773 -+/// use nix::sys::ptrace::step;
18774 -+/// use nix::unistd::Pid;
18775 -+/// use nix::sys::signal::Signal;
18776 -+/// use nix::sys::wait::*;
18777 -+/// fn main() {
18778 -+/// // If a process changes state to the stopped state because of a SIGUSR1
18779 -+/// // signal, this will step the process forward and forward the user
18780 -+/// // signal to the stopped process
18781 -+/// match waitpid(Pid::from_raw(-1), None) {
18782 -+/// Ok(WaitStatus::Stopped(pid, Signal::SIGUSR1)) => {
18783 -+/// let _ = step(pid, Signal::SIGUSR1);
18784 -+/// }
18785 -+/// _ => {},
18786 -+/// }
18787 -+/// }
18788 -+/// ```
18789 -+pub fn step<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
18790 -+ let data = match sig.into() {
18791 -+ Some(s) => s as i32 as *mut c_void,
18792 -+ None => ptr::null_mut(),
18793 -+ };
18794 -+ unsafe {
18795 -+ ptrace_other(Request::PTRACE_SINGLESTEP, pid, ptr::null_mut(), data).map(drop)
18796 -+ }
18797 -+}
18798 -+
18799 -+
18800 -+/// Reads a word from a processes memory at the given address
18801 -+pub fn read(pid: Pid, addr: AddressType) -> Result<c_long> {
18802 -+ ptrace_peek(Request::PTRACE_PEEKDATA, pid, addr, ptr::null_mut())
18803 -+}
18804 -+
18805 -+/// Writes a word into the processes memory at the given address
18806 -+pub fn write(pid: Pid, addr: AddressType, data: *mut c_void) -> Result<()> {
18807 -+ unsafe {
18808 -+ ptrace_other(Request::PTRACE_POKEDATA, pid, addr, data).map(drop)
18809 -+ }
18810 -+}
18811 -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
18812 -new file mode 100644
18813 -index 0000000000000..782c30409bc12
18814 ---- /dev/null
18815 -+++ b/third_party/rust/nix-0.15.0/src/sys/ptrace/mod.rs
18816 -@@ -0,0 +1,22 @@
18817 -+///! Provides helpers for making ptrace system calls
18818 -+
18819 -+#[cfg(any(target_os = "android", target_os = "linux"))]
18820 -+mod linux;
18821 -+
18822 -+#[cfg(any(target_os = "android", target_os = "linux"))]
18823 -+pub use self::linux::*;
18824 -+
18825 -+#[cfg(any(target_os = "dragonfly",
18826 -+ target_os = "freebsd",
18827 -+ target_os = "macos",
18828 -+ target_os = "netbsd",
18829 -+ target_os = "openbsd"))]
18830 -+mod bsd;
18831 -+
18832 -+#[cfg(any(target_os = "dragonfly",
18833 -+ target_os = "freebsd",
18834 -+ target_os = "macos",
18835 -+ target_os = "netbsd",
18836 -+ target_os = "openbsd"
18837 -+ ))]
18838 -+pub use self::bsd::*;
18839 -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
18840 -new file mode 100644
18841 -index 0000000000000..8946fca2213c8
18842 ---- /dev/null
18843 -+++ b/third_party/rust/nix-0.15.0/src/sys/quota.rs
18844 -@@ -0,0 +1,273 @@
18845 -+//! Set and configure disk quotas for users, groups, or projects.
18846 -+//!
18847 -+//! # Examples
18848 -+//!
18849 -+//! Enabling and setting a quota:
18850 -+//!
18851 -+//! ```rust,no_run
18852 -+//! # use nix::sys::quota::{Dqblk, quotactl_on, quotactl_set, QuotaFmt, QuotaType, QuotaValidFlags};
18853 -+//! quotactl_on(QuotaType::USRQUOTA, "/dev/sda1", QuotaFmt::QFMT_VFS_V1, "aquota.user");
18854 -+//! let mut dqblk: Dqblk = Default::default();
18855 -+//! dqblk.set_blocks_hard_limit(10000);
18856 -+//! dqblk.set_blocks_soft_limit(8000);
18857 -+//! quotactl_set(QuotaType::USRQUOTA, "/dev/sda1", 50, &dqblk, QuotaValidFlags::QIF_BLIMITS);
18858 -+//! ```
18859 -+use std::default::Default;
18860 -+use std::{mem, ptr};
18861 -+use libc::{self, c_int, c_char};
18862 -+use {Result, NixPath};
18863 -+use errno::Errno;
18864 -+
18865 -+struct QuotaCmd(QuotaSubCmd, QuotaType);
18866 -+
18867 -+impl QuotaCmd {
18868 -+ fn as_int(&self) -> c_int {
18869 -+ unsafe { libc::QCMD(self.0 as i32, self.1 as i32) }
18870 -+ }
18871 -+}
18872 -+
18873 -+// linux quota version >= 2
18874 -+libc_enum!{
18875 -+ #[repr(i32)]
18876 -+ enum QuotaSubCmd {
18877 -+ Q_SYNC,
18878 -+ Q_QUOTAON,
18879 -+ Q_QUOTAOFF,
18880 -+ Q_GETQUOTA,
18881 -+ Q_SETQUOTA,
18882 -+ }
18883 -+}
18884 -+
18885 -+libc_enum!{
18886 -+ /// The scope of the quota.
18887 -+ #[repr(i32)]
18888 -+ pub enum QuotaType {
18889 -+ /// Specify a user quota
18890 -+ USRQUOTA,
18891 -+ /// Specify a group quota
18892 -+ GRPQUOTA,
18893 -+ }
18894 -+}
18895 -+
18896 -+libc_enum!{
18897 -+ /// The type of quota format to use.
18898 -+ #[repr(i32)]
18899 -+ pub enum QuotaFmt {
18900 -+ /// Use the original quota format.
18901 -+ QFMT_VFS_OLD,
18902 -+ /// Use the standard VFS v0 quota format.
18903 -+ ///
18904 -+ /// Handles 32-bit UIDs/GIDs and quota limits up to 2<sup>32</sup> bytes/2<sup>32</sup> inodes.
18905 -+ QFMT_VFS_V0,
18906 -+ /// Use the VFS v1 quota format.
18907 -+ ///
18908 -+ /// Handles 32-bit UIDs/GIDs and quota limits of 2<sup>64</sup> bytes/2<sup>64</sup> inodes.
18909 -+ QFMT_VFS_V1,
18910 -+ }
18911 -+}
18912 -+
18913 -+libc_bitflags!(
18914 -+ /// Indicates the quota fields that are valid to read from.
18915 -+ #[derive(Default)]
18916 -+ pub struct QuotaValidFlags: u32 {
18917 -+ /// The block hard & soft limit fields.
18918 -+ QIF_BLIMITS;
18919 -+ /// The current space field.
18920 -+ QIF_SPACE;
18921 -+ /// The inode hard & soft limit fields.
18922 -+ QIF_ILIMITS;
18923 -+ /// The current inodes field.
18924 -+ QIF_INODES;
18925 -+ /// The disk use time limit field.
18926 -+ QIF_BTIME;
18927 -+ /// The file quote time limit field.
18928 -+ QIF_ITIME;
18929 -+ /// All block & inode limits.
18930 -+ QIF_LIMITS;
18931 -+ /// The space & inodes usage fields.
18932 -+ QIF_USAGE;
18933 -+ /// The time limit fields.
18934 -+ QIF_TIMES;
18935 -+ /// All fields.
18936 -+ QIF_ALL;
18937 -+ }
18938 -+);
18939 -+
18940 -+/// Wrapper type for `if_dqblk`
18941 -+// FIXME: Change to repr(transparent)
18942 -+#[repr(C)]
18943 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
18944 -+pub struct Dqblk(libc::dqblk);
18945 -+
18946 -+impl Default for Dqblk {
18947 -+ fn default() -> Dqblk {
18948 -+ Dqblk(libc::dqblk {
18949 -+ dqb_bhardlimit: 0,
18950 -+ dqb_bsoftlimit: 0,
18951 -+ dqb_curspace: 0,
18952 -+ dqb_ihardlimit: 0,
18953 -+ dqb_isoftlimit: 0,
18954 -+ dqb_curinodes: 0,
18955 -+ dqb_btime: 0,
18956 -+ dqb_itime: 0,
18957 -+ dqb_valid: 0,
18958 -+ })
18959 -+ }
18960 -+}
18961 -+
18962 -+impl Dqblk {
18963 -+ /// The absolute limit on disk quota blocks allocated.
18964 -+ pub fn blocks_hard_limit(&self) -> Option<u64> {
18965 -+ let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
18966 -+ if valid_fields.contains(QuotaValidFlags::QIF_BLIMITS) {
18967 -+ Some(self.0.dqb_bhardlimit)
18968 -+ } else {
18969 -+ None
18970 -+ }
18971 -+ }
18972 -+
18973 -+ /// Set the absolute limit on disk quota blocks allocated.
18974 -+ pub fn set_blocks_hard_limit(&mut self, limit: u64) {
18975 -+ self.0.dqb_bhardlimit = limit;
18976 -+ }
18977 -+
18978 -+ /// Preferred limit on disk quota blocks
18979 -+ pub fn blocks_soft_limit(&self) -> Option<u64> {
18980 -+ let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
18981 -+ if valid_fields.contains(QuotaValidFlags::QIF_BLIMITS) {
18982 -+ Some(self.0.dqb_bsoftlimit)
18983 -+ } else {
18984 -+ None
18985 -+ }
18986 -+ }
18987 -+
18988 -+ /// Set the preferred limit on disk quota blocks allocated.
18989 -+ pub fn set_blocks_soft_limit(&mut self, limit: u64) {
18990 -+ self.0.dqb_bsoftlimit = limit;
18991 -+ }
18992 -+
18993 -+ /// Current occupied space (bytes).
18994 -+ pub fn occupied_space(&self) -> Option<u64> {
18995 -+ let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
18996 -+ if valid_fields.contains(QuotaValidFlags::QIF_SPACE) {
18997 -+ Some(self.0.dqb_curspace)
18998 -+ } else {
18999 -+ None
19000 -+ }
19001 -+ }
19002 -+
19003 -+ /// Maximum number of allocated inodes.
19004 -+ pub fn inodes_hard_limit(&self) -> Option<u64> {
19005 -+ let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
19006 -+ if valid_fields.contains(QuotaValidFlags::QIF_ILIMITS) {
19007 -+ Some(self.0.dqb_ihardlimit)
19008 -+ } else {
19009 -+ None
19010 -+ }
19011 -+ }
19012 -+
19013 -+ /// Set the maximum number of allocated inodes.
19014 -+ pub fn set_inodes_hard_limit(&mut self, limit: u64) {
19015 -+ self.0.dqb_ihardlimit = limit;
19016 -+ }
19017 -+
19018 -+ /// Preferred inode limit
19019 -+ pub fn inodes_soft_limit(&self) -> Option<u64> {
19020 -+ let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
19021 -+ if valid_fields.contains(QuotaValidFlags::QIF_ILIMITS) {
19022 -+ Some(self.0.dqb_isoftlimit)
19023 -+ } else {
19024 -+ None
19025 -+ }
19026 -+ }
19027 -+
19028 -+ /// Set the preferred limit of allocated inodes.
19029 -+ pub fn set_inodes_soft_limit(&mut self, limit: u64) {
19030 -+ self.0.dqb_isoftlimit = limit;
19031 -+ }
19032 -+
19033 -+ /// Current number of allocated inodes.
19034 -+ pub fn allocated_inodes(&self) -> Option<u64> {
19035 -+ let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
19036 -+ if valid_fields.contains(QuotaValidFlags::QIF_INODES) {
19037 -+ Some(self.0.dqb_curinodes)
19038 -+ } else {
19039 -+ None
19040 -+ }
19041 -+ }
19042 -+
19043 -+ /// Time limit for excessive disk use.
19044 -+ pub fn block_time_limit(&self) -> Option<u64> {
19045 -+ let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
19046 -+ if valid_fields.contains(QuotaValidFlags::QIF_BTIME) {
19047 -+ Some(self.0.dqb_btime)
19048 -+ } else {
19049 -+ None
19050 -+ }
19051 -+ }
19052 -+
19053 -+ /// Set the time limit for excessive disk use.
19054 -+ pub fn set_block_time_limit(&mut self, limit: u64) {
19055 -+ self.0.dqb_btime = limit;
19056 -+ }
19057 -+
19058 -+ /// Time limit for excessive files.
19059 -+ pub fn inode_time_limit(&self) -> Option<u64> {
19060 -+ let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
19061 -+ if valid_fields.contains(QuotaValidFlags::QIF_ITIME) {
19062 -+ Some(self.0.dqb_itime)
19063 -+ } else {
19064 -+ None
19065 -+ }
19066 -+ }
19067 -+
19068 -+ /// Set the time limit for excessive files.
19069 -+ pub fn set_inode_time_limit(&mut self, limit: u64) {
19070 -+ self.0.dqb_itime = limit;
19071 -+ }
19072 -+}
19073 -+
19074 -+fn quotactl<P: ?Sized + NixPath>(cmd: QuotaCmd, special: Option<&P>, id: c_int, addr: *mut c_char) -> Result<()> {
19075 -+ unsafe {
19076 -+ Errno::clear();
19077 -+ let res = match special {
19078 -+ Some(dev) => dev.with_nix_path(|path| libc::quotactl(cmd.as_int(), path.as_ptr(), id, addr)),
19079 -+ None => Ok(libc::quotactl(cmd.as_int(), ptr::null(), id, addr)),
19080 -+ }?;
19081 -+
19082 -+ Errno::result(res).map(drop)
19083 -+ }
19084 -+}
19085 -+
19086 -+/// Turn on disk quotas for a block device.
19087 -+pub fn quotactl_on<P: ?Sized + NixPath>(which: QuotaType, special: &P, format: QuotaFmt, quota_file: &P) -> Result<()> {
19088 -+ quota_file.with_nix_path(|path| {
19089 -+ let mut path_copy = path.to_bytes_with_nul().to_owned();
19090 -+ let p: *mut c_char = path_copy.as_mut_ptr() as *mut c_char;
19091 -+ quotactl(QuotaCmd(QuotaSubCmd::Q_QUOTAON, which), Some(special), format as c_int, p)
19092 -+ })?
19093 -+}
19094 -+
19095 -+/// Disable disk quotas for a block device.
19096 -+pub fn quotactl_off<P: ?Sized + NixPath>(which: QuotaType, special: &P) -> Result<()> {
19097 -+ quotactl(QuotaCmd(QuotaSubCmd::Q_QUOTAOFF, which), Some(special), 0, ptr::null_mut())
19098 -+}
19099 -+
19100 -+/// Update the on-disk copy of quota usages for a filesystem.
19101 -+pub fn quotactl_sync<P: ?Sized + NixPath>(which: QuotaType, special: Option<&P>) -> Result<()> {
19102 -+ quotactl(QuotaCmd(QuotaSubCmd::Q_SYNC, which), special, 0, ptr::null_mut())
19103 -+}
19104 -+
19105 -+/// Get disk quota limits and current usage for the given user/group id.
19106 -+pub fn quotactl_get<P: ?Sized + NixPath>(which: QuotaType, special: &P, id: c_int) -> Result<Dqblk> {
19107 -+ let mut dqblk = unsafe { mem::uninitialized() };
19108 -+ quotactl(QuotaCmd(QuotaSubCmd::Q_GETQUOTA, which), Some(special), id, &mut dqblk as *mut _ as *mut c_char)?;
19109 -+ dqblk
19110 -+}
19111 -+
19112 -+/// Configure quota values for the specified fields for a given user/group id.
19113 -+pub fn quotactl_set<P: ?Sized + NixPath>(which: QuotaType, special: &P, id: c_int, dqblk: &Dqblk, fields: QuotaValidFlags) -> Result<()> {
19114 -+ let mut dqblk_copy = *dqblk;
19115 -+ dqblk_copy.0.dqb_valid = fields.bits();
19116 -+ quotactl(QuotaCmd(QuotaSubCmd::Q_SETQUOTA, which), Some(special), id, &mut dqblk_copy as *mut _ as *mut c_char)
19117 -+}
19118 -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
19119 -new file mode 100644
19120 -index 0000000000000..bafa8fc11996d
19121 ---- /dev/null
19122 -+++ b/third_party/rust/nix-0.15.0/src/sys/reboot.rs
19123 -@@ -0,0 +1,45 @@
19124 -+//! Reboot/shutdown or enable/disable Ctrl-Alt-Delete.
19125 -+
19126 -+use {Error, Result};
19127 -+use errno::Errno;
19128 -+use libc;
19129 -+use void::Void;
19130 -+use std::mem::drop;
19131 -+
19132 -+libc_enum! {
19133 -+ /// How exactly should the system be rebooted.
19134 -+ ///
19135 -+ /// See [`set_cad_enabled()`](fn.set_cad_enabled.html) for
19136 -+ /// enabling/disabling Ctrl-Alt-Delete.
19137 -+ #[repr(i32)]
19138 -+ pub enum RebootMode {
19139 -+ RB_HALT_SYSTEM,
19140 -+ RB_KEXEC,
19141 -+ RB_POWER_OFF,
19142 -+ RB_AUTOBOOT,
19143 -+ // we do not support Restart2,
19144 -+ RB_SW_SUSPEND,
19145 -+ }
19146 -+}
19147 -+
19148 -+pub fn reboot(how: RebootMode) -> Result<Void> {
19149 -+ unsafe {
19150 -+ libc::reboot(how as libc::c_int)
19151 -+ };
19152 -+ Err(Error::Sys(Errno::last()))
19153 -+}
19154 -+
19155 -+/// Enable or disable the reboot keystroke (Ctrl-Alt-Delete).
19156 -+///
19157 -+/// Corresponds to calling `reboot(RB_ENABLE_CAD)` or `reboot(RB_DISABLE_CAD)` in C.
19158 -+pub fn set_cad_enabled(enable: bool) -> Result<()> {
19159 -+ let cmd = if enable {
19160 -+ libc::RB_ENABLE_CAD
19161 -+ } else {
19162 -+ libc::RB_DISABLE_CAD
19163 -+ };
19164 -+ let res = unsafe {
19165 -+ libc::reboot(cmd)
19166 -+ };
19167 -+ Errno::result(res).map(drop)
19168 -+}
19169 -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
19170 -new file mode 100644
19171 -index 0000000000000..1b518e29f67a6
19172 ---- /dev/null
19173 -+++ b/third_party/rust/nix-0.15.0/src/sys/select.rs
19174 -@@ -0,0 +1,334 @@
19175 -+use std::mem;
19176 -+use std::os::unix::io::RawFd;
19177 -+use std::ptr::{null, null_mut};
19178 -+use libc::{self, c_int};
19179 -+use Result;
19180 -+use errno::Errno;
19181 -+use sys::signal::SigSet;
19182 -+use sys::time::{TimeSpec, TimeVal};
19183 -+
19184 -+pub use libc::FD_SETSIZE;
19185 -+
19186 -+// FIXME: Change to repr(transparent) once it's stable
19187 -+#[repr(C)]
19188 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
19189 -+pub struct FdSet(libc::fd_set);
19190 -+
19191 -+impl FdSet {
19192 -+ pub fn new() -> FdSet {
19193 -+ let mut fdset = unsafe { mem::uninitialized() };
19194 -+ unsafe { libc::FD_ZERO(&mut fdset) };
19195 -+ FdSet(fdset)
19196 -+ }
19197 -+
19198 -+ pub fn insert(&mut self, fd: RawFd) {
19199 -+ unsafe { libc::FD_SET(fd, &mut self.0) };
19200 -+ }
19201 -+
19202 -+ pub fn remove(&mut self, fd: RawFd) {
19203 -+ unsafe { libc::FD_CLR(fd, &mut self.0) };
19204 -+ }
19205 -+
19206 -+ pub fn contains(&mut self, fd: RawFd) -> bool {
19207 -+ unsafe { libc::FD_ISSET(fd, &mut self.0) }
19208 -+ }
19209 -+
19210 -+ pub fn clear(&mut self) {
19211 -+ unsafe { libc::FD_ZERO(&mut self.0) };
19212 -+ }
19213 -+
19214 -+ /// Finds the highest file descriptor in the set.
19215 -+ ///
19216 -+ /// Returns `None` if the set is empty.
19217 -+ ///
19218 -+ /// This can be used to calculate the `nfds` parameter of the [`select`] function.
19219 -+ ///
19220 -+ /// # Example
19221 -+ ///
19222 -+ /// ```
19223 -+ /// # extern crate nix;
19224 -+ /// # use nix::sys::select::FdSet;
19225 -+ /// # fn main() {
19226 -+ /// let mut set = FdSet::new();
19227 -+ /// set.insert(4);
19228 -+ /// set.insert(9);
19229 -+ /// assert_eq!(set.highest(), Some(9));
19230 -+ /// # }
19231 -+ /// ```
19232 -+ ///
19233 -+ /// [`select`]: fn.select.html
19234 -+ pub fn highest(&mut self) -> Option<RawFd> {
19235 -+ for i in (0..FD_SETSIZE).rev() {
19236 -+ let i = i as RawFd;
19237 -+ if unsafe { libc::FD_ISSET(i, self as *mut _ as *mut libc::fd_set) } {
19238 -+ return Some(i)
19239 -+ }
19240 -+ }
19241 -+
19242 -+ None
19243 -+ }
19244 -+}
19245 -+
19246 -+/// Monitors file descriptors for readiness
19247 -+///
19248 -+/// Returns the total number of ready file descriptors in all sets. The sets are changed so that all
19249 -+/// file descriptors that are ready for the given operation are set.
19250 -+///
19251 -+/// When this function returns, `timeout` has an implementation-defined value.
19252 -+///
19253 -+/// # Parameters
19254 -+///
19255 -+/// * `nfds`: The highest file descriptor set in any of the passed `FdSet`s, plus 1. If `None`, this
19256 -+/// is calculated automatically by calling [`FdSet::highest`] on all descriptor sets and adding 1
19257 -+/// to the maximum of that.
19258 -+/// * `readfds`: File descriptors to check for being ready to read.
19259 -+/// * `writefds`: File descriptors to check for being ready to write.
19260 -+/// * `errorfds`: File descriptors to check for pending error conditions.
19261 -+/// * `timeout`: Maximum time to wait for descriptors to become ready (`None` to block
19262 -+/// indefinitely).
19263 -+///
19264 -+/// # References
19265 -+///
19266 -+/// [select(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html)
19267 -+///
19268 -+/// [`FdSet::highest`]: struct.FdSet.html#method.highest
19269 -+pub fn select<'a, N, R, W, E, T>(nfds: N,
19270 -+ readfds: R,
19271 -+ writefds: W,
19272 -+ errorfds: E,
19273 -+ timeout: T) -> Result<c_int>
19274 -+where
19275 -+ N: Into<Option<c_int>>,
19276 -+ R: Into<Option<&'a mut FdSet>>,
19277 -+ W: Into<Option<&'a mut FdSet>>,
19278 -+ E: Into<Option<&'a mut FdSet>>,
19279 -+ T: Into<Option<&'a mut TimeVal>>,
19280 -+{
19281 -+ let mut readfds = readfds.into();
19282 -+ let mut writefds = writefds.into();
19283 -+ let mut errorfds = errorfds.into();
19284 -+ let timeout = timeout.into();
19285 -+
19286 -+ let nfds = nfds.into().unwrap_or_else(|| {
19287 -+ readfds.iter_mut()
19288 -+ .chain(writefds.iter_mut())
19289 -+ .chain(errorfds.iter_mut())
19290 -+ .map(|set| set.highest().unwrap_or(-1))
19291 -+ .max()
19292 -+ .unwrap_or(-1) + 1
19293 -+ });
19294 -+
19295 -+ let readfds = readfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
19296 -+ let writefds = writefds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
19297 -+ let errorfds = errorfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
19298 -+ let timeout = timeout.map(|tv| tv as *mut _ as *mut libc::timeval)
19299 -+ .unwrap_or(null_mut());
19300 -+
19301 -+ let res = unsafe {
19302 -+ libc::select(nfds, readfds, writefds, errorfds, timeout)
19303 -+ };
19304 -+
19305 -+ Errno::result(res)
19306 -+}
19307 -+
19308 -+/// Monitors file descriptors for readiness with an altered signal mask.
19309 -+///
19310 -+/// Returns the total number of ready file descriptors in all sets. The sets are changed so that all
19311 -+/// file descriptors that are ready for the given operation are set.
19312 -+///
19313 -+/// When this function returns, the original signal mask is restored.
19314 -+///
19315 -+/// Unlike [`select`](#fn.select), `pselect` does not mutate the `timeout` value.
19316 -+///
19317 -+/// # Parameters
19318 -+///
19319 -+/// * `nfds`: The highest file descriptor set in any of the passed `FdSet`s, plus 1. If `None`, this
19320 -+/// is calculated automatically by calling [`FdSet::highest`] on all descriptor sets and adding 1
19321 -+/// to the maximum of that.
19322 -+/// * `readfds`: File descriptors to check for read readiness
19323 -+/// * `writefds`: File descriptors to check for write readiness
19324 -+/// * `errorfds`: File descriptors to check for pending error conditions.
19325 -+/// * `timeout`: Maximum time to wait for descriptors to become ready (`None` to block
19326 -+/// indefinitely).
19327 -+/// * `sigmask`: Signal mask to activate while waiting for file descriptors to turn
19328 -+/// ready (`None` to set no alternative signal mask).
19329 -+///
19330 -+/// # References
19331 -+///
19332 -+/// [pselect(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pselect.html)
19333 -+///
19334 -+/// [The new pselect() system call](https://lwn.net/Articles/176911/)
19335 -+///
19336 -+/// [`FdSet::highest`]: struct.FdSet.html#method.highest
19337 -+pub fn pselect<'a, N, R, W, E, T, S>(nfds: N,
19338 -+ readfds: R,
19339 -+ writefds: W,
19340 -+ errorfds: E,
19341 -+ timeout: T,
19342 -+ sigmask: S) -> Result<c_int>
19343 -+where
19344 -+ N: Into<Option<c_int>>,
19345 -+ R: Into<Option<&'a mut FdSet>>,
19346 -+ W: Into<Option<&'a mut FdSet>>,
19347 -+ E: Into<Option<&'a mut FdSet>>,
19348 -+ T: Into<Option<&'a TimeSpec>>,
19349 -+ S: Into<Option<&'a SigSet>>,
19350 -+{
19351 -+ let mut readfds = readfds.into();
19352 -+ let mut writefds = writefds.into();
19353 -+ let mut errorfds = errorfds.into();
19354 -+ let sigmask = sigmask.into();
19355 -+ let timeout = timeout.into();
19356 -+
19357 -+ let nfds = nfds.into().unwrap_or_else(|| {
19358 -+ readfds.iter_mut()
19359 -+ .chain(writefds.iter_mut())
19360 -+ .chain(errorfds.iter_mut())
19361 -+ .map(|set| set.highest().unwrap_or(-1))
19362 -+ .max()
19363 -+ .unwrap_or(-1) + 1
19364 -+ });
19365 -+
19366 -+ let readfds = readfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
19367 -+ let writefds = writefds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
19368 -+ let errorfds = errorfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
19369 -+ let timeout = timeout.map(|ts| ts.as_ref() as *const libc::timespec).unwrap_or(null());
19370 -+ let sigmask = sigmask.map(|sm| sm.as_ref() as *const libc::sigset_t).unwrap_or(null());
19371 -+
19372 -+ let res = unsafe {
19373 -+ libc::pselect(nfds, readfds, writefds, errorfds, timeout, sigmask)
19374 -+ };
19375 -+
19376 -+ Errno::result(res)
19377 -+}
19378 -+
19379 -+
19380 -+#[cfg(test)]
19381 -+mod tests {
19382 -+ use super::*;
19383 -+ use std::os::unix::io::RawFd;
19384 -+ use sys::time::{TimeVal, TimeValLike};
19385 -+ use unistd::{write, pipe};
19386 -+
19387 -+ #[test]
19388 -+ fn fdset_insert() {
19389 -+ let mut fd_set = FdSet::new();
19390 -+
19391 -+ for i in 0..FD_SETSIZE {
19392 -+ assert!(!fd_set.contains(i as RawFd));
19393 -+ }
19394 -+
19395 -+ fd_set.insert(7);
19396 -+
19397 -+ assert!(fd_set.contains(7));
19398 -+ }
19399 -+
19400 -+ #[test]
19401 -+ fn fdset_remove() {
19402 -+ let mut fd_set = FdSet::new();
19403 -+
19404 -+ for i in 0..FD_SETSIZE {
19405 -+ assert!(!fd_set.contains(i as RawFd));
19406 -+ }
19407 -+
19408 -+ fd_set.insert(7);
19409 -+ fd_set.remove(7);
19410 -+
19411 -+ for i in 0..FD_SETSIZE {
19412 -+ assert!(!fd_set.contains(i as RawFd));
19413 -+ }
19414 -+ }
19415 -+
19416 -+ #[test]
19417 -+ fn fdset_clear() {
19418 -+ let mut fd_set = FdSet::new();
19419 -+ fd_set.insert(1);
19420 -+ fd_set.insert((FD_SETSIZE / 2) as RawFd);
19421 -+ fd_set.insert((FD_SETSIZE - 1) as RawFd);
19422 -+
19423 -+ fd_set.clear();
19424 -+
19425 -+ for i in 0..FD_SETSIZE {
19426 -+ assert!(!fd_set.contains(i as RawFd));
19427 -+ }
19428 -+ }
19429 -+
19430 -+ #[test]
19431 -+ fn fdset_highest() {
19432 -+ let mut set = FdSet::new();
19433 -+ assert_eq!(set.highest(), None);
19434 -+ set.insert(0);
19435 -+ assert_eq!(set.highest(), Some(0));
19436 -+ set.insert(90);
19437 -+ assert_eq!(set.highest(), Some(90));
19438 -+ set.remove(0);
19439 -+ assert_eq!(set.highest(), Some(90));
19440 -+ set.remove(90);
19441 -+ assert_eq!(set.highest(), None);
19442 -+
19443 -+ set.insert(4);
19444 -+ set.insert(5);
19445 -+ set.insert(7);
19446 -+ assert_eq!(set.highest(), Some(7));
19447 -+ }
19448 -+
19449 -+ #[test]
19450 -+ fn test_select() {
19451 -+ let (r1, w1) = pipe().unwrap();
19452 -+ write(w1, b"hi!").unwrap();
19453 -+ let (r2, _w2) = pipe().unwrap();
19454 -+
19455 -+ let mut fd_set = FdSet::new();
19456 -+ fd_set.insert(r1);
19457 -+ fd_set.insert(r2);
19458 -+
19459 -+ let mut timeout = TimeVal::seconds(10);
19460 -+ assert_eq!(1, select(None,
19461 -+ &mut fd_set,
19462 -+ None,
19463 -+ None,
19464 -+ &mut timeout).unwrap());
19465 -+ assert!(fd_set.contains(r1));
19466 -+ assert!(!fd_set.contains(r2));
19467 -+ }
19468 -+
19469 -+ #[test]
19470 -+ fn test_select_nfds() {
19471 -+ let (r1, w1) = pipe().unwrap();
19472 -+ write(w1, b"hi!").unwrap();
19473 -+ let (r2, _w2) = pipe().unwrap();
19474 -+
19475 -+ let mut fd_set = FdSet::new();
19476 -+ fd_set.insert(r1);
19477 -+ fd_set.insert(r2);
19478 -+
19479 -+ let mut timeout = TimeVal::seconds(10);
19480 -+ assert_eq!(1, select(Some(fd_set.highest().unwrap() + 1),
19481 -+ &mut fd_set,
19482 -+ None,
19483 -+ None,
19484 -+ &mut timeout).unwrap());
19485 -+ assert!(fd_set.contains(r1));
19486 -+ assert!(!fd_set.contains(r2));
19487 -+ }
19488 -+
19489 -+ #[test]
19490 -+ fn test_select_nfds2() {
19491 -+ let (r1, w1) = pipe().unwrap();
19492 -+ write(w1, b"hi!").unwrap();
19493 -+ let (r2, _w2) = pipe().unwrap();
19494 -+
19495 -+ let mut fd_set = FdSet::new();
19496 -+ fd_set.insert(r1);
19497 -+ fd_set.insert(r2);
19498 -+
19499 -+ let mut timeout = TimeVal::seconds(10);
19500 -+ assert_eq!(1, select(::std::cmp::max(r1, r2) + 1,
19501 -+ &mut fd_set,
19502 -+ None,
19503 -+ None,
19504 -+ &mut timeout).unwrap());
19505 -+ assert!(fd_set.contains(r1));
19506 -+ assert!(!fd_set.contains(r2));
19507 -+ }
19508 -+}
19509 -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
19510 -new file mode 100644
19511 -index 0000000000000..a47d8962f73fb
19512 ---- /dev/null
19513 -+++ b/third_party/rust/nix-0.15.0/src/sys/sendfile.rs
19514 -@@ -0,0 +1,200 @@
19515 -+use std::os::unix::io::RawFd;
19516 -+use std::ptr;
19517 -+
19518 -+use libc::{self, off_t};
19519 -+
19520 -+use Result;
19521 -+use errno::Errno;
19522 -+
19523 -+/// Copy up to `count` bytes to `out_fd` from `in_fd` starting at `offset`.
19524 -+///
19525 -+/// Returns a `Result` with the number of bytes written.
19526 -+///
19527 -+/// If `offset` is `None`, `sendfile` will begin reading at the current offset of `in_fd`and will
19528 -+/// update the offset of `in_fd`. If `offset` is `Some`, `sendfile` will begin at the specified
19529 -+/// offset and will not update the offset of `in_fd`. Instead, it will mutate `offset` to point to
19530 -+/// the byte after the last byte copied.
19531 -+///
19532 -+/// `in_fd` must support `mmap`-like operations and therefore cannot be a socket.
19533 -+///
19534 -+/// For more information, see [the sendfile(2) man page.](http://man7.org/linux/man-pages/man2/sendfile.2.html)
19535 -+#[cfg(any(target_os = "android", target_os = "linux"))]
19536 -+pub fn sendfile(
19537 -+ out_fd: RawFd,
19538 -+ in_fd: RawFd,
19539 -+ offset: Option<&mut off_t>,
19540 -+ count: usize,
19541 -+) -> Result<usize> {
19542 -+ let offset = offset
19543 -+ .map(|offset| offset as *mut _)
19544 -+ .unwrap_or(ptr::null_mut());
19545 -+ let ret = unsafe { libc::sendfile(out_fd, in_fd, offset, count) };
19546 -+ Errno::result(ret).map(|r| r as usize)
19547 -+}
19548 -+
19549 -+cfg_if! {
19550 -+ if #[cfg(any(target_os = "freebsd",
19551 -+ target_os = "ios",
19552 -+ target_os = "macos"))] {
19553 -+ use sys::uio::IoVec;
19554 -+
19555 -+ #[derive(Clone, Debug, Eq, Hash, PartialEq)]
19556 -+ struct SendfileHeaderTrailer<'a>(
19557 -+ libc::sf_hdtr,
19558 -+ Option<Vec<IoVec<&'a [u8]>>>,
19559 -+ Option<Vec<IoVec<&'a [u8]>>>,
19560 -+ );
19561 -+
19562 -+ impl<'a> SendfileHeaderTrailer<'a> {
19563 -+ fn new(
19564 -+ headers: Option<&'a [&'a [u8]]>,
19565 -+ trailers: Option<&'a [&'a [u8]]>
19566 -+ ) -> SendfileHeaderTrailer<'a> {
19567 -+ let header_iovecs: Option<Vec<IoVec<&[u8]>>> =
19568 -+ headers.map(|s| s.iter().map(|b| IoVec::from_slice(b)).collect());
19569 -+ let trailer_iovecs: Option<Vec<IoVec<&[u8]>>> =
19570 -+ trailers.map(|s| s.iter().map(|b| IoVec::from_slice(b)).collect());
19571 -+ SendfileHeaderTrailer(
19572 -+ libc::sf_hdtr {
19573 -+ headers: {
19574 -+ header_iovecs
19575 -+ .as_ref()
19576 -+ .map_or(ptr::null(), |v| v.as_ptr()) as *mut libc::iovec
19577 -+ },
19578 -+ hdr_cnt: header_iovecs.as_ref().map(|v| v.len()).unwrap_or(0) as i32,
19579 -+ trailers: {
19580 -+ trailer_iovecs
19581 -+ .as_ref()
19582 -+ .map_or(ptr::null(), |v| v.as_ptr()) as *mut libc::iovec
19583 -+ },
19584 -+ trl_cnt: trailer_iovecs.as_ref().map(|v| v.len()).unwrap_or(0) as i32
19585 -+ },
19586 -+ header_iovecs,
19587 -+ trailer_iovecs,
19588 -+ )
19589 -+ }
19590 -+ }
19591 -+ }
19592 -+}
19593 -+
19594 -+cfg_if! {
19595 -+ if #[cfg(target_os = "freebsd")] {
19596 -+ use libc::c_int;
19597 -+
19598 -+ libc_bitflags!{
19599 -+ /// Configuration options for [`sendfile`.](fn.sendfile.html)
19600 -+ pub struct SfFlags: c_int {
19601 -+ /// Causes `sendfile` to return EBUSY instead of blocking when attempting to read a
19602 -+ /// busy page.
19603 -+ SF_NODISKIO;
19604 -+ /// Causes `sendfile` to sleep until the network stack releases its reference to the
19605 -+ /// VM pages read. When `sendfile` returns, the data is not guaranteed to have been
19606 -+ /// sent, but it is safe to modify the file.
19607 -+ SF_SYNC;
19608 -+ /// Causes `sendfile` to cache exactly the number of pages specified in the
19609 -+ /// `readahead` parameter, disabling caching heuristics.
19610 -+ SF_USER_READAHEAD;
19611 -+ /// Causes `sendfile` not to cache the data read.
19612 -+ SF_NOCACHE;
19613 -+ }
19614 -+ }
19615 -+
19616 -+ /// Read up to `count` bytes from `in_fd` starting at `offset` and write to `out_sock`.
19617 -+ ///
19618 -+ /// Returns a `Result` and a count of bytes written. Bytes written may be non-zero even if
19619 -+ /// an error occurs.
19620 -+ ///
19621 -+ /// `in_fd` must describe a regular file or shared memory object. `out_sock` must describe a
19622 -+ /// stream socket.
19623 -+ ///
19624 -+ /// If `offset` falls past the end of the file, the function returns success and zero bytes
19625 -+ /// written.
19626 -+ ///
19627 -+ /// If `count` is `None` or 0, bytes will be read from `in_fd` until reaching the end of
19628 -+ /// file (EOF).
19629 -+ ///
19630 -+ /// `headers` and `trailers` specify optional slices of byte slices to be sent before and
19631 -+ /// after the data read from `in_fd`, respectively. The length of headers and trailers sent
19632 -+ /// is included in the returned count of bytes written. The values of `offset` and `count`
19633 -+ /// do not apply to headers or trailers.
19634 -+ ///
19635 -+ /// `readahead` specifies the minimum number of pages to cache in memory ahead of the page
19636 -+ /// currently being sent.
19637 -+ ///
19638 -+ /// For more information, see
19639 -+ /// [the sendfile(2) man page.](https://www.freebsd.org/cgi/man.cgi?query=sendfile&sektion=2)
19640 -+ pub fn sendfile(
19641 -+ in_fd: RawFd,
19642 -+ out_sock: RawFd,
19643 -+ offset: off_t,
19644 -+ count: Option<usize>,
19645 -+ headers: Option<&[&[u8]]>,
19646 -+ trailers: Option<&[&[u8]]>,
19647 -+ flags: SfFlags,
19648 -+ readahead: u16
19649 -+ ) -> (Result<()>, off_t) {
19650 -+ // Readahead goes in upper 16 bits
19651 -+ // Flags goes in lower 16 bits
19652 -+ // see `man 2 sendfile`
19653 -+ let flags: u32 = ((readahead as u32) << 16) | (flags.bits() as u32);
19654 -+ let mut bytes_sent: off_t = 0;
19655 -+ let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers));
19656 -+ let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr);
19657 -+ let return_code = unsafe {
19658 -+ libc::sendfile(in_fd,
19659 -+ out_sock,
19660 -+ offset,
19661 -+ count.unwrap_or(0),
19662 -+ hdtr_ptr as *mut libc::sf_hdtr,
19663 -+ &mut bytes_sent as *mut off_t,
19664 -+ flags as c_int)
19665 -+ };
19666 -+ (Errno::result(return_code).and(Ok(())), bytes_sent)
19667 -+ }
19668 -+ } else if #[cfg(any(target_os = "ios", target_os = "macos"))] {
19669 -+ /// Read bytes from `in_fd` starting at `offset` and write up to `count` bytes to
19670 -+ /// `out_sock`.
19671 -+ ///
19672 -+ /// Returns a `Result` and a count of bytes written. Bytes written may be non-zero even if
19673 -+ /// an error occurs.
19674 -+ ///
19675 -+ /// `in_fd` must describe a regular file. `out_sock` must describe a stream socket.
19676 -+ ///
19677 -+ /// If `offset` falls past the end of the file, the function returns success and zero bytes
19678 -+ /// written.
19679 -+ ///
19680 -+ /// If `count` is `None` or 0, bytes will be read from `in_fd` until reaching the end of
19681 -+ /// file (EOF).
19682 -+ ///
19683 -+ /// `hdtr` specifies an optional list of headers and trailers to be sent before and after
19684 -+ /// the data read from `in_fd`, respectively. The length of headers and trailers sent is
19685 -+ /// included in the returned count of bytes written. If any headers are specified and
19686 -+ /// `count` is non-zero, the length of the headers will be counted in the limit of total
19687 -+ /// bytes sent. Trailers do not count toward the limit of bytes sent and will always be sent
19688 -+ /// regardless. The value of `offset` does not affect headers or trailers.
19689 -+ ///
19690 -+ /// For more information, see
19691 -+ /// [the sendfile(2) man page.](https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man2/sendfile.2.html)
19692 -+ pub fn sendfile(
19693 -+ in_fd: RawFd,
19694 -+ out_sock: RawFd,
19695 -+ offset: off_t,
19696 -+ count: Option<off_t>,
19697 -+ headers: Option<&[&[u8]]>,
19698 -+ trailers: Option<&[&[u8]]>
19699 -+ ) -> (Result<()>, off_t) {
19700 -+ let mut len = count.unwrap_or(0);
19701 -+ let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers));
19702 -+ let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr);
19703 -+ let return_code = unsafe {
19704 -+ libc::sendfile(in_fd,
19705 -+ out_sock,
19706 -+ offset,
19707 -+ &mut len as *mut off_t,
19708 -+ hdtr_ptr as *mut libc::sf_hdtr,
19709 -+ 0)
19710 -+ };
19711 -+ (Errno::result(return_code).and(Ok(())), len)
19712 -+ }
19713 -+ }
19714 -+}
19715 -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
19716 -new file mode 100644
19717 -index 0000000000000..1013a77fd4b40
19718 ---- /dev/null
19719 -+++ b/third_party/rust/nix-0.15.0/src/sys/signal.rs
19720 -@@ -0,0 +1,966 @@
19721 -+// Portions of this file are Copyright 2014 The Rust Project Developers.
19722 -+// See http://rust-lang.org/COPYRIGHT.
19723 -+
19724 -+///! Operating system signals.
19725 -+
19726 -+use libc;
19727 -+use {Error, Result};
19728 -+use errno::Errno;
19729 -+use std::mem;
19730 -+use std::fmt;
19731 -+use std::str::FromStr;
19732 -+#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
19733 -+use std::os::unix::io::RawFd;
19734 -+use std::ptr;
19735 -+
19736 -+#[cfg(not(target_os = "openbsd"))]
19737 -+pub use self::sigevent::*;
19738 -+
19739 -+libc_enum!{
19740 -+ // Currently there is only one definition of c_int in libc, as well as only one
19741 -+ // type for signal constants.
19742 -+ // We would prefer to use the libc::c_int alias in the repr attribute. Unfortunately
19743 -+ // this is not (yet) possible.
19744 -+ #[repr(i32)]
19745 -+ pub enum Signal {
19746 -+ SIGHUP,
19747 -+ SIGINT,
19748 -+ SIGQUIT,
19749 -+ SIGILL,
19750 -+ SIGTRAP,
19751 -+ SIGABRT,
19752 -+ SIGBUS,
19753 -+ SIGFPE,
19754 -+ SIGKILL,
19755 -+ SIGUSR1,
19756 -+ SIGSEGV,
19757 -+ SIGUSR2,
19758 -+ SIGPIPE,
19759 -+ SIGALRM,
19760 -+ SIGTERM,
19761 -+ #[cfg(all(any(target_os = "android", target_os = "emscripten", target_os = "linux"),
19762 -+ not(any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64"))))]
19763 -+ SIGSTKFLT,
19764 -+ SIGCHLD,
19765 -+ SIGCONT,
19766 -+ SIGSTOP,
19767 -+ SIGTSTP,
19768 -+ SIGTTIN,
19769 -+ SIGTTOU,
19770 -+ SIGURG,
19771 -+ SIGXCPU,
19772 -+ SIGXFSZ,
19773 -+ SIGVTALRM,
19774 -+ SIGPROF,
19775 -+ SIGWINCH,
19776 -+ SIGIO,
19777 -+ #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux"))]
19778 -+ SIGPWR,
19779 -+ SIGSYS,
19780 -+ #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
19781 -+ SIGEMT,
19782 -+ #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
19783 -+ SIGINFO,
19784 -+ }
19785 -+}
19786 -+
19787 -+impl FromStr for Signal {
19788 -+ type Err = Error;
19789 -+ fn from_str(s: &str) -> Result<Signal> {
19790 -+ Ok(match s {
19791 -+ "SIGHUP" => Signal::SIGHUP,
19792 -+ "SIGINT" => Signal::SIGINT,
19793 -+ "SIGQUIT" => Signal::SIGQUIT,
19794 -+ "SIGILL" => Signal::SIGILL,
19795 -+ "SIGTRAP" => Signal::SIGTRAP,
19796 -+ "SIGABRT" => Signal::SIGABRT,
19797 -+ "SIGBUS" => Signal::SIGBUS,
19798 -+ "SIGFPE" => Signal::SIGFPE,
19799 -+ "SIGKILL" => Signal::SIGKILL,
19800 -+ "SIGUSR1" => Signal::SIGUSR1,
19801 -+ "SIGSEGV" => Signal::SIGSEGV,
19802 -+ "SIGUSR2" => Signal::SIGUSR2,
19803 -+ "SIGPIPE" => Signal::SIGPIPE,
19804 -+ "SIGALRM" => Signal::SIGALRM,
19805 -+ "SIGTERM" => Signal::SIGTERM,
19806 -+ #[cfg(all(any(target_os = "android", target_os = "emscripten", target_os = "linux"),
19807 -+ not(any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64"))))]
19808 -+ "SIGSTKFLT" => Signal::SIGSTKFLT,
19809 -+ "SIGCHLD" => Signal::SIGCHLD,
19810 -+ "SIGCONT" => Signal::SIGCONT,
19811 -+ "SIGSTOP" => Signal::SIGSTOP,
19812 -+ "SIGTSTP" => Signal::SIGTSTP,
19813 -+ "SIGTTIN" => Signal::SIGTTIN,
19814 -+ "SIGTTOU" => Signal::SIGTTOU,
19815 -+ "SIGURG" => Signal::SIGURG,
19816 -+ "SIGXCPU" => Signal::SIGXCPU,
19817 -+ "SIGXFSZ" => Signal::SIGXFSZ,
19818 -+ "SIGVTALRM" => Signal::SIGVTALRM,
19819 -+ "SIGPROF" => Signal::SIGPROF,
19820 -+ "SIGWINCH" => Signal::SIGWINCH,
19821 -+ "SIGIO" => Signal::SIGIO,
19822 -+ #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux"))]
19823 -+ "SIGPWR" => Signal::SIGPWR,
19824 -+ "SIGSYS" => Signal::SIGSYS,
19825 -+ #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
19826 -+ "SIGEMT" => Signal::SIGEMT,
19827 -+ #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
19828 -+ "SIGINFO" => Signal::SIGINFO,
19829 -+ _ => return Err(Error::invalid_argument()),
19830 -+ })
19831 -+ }
19832 -+}
19833 -+
19834 -+impl AsRef<str> for Signal {
19835 -+ fn as_ref(&self) -> &str {
19836 -+ match *self {
19837 -+ Signal::SIGHUP => "SIGHUP",
19838 -+ Signal::SIGINT => "SIGINT",
19839 -+ Signal::SIGQUIT => "SIGQUIT",
19840 -+ Signal::SIGILL => "SIGILL",
19841 -+ Signal::SIGTRAP => "SIGTRAP",
19842 -+ Signal::SIGABRT => "SIGABRT",
19843 -+ Signal::SIGBUS => "SIGBUS",
19844 -+ Signal::SIGFPE => "SIGFPE",
19845 -+ Signal::SIGKILL => "SIGKILL",
19846 -+ Signal::SIGUSR1 => "SIGUSR1",
19847 -+ Signal::SIGSEGV => "SIGSEGV",
19848 -+ Signal::SIGUSR2 => "SIGUSR2",
19849 -+ Signal::SIGPIPE => "SIGPIPE",
19850 -+ Signal::SIGALRM => "SIGALRM",
19851 -+ Signal::SIGTERM => "SIGTERM",
19852 -+ #[cfg(all(any(target_os = "android", target_os = "emscripten", target_os = "linux"),
19853 -+ not(any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64"))))]
19854 -+ Signal::SIGSTKFLT => "SIGSTKFLT",
19855 -+ Signal::SIGCHLD => "SIGCHLD",
19856 -+ Signal::SIGCONT => "SIGCONT",
19857 -+ Signal::SIGSTOP => "SIGSTOP",
19858 -+ Signal::SIGTSTP => "SIGTSTP",
19859 -+ Signal::SIGTTIN => "SIGTTIN",
19860 -+ Signal::SIGTTOU => "SIGTTOU",
19861 -+ Signal::SIGURG => "SIGURG",
19862 -+ Signal::SIGXCPU => "SIGXCPU",
19863 -+ Signal::SIGXFSZ => "SIGXFSZ",
19864 -+ Signal::SIGVTALRM => "SIGVTALRM",
19865 -+ Signal::SIGPROF => "SIGPROF",
19866 -+ Signal::SIGWINCH => "SIGWINCH",
19867 -+ Signal::SIGIO => "SIGIO",
19868 -+ #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux"))]
19869 -+ Signal::SIGPWR => "SIGPWR",
19870 -+ Signal::SIGSYS => "SIGSYS",
19871 -+ #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
19872 -+ Signal::SIGEMT => "SIGEMT",
19873 -+ #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
19874 -+ Signal::SIGINFO => "SIGINFO",
19875 -+ }
19876 -+ }
19877 -+}
19878 -+
19879 -+impl fmt::Display for Signal {
19880 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
19881 -+ f.write_str(self.as_ref())
19882 -+ }
19883 -+}
19884 -+
19885 -+pub use self::Signal::*;
19886 -+
19887 -+#[cfg(all(any(target_os = "linux", target_os = "android", target_os = "emscripten"), not(any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64"))))]
19888 -+const SIGNALS: [Signal; 31] = [
19889 -+ SIGHUP,
19890 -+ SIGINT,
19891 -+ SIGQUIT,
19892 -+ SIGILL,
19893 -+ SIGTRAP,
19894 -+ SIGABRT,
19895 -+ SIGBUS,
19896 -+ SIGFPE,
19897 -+ SIGKILL,
19898 -+ SIGUSR1,
19899 -+ SIGSEGV,
19900 -+ SIGUSR2,
19901 -+ SIGPIPE,
19902 -+ SIGALRM,
19903 -+ SIGTERM,
19904 -+ SIGSTKFLT,
19905 -+ SIGCHLD,
19906 -+ SIGCONT,
19907 -+ SIGSTOP,
19908 -+ SIGTSTP,
19909 -+ SIGTTIN,
19910 -+ SIGTTOU,
19911 -+ SIGURG,
19912 -+ SIGXCPU,
19913 -+ SIGXFSZ,
19914 -+ SIGVTALRM,
19915 -+ SIGPROF,
19916 -+ SIGWINCH,
19917 -+ SIGIO,
19918 -+ SIGPWR,
19919 -+ SIGSYS];
19920 -+#[cfg(all(any(target_os = "linux", target_os = "android", target_os = "emscripten"), any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64")))]
19921 -+const SIGNALS: [Signal; 30] = [
19922 -+ SIGHUP,
19923 -+ SIGINT,
19924 -+ SIGQUIT,
19925 -+ SIGILL,
19926 -+ SIGTRAP,
19927 -+ SIGABRT,
19928 -+ SIGBUS,
19929 -+ SIGFPE,
19930 -+ SIGKILL,
19931 -+ SIGUSR1,
19932 -+ SIGSEGV,
19933 -+ SIGUSR2,
19934 -+ SIGPIPE,
19935 -+ SIGALRM,
19936 -+ SIGTERM,
19937 -+ SIGCHLD,
19938 -+ SIGCONT,
19939 -+ SIGSTOP,
19940 -+ SIGTSTP,
19941 -+ SIGTTIN,
19942 -+ SIGTTOU,
19943 -+ SIGURG,
19944 -+ SIGXCPU,
19945 -+ SIGXFSZ,
19946 -+ SIGVTALRM,
19947 -+ SIGPROF,
19948 -+ SIGWINCH,
19949 -+ SIGIO,
19950 -+ SIGPWR,
19951 -+ SIGSYS];
19952 -+#[cfg(not(any(target_os = "linux", target_os = "android", target_os = "emscripten")))]
19953 -+const SIGNALS: [Signal; 31] = [
19954 -+ SIGHUP,
19955 -+ SIGINT,
19956 -+ SIGQUIT,
19957 -+ SIGILL,
19958 -+ SIGTRAP,
19959 -+ SIGABRT,
19960 -+ SIGBUS,
19961 -+ SIGFPE,
19962 -+ SIGKILL,
19963 -+ SIGUSR1,
19964 -+ SIGSEGV,
19965 -+ SIGUSR2,
19966 -+ SIGPIPE,
19967 -+ SIGALRM,
19968 -+ SIGTERM,
19969 -+ SIGCHLD,
19970 -+ SIGCONT,
19971 -+ SIGSTOP,
19972 -+ SIGTSTP,
19973 -+ SIGTTIN,
19974 -+ SIGTTOU,
19975 -+ SIGURG,
19976 -+ SIGXCPU,
19977 -+ SIGXFSZ,
19978 -+ SIGVTALRM,
19979 -+ SIGPROF,
19980 -+ SIGWINCH,
19981 -+ SIGIO,
19982 -+ SIGSYS,
19983 -+ SIGEMT,
19984 -+ SIGINFO];
19985 -+
19986 -+pub const NSIG: libc::c_int = 32;
19987 -+
19988 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
19989 -+pub struct SignalIterator {
19990 -+ next: usize,
19991 -+}
19992 -+
19993 -+impl Iterator for SignalIterator {
19994 -+ type Item = Signal;
19995 -+
19996 -+ fn next(&mut self) -> Option<Signal> {
19997 -+ if self.next < SIGNALS.len() {
19998 -+ let next_signal = SIGNALS[self.next];
19999 -+ self.next += 1;
20000 -+ Some(next_signal)
20001 -+ } else {
20002 -+ None
20003 -+ }
20004 -+ }
20005 -+}
20006 -+
20007 -+impl Signal {
20008 -+ pub fn iterator() -> SignalIterator {
20009 -+ SignalIterator{next: 0}
20010 -+ }
20011 -+
20012 -+ // We do not implement the From trait, because it is supposed to be infallible.
20013 -+ // With Rust RFC 1542 comes the appropriate trait TryFrom. Once it is
20014 -+ // implemented, we'll replace this function.
20015 -+ #[inline]
20016 -+ pub fn from_c_int(signum: libc::c_int) -> Result<Signal> {
20017 -+ if 0 < signum && signum < NSIG {
20018 -+ Ok(unsafe { mem::transmute(signum) })
20019 -+ } else {
20020 -+ Err(Error::invalid_argument())
20021 -+ }
20022 -+ }
20023 -+}
20024 -+
20025 -+pub const SIGIOT : Signal = SIGABRT;
20026 -+pub const SIGPOLL : Signal = SIGIO;
20027 -+pub const SIGUNUSED : Signal = SIGSYS;
20028 -+
20029 -+libc_bitflags!{
20030 -+ pub struct SaFlags: libc::c_int {
20031 -+ SA_NOCLDSTOP;
20032 -+ SA_NOCLDWAIT;
20033 -+ SA_NODEFER;
20034 -+ SA_ONSTACK;
20035 -+ SA_RESETHAND;
20036 -+ SA_RESTART;
20037 -+ SA_SIGINFO;
20038 -+ }
20039 -+}
20040 -+
20041 -+libc_enum! {
20042 -+ #[repr(i32)]
20043 -+ pub enum SigmaskHow {
20044 -+ SIG_BLOCK,
20045 -+ SIG_UNBLOCK,
20046 -+ SIG_SETMASK,
20047 -+ }
20048 -+}
20049 -+
20050 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
20051 -+pub struct SigSet {
20052 -+ sigset: libc::sigset_t
20053 -+}
20054 -+
20055 -+
20056 -+impl SigSet {
20057 -+ pub fn all() -> SigSet {
20058 -+ let mut sigset: libc::sigset_t = unsafe { mem::uninitialized() };
20059 -+ let _ = unsafe { libc::sigfillset(&mut sigset as *mut libc::sigset_t) };
20060 -+
20061 -+ SigSet { sigset: sigset }
20062 -+ }
20063 -+
20064 -+ pub fn empty() -> SigSet {
20065 -+ let mut sigset: libc::sigset_t = unsafe { mem::uninitialized() };
20066 -+ let _ = unsafe { libc::sigemptyset(&mut sigset as *mut libc::sigset_t) };
20067 -+
20068 -+ SigSet { sigset: sigset }
20069 -+ }
20070 -+
20071 -+ pub fn add(&mut self, signal: Signal) {
20072 -+ unsafe { libc::sigaddset(&mut self.sigset as *mut libc::sigset_t, signal as libc::c_int) };
20073 -+ }
20074 -+
20075 -+ pub fn clear(&mut self) {
20076 -+ unsafe { libc::sigemptyset(&mut self.sigset as *mut libc::sigset_t) };
20077 -+ }
20078 -+
20079 -+ pub fn remove(&mut self, signal: Signal) {
20080 -+ unsafe { libc::sigdelset(&mut self.sigset as *mut libc::sigset_t, signal as libc::c_int) };
20081 -+ }
20082 -+
20083 -+ pub fn contains(&self, signal: Signal) -> bool {
20084 -+ let res = unsafe { libc::sigismember(&self.sigset as *const libc::sigset_t, signal as libc::c_int) };
20085 -+
20086 -+ match res {
20087 -+ 1 => true,
20088 -+ 0 => false,
20089 -+ _ => unreachable!("unexpected value from sigismember"),
20090 -+ }
20091 -+ }
20092 -+
20093 -+ pub fn extend(&mut self, other: &SigSet) {
20094 -+ for signal in Signal::iterator() {
20095 -+ if other.contains(signal) {
20096 -+ self.add(signal);
20097 -+ }
20098 -+ }
20099 -+ }
20100 -+
20101 -+ /// Gets the currently blocked (masked) set of signals for the calling thread.
20102 -+ pub fn thread_get_mask() -> Result<SigSet> {
20103 -+ let mut oldmask: SigSet = unsafe { mem::uninitialized() };
20104 -+ pthread_sigmask(SigmaskHow::SIG_SETMASK, None, Some(&mut oldmask))?;
20105 -+ Ok(oldmask)
20106 -+ }
20107 -+
20108 -+ /// Sets the set of signals as the signal mask for the calling thread.
20109 -+ pub fn thread_set_mask(&self) -> Result<()> {
20110 -+ pthread_sigmask(SigmaskHow::SIG_SETMASK, Some(self), None)
20111 -+ }
20112 -+
20113 -+ /// Adds the set of signals to the signal mask for the calling thread.
20114 -+ pub fn thread_block(&self) -> Result<()> {
20115 -+ pthread_sigmask(SigmaskHow::SIG_BLOCK, Some(self), None)
20116 -+ }
20117 -+
20118 -+ /// Removes the set of signals from the signal mask for the calling thread.
20119 -+ pub fn thread_unblock(&self) -> Result<()> {
20120 -+ pthread_sigmask(SigmaskHow::SIG_UNBLOCK, Some(self), None)
20121 -+ }
20122 -+
20123 -+ /// Sets the set of signals as the signal mask, and returns the old mask.
20124 -+ pub fn thread_swap_mask(&self, how: SigmaskHow) -> Result<SigSet> {
20125 -+ let mut oldmask: SigSet = unsafe { mem::uninitialized() };
20126 -+ pthread_sigmask(how, Some(self), Some(&mut oldmask))?;
20127 -+ Ok(oldmask)
20128 -+ }
20129 -+
20130 -+ /// Suspends execution of the calling thread until one of the signals in the
20131 -+ /// signal mask becomes pending, and returns the accepted signal.
20132 -+ pub fn wait(&self) -> Result<Signal> {
20133 -+ let mut signum: libc::c_int = unsafe { mem::uninitialized() };
20134 -+ let res = unsafe { libc::sigwait(&self.sigset as *const libc::sigset_t, &mut signum) };
20135 -+
20136 -+ Errno::result(res).map(|_| Signal::from_c_int(signum).unwrap())
20137 -+ }
20138 -+}
20139 -+
20140 -+impl AsRef<libc::sigset_t> for SigSet {
20141 -+ fn as_ref(&self) -> &libc::sigset_t {
20142 -+ &self.sigset
20143 -+ }
20144 -+}
20145 -+
20146 -+/// A signal handler.
20147 -+#[allow(unknown_lints)]
20148 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
20149 -+pub enum SigHandler {
20150 -+ /// Default signal handling.
20151 -+ SigDfl,
20152 -+ /// Request that the signal be ignored.
20153 -+ SigIgn,
20154 -+ /// Use the given signal-catching function, which takes in the signal.
20155 -+ Handler(extern fn(libc::c_int)),
20156 -+ /// Use the given signal-catching function, which takes in the signal, information about how
20157 -+ /// the signal was generated, and a pointer to the threads `ucontext_t`.
20158 -+ SigAction(extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void))
20159 -+}
20160 -+
20161 -+/// Action to take on receipt of a signal. Corresponds to `sigaction`.
20162 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
20163 -+pub struct SigAction {
20164 -+ sigaction: libc::sigaction
20165 -+}
20166 -+
20167 -+impl SigAction {
20168 -+ /// Creates a new action.
20169 -+ ///
20170 -+ /// The `SA_SIGINFO` bit in the `flags` argument is ignored (it will be set only if `handler`
20171 -+ /// is the `SigAction` variant). `mask` specifies other signals to block during execution of
20172 -+ /// the signal-catching function.
20173 -+ pub fn new(handler: SigHandler, flags: SaFlags, mask: SigSet) -> SigAction {
20174 -+ let mut s = unsafe { mem::uninitialized::<libc::sigaction>() };
20175 -+ s.sa_sigaction = match handler {
20176 -+ SigHandler::SigDfl => libc::SIG_DFL,
20177 -+ SigHandler::SigIgn => libc::SIG_IGN,
20178 -+ SigHandler::Handler(f) => f as *const extern fn(libc::c_int) as usize,
20179 -+ SigHandler::SigAction(f) => f as *const extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void) as usize,
20180 -+ };
20181 -+ s.sa_flags = match handler {
20182 -+ SigHandler::SigAction(_) => (flags | SaFlags::SA_SIGINFO).bits(),
20183 -+ _ => (flags - SaFlags::SA_SIGINFO).bits(),
20184 -+ };
20185 -+ s.sa_mask = mask.sigset;
20186 -+
20187 -+ SigAction { sigaction: s }
20188 -+ }
20189 -+
20190 -+ /// Returns the flags set on the action.
20191 -+ pub fn flags(&self) -> SaFlags {
20192 -+ SaFlags::from_bits_truncate(self.sigaction.sa_flags)
20193 -+ }
20194 -+
20195 -+ /// Returns the set of signals that are blocked during execution of the action's
20196 -+ /// signal-catching function.
20197 -+ pub fn mask(&self) -> SigSet {
20198 -+ SigSet { sigset: self.sigaction.sa_mask }
20199 -+ }
20200 -+
20201 -+ /// Returns the action's handler.
20202 -+ pub fn handler(&self) -> SigHandler {
20203 -+ match self.sigaction.sa_sigaction {
20204 -+ libc::SIG_DFL => SigHandler::SigDfl,
20205 -+ libc::SIG_IGN => SigHandler::SigIgn,
20206 -+ f if self.flags().contains(SaFlags::SA_SIGINFO) =>
20207 -+ SigHandler::SigAction( unsafe { mem::transmute(f) } ),
20208 -+ f => SigHandler::Handler( unsafe { mem::transmute(f) } ),
20209 -+ }
20210 -+ }
20211 -+}
20212 -+
20213 -+/// Changes the action taken by a process on receipt of a specific signal.
20214 -+///
20215 -+/// `signal` can be any signal except `SIGKILL` or `SIGSTOP`. On success, it returns the previous
20216 -+/// action for the given signal. If `sigaction` fails, no new signal handler is installed.
20217 -+///
20218 -+/// # Safety
20219 -+///
20220 -+/// Signal handlers may be called at any point during execution, which limits what is safe to do in
20221 -+/// the body of the signal-catching function. Be certain to only make syscalls that are explicitly
20222 -+/// marked safe for signal handlers and only share global data using atomics.
20223 -+pub unsafe fn sigaction(signal: Signal, sigaction: &SigAction) -> Result<SigAction> {
20224 -+ let mut oldact = mem::uninitialized::<libc::sigaction>();
20225 -+
20226 -+ let res =
20227 -+ libc::sigaction(signal as libc::c_int, &sigaction.sigaction as *const libc::sigaction, &mut oldact as *mut libc::sigaction);
20228 -+
20229 -+ Errno::result(res).map(|_| SigAction { sigaction: oldact })
20230 -+}
20231 -+
20232 -+/// Signal management (see [signal(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html))
20233 -+///
20234 -+/// Installs `handler` for the given `signal`, returning the previous signal
20235 -+/// handler. `signal` should only be used following another call to `signal` or
20236 -+/// if the current handler is the default. The return value of `signal` is
20237 -+/// undefined after setting the handler with [`sigaction`][SigActionFn].
20238 -+///
20239 -+/// # Safety
20240 -+///
20241 -+/// If the pointer to the previous signal handler is invalid, undefined
20242 -+/// behavior could be invoked when casting it back to a [`SigAction`][SigActionStruct].
20243 -+///
20244 -+/// # Examples
20245 -+///
20246 -+/// Ignore `SIGINT`:
20247 -+///
20248 -+/// ```no_run
20249 -+/// # use nix::sys::signal::{self, Signal, SigHandler};
20250 -+/// unsafe { signal::signal(Signal::SIGINT, SigHandler::SigIgn) }.unwrap();
20251 -+/// ```
20252 -+///
20253 -+/// Use a signal handler to set a flag variable:
20254 -+///
20255 -+/// ```no_run
20256 -+/// # #[macro_use] extern crate lazy_static;
20257 -+/// # extern crate libc;
20258 -+/// # extern crate nix;
20259 -+/// # use std::sync::atomic::{AtomicBool, Ordering};
20260 -+/// # use nix::sys::signal::{self, Signal, SigHandler};
20261 -+/// lazy_static! {
20262 -+/// static ref SIGNALED: AtomicBool = AtomicBool::new(false);
20263 -+/// }
20264 -+///
20265 -+/// extern fn handle_sigint(signal: libc::c_int) {
20266 -+/// let signal = Signal::from_c_int(signal).unwrap();
20267 -+/// SIGNALED.store(signal == Signal::SIGINT, Ordering::Relaxed);
20268 -+/// }
20269 -+///
20270 -+/// fn main() {
20271 -+/// let handler = SigHandler::Handler(handle_sigint);
20272 -+/// unsafe { signal::signal(Signal::SIGINT, handler) }.unwrap();
20273 -+/// }
20274 -+/// ```
20275 -+///
20276 -+/// # Errors
20277 -+///
20278 -+/// Returns [`Error::UnsupportedOperation`] if `handler` is
20279 -+/// [`SigAction`][SigActionStruct]. Use [`sigaction`][SigActionFn] instead.
20280 -+///
20281 -+/// `signal` also returns any error from `libc::signal`, such as when an attempt
20282 -+/// is made to catch a signal that cannot be caught or to ignore a signal that
20283 -+/// cannot be ignored.
20284 -+///
20285 -+/// [`Error::UnsupportedOperation`]: ../../enum.Error.html#variant.UnsupportedOperation
20286 -+/// [SigActionStruct]: struct.SigAction.html
20287 -+/// [sigactionFn]: fn.sigaction.html
20288 -+pub unsafe fn signal(signal: Signal, handler: SigHandler) -> Result<SigHandler> {
20289 -+ let signal = signal as libc::c_int;
20290 -+ let res = match handler {
20291 -+ SigHandler::SigDfl => libc::signal(signal, libc::SIG_DFL),
20292 -+ SigHandler::SigIgn => libc::signal(signal, libc::SIG_IGN),
20293 -+ SigHandler::Handler(handler) => libc::signal(signal, handler as libc::sighandler_t),
20294 -+ SigHandler::SigAction(_) => return Err(Error::UnsupportedOperation),
20295 -+ };
20296 -+ Errno::result(res).map(|oldhandler| {
20297 -+ match oldhandler {
20298 -+ libc::SIG_DFL => SigHandler::SigDfl,
20299 -+ libc::SIG_IGN => SigHandler::SigIgn,
20300 -+ f => SigHandler::Handler(mem::transmute(f)),
20301 -+ }
20302 -+ })
20303 -+}
20304 -+
20305 -+/// Manages the signal mask (set of blocked signals) for the calling thread.
20306 -+///
20307 -+/// If the `set` parameter is `Some(..)`, then the signal mask will be updated with the signal set.
20308 -+/// The `how` flag decides the type of update. If `set` is `None`, `how` will be ignored,
20309 -+/// and no modification will take place.
20310 -+///
20311 -+/// If the 'oldset' parameter is `Some(..)` then the current signal mask will be written into it.
20312 -+///
20313 -+/// If both `set` and `oldset` is `Some(..)`, the current signal mask will be written into oldset,
20314 -+/// and then it will be updated with `set`.
20315 -+///
20316 -+/// If both `set` and `oldset` is None, this function is a no-op.
20317 -+///
20318 -+/// For more information, visit the [`pthread_sigmask`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_sigmask.html),
20319 -+/// or [`sigprocmask`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html) man pages.
20320 -+pub fn pthread_sigmask(how: SigmaskHow,
20321 -+ set: Option<&SigSet>,
20322 -+ oldset: Option<&mut SigSet>) -> Result<()> {
20323 -+ if set.is_none() && oldset.is_none() {
20324 -+ return Ok(())
20325 -+ }
20326 -+
20327 -+ let res = unsafe {
20328 -+ // if set or oldset is None, pass in null pointers instead
20329 -+ libc::pthread_sigmask(how as libc::c_int,
20330 -+ set.map_or_else(ptr::null::<libc::sigset_t>,
20331 -+ |s| &s.sigset as *const libc::sigset_t),
20332 -+ oldset.map_or_else(ptr::null_mut::<libc::sigset_t>,
20333 -+ |os| &mut os.sigset as *mut libc::sigset_t))
20334 -+ };
20335 -+
20336 -+ Errno::result(res).map(drop)
20337 -+}
20338 -+
20339 -+/// Examine and change blocked signals.
20340 -+///
20341 -+/// For more informations see the [`sigprocmask` man
20342 -+/// pages](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html).
20343 -+pub fn sigprocmask(how: SigmaskHow, set: Option<&SigSet>, oldset: Option<&mut SigSet>) -> Result<()> {
20344 -+ if set.is_none() && oldset.is_none() {
20345 -+ return Ok(())
20346 -+ }
20347 -+
20348 -+ let res = unsafe {
20349 -+ // if set or oldset is None, pass in null pointers instead
20350 -+ libc::sigprocmask(how as libc::c_int,
20351 -+ set.map_or_else(ptr::null::<libc::sigset_t>,
20352 -+ |s| &s.sigset as *const libc::sigset_t),
20353 -+ oldset.map_or_else(ptr::null_mut::<libc::sigset_t>,
20354 -+ |os| &mut os.sigset as *mut libc::sigset_t))
20355 -+ };
20356 -+
20357 -+ Errno::result(res).map(drop)
20358 -+}
20359 -+
20360 -+pub fn kill<T: Into<Option<Signal>>>(pid: ::unistd::Pid, signal: T) -> Result<()> {
20361 -+ let res = unsafe { libc::kill(pid.into(),
20362 -+ match signal.into() {
20363 -+ Some(s) => s as libc::c_int,
20364 -+ None => 0,
20365 -+ }) };
20366 -+
20367 -+ Errno::result(res).map(drop)
20368 -+}
20369 -+
20370 -+/// Send a signal to a process group [(see
20371 -+/// killpg(3))](http://pubs.opengroup.org/onlinepubs/9699919799/functions/killpg.html).
20372 -+///
20373 -+/// If `pgrp` less then or equal 1, the behavior is platform-specific.
20374 -+/// If `signal` is `None`, `killpg` will only preform error checking and won't
20375 -+/// send any signal.
20376 -+pub fn killpg<T: Into<Option<Signal>>>(pgrp: ::unistd::Pid, signal: T) -> Result<()> {
20377 -+ let res = unsafe { libc::killpg(pgrp.into(),
20378 -+ match signal.into() {
20379 -+ Some(s) => s as libc::c_int,
20380 -+ None => 0,
20381 -+ }) };
20382 -+
20383 -+ Errno::result(res).map(drop)
20384 -+}
20385 -+
20386 -+pub fn raise(signal: Signal) -> Result<()> {
20387 -+ let res = unsafe { libc::raise(signal as libc::c_int) };
20388 -+
20389 -+ Errno::result(res).map(drop)
20390 -+}
20391 -+
20392 -+
20393 -+#[cfg(target_os = "freebsd")]
20394 -+pub type type_of_thread_id = libc::lwpid_t;
20395 -+#[cfg(target_os = "linux")]
20396 -+pub type type_of_thread_id = libc::pid_t;
20397 -+
20398 -+/// Used to request asynchronous notification of certain events, for example,
20399 -+/// with POSIX AIO, POSIX message queues, and POSIX timers.
20400 -+// sigval is actually a union of a int and a void*. But it's never really used
20401 -+// as a pointer, because neither libc nor the kernel ever dereference it. nix
20402 -+// therefore presents it as an intptr_t, which is how kevent uses it.
20403 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
20404 -+pub enum SigevNotify {
20405 -+ /// No notification will be delivered
20406 -+ SigevNone,
20407 -+ /// The signal given by `signal` will be delivered to the process. The
20408 -+ /// value in `si_value` will be present in the `si_value` field of the
20409 -+ /// `siginfo_t` structure of the queued signal.
20410 -+ SigevSignal { signal: Signal, si_value: libc::intptr_t },
20411 -+ // Note: SIGEV_THREAD is not implemented because libc::sigevent does not
20412 -+ // expose a way to set the union members needed by SIGEV_THREAD.
20413 -+ /// A new `kevent` is posted to the kqueue `kq`. The `kevent`'s `udata`
20414 -+ /// field will contain the value in `udata`.
20415 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
20416 -+ SigevKevent { kq: RawFd, udata: libc::intptr_t },
20417 -+ /// The signal `signal` is queued to the thread whose LWP ID is given in
20418 -+ /// `thread_id`. The value stored in `si_value` will be present in the
20419 -+ /// `si_value` of the `siginfo_t` structure of the queued signal.
20420 -+ #[cfg(any(target_os = "freebsd", target_os = "linux"))]
20421 -+ SigevThreadId { signal: Signal, thread_id: type_of_thread_id,
20422 -+ si_value: libc::intptr_t },
20423 -+}
20424 -+
20425 -+#[cfg(not(target_os = "openbsd"))]
20426 -+mod sigevent {
20427 -+ use libc;
20428 -+ use std::mem;
20429 -+ use std::ptr;
20430 -+ use super::SigevNotify;
20431 -+ #[cfg(any(target_os = "freebsd", target_os = "linux"))]
20432 -+ use super::type_of_thread_id;
20433 -+
20434 -+ /// Used to request asynchronous notification of the completion of certain
20435 -+ /// events, such as POSIX AIO and timers.
20436 -+ #[repr(C)]
20437 -+ #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
20438 -+ pub struct SigEvent {
20439 -+ sigevent: libc::sigevent
20440 -+ }
20441 -+
20442 -+ impl SigEvent {
20443 -+ /// **Note:** this constructor does not allow the user to set the
20444 -+ /// `sigev_notify_kevent_flags` field. That's considered ok because on FreeBSD
20445 -+ /// at least those flags don't do anything useful. That field is part of a
20446 -+ /// union that shares space with the more genuinely useful fields.
20447 -+ ///
20448 -+ /// **Note:** This constructor also doesn't allow the caller to set the
20449 -+ /// `sigev_notify_function` or `sigev_notify_attributes` fields, which are
20450 -+ /// required for `SIGEV_THREAD`. That's considered ok because on no operating
20451 -+ /// system is `SIGEV_THREAD` the most efficient way to deliver AIO
20452 -+ /// notification. FreeBSD and DragonFly BSD programs should prefer `SIGEV_KEVENT`.
20453 -+ /// Linux, Solaris, and portable programs should prefer `SIGEV_THREAD_ID` or
20454 -+ /// `SIGEV_SIGNAL`. That field is part of a union that shares space with the
20455 -+ /// more genuinely useful `sigev_notify_thread_id`
20456 -+ pub fn new(sigev_notify: SigevNotify) -> SigEvent {
20457 -+ let mut sev = unsafe { mem::zeroed::<libc::sigevent>()};
20458 -+ sev.sigev_notify = match sigev_notify {
20459 -+ SigevNotify::SigevNone => libc::SIGEV_NONE,
20460 -+ SigevNotify::SigevSignal{..} => libc::SIGEV_SIGNAL,
20461 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
20462 -+ SigevNotify::SigevKevent{..} => libc::SIGEV_KEVENT,
20463 -+ #[cfg(target_os = "freebsd")]
20464 -+ SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID,
20465 -+ #[cfg(all(target_os = "linux", target_env = "gnu", not(target_arch = "mips")))]
20466 -+ SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID,
20467 -+ #[cfg(any(all(target_os = "linux", target_env = "musl"), target_arch = "mips"))]
20468 -+ SigevNotify::SigevThreadId{..} => 4 // No SIGEV_THREAD_ID defined
20469 -+ };
20470 -+ sev.sigev_signo = match sigev_notify {
20471 -+ SigevNotify::SigevSignal{ signal, .. } => signal as libc::c_int,
20472 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
20473 -+ SigevNotify::SigevKevent{ kq, ..} => kq,
20474 -+ #[cfg(any(target_os = "linux", target_os = "freebsd"))]
20475 -+ SigevNotify::SigevThreadId{ signal, .. } => signal as libc::c_int,
20476 -+ _ => 0
20477 -+ };
20478 -+ sev.sigev_value.sival_ptr = match sigev_notify {
20479 -+ SigevNotify::SigevNone => ptr::null_mut::<libc::c_void>(),
20480 -+ SigevNotify::SigevSignal{ si_value, .. } => si_value as *mut libc::c_void,
20481 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
20482 -+ SigevNotify::SigevKevent{ udata, .. } => udata as *mut libc::c_void,
20483 -+ #[cfg(any(target_os = "freebsd", target_os = "linux"))]
20484 -+ SigevNotify::SigevThreadId{ si_value, .. } => si_value as *mut libc::c_void,
20485 -+ };
20486 -+ SigEvent::set_tid(&mut sev, &sigev_notify);
20487 -+ SigEvent{sigevent: sev}
20488 -+ }
20489 -+
20490 -+ #[cfg(any(target_os = "freebsd", target_os = "linux"))]
20491 -+ fn set_tid(sev: &mut libc::sigevent, sigev_notify: &SigevNotify) {
20492 -+ sev.sigev_notify_thread_id = match *sigev_notify {
20493 -+ SigevNotify::SigevThreadId { thread_id, .. } => thread_id,
20494 -+ _ => 0 as type_of_thread_id
20495 -+ };
20496 -+ }
20497 -+
20498 -+ #[cfg(not(any(target_os = "freebsd", target_os = "linux")))]
20499 -+ fn set_tid(_sev: &mut libc::sigevent, _sigev_notify: &SigevNotify) {
20500 -+ }
20501 -+
20502 -+ pub fn sigevent(&self) -> libc::sigevent {
20503 -+ self.sigevent
20504 -+ }
20505 -+ }
20506 -+
20507 -+ impl<'a> From<&'a libc::sigevent> for SigEvent {
20508 -+ fn from(sigevent: &libc::sigevent) -> Self {
20509 -+ SigEvent{ sigevent: *sigevent }
20510 -+ }
20511 -+ }
20512 -+}
20513 -+
20514 -+#[cfg(test)]
20515 -+mod tests {
20516 -+ use std::thread;
20517 -+ use super::*;
20518 -+
20519 -+ #[test]
20520 -+ fn test_contains() {
20521 -+ let mut mask = SigSet::empty();
20522 -+ mask.add(SIGUSR1);
20523 -+
20524 -+ assert!(mask.contains(SIGUSR1));
20525 -+ assert!(!mask.contains(SIGUSR2));
20526 -+
20527 -+ let all = SigSet::all();
20528 -+ assert!(all.contains(SIGUSR1));
20529 -+ assert!(all.contains(SIGUSR2));
20530 -+ }
20531 -+
20532 -+ #[test]
20533 -+ fn test_clear() {
20534 -+ let mut set = SigSet::all();
20535 -+ set.clear();
20536 -+ for signal in Signal::iterator() {
20537 -+ assert!(!set.contains(signal));
20538 -+ }
20539 -+ }
20540 -+
20541 -+ #[test]
20542 -+ fn test_from_str_round_trips() {
20543 -+ for signal in Signal::iterator() {
20544 -+ assert_eq!(signal.as_ref().parse::<Signal>().unwrap(), signal);
20545 -+ assert_eq!(signal.to_string().parse::<Signal>().unwrap(), signal);
20546 -+ }
20547 -+ }
20548 -+
20549 -+ #[test]
20550 -+ fn test_from_str_invalid_value() {
20551 -+ let errval = Err(Error::Sys(Errno::EINVAL));
20552 -+ assert_eq!("NOSIGNAL".parse::<Signal>(), errval);
20553 -+ assert_eq!("kill".parse::<Signal>(), errval);
20554 -+ assert_eq!("9".parse::<Signal>(), errval);
20555 -+ }
20556 -+
20557 -+ #[test]
20558 -+ fn test_extend() {
20559 -+ let mut one_signal = SigSet::empty();
20560 -+ one_signal.add(SIGUSR1);
20561 -+
20562 -+ let mut two_signals = SigSet::empty();
20563 -+ two_signals.add(SIGUSR2);
20564 -+ two_signals.extend(&one_signal);
20565 -+
20566 -+ assert!(two_signals.contains(SIGUSR1));
20567 -+ assert!(two_signals.contains(SIGUSR2));
20568 -+ }
20569 -+
20570 -+ #[test]
20571 -+ fn test_thread_signal_set_mask() {
20572 -+ thread::spawn(|| {
20573 -+ let prev_mask = SigSet::thread_get_mask()
20574 -+ .expect("Failed to get existing signal mask!");
20575 -+
20576 -+ let mut test_mask = prev_mask;
20577 -+ test_mask.add(SIGUSR1);
20578 -+
20579 -+ assert!(test_mask.thread_set_mask().is_ok());
20580 -+ let new_mask = SigSet::thread_get_mask()
20581 -+ .expect("Failed to get new mask!");
20582 -+
20583 -+ assert!(new_mask.contains(SIGUSR1));
20584 -+ assert!(!new_mask.contains(SIGUSR2));
20585 -+
20586 -+ prev_mask.thread_set_mask().expect("Failed to revert signal mask!");
20587 -+ }).join().unwrap();
20588 -+ }
20589 -+
20590 -+ #[test]
20591 -+ fn test_thread_signal_block() {
20592 -+ thread::spawn(|| {
20593 -+ let mut mask = SigSet::empty();
20594 -+ mask.add(SIGUSR1);
20595 -+
20596 -+ assert!(mask.thread_block().is_ok());
20597 -+
20598 -+ assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR1));
20599 -+ }).join().unwrap();
20600 -+ }
20601 -+
20602 -+ #[test]
20603 -+ fn test_thread_signal_unblock() {
20604 -+ thread::spawn(|| {
20605 -+ let mut mask = SigSet::empty();
20606 -+ mask.add(SIGUSR1);
20607 -+
20608 -+ assert!(mask.thread_unblock().is_ok());
20609 -+
20610 -+ assert!(!SigSet::thread_get_mask().unwrap().contains(SIGUSR1));
20611 -+ }).join().unwrap();
20612 -+ }
20613 -+
20614 -+ #[test]
20615 -+ fn test_thread_signal_swap() {
20616 -+ thread::spawn(|| {
20617 -+ let mut mask = SigSet::empty();
20618 -+ mask.add(SIGUSR1);
20619 -+ mask.thread_block().unwrap();
20620 -+
20621 -+ assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR1));
20622 -+
20623 -+ let mut mask2 = SigSet::empty();
20624 -+ mask2.add(SIGUSR2);
20625 -+
20626 -+ let oldmask = mask2.thread_swap_mask(SigmaskHow::SIG_SETMASK)
20627 -+ .unwrap();
20628 -+
20629 -+ assert!(oldmask.contains(SIGUSR1));
20630 -+ assert!(!oldmask.contains(SIGUSR2));
20631 -+
20632 -+ assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR2));
20633 -+ }).join().unwrap();
20634 -+ }
20635 -+
20636 -+ #[test]
20637 -+ fn test_sigaction() {
20638 -+ use libc;
20639 -+ thread::spawn(|| {
20640 -+ extern fn test_sigaction_handler(_: libc::c_int) {}
20641 -+ extern fn test_sigaction_action(_: libc::c_int,
20642 -+ _: *mut libc::siginfo_t, _: *mut libc::c_void) {}
20643 -+
20644 -+ let handler_sig = SigHandler::Handler(test_sigaction_handler);
20645 -+
20646 -+ let flags = SaFlags::SA_ONSTACK | SaFlags::SA_RESTART |
20647 -+ SaFlags::SA_SIGINFO;
20648 -+
20649 -+ let mut mask = SigSet::empty();
20650 -+ mask.add(SIGUSR1);
20651 -+
20652 -+ let action_sig = SigAction::new(handler_sig, flags, mask);
20653 -+
20654 -+ assert_eq!(action_sig.flags(),
20655 -+ SaFlags::SA_ONSTACK | SaFlags::SA_RESTART);
20656 -+ assert_eq!(action_sig.handler(), handler_sig);
20657 -+
20658 -+ mask = action_sig.mask();
20659 -+ assert!(mask.contains(SIGUSR1));
20660 -+ assert!(!mask.contains(SIGUSR2));
20661 -+
20662 -+ let handler_act = SigHandler::SigAction(test_sigaction_action);
20663 -+ let action_act = SigAction::new(handler_act, flags, mask);
20664 -+ assert_eq!(action_act.handler(), handler_act);
20665 -+
20666 -+ let action_dfl = SigAction::new(SigHandler::SigDfl, flags, mask);
20667 -+ assert_eq!(action_dfl.handler(), SigHandler::SigDfl);
20668 -+
20669 -+ let action_ign = SigAction::new(SigHandler::SigIgn, flags, mask);
20670 -+ assert_eq!(action_ign.handler(), SigHandler::SigIgn);
20671 -+ }).join().unwrap();
20672 -+ }
20673 -+
20674 -+ #[test]
20675 -+ fn test_sigwait() {
20676 -+ thread::spawn(|| {
20677 -+ let mut mask = SigSet::empty();
20678 -+ mask.add(SIGUSR1);
20679 -+ mask.add(SIGUSR2);
20680 -+ mask.thread_block().unwrap();
20681 -+
20682 -+ raise(SIGUSR1).unwrap();
20683 -+ assert_eq!(mask.wait().unwrap(), SIGUSR1);
20684 -+ }).join().unwrap();
20685 -+ }
20686 -+}
20687 -diff --git a/third_party/rust/nix-0.15.0/src/sys/signalfd.rs b/third_party/rust/nix-0.15.0/src/sys/signalfd.rs
20688 -new file mode 100644
20689 -index 0000000000000..5425a27be9e52
20690 ---- /dev/null
20691 -+++ b/third_party/rust/nix-0.15.0/src/sys/signalfd.rs
20692 -@@ -0,0 +1,170 @@
20693 -+//! Interface for the `signalfd` syscall.
20694 -+//!
20695 -+//! # Signal discarding
20696 -+//! When a signal can't be delivered to a process (or thread), it will become a pending signal.
20697 -+//! Failure to deliver could happen if the signal is blocked by every thread in the process or if
20698 -+//! the signal handler is still handling a previous signal.
20699 -+//!
20700 -+//! If a signal is sent to a process (or thread) that already has a pending signal of the same
20701 -+//! type, it will be discarded. This means that if signals of the same type are received faster than
20702 -+//! they are processed, some of those signals will be dropped. Because of this limitation,
20703 -+//! `signalfd` in itself cannot be used for reliable communication between processes or threads.
20704 -+//!
20705 -+//! Once the signal is unblocked, or the signal handler is finished, and a signal is still pending
20706 -+//! (ie. not consumed from a signalfd) it will be delivered to the signal handler.
20707 -+//!
20708 -+//! Please note that signal discarding is not specific to `signalfd`, but also happens with regular
20709 -+//! signal handlers.
20710 -+use libc;
20711 -+use unistd;
20712 -+use {Error, Result};
20713 -+use errno::Errno;
20714 -+pub use sys::signal::{self, SigSet};
20715 -+pub use libc::signalfd_siginfo as siginfo;
20716 -+
20717 -+use std::os::unix::io::{RawFd, AsRawFd};
20718 -+use std::mem;
20719 -+
20720 -+
20721 -+libc_bitflags!{
20722 -+ pub struct SfdFlags: libc::c_int {
20723 -+ SFD_NONBLOCK;
20724 -+ SFD_CLOEXEC;
20725 -+ }
20726 -+}
20727 -+
20728 -+pub const SIGNALFD_NEW: RawFd = -1;
20729 -+pub const SIGNALFD_SIGINFO_SIZE: usize = 128;
20730 -+
20731 -+/// Creates a new file descriptor for reading signals.
20732 -+///
20733 -+/// **Important:** please read the module level documentation about signal discarding before using
20734 -+/// this function!
20735 -+///
20736 -+/// The `mask` parameter specifies the set of signals that can be accepted via this file descriptor.
20737 -+///
20738 -+/// A signal must be blocked on every thread in a process, otherwise it won't be visible from
20739 -+/// signalfd (the default handler will be invoked instead).
20740 -+///
20741 -+/// See [the signalfd man page for more information](http://man7.org/linux/man-pages/man2/signalfd.2.html)
20742 -+pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result<RawFd> {
20743 -+ unsafe {
20744 -+ Errno::result(libc::signalfd(fd as libc::c_int, mask.as_ref(), flags.bits()))
20745 -+ }
20746 -+}
20747 -+
20748 -+/// A helper struct for creating, reading and closing a `signalfd` instance.
20749 -+///
20750 -+/// **Important:** please read the module level documentation about signal discarding before using
20751 -+/// this struct!
20752 -+///
20753 -+/// # Examples
20754 -+///
20755 -+/// ```
20756 -+/// # use nix::sys::signalfd::*;
20757 -+/// // Set the thread to block the SIGUSR1 signal, otherwise the default handler will be used
20758 -+/// let mut mask = SigSet::empty();
20759 -+/// mask.add(signal::SIGUSR1);
20760 -+/// mask.thread_block().unwrap();
20761 -+///
20762 -+/// // Signals are queued up on the file descriptor
20763 -+/// let mut sfd = SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap();
20764 -+///
20765 -+/// match sfd.read_signal() {
20766 -+/// // we caught a signal
20767 -+/// Ok(Some(sig)) => (),
20768 -+/// // there were no signals waiting (only happens when the SFD_NONBLOCK flag is set,
20769 -+/// // otherwise the read_signal call blocks)
20770 -+/// Ok(None) => (),
20771 -+/// Err(err) => (), // some error happend
20772 -+/// }
20773 -+/// ```
20774 -+#[derive(Clone, Debug, Eq, Hash, PartialEq)]
20775 -+pub struct SignalFd(RawFd);
20776 -+
20777 -+impl SignalFd {
20778 -+ pub fn new(mask: &SigSet) -> Result<SignalFd> {
20779 -+ Self::with_flags(mask, SfdFlags::empty())
20780 -+ }
20781 -+
20782 -+ pub fn with_flags(mask: &SigSet, flags: SfdFlags) -> Result<SignalFd> {
20783 -+ let fd = signalfd(SIGNALFD_NEW, mask, flags)?;
20784 -+
20785 -+ Ok(SignalFd(fd))
20786 -+ }
20787 -+
20788 -+ pub fn set_mask(&mut self, mask: &SigSet) -> Result<()> {
20789 -+ signalfd(self.0, mask, SfdFlags::empty()).map(drop)
20790 -+ }
20791 -+
20792 -+ pub fn read_signal(&mut self) -> Result<Option<siginfo>> {
20793 -+ let mut buffer: [u8; SIGNALFD_SIGINFO_SIZE] = unsafe { mem::uninitialized() };
20794 -+
20795 -+ match unistd::read(self.0, &mut buffer) {
20796 -+ Ok(SIGNALFD_SIGINFO_SIZE) => Ok(Some(unsafe { mem::transmute(buffer) })),
20797 -+ Ok(_) => unreachable!("partial read on signalfd"),
20798 -+ Err(Error::Sys(Errno::EAGAIN)) => Ok(None),
20799 -+ Err(error) => Err(error)
20800 -+ }
20801 -+ }
20802 -+}
20803 -+
20804 -+impl Drop for SignalFd {
20805 -+ fn drop(&mut self) {
20806 -+ let _ = unistd::close(self.0);
20807 -+ }
20808 -+}
20809 -+
20810 -+impl AsRawFd for SignalFd {
20811 -+ fn as_raw_fd(&self) -> RawFd {
20812 -+ self.0
20813 -+ }
20814 -+}
20815 -+
20816 -+impl Iterator for SignalFd {
20817 -+ type Item = siginfo;
20818 -+
20819 -+ fn next(&mut self) -> Option<Self::Item> {
20820 -+ match self.read_signal() {
20821 -+ Ok(Some(sig)) => Some(sig),
20822 -+ Ok(None) | Err(_) => None,
20823 -+ }
20824 -+ }
20825 -+}
20826 -+
20827 -+
20828 -+#[cfg(test)]
20829 -+mod tests {
20830 -+ use super::*;
20831 -+ use std::mem;
20832 -+ use libc;
20833 -+
20834 -+
20835 -+ #[test]
20836 -+ fn check_siginfo_size() {
20837 -+ assert_eq!(mem::size_of::<libc::signalfd_siginfo>(), SIGNALFD_SIGINFO_SIZE);
20838 -+ }
20839 -+
20840 -+ #[test]
20841 -+ fn create_signalfd() {
20842 -+ let mask = SigSet::empty();
20843 -+ let fd = SignalFd::new(&mask);
20844 -+ assert!(fd.is_ok());
20845 -+ }
20846 -+
20847 -+ #[test]
20848 -+ fn create_signalfd_with_opts() {
20849 -+ let mask = SigSet::empty();
20850 -+ let fd = SignalFd::with_flags(&mask, SfdFlags::SFD_CLOEXEC | SfdFlags::SFD_NONBLOCK);
20851 -+ assert!(fd.is_ok());
20852 -+ }
20853 -+
20854 -+ #[test]
20855 -+ fn read_empty_signalfd() {
20856 -+ let mask = SigSet::empty();
20857 -+ let mut fd = SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap();
20858 -+
20859 -+ let res = fd.read_signal();
20860 -+ assert!(res.unwrap().is_none());
20861 -+ }
20862 -+}
20863 -diff --git a/third_party/rust/nix-0.15.0/src/sys/socket/addr.rs b/third_party/rust/nix-0.15.0/src/sys/socket/addr.rs
20864 -new file mode 100644
20865 -index 0000000000000..ed41441155361
20866 ---- /dev/null
20867 -+++ b/third_party/rust/nix-0.15.0/src/sys/socket/addr.rs
20868 -@@ -0,0 +1,1278 @@
20869 -+use super::sa_family_t;
20870 -+use {Error, Result, NixPath};
20871 -+use errno::Errno;
20872 -+use libc;
20873 -+use std::{fmt, mem, net, ptr, slice};
20874 -+use std::ffi::OsStr;
20875 -+use std::hash::{Hash, Hasher};
20876 -+use std::path::Path;
20877 -+use std::os::unix::ffi::OsStrExt;
20878 -+#[cfg(any(target_os = "android", target_os = "linux"))]
20879 -+use ::sys::socket::addr::netlink::NetlinkAddr;
20880 -+#[cfg(any(target_os = "android", target_os = "linux"))]
20881 -+use ::sys::socket::addr::alg::AlgAddr;
20882 -+#[cfg(any(target_os = "ios", target_os = "macos"))]
20883 -+use std::os::unix::io::RawFd;
20884 -+#[cfg(any(target_os = "ios", target_os = "macos"))]
20885 -+use ::sys::socket::addr::sys_control::SysControlAddr;
20886 -+#[cfg(any(target_os = "android",
20887 -+ target_os = "dragonfly",
20888 -+ target_os = "freebsd",
20889 -+ target_os = "ios",
20890 -+ target_os = "linux",
20891 -+ target_os = "macos",
20892 -+ target_os = "netbsd",
20893 -+ target_os = "openbsd"))]
20894 -+pub use self::datalink::LinkAddr;
20895 -+#[cfg(target_os = "linux")]
20896 -+pub use self::vsock::VsockAddr;
20897 -+
20898 -+/// These constants specify the protocol family to be used
20899 -+/// in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html)
20900 -+#[repr(i32)]
20901 -+#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
20902 -+pub enum AddressFamily {
20903 -+ /// Local communication (see [`unix(7)`](http://man7.org/linux/man-pages/man7/unix.7.html))
20904 -+ Unix = libc::AF_UNIX,
20905 -+ /// IPv4 Internet protocols (see [`ip(7)`](http://man7.org/linux/man-pages/man7/ip.7.html))
20906 -+ Inet = libc::AF_INET,
20907 -+ /// IPv6 Internet protocols (see [`ipv6(7)`](http://man7.org/linux/man-pages/man7/ipv6.7.html))
20908 -+ Inet6 = libc::AF_INET6,
20909 -+ /// Kernel user interface device (see [`netlink(7)`](http://man7.org/linux/man-pages/man7/netlink.7.html))
20910 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20911 -+ Netlink = libc::AF_NETLINK,
20912 -+ /// Low level packet interface (see [`packet(7)`](http://man7.org/linux/man-pages/man7/packet.7.html))
20913 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20914 -+ Packet = libc::AF_PACKET,
20915 -+ /// KEXT Controls and Notifications
20916 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
20917 -+ System = libc::AF_SYSTEM,
20918 -+ /// Amateur radio AX.25 protocol
20919 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20920 -+ Ax25 = libc::AF_AX25,
20921 -+ /// IPX - Novell protocols
20922 -+ Ipx = libc::AF_IPX,
20923 -+ /// AppleTalk
20924 -+ AppleTalk = libc::AF_APPLETALK,
20925 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20926 -+ NetRom = libc::AF_NETROM,
20927 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20928 -+ Bridge = libc::AF_BRIDGE,
20929 -+ /// Access to raw ATM PVCs
20930 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20931 -+ AtmPvc = libc::AF_ATMPVC,
20932 -+ /// ITU-T X.25 / ISO-8208 protocol (see [`x25(7)`](http://man7.org/linux/man-pages/man7/x25.7.html))
20933 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20934 -+ X25 = libc::AF_X25,
20935 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20936 -+ Rose = libc::AF_ROSE,
20937 -+ Decnet = libc::AF_DECnet,
20938 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20939 -+ NetBeui = libc::AF_NETBEUI,
20940 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20941 -+ Security = libc::AF_SECURITY,
20942 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20943 -+ Key = libc::AF_KEY,
20944 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20945 -+ Ash = libc::AF_ASH,
20946 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20947 -+ Econet = libc::AF_ECONET,
20948 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20949 -+ AtmSvc = libc::AF_ATMSVC,
20950 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20951 -+ Rds = libc::AF_RDS,
20952 -+ Sna = libc::AF_SNA,
20953 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20954 -+ Irda = libc::AF_IRDA,
20955 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20956 -+ Pppox = libc::AF_PPPOX,
20957 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20958 -+ Wanpipe = libc::AF_WANPIPE,
20959 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20960 -+ Llc = libc::AF_LLC,
20961 -+ #[cfg(target_os = "linux")]
20962 -+ Ib = libc::AF_IB,
20963 -+ #[cfg(target_os = "linux")]
20964 -+ Mpls = libc::AF_MPLS,
20965 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20966 -+ Can = libc::AF_CAN,
20967 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20968 -+ Tipc = libc::AF_TIPC,
20969 -+ #[cfg(not(any(target_os = "ios", target_os = "macos")))]
20970 -+ Bluetooth = libc::AF_BLUETOOTH,
20971 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20972 -+ Iucv = libc::AF_IUCV,
20973 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20974 -+ RxRpc = libc::AF_RXRPC,
20975 -+ Isdn = libc::AF_ISDN,
20976 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20977 -+ Phonet = libc::AF_PHONET,
20978 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20979 -+ Ieee802154 = libc::AF_IEEE802154,
20980 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20981 -+ Caif = libc::AF_CAIF,
20982 -+ /// Interface to kernel crypto API
20983 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
20984 -+ Alg = libc::AF_ALG,
20985 -+ #[cfg(target_os = "linux")]
20986 -+ Nfc = libc::AF_NFC,
20987 -+ #[cfg(target_os = "linux")]
20988 -+ Vsock = libc::AF_VSOCK,
20989 -+ #[cfg(any(target_os = "dragonfly",
20990 -+ target_os = "freebsd",
20991 -+ target_os = "ios",
20992 -+ target_os = "macos",
20993 -+ target_os = "netbsd",
20994 -+ target_os = "openbsd"))]
20995 -+ ImpLink = libc::AF_IMPLINK,
20996 -+ #[cfg(any(target_os = "dragonfly",
20997 -+ target_os = "freebsd",
20998 -+ target_os = "ios",
20999 -+ target_os = "macos",
21000 -+ target_os = "netbsd",
21001 -+ target_os = "openbsd"))]
21002 -+ Pup = libc::AF_PUP,
21003 -+ #[cfg(any(target_os = "dragonfly",
21004 -+ target_os = "freebsd",
21005 -+ target_os = "ios",
21006 -+ target_os = "macos",
21007 -+ target_os = "netbsd",
21008 -+ target_os = "openbsd"))]
21009 -+ Chaos = libc::AF_CHAOS,
21010 -+ #[cfg(any(target_os = "ios",
21011 -+ target_os = "macos",
21012 -+ target_os = "netbsd",
21013 -+ target_os = "openbsd"))]
21014 -+ Ns = libc::AF_NS,
21015 -+ #[cfg(any(target_os = "dragonfly",
21016 -+ target_os = "freebsd",
21017 -+ target_os = "ios",
21018 -+ target_os = "macos",
21019 -+ target_os = "netbsd",
21020 -+ target_os = "openbsd"))]
21021 -+ Iso = libc::AF_ISO,
21022 -+ #[cfg(any(target_os = "dragonfly",
21023 -+ target_os = "freebsd",
21024 -+ target_os = "ios",
21025 -+ target_os = "macos",
21026 -+ target_os = "netbsd",
21027 -+ target_os = "openbsd"))]
21028 -+ Datakit = libc::AF_DATAKIT,
21029 -+ #[cfg(any(target_os = "dragonfly",
21030 -+ target_os = "freebsd",
21031 -+ target_os = "ios",
21032 -+ target_os = "macos",
21033 -+ target_os = "netbsd",
21034 -+ target_os = "openbsd"))]
21035 -+ Ccitt = libc::AF_CCITT,
21036 -+ #[cfg(any(target_os = "dragonfly",
21037 -+ target_os = "freebsd",
21038 -+ target_os = "ios",
21039 -+ target_os = "macos",
21040 -+ target_os = "netbsd",
21041 -+ target_os = "openbsd"))]
21042 -+ Dli = libc::AF_DLI,
21043 -+ #[cfg(any(target_os = "dragonfly",
21044 -+ target_os = "freebsd",
21045 -+ target_os = "ios",
21046 -+ target_os = "macos",
21047 -+ target_os = "netbsd",
21048 -+ target_os = "openbsd"))]
21049 -+ Lat = libc::AF_LAT,
21050 -+ #[cfg(any(target_os = "dragonfly",
21051 -+ target_os = "freebsd",
21052 -+ target_os = "ios",
21053 -+ target_os = "macos",
21054 -+ target_os = "netbsd",
21055 -+ target_os = "openbsd"))]
21056 -+ Hylink = libc::AF_HYLINK,
21057 -+ #[cfg(any(target_os = "dragonfly",
21058 -+ target_os = "freebsd",
21059 -+ target_os = "ios",
21060 -+ target_os = "macos",
21061 -+ target_os = "netbsd",
21062 -+ target_os = "openbsd"))]
21063 -+ Link = libc::AF_LINK,
21064 -+ #[cfg(any(target_os = "dragonfly",
21065 -+ target_os = "freebsd",
21066 -+ target_os = "ios",
21067 -+ target_os = "macos",
21068 -+ target_os = "netbsd",
21069 -+ target_os = "openbsd"))]
21070 -+ Coip = libc::AF_COIP,
21071 -+ #[cfg(any(target_os = "dragonfly",
21072 -+ target_os = "freebsd",
21073 -+ target_os = "ios",
21074 -+ target_os = "macos",
21075 -+ target_os = "netbsd",
21076 -+ target_os = "openbsd"))]
21077 -+ Cnt = libc::AF_CNT,
21078 -+ #[cfg(any(target_os = "dragonfly",
21079 -+ target_os = "freebsd",
21080 -+ target_os = "ios",
21081 -+ target_os = "macos",
21082 -+ target_os = "netbsd",
21083 -+ target_os = "openbsd"))]
21084 -+ Natm = libc::AF_NATM,
21085 -+ /// Unspecified address family, (see [`getaddrinfo(3)`](http://man7.org/linux/man-pages/man3/getaddrinfo.3.html))
21086 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21087 -+ Unspec = libc::AF_UNSPEC,
21088 -+}
21089 -+
21090 -+impl AddressFamily {
21091 -+ /// Create a new `AddressFamily` from an integer value retrieved from `libc`, usually from
21092 -+ /// the `sa_family` field of a `sockaddr`.
21093 -+ ///
21094 -+ /// Currently only supports these address families: Unix, Inet (v4 & v6), Netlink, Link/Packet
21095 -+ /// and System. Returns None for unsupported or unknown address families.
21096 -+ pub fn from_i32(family: i32) -> Option<AddressFamily> {
21097 -+ match family {
21098 -+ libc::AF_UNIX => Some(AddressFamily::Unix),
21099 -+ libc::AF_INET => Some(AddressFamily::Inet),
21100 -+ libc::AF_INET6 => Some(AddressFamily::Inet6),
21101 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21102 -+ libc::AF_NETLINK => Some(AddressFamily::Netlink),
21103 -+ #[cfg(any(target_os = "macos", target_os = "macos"))]
21104 -+ libc::AF_SYSTEM => Some(AddressFamily::System),
21105 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21106 -+ libc::AF_PACKET => Some(AddressFamily::Packet),
21107 -+ #[cfg(any(target_os = "dragonfly",
21108 -+ target_os = "freebsd",
21109 -+ target_os = "ios",
21110 -+ target_os = "macos",
21111 -+ target_os = "netbsd",
21112 -+ target_os = "openbsd"))]
21113 -+ libc::AF_LINK => Some(AddressFamily::Link),
21114 -+ #[cfg(target_os = "linux")]
21115 -+ libc::AF_VSOCK => Some(AddressFamily::Vsock),
21116 -+ _ => None
21117 -+ }
21118 -+ }
21119 -+}
21120 -+
21121 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
21122 -+pub enum InetAddr {
21123 -+ V4(libc::sockaddr_in),
21124 -+ V6(libc::sockaddr_in6),
21125 -+}
21126 -+
21127 -+impl InetAddr {
21128 -+ pub fn from_std(std: &net::SocketAddr) -> InetAddr {
21129 -+ match *std {
21130 -+ net::SocketAddr::V4(ref addr) => {
21131 -+ InetAddr::V4(libc::sockaddr_in {
21132 -+ sin_family: AddressFamily::Inet as sa_family_t,
21133 -+ sin_port: addr.port().to_be(), // network byte order
21134 -+ sin_addr: Ipv4Addr::from_std(addr.ip()).0,
21135 -+ .. unsafe { mem::zeroed() }
21136 -+ })
21137 -+ }
21138 -+ net::SocketAddr::V6(ref addr) => {
21139 -+ InetAddr::V6(libc::sockaddr_in6 {
21140 -+ sin6_family: AddressFamily::Inet6 as sa_family_t,
21141 -+ sin6_port: addr.port().to_be(), // network byte order
21142 -+ sin6_addr: Ipv6Addr::from_std(addr.ip()).0,
21143 -+ sin6_flowinfo: addr.flowinfo(), // host byte order
21144 -+ sin6_scope_id: addr.scope_id(), // host byte order
21145 -+ .. unsafe { mem::zeroed() }
21146 -+ })
21147 -+ }
21148 -+ }
21149 -+ }
21150 -+
21151 -+ pub fn new(ip: IpAddr, port: u16) -> InetAddr {
21152 -+ match ip {
21153 -+ IpAddr::V4(ref ip) => {
21154 -+ InetAddr::V4(libc::sockaddr_in {
21155 -+ sin_family: AddressFamily::Inet as sa_family_t,
21156 -+ sin_port: port.to_be(),
21157 -+ sin_addr: ip.0,
21158 -+ .. unsafe { mem::zeroed() }
21159 -+ })
21160 -+ }
21161 -+ IpAddr::V6(ref ip) => {
21162 -+ InetAddr::V6(libc::sockaddr_in6 {
21163 -+ sin6_family: AddressFamily::Inet6 as sa_family_t,
21164 -+ sin6_port: port.to_be(),
21165 -+ sin6_addr: ip.0,
21166 -+ .. unsafe { mem::zeroed() }
21167 -+ })
21168 -+ }
21169 -+ }
21170 -+ }
21171 -+ /// Gets the IP address associated with this socket address.
21172 -+ pub fn ip(&self) -> IpAddr {
21173 -+ match *self {
21174 -+ InetAddr::V4(ref sa) => IpAddr::V4(Ipv4Addr(sa.sin_addr)),
21175 -+ InetAddr::V6(ref sa) => IpAddr::V6(Ipv6Addr(sa.sin6_addr)),
21176 -+ }
21177 -+ }
21178 -+
21179 -+ /// Gets the port number associated with this socket address
21180 -+ pub fn port(&self) -> u16 {
21181 -+ match *self {
21182 -+ InetAddr::V6(ref sa) => u16::from_be(sa.sin6_port),
21183 -+ InetAddr::V4(ref sa) => u16::from_be(sa.sin_port),
21184 -+ }
21185 -+ }
21186 -+
21187 -+ pub fn to_std(&self) -> net::SocketAddr {
21188 -+ match *self {
21189 -+ InetAddr::V4(ref sa) => net::SocketAddr::V4(
21190 -+ net::SocketAddrV4::new(
21191 -+ Ipv4Addr(sa.sin_addr).to_std(),
21192 -+ self.port())),
21193 -+ InetAddr::V6(ref sa) => net::SocketAddr::V6(
21194 -+ net::SocketAddrV6::new(
21195 -+ Ipv6Addr(sa.sin6_addr).to_std(),
21196 -+ self.port(),
21197 -+ sa.sin6_flowinfo,
21198 -+ sa.sin6_scope_id)),
21199 -+ }
21200 -+ }
21201 -+
21202 -+ pub fn to_str(&self) -> String {
21203 -+ format!("{}", self)
21204 -+ }
21205 -+}
21206 -+
21207 -+impl fmt::Display for InetAddr {
21208 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21209 -+ match *self {
21210 -+ InetAddr::V4(_) => write!(f, "{}:{}", self.ip(), self.port()),
21211 -+ InetAddr::V6(_) => write!(f, "[{}]:{}", self.ip(), self.port()),
21212 -+ }
21213 -+ }
21214 -+}
21215 -+
21216 -+/*
21217 -+ *
21218 -+ * ===== IpAddr =====
21219 -+ *
21220 -+ */
21221 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
21222 -+pub enum IpAddr {
21223 -+ V4(Ipv4Addr),
21224 -+ V6(Ipv6Addr),
21225 -+}
21226 -+
21227 -+impl IpAddr {
21228 -+ /// Create a new IpAddr that contains an IPv4 address.
21229 -+ ///
21230 -+ /// The result will represent the IP address a.b.c.d
21231 -+ pub fn new_v4(a: u8, b: u8, c: u8, d: u8) -> IpAddr {
21232 -+ IpAddr::V4(Ipv4Addr::new(a, b, c, d))
21233 -+ }
21234 -+
21235 -+ /// Create a new IpAddr that contains an IPv6 address.
21236 -+ ///
21237 -+ /// The result will represent the IP address a:b:c:d:e:f
21238 -+ pub fn new_v6(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> IpAddr {
21239 -+ IpAddr::V6(Ipv6Addr::new(a, b, c, d, e, f, g, h))
21240 -+ }
21241 -+
21242 -+ pub fn from_std(std: &net::IpAddr) -> IpAddr {
21243 -+ match *std {
21244 -+ net::IpAddr::V4(ref std) => IpAddr::V4(Ipv4Addr::from_std(std)),
21245 -+ net::IpAddr::V6(ref std) => IpAddr::V6(Ipv6Addr::from_std(std)),
21246 -+ }
21247 -+ }
21248 -+
21249 -+ pub fn to_std(&self) -> net::IpAddr {
21250 -+ match *self {
21251 -+ IpAddr::V4(ref ip) => net::IpAddr::V4(ip.to_std()),
21252 -+ IpAddr::V6(ref ip) => net::IpAddr::V6(ip.to_std()),
21253 -+ }
21254 -+ }
21255 -+}
21256 -+
21257 -+impl fmt::Display for IpAddr {
21258 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21259 -+ match *self {
21260 -+ IpAddr::V4(ref v4) => v4.fmt(f),
21261 -+ IpAddr::V6(ref v6) => v6.fmt(f)
21262 -+ }
21263 -+ }
21264 -+}
21265 -+
21266 -+/*
21267 -+ *
21268 -+ * ===== Ipv4Addr =====
21269 -+ *
21270 -+ */
21271 -+
21272 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
21273 -+pub struct Ipv4Addr(pub libc::in_addr);
21274 -+
21275 -+impl Ipv4Addr {
21276 -+ pub fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
21277 -+ let ip = (((a as u32) << 24) |
21278 -+ ((b as u32) << 16) |
21279 -+ ((c as u32) << 8) |
21280 -+ ((d as u32) << 0)).to_be();
21281 -+
21282 -+ Ipv4Addr(libc::in_addr { s_addr: ip })
21283 -+ }
21284 -+
21285 -+ pub fn from_std(std: &net::Ipv4Addr) -> Ipv4Addr {
21286 -+ let bits = std.octets();
21287 -+ Ipv4Addr::new(bits[0], bits[1], bits[2], bits[3])
21288 -+ }
21289 -+
21290 -+ pub fn any() -> Ipv4Addr {
21291 -+ Ipv4Addr(libc::in_addr { s_addr: libc::INADDR_ANY })
21292 -+ }
21293 -+
21294 -+ pub fn octets(&self) -> [u8; 4] {
21295 -+ let bits = u32::from_be(self.0.s_addr);
21296 -+ [(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8]
21297 -+ }
21298 -+
21299 -+ pub fn to_std(&self) -> net::Ipv4Addr {
21300 -+ let bits = self.octets();
21301 -+ net::Ipv4Addr::new(bits[0], bits[1], bits[2], bits[3])
21302 -+ }
21303 -+}
21304 -+
21305 -+impl fmt::Display for Ipv4Addr {
21306 -+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
21307 -+ let octets = self.octets();
21308 -+ write!(fmt, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3])
21309 -+ }
21310 -+}
21311 -+
21312 -+/*
21313 -+ *
21314 -+ * ===== Ipv6Addr =====
21315 -+ *
21316 -+ */
21317 -+
21318 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
21319 -+pub struct Ipv6Addr(pub libc::in6_addr);
21320 -+
21321 -+// Note that IPv6 addresses are stored in big endian order on all architectures.
21322 -+// See https://tools.ietf.org/html/rfc1700 or consult your favorite search
21323 -+// engine.
21324 -+
21325 -+macro_rules! to_u8_array {
21326 -+ ($($num:ident),*) => {
21327 -+ [ $(($num>>8) as u8, ($num&0xff) as u8,)* ]
21328 -+ }
21329 -+}
21330 -+
21331 -+macro_rules! to_u16_array {
21332 -+ ($slf:ident, $($first:expr, $second:expr),*) => {
21333 -+ [$( (($slf.0.s6_addr[$first] as u16) << 8) + $slf.0.s6_addr[$second] as u16,)*]
21334 -+ }
21335 -+}
21336 -+
21337 -+impl Ipv6Addr {
21338 -+ pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr {
21339 -+ let mut in6_addr_var: libc::in6_addr = unsafe{mem::uninitialized()};
21340 -+ in6_addr_var.s6_addr = to_u8_array!(a,b,c,d,e,f,g,h);
21341 -+ Ipv6Addr(in6_addr_var)
21342 -+ }
21343 -+
21344 -+ pub fn from_std(std: &net::Ipv6Addr) -> Ipv6Addr {
21345 -+ let s = std.segments();
21346 -+ Ipv6Addr::new(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7])
21347 -+ }
21348 -+
21349 -+ /// Return the eight 16-bit segments that make up this address
21350 -+ pub fn segments(&self) -> [u16; 8] {
21351 -+ to_u16_array!(self, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
21352 -+ }
21353 -+
21354 -+ pub fn to_std(&self) -> net::Ipv6Addr {
21355 -+ let s = self.segments();
21356 -+ net::Ipv6Addr::new(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7])
21357 -+ }
21358 -+}
21359 -+
21360 -+impl fmt::Display for Ipv6Addr {
21361 -+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
21362 -+ self.to_std().fmt(fmt)
21363 -+ }
21364 -+}
21365 -+
21366 -+/// A wrapper around `sockaddr_un`.
21367 -+///
21368 -+/// This also tracks the length of `sun_path` address (excluding
21369 -+/// a terminating null), because it may not be null-terminated. For example,
21370 -+/// unconnected and Linux abstract sockets are never null-terminated, and POSIX
21371 -+/// does not require that `sun_len` include the terminating null even for normal
21372 -+/// sockets. Note that the actual sockaddr length is greater by
21373 -+/// `offset_of!(libc::sockaddr_un, sun_path)`
21374 -+#[derive(Clone, Copy, Debug)]
21375 -+pub struct UnixAddr(pub libc::sockaddr_un, pub usize);
21376 -+
21377 -+impl UnixAddr {
21378 -+ /// Create a new sockaddr_un representing a filesystem path.
21379 -+ pub fn new<P: ?Sized + NixPath>(path: &P) -> Result<UnixAddr> {
21380 -+ path.with_nix_path(|cstr| {
21381 -+ unsafe {
21382 -+ let mut ret = libc::sockaddr_un {
21383 -+ sun_family: AddressFamily::Unix as sa_family_t,
21384 -+ .. mem::zeroed()
21385 -+ };
21386 -+
21387 -+ let bytes = cstr.to_bytes();
21388 -+
21389 -+ if bytes.len() > ret.sun_path.len() {
21390 -+ return Err(Error::Sys(Errno::ENAMETOOLONG));
21391 -+ }
21392 -+
21393 -+ ptr::copy_nonoverlapping(bytes.as_ptr(),
21394 -+ ret.sun_path.as_mut_ptr() as *mut u8,
21395 -+ bytes.len());
21396 -+
21397 -+ Ok(UnixAddr(ret, bytes.len()))
21398 -+ }
21399 -+ })?
21400 -+ }
21401 -+
21402 -+ /// Create a new `sockaddr_un` representing an address in the "abstract namespace".
21403 -+ ///
21404 -+ /// The leading null byte for the abstract namespace is automatically added;
21405 -+ /// thus the input `path` is expected to be the bare name, not null-prefixed.
21406 -+ /// This is a Linux-specific extension, primarily used to allow chrooted
21407 -+ /// processes to communicate with processes having a different filesystem view.
21408 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21409 -+ pub fn new_abstract(path: &[u8]) -> Result<UnixAddr> {
21410 -+ unsafe {
21411 -+ let mut ret = libc::sockaddr_un {
21412 -+ sun_family: AddressFamily::Unix as sa_family_t,
21413 -+ .. mem::zeroed()
21414 -+ };
21415 -+
21416 -+ if path.len() + 1 > ret.sun_path.len() {
21417 -+ return Err(Error::Sys(Errno::ENAMETOOLONG));
21418 -+ }
21419 -+
21420 -+ // Abstract addresses are represented by sun_path[0] ==
21421 -+ // b'\0', so copy starting one byte in.
21422 -+ ptr::copy_nonoverlapping(path.as_ptr(),
21423 -+ ret.sun_path.as_mut_ptr().offset(1) as *mut u8,
21424 -+ path.len());
21425 -+
21426 -+ Ok(UnixAddr(ret, ret.sun_path.len()))
21427 -+ }
21428 -+ }
21429 -+
21430 -+ fn sun_path(&self) -> &[u8] {
21431 -+ unsafe { slice::from_raw_parts(self.0.sun_path.as_ptr() as *const u8, self.1) }
21432 -+ }
21433 -+
21434 -+ /// If this address represents a filesystem path, return that path.
21435 -+ pub fn path(&self) -> Option<&Path> {
21436 -+ if self.1 == 0 || self.0.sun_path[0] == 0 {
21437 -+ // unnamed or abstract
21438 -+ None
21439 -+ } else {
21440 -+ let p = self.sun_path();
21441 -+ // POSIX only requires that `sun_len` be at least long enough to
21442 -+ // contain the pathname, and it need not be null-terminated. So we
21443 -+ // need to create a string that is the shorter of the
21444 -+ // null-terminated length or the full length.
21445 -+ let ptr = &self.0.sun_path as *const libc::c_char;
21446 -+ let reallen = unsafe { libc::strnlen(ptr, p.len()) };
21447 -+ Some(Path::new(<OsStr as OsStrExt>::from_bytes(&p[..reallen])))
21448 -+ }
21449 -+ }
21450 -+
21451 -+ /// If this address represents an abstract socket, return its name.
21452 -+ ///
21453 -+ /// For abstract sockets only the bare name is returned, without the
21454 -+ /// leading null byte. `None` is returned for unnamed or path-backed sockets.
21455 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21456 -+ pub fn as_abstract(&self) -> Option<&[u8]> {
21457 -+ if self.1 >= 1 && self.0.sun_path[0] == 0 {
21458 -+ Some(&self.sun_path()[1..])
21459 -+ } else {
21460 -+ // unnamed or filesystem path
21461 -+ None
21462 -+ }
21463 -+ }
21464 -+}
21465 -+
21466 -+impl fmt::Display for UnixAddr {
21467 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21468 -+ if self.1 == 0 {
21469 -+ f.write_str("<unbound UNIX socket>")
21470 -+ } else if let Some(path) = self.path() {
21471 -+ path.display().fmt(f)
21472 -+ } else {
21473 -+ let display = String::from_utf8_lossy(&self.sun_path()[1..]);
21474 -+ write!(f, "@{}", display)
21475 -+ }
21476 -+ }
21477 -+}
21478 -+
21479 -+impl PartialEq for UnixAddr {
21480 -+ fn eq(&self, other: &UnixAddr) -> bool {
21481 -+ self.sun_path() == other.sun_path()
21482 -+ }
21483 -+}
21484 -+
21485 -+impl Eq for UnixAddr {}
21486 -+
21487 -+impl Hash for UnixAddr {
21488 -+ fn hash<H: Hasher>(&self, s: &mut H) {
21489 -+ ( self.0.sun_family, self.sun_path() ).hash(s)
21490 -+ }
21491 -+}
21492 -+
21493 -+/// Represents a socket address
21494 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
21495 -+pub enum SockAddr {
21496 -+ Inet(InetAddr),
21497 -+ Unix(UnixAddr),
21498 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21499 -+ Netlink(NetlinkAddr),
21500 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21501 -+ Alg(AlgAddr),
21502 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
21503 -+ SysControl(SysControlAddr),
21504 -+ /// Datalink address (MAC)
21505 -+ #[cfg(any(target_os = "android",
21506 -+ target_os = "dragonfly",
21507 -+ target_os = "freebsd",
21508 -+ target_os = "ios",
21509 -+ target_os = "linux",
21510 -+ target_os = "macos",
21511 -+ target_os = "netbsd",
21512 -+ target_os = "openbsd"))]
21513 -+ Link(LinkAddr),
21514 -+ #[cfg(target_os = "linux")]
21515 -+ Vsock(VsockAddr),
21516 -+}
21517 -+
21518 -+impl SockAddr {
21519 -+ pub fn new_inet(addr: InetAddr) -> SockAddr {
21520 -+ SockAddr::Inet(addr)
21521 -+ }
21522 -+
21523 -+ pub fn new_unix<P: ?Sized + NixPath>(path: &P) -> Result<SockAddr> {
21524 -+ Ok(SockAddr::Unix(UnixAddr::new(path)?))
21525 -+ }
21526 -+
21527 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21528 -+ pub fn new_netlink(pid: u32, groups: u32) -> SockAddr {
21529 -+ SockAddr::Netlink(NetlinkAddr::new(pid, groups))
21530 -+ }
21531 -+
21532 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21533 -+ pub fn new_alg(alg_type: &str, alg_name: &str) -> SockAddr {
21534 -+ SockAddr::Alg(AlgAddr::new(alg_type, alg_name))
21535 -+ }
21536 -+
21537 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
21538 -+ pub fn new_sys_control(sockfd: RawFd, name: &str, unit: u32) -> Result<SockAddr> {
21539 -+ SysControlAddr::from_name(sockfd, name, unit).map(|a| SockAddr::SysControl(a))
21540 -+ }
21541 -+
21542 -+ #[cfg(target_os = "linux")]
21543 -+ pub fn new_vsock(cid: u32, port: u32) -> SockAddr {
21544 -+ SockAddr::Vsock(VsockAddr::new(cid, port))
21545 -+ }
21546 -+
21547 -+ pub fn family(&self) -> AddressFamily {
21548 -+ match *self {
21549 -+ SockAddr::Inet(InetAddr::V4(..)) => AddressFamily::Inet,
21550 -+ SockAddr::Inet(InetAddr::V6(..)) => AddressFamily::Inet6,
21551 -+ SockAddr::Unix(..) => AddressFamily::Unix,
21552 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21553 -+ SockAddr::Netlink(..) => AddressFamily::Netlink,
21554 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21555 -+ SockAddr::Alg(..) => AddressFamily::Alg,
21556 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
21557 -+ SockAddr::SysControl(..) => AddressFamily::System,
21558 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21559 -+ SockAddr::Link(..) => AddressFamily::Packet,
21560 -+ #[cfg(any(target_os = "dragonfly",
21561 -+ target_os = "freebsd",
21562 -+ target_os = "ios",
21563 -+ target_os = "macos",
21564 -+ target_os = "netbsd",
21565 -+ target_os = "openbsd"))]
21566 -+ SockAddr::Link(..) => AddressFamily::Link,
21567 -+ #[cfg(target_os = "linux")]
21568 -+ SockAddr::Vsock(..) => AddressFamily::Vsock,
21569 -+ }
21570 -+ }
21571 -+
21572 -+ pub fn to_str(&self) -> String {
21573 -+ format!("{}", self)
21574 -+ }
21575 -+
21576 -+ /// Creates a `SockAddr` struct from libc's sockaddr.
21577 -+ ///
21578 -+ /// Supports only the following address families: Unix, Inet (v4 & v6), Netlink and System.
21579 -+ /// Returns None for unsupported families.
21580 -+ pub unsafe fn from_libc_sockaddr(addr: *const libc::sockaddr) -> Option<SockAddr> {
21581 -+ if addr.is_null() {
21582 -+ None
21583 -+ } else {
21584 -+ match AddressFamily::from_i32((*addr).sa_family as i32) {
21585 -+ Some(AddressFamily::Unix) => None,
21586 -+ Some(AddressFamily::Inet) => Some(SockAddr::Inet(
21587 -+ InetAddr::V4(*(addr as *const libc::sockaddr_in)))),
21588 -+ Some(AddressFamily::Inet6) => Some(SockAddr::Inet(
21589 -+ InetAddr::V6(*(addr as *const libc::sockaddr_in6)))),
21590 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21591 -+ Some(AddressFamily::Netlink) => Some(SockAddr::Netlink(
21592 -+ NetlinkAddr(*(addr as *const libc::sockaddr_nl)))),
21593 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
21594 -+ Some(AddressFamily::System) => Some(SockAddr::SysControl(
21595 -+ SysControlAddr(*(addr as *const libc::sockaddr_ctl)))),
21596 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21597 -+ Some(AddressFamily::Packet) => Some(SockAddr::Link(
21598 -+ LinkAddr(*(addr as *const libc::sockaddr_ll)))),
21599 -+ #[cfg(any(target_os = "dragonfly",
21600 -+ target_os = "freebsd",
21601 -+ target_os = "ios",
21602 -+ target_os = "macos",
21603 -+ target_os = "netbsd",
21604 -+ target_os = "openbsd"))]
21605 -+ Some(AddressFamily::Link) => {
21606 -+ let ether_addr = LinkAddr(*(addr as *const libc::sockaddr_dl));
21607 -+ if ether_addr.is_empty() {
21608 -+ None
21609 -+ } else {
21610 -+ Some(SockAddr::Link(ether_addr))
21611 -+ }
21612 -+ },
21613 -+ #[cfg(target_os = "linux")]
21614 -+ Some(AddressFamily::Vsock) => Some(SockAddr::Vsock(
21615 -+ VsockAddr(*(addr as *const libc::sockaddr_vm)))),
21616 -+ // Other address families are currently not supported and simply yield a None
21617 -+ // entry instead of a proper conversion to a `SockAddr`.
21618 -+ Some(_) | None => None,
21619 -+ }
21620 -+ }
21621 -+ }
21622 -+
21623 -+ /// Conversion from nix's SockAddr type to the underlying libc sockaddr type.
21624 -+ ///
21625 -+ /// This is useful for interfacing with other libc functions that don't yet have nix wrappers.
21626 -+ /// Returns a reference to the underlying data type (as a sockaddr reference) along
21627 -+ /// with the size of the actual data type. sockaddr is commonly used as a proxy for
21628 -+ /// a superclass as C doesn't support inheritance, so many functions that take
21629 -+ /// a sockaddr * need to take the size of the underlying type as well and then internally cast it back.
21630 -+ pub unsafe fn as_ffi_pair(&self) -> (&libc::sockaddr, libc::socklen_t) {
21631 -+ match *self {
21632 -+ SockAddr::Inet(InetAddr::V4(ref addr)) => (mem::transmute(addr), mem::size_of::<libc::sockaddr_in>() as libc::socklen_t),
21633 -+ SockAddr::Inet(InetAddr::V6(ref addr)) => (mem::transmute(addr), mem::size_of::<libc::sockaddr_in6>() as libc::socklen_t),
21634 -+ SockAddr::Unix(UnixAddr(ref addr, len)) => (mem::transmute(addr), (len + offset_of!(libc::sockaddr_un, sun_path)) as libc::socklen_t),
21635 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21636 -+ SockAddr::Netlink(NetlinkAddr(ref sa)) => (mem::transmute(sa), mem::size_of::<libc::sockaddr_nl>() as libc::socklen_t),
21637 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21638 -+ SockAddr::Alg(AlgAddr(ref sa)) => (mem::transmute(sa), mem::size_of::<libc::sockaddr_alg>() as libc::socklen_t),
21639 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
21640 -+ SockAddr::SysControl(SysControlAddr(ref sa)) => (mem::transmute(sa), mem::size_of::<libc::sockaddr_ctl>() as libc::socklen_t),
21641 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21642 -+ SockAddr::Link(LinkAddr(ref ether_addr)) => (mem::transmute(ether_addr), mem::size_of::<libc::sockaddr_ll>() as libc::socklen_t),
21643 -+ #[cfg(any(target_os = "dragonfly",
21644 -+ target_os = "freebsd",
21645 -+ target_os = "ios",
21646 -+ target_os = "macos",
21647 -+ target_os = "netbsd",
21648 -+ target_os = "openbsd"))]
21649 -+ SockAddr::Link(LinkAddr(ref ether_addr)) => (mem::transmute(ether_addr), mem::size_of::<libc::sockaddr_dl>() as libc::socklen_t),
21650 -+ #[cfg(target_os = "linux")]
21651 -+ SockAddr::Vsock(VsockAddr(ref sa)) => (mem::transmute(sa), mem::size_of::<libc::sockaddr_vm>() as libc::socklen_t),
21652 -+ }
21653 -+ }
21654 -+}
21655 -+
21656 -+impl fmt::Display for SockAddr {
21657 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21658 -+ match *self {
21659 -+ SockAddr::Inet(ref inet) => inet.fmt(f),
21660 -+ SockAddr::Unix(ref unix) => unix.fmt(f),
21661 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21662 -+ SockAddr::Netlink(ref nl) => nl.fmt(f),
21663 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
21664 -+ SockAddr::Alg(ref nl) => nl.fmt(f),
21665 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
21666 -+ SockAddr::SysControl(ref sc) => sc.fmt(f),
21667 -+ #[cfg(any(target_os = "android",
21668 -+ target_os = "dragonfly",
21669 -+ target_os = "freebsd",
21670 -+ target_os = "ios",
21671 -+ target_os = "linux",
21672 -+ target_os = "macos",
21673 -+ target_os = "netbsd",
21674 -+ target_os = "openbsd"))]
21675 -+ SockAddr::Link(ref ether_addr) => ether_addr.fmt(f),
21676 -+ #[cfg(target_os = "linux")]
21677 -+ SockAddr::Vsock(ref svm) => svm.fmt(f),
21678 -+ }
21679 -+ }
21680 -+}
21681 -+
21682 -+#[cfg(any(target_os = "android", target_os = "linux"))]
21683 -+pub mod netlink {
21684 -+ use ::sys::socket::addr::AddressFamily;
21685 -+ use libc::{sa_family_t, sockaddr_nl};
21686 -+ use std::{fmt, mem};
21687 -+
21688 -+ #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
21689 -+ pub struct NetlinkAddr(pub sockaddr_nl);
21690 -+
21691 -+ impl NetlinkAddr {
21692 -+ pub fn new(pid: u32, groups: u32) -> NetlinkAddr {
21693 -+ let mut addr: sockaddr_nl = unsafe { mem::zeroed() };
21694 -+ addr.nl_family = AddressFamily::Netlink as sa_family_t;
21695 -+ addr.nl_pid = pid;
21696 -+ addr.nl_groups = groups;
21697 -+
21698 -+ NetlinkAddr(addr)
21699 -+ }
21700 -+
21701 -+ pub fn pid(&self) -> u32 {
21702 -+ self.0.nl_pid
21703 -+ }
21704 -+
21705 -+ pub fn groups(&self) -> u32 {
21706 -+ self.0.nl_groups
21707 -+ }
21708 -+ }
21709 -+
21710 -+ impl fmt::Display for NetlinkAddr {
21711 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21712 -+ write!(f, "pid: {} groups: {}", self.pid(), self.groups())
21713 -+ }
21714 -+ }
21715 -+}
21716 -+
21717 -+#[cfg(any(target_os = "android", target_os = "linux"))]
21718 -+pub mod alg {
21719 -+ use libc::{AF_ALG, sockaddr_alg, c_char};
21720 -+ use std::{fmt, mem, str};
21721 -+ use std::hash::{Hash, Hasher};
21722 -+ use std::ffi::CStr;
21723 -+
21724 -+ #[derive(Copy, Clone)]
21725 -+ pub struct AlgAddr(pub sockaddr_alg);
21726 -+
21727 -+ // , PartialEq, Eq, Debug, Hash
21728 -+ impl PartialEq for AlgAddr {
21729 -+ fn eq(&self, other: &Self) -> bool {
21730 -+ let (inner, other) = (self.0, other.0);
21731 -+ (inner.salg_family, &inner.salg_type[..], inner.salg_feat, inner.salg_mask, &inner.salg_name[..]) ==
21732 -+ (other.salg_family, &other.salg_type[..], other.salg_feat, other.salg_mask, &other.salg_name[..])
21733 -+ }
21734 -+ }
21735 -+
21736 -+ impl Eq for AlgAddr {}
21737 -+
21738 -+ impl Hash for AlgAddr {
21739 -+ fn hash<H: Hasher>(&self, s: &mut H) {
21740 -+ let inner = self.0;
21741 -+ (inner.salg_family, &inner.salg_type[..], inner.salg_feat, inner.salg_mask, &inner.salg_name[..]).hash(s);
21742 -+ }
21743 -+ }
21744 -+
21745 -+ impl AlgAddr {
21746 -+ pub fn new(alg_type: &str, alg_name: &str) -> AlgAddr {
21747 -+ let mut addr: sockaddr_alg = unsafe { mem::zeroed() };
21748 -+ addr.salg_family = AF_ALG as u16;
21749 -+ addr.salg_type[..alg_type.len()].copy_from_slice(alg_type.to_string().as_bytes());
21750 -+ addr.salg_name[..alg_name.len()].copy_from_slice(alg_name.to_string().as_bytes());
21751 -+
21752 -+ AlgAddr(addr)
21753 -+ }
21754 -+
21755 -+
21756 -+ pub fn alg_type(&self) -> &CStr {
21757 -+ unsafe { CStr::from_ptr(self.0.salg_type.as_ptr() as *const c_char) }
21758 -+ }
21759 -+
21760 -+ pub fn alg_name(&self) -> &CStr {
21761 -+ unsafe { CStr::from_ptr(self.0.salg_name.as_ptr() as *const c_char) }
21762 -+ }
21763 -+ }
21764 -+
21765 -+ impl fmt::Display for AlgAddr {
21766 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21767 -+ write!(f, "type: {} alg: {}",
21768 -+ self.alg_name().to_string_lossy(),
21769 -+ self.alg_type().to_string_lossy())
21770 -+ }
21771 -+ }
21772 -+
21773 -+ impl fmt::Debug for AlgAddr {
21774 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21775 -+ fmt::Display::fmt(self, f)
21776 -+ }
21777 -+ }
21778 -+}
21779 -+
21780 -+#[cfg(any(target_os = "ios", target_os = "macos"))]
21781 -+pub mod sys_control {
21782 -+ use ::sys::socket::addr::AddressFamily;
21783 -+ use libc::{self, c_uchar};
21784 -+ use std::{fmt, mem};
21785 -+ use std::os::unix::io::RawFd;
21786 -+ use {Errno, Error, Result};
21787 -+
21788 -+ // FIXME: Move type into `libc`
21789 -+ #[repr(C)]
21790 -+ #[derive(Clone, Copy)]
21791 -+ #[allow(missing_debug_implementations)]
21792 -+ pub struct ctl_ioc_info {
21793 -+ pub ctl_id: u32,
21794 -+ pub ctl_name: [c_uchar; MAX_KCTL_NAME],
21795 -+ }
21796 -+
21797 -+ const CTL_IOC_MAGIC: u8 = 'N' as u8;
21798 -+ const CTL_IOC_INFO: u8 = 3;
21799 -+ const MAX_KCTL_NAME: usize = 96;
21800 -+
21801 -+ ioctl_readwrite!(ctl_info, CTL_IOC_MAGIC, CTL_IOC_INFO, ctl_ioc_info);
21802 -+
21803 -+ #[repr(C)]
21804 -+ #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
21805 -+ pub struct SysControlAddr(pub libc::sockaddr_ctl);
21806 -+
21807 -+ impl SysControlAddr {
21808 -+ pub fn new(id: u32, unit: u32) -> SysControlAddr {
21809 -+ let addr = libc::sockaddr_ctl {
21810 -+ sc_len: mem::size_of::<libc::sockaddr_ctl>() as c_uchar,
21811 -+ sc_family: AddressFamily::System as c_uchar,
21812 -+ ss_sysaddr: libc::AF_SYS_CONTROL as u16,
21813 -+ sc_id: id,
21814 -+ sc_unit: unit,
21815 -+ sc_reserved: [0; 5]
21816 -+ };
21817 -+
21818 -+ SysControlAddr(addr)
21819 -+ }
21820 -+
21821 -+ pub fn from_name(sockfd: RawFd, name: &str, unit: u32) -> Result<SysControlAddr> {
21822 -+ if name.len() > MAX_KCTL_NAME {
21823 -+ return Err(Error::Sys(Errno::ENAMETOOLONG));
21824 -+ }
21825 -+
21826 -+ let mut ctl_name = [0; MAX_KCTL_NAME];
21827 -+ ctl_name[..name.len()].clone_from_slice(name.as_bytes());
21828 -+ let mut info = ctl_ioc_info { ctl_id: 0, ctl_name: ctl_name };
21829 -+
21830 -+ unsafe { ctl_info(sockfd, &mut info)?; }
21831 -+
21832 -+ Ok(SysControlAddr::new(info.ctl_id, unit))
21833 -+ }
21834 -+
21835 -+ pub fn id(&self) -> u32 {
21836 -+ self.0.sc_id
21837 -+ }
21838 -+
21839 -+ pub fn unit(&self) -> u32 {
21840 -+ self.0.sc_unit
21841 -+ }
21842 -+ }
21843 -+
21844 -+ impl fmt::Display for SysControlAddr {
21845 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21846 -+ fmt::Debug::fmt(self, f)
21847 -+ }
21848 -+ }
21849 -+}
21850 -+
21851 -+
21852 -+#[cfg(any(target_os = "android", target_os = "linux"))]
21853 -+mod datalink {
21854 -+ use super::{libc, fmt, AddressFamily};
21855 -+
21856 -+ /// Hardware Address
21857 -+ #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
21858 -+ pub struct LinkAddr(pub libc::sockaddr_ll);
21859 -+
21860 -+ impl LinkAddr {
21861 -+ /// Always AF_PACKET
21862 -+ pub fn family(&self) -> AddressFamily {
21863 -+ assert_eq!(self.0.sll_family as i32, libc::AF_PACKET);
21864 -+ AddressFamily::Packet
21865 -+ }
21866 -+
21867 -+ /// Physical-layer protocol
21868 -+ pub fn protocol(&self) -> u16 {
21869 -+ self.0.sll_protocol
21870 -+ }
21871 -+
21872 -+ /// Interface number
21873 -+ pub fn ifindex(&self) -> usize {
21874 -+ self.0.sll_ifindex as usize
21875 -+ }
21876 -+
21877 -+ /// ARP hardware type
21878 -+ pub fn hatype(&self) -> u16 {
21879 -+ self.0.sll_hatype
21880 -+ }
21881 -+
21882 -+ /// Packet type
21883 -+ pub fn pkttype(&self) -> u8 {
21884 -+ self.0.sll_pkttype
21885 -+ }
21886 -+
21887 -+ /// Length of MAC address
21888 -+ pub fn halen(&self) -> usize {
21889 -+ self.0.sll_halen as usize
21890 -+ }
21891 -+
21892 -+ /// Physical-layer address (MAC)
21893 -+ pub fn addr(&self) -> [u8; 6] {
21894 -+ let a = self.0.sll_addr[0] as u8;
21895 -+ let b = self.0.sll_addr[1] as u8;
21896 -+ let c = self.0.sll_addr[2] as u8;
21897 -+ let d = self.0.sll_addr[3] as u8;
21898 -+ let e = self.0.sll_addr[4] as u8;
21899 -+ let f = self.0.sll_addr[5] as u8;
21900 -+
21901 -+ [a, b, c, d, e, f]
21902 -+ }
21903 -+ }
21904 -+
21905 -+ impl fmt::Display for LinkAddr {
21906 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21907 -+ let addr = self.addr();
21908 -+ write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
21909 -+ addr[0],
21910 -+ addr[1],
21911 -+ addr[2],
21912 -+ addr[3],
21913 -+ addr[4],
21914 -+ addr[5])
21915 -+ }
21916 -+ }
21917 -+}
21918 -+
21919 -+#[cfg(any(target_os = "dragonfly",
21920 -+ target_os = "freebsd",
21921 -+ target_os = "ios",
21922 -+ target_os = "macos",
21923 -+ target_os = "netbsd",
21924 -+ target_os = "openbsd"))]
21925 -+mod datalink {
21926 -+ use super::{libc, fmt, AddressFamily};
21927 -+
21928 -+ /// Hardware Address
21929 -+ #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
21930 -+ pub struct LinkAddr(pub libc::sockaddr_dl);
21931 -+
21932 -+ impl LinkAddr {
21933 -+ /// Total length of sockaddr
21934 -+ pub fn len(&self) -> usize {
21935 -+ self.0.sdl_len as usize
21936 -+ }
21937 -+
21938 -+ /// always == AF_LINK
21939 -+ pub fn family(&self) -> AddressFamily {
21940 -+ assert_eq!(self.0.sdl_family as i32, libc::AF_LINK);
21941 -+ AddressFamily::Link
21942 -+ }
21943 -+
21944 -+ /// interface index, if != 0, system given index for interface
21945 -+ pub fn ifindex(&self) -> usize {
21946 -+ self.0.sdl_index as usize
21947 -+ }
21948 -+
21949 -+ /// Datalink type
21950 -+ pub fn datalink_type(&self) -> u8 {
21951 -+ self.0.sdl_type
21952 -+ }
21953 -+
21954 -+ // MAC address start position
21955 -+ pub fn nlen(&self) -> usize {
21956 -+ self.0.sdl_nlen as usize
21957 -+ }
21958 -+
21959 -+ /// link level address length
21960 -+ pub fn alen(&self) -> usize {
21961 -+ self.0.sdl_alen as usize
21962 -+ }
21963 -+
21964 -+ /// link layer selector length
21965 -+ pub fn slen(&self) -> usize {
21966 -+ self.0.sdl_slen as usize
21967 -+ }
21968 -+
21969 -+ /// if link level address length == 0,
21970 -+ /// or `sdl_data` not be larger.
21971 -+ pub fn is_empty(&self) -> bool {
21972 -+ let nlen = self.nlen();
21973 -+ let alen = self.alen();
21974 -+ let data_len = self.0.sdl_data.len();
21975 -+
21976 -+ if alen > 0 && nlen + alen < data_len {
21977 -+ false
21978 -+ } else {
21979 -+ true
21980 -+ }
21981 -+ }
21982 -+
21983 -+ /// Physical-layer address (MAC)
21984 -+ pub fn addr(&self) -> [u8; 6] {
21985 -+ let nlen = self.nlen();
21986 -+ let data = self.0.sdl_data;
21987 -+
21988 -+ assert!(!self.is_empty());
21989 -+
21990 -+ let a = data[nlen] as u8;
21991 -+ let b = data[nlen + 1] as u8;
21992 -+ let c = data[nlen + 2] as u8;
21993 -+ let d = data[nlen + 3] as u8;
21994 -+ let e = data[nlen + 4] as u8;
21995 -+ let f = data[nlen + 5] as u8;
21996 -+
21997 -+ [a, b, c, d, e, f]
21998 -+ }
21999 -+ }
22000 -+
22001 -+ impl fmt::Display for LinkAddr {
22002 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22003 -+ let addr = self.addr();
22004 -+ write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
22005 -+ addr[0],
22006 -+ addr[1],
22007 -+ addr[2],
22008 -+ addr[3],
22009 -+ addr[4],
22010 -+ addr[5])
22011 -+ }
22012 -+ }
22013 -+}
22014 -+
22015 -+#[cfg(target_os = "linux")]
22016 -+pub mod vsock {
22017 -+ use ::sys::socket::addr::AddressFamily;
22018 -+ use libc::{sa_family_t, sockaddr_vm};
22019 -+ use std::{fmt, mem};
22020 -+ use std::hash::{Hash, Hasher};
22021 -+
22022 -+ #[derive(Copy, Clone)]
22023 -+ pub struct VsockAddr(pub sockaddr_vm);
22024 -+
22025 -+ impl PartialEq for VsockAddr {
22026 -+ fn eq(&self, other: &Self) -> bool {
22027 -+ let (inner, other) = (self.0, other.0);
22028 -+ (inner.svm_family, inner.svm_cid, inner.svm_port) ==
22029 -+ (other.svm_family, other.svm_cid, other.svm_port)
22030 -+ }
22031 -+ }
22032 -+
22033 -+ impl Eq for VsockAddr {}
22034 -+
22035 -+ impl Hash for VsockAddr {
22036 -+ fn hash<H: Hasher>(&self, s: &mut H) {
22037 -+ let inner = self.0;
22038 -+ (inner.svm_family, inner.svm_cid, inner.svm_port).hash(s);
22039 -+ }
22040 -+ }
22041 -+
22042 -+ /// VSOCK Address
22043 -+ ///
22044 -+ /// The address for AF_VSOCK socket is defined as a combination of a
22045 -+ /// 32-bit Context Identifier (CID) and a 32-bit port number.
22046 -+ impl VsockAddr {
22047 -+ pub fn new(cid: u32, port: u32) -> VsockAddr {
22048 -+ let mut addr: sockaddr_vm = unsafe { mem::zeroed() };
22049 -+ addr.svm_family = AddressFamily::Vsock as sa_family_t;
22050 -+ addr.svm_cid = cid;
22051 -+ addr.svm_port = port;
22052 -+
22053 -+ VsockAddr(addr)
22054 -+ }
22055 -+
22056 -+ /// Context Identifier (CID)
22057 -+ pub fn cid(&self) -> u32 {
22058 -+ self.0.svm_cid
22059 -+ }
22060 -+
22061 -+ /// Port number
22062 -+ pub fn port(&self) -> u32 {
22063 -+ self.0.svm_port
22064 -+ }
22065 -+ }
22066 -+
22067 -+ impl fmt::Display for VsockAddr {
22068 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22069 -+ write!(f, "cid: {} port: {}", self.cid(), self.port())
22070 -+ }
22071 -+ }
22072 -+
22073 -+ impl fmt::Debug for VsockAddr {
22074 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22075 -+ fmt::Display::fmt(self, f)
22076 -+ }
22077 -+ }
22078 -+}
22079 -+
22080 -+#[cfg(test)]
22081 -+mod tests {
22082 -+ #[cfg(any(target_os = "android",
22083 -+ target_os = "dragonfly",
22084 -+ target_os = "freebsd",
22085 -+ target_os = "ios",
22086 -+ target_os = "linux",
22087 -+ target_os = "macos",
22088 -+ target_os = "netbsd",
22089 -+ target_os = "openbsd"))]
22090 -+ use super::*;
22091 -+
22092 -+ #[cfg(any(target_os = "dragonfly",
22093 -+ target_os = "freebsd",
22094 -+ target_os = "ios",
22095 -+ target_os = "macos",
22096 -+ target_os = "netbsd",
22097 -+ target_os = "openbsd"))]
22098 -+ #[test]
22099 -+ fn test_macos_loopback_datalink_addr() {
22100 -+ let bytes = [20i8, 18, 1, 0, 24, 3, 0, 0, 108, 111, 48, 0, 0, 0, 0, 0];
22101 -+ let sa = bytes.as_ptr() as *const libc::sockaddr;
22102 -+ let _sock_addr = unsafe { SockAddr::from_libc_sockaddr(sa) };
22103 -+ assert!(_sock_addr.is_none());
22104 -+ }
22105 -+
22106 -+ #[cfg(any(target_os = "dragonfly",
22107 -+ target_os = "freebsd",
22108 -+ target_os = "ios",
22109 -+ target_os = "macos",
22110 -+ target_os = "netbsd",
22111 -+ target_os = "openbsd"))]
22112 -+ #[test]
22113 -+ fn test_macos_tap_datalink_addr() {
22114 -+ let bytes = [20i8, 18, 7, 0, 6, 3, 6, 0, 101, 110, 48, 24, 101, -112, -35, 76, -80];
22115 -+ let ptr = bytes.as_ptr();
22116 -+ let sa = ptr as *const libc::sockaddr;
22117 -+ let _sock_addr = unsafe { SockAddr::from_libc_sockaddr(sa) };
22118 -+
22119 -+ assert!(_sock_addr.is_some());
22120 -+
22121 -+ let sock_addr = _sock_addr.unwrap();
22122 -+
22123 -+ assert_eq!(sock_addr.family(), AddressFamily::Link);
22124 -+
22125 -+ match sock_addr {
22126 -+ SockAddr::Link(ether_addr) => {
22127 -+ assert_eq!(ether_addr.addr(), [24u8, 101, 144, 221, 76, 176]);
22128 -+ },
22129 -+ _ => { unreachable!() }
22130 -+ };
22131 -+ }
22132 -+
22133 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22134 -+ #[test]
22135 -+ fn test_abstract_sun_path() {
22136 -+ let name = String::from("nix\0abstract\0test");
22137 -+ let addr = UnixAddr::new_abstract(name.as_bytes()).unwrap();
22138 -+
22139 -+ let sun_path1 = addr.sun_path();
22140 -+ let sun_path2 = [0u8, 110, 105, 120, 0, 97, 98, 115, 116, 114, 97, 99, 116, 0, 116, 101, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
22141 -+ assert_eq!(sun_path1.len(), sun_path2.len());
22142 -+ for i in 0..sun_path1.len() {
22143 -+ assert_eq!(sun_path1[i], sun_path2[i]);
22144 -+ }
22145 -+ }
22146 -+}
22147 -diff --git a/third_party/rust/nix-0.15.0/src/sys/socket/mod.rs b/third_party/rust/nix-0.15.0/src/sys/socket/mod.rs
22148 -new file mode 100644
22149 -index 0000000000000..1c12c5f851734
22150 ---- /dev/null
22151 -+++ b/third_party/rust/nix-0.15.0/src/sys/socket/mod.rs
22152 -@@ -0,0 +1,1294 @@
22153 -+//! Socket interface functions
22154 -+//!
22155 -+//! [Further reading](http://man7.org/linux/man-pages/man7/socket.7.html)
22156 -+use {Error, Result};
22157 -+use errno::Errno;
22158 -+use libc::{self, c_void, c_int, iovec, socklen_t, size_t,
22159 -+ CMSG_FIRSTHDR, CMSG_NXTHDR, CMSG_DATA, CMSG_LEN};
22160 -+use std::{mem, ptr, slice};
22161 -+use std::os::unix::io::RawFd;
22162 -+use sys::time::TimeVal;
22163 -+use sys::uio::IoVec;
22164 -+
22165 -+mod addr;
22166 -+pub mod sockopt;
22167 -+
22168 -+/*
22169 -+ *
22170 -+ * ===== Re-exports =====
22171 -+ *
22172 -+ */
22173 -+
22174 -+pub use self::addr::{
22175 -+ AddressFamily,
22176 -+ SockAddr,
22177 -+ InetAddr,
22178 -+ UnixAddr,
22179 -+ IpAddr,
22180 -+ Ipv4Addr,
22181 -+ Ipv6Addr,
22182 -+ LinkAddr,
22183 -+};
22184 -+#[cfg(any(target_os = "android", target_os = "linux"))]
22185 -+pub use ::sys::socket::addr::netlink::NetlinkAddr;
22186 -+#[cfg(any(target_os = "android", target_os = "linux"))]
22187 -+pub use sys::socket::addr::alg::AlgAddr;
22188 -+#[cfg(target_os = "linux")]
22189 -+pub use sys::socket::addr::vsock::VsockAddr;
22190 -+
22191 -+pub use libc::{
22192 -+ cmsghdr,
22193 -+ msghdr,
22194 -+ sa_family_t,
22195 -+ sockaddr,
22196 -+ sockaddr_in,
22197 -+ sockaddr_in6,
22198 -+ sockaddr_storage,
22199 -+ sockaddr_un,
22200 -+};
22201 -+
22202 -+// Needed by the cmsg_space macro
22203 -+#[doc(hidden)]
22204 -+pub use libc::{c_uint, CMSG_SPACE};
22205 -+
22206 -+/// These constants are used to specify the communication semantics
22207 -+/// when creating a socket with [`socket()`](fn.socket.html)
22208 -+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
22209 -+#[repr(i32)]
22210 -+pub enum SockType {
22211 -+ /// Provides sequenced, reliable, two-way, connection-
22212 -+ /// based byte streams. An out-of-band data transmission
22213 -+ /// mechanism may be supported.
22214 -+ Stream = libc::SOCK_STREAM,
22215 -+ /// Supports datagrams (connectionless, unreliable
22216 -+ /// messages of a fixed maximum length).
22217 -+ Datagram = libc::SOCK_DGRAM,
22218 -+ /// Provides a sequenced, reliable, two-way connection-
22219 -+ /// based data transmission path for datagrams of fixed
22220 -+ /// maximum length; a consumer is required to read an
22221 -+ /// entire packet with each input system call.
22222 -+ SeqPacket = libc::SOCK_SEQPACKET,
22223 -+ /// Provides raw network protocol access.
22224 -+ Raw = libc::SOCK_RAW,
22225 -+ /// Provides a reliable datagram layer that does not
22226 -+ /// guarantee ordering.
22227 -+ Rdm = libc::SOCK_RDM,
22228 -+}
22229 -+
22230 -+/// Constants used in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html)
22231 -+/// to specify the protocol to use.
22232 -+#[repr(i32)]
22233 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
22234 -+pub enum SockProtocol {
22235 -+ /// TCP protocol ([ip(7)](http://man7.org/linux/man-pages/man7/ip.7.html))
22236 -+ Tcp = libc::IPPROTO_TCP,
22237 -+ /// UDP protocol ([ip(7)](http://man7.org/linux/man-pages/man7/ip.7.html))
22238 -+ Udp = libc::IPPROTO_UDP,
22239 -+ /// Allows applications and other KEXTs to be notified when certain kernel events occur
22240 -+ /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
22241 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
22242 -+ KextEvent = libc::SYSPROTO_EVENT,
22243 -+ /// Allows applications to configure and control a KEXT
22244 -+ /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
22245 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
22246 -+ KextControl = libc::SYSPROTO_CONTROL,
22247 -+}
22248 -+
22249 -+libc_bitflags!{
22250 -+ /// Additional socket options
22251 -+ pub struct SockFlag: c_int {
22252 -+ /// Set non-blocking mode on the new socket
22253 -+ #[cfg(any(target_os = "android",
22254 -+ target_os = "dragonfly",
22255 -+ target_os = "freebsd",
22256 -+ target_os = "linux",
22257 -+ target_os = "netbsd",
22258 -+ target_os = "openbsd"))]
22259 -+ SOCK_NONBLOCK;
22260 -+ /// Set close-on-exec on the new descriptor
22261 -+ #[cfg(any(target_os = "android",
22262 -+ target_os = "dragonfly",
22263 -+ target_os = "freebsd",
22264 -+ target_os = "linux",
22265 -+ target_os = "netbsd",
22266 -+ target_os = "openbsd"))]
22267 -+ SOCK_CLOEXEC;
22268 -+ /// Return `EPIPE` instead of raising `SIGPIPE`
22269 -+ #[cfg(target_os = "netbsd")]
22270 -+ SOCK_NOSIGPIPE;
22271 -+ /// For domains `AF_INET(6)`, only allow `connect(2)`, `sendto(2)`, or `sendmsg(2)`
22272 -+ /// to the DNS port (typically 53)
22273 -+ #[cfg(target_os = "openbsd")]
22274 -+ SOCK_DNS;
22275 -+ }
22276 -+}
22277 -+
22278 -+libc_bitflags!{
22279 -+ /// Flags for send/recv and their relatives
22280 -+ pub struct MsgFlags: c_int {
22281 -+ /// Sends or requests out-of-band data on sockets that support this notion
22282 -+ /// (e.g., of type [`Stream`](enum.SockType.html)); the underlying protocol must also
22283 -+ /// support out-of-band data.
22284 -+ MSG_OOB;
22285 -+ /// Peeks at an incoming message. The data is treated as unread and the next
22286 -+ /// [`recv()`](fn.recv.html)
22287 -+ /// or similar function shall still return this data.
22288 -+ MSG_PEEK;
22289 -+ /// Receive operation blocks until the full amount of data can be
22290 -+ /// returned. The function may return smaller amount of data if a signal
22291 -+ /// is caught, an error or disconnect occurs.
22292 -+ MSG_WAITALL;
22293 -+ /// Enables nonblocking operation; if the operation would block,
22294 -+ /// `EAGAIN` or `EWOULDBLOCK` is returned. This provides similar
22295 -+ /// behavior to setting the `O_NONBLOCK` flag
22296 -+ /// (via the [`fcntl`](../../fcntl/fn.fcntl.html)
22297 -+ /// `F_SETFL` operation), but differs in that `MSG_DONTWAIT` is a per-
22298 -+ /// call option, whereas `O_NONBLOCK` is a setting on the open file
22299 -+ /// description (see [open(2)](http://man7.org/linux/man-pages/man2/open.2.html)),
22300 -+ /// which will affect all threads in
22301 -+ /// the calling process and as well as other processes that hold
22302 -+ /// file descriptors referring to the same open file description.
22303 -+ MSG_DONTWAIT;
22304 -+ /// Receive flags: Control Data was discarded (buffer too small)
22305 -+ MSG_CTRUNC;
22306 -+ /// For raw ([`Packet`](addr/enum.AddressFamily.html)), Internet datagram
22307 -+ /// (since Linux 2.4.27/2.6.8),
22308 -+ /// netlink (since Linux 2.6.22) and UNIX datagram (since Linux 3.4)
22309 -+ /// sockets: return the real length of the packet or datagram, even
22310 -+ /// when it was longer than the passed buffer. Not implemented for UNIX
22311 -+ /// domain ([unix(7)](https://linux.die.net/man/7/unix)) sockets.
22312 -+ ///
22313 -+ /// For use with Internet stream sockets, see [tcp(7)](https://linux.die.net/man/7/tcp).
22314 -+ MSG_TRUNC;
22315 -+ /// Terminates a record (when this notion is supported, as for
22316 -+ /// sockets of type [`SeqPacket`](enum.SockType.html)).
22317 -+ MSG_EOR;
22318 -+ /// This flag specifies that queued errors should be received from
22319 -+ /// the socket error queue. (For more details, see
22320 -+ /// [recvfrom(2)](https://linux.die.net/man/2/recvfrom))
22321 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22322 -+ MSG_ERRQUEUE;
22323 -+ /// Set the `close-on-exec` flag for the file descriptor received via a UNIX domain
22324 -+ /// file descriptor using the `SCM_RIGHTS` operation (described in
22325 -+ /// [unix(7)](https://linux.die.net/man/7/unix)).
22326 -+ /// This flag is useful for the same reasons as the `O_CLOEXEC` flag of
22327 -+ /// [open(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html).
22328 -+ ///
22329 -+ /// Only used in [`recvmsg`](fn.recvmsg.html) function.
22330 -+ #[cfg(any(target_os = "android",
22331 -+ target_os = "dragonfly",
22332 -+ target_os = "freebsd",
22333 -+ target_os = "linux",
22334 -+ target_os = "netbsd",
22335 -+ target_os = "openbsd"))]
22336 -+ MSG_CMSG_CLOEXEC;
22337 -+ }
22338 -+}
22339 -+
22340 -+cfg_if! {
22341 -+ if #[cfg(any(target_os = "android", target_os = "linux"))] {
22342 -+ /// Unix credentials of the sending process.
22343 -+ ///
22344 -+ /// This struct is used with the `SO_PEERCRED` ancillary message for UNIX sockets.
22345 -+ #[repr(C)]
22346 -+ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
22347 -+ pub struct UnixCredentials(libc::ucred);
22348 -+
22349 -+ impl UnixCredentials {
22350 -+ /// Returns the process identifier
22351 -+ pub fn pid(&self) -> libc::pid_t {
22352 -+ self.0.pid
22353 -+ }
22354 -+
22355 -+ /// Returns the user identifier
22356 -+ pub fn uid(&self) -> libc::uid_t {
22357 -+ self.0.uid
22358 -+ }
22359 -+
22360 -+ /// Returns the group identifier
22361 -+ pub fn gid(&self) -> libc::gid_t {
22362 -+ self.0.gid
22363 -+ }
22364 -+ }
22365 -+
22366 -+ impl From<libc::ucred> for UnixCredentials {
22367 -+ fn from(cred: libc::ucred) -> Self {
22368 -+ UnixCredentials(cred)
22369 -+ }
22370 -+ }
22371 -+
22372 -+ impl Into<libc::ucred> for UnixCredentials {
22373 -+ fn into(self) -> libc::ucred {
22374 -+ self.0
22375 -+ }
22376 -+ }
22377 -+ }
22378 -+}
22379 -+
22380 -+/// Request for multicast socket operations
22381 -+///
22382 -+/// This is a wrapper type around `ip_mreq`.
22383 -+#[repr(C)]
22384 -+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
22385 -+pub struct IpMembershipRequest(libc::ip_mreq);
22386 -+
22387 -+impl IpMembershipRequest {
22388 -+ /// Instantiate a new `IpMembershipRequest`
22389 -+ ///
22390 -+ /// If `interface` is `None`, then `Ipv4Addr::any()` will be used for the interface.
22391 -+ pub fn new(group: Ipv4Addr, interface: Option<Ipv4Addr>) -> Self {
22392 -+ IpMembershipRequest(libc::ip_mreq {
22393 -+ imr_multiaddr: group.0,
22394 -+ imr_interface: interface.unwrap_or_else(Ipv4Addr::any).0,
22395 -+ })
22396 -+ }
22397 -+}
22398 -+
22399 -+/// Request for ipv6 multicast socket operations
22400 -+///
22401 -+/// This is a wrapper type around `ipv6_mreq`.
22402 -+#[repr(C)]
22403 -+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
22404 -+pub struct Ipv6MembershipRequest(libc::ipv6_mreq);
22405 -+
22406 -+impl Ipv6MembershipRequest {
22407 -+ /// Instantiate a new `Ipv6MembershipRequest`
22408 -+ pub fn new(group: Ipv6Addr) -> Self {
22409 -+ Ipv6MembershipRequest(libc::ipv6_mreq {
22410 -+ ipv6mr_multiaddr: group.0,
22411 -+ ipv6mr_interface: 0,
22412 -+ })
22413 -+ }
22414 -+}
22415 -+
22416 -+cfg_if! {
22417 -+ // Darwin and DragonFly BSD always align struct cmsghdr to 32-bit only.
22418 -+ if #[cfg(any(target_os = "dragonfly", target_os = "ios", target_os = "macos"))] {
22419 -+ type align_of_cmsg_data = u32;
22420 -+ } else {
22421 -+ type align_of_cmsg_data = size_t;
22422 -+ }
22423 -+}
22424 -+
22425 -+/// A type that can be used to store ancillary data received by
22426 -+/// [`recvmsg`](fn.recvmsg.html)
22427 -+pub trait CmsgBuffer {
22428 -+ fn as_bytes_mut(&mut self) -> &mut [u8];
22429 -+}
22430 -+
22431 -+/// Create a buffer large enough for storing some control messages as returned
22432 -+/// by [`recvmsg`](fn.recvmsg.html).
22433 -+///
22434 -+/// # Examples
22435 -+///
22436 -+/// ```
22437 -+/// # #[macro_use] extern crate nix;
22438 -+/// # use nix::sys::time::TimeVal;
22439 -+/// # use std::os::unix::io::RawFd;
22440 -+/// # fn main() {
22441 -+/// // Create a buffer for a `ControlMessageOwned::ScmTimestamp` message
22442 -+/// let _ = cmsg_space!(TimeVal);
22443 -+/// // Create a buffer big enough for a `ControlMessageOwned::ScmRights` message
22444 -+/// // with two file descriptors
22445 -+/// let _ = cmsg_space!([RawFd; 2]);
22446 -+/// // Create a buffer big enough for a `ControlMessageOwned::ScmRights` message
22447 -+/// // and a `ControlMessageOwned::ScmTimestamp` message
22448 -+/// let _ = cmsg_space!(RawFd, TimeVal);
22449 -+/// # }
22450 -+/// ```
22451 -+// Unfortunately, CMSG_SPACE isn't a const_fn, or else we could return a
22452 -+// stack-allocated array.
22453 -+#[macro_export]
22454 -+macro_rules! cmsg_space {
22455 -+ ( $( $x:ty ),* ) => {
22456 -+ {
22457 -+ use nix::sys::socket::{c_uint, CMSG_SPACE};
22458 -+ use std::mem;
22459 -+ let mut space = 0;
22460 -+ $(
22461 -+ // CMSG_SPACE is always safe
22462 -+ space += unsafe {
22463 -+ CMSG_SPACE(mem::size_of::<$x>() as c_uint)
22464 -+ } as usize;
22465 -+ )*
22466 -+ let mut v = Vec::<u8>::with_capacity(space);
22467 -+ // safe because any bit pattern is a valid u8
22468 -+ unsafe {v.set_len(space)};
22469 -+ v
22470 -+ }
22471 -+ }
22472 -+}
22473 -+
22474 -+/// A structure used to make room in a cmsghdr passed to recvmsg. The
22475 -+/// size and alignment match that of a cmsghdr followed by a T, but the
22476 -+/// fields are not accessible, as the actual types will change on a call
22477 -+/// to recvmsg.
22478 -+///
22479 -+/// To make room for multiple messages, nest the type parameter with
22480 -+/// tuples:
22481 -+///
22482 -+/// ```
22483 -+/// use std::os::unix::io::RawFd;
22484 -+/// use nix::sys::socket::CmsgSpace;
22485 -+/// let cmsg: CmsgSpace<([RawFd; 3], CmsgSpace<[RawFd; 2]>)> = CmsgSpace::new();
22486 -+/// ```
22487 -+#[repr(C)]
22488 -+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
22489 -+pub struct CmsgSpace<T> {
22490 -+ _hdr: cmsghdr,
22491 -+ _pad: [align_of_cmsg_data; 0],
22492 -+ _data: T,
22493 -+}
22494 -+
22495 -+impl<T> CmsgSpace<T> {
22496 -+ /// Create a CmsgSpace<T>. The structure is used only for space, so
22497 -+ /// the fields are uninitialized.
22498 -+ #[deprecated( since="0.14.0", note="Use the cmsg_space! macro instead")]
22499 -+ pub fn new() -> Self {
22500 -+ // Safe because the fields themselves aren't accessible.
22501 -+ unsafe { mem::uninitialized() }
22502 -+ }
22503 -+}
22504 -+
22505 -+impl<T> CmsgBuffer for CmsgSpace<T> {
22506 -+ fn as_bytes_mut(&mut self) -> &mut [u8] {
22507 -+ // Safe because nothing ever attempts to access CmsgSpace's fields
22508 -+ unsafe {
22509 -+ slice::from_raw_parts_mut(self as *mut CmsgSpace<T> as *mut u8,
22510 -+ mem::size_of::<Self>())
22511 -+ }
22512 -+ }
22513 -+}
22514 -+
22515 -+impl CmsgBuffer for Vec<u8> {
22516 -+ fn as_bytes_mut(&mut self) -> &mut [u8] {
22517 -+ &mut self[..]
22518 -+ }
22519 -+}
22520 -+
22521 -+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
22522 -+pub struct RecvMsg<'a> {
22523 -+ pub bytes: usize,
22524 -+ cmsghdr: Option<&'a cmsghdr>,
22525 -+ pub address: Option<SockAddr>,
22526 -+ pub flags: MsgFlags,
22527 -+ mhdr: msghdr,
22528 -+}
22529 -+
22530 -+impl<'a> RecvMsg<'a> {
22531 -+ /// Iterate over the valid control messages pointed to by this
22532 -+ /// msghdr.
22533 -+ pub fn cmsgs(&self) -> CmsgIterator {
22534 -+ CmsgIterator {
22535 -+ cmsghdr: self.cmsghdr,
22536 -+ mhdr: &self.mhdr
22537 -+ }
22538 -+ }
22539 -+}
22540 -+
22541 -+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
22542 -+pub struct CmsgIterator<'a> {
22543 -+ /// Control message buffer to decode from. Must adhere to cmsg alignment.
22544 -+ cmsghdr: Option<&'a cmsghdr>,
22545 -+ mhdr: &'a msghdr
22546 -+}
22547 -+
22548 -+impl<'a> Iterator for CmsgIterator<'a> {
22549 -+ type Item = ControlMessageOwned;
22550 -+
22551 -+ fn next(&mut self) -> Option<ControlMessageOwned> {
22552 -+ match self.cmsghdr {
22553 -+ None => None, // No more messages
22554 -+ Some(hdr) => {
22555 -+ // Get the data.
22556 -+ // Safe if cmsghdr points to valid data returned by recvmsg(2)
22557 -+ let cm = unsafe { Some(ControlMessageOwned::decode_from(hdr))};
22558 -+ // Advance the internal pointer. Safe if mhdr and cmsghdr point
22559 -+ // to valid data returned by recvmsg(2)
22560 -+ self.cmsghdr = unsafe {
22561 -+ let p = CMSG_NXTHDR(self.mhdr as *const _, hdr as *const _);
22562 -+ p.as_ref()
22563 -+ };
22564 -+ cm
22565 -+ }
22566 -+ }
22567 -+ }
22568 -+}
22569 -+
22570 -+/// A type-safe wrapper around a single control message, as used with
22571 -+/// [`recvmsg`](#fn.recvmsg).
22572 -+///
22573 -+/// [Further reading](http://man7.org/linux/man-pages/man3/cmsg.3.html)
22574 -+// Nix version 0.13.0 and earlier used ControlMessage for both recvmsg and
22575 -+// sendmsg. However, on some platforms the messages returned by recvmsg may be
22576 -+// unaligned. ControlMessageOwned takes those messages by copy, obviating any
22577 -+// alignment issues.
22578 -+//
22579 -+// See https://github.com/nix-rust/nix/issues/999
22580 -+#[derive(Clone, Debug, Eq, PartialEq)]
22581 -+pub enum ControlMessageOwned {
22582 -+ /// Received version of
22583 -+ /// [`ControlMessage::ScmRights`][#enum.ControlMessage.html#variant.ScmRights]
22584 -+ ScmRights(Vec<RawFd>),
22585 -+ /// Received version of
22586 -+ /// [`ControlMessage::ScmCredentials`][#enum.ControlMessage.html#variant.ScmCredentials]
22587 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22588 -+ ScmCredentials(libc::ucred),
22589 -+ /// A message of type `SCM_TIMESTAMP`, containing the time the
22590 -+ /// packet was received by the kernel.
22591 -+ ///
22592 -+ /// See the kernel's explanation in "SO_TIMESTAMP" of
22593 -+ /// [networking/timestamping](https://www.kernel.org/doc/Documentation/networking/timestamping.txt).
22594 -+ ///
22595 -+ /// # Examples
22596 -+ ///
22597 -+ // Disable this test on FreeBSD i386
22598 -+ // https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=222039
22599 -+ #[cfg_attr(not(all(target_os = "freebsd", target_arch = "x86")), doc = " ```")]
22600 -+ #[cfg_attr(all(target_os = "freebsd", target_arch = "x86"), doc = " ```no_run")]
22601 -+ /// # #[macro_use] extern crate nix;
22602 -+ /// # use nix::sys::socket::*;
22603 -+ /// # use nix::sys::uio::IoVec;
22604 -+ /// # use nix::sys::time::*;
22605 -+ /// # use std::time::*;
22606 -+ /// # fn main() {
22607 -+ /// // Set up
22608 -+ /// let message = "Ohayō!".as_bytes();
22609 -+ /// let in_socket = socket(
22610 -+ /// AddressFamily::Inet,
22611 -+ /// SockType::Datagram,
22612 -+ /// SockFlag::empty(),
22613 -+ /// None).unwrap();
22614 -+ /// setsockopt(in_socket, sockopt::ReceiveTimestamp, &true).unwrap();
22615 -+ /// let localhost = InetAddr::new(IpAddr::new_v4(127, 0, 0, 1), 0);
22616 -+ /// bind(in_socket, &SockAddr::new_inet(localhost)).unwrap();
22617 -+ /// let address = getsockname(in_socket).unwrap();
22618 -+ /// // Get initial time
22619 -+ /// let time0 = SystemTime::now();
22620 -+ /// // Send the message
22621 -+ /// let iov = [IoVec::from_slice(message)];
22622 -+ /// let flags = MsgFlags::empty();
22623 -+ /// let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap();
22624 -+ /// assert_eq!(message.len(), l);
22625 -+ /// // Receive the message
22626 -+ /// let mut buffer = vec![0u8; message.len()];
22627 -+ /// let mut cmsgspace = cmsg_space!(TimeVal);
22628 -+ /// let iov = [IoVec::from_mut_slice(&mut buffer)];
22629 -+ /// let r = recvmsg(in_socket, &iov, Some(&mut cmsgspace), flags).unwrap();
22630 -+ /// let rtime = match r.cmsgs().next() {
22631 -+ /// Some(ControlMessageOwned::ScmTimestamp(rtime)) => rtime,
22632 -+ /// Some(_) => panic!("Unexpected control message"),
22633 -+ /// None => panic!("No control message")
22634 -+ /// };
22635 -+ /// // Check the final time
22636 -+ /// let time1 = SystemTime::now();
22637 -+ /// // the packet's received timestamp should lie in-between the two system
22638 -+ /// // times, unless the system clock was adjusted in the meantime.
22639 -+ /// let rduration = Duration::new(rtime.tv_sec() as u64,
22640 -+ /// rtime.tv_usec() as u32 * 1000);
22641 -+ /// assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration);
22642 -+ /// assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap());
22643 -+ /// // Close socket
22644 -+ /// nix::unistd::close(in_socket).unwrap();
22645 -+ /// # }
22646 -+ /// ```
22647 -+ ScmTimestamp(TimeVal),
22648 -+ #[cfg(any(
22649 -+ target_os = "android",
22650 -+ target_os = "ios",
22651 -+ target_os = "linux",
22652 -+ target_os = "macos",
22653 -+ target_os = "netbsd",
22654 -+ ))]
22655 -+ Ipv4PacketInfo(libc::in_pktinfo),
22656 -+ #[cfg(any(
22657 -+ target_os = "android",
22658 -+ target_os = "dragonfly",
22659 -+ target_os = "freebsd",
22660 -+ target_os = "ios",
22661 -+ target_os = "linux",
22662 -+ target_os = "macos",
22663 -+ target_os = "openbsd",
22664 -+ target_os = "netbsd",
22665 -+ ))]
22666 -+ Ipv6PacketInfo(libc::in6_pktinfo),
22667 -+ #[cfg(any(
22668 -+ target_os = "freebsd",
22669 -+ target_os = "ios",
22670 -+ target_os = "macos",
22671 -+ target_os = "netbsd",
22672 -+ target_os = "openbsd",
22673 -+ ))]
22674 -+ Ipv4RecvIf(libc::sockaddr_dl),
22675 -+ #[cfg(any(
22676 -+ target_os = "freebsd",
22677 -+ target_os = "ios",
22678 -+ target_os = "macos",
22679 -+ target_os = "netbsd",
22680 -+ target_os = "openbsd",
22681 -+ ))]
22682 -+ Ipv4RecvDstAddr(libc::in_addr),
22683 -+ /// Catch-all variant for unimplemented cmsg types.
22684 -+ #[doc(hidden)]
22685 -+ Unknown(UnknownCmsg),
22686 -+}
22687 -+
22688 -+impl ControlMessageOwned {
22689 -+ /// Decodes a `ControlMessageOwned` from raw bytes.
22690 -+ ///
22691 -+ /// This is only safe to call if the data is correct for the message type
22692 -+ /// specified in the header. Normally, the kernel ensures that this is the
22693 -+ /// case. "Correct" in this case includes correct length, alignment and
22694 -+ /// actual content.
22695 -+ ///
22696 -+ /// Returns `None` if the data may be unaligned. In that case use
22697 -+ /// `ControlMessageOwned::decode_from`.
22698 -+ unsafe fn decode_from(header: &cmsghdr) -> ControlMessageOwned
22699 -+ {
22700 -+ let p = CMSG_DATA(header);
22701 -+ let len = header as *const _ as usize + header.cmsg_len as usize
22702 -+ - p as usize;
22703 -+ match (header.cmsg_level, header.cmsg_type) {
22704 -+ (libc::SOL_SOCKET, libc::SCM_RIGHTS) => {
22705 -+ let n = len / mem::size_of::<RawFd>();
22706 -+ let mut fds = Vec::with_capacity(n);
22707 -+ for i in 0..n {
22708 -+ let fdp = (p as *const RawFd).offset(i as isize);
22709 -+ fds.push(ptr::read_unaligned(fdp));
22710 -+ }
22711 -+ let cmo = ControlMessageOwned::ScmRights(fds);
22712 -+ cmo
22713 -+ },
22714 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22715 -+ (libc::SOL_SOCKET, libc::SCM_CREDENTIALS) => {
22716 -+ let cred: libc::ucred = ptr::read_unaligned(p as *const _);
22717 -+ ControlMessageOwned::ScmCredentials(cred)
22718 -+ }
22719 -+ (libc::SOL_SOCKET, libc::SCM_TIMESTAMP) => {
22720 -+ let tv: libc::timeval = ptr::read_unaligned(p as *const _);
22721 -+ ControlMessageOwned::ScmTimestamp(TimeVal::from(tv))
22722 -+ },
22723 -+ #[cfg(any(
22724 -+ target_os = "android",
22725 -+ target_os = "freebsd",
22726 -+ target_os = "ios",
22727 -+ target_os = "linux",
22728 -+ target_os = "macos"
22729 -+ ))]
22730 -+ (libc::IPPROTO_IPV6, libc::IPV6_PKTINFO) => {
22731 -+ let info = ptr::read_unaligned(p as *const libc::in6_pktinfo);
22732 -+ ControlMessageOwned::Ipv6PacketInfo(info)
22733 -+ }
22734 -+ #[cfg(any(
22735 -+ target_os = "android",
22736 -+ target_os = "ios",
22737 -+ target_os = "linux",
22738 -+ target_os = "macos",
22739 -+ target_os = "netbsd",
22740 -+ ))]
22741 -+ (libc::IPPROTO_IP, libc::IP_PKTINFO) => {
22742 -+ let info = ptr::read_unaligned(p as *const libc::in_pktinfo);
22743 -+ ControlMessageOwned::Ipv4PacketInfo(info)
22744 -+ }
22745 -+ #[cfg(any(
22746 -+ target_os = "freebsd",
22747 -+ target_os = "ios",
22748 -+ target_os = "macos",
22749 -+ target_os = "netbsd",
22750 -+ target_os = "openbsd",
22751 -+ ))]
22752 -+ (libc::IPPROTO_IP, libc::IP_RECVIF) => {
22753 -+ let dl = ptr::read_unaligned(p as *const libc::sockaddr_dl);
22754 -+ ControlMessageOwned::Ipv4RecvIf(dl)
22755 -+ },
22756 -+ #[cfg(any(
22757 -+ target_os = "freebsd",
22758 -+ target_os = "ios",
22759 -+ target_os = "macos",
22760 -+ target_os = "netbsd",
22761 -+ target_os = "openbsd",
22762 -+ ))]
22763 -+ (libc::IPPROTO_IP, libc::IP_RECVDSTADDR) => {
22764 -+ let dl = ptr::read_unaligned(p as *const libc::in_addr);
22765 -+ ControlMessageOwned::Ipv4RecvDstAddr(dl)
22766 -+ },
22767 -+ (_, _) => {
22768 -+ let sl = slice::from_raw_parts(p, len);
22769 -+ let ucmsg = UnknownCmsg(*header, Vec::<u8>::from(&sl[..]));
22770 -+ ControlMessageOwned::Unknown(ucmsg)
22771 -+ }
22772 -+ }
22773 -+ }
22774 -+}
22775 -+
22776 -+/// A type-safe zero-copy wrapper around a single control message, as used wih
22777 -+/// [`sendmsg`](#fn.sendmsg). More types may be added to this enum; do not
22778 -+/// exhaustively pattern-match it.
22779 -+///
22780 -+/// [Further reading](http://man7.org/linux/man-pages/man3/cmsg.3.html)
22781 -+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
22782 -+pub enum ControlMessage<'a> {
22783 -+ /// A message of type `SCM_RIGHTS`, containing an array of file
22784 -+ /// descriptors passed between processes.
22785 -+ ///
22786 -+ /// See the description in the "Ancillary messages" section of the
22787 -+ /// [unix(7) man page](http://man7.org/linux/man-pages/man7/unix.7.html).
22788 -+ ///
22789 -+ /// Using multiple `ScmRights` messages for a single `sendmsg` call isn't
22790 -+ /// recommended since it causes platform-dependent behaviour: It might
22791 -+ /// swallow all but the first `ScmRights` message or fail with `EINVAL`.
22792 -+ /// Instead, you can put all fds to be passed into a single `ScmRights`
22793 -+ /// message.
22794 -+ ScmRights(&'a [RawFd]),
22795 -+ /// A message of type `SCM_CREDENTIALS`, containing the pid, uid and gid of
22796 -+ /// a process connected to the socket.
22797 -+ ///
22798 -+ /// This is similar to the socket option `SO_PEERCRED`, but requires a
22799 -+ /// process to explicitly send its credentials. A process running as root is
22800 -+ /// allowed to specify any credentials, while credentials sent by other
22801 -+ /// processes are verified by the kernel.
22802 -+ ///
22803 -+ /// For further information, please refer to the
22804 -+ /// [`unix(7)`](http://man7.org/linux/man-pages/man7/unix.7.html) man page.
22805 -+ // FIXME: When `#[repr(transparent)]` is stable, use it on `UnixCredentials`
22806 -+ // and put that in here instead of a raw ucred.
22807 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22808 -+ ScmCredentials(&'a libc::ucred),
22809 -+
22810 -+ /// Set IV for `AF_ALG` crypto API.
22811 -+ ///
22812 -+ /// For further information, please refer to the
22813 -+ /// [`documentation`](https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html)
22814 -+ #[cfg(any(
22815 -+ target_os = "android",
22816 -+ target_os = "linux",
22817 -+ ))]
22818 -+ AlgSetIv(&'a [u8]),
22819 -+ /// Set crypto operation for `AF_ALG` crypto API. It may be one of
22820 -+ /// `ALG_OP_ENCRYPT` or `ALG_OP_DECRYPT`
22821 -+ ///
22822 -+ /// For further information, please refer to the
22823 -+ /// [`documentation`](https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html)
22824 -+ #[cfg(any(
22825 -+ target_os = "android",
22826 -+ target_os = "linux",
22827 -+ ))]
22828 -+ AlgSetOp(&'a libc::c_int),
22829 -+ /// Set the length of associated authentication data (AAD) (applicable only to AEAD algorithms)
22830 -+ /// for `AF_ALG` crypto API.
22831 -+ ///
22832 -+ /// For further information, please refer to the
22833 -+ /// [`documentation`](https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html)
22834 -+ #[cfg(any(
22835 -+ target_os = "android",
22836 -+ target_os = "linux",
22837 -+ ))]
22838 -+ AlgSetAeadAssoclen(&'a u32),
22839 -+
22840 -+}
22841 -+
22842 -+// An opaque structure used to prevent cmsghdr from being a public type
22843 -+#[doc(hidden)]
22844 -+#[derive(Clone, Debug, Eq, PartialEq)]
22845 -+pub struct UnknownCmsg(cmsghdr, Vec<u8>);
22846 -+
22847 -+impl<'a> ControlMessage<'a> {
22848 -+ /// The value of CMSG_SPACE on this message.
22849 -+ /// Safe because CMSG_SPACE is always safe
22850 -+ fn space(&self) -> usize {
22851 -+ unsafe{CMSG_SPACE(self.len() as libc::c_uint) as usize}
22852 -+ }
22853 -+
22854 -+ /// The value of CMSG_LEN on this message.
22855 -+ /// Safe because CMSG_LEN is always safe
22856 -+ #[cfg(any(target_os = "android",
22857 -+ all(target_os = "linux", not(target_env = "musl"))))]
22858 -+ fn cmsg_len(&self) -> usize {
22859 -+ unsafe{CMSG_LEN(self.len() as libc::c_uint) as usize}
22860 -+ }
22861 -+
22862 -+ #[cfg(not(any(target_os = "android",
22863 -+ all(target_os = "linux", not(target_env = "musl")))))]
22864 -+ fn cmsg_len(&self) -> libc::c_uint {
22865 -+ unsafe{CMSG_LEN(self.len() as libc::c_uint)}
22866 -+ }
22867 -+
22868 -+ /// Return a reference to the payload data as a byte pointer
22869 -+ fn copy_to_cmsg_data(&self, cmsg_data: *mut u8) {
22870 -+ let data_ptr = match self {
22871 -+ &ControlMessage::ScmRights(fds) => {
22872 -+ fds as *const _ as *const u8
22873 -+ },
22874 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22875 -+ &ControlMessage::ScmCredentials(creds) => {
22876 -+ creds as *const libc::ucred as *const u8
22877 -+ }
22878 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22879 -+ &ControlMessage::AlgSetIv(iv) => {
22880 -+ unsafe {
22881 -+ let alg_iv = cmsg_data as *mut libc::af_alg_iv;
22882 -+ (*alg_iv).ivlen = iv.len() as u32;
22883 -+ ptr::copy_nonoverlapping(
22884 -+ iv.as_ptr(),
22885 -+ (*alg_iv).iv.as_mut_ptr(),
22886 -+ iv.len()
22887 -+ );
22888 -+ };
22889 -+ return
22890 -+ },
22891 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22892 -+ &ControlMessage::AlgSetOp(op) => {
22893 -+ op as *const _ as *const u8
22894 -+ },
22895 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22896 -+ &ControlMessage::AlgSetAeadAssoclen(len) => {
22897 -+ len as *const _ as *const u8
22898 -+ },
22899 -+ };
22900 -+ unsafe {
22901 -+ ptr::copy_nonoverlapping(
22902 -+ data_ptr,
22903 -+ cmsg_data,
22904 -+ self.len()
22905 -+ )
22906 -+ };
22907 -+ }
22908 -+
22909 -+ /// The size of the payload, excluding its cmsghdr
22910 -+ fn len(&self) -> usize {
22911 -+ match self {
22912 -+ &ControlMessage::ScmRights(fds) => {
22913 -+ mem::size_of_val(fds)
22914 -+ },
22915 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22916 -+ &ControlMessage::ScmCredentials(creds) => {
22917 -+ mem::size_of_val(creds)
22918 -+ }
22919 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22920 -+ &ControlMessage::AlgSetIv(iv) => {
22921 -+ mem::size_of::<libc::af_alg_iv>() + iv.len()
22922 -+ },
22923 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22924 -+ &ControlMessage::AlgSetOp(op) => {
22925 -+ mem::size_of_val(op)
22926 -+ },
22927 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22928 -+ &ControlMessage::AlgSetAeadAssoclen(len) => {
22929 -+ mem::size_of_val(len)
22930 -+ },
22931 -+ }
22932 -+ }
22933 -+
22934 -+ /// Returns the value to put into the `cmsg_level` field of the header.
22935 -+ fn cmsg_level(&self) -> libc::c_int {
22936 -+ match self {
22937 -+ &ControlMessage::ScmRights(_) => libc::SOL_SOCKET,
22938 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22939 -+ &ControlMessage::ScmCredentials(_) => libc::SOL_SOCKET,
22940 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22941 -+ &ControlMessage::AlgSetIv(_) | &ControlMessage::AlgSetOp(_) | &ControlMessage::AlgSetAeadAssoclen(_) => {
22942 -+ libc::SOL_ALG
22943 -+ },
22944 -+ }
22945 -+ }
22946 -+
22947 -+ /// Returns the value to put into the `cmsg_type` field of the header.
22948 -+ fn cmsg_type(&self) -> libc::c_int {
22949 -+ match self {
22950 -+ &ControlMessage::ScmRights(_) => libc::SCM_RIGHTS,
22951 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22952 -+ &ControlMessage::ScmCredentials(_) => libc::SCM_CREDENTIALS,
22953 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22954 -+ &ControlMessage::AlgSetIv(_) => {
22955 -+ libc::ALG_SET_IV
22956 -+ },
22957 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22958 -+ &ControlMessage::AlgSetOp(_) => {
22959 -+ libc::ALG_SET_OP
22960 -+ },
22961 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
22962 -+ &ControlMessage::AlgSetAeadAssoclen(_) => {
22963 -+ libc::ALG_SET_AEAD_ASSOCLEN
22964 -+ },
22965 -+ }
22966 -+ }
22967 -+
22968 -+ // Unsafe: cmsg must point to a valid cmsghdr with enough space to
22969 -+ // encode self.
22970 -+ unsafe fn encode_into(&self, cmsg: *mut cmsghdr) {
22971 -+ (*cmsg).cmsg_level = self.cmsg_level();
22972 -+ (*cmsg).cmsg_type = self.cmsg_type();
22973 -+ (*cmsg).cmsg_len = self.cmsg_len();
22974 -+ self.copy_to_cmsg_data(CMSG_DATA(cmsg));
22975 -+ }
22976 -+}
22977 -+
22978 -+
22979 -+/// Send data in scatter-gather vectors to a socket, possibly accompanied
22980 -+/// by ancillary data. Optionally direct the message at the given address,
22981 -+/// as with sendto.
22982 -+///
22983 -+/// Allocates if cmsgs is nonempty.
22984 -+pub fn sendmsg(fd: RawFd, iov: &[IoVec<&[u8]>], cmsgs: &[ControlMessage],
22985 -+ flags: MsgFlags, addr: Option<&SockAddr>) -> Result<usize>
22986 -+{
22987 -+ let capacity = cmsgs.iter().map(|c| c.space()).sum();
22988 -+
22989 -+ // First size the buffer needed to hold the cmsgs. It must be zeroed,
22990 -+ // because subsequent code will not clear the padding bytes.
22991 -+ let cmsg_buffer = vec![0u8; capacity];
22992 -+
22993 -+ // Next encode the sending address, if provided
22994 -+ let (name, namelen) = match addr {
22995 -+ Some(addr) => {
22996 -+ let (x, y) = unsafe { addr.as_ffi_pair() };
22997 -+ (x as *const _, y)
22998 -+ },
22999 -+ None => (ptr::null(), 0),
23000 -+ };
23001 -+
23002 -+ // The message header must be initialized before the individual cmsgs.
23003 -+ let cmsg_ptr = if capacity > 0 {
23004 -+ cmsg_buffer.as_ptr() as *mut c_void
23005 -+ } else {
23006 -+ ptr::null_mut()
23007 -+ };
23008 -+
23009 -+ let mhdr = {
23010 -+ // Musl's msghdr has private fields, so this is the only way to
23011 -+ // initialize it.
23012 -+ let mut mhdr: msghdr = unsafe{mem::uninitialized()};
23013 -+ mhdr.msg_name = name as *mut _;
23014 -+ mhdr.msg_namelen = namelen;
23015 -+ // transmute iov into a mutable pointer. sendmsg doesn't really mutate
23016 -+ // the buffer, but the standard says that it takes a mutable pointer
23017 -+ mhdr.msg_iov = iov.as_ptr() as *mut _;
23018 -+ mhdr.msg_iovlen = iov.len() as _;
23019 -+ mhdr.msg_control = cmsg_ptr;
23020 -+ mhdr.msg_controllen = capacity as _;
23021 -+ mhdr.msg_flags = 0;
23022 -+ mhdr
23023 -+ };
23024 -+
23025 -+ // Encode each cmsg. This must happen after initializing the header because
23026 -+ // CMSG_NEXT_HDR and friends read the msg_control and msg_controllen fields.
23027 -+ // CMSG_FIRSTHDR is always safe
23028 -+ let mut pmhdr: *mut cmsghdr = unsafe{CMSG_FIRSTHDR(&mhdr as *const msghdr)};
23029 -+ for cmsg in cmsgs {
23030 -+ assert_ne!(pmhdr, ptr::null_mut());
23031 -+ // Safe because we know that pmhdr is valid, and we initialized it with
23032 -+ // sufficient space
23033 -+ unsafe { cmsg.encode_into(pmhdr) };
23034 -+ // Safe because mhdr is valid
23035 -+ pmhdr = unsafe{CMSG_NXTHDR(&mhdr as *const msghdr, pmhdr)};
23036 -+ }
23037 -+
23038 -+ let ret = unsafe { libc::sendmsg(fd, &mhdr, flags.bits()) };
23039 -+
23040 -+ Errno::result(ret).map(|r| r as usize)
23041 -+}
23042 -+
23043 -+/// Receive message in scatter-gather vectors from a socket, and
23044 -+/// optionally receive ancillary data into the provided buffer.
23045 -+/// If no ancillary data is desired, use () as the type parameter.
23046 -+///
23047 -+/// # References
23048 -+/// [recvmsg(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html)
23049 -+pub fn recvmsg<'a>(fd: RawFd, iov: &[IoVec<&mut [u8]>],
23050 -+ cmsg_buffer: Option<&'a mut dyn CmsgBuffer>,
23051 -+ flags: MsgFlags) -> Result<RecvMsg<'a>>
23052 -+{
23053 -+ let mut address: sockaddr_storage = unsafe { mem::uninitialized() };
23054 -+ let (msg_control, msg_controllen) = match cmsg_buffer {
23055 -+ Some(cmsgspace) => {
23056 -+ let msg_buf = cmsgspace.as_bytes_mut();
23057 -+ (msg_buf.as_mut_ptr(), msg_buf.len())
23058 -+ },
23059 -+ None => (ptr::null_mut(), 0),
23060 -+ };
23061 -+ let mut mhdr = {
23062 -+ // Musl's msghdr has private fields, so this is the only way to
23063 -+ // initialize it.
23064 -+ let mut mhdr: msghdr = unsafe{mem::uninitialized()};
23065 -+ mhdr.msg_name = &mut address as *mut sockaddr_storage as *mut c_void;
23066 -+ mhdr.msg_namelen = mem::size_of::<sockaddr_storage>() as socklen_t;
23067 -+ mhdr.msg_iov = iov.as_ptr() as *mut iovec;
23068 -+ mhdr.msg_iovlen = iov.len() as _;
23069 -+ mhdr.msg_control = msg_control as *mut c_void;
23070 -+ mhdr.msg_controllen = msg_controllen as _;
23071 -+ mhdr.msg_flags = 0;
23072 -+ mhdr
23073 -+ };
23074 -+
23075 -+ let ret = unsafe { libc::recvmsg(fd, &mut mhdr, flags.bits()) };
23076 -+
23077 -+ Errno::result(ret).map(|r| {
23078 -+ let cmsghdr = unsafe {
23079 -+ if mhdr.msg_controllen > 0 {
23080 -+ // got control message(s)
23081 -+ debug_assert!(!mhdr.msg_control.is_null());
23082 -+ debug_assert!(msg_controllen >= mhdr.msg_controllen as usize);
23083 -+ CMSG_FIRSTHDR(&mhdr as *const msghdr)
23084 -+ } else {
23085 -+ ptr::null()
23086 -+ }.as_ref()
23087 -+ };
23088 -+
23089 -+ let address = unsafe {
23090 -+ sockaddr_storage_to_addr(&address, mhdr.msg_namelen as usize).ok()
23091 -+ };
23092 -+ RecvMsg {
23093 -+ bytes: r as usize,
23094 -+ cmsghdr,
23095 -+ address,
23096 -+ flags: MsgFlags::from_bits_truncate(mhdr.msg_flags),
23097 -+ mhdr,
23098 -+ }
23099 -+ })
23100 -+}
23101 -+
23102 -+
23103 -+/// Create an endpoint for communication
23104 -+///
23105 -+/// The `protocol` specifies a particular protocol to be used with the
23106 -+/// socket. Normally only a single protocol exists to support a
23107 -+/// particular socket type within a given protocol family, in which case
23108 -+/// protocol can be specified as `None`. However, it is possible that many
23109 -+/// protocols may exist, in which case a particular protocol must be
23110 -+/// specified in this manner.
23111 -+///
23112 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html)
23113 -+pub fn socket<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: T) -> Result<RawFd> {
23114 -+ let protocol = match protocol.into() {
23115 -+ None => 0,
23116 -+ Some(p) => p as c_int,
23117 -+ };
23118 -+
23119 -+ // SockFlags are usually embedded into `ty`, but we don't do that in `nix` because it's a
23120 -+ // little easier to understand by separating it out. So we have to merge these bitfields
23121 -+ // here.
23122 -+ let mut ty = ty as c_int;
23123 -+ ty |= flags.bits();
23124 -+
23125 -+ let res = unsafe { libc::socket(domain as c_int, ty, protocol) };
23126 -+
23127 -+ Errno::result(res)
23128 -+}
23129 -+
23130 -+/// Create a pair of connected sockets
23131 -+///
23132 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/socketpair.html)
23133 -+pub fn socketpair<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType, protocol: T,
23134 -+ flags: SockFlag) -> Result<(RawFd, RawFd)> {
23135 -+ let protocol = match protocol.into() {
23136 -+ None => 0,
23137 -+ Some(p) => p as c_int,
23138 -+ };
23139 -+
23140 -+ // SockFlags are usually embedded into `ty`, but we don't do that in `nix` because it's a
23141 -+ // little easier to understand by separating it out. So we have to merge these bitfields
23142 -+ // here.
23143 -+ let mut ty = ty as c_int;
23144 -+ ty |= flags.bits();
23145 -+
23146 -+ let mut fds = [-1, -1];
23147 -+
23148 -+ let res = unsafe { libc::socketpair(domain as c_int, ty, protocol, fds.as_mut_ptr()) };
23149 -+ Errno::result(res)?;
23150 -+
23151 -+ Ok((fds[0], fds[1]))
23152 -+}
23153 -+
23154 -+/// Listen for connections on a socket
23155 -+///
23156 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html)
23157 -+pub fn listen(sockfd: RawFd, backlog: usize) -> Result<()> {
23158 -+ let res = unsafe { libc::listen(sockfd, backlog as c_int) };
23159 -+
23160 -+ Errno::result(res).map(drop)
23161 -+}
23162 -+
23163 -+/// Bind a name to a socket
23164 -+///
23165 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html)
23166 -+pub fn bind(fd: RawFd, addr: &SockAddr) -> Result<()> {
23167 -+ let res = unsafe {
23168 -+ let (ptr, len) = addr.as_ffi_pair();
23169 -+ libc::bind(fd, ptr, len)
23170 -+ };
23171 -+
23172 -+ Errno::result(res).map(drop)
23173 -+}
23174 -+
23175 -+/// Accept a connection on a socket
23176 -+///
23177 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html)
23178 -+pub fn accept(sockfd: RawFd) -> Result<RawFd> {
23179 -+ let res = unsafe { libc::accept(sockfd, ptr::null_mut(), ptr::null_mut()) };
23180 -+
23181 -+ Errno::result(res)
23182 -+}
23183 -+
23184 -+/// Accept a connection on a socket
23185 -+///
23186 -+/// [Further reading](http://man7.org/linux/man-pages/man2/accept.2.html)
23187 -+#[cfg(any(target_os = "android",
23188 -+ target_os = "freebsd",
23189 -+ target_os = "linux",
23190 -+ target_os = "openbsd"))]
23191 -+pub fn accept4(sockfd: RawFd, flags: SockFlag) -> Result<RawFd> {
23192 -+ let res = unsafe { libc::accept4(sockfd, ptr::null_mut(), ptr::null_mut(), flags.bits()) };
23193 -+
23194 -+ Errno::result(res)
23195 -+}
23196 -+
23197 -+/// Initiate a connection on a socket
23198 -+///
23199 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html)
23200 -+pub fn connect(fd: RawFd, addr: &SockAddr) -> Result<()> {
23201 -+ let res = unsafe {
23202 -+ let (ptr, len) = addr.as_ffi_pair();
23203 -+ libc::connect(fd, ptr, len)
23204 -+ };
23205 -+
23206 -+ Errno::result(res).map(drop)
23207 -+}
23208 -+
23209 -+/// Receive data from a connection-oriented socket. Returns the number of
23210 -+/// bytes read
23211 -+///
23212 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html)
23213 -+pub fn recv(sockfd: RawFd, buf: &mut [u8], flags: MsgFlags) -> Result<usize> {
23214 -+ unsafe {
23215 -+ let ret = libc::recv(
23216 -+ sockfd,
23217 -+ buf.as_ptr() as *mut c_void,
23218 -+ buf.len() as size_t,
23219 -+ flags.bits());
23220 -+
23221 -+ Errno::result(ret).map(|r| r as usize)
23222 -+ }
23223 -+}
23224 -+
23225 -+/// Receive data from a connectionless or connection-oriented socket. Returns
23226 -+/// the number of bytes read and the socket address of the sender.
23227 -+///
23228 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html)
23229 -+pub fn recvfrom(sockfd: RawFd, buf: &mut [u8]) -> Result<(usize, SockAddr)> {
23230 -+ unsafe {
23231 -+ let addr: sockaddr_storage = mem::zeroed();
23232 -+ let mut len = mem::size_of::<sockaddr_storage>() as socklen_t;
23233 -+
23234 -+ let ret = Errno::result(libc::recvfrom(
23235 -+ sockfd,
23236 -+ buf.as_ptr() as *mut c_void,
23237 -+ buf.len() as size_t,
23238 -+ 0,
23239 -+ mem::transmute(&addr),
23240 -+ &mut len as *mut socklen_t))?;
23241 -+
23242 -+ sockaddr_storage_to_addr(&addr, len as usize)
23243 -+ .map(|addr| (ret as usize, addr))
23244 -+ }
23245 -+}
23246 -+
23247 -+/// Send a message to a socket
23248 -+///
23249 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html)
23250 -+pub fn sendto(fd: RawFd, buf: &[u8], addr: &SockAddr, flags: MsgFlags) -> Result<usize> {
23251 -+ let ret = unsafe {
23252 -+ let (ptr, len) = addr.as_ffi_pair();
23253 -+ libc::sendto(fd, buf.as_ptr() as *const c_void, buf.len() as size_t, flags.bits(), ptr, len)
23254 -+ };
23255 -+
23256 -+ Errno::result(ret).map(|r| r as usize)
23257 -+}
23258 -+
23259 -+/// Send data to a connection-oriented socket. Returns the number of bytes read
23260 -+///
23261 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html)
23262 -+pub fn send(fd: RawFd, buf: &[u8], flags: MsgFlags) -> Result<usize> {
23263 -+ let ret = unsafe {
23264 -+ libc::send(fd, buf.as_ptr() as *const c_void, buf.len() as size_t, flags.bits())
23265 -+ };
23266 -+
23267 -+ Errno::result(ret).map(|r| r as usize)
23268 -+}
23269 -+
23270 -+/*
23271 -+ *
23272 -+ * ===== Socket Options =====
23273 -+ *
23274 -+ */
23275 -+
23276 -+/// The protocol level at which to get / set socket options. Used as an
23277 -+/// argument to `getsockopt` and `setsockopt`.
23278 -+///
23279 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html)
23280 -+#[repr(i32)]
23281 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
23282 -+pub enum SockLevel {
23283 -+ Socket = libc::SOL_SOCKET,
23284 -+ Tcp = libc::IPPROTO_TCP,
23285 -+ Ip = libc::IPPROTO_IP,
23286 -+ Ipv6 = libc::IPPROTO_IPV6,
23287 -+ Udp = libc::IPPROTO_UDP,
23288 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
23289 -+ Netlink = libc::SOL_NETLINK,
23290 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
23291 -+ Alg = libc::SOL_ALG,
23292 -+}
23293 -+
23294 -+/// Represents a socket option that can be accessed or set. Used as an argument
23295 -+/// to `getsockopt`
23296 -+pub trait GetSockOpt : Copy {
23297 -+ type Val;
23298 -+
23299 -+ #[doc(hidden)]
23300 -+ fn get(&self, fd: RawFd) -> Result<Self::Val>;
23301 -+}
23302 -+
23303 -+/// Represents a socket option that can be accessed or set. Used as an argument
23304 -+/// to `setsockopt`
23305 -+pub trait SetSockOpt : Clone {
23306 -+ type Val;
23307 -+
23308 -+ #[doc(hidden)]
23309 -+ fn set(&self, fd: RawFd, val: &Self::Val) -> Result<()>;
23310 -+}
23311 -+
23312 -+/// Get the current value for the requested socket option
23313 -+///
23314 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html)
23315 -+pub fn getsockopt<O: GetSockOpt>(fd: RawFd, opt: O) -> Result<O::Val> {
23316 -+ opt.get(fd)
23317 -+}
23318 -+
23319 -+/// Sets the value for the requested socket option
23320 -+///
23321 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html)
23322 -+///
23323 -+/// # Examples
23324 -+///
23325 -+/// ```
23326 -+/// use nix::sys::socket::setsockopt;
23327 -+/// use nix::sys::socket::sockopt::KeepAlive;
23328 -+/// use std::net::TcpListener;
23329 -+/// use std::os::unix::io::AsRawFd;
23330 -+///
23331 -+/// let listener = TcpListener::bind("0.0.0.0:0").unwrap();
23332 -+/// let fd = listener.as_raw_fd();
23333 -+/// let res = setsockopt(fd, KeepAlive, &true);
23334 -+/// assert!(res.is_ok());
23335 -+/// ```
23336 -+pub fn setsockopt<O: SetSockOpt>(fd: RawFd, opt: O, val: &O::Val) -> Result<()> {
23337 -+ opt.set(fd, val)
23338 -+}
23339 -+
23340 -+/// Get the address of the peer connected to the socket `fd`.
23341 -+///
23342 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html)
23343 -+pub fn getpeername(fd: RawFd) -> Result<SockAddr> {
23344 -+ unsafe {
23345 -+ let addr: sockaddr_storage = mem::uninitialized();
23346 -+ let mut len = mem::size_of::<sockaddr_storage>() as socklen_t;
23347 -+
23348 -+ let ret = libc::getpeername(fd, mem::transmute(&addr), &mut len);
23349 -+
23350 -+ Errno::result(ret)?;
23351 -+
23352 -+ sockaddr_storage_to_addr(&addr, len as usize)
23353 -+ }
23354 -+}
23355 -+
23356 -+/// Get the current address to which the socket `fd` is bound.
23357 -+///
23358 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html)
23359 -+pub fn getsockname(fd: RawFd) -> Result<SockAddr> {
23360 -+ unsafe {
23361 -+ let addr: sockaddr_storage = mem::uninitialized();
23362 -+ let mut len = mem::size_of::<sockaddr_storage>() as socklen_t;
23363 -+
23364 -+ let ret = libc::getsockname(fd, mem::transmute(&addr), &mut len);
23365 -+
23366 -+ Errno::result(ret)?;
23367 -+
23368 -+ sockaddr_storage_to_addr(&addr, len as usize)
23369 -+ }
23370 -+}
23371 -+
23372 -+/// Return the appropriate `SockAddr` type from a `sockaddr_storage` of a certain
23373 -+/// size. In C this would usually be done by casting. The `len` argument
23374 -+/// should be the number of bytes in the `sockaddr_storage` that are actually
23375 -+/// allocated and valid. It must be at least as large as all the useful parts
23376 -+/// of the structure. Note that in the case of a `sockaddr_un`, `len` need not
23377 -+/// include the terminating null.
23378 -+pub unsafe fn sockaddr_storage_to_addr(
23379 -+ addr: &sockaddr_storage,
23380 -+ len: usize) -> Result<SockAddr> {
23381 -+
23382 -+ if len < mem::size_of_val(&addr.ss_family) {
23383 -+ return Err(Error::Sys(Errno::ENOTCONN));
23384 -+ }
23385 -+
23386 -+ match addr.ss_family as c_int {
23387 -+ libc::AF_INET => {
23388 -+ assert!(len as usize == mem::size_of::<sockaddr_in>());
23389 -+ let ret = *(addr as *const _ as *const sockaddr_in);
23390 -+ Ok(SockAddr::Inet(InetAddr::V4(ret)))
23391 -+ }
23392 -+ libc::AF_INET6 => {
23393 -+ assert!(len as usize == mem::size_of::<sockaddr_in6>());
23394 -+ Ok(SockAddr::Inet(InetAddr::V6(*(addr as *const _ as *const sockaddr_in6))))
23395 -+ }
23396 -+ libc::AF_UNIX => {
23397 -+ let sun = *(addr as *const _ as *const sockaddr_un);
23398 -+ let pathlen = len - offset_of!(sockaddr_un, sun_path);
23399 -+ Ok(SockAddr::Unix(UnixAddr(sun, pathlen)))
23400 -+ }
23401 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
23402 -+ libc::AF_NETLINK => {
23403 -+ use libc::sockaddr_nl;
23404 -+ Ok(SockAddr::Netlink(NetlinkAddr(*(addr as *const _ as *const sockaddr_nl))))
23405 -+ }
23406 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
23407 -+ libc::AF_ALG => {
23408 -+ use libc::sockaddr_alg;
23409 -+ Ok(SockAddr::Alg(AlgAddr(*(addr as *const _ as *const sockaddr_alg))))
23410 -+ }
23411 -+ #[cfg(target_os = "linux")]
23412 -+ libc::AF_VSOCK => {
23413 -+ use libc::sockaddr_vm;
23414 -+ Ok(SockAddr::Vsock(VsockAddr(*(addr as *const _ as *const sockaddr_vm))))
23415 -+ }
23416 -+ af => panic!("unexpected address family {}", af),
23417 -+ }
23418 -+}
23419 -+
23420 -+
23421 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
23422 -+pub enum Shutdown {
23423 -+ /// Further receptions will be disallowed.
23424 -+ Read,
23425 -+ /// Further transmissions will be disallowed.
23426 -+ Write,
23427 -+ /// Further receptions and transmissions will be disallowed.
23428 -+ Both,
23429 -+}
23430 -+
23431 -+/// Shut down part of a full-duplex connection.
23432 -+///
23433 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html)
23434 -+pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> {
23435 -+ unsafe {
23436 -+ use libc::shutdown;
23437 -+
23438 -+ let how = match how {
23439 -+ Shutdown::Read => libc::SHUT_RD,
23440 -+ Shutdown::Write => libc::SHUT_WR,
23441 -+ Shutdown::Both => libc::SHUT_RDWR,
23442 -+ };
23443 -+
23444 -+ Errno::result(shutdown(df, how)).map(drop)
23445 -+ }
23446 -+}
23447 -diff --git a/third_party/rust/nix-0.15.0/src/sys/socket/sockopt.rs b/third_party/rust/nix-0.15.0/src/sys/socket/sockopt.rs
23448 -new file mode 100644
23449 -index 0000000000000..a996010018d5b
23450 ---- /dev/null
23451 -+++ b/third_party/rust/nix-0.15.0/src/sys/socket/sockopt.rs
23452 -@@ -0,0 +1,680 @@
23453 -+use super::{GetSockOpt, SetSockOpt};
23454 -+use Result;
23455 -+use errno::Errno;
23456 -+use sys::time::TimeVal;
23457 -+use libc::{self, c_int, c_void, socklen_t};
23458 -+use std::mem;
23459 -+use std::os::unix::io::RawFd;
23460 -+use std::ffi::{OsStr, OsString};
23461 -+#[cfg(target_family = "unix")]
23462 -+use std::os::unix::ffi::OsStrExt;
23463 -+
23464 -+// Constants
23465 -+// TCP_CA_NAME_MAX isn't defined in user space include files
23466 -+#[cfg(any(target_os = "freebsd", target_os = "linux"))]
23467 -+const TCP_CA_NAME_MAX: usize = 16;
23468 -+
23469 -+/// Helper for implementing `SetSockOpt` for a given socket option. See
23470 -+/// [`::sys::socket::SetSockOpt`](sys/socket/trait.SetSockOpt.html).
23471 -+///
23472 -+/// This macro aims to help implementing `SetSockOpt` for different socket options that accept
23473 -+/// different kinds of data to be used with `setsockopt`.
23474 -+///
23475 -+/// Instead of using this macro directly consider using `sockopt_impl!`, especially if the option
23476 -+/// you are implementing represents a simple type.
23477 -+///
23478 -+/// # Arguments
23479 -+///
23480 -+/// * `$name:ident`: name of the type you want to implement `SetSockOpt` for.
23481 -+/// * `$level:path` : socket layer, or a `protocol level`: could be *raw sockets*
23482 -+/// (`libc::SOL_SOCKET`), *ip protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`),
23483 -+/// and more. Please refer to your system manual for more options. Will be passed as the second
23484 -+/// argument (`level`) to the `setsockopt` call.
23485 -+/// * `$flag:path`: a flag name to set. Some examples: `libc::SO_REUSEADDR`, `libc::TCP_NODELAY`,
23486 -+/// `libc::IP_ADD_MEMBERSHIP` and others. Will be passed as the third argument (`option_name`)
23487 -+/// to the `setsockopt` call.
23488 -+/// * Type of the value that you are going to set.
23489 -+/// * Type that implements the `Set` trait for the type from the previous item (like `SetBool` for
23490 -+/// `bool`, `SetUsize` for `usize`, etc.).
23491 -+macro_rules! setsockopt_impl {
23492 -+ ($name:ident, $level:path, $flag:path, $ty:ty, $setter:ty) => {
23493 -+ impl SetSockOpt for $name {
23494 -+ type Val = $ty;
23495 -+
23496 -+ fn set(&self, fd: RawFd, val: &$ty) -> Result<()> {
23497 -+ unsafe {
23498 -+ let setter: $setter = Set::new(val);
23499 -+
23500 -+ let res = libc::setsockopt(fd, $level, $flag,
23501 -+ setter.ffi_ptr(),
23502 -+ setter.ffi_len());
23503 -+ Errno::result(res).map(drop)
23504 -+ }
23505 -+ }
23506 -+ }
23507 -+ }
23508 -+}
23509 -+
23510 -+/// Helper for implementing `GetSockOpt` for a given socket option. See
23511 -+/// [`::sys::socket::GetSockOpt`](sys/socket/trait.GetSockOpt.html).
23512 -+///
23513 -+/// This macro aims to help implementing `GetSockOpt` for different socket options that accept
23514 -+/// different kinds of data to be use with `getsockopt`.
23515 -+///
23516 -+/// Instead of using this macro directly consider using `sockopt_impl!`, especially if the option
23517 -+/// you are implementing represents a simple type.
23518 -+///
23519 -+/// # Arguments
23520 -+///
23521 -+/// * Name of the type you want to implement `GetSockOpt` for.
23522 -+/// * Socket layer, or a `protocol level`: could be *raw sockets* (`lic::SOL_SOCKET`), *ip
23523 -+/// protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`), and more. Please refer
23524 -+/// to your system manual for more options. Will be passed as the second argument (`level`) to
23525 -+/// the `getsockopt` call.
23526 -+/// * A flag to set. Some examples: `libc::SO_REUSEADDR`, `libc::TCP_NODELAY`,
23527 -+/// `libc::SO_ORIGINAL_DST` and others. Will be passed as the third argument (`option_name`) to
23528 -+/// the `getsockopt` call.
23529 -+/// * Type of the value that you are going to get.
23530 -+/// * Type that implements the `Get` trait for the type from the previous item (`GetBool` for
23531 -+/// `bool`, `GetUsize` for `usize`, etc.).
23532 -+macro_rules! getsockopt_impl {
23533 -+ ($name:ident, $level:path, $flag:path, $ty:ty, $getter:ty) => {
23534 -+ impl GetSockOpt for $name {
23535 -+ type Val = $ty;
23536 -+
23537 -+ fn get(&self, fd: RawFd) -> Result<$ty> {
23538 -+ unsafe {
23539 -+ let mut getter: $getter = Get::blank();
23540 -+
23541 -+ let res = libc::getsockopt(fd, $level, $flag,
23542 -+ getter.ffi_ptr(),
23543 -+ getter.ffi_len());
23544 -+ Errno::result(res)?;
23545 -+
23546 -+ Ok(getter.unwrap())
23547 -+ }
23548 -+ }
23549 -+ }
23550 -+ }
23551 -+}
23552 -+
23553 -+/// Helper to generate the sockopt accessors. See
23554 -+/// [`::sys::socket::GetSockOpt`](sys/socket/trait.GetSockOpt.html) and
23555 -+/// [`::sys::socket::SetSockOpt`](sys/socket/trait.SetSockOpt.html).
23556 -+///
23557 -+/// This macro aims to help implementing `GetSockOpt` and `SetSockOpt` for different socket options
23558 -+/// that accept different kinds of data to be use with `getsockopt` and `setsockopt` respectively.
23559 -+///
23560 -+/// Basically this macro wraps up the [`getsockopt_impl!`](macro.getsockopt_impl.html) and
23561 -+/// [`setsockopt_impl!`](macro.setsockopt_impl.html) macros.
23562 -+///
23563 -+/// # Arguments
23564 -+///
23565 -+/// * `GetOnly`, `SetOnly` or `Both`: whether you want to implement only getter, only setter or
23566 -+/// both of them.
23567 -+/// * `$name:ident`: name of type `GetSockOpt`/`SetSockOpt` will be implemented for.
23568 -+/// * `$level:path` : socket layer, or a `protocol level`: could be *raw sockets*
23569 -+/// (`lic::SOL_SOCKET`), *ip protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`),
23570 -+/// and more. Please refer to your system manual for more options. Will be passed as the second
23571 -+/// argument (`level`) to the `getsockopt`/`setsockopt` call.
23572 -+/// * `$flag:path`: a flag name to set. Some examples: `libc::SO_REUSEADDR`, `libc::TCP_NODELAY`,
23573 -+/// `libc::IP_ADD_MEMBERSHIP` and others. Will be passed as the third argument (`option_name`)
23574 -+/// to the `setsockopt`/`getsockopt` call.
23575 -+/// * `$ty:ty`: type of the value that will be get/set.
23576 -+/// * `$getter:ty`: `Get` implementation; optional; only for `GetOnly` and `Both`.
23577 -+/// * `$setter:ty`: `Set` implementation; optional; only for `SetOnly` and `Both`.
23578 -+macro_rules! sockopt_impl {
23579 -+ (GetOnly, $name:ident, $level:path, $flag:path, bool) => {
23580 -+ sockopt_impl!(GetOnly, $name, $level, $flag, bool, GetBool);
23581 -+ };
23582 -+
23583 -+ (GetOnly, $name:ident, $level:path, $flag:path, u8) => {
23584 -+ sockopt_impl!(GetOnly, $name, $level, $flag, u8, GetU8);
23585 -+ };
23586 -+
23587 -+ (GetOnly, $name:ident, $level:path, $flag:path, usize) => {
23588 -+ sockopt_impl!(GetOnly, $name, $level, $flag, usize, GetUsize);
23589 -+ };
23590 -+
23591 -+ (SetOnly, $name:ident, $level:path, $flag:path, bool) => {
23592 -+ sockopt_impl!(SetOnly, $name, $level, $flag, bool, SetBool);
23593 -+ };
23594 -+
23595 -+ (SetOnly, $name:ident, $level:path, $flag:path, u8) => {
23596 -+ sockopt_impl!(SetOnly, $name, $level, $flag, u8, SetU8);
23597 -+ };
23598 -+
23599 -+ (SetOnly, $name:ident, $level:path, $flag:path, usize) => {
23600 -+ sockopt_impl!(SetOnly, $name, $level, $flag, usize, SetUsize);
23601 -+ };
23602 -+
23603 -+ (Both, $name:ident, $level:path, $flag:path, bool) => {
23604 -+ sockopt_impl!(Both, $name, $level, $flag, bool, GetBool, SetBool);
23605 -+ };
23606 -+
23607 -+ (Both, $name:ident, $level:path, $flag:path, u8) => {
23608 -+ sockopt_impl!(Both, $name, $level, $flag, u8, GetU8, SetU8);
23609 -+ };
23610 -+
23611 -+ (Both, $name:ident, $level:path, $flag:path, usize) => {
23612 -+ sockopt_impl!(Both, $name, $level, $flag, usize, GetUsize, SetUsize);
23613 -+ };
23614 -+
23615 -+ (Both, $name:ident, $level:path, $flag:path, OsString<$array:ty>) => {
23616 -+ sockopt_impl!(Both, $name, $level, $flag, OsString, GetOsString<$array>, SetOsString);
23617 -+ };
23618 -+
23619 -+ /*
23620 -+ * Matchers with generic getter types must be placed at the end, so
23621 -+ * they'll only match _after_ specialized matchers fail
23622 -+ */
23623 -+ (GetOnly, $name:ident, $level:path, $flag:path, $ty:ty) => {
23624 -+ sockopt_impl!(GetOnly, $name, $level, $flag, $ty, GetStruct<$ty>);
23625 -+ };
23626 -+
23627 -+ (GetOnly, $name:ident, $level:path, $flag:path, $ty:ty, $getter:ty) => {
23628 -+ #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
23629 -+ pub struct $name;
23630 -+
23631 -+ getsockopt_impl!($name, $level, $flag, $ty, $getter);
23632 -+ };
23633 -+
23634 -+ (SetOnly, $name:ident, $level:path, $flag:path, $ty:ty) => {
23635 -+ sockopt_impl!(SetOnly, $name, $level, $flag, $ty, SetStruct<$ty>);
23636 -+ };
23637 -+
23638 -+ (SetOnly, $name:ident, $level:path, $flag:path, $ty:ty, $setter:ty) => {
23639 -+ #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
23640 -+ pub struct $name;
23641 -+
23642 -+ setsockopt_impl!($name, $level, $flag, $ty, $setter);
23643 -+ };
23644 -+
23645 -+ (Both, $name:ident, $level:path, $flag:path, $ty:ty, $getter:ty, $setter:ty) => {
23646 -+ #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
23647 -+ pub struct $name;
23648 -+
23649 -+ setsockopt_impl!($name, $level, $flag, $ty, $setter);
23650 -+ getsockopt_impl!($name, $level, $flag, $ty, $getter);
23651 -+ };
23652 -+
23653 -+ (Both, $name:ident, $level:path, $flag:path, $ty:ty) => {
23654 -+ sockopt_impl!(Both, $name, $level, $flag, $ty, GetStruct<$ty>, SetStruct<$ty>);
23655 -+ };
23656 -+}
23657 -+
23658 -+/*
23659 -+ *
23660 -+ * ===== Define sockopts =====
23661 -+ *
23662 -+ */
23663 -+
23664 -+sockopt_impl!(Both, ReuseAddr, libc::SOL_SOCKET, libc::SO_REUSEADDR, bool);
23665 -+sockopt_impl!(Both, ReusePort, libc::SOL_SOCKET, libc::SO_REUSEPORT, bool);
23666 -+sockopt_impl!(Both, TcpNoDelay, libc::IPPROTO_TCP, libc::TCP_NODELAY, bool);
23667 -+sockopt_impl!(Both, Linger, libc::SOL_SOCKET, libc::SO_LINGER, libc::linger);
23668 -+sockopt_impl!(SetOnly, IpAddMembership, libc::IPPROTO_IP, libc::IP_ADD_MEMBERSHIP, super::IpMembershipRequest);
23669 -+sockopt_impl!(SetOnly, IpDropMembership, libc::IPPROTO_IP, libc::IP_DROP_MEMBERSHIP, super::IpMembershipRequest);
23670 -+cfg_if! {
23671 -+ if #[cfg(any(target_os = "android", target_os = "linux"))] {
23672 -+ sockopt_impl!(SetOnly, Ipv6AddMembership, libc::IPPROTO_IPV6, libc::IPV6_ADD_MEMBERSHIP, super::Ipv6MembershipRequest);
23673 -+ sockopt_impl!(SetOnly, Ipv6DropMembership, libc::IPPROTO_IPV6, libc::IPV6_DROP_MEMBERSHIP, super::Ipv6MembershipRequest);
23674 -+ } else if #[cfg(any(target_os = "dragonfly",
23675 -+ target_os = "freebsd",
23676 -+ target_os = "ios",
23677 -+ target_os = "macos",
23678 -+ target_os = "netbsd",
23679 -+ target_os = "openbsd"))] {
23680 -+ sockopt_impl!(SetOnly, Ipv6AddMembership, libc::IPPROTO_IPV6, libc::IPV6_JOIN_GROUP, super::Ipv6MembershipRequest);
23681 -+ sockopt_impl!(SetOnly, Ipv6DropMembership, libc::IPPROTO_IPV6, libc::IPV6_LEAVE_GROUP, super::Ipv6MembershipRequest);
23682 -+ }
23683 -+}
23684 -+sockopt_impl!(Both, IpMulticastTtl, libc::IPPROTO_IP, libc::IP_MULTICAST_TTL, u8);
23685 -+sockopt_impl!(Both, IpMulticastLoop, libc::IPPROTO_IP, libc::IP_MULTICAST_LOOP, bool);
23686 -+sockopt_impl!(Both, ReceiveTimeout, libc::SOL_SOCKET, libc::SO_RCVTIMEO, TimeVal);
23687 -+sockopt_impl!(Both, SendTimeout, libc::SOL_SOCKET, libc::SO_SNDTIMEO, TimeVal);
23688 -+sockopt_impl!(Both, Broadcast, libc::SOL_SOCKET, libc::SO_BROADCAST, bool);
23689 -+sockopt_impl!(Both, OobInline, libc::SOL_SOCKET, libc::SO_OOBINLINE, bool);
23690 -+sockopt_impl!(GetOnly, SocketError, libc::SOL_SOCKET, libc::SO_ERROR, i32);
23691 -+sockopt_impl!(Both, KeepAlive, libc::SOL_SOCKET, libc::SO_KEEPALIVE, bool);
23692 -+#[cfg(any(target_os = "android", target_os = "linux"))]
23693 -+sockopt_impl!(GetOnly, PeerCredentials, libc::SOL_SOCKET, libc::SO_PEERCRED, super::UnixCredentials);
23694 -+#[cfg(any(target_os = "ios",
23695 -+ target_os = "macos"))]
23696 -+sockopt_impl!(Both, TcpKeepAlive, libc::IPPROTO_TCP, libc::TCP_KEEPALIVE, u32);
23697 -+#[cfg(any(target_os = "android",
23698 -+ target_os = "dragonfly",
23699 -+ target_os = "freebsd",
23700 -+ target_os = "linux",
23701 -+ target_os = "nacl"))]
23702 -+sockopt_impl!(Both, TcpKeepIdle, libc::IPPROTO_TCP, libc::TCP_KEEPIDLE, u32);
23703 -+sockopt_impl!(Both, RcvBuf, libc::SOL_SOCKET, libc::SO_RCVBUF, usize);
23704 -+sockopt_impl!(Both, SndBuf, libc::SOL_SOCKET, libc::SO_SNDBUF, usize);
23705 -+#[cfg(any(target_os = "android", target_os = "linux"))]
23706 -+sockopt_impl!(SetOnly, RcvBufForce, libc::SOL_SOCKET, libc::SO_RCVBUFFORCE, usize);
23707 -+#[cfg(any(target_os = "android", target_os = "linux"))]
23708 -+sockopt_impl!(SetOnly, SndBufForce, libc::SOL_SOCKET, libc::SO_SNDBUFFORCE, usize);
23709 -+sockopt_impl!(GetOnly, SockType, libc::SOL_SOCKET, libc::SO_TYPE, super::SockType);
23710 -+sockopt_impl!(GetOnly, AcceptConn, libc::SOL_SOCKET, libc::SO_ACCEPTCONN, bool);
23711 -+#[cfg(any(target_os = "android", target_os = "linux"))]
23712 -+sockopt_impl!(GetOnly, OriginalDst, libc::SOL_IP, libc::SO_ORIGINAL_DST, libc::sockaddr_in);
23713 -+sockopt_impl!(Both, ReceiveTimestamp, libc::SOL_SOCKET, libc::SO_TIMESTAMP, bool);
23714 -+#[cfg(any(target_os = "android", target_os = "linux"))]
23715 -+sockopt_impl!(Both, IpTransparent, libc::SOL_IP, libc::IP_TRANSPARENT, bool);
23716 -+#[cfg(target_os = "openbsd")]
23717 -+sockopt_impl!(Both, BindAny, libc::SOL_SOCKET, libc::SO_BINDANY, bool);
23718 -+#[cfg(target_os = "freebsd")]
23719 -+sockopt_impl!(Both, BindAny, libc::IPPROTO_IP, libc::IP_BINDANY, bool);
23720 -+#[cfg(target_os = "linux")]
23721 -+sockopt_impl!(Both, Mark, libc::SOL_SOCKET, libc::SO_MARK, u32);
23722 -+#[cfg(any(target_os = "android", target_os = "linux"))]
23723 -+sockopt_impl!(Both, PassCred, libc::SOL_SOCKET, libc::SO_PASSCRED, bool);
23724 -+#[cfg(any(target_os = "freebsd", target_os = "linux"))]
23725 -+sockopt_impl!(Both, TcpCongestion, libc::IPPROTO_TCP, libc::TCP_CONGESTION, OsString<[u8; TCP_CA_NAME_MAX]>);
23726 -+#[cfg(any(
23727 -+ target_os = "android",
23728 -+ target_os = "ios",
23729 -+ target_os = "linux",
23730 -+ target_os = "macos",
23731 -+ target_os = "netbsd",
23732 -+))]
23733 -+sockopt_impl!(Both, Ipv4PacketInfo, libc::IPPROTO_IP, libc::IP_PKTINFO, bool);
23734 -+#[cfg(any(
23735 -+ target_os = "android",
23736 -+ target_os = "freebsd",
23737 -+ target_os = "ios",
23738 -+ target_os = "linux",
23739 -+ target_os = "macos",
23740 -+ target_os = "netbsd",
23741 -+ target_os = "openbsd",
23742 -+))]
23743 -+sockopt_impl!(Both, Ipv6RecvPacketInfo, libc::IPPROTO_IPV6, libc::IPV6_RECVPKTINFO, bool);
23744 -+#[cfg(any(
23745 -+ target_os = "freebsd",
23746 -+ target_os = "ios",
23747 -+ target_os = "macos",
23748 -+ target_os = "netbsd",
23749 -+ target_os = "openbsd",
23750 -+))]
23751 -+sockopt_impl!(Both, Ipv4RecvIf, libc::IPPROTO_IP, libc::IP_RECVIF, bool);
23752 -+#[cfg(any(
23753 -+ target_os = "freebsd",
23754 -+ target_os = "ios",
23755 -+ target_os = "macos",
23756 -+ target_os = "netbsd",
23757 -+ target_os = "openbsd",
23758 -+))]
23759 -+sockopt_impl!(Both, Ipv4RecvDstAddr, libc::IPPROTO_IP, libc::IP_RECVDSTADDR, bool);
23760 -+
23761 -+
23762 -+#[cfg(any(target_os = "android", target_os = "linux"))]
23763 -+#[derive(Copy, Clone, Debug)]
23764 -+pub struct AlgSetAeadAuthSize;
23765 -+
23766 -+// ALG_SET_AEAD_AUTH_SIZE read the length from passed `option_len`
23767 -+// See https://elixir.bootlin.com/linux/v4.4/source/crypto/af_alg.c#L222
23768 -+#[cfg(any(target_os = "android", target_os = "linux"))]
23769 -+impl SetSockOpt for AlgSetAeadAuthSize {
23770 -+ type Val = usize;
23771 -+
23772 -+ fn set(&self, fd: RawFd, val: &usize) -> Result<()> {
23773 -+ unsafe {
23774 -+ let res = libc::setsockopt(fd,
23775 -+ libc::SOL_ALG,
23776 -+ libc::ALG_SET_AEAD_AUTHSIZE,
23777 -+ ::std::ptr::null(),
23778 -+ *val as libc::socklen_t);
23779 -+ Errno::result(res).map(drop)
23780 -+ }
23781 -+ }
23782 -+}
23783 -+
23784 -+#[cfg(any(target_os = "android", target_os = "linux"))]
23785 -+#[derive(Clone, Debug)]
23786 -+pub struct AlgSetKey<T>(::std::marker::PhantomData<T>);
23787 -+
23788 -+#[cfg(any(target_os = "android", target_os = "linux"))]
23789 -+impl<T> Default for AlgSetKey<T> {
23790 -+ fn default() -> Self {
23791 -+ AlgSetKey(Default::default())
23792 -+ }
23793 -+}
23794 -+
23795 -+#[cfg(any(target_os = "android", target_os = "linux"))]
23796 -+impl<T> SetSockOpt for AlgSetKey<T> where T: AsRef<[u8]> + Clone {
23797 -+ type Val = T;
23798 -+
23799 -+ fn set(&self, fd: RawFd, val: &T) -> Result<()> {
23800 -+ unsafe {
23801 -+ let res = libc::setsockopt(fd,
23802 -+ libc::SOL_ALG,
23803 -+ libc::ALG_SET_KEY,
23804 -+ val.as_ref().as_ptr() as *const _,
23805 -+ val.as_ref().len() as libc::socklen_t);
23806 -+ Errno::result(res).map(drop)
23807 -+ }
23808 -+ }
23809 -+}
23810 -+
23811 -+/*
23812 -+ *
23813 -+ * ===== Accessor helpers =====
23814 -+ *
23815 -+ */
23816 -+
23817 -+/// Helper trait that describes what is expected from a `GetSockOpt` getter.
23818 -+unsafe trait Get<T> {
23819 -+ /// Returns an empty value.
23820 -+ unsafe fn blank() -> Self;
23821 -+ /// Returns a pointer to the stored value. This pointer will be passed to the system's
23822 -+ /// `getsockopt` call (`man 3p getsockopt`, argument `option_value`).
23823 -+ fn ffi_ptr(&mut self) -> *mut c_void;
23824 -+ /// Returns length of the stored value. This pointer will be passed to the system's
23825 -+ /// `getsockopt` call (`man 3p getsockopt`, argument `option_len`).
23826 -+ fn ffi_len(&mut self) -> *mut socklen_t;
23827 -+ /// Returns the stored value.
23828 -+ unsafe fn unwrap(self) -> T;
23829 -+}
23830 -+
23831 -+/// Helper trait that describes what is expected from a `SetSockOpt` setter.
23832 -+unsafe trait Set<'a, T> {
23833 -+ /// Initialize the setter with a given value.
23834 -+ fn new(val: &'a T) -> Self;
23835 -+ /// Returns a pointer to the stored value. This pointer will be passed to the system's
23836 -+ /// `setsockopt` call (`man 3p setsockopt`, argument `option_value`).
23837 -+ fn ffi_ptr(&self) -> *const c_void;
23838 -+ /// Returns length of the stored value. This pointer will be passed to the system's
23839 -+ /// `setsockopt` call (`man 3p setsockopt`, argument `option_len`).
23840 -+ fn ffi_len(&self) -> socklen_t;
23841 -+}
23842 -+
23843 -+/// Getter for an arbitrary `struct`.
23844 -+struct GetStruct<T> {
23845 -+ len: socklen_t,
23846 -+ val: T,
23847 -+}
23848 -+
23849 -+unsafe impl<T> Get<T> for GetStruct<T> {
23850 -+ unsafe fn blank() -> Self {
23851 -+ GetStruct {
23852 -+ len: mem::size_of::<T>() as socklen_t,
23853 -+ val: mem::zeroed(),
23854 -+ }
23855 -+ }
23856 -+
23857 -+ fn ffi_ptr(&mut self) -> *mut c_void {
23858 -+ &mut self.val as *mut T as *mut c_void
23859 -+ }
23860 -+
23861 -+ fn ffi_len(&mut self) -> *mut socklen_t {
23862 -+ &mut self.len
23863 -+ }
23864 -+
23865 -+ unsafe fn unwrap(self) -> T {
23866 -+ assert!(self.len as usize == mem::size_of::<T>(), "invalid getsockopt implementation");
23867 -+ self.val
23868 -+ }
23869 -+}
23870 -+
23871 -+/// Setter for an arbitrary `struct`.
23872 -+struct SetStruct<'a, T: 'static> {
23873 -+ ptr: &'a T,
23874 -+}
23875 -+
23876 -+unsafe impl<'a, T> Set<'a, T> for SetStruct<'a, T> {
23877 -+ fn new(ptr: &'a T) -> SetStruct<'a, T> {
23878 -+ SetStruct { ptr: ptr }
23879 -+ }
23880 -+
23881 -+ fn ffi_ptr(&self) -> *const c_void {
23882 -+ self.ptr as *const T as *const c_void
23883 -+ }
23884 -+
23885 -+ fn ffi_len(&self) -> socklen_t {
23886 -+ mem::size_of::<T>() as socklen_t
23887 -+ }
23888 -+}
23889 -+
23890 -+/// Getter for a boolean value.
23891 -+struct GetBool {
23892 -+ len: socklen_t,
23893 -+ val: c_int,
23894 -+}
23895 -+
23896 -+unsafe impl Get<bool> for GetBool {
23897 -+ unsafe fn blank() -> Self {
23898 -+ GetBool {
23899 -+ len: mem::size_of::<c_int>() as socklen_t,
23900 -+ val: mem::zeroed(),
23901 -+ }
23902 -+ }
23903 -+
23904 -+ fn ffi_ptr(&mut self) -> *mut c_void {
23905 -+ &mut self.val as *mut c_int as *mut c_void
23906 -+ }
23907 -+
23908 -+ fn ffi_len(&mut self) -> *mut socklen_t {
23909 -+ &mut self.len
23910 -+ }
23911 -+
23912 -+ unsafe fn unwrap(self) -> bool {
23913 -+ assert!(self.len as usize == mem::size_of::<c_int>(), "invalid getsockopt implementation");
23914 -+ self.val != 0
23915 -+ }
23916 -+}
23917 -+
23918 -+/// Setter for a boolean value.
23919 -+struct SetBool {
23920 -+ val: c_int,
23921 -+}
23922 -+
23923 -+unsafe impl<'a> Set<'a, bool> for SetBool {
23924 -+ fn new(val: &'a bool) -> SetBool {
23925 -+ SetBool { val: if *val { 1 } else { 0 } }
23926 -+ }
23927 -+
23928 -+ fn ffi_ptr(&self) -> *const c_void {
23929 -+ &self.val as *const c_int as *const c_void
23930 -+ }
23931 -+
23932 -+ fn ffi_len(&self) -> socklen_t {
23933 -+ mem::size_of::<c_int>() as socklen_t
23934 -+ }
23935 -+}
23936 -+
23937 -+/// Getter for an `u8` value.
23938 -+struct GetU8 {
23939 -+ len: socklen_t,
23940 -+ val: u8,
23941 -+}
23942 -+
23943 -+unsafe impl Get<u8> for GetU8 {
23944 -+ unsafe fn blank() -> Self {
23945 -+ GetU8 {
23946 -+ len: mem::size_of::<u8>() as socklen_t,
23947 -+ val: mem::zeroed(),
23948 -+ }
23949 -+ }
23950 -+
23951 -+ fn ffi_ptr(&mut self) -> *mut c_void {
23952 -+ &mut self.val as *mut u8 as *mut c_void
23953 -+ }
23954 -+
23955 -+ fn ffi_len(&mut self) -> *mut socklen_t {
23956 -+ &mut self.len
23957 -+ }
23958 -+
23959 -+ unsafe fn unwrap(self) -> u8 {
23960 -+ assert!(self.len as usize == mem::size_of::<u8>(), "invalid getsockopt implementation");
23961 -+ self.val as u8
23962 -+ }
23963 -+}
23964 -+
23965 -+/// Setter for an `u8` value.
23966 -+struct SetU8 {
23967 -+ val: u8,
23968 -+}
23969 -+
23970 -+unsafe impl<'a> Set<'a, u8> for SetU8 {
23971 -+ fn new(val: &'a u8) -> SetU8 {
23972 -+ SetU8 { val: *val as u8 }
23973 -+ }
23974 -+
23975 -+ fn ffi_ptr(&self) -> *const c_void {
23976 -+ &self.val as *const u8 as *const c_void
23977 -+ }
23978 -+
23979 -+ fn ffi_len(&self) -> socklen_t {
23980 -+ mem::size_of::<c_int>() as socklen_t
23981 -+ }
23982 -+}
23983 -+
23984 -+/// Getter for an `usize` value.
23985 -+struct GetUsize {
23986 -+ len: socklen_t,
23987 -+ val: c_int,
23988 -+}
23989 -+
23990 -+unsafe impl Get<usize> for GetUsize {
23991 -+ unsafe fn blank() -> Self {
23992 -+ GetUsize {
23993 -+ len: mem::size_of::<c_int>() as socklen_t,
23994 -+ val: mem::zeroed(),
23995 -+ }
23996 -+ }
23997 -+
23998 -+ fn ffi_ptr(&mut self) -> *mut c_void {
23999 -+ &mut self.val as *mut c_int as *mut c_void
24000 -+ }
24001 -+
24002 -+ fn ffi_len(&mut self) -> *mut socklen_t {
24003 -+ &mut self.len
24004 -+ }
24005 -+
24006 -+ unsafe fn unwrap(self) -> usize {
24007 -+ assert!(self.len as usize == mem::size_of::<c_int>(), "invalid getsockopt implementation");
24008 -+ self.val as usize
24009 -+ }
24010 -+}
24011 -+
24012 -+/// Setter for an `usize` value.
24013 -+struct SetUsize {
24014 -+ val: c_int,
24015 -+}
24016 -+
24017 -+unsafe impl<'a> Set<'a, usize> for SetUsize {
24018 -+ fn new(val: &'a usize) -> SetUsize {
24019 -+ SetUsize { val: *val as c_int }
24020 -+ }
24021 -+
24022 -+ fn ffi_ptr(&self) -> *const c_void {
24023 -+ &self.val as *const c_int as *const c_void
24024 -+ }
24025 -+
24026 -+ fn ffi_len(&self) -> socklen_t {
24027 -+ mem::size_of::<c_int>() as socklen_t
24028 -+ }
24029 -+}
24030 -+
24031 -+/// Getter for a `OsString` value.
24032 -+struct GetOsString<T: AsMut<[u8]>> {
24033 -+ len: socklen_t,
24034 -+ val: T,
24035 -+}
24036 -+
24037 -+unsafe impl<T: AsMut<[u8]>> Get<OsString> for GetOsString<T> {
24038 -+ unsafe fn blank() -> Self {
24039 -+ GetOsString {
24040 -+ len: mem::size_of::<T>() as socklen_t,
24041 -+ val: mem::zeroed(),
24042 -+ }
24043 -+ }
24044 -+
24045 -+ fn ffi_ptr(&mut self) -> *mut c_void {
24046 -+ &mut self.val as *mut T as *mut c_void
24047 -+ }
24048 -+
24049 -+ fn ffi_len(&mut self) -> *mut socklen_t {
24050 -+ &mut self.len
24051 -+ }
24052 -+
24053 -+ unsafe fn unwrap(mut self) -> OsString {
24054 -+ OsStr::from_bytes(self.val.as_mut()).to_owned()
24055 -+ }
24056 -+}
24057 -+
24058 -+/// Setter for a `OsString` value.
24059 -+struct SetOsString<'a> {
24060 -+ val: &'a OsStr,
24061 -+}
24062 -+
24063 -+unsafe impl<'a> Set<'a, OsString> for SetOsString<'a> {
24064 -+ fn new(val: &'a OsString) -> SetOsString {
24065 -+ SetOsString { val: val.as_os_str() }
24066 -+ }
24067 -+
24068 -+ fn ffi_ptr(&self) -> *const c_void {
24069 -+ self.val.as_bytes().as_ptr() as *const c_void
24070 -+ }
24071 -+
24072 -+ fn ffi_len(&self) -> socklen_t {
24073 -+ self.val.len() as socklen_t
24074 -+ }
24075 -+}
24076 -+
24077 -+
24078 -+#[cfg(test)]
24079 -+mod test {
24080 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
24081 -+ #[test]
24082 -+ fn can_get_peercred_on_unix_socket() {
24083 -+ use super::super::*;
24084 -+
24085 -+ let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap();
24086 -+ let a_cred = getsockopt(a, super::PeerCredentials).unwrap();
24087 -+ let b_cred = getsockopt(b, super::PeerCredentials).unwrap();
24088 -+ assert_eq!(a_cred, b_cred);
24089 -+ assert!(a_cred.pid() != 0);
24090 -+ }
24091 -+
24092 -+ #[test]
24093 -+ fn is_socket_type_unix() {
24094 -+ use super::super::*;
24095 -+ use ::unistd::close;
24096 -+
24097 -+ let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap();
24098 -+ let a_type = getsockopt(a, super::SockType).unwrap();
24099 -+ assert!(a_type == SockType::Stream);
24100 -+ close(a).unwrap();
24101 -+ close(b).unwrap();
24102 -+ }
24103 -+
24104 -+ #[test]
24105 -+ fn is_socket_type_dgram() {
24106 -+ use super::super::*;
24107 -+ use ::unistd::close;
24108 -+
24109 -+ let s = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), None).unwrap();
24110 -+ let s_type = getsockopt(s, super::SockType).unwrap();
24111 -+ assert!(s_type == SockType::Datagram);
24112 -+ close(s).unwrap();
24113 -+ }
24114 -+
24115 -+ #[cfg(any(target_os = "freebsd",
24116 -+ target_os = "linux",
24117 -+ target_os = "nacl"))]
24118 -+ #[test]
24119 -+ fn can_get_listen_on_tcp_socket() {
24120 -+ use super::super::*;
24121 -+ use ::unistd::close;
24122 -+
24123 -+ let s = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), None).unwrap();
24124 -+ let s_listening = getsockopt(s, super::AcceptConn).unwrap();
24125 -+ assert!(!s_listening);
24126 -+ listen(s, 10).unwrap();
24127 -+ let s_listening2 = getsockopt(s, super::AcceptConn).unwrap();
24128 -+ assert!(s_listening2);
24129 -+ close(s).unwrap();
24130 -+ }
24131 -+
24132 -+}
24133 -diff --git a/third_party/rust/nix-0.15.0/src/sys/stat.rs b/third_party/rust/nix-0.15.0/src/sys/stat.rs
24134 -new file mode 100644
24135 -index 0000000000000..66c8c9dd1b720
24136 ---- /dev/null
24137 -+++ b/third_party/rust/nix-0.15.0/src/sys/stat.rs
24138 -@@ -0,0 +1,294 @@
24139 -+pub use libc::{dev_t, mode_t};
24140 -+pub use libc::stat as FileStat;
24141 -+
24142 -+use {Result, NixPath};
24143 -+use errno::Errno;
24144 -+use fcntl::{AtFlags, at_rawfd};
24145 -+use libc;
24146 -+use std::mem;
24147 -+use std::os::unix::io::RawFd;
24148 -+use sys::time::{TimeSpec, TimeVal};
24149 -+
24150 -+libc_bitflags!(
24151 -+ pub struct SFlag: mode_t {
24152 -+ S_IFIFO;
24153 -+ S_IFCHR;
24154 -+ S_IFDIR;
24155 -+ S_IFBLK;
24156 -+ S_IFREG;
24157 -+ S_IFLNK;
24158 -+ S_IFSOCK;
24159 -+ S_IFMT;
24160 -+ }
24161 -+);
24162 -+
24163 -+libc_bitflags! {
24164 -+ pub struct Mode: mode_t {
24165 -+ S_IRWXU;
24166 -+ S_IRUSR;
24167 -+ S_IWUSR;
24168 -+ S_IXUSR;
24169 -+ S_IRWXG;
24170 -+ S_IRGRP;
24171 -+ S_IWGRP;
24172 -+ S_IXGRP;
24173 -+ S_IRWXO;
24174 -+ S_IROTH;
24175 -+ S_IWOTH;
24176 -+ S_IXOTH;
24177 -+ S_ISUID as mode_t;
24178 -+ S_ISGID as mode_t;
24179 -+ S_ISVTX as mode_t;
24180 -+ }
24181 -+}
24182 -+
24183 -+pub fn mknod<P: ?Sized + NixPath>(path: &P, kind: SFlag, perm: Mode, dev: dev_t) -> Result<()> {
24184 -+ let res = path.with_nix_path(|cstr| {
24185 -+ unsafe {
24186 -+ libc::mknod(cstr.as_ptr(), kind.bits | perm.bits() as mode_t, dev)
24187 -+ }
24188 -+ })?;
24189 -+
24190 -+ Errno::result(res).map(drop)
24191 -+}
24192 -+
24193 -+#[cfg(target_os = "linux")]
24194 -+pub fn major(dev: dev_t) -> u64 {
24195 -+ ((dev >> 32) & 0xffff_f000) |
24196 -+ ((dev >> 8) & 0x0000_0fff)
24197 -+}
24198 -+
24199 -+#[cfg(target_os = "linux")]
24200 -+pub fn minor(dev: dev_t) -> u64 {
24201 -+ ((dev >> 12) & 0xffff_ff00) |
24202 -+ ((dev ) & 0x0000_00ff)
24203 -+}
24204 -+
24205 -+#[cfg(target_os = "linux")]
24206 -+pub fn makedev(major: u64, minor: u64) -> dev_t {
24207 -+ ((major & 0xffff_f000) << 32) |
24208 -+ ((major & 0x0000_0fff) << 8) |
24209 -+ ((minor & 0xffff_ff00) << 12) |
24210 -+ (minor & 0x0000_00ff)
24211 -+}
24212 -+
24213 -+pub fn umask(mode: Mode) -> Mode {
24214 -+ let prev = unsafe { libc::umask(mode.bits() as mode_t) };
24215 -+ Mode::from_bits(prev).expect("[BUG] umask returned invalid Mode")
24216 -+}
24217 -+
24218 -+pub fn stat<P: ?Sized + NixPath>(path: &P) -> Result<FileStat> {
24219 -+ let mut dst = unsafe { mem::uninitialized() };
24220 -+ let res = path.with_nix_path(|cstr| {
24221 -+ unsafe {
24222 -+ libc::stat(cstr.as_ptr(), &mut dst as *mut FileStat)
24223 -+ }
24224 -+ })?;
24225 -+
24226 -+ Errno::result(res)?;
24227 -+
24228 -+ Ok(dst)
24229 -+}
24230 -+
24231 -+pub fn lstat<P: ?Sized + NixPath>(path: &P) -> Result<FileStat> {
24232 -+ let mut dst = unsafe { mem::uninitialized() };
24233 -+ let res = path.with_nix_path(|cstr| {
24234 -+ unsafe {
24235 -+ libc::lstat(cstr.as_ptr(), &mut dst as *mut FileStat)
24236 -+ }
24237 -+ })?;
24238 -+
24239 -+ Errno::result(res)?;
24240 -+
24241 -+ Ok(dst)
24242 -+}
24243 -+
24244 -+pub fn fstat(fd: RawFd) -> Result<FileStat> {
24245 -+ let mut dst = unsafe { mem::uninitialized() };
24246 -+ let res = unsafe { libc::fstat(fd, &mut dst as *mut FileStat) };
24247 -+
24248 -+ Errno::result(res)?;
24249 -+
24250 -+ Ok(dst)
24251 -+}
24252 -+
24253 -+pub fn fstatat<P: ?Sized + NixPath>(dirfd: RawFd, pathname: &P, f: AtFlags) -> Result<FileStat> {
24254 -+ let mut dst = unsafe { mem::uninitialized() };
24255 -+ let res = pathname.with_nix_path(|cstr| {
24256 -+ unsafe { libc::fstatat(dirfd, cstr.as_ptr(), &mut dst as *mut FileStat, f.bits() as libc::c_int) }
24257 -+ })?;
24258 -+
24259 -+ Errno::result(res)?;
24260 -+
24261 -+ Ok(dst)
24262 -+}
24263 -+
24264 -+/// Change the file permission bits of the file specified by a file descriptor.
24265 -+///
24266 -+/// # References
24267 -+///
24268 -+/// [fchmod(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmod.html).
24269 -+pub fn fchmod(fd: RawFd, mode: Mode) -> Result<()> {
24270 -+ let res = unsafe { libc::fchmod(fd, mode.bits() as mode_t) };
24271 -+
24272 -+ Errno::result(res).map(drop)
24273 -+}
24274 -+
24275 -+/// Flags for `fchmodat` function.
24276 -+#[derive(Clone, Copy, Debug)]
24277 -+pub enum FchmodatFlags {
24278 -+ FollowSymlink,
24279 -+ NoFollowSymlink,
24280 -+}
24281 -+
24282 -+/// Change the file permission bits.
24283 -+///
24284 -+/// The file to be changed is determined relative to the directory associated
24285 -+/// with the file descriptor `dirfd` or the current working directory
24286 -+/// if `dirfd` is `None`.
24287 -+///
24288 -+/// If `flag` is `FchmodatFlags::NoFollowSymlink` and `path` names a symbolic link,
24289 -+/// then the mode of the symbolic link is changed.
24290 -+///
24291 -+/// `fchmod(None, path, mode, FchmodatFlags::FollowSymlink)` is identical to
24292 -+/// a call `libc::chmod(path, mode)`. That's why `chmod` is unimplemented
24293 -+/// in the `nix` crate.
24294 -+///
24295 -+/// # References
24296 -+///
24297 -+/// [fchmodat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmodat.html).
24298 -+pub fn fchmodat<P: ?Sized + NixPath>(
24299 -+ dirfd: Option<RawFd>,
24300 -+ path: &P,
24301 -+ mode: Mode,
24302 -+ flag: FchmodatFlags,
24303 -+) -> Result<()> {
24304 -+ let atflag =
24305 -+ match flag {
24306 -+ FchmodatFlags::FollowSymlink => AtFlags::empty(),
24307 -+ FchmodatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW,
24308 -+ };
24309 -+ let res = path.with_nix_path(|cstr| unsafe {
24310 -+ libc::fchmodat(
24311 -+ at_rawfd(dirfd),
24312 -+ cstr.as_ptr(),
24313 -+ mode.bits() as mode_t,
24314 -+ atflag.bits() as libc::c_int,
24315 -+ )
24316 -+ })?;
24317 -+
24318 -+ Errno::result(res).map(drop)
24319 -+}
24320 -+
24321 -+/// Change the access and modification times of a file.
24322 -+///
24323 -+/// `utimes(path, times)` is identical to
24324 -+/// `utimensat(None, path, times, UtimensatFlags::FollowSymlink)`. The former
24325 -+/// is a deprecated API so prefer using the latter if the platforms you care
24326 -+/// about support it.
24327 -+///
24328 -+/// # References
24329 -+///
24330 -+/// [utimes(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/utimes.html).
24331 -+pub fn utimes<P: ?Sized + NixPath>(path: &P, atime: &TimeVal, mtime: &TimeVal) -> Result<()> {
24332 -+ let times: [libc::timeval; 2] = [*atime.as_ref(), *mtime.as_ref()];
24333 -+ let res = path.with_nix_path(|cstr| unsafe {
24334 -+ libc::utimes(cstr.as_ptr(), &times[0])
24335 -+ })?;
24336 -+
24337 -+ Errno::result(res).map(drop)
24338 -+}
24339 -+
24340 -+/// Change the access and modification times of a file without following symlinks.
24341 -+///
24342 -+/// `lutimes(path, times)` is identical to
24343 -+/// `utimensat(None, path, times, UtimensatFlags::NoFollowSymlink)`. The former
24344 -+/// is a deprecated API so prefer using the latter if the platforms you care
24345 -+/// about support it.
24346 -+///
24347 -+/// # References
24348 -+///
24349 -+/// [lutimes(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/lutimes.html).
24350 -+#[cfg(any(target_os = "linux",
24351 -+ target_os = "haiku",
24352 -+ target_os = "ios",
24353 -+ target_os = "macos",
24354 -+ target_os = "freebsd",
24355 -+ target_os = "netbsd"))]
24356 -+pub fn lutimes<P: ?Sized + NixPath>(path: &P, atime: &TimeVal, mtime: &TimeVal) -> Result<()> {
24357 -+ let times: [libc::timeval; 2] = [*atime.as_ref(), *mtime.as_ref()];
24358 -+ let res = path.with_nix_path(|cstr| unsafe {
24359 -+ libc::lutimes(cstr.as_ptr(), &times[0])
24360 -+ })?;
24361 -+
24362 -+ Errno::result(res).map(drop)
24363 -+}
24364 -+
24365 -+/// Change the access and modification times of the file specified by a file descriptor.
24366 -+///
24367 -+/// # References
24368 -+///
24369 -+/// [futimens(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html).
24370 -+#[inline]
24371 -+pub fn futimens(fd: RawFd, atime: &TimeSpec, mtime: &TimeSpec) -> Result<()> {
24372 -+ let times: [libc::timespec; 2] = [*atime.as_ref(), *mtime.as_ref()];
24373 -+ let res = unsafe { libc::futimens(fd, &times[0]) };
24374 -+
24375 -+ Errno::result(res).map(drop)
24376 -+}
24377 -+
24378 -+/// Flags for `utimensat` function.
24379 -+#[derive(Clone, Copy, Debug)]
24380 -+pub enum UtimensatFlags {
24381 -+ FollowSymlink,
24382 -+ NoFollowSymlink,
24383 -+}
24384 -+
24385 -+/// Change the access and modification times of a file.
24386 -+///
24387 -+/// The file to be changed is determined relative to the directory associated
24388 -+/// with the file descriptor `dirfd` or the current working directory
24389 -+/// if `dirfd` is `None`.
24390 -+///
24391 -+/// If `flag` is `UtimensatFlags::NoFollowSymlink` and `path` names a symbolic link,
24392 -+/// then the mode of the symbolic link is changed.
24393 -+///
24394 -+/// `utimensat(None, path, times, UtimensatFlags::FollowSymlink)` is identical to
24395 -+/// `utimes(path, times)`. The latter is a deprecated API so prefer using the
24396 -+/// former if the platforms you care about support it.
24397 -+///
24398 -+/// # References
24399 -+///
24400 -+/// [utimensat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/utimens.html).
24401 -+pub fn utimensat<P: ?Sized + NixPath>(
24402 -+ dirfd: Option<RawFd>,
24403 -+ path: &P,
24404 -+ atime: &TimeSpec,
24405 -+ mtime: &TimeSpec,
24406 -+ flag: UtimensatFlags
24407 -+) -> Result<()> {
24408 -+ let atflag =
24409 -+ match flag {
24410 -+ UtimensatFlags::FollowSymlink => AtFlags::empty(),
24411 -+ UtimensatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW,
24412 -+ };
24413 -+ let times: [libc::timespec; 2] = [*atime.as_ref(), *mtime.as_ref()];
24414 -+ let res = path.with_nix_path(|cstr| unsafe {
24415 -+ libc::utimensat(
24416 -+ at_rawfd(dirfd),
24417 -+ cstr.as_ptr(),
24418 -+ &times[0],
24419 -+ atflag.bits() as libc::c_int,
24420 -+ )
24421 -+ })?;
24422 -+
24423 -+ Errno::result(res).map(drop)
24424 -+}
24425 -+
24426 -+pub fn mkdirat<P: ?Sized + NixPath>(fd: RawFd, path: &P, mode: Mode) -> Result<()> {
24427 -+ let res = path.with_nix_path(|cstr| {
24428 -+ unsafe { libc::mkdirat(fd, cstr.as_ptr(), mode.bits() as mode_t) }
24429 -+ })?;
24430 -+
24431 -+ Errno::result(res).map(drop)
24432 -+}
24433 -diff --git a/third_party/rust/nix-0.15.0/src/sys/statfs.rs b/third_party/rust/nix-0.15.0/src/sys/statfs.rs
24434 -new file mode 100644
24435 -index 0000000000000..d4596bf336958
24436 ---- /dev/null
24437 -+++ b/third_party/rust/nix-0.15.0/src/sys/statfs.rs
24438 -@@ -0,0 +1,548 @@
24439 -+use std::fmt::{self, Debug};
24440 -+use std::mem;
24441 -+use std::os::unix::io::AsRawFd;
24442 -+#[cfg(not(any(target_os = "linux", target_os = "android")))]
24443 -+use std::ffi::CStr;
24444 -+
24445 -+use libc;
24446 -+
24447 -+use {NixPath, Result};
24448 -+use errno::Errno;
24449 -+
24450 -+#[cfg(target_os = "android")]
24451 -+pub type fsid_t = libc::__fsid_t;
24452 -+#[cfg(not(target_os = "android"))]
24453 -+pub type fsid_t = libc::fsid_t;
24454 -+
24455 -+#[derive(Clone, Copy)]
24456 -+pub struct Statfs(libc::statfs);
24457 -+
24458 -+#[cfg(target_os = "freebsd")]
24459 -+#[derive(Eq, Copy, Clone, PartialEq, Debug)]
24460 -+pub struct FsType(u32);
24461 -+#[cfg(target_os = "android")]
24462 -+#[derive(Eq, Copy, Clone, PartialEq, Debug)]
24463 -+pub struct FsType(libc::c_ulong);
24464 -+#[cfg(all(target_os = "linux", target_arch = "s390x"))]
24465 -+#[derive(Eq, Copy, Clone, PartialEq, Debug)]
24466 -+pub struct FsType(u32);
24467 -+#[cfg(all(target_os = "linux", target_env = "musl"))]
24468 -+#[derive(Eq, Copy, Clone, PartialEq, Debug)]
24469 -+pub struct FsType(libc::c_ulong);
24470 -+#[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
24471 -+#[derive(Eq, Copy, Clone, PartialEq, Debug)]
24472 -+pub struct FsType(libc::c_long);
24473 -+
24474 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24475 -+pub const ADFS_SUPER_MAGIC: FsType = FsType(libc::ADFS_SUPER_MAGIC);
24476 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24477 -+pub const AFFS_SUPER_MAGIC: FsType = FsType(libc::AFFS_SUPER_MAGIC);
24478 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24479 -+pub const CODA_SUPER_MAGIC: FsType = FsType(libc::CODA_SUPER_MAGIC);
24480 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24481 -+pub const CRAMFS_MAGIC: FsType = FsType(libc::CRAMFS_MAGIC);
24482 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24483 -+pub const EFS_SUPER_MAGIC: FsType = FsType(libc::EFS_SUPER_MAGIC);
24484 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24485 -+pub const EXT2_SUPER_MAGIC: FsType = FsType(libc::EXT2_SUPER_MAGIC);
24486 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24487 -+pub const EXT3_SUPER_MAGIC: FsType = FsType(libc::EXT3_SUPER_MAGIC);
24488 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24489 -+pub const EXT4_SUPER_MAGIC: FsType = FsType(libc::EXT4_SUPER_MAGIC);
24490 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24491 -+pub const HPFS_SUPER_MAGIC: FsType = FsType(libc::HPFS_SUPER_MAGIC);
24492 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24493 -+pub const HUGETLBFS_MAGIC: FsType = FsType(libc::HUGETLBFS_MAGIC);
24494 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24495 -+pub const ISOFS_SUPER_MAGIC: FsType = FsType(libc::ISOFS_SUPER_MAGIC);
24496 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24497 -+pub const JFFS2_SUPER_MAGIC: FsType = FsType(libc::JFFS2_SUPER_MAGIC);
24498 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24499 -+pub const MINIX_SUPER_MAGIC: FsType = FsType(libc::MINIX_SUPER_MAGIC);
24500 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24501 -+pub const MINIX_SUPER_MAGIC2: FsType = FsType(libc::MINIX_SUPER_MAGIC2);
24502 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24503 -+pub const MINIX2_SUPER_MAGIC: FsType = FsType(libc::MINIX2_SUPER_MAGIC);
24504 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24505 -+pub const MINIX2_SUPER_MAGIC2: FsType = FsType(libc::MINIX2_SUPER_MAGIC2);
24506 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24507 -+pub const MSDOS_SUPER_MAGIC: FsType = FsType(libc::MSDOS_SUPER_MAGIC);
24508 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24509 -+pub const NCP_SUPER_MAGIC: FsType = FsType(libc::NCP_SUPER_MAGIC);
24510 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24511 -+pub const NFS_SUPER_MAGIC: FsType = FsType(libc::NFS_SUPER_MAGIC);
24512 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24513 -+pub const OPENPROM_SUPER_MAGIC: FsType = FsType(libc::OPENPROM_SUPER_MAGIC);
24514 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24515 -+pub const PROC_SUPER_MAGIC: FsType = FsType(libc::PROC_SUPER_MAGIC);
24516 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24517 -+pub const QNX4_SUPER_MAGIC: FsType = FsType(libc::QNX4_SUPER_MAGIC);
24518 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24519 -+pub const REISERFS_SUPER_MAGIC: FsType = FsType(libc::REISERFS_SUPER_MAGIC);
24520 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24521 -+pub const SMB_SUPER_MAGIC: FsType = FsType(libc::SMB_SUPER_MAGIC);
24522 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24523 -+pub const TMPFS_MAGIC: FsType = FsType(libc::TMPFS_MAGIC);
24524 -+#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
24525 -+pub const USBDEVICE_SUPER_MAGIC: FsType = FsType(libc::USBDEVICE_SUPER_MAGIC);
24526 -+
24527 -+impl Statfs {
24528 -+ /// Magic code defining system type
24529 -+ #[cfg(not(any(
24530 -+ target_os = "openbsd",
24531 -+ target_os = "ios",
24532 -+ target_os = "macos"
24533 -+ )))]
24534 -+ pub fn filesystem_type(&self) -> FsType {
24535 -+ FsType(self.0.f_type)
24536 -+ }
24537 -+
24538 -+ /// Magic code defining system type
24539 -+ #[cfg(not(any(target_os = "linux", target_os = "android")))]
24540 -+ pub fn filesystem_type_name(&self) -> &str {
24541 -+ let c_str = unsafe { CStr::from_ptr(self.0.f_fstypename.as_ptr()) };
24542 -+ c_str.to_str().unwrap()
24543 -+ }
24544 -+
24545 -+ /// Optimal transfer block size
24546 -+ #[cfg(any(target_os = "ios", target_os = "macos", target_os = "openbsd"))]
24547 -+ pub fn optimal_transfer_size(&self) -> i32 {
24548 -+ self.0.f_iosize
24549 -+ }
24550 -+
24551 -+ /// Optimal transfer block size
24552 -+ #[cfg(all(target_os = "linux", target_arch = "s390x"))]
24553 -+ pub fn optimal_transfer_size(&self) -> u32 {
24554 -+ self.0.f_bsize
24555 -+ }
24556 -+
24557 -+ /// Optimal transfer block size
24558 -+ #[cfg(all(target_os = "linux", target_env = "musl"))]
24559 -+ pub fn optimal_transfer_size(&self) -> libc::c_ulong {
24560 -+ self.0.f_bsize
24561 -+ }
24562 -+
24563 -+ /// Optimal transfer block size
24564 -+ #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
24565 -+ pub fn optimal_transfer_size(&self) -> libc::c_long {
24566 -+ self.0.f_bsize
24567 -+ }
24568 -+
24569 -+ /// Optimal transfer block size
24570 -+ #[cfg(target_os = "android")]
24571 -+ pub fn optimal_transfer_size(&self) -> libc::c_ulong {
24572 -+ self.0.f_bsize
24573 -+ }
24574 -+
24575 -+ /// Optimal transfer block size
24576 -+ #[cfg(target_os = "dragonfly")]
24577 -+ pub fn optimal_transfer_size(&self) -> libc::c_long {
24578 -+ self.0.f_iosize
24579 -+ }
24580 -+
24581 -+ /// Optimal transfer block size
24582 -+ #[cfg(target_os = "freebsd")]
24583 -+ pub fn optimal_transfer_size(&self) -> u64 {
24584 -+ self.0.f_iosize
24585 -+ }
24586 -+
24587 -+ /// Size of a block
24588 -+ #[cfg(any(target_os = "ios", target_os = "macos", target_os = "openbsd"))]
24589 -+ pub fn block_size(&self) -> u32 {
24590 -+ self.0.f_bsize
24591 -+ }
24592 -+
24593 -+ /// Size of a block
24594 -+ // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
24595 -+ #[cfg(all(target_os = "linux", target_arch = "s390x"))]
24596 -+ pub fn block_size(&self) -> u32 {
24597 -+ self.0.f_bsize
24598 -+ }
24599 -+
24600 -+ /// Size of a block
24601 -+ // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
24602 -+ #[cfg(all(target_os = "linux", target_env = "musl"))]
24603 -+ pub fn block_size(&self) -> libc::c_ulong {
24604 -+ self.0.f_bsize
24605 -+ }
24606 -+
24607 -+ /// Size of a block
24608 -+ // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
24609 -+ #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
24610 -+ pub fn block_size(&self) -> libc::c_long {
24611 -+ self.0.f_bsize
24612 -+ }
24613 -+
24614 -+ /// Size of a block
24615 -+ #[cfg(target_os = "freebsd")]
24616 -+ pub fn block_size(&self) -> u64 {
24617 -+ self.0.f_bsize
24618 -+ }
24619 -+
24620 -+ /// Size of a block
24621 -+ #[cfg(target_os = "android")]
24622 -+ pub fn block_size(&self) -> libc::c_ulong {
24623 -+ self.0.f_bsize
24624 -+ }
24625 -+
24626 -+ /// Size of a block
24627 -+ #[cfg(target_os = "dragonfly")]
24628 -+ pub fn block_size(&self) -> libc::c_long {
24629 -+ self.0.f_bsize
24630 -+ }
24631 -+
24632 -+ /// Maximum length of filenames
24633 -+ #[cfg(any(target_os = "freebsd", target_os = "openbsd"))]
24634 -+ pub fn maximum_name_length(&self) -> u32 {
24635 -+ self.0.f_namemax
24636 -+ }
24637 -+
24638 -+ /// Maximum length of filenames
24639 -+ #[cfg(all(target_os = "linux", target_arch = "s390x"))]
24640 -+ pub fn maximum_name_length(&self) -> u32 {
24641 -+ self.0.f_namelen
24642 -+ }
24643 -+
24644 -+ /// Maximum length of filenames
24645 -+ #[cfg(all(target_os = "linux", target_env = "musl"))]
24646 -+ pub fn maximum_name_length(&self) -> libc::c_ulong {
24647 -+ self.0.f_namelen
24648 -+ }
24649 -+
24650 -+ /// Maximum length of filenames
24651 -+ #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
24652 -+ pub fn maximum_name_length(&self) -> libc::c_long {
24653 -+ self.0.f_namelen
24654 -+ }
24655 -+
24656 -+ /// Maximum length of filenames
24657 -+ #[cfg(target_os = "android")]
24658 -+ pub fn maximum_name_length(&self) -> libc::c_ulong {
24659 -+ self.0.f_namelen
24660 -+ }
24661 -+
24662 -+ /// Total data blocks in filesystem
24663 -+ #[cfg(any(
24664 -+ target_os = "ios",
24665 -+ target_os = "macos",
24666 -+ target_os = "android",
24667 -+ target_os = "freebsd",
24668 -+ target_os = "openbsd",
24669 -+ ))]
24670 -+ pub fn blocks(&self) -> u64 {
24671 -+ self.0.f_blocks
24672 -+ }
24673 -+
24674 -+ /// Total data blocks in filesystem
24675 -+ #[cfg(target_os = "dragonfly")]
24676 -+ pub fn blocks(&self) -> libc::c_long {
24677 -+ self.0.f_blocks
24678 -+ }
24679 -+
24680 -+ /// Total data blocks in filesystem
24681 -+ #[cfg(all(target_os = "linux", target_env = "musl"))]
24682 -+ pub fn blocks(&self) -> u64 {
24683 -+ self.0.f_blocks
24684 -+ }
24685 -+
24686 -+ /// Total data blocks in filesystem
24687 -+ #[cfg(not(any(
24688 -+ target_os = "ios",
24689 -+ target_os = "macos",
24690 -+ target_os = "android",
24691 -+ target_os = "freebsd",
24692 -+ target_os = "openbsd",
24693 -+ target_os = "dragonfly",
24694 -+ all(target_os = "linux", target_env = "musl")
24695 -+ )))]
24696 -+ pub fn blocks(&self) -> libc::c_ulong {
24697 -+ self.0.f_blocks
24698 -+ }
24699 -+
24700 -+ /// Free blocks in filesystem
24701 -+ #[cfg(any(
24702 -+ target_os = "ios",
24703 -+ target_os = "macos",
24704 -+ target_os = "android",
24705 -+ target_os = "freebsd",
24706 -+ target_os = "openbsd",
24707 -+ ))]
24708 -+ pub fn blocks_free(&self) -> u64 {
24709 -+ self.0.f_bfree
24710 -+ }
24711 -+
24712 -+ /// Free blocks in filesystem
24713 -+ #[cfg(target_os = "dragonfly")]
24714 -+ pub fn blocks_free(&self) -> libc::c_long {
24715 -+ self.0.f_bfree
24716 -+ }
24717 -+
24718 -+ /// Free blocks in filesystem
24719 -+ #[cfg(all(target_os = "linux", target_env = "musl"))]
24720 -+ pub fn blocks_free(&self) -> u64 {
24721 -+ self.0.f_bfree
24722 -+ }
24723 -+
24724 -+ /// Free blocks in filesystem
24725 -+ #[cfg(not(any(
24726 -+ target_os = "ios",
24727 -+ target_os = "macos",
24728 -+ target_os = "android",
24729 -+ target_os = "freebsd",
24730 -+ target_os = "openbsd",
24731 -+ target_os = "dragonfly",
24732 -+ all(target_os = "linux", target_env = "musl")
24733 -+ )))]
24734 -+ pub fn blocks_free(&self) -> libc::c_ulong {
24735 -+ self.0.f_bfree
24736 -+ }
24737 -+
24738 -+ /// Free blocks available to unprivileged user
24739 -+ #[cfg(any(target_os = "ios", target_os = "macos", target_os = "android"))]
24740 -+ pub fn blocks_available(&self) -> u64 {
24741 -+ self.0.f_bavail
24742 -+ }
24743 -+
24744 -+ /// Free blocks available to unprivileged user
24745 -+ #[cfg(target_os = "dragonfly")]
24746 -+ pub fn blocks_available(&self) -> libc::c_long {
24747 -+ self.0.f_bavail
24748 -+ }
24749 -+
24750 -+ /// Free blocks available to unprivileged user
24751 -+ #[cfg(any(target_os = "freebsd", target_os = "openbsd"))]
24752 -+ pub fn blocks_available(&self) -> i64 {
24753 -+ self.0.f_bavail
24754 -+ }
24755 -+
24756 -+ /// Free blocks available to unprivileged user
24757 -+ #[cfg(all(target_os = "linux", target_env = "musl"))]
24758 -+ pub fn blocks_available(&self) -> u64 {
24759 -+ self.0.f_bavail
24760 -+ }
24761 -+
24762 -+ /// Free blocks available to unprivileged user
24763 -+ #[cfg(not(any(
24764 -+ target_os = "ios",
24765 -+ target_os = "macos",
24766 -+ target_os = "android",
24767 -+ target_os = "freebsd",
24768 -+ target_os = "openbsd",
24769 -+ target_os = "dragonfly",
24770 -+ all(target_os = "linux", target_env = "musl")
24771 -+ )))]
24772 -+ pub fn blocks_available(&self) -> libc::c_ulong {
24773 -+ self.0.f_bavail
24774 -+ }
24775 -+
24776 -+ /// Total file nodes in filesystem
24777 -+ #[cfg(any(
24778 -+ target_os = "ios",
24779 -+ target_os = "macos",
24780 -+ target_os = "android",
24781 -+ target_os = "freebsd",
24782 -+ target_os = "openbsd",
24783 -+ ))]
24784 -+ pub fn files(&self) -> u64 {
24785 -+ self.0.f_files
24786 -+ }
24787 -+
24788 -+ /// Total file nodes in filesystem
24789 -+ #[cfg(target_os = "dragonfly")]
24790 -+ pub fn files(&self) -> libc::c_long {
24791 -+ self.0.f_files
24792 -+ }
24793 -+
24794 -+ /// Total file nodes in filesystem
24795 -+ #[cfg(all(target_os = "linux", target_env = "musl"))]
24796 -+ pub fn files(&self) -> u64 {
24797 -+ self.0.f_files
24798 -+ }
24799 -+
24800 -+ /// Total file nodes in filesystem
24801 -+ #[cfg(not(any(
24802 -+ target_os = "ios",
24803 -+ target_os = "macos",
24804 -+ target_os = "android",
24805 -+ target_os = "freebsd",
24806 -+ target_os = "openbsd",
24807 -+ target_os = "dragonfly",
24808 -+ all(target_os = "linux", target_env = "musl")
24809 -+ )))]
24810 -+ pub fn files(&self) -> libc::c_ulong {
24811 -+ self.0.f_files
24812 -+ }
24813 -+
24814 -+ /// Free file nodes in filesystem
24815 -+ #[cfg(any(target_os = "ios", target_os = "macos", target_os = "android"))]
24816 -+ pub fn files_free(&self) -> u64 {
24817 -+ self.0.f_ffree
24818 -+ }
24819 -+
24820 -+ /// Free file nodes in filesystem
24821 -+ #[cfg(target_os = "dragonfly")]
24822 -+ pub fn files_free(&self) -> libc::c_long {
24823 -+ self.0.f_ffree
24824 -+ }
24825 -+
24826 -+ /// Free file nodes in filesystem
24827 -+ #[cfg(any(target_os = "freebsd", target_os = "openbsd"))]
24828 -+ pub fn files_free(&self) -> i64 {
24829 -+ self.0.f_ffree
24830 -+ }
24831 -+
24832 -+ /// Free file nodes in filesystem
24833 -+ #[cfg(all(target_os = "linux", target_env = "musl"))]
24834 -+ pub fn files_free(&self) -> u64 {
24835 -+ self.0.f_ffree
24836 -+ }
24837 -+
24838 -+ /// Free file nodes in filesystem
24839 -+ #[cfg(not(any(
24840 -+ target_os = "ios",
24841 -+ target_os = "macos",
24842 -+ target_os = "android",
24843 -+ target_os = "freebsd",
24844 -+ target_os = "openbsd",
24845 -+ target_os = "dragonfly",
24846 -+ all(target_os = "linux", target_env = "musl")
24847 -+ )))]
24848 -+ pub fn files_free(&self) -> libc::c_ulong {
24849 -+ self.0.f_ffree
24850 -+ }
24851 -+
24852 -+ /// Filesystem ID
24853 -+ pub fn filesystem_id(&self) -> fsid_t {
24854 -+ self.0.f_fsid
24855 -+ }
24856 -+}
24857 -+
24858 -+impl Debug for Statfs {
24859 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24860 -+ f.debug_struct("Statfs")
24861 -+ .field("optimal_transfer_size", &self.optimal_transfer_size())
24862 -+ .field("block_size", &self.block_size())
24863 -+ .field("blocks", &self.blocks())
24864 -+ .field("blocks_free", &self.blocks_free())
24865 -+ .field("blocks_available", &self.blocks_available())
24866 -+ .field("files", &self.files())
24867 -+ .field("files_free", &self.files_free())
24868 -+ .field("filesystem_id", &self.filesystem_id())
24869 -+ .finish()
24870 -+ }
24871 -+}
24872 -+
24873 -+pub fn statfs<P: ?Sized + NixPath>(path: &P) -> Result<Statfs> {
24874 -+ unsafe {
24875 -+ let mut stat: Statfs = mem::uninitialized();
24876 -+ let res = path.with_nix_path(|path| libc::statfs(path.as_ptr(), &mut stat.0))?;
24877 -+ Errno::result(res).map(|_| stat)
24878 -+ }
24879 -+}
24880 -+
24881 -+pub fn fstatfs<T: AsRawFd>(fd: &T) -> Result<Statfs> {
24882 -+ unsafe {
24883 -+ let mut stat: Statfs = mem::uninitialized();
24884 -+ Errno::result(libc::fstatfs(fd.as_raw_fd(), &mut stat.0)).map(|_| stat)
24885 -+ }
24886 -+}
24887 -+
24888 -+#[cfg(test)]
24889 -+mod test {
24890 -+ use std::fs::File;
24891 -+
24892 -+ use sys::statfs::*;
24893 -+ use sys::statvfs::*;
24894 -+ use std::path::Path;
24895 -+
24896 -+ #[test]
24897 -+ fn statfs_call() {
24898 -+ check_statfs("/tmp");
24899 -+ check_statfs("/dev");
24900 -+ check_statfs("/run");
24901 -+ check_statfs("/");
24902 -+ }
24903 -+
24904 -+ #[test]
24905 -+ fn fstatfs_call() {
24906 -+ check_fstatfs("/tmp");
24907 -+ check_fstatfs("/dev");
24908 -+ check_fstatfs("/run");
24909 -+ check_fstatfs("/");
24910 -+ }
24911 -+
24912 -+ fn check_fstatfs(path: &str) {
24913 -+ if !Path::new(path).exists() {
24914 -+ return;
24915 -+ }
24916 -+ let vfs = statvfs(path.as_bytes()).unwrap();
24917 -+ let file = File::open(path).unwrap();
24918 -+ let fs = fstatfs(&file).unwrap();
24919 -+ assert_fs_equals(fs, vfs);
24920 -+ }
24921 -+
24922 -+ fn check_statfs(path: &str) {
24923 -+ if !Path::new(path).exists() {
24924 -+ return;
24925 -+ }
24926 -+ let vfs = statvfs(path.as_bytes()).unwrap();
24927 -+ let fs = statfs(path.as_bytes()).unwrap();
24928 -+ assert_fs_equals(fs, vfs);
24929 -+ }
24930 -+
24931 -+ fn assert_fs_equals(fs: Statfs, vfs: Statvfs) {
24932 -+ assert_eq!(fs.files() as u64, vfs.files() as u64);
24933 -+ assert_eq!(fs.blocks() as u64, vfs.blocks() as u64);
24934 -+ assert_eq!(fs.block_size() as u64, vfs.fragment_size() as u64);
24935 -+ }
24936 -+
24937 -+ // This test is ignored because files_free/blocks_free can change after statvfs call and before
24938 -+ // statfs call.
24939 -+ #[test]
24940 -+ #[ignore]
24941 -+ fn statfs_call_strict() {
24942 -+ check_statfs_strict("/tmp");
24943 -+ check_statfs_strict("/dev");
24944 -+ check_statfs_strict("/run");
24945 -+ check_statfs_strict("/");
24946 -+ }
24947 -+
24948 -+ // This test is ignored because files_free/blocks_free can change after statvfs call and before
24949 -+ // fstatfs call.
24950 -+ #[test]
24951 -+ #[ignore]
24952 -+ fn fstatfs_call_strict() {
24953 -+ check_fstatfs_strict("/tmp");
24954 -+ check_fstatfs_strict("/dev");
24955 -+ check_fstatfs_strict("/run");
24956 -+ check_fstatfs_strict("/");
24957 -+ }
24958 -+
24959 -+ fn check_fstatfs_strict(path: &str) {
24960 -+ if !Path::new(path).exists() {
24961 -+ return;
24962 -+ }
24963 -+ let vfs = statvfs(path.as_bytes());
24964 -+ let file = File::open(path).unwrap();
24965 -+ let fs = fstatfs(&file);
24966 -+ assert_fs_equals_strict(fs.unwrap(), vfs.unwrap())
24967 -+ }
24968 -+
24969 -+ fn check_statfs_strict(path: &str) {
24970 -+ if !Path::new(path).exists() {
24971 -+ return;
24972 -+ }
24973 -+ let vfs = statvfs(path.as_bytes());
24974 -+ let fs = statfs(path.as_bytes());
24975 -+ assert_fs_equals_strict(fs.unwrap(), vfs.unwrap())
24976 -+ }
24977 -+
24978 -+ fn assert_fs_equals_strict(fs: Statfs, vfs: Statvfs) {
24979 -+ assert_eq!(fs.files_free() as u64, vfs.files_free() as u64);
24980 -+ assert_eq!(fs.blocks_free() as u64, vfs.blocks_free() as u64);
24981 -+ assert_eq!(fs.blocks_available() as u64, vfs.blocks_available() as u64);
24982 -+ assert_eq!(fs.files() as u64, vfs.files() as u64);
24983 -+ assert_eq!(fs.blocks() as u64, vfs.blocks() as u64);
24984 -+ assert_eq!(fs.block_size() as u64, vfs.fragment_size() as u64);
24985 -+ }
24986 -+}
24987 -diff --git a/third_party/rust/nix-0.15.0/src/sys/statvfs.rs b/third_party/rust/nix-0.15.0/src/sys/statvfs.rs
24988 -new file mode 100644
24989 -index 0000000000000..e5980369d5119
24990 ---- /dev/null
24991 -+++ b/third_party/rust/nix-0.15.0/src/sys/statvfs.rs
24992 -@@ -0,0 +1,160 @@
24993 -+//! Get filesystem statistics
24994 -+//!
24995 -+//! See [the man pages](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatvfs.html)
24996 -+//! for more details.
24997 -+use std::mem;
24998 -+use std::os::unix::io::AsRawFd;
24999 -+
25000 -+use libc::{self, c_ulong};
25001 -+
25002 -+use {Result, NixPath};
25003 -+use errno::Errno;
25004 -+
25005 -+libc_bitflags!(
25006 -+ /// File system mount Flags
25007 -+ #[repr(C)]
25008 -+ #[derive(Default)]
25009 -+ pub struct FsFlags: c_ulong {
25010 -+ /// Read Only
25011 -+ ST_RDONLY;
25012 -+ /// Do not allow the set-uid bits to have an effect
25013 -+ ST_NOSUID;
25014 -+ /// Do not interpret character or block-special devices
25015 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25016 -+ ST_NODEV;
25017 -+ /// Do not allow execution of binaries on the filesystem
25018 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25019 -+ ST_NOEXEC;
25020 -+ /// All IO should be done synchronously
25021 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25022 -+ ST_SYNCHRONOUS;
25023 -+ /// Allow mandatory locks on the filesystem
25024 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25025 -+ ST_MANDLOCK;
25026 -+ /// Write on file/directory/symlink
25027 -+ #[cfg(target_os = "linux")]
25028 -+ ST_WRITE;
25029 -+ /// Append-only file
25030 -+ #[cfg(target_os = "linux")]
25031 -+ ST_APPEND;
25032 -+ /// Immutable file
25033 -+ #[cfg(target_os = "linux")]
25034 -+ ST_IMMUTABLE;
25035 -+ /// Do not update access times on files
25036 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25037 -+ ST_NOATIME;
25038 -+ /// Do not update access times on files
25039 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25040 -+ ST_NODIRATIME;
25041 -+ /// Update access time relative to modify/change time
25042 -+ #[cfg(any(target_os = "android", all(target_os = "linux", not(target_env = "musl"))))]
25043 -+ ST_RELATIME;
25044 -+ }
25045 -+);
25046 -+
25047 -+/// Wrapper around the POSIX `statvfs` struct
25048 -+///
25049 -+/// For more information see the [`statvfs(3)` man pages](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_statvfs.h.html).
25050 -+// FIXME: Replace with repr(transparent)
25051 -+#[repr(C)]
25052 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
25053 -+pub struct Statvfs(libc::statvfs);
25054 -+
25055 -+impl Statvfs {
25056 -+ /// get the file system block size
25057 -+ pub fn block_size(&self) -> c_ulong {
25058 -+ self.0.f_bsize
25059 -+ }
25060 -+
25061 -+ /// Get the fundamental file system block size
25062 -+ pub fn fragment_size(&self) -> c_ulong {
25063 -+ self.0.f_frsize
25064 -+ }
25065 -+
25066 -+ /// Get the number of blocks.
25067 -+ ///
25068 -+ /// Units are in units of `fragment_size()`
25069 -+ pub fn blocks(&self) -> libc::fsblkcnt_t {
25070 -+ self.0.f_blocks
25071 -+ }
25072 -+
25073 -+ /// Get the number of free blocks in the file system
25074 -+ pub fn blocks_free(&self) -> libc::fsblkcnt_t {
25075 -+ self.0.f_bfree
25076 -+ }
25077 -+
25078 -+ /// Get the number of free blocks for unprivileged users
25079 -+ pub fn blocks_available(&self) -> libc::fsblkcnt_t {
25080 -+ self.0.f_bavail
25081 -+ }
25082 -+
25083 -+ /// Get the total number of file inodes
25084 -+ pub fn files(&self) -> libc::fsfilcnt_t {
25085 -+ self.0.f_files
25086 -+ }
25087 -+
25088 -+ /// Get the number of free file inodes
25089 -+ pub fn files_free(&self) -> libc::fsfilcnt_t {
25090 -+ self.0.f_ffree
25091 -+ }
25092 -+
25093 -+ /// Get the number of free file inodes for unprivileged users
25094 -+ pub fn files_available(&self) -> libc::fsfilcnt_t {
25095 -+ self.0.f_favail
25096 -+ }
25097 -+
25098 -+ /// Get the file system id
25099 -+ pub fn filesystem_id(&self) -> c_ulong {
25100 -+ self.0.f_fsid
25101 -+ }
25102 -+
25103 -+ /// Get the mount flags
25104 -+ pub fn flags(&self) -> FsFlags {
25105 -+ FsFlags::from_bits_truncate(self.0.f_flag)
25106 -+ }
25107 -+
25108 -+ /// Get the maximum filename length
25109 -+ pub fn name_max(&self) -> c_ulong {
25110 -+ self.0.f_namemax
25111 -+ }
25112 -+
25113 -+}
25114 -+
25115 -+/// Return a `Statvfs` object with information about the `path`
25116 -+pub fn statvfs<P: ?Sized + NixPath>(path: &P) -> Result<Statvfs> {
25117 -+ unsafe {
25118 -+ Errno::clear();
25119 -+ let mut stat: Statvfs = mem::uninitialized();
25120 -+ let res = path.with_nix_path(|path|
25121 -+ libc::statvfs(path.as_ptr(), &mut stat.0)
25122 -+ )?;
25123 -+
25124 -+ Errno::result(res).map(|_| stat)
25125 -+ }
25126 -+}
25127 -+
25128 -+/// Return a `Statvfs` object with information about `fd`
25129 -+pub fn fstatvfs<T: AsRawFd>(fd: &T) -> Result<Statvfs> {
25130 -+ unsafe {
25131 -+ Errno::clear();
25132 -+ let mut stat: Statvfs = mem::uninitialized();
25133 -+ Errno::result(libc::fstatvfs(fd.as_raw_fd(), &mut stat.0)).map(|_| stat)
25134 -+ }
25135 -+}
25136 -+
25137 -+#[cfg(test)]
25138 -+mod test {
25139 -+ use std::fs::File;
25140 -+ use sys::statvfs::*;
25141 -+
25142 -+ #[test]
25143 -+ fn statvfs_call() {
25144 -+ statvfs("/".as_bytes()).unwrap();
25145 -+ }
25146 -+
25147 -+ #[test]
25148 -+ fn fstatvfs_call() {
25149 -+ let root = File::open("/").unwrap();
25150 -+ fstatvfs(&root).unwrap();
25151 -+ }
25152 -+}
25153 -diff --git a/third_party/rust/nix-0.15.0/src/sys/sysinfo.rs b/third_party/rust/nix-0.15.0/src/sys/sysinfo.rs
25154 -new file mode 100644
25155 -index 0000000000000..4c8e38988886d
25156 ---- /dev/null
25157 -+++ b/third_party/rust/nix-0.15.0/src/sys/sysinfo.rs
25158 -@@ -0,0 +1,72 @@
25159 -+use libc::{self, SI_LOAD_SHIFT};
25160 -+use std::{cmp, mem};
25161 -+use std::time::Duration;
25162 -+
25163 -+use Result;
25164 -+use errno::Errno;
25165 -+
25166 -+/// System info structure returned by `sysinfo`.
25167 -+#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
25168 -+pub struct SysInfo(libc::sysinfo);
25169 -+
25170 -+impl SysInfo {
25171 -+ /// Returns the load average tuple.
25172 -+ ///
25173 -+ /// The returned values represent the load average over time intervals of
25174 -+ /// 1, 5, and 15 minutes, respectively.
25175 -+ pub fn load_average(&self) -> (f64, f64, f64) {
25176 -+ (
25177 -+ self.0.loads[0] as f64 / (1 << SI_LOAD_SHIFT) as f64,
25178 -+ self.0.loads[1] as f64 / (1 << SI_LOAD_SHIFT) as f64,
25179 -+ self.0.loads[2] as f64 / (1 << SI_LOAD_SHIFT) as f64,
25180 -+ )
25181 -+ }
25182 -+
25183 -+ /// Returns the time since system boot.
25184 -+ pub fn uptime(&self) -> Duration {
25185 -+ // Truncate negative values to 0
25186 -+ Duration::from_secs(cmp::max(self.0.uptime, 0) as u64)
25187 -+ }
25188 -+
25189 -+ /// Current number of processes.
25190 -+ pub fn process_count(&self) -> u16 {
25191 -+ self.0.procs
25192 -+ }
25193 -+
25194 -+ /// Returns the amount of swap memory in Bytes.
25195 -+ pub fn swap_total(&self) -> u64 {
25196 -+ self.scale_mem(self.0.totalswap)
25197 -+ }
25198 -+
25199 -+ /// Returns the amount of unused swap memory in Bytes.
25200 -+ pub fn swap_free(&self) -> u64 {
25201 -+ self.scale_mem(self.0.freeswap)
25202 -+ }
25203 -+
25204 -+ /// Returns the total amount of installed RAM in Bytes.
25205 -+ pub fn ram_total(&self) -> u64 {
25206 -+ self.scale_mem(self.0.totalram)
25207 -+ }
25208 -+
25209 -+ /// Returns the amount of completely unused RAM in Bytes.
25210 -+ ///
25211 -+ /// "Unused" in this context means that the RAM in neither actively used by
25212 -+ /// programs, nor by the operating system as disk cache or buffer. It is
25213 -+ /// "wasted" RAM since it currently serves no purpose.
25214 -+ pub fn ram_unused(&self) -> u64 {
25215 -+ self.scale_mem(self.0.freeram)
25216 -+ }
25217 -+
25218 -+ fn scale_mem(&self, units: libc::c_ulong) -> u64 {
25219 -+ units as u64 * self.0.mem_unit as u64
25220 -+ }
25221 -+}
25222 -+
25223 -+/// Returns system information.
25224 -+///
25225 -+/// [See `sysinfo(2)`](http://man7.org/linux/man-pages/man2/sysinfo.2.html).
25226 -+pub fn sysinfo() -> Result<SysInfo> {
25227 -+ let mut info: libc::sysinfo = unsafe { mem::uninitialized() };
25228 -+ let res = unsafe { libc::sysinfo(&mut info) };
25229 -+ Errno::result(res).map(|_| SysInfo(info))
25230 -+}
25231 -diff --git a/third_party/rust/nix-0.15.0/src/sys/termios.rs b/third_party/rust/nix-0.15.0/src/sys/termios.rs
25232 -new file mode 100644
25233 -index 0000000000000..c7cdf10b461c1
25234 ---- /dev/null
25235 -+++ b/third_party/rust/nix-0.15.0/src/sys/termios.rs
25236 -@@ -0,0 +1,1107 @@
25237 -+//! An interface for controlling asynchronous communication ports
25238 -+//!
25239 -+//! This interface provides a safe wrapper around the termios subsystem defined by POSIX. The
25240 -+//! underlying types are all implemented in libc for most platforms and either wrapped in safer
25241 -+//! types here or exported directly.
25242 -+//!
25243 -+//! If you are unfamiliar with the `termios` API, you should first read the
25244 -+//! [API documentation](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/termios.h.html) and
25245 -+//! then come back to understand how `nix` safely wraps it.
25246 -+//!
25247 -+//! It should be noted that this API incurs some runtime overhead above the base `libc` definitions.
25248 -+//! As this interface is not used with high-bandwidth information, this should be fine in most
25249 -+//! cases. The primary cost when using this API is that the `Termios` datatype here duplicates the
25250 -+//! standard fields of the underlying `termios` struct and uses safe type wrappers for those fields.
25251 -+//! This means that when crossing the FFI interface to the underlying C library, data is first
25252 -+//! copied into the underlying `termios` struct, then the operation is done, and the data is copied
25253 -+//! back (with additional sanity checking) into the safe wrapper types. The `termios` struct is
25254 -+//! relatively small across all platforms (on the order of 32-64 bytes).
25255 -+//!
25256 -+//! The following examples highlight some of the API use cases such that users coming from using C
25257 -+//! or reading the standard documentation will understand how to use the safe API exposed here.
25258 -+//!
25259 -+//! Example disabling processing of the end-of-file control character:
25260 -+//!
25261 -+//! ```
25262 -+//! # use self::nix::sys::termios::SpecialCharacterIndices::VEOF;
25263 -+//! # use self::nix::sys::termios::{_POSIX_VDISABLE, Termios};
25264 -+//! # let mut termios = unsafe { Termios::default_uninit() };
25265 -+//! termios.control_chars[VEOF as usize] = _POSIX_VDISABLE;
25266 -+//! ```
25267 -+//!
25268 -+//! The flags within `Termios` are defined as bitfields using the `bitflags` crate. This provides
25269 -+//! an interface for working with bitfields that is similar to working with the raw unsigned
25270 -+//! integer types but offers type safety because of the internal checking that values will always
25271 -+//! be a valid combination of the defined flags.
25272 -+//!
25273 -+//! An example showing some of the basic operations for interacting with the control flags:
25274 -+//!
25275 -+//! ```
25276 -+//! # use self::nix::sys::termios::{ControlFlags, Termios};
25277 -+//! # let mut termios = unsafe { Termios::default_uninit() };
25278 -+//! termios.control_flags & ControlFlags::CSIZE == ControlFlags::CS5;
25279 -+//! termios.control_flags |= ControlFlags::CS5;
25280 -+//! ```
25281 -+//!
25282 -+//! # Baud rates
25283 -+//!
25284 -+//! This API is not consistent across platforms when it comes to `BaudRate`: Android and Linux both
25285 -+//! only support the rates specified by the `BaudRate` enum through their termios API while the BSDs
25286 -+//! support arbitrary baud rates as the values of the `BaudRate` enum constants are the same integer
25287 -+//! value of the constant (`B9600` == `9600`). Therefore the `nix::termios` API uses the following
25288 -+//! conventions:
25289 -+//!
25290 -+//! * `cfgetispeed()` - Returns `u32` on BSDs, `BaudRate` on Android/Linux
25291 -+//! * `cfgetospeed()` - Returns `u32` on BSDs, `BaudRate` on Android/Linux
25292 -+//! * `cfsetispeed()` - Takes `u32` or `BaudRate` on BSDs, `BaudRate` on Android/Linux
25293 -+//! * `cfsetospeed()` - Takes `u32` or `BaudRate` on BSDs, `BaudRate` on Android/Linux
25294 -+//! * `cfsetspeed()` - Takes `u32` or `BaudRate` on BSDs, `BaudRate` on Android/Linux
25295 -+//!
25296 -+//! The most common use case of specifying a baud rate using the enum will work the same across
25297 -+//! platforms:
25298 -+//!
25299 -+//! ```rust
25300 -+//! # #[macro_use] extern crate nix;
25301 -+//! # use nix::sys::termios::{BaudRate, cfsetispeed, cfsetospeed, cfsetspeed, Termios};
25302 -+//! # fn main() {
25303 -+//! # let mut t = unsafe { Termios::default_uninit() };
25304 -+//! cfsetispeed(&mut t, BaudRate::B9600);
25305 -+//! cfsetospeed(&mut t, BaudRate::B9600);
25306 -+//! cfsetspeed(&mut t, BaudRate::B9600);
25307 -+//! # }
25308 -+//! ```
25309 -+//!
25310 -+//! Additionally round-tripping baud rates is consistent across platforms:
25311 -+//!
25312 -+//! ```rust
25313 -+//! # extern crate nix;
25314 -+//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetispeed, cfsetspeed, Termios};
25315 -+//! # fn main() {
25316 -+//! # let mut t = unsafe { Termios::default_uninit() };
25317 -+//! # cfsetspeed(&mut t, BaudRate::B9600);
25318 -+//! let speed = cfgetispeed(&t);
25319 -+//! assert!(speed == cfgetospeed(&t));
25320 -+//! cfsetispeed(&mut t, speed);
25321 -+//! # }
25322 -+//! ```
25323 -+//!
25324 -+//! On non-BSDs, `cfgetispeed()` and `cfgetospeed()` both return a `BaudRate`:
25325 -+//!
25326 -+// FIXME: Replace `ignore` with `compile_fail` once 1.22 is the minimum support Rust version
25327 -+#![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
25328 -+ target_os = "macos", target_os = "netbsd", target_os = "openbsd"),
25329 -+ doc = " ```rust,ignore")]
25330 -+#![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
25331 -+ target_os = "macos", target_os = "netbsd", target_os = "openbsd")),
25332 -+ doc = " ```rust")]
25333 -+//! # extern crate nix;
25334 -+//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetspeed, Termios};
25335 -+//! # fn main() {
25336 -+//! # let mut t = unsafe { Termios::default_uninit() };
25337 -+//! # cfsetspeed(&mut t, BaudRate::B9600);
25338 -+//! assert!(cfgetispeed(&t) == BaudRate::B9600);
25339 -+//! assert!(cfgetospeed(&t) == BaudRate::B9600);
25340 -+//! # }
25341 -+//! ```
25342 -+//!
25343 -+//! But on the BSDs, `cfgetispeed()` and `cfgetospeed()` both return `u32`s:
25344 -+//!
25345 -+// FIXME: Replace `ignore` with `compile_fail` once 1.22 is the minimum support Rust version
25346 -+#![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
25347 -+ target_os = "macos", target_os = "netbsd", target_os = "openbsd"),
25348 -+ doc = " ```rust")]
25349 -+#![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
25350 -+ target_os = "macos", target_os = "netbsd", target_os = "openbsd")),
25351 -+ doc = " ```rust,ignore")]
25352 -+//! # extern crate nix;
25353 -+//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetspeed, Termios};
25354 -+//! # fn main() {
25355 -+//! # let mut t = unsafe { Termios::default_uninit() };
25356 -+//! # cfsetspeed(&mut t, 9600u32);
25357 -+//! assert!(cfgetispeed(&t) == 9600u32);
25358 -+//! assert!(cfgetospeed(&t) == 9600u32);
25359 -+//! # }
25360 -+//! ```
25361 -+//!
25362 -+//! It's trivial to convert from a `BaudRate` to a `u32` on BSDs:
25363 -+//!
25364 -+// FIXME: Replace `ignore` with `compile_fail` once 1.22 is the minimum support Rust version
25365 -+#![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
25366 -+ target_os = "macos", target_os = "netbsd", target_os = "openbsd"),
25367 -+ doc = " ```rust")]
25368 -+#![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
25369 -+ target_os = "macos", target_os = "netbsd", target_os = "openbsd")),
25370 -+ doc = " ```rust,ignore")]
25371 -+//! # extern crate nix;
25372 -+//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfsetspeed, Termios};
25373 -+//! # fn main() {
25374 -+//! # let mut t = unsafe { Termios::default_uninit() };
25375 -+//! # cfsetspeed(&mut t, 9600u32);
25376 -+//! assert!(cfgetispeed(&t) == BaudRate::B9600.into());
25377 -+//! assert!(u32::from(BaudRate::B9600) == 9600u32);
25378 -+//! # }
25379 -+//! ```
25380 -+//!
25381 -+//! And on BSDs you can specify arbitrary baud rates (**note** this depends on hardware support)
25382 -+//! by specifying baud rates directly using `u32`s:
25383 -+//!
25384 -+// FIXME: Replace `ignore` with `compile_fail` once 1.22 is the minimum support Rust version
25385 -+#![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
25386 -+ target_os = "macos", target_os = "netbsd", target_os = "openbsd"),
25387 -+ doc = " ```rust")]
25388 -+#![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
25389 -+ target_os = "macos", target_os = "netbsd", target_os = "openbsd")),
25390 -+ doc = " ```rust,ignore")]
25391 -+//! # extern crate nix;
25392 -+//! # use nix::sys::termios::{cfsetispeed, cfsetospeed, cfsetspeed, Termios};
25393 -+//! # fn main() {
25394 -+//! # let mut t = unsafe { Termios::default_uninit() };
25395 -+//! cfsetispeed(&mut t, 9600u32);
25396 -+//! cfsetospeed(&mut t, 9600u32);
25397 -+//! cfsetspeed(&mut t, 9600u32);
25398 -+//! # }
25399 -+//! ```
25400 -+use Result;
25401 -+use errno::Errno;
25402 -+use libc::{self, c_int, tcflag_t};
25403 -+use std::cell::{Ref, RefCell};
25404 -+use std::convert::From;
25405 -+use std::mem;
25406 -+use std::os::unix::io::RawFd;
25407 -+
25408 -+use ::unistd::Pid;
25409 -+
25410 -+/// Stores settings for the termios API
25411 -+///
25412 -+/// This is a wrapper around the `libc::termios` struct that provides a safe interface for the
25413 -+/// standard fields. The only safe way to obtain an instance of this struct is to extract it from
25414 -+/// an open port using `tcgetattr()`.
25415 -+#[derive(Clone, Debug, Eq, PartialEq)]
25416 -+pub struct Termios {
25417 -+ inner: RefCell<libc::termios>,
25418 -+ /// Input mode flags (see `termios.c_iflag` documentation)
25419 -+ pub input_flags: InputFlags,
25420 -+ /// Output mode flags (see `termios.c_oflag` documentation)
25421 -+ pub output_flags: OutputFlags,
25422 -+ /// Control mode flags (see `termios.c_cflag` documentation)
25423 -+ pub control_flags: ControlFlags,
25424 -+ /// Local mode flags (see `termios.c_lflag` documentation)
25425 -+ pub local_flags: LocalFlags,
25426 -+ /// Control characters (see `termios.c_cc` documentation)
25427 -+ pub control_chars: [libc::cc_t; NCCS],
25428 -+}
25429 -+
25430 -+impl Termios {
25431 -+ /// Exposes an immutable reference to the underlying `libc::termios` data structure.
25432 -+ ///
25433 -+ /// This can be used for interfacing with other FFI functions like:
25434 -+ ///
25435 -+ /// ```rust
25436 -+ /// # extern crate libc;
25437 -+ /// # extern crate nix;
25438 -+ /// # fn main() {
25439 -+ /// # use nix::sys::termios::Termios;
25440 -+ /// # let mut termios = unsafe { Termios::default_uninit() };
25441 -+ /// let inner_termios = termios.get_libc_termios();
25442 -+ /// unsafe { libc::cfgetispeed(&*inner_termios) };
25443 -+ /// # }
25444 -+ /// ```
25445 -+ ///
25446 -+ /// There is no public API exposed for functions that modify the underlying `libc::termios`
25447 -+ /// data because it requires additional work to maintain type safety.
25448 -+ // FIXME: Switch this over to use pub(crate)
25449 -+ #[doc(hidden)]
25450 -+ pub fn get_libc_termios(&self) -> Ref<libc::termios> {
25451 -+ {
25452 -+ let mut termios = self.inner.borrow_mut();
25453 -+ termios.c_iflag = self.input_flags.bits();
25454 -+ termios.c_oflag = self.output_flags.bits();
25455 -+ termios.c_cflag = self.control_flags.bits();
25456 -+ termios.c_lflag = self.local_flags.bits();
25457 -+ termios.c_cc = self.control_chars;
25458 -+ }
25459 -+ self.inner.borrow()
25460 -+ }
25461 -+
25462 -+ /// Exposes the inner `libc::termios` datastore within `Termios`.
25463 -+ ///
25464 -+ /// This is unsafe because if this is used to modify the inner libc::termios struct, it will not
25465 -+ /// automatically update the safe wrapper type around it. Therefore we disable docs to
25466 -+ /// effectively limit its use to nix internals. In this case it should also be paired with a
25467 -+ /// call to `update_wrapper()` so that the wrapper-type and internal representation stay
25468 -+ /// consistent.
25469 -+ unsafe fn get_libc_termios_mut(&mut self) -> *mut libc::termios {
25470 -+ {
25471 -+ let mut termios = self.inner.borrow_mut();
25472 -+ termios.c_iflag = self.input_flags.bits();
25473 -+ termios.c_oflag = self.output_flags.bits();
25474 -+ termios.c_cflag = self.control_flags.bits();
25475 -+ termios.c_lflag = self.local_flags.bits();
25476 -+ termios.c_cc = self.control_chars;
25477 -+ }
25478 -+ self.inner.as_ptr()
25479 -+ }
25480 -+
25481 -+ /// Allows for easily creating new `Termios` structs that will be overwritten with real data.
25482 -+ ///
25483 -+ /// This should only be used when the inner libc::termios struct will be overwritten before it's
25484 -+ /// read.
25485 -+ // FIXME: Switch this over to use pub(crate)
25486 -+ #[doc(hidden)]
25487 -+ pub unsafe fn default_uninit() -> Self {
25488 -+ Termios {
25489 -+ inner: RefCell::new(mem::uninitialized()),
25490 -+ input_flags: InputFlags::empty(),
25491 -+ output_flags: OutputFlags::empty(),
25492 -+ control_flags: ControlFlags::empty(),
25493 -+ local_flags: LocalFlags::empty(),
25494 -+ control_chars: [0 as libc::cc_t; NCCS],
25495 -+ }
25496 -+ }
25497 -+
25498 -+ /// Updates the wrapper values from the internal `libc::termios` data structure.
25499 -+ #[doc(hidden)]
25500 -+ pub fn update_wrapper(&mut self) {
25501 -+ let termios = *self.inner.borrow_mut();
25502 -+ self.input_flags = InputFlags::from_bits_truncate(termios.c_iflag);
25503 -+ self.output_flags = OutputFlags::from_bits_truncate(termios.c_oflag);
25504 -+ self.control_flags = ControlFlags::from_bits_truncate(termios.c_cflag);
25505 -+ self.local_flags = LocalFlags::from_bits_truncate(termios.c_lflag);
25506 -+ self.control_chars = termios.c_cc;
25507 -+ }
25508 -+}
25509 -+
25510 -+impl From<libc::termios> for Termios {
25511 -+ fn from(termios: libc::termios) -> Self {
25512 -+ Termios {
25513 -+ inner: RefCell::new(termios),
25514 -+ input_flags: InputFlags::from_bits_truncate(termios.c_iflag),
25515 -+ output_flags: OutputFlags::from_bits_truncate(termios.c_oflag),
25516 -+ control_flags: ControlFlags::from_bits_truncate(termios.c_cflag),
25517 -+ local_flags: LocalFlags::from_bits_truncate(termios.c_lflag),
25518 -+ control_chars: termios.c_cc,
25519 -+ }
25520 -+ }
25521 -+}
25522 -+
25523 -+impl From<Termios> for libc::termios {
25524 -+ fn from(termios: Termios) -> Self {
25525 -+ termios.inner.into_inner()
25526 -+ }
25527 -+}
25528 -+
25529 -+libc_enum!{
25530 -+ /// Baud rates supported by the system.
25531 -+ ///
25532 -+ /// For the BSDs, arbitrary baud rates can be specified by using `u32`s directly instead of this
25533 -+ /// enum.
25534 -+ ///
25535 -+ /// B0 is special and will disable the port.
25536 -+ #[cfg_attr(all(any(target_os = "ios", target_os = "macos"), target_pointer_width = "64"), repr(u64))]
25537 -+ #[cfg_attr(not(all(any(target_os = "ios", target_os = "macos"), target_pointer_width = "64")), repr(u32))]
25538 -+ pub enum BaudRate {
25539 -+ B0,
25540 -+ B50,
25541 -+ B75,
25542 -+ B110,
25543 -+ B134,
25544 -+ B150,
25545 -+ B200,
25546 -+ B300,
25547 -+ B600,
25548 -+ B1200,
25549 -+ B1800,
25550 -+ B2400,
25551 -+ B4800,
25552 -+ #[cfg(any(target_os = "dragonfly",
25553 -+ target_os = "freebsd",
25554 -+ target_os = "macos",
25555 -+ target_os = "netbsd",
25556 -+ target_os = "openbsd"))]
25557 -+ B7200,
25558 -+ B9600,
25559 -+ #[cfg(any(target_os = "dragonfly",
25560 -+ target_os = "freebsd",
25561 -+ target_os = "macos",
25562 -+ target_os = "netbsd",
25563 -+ target_os = "openbsd"))]
25564 -+ B14400,
25565 -+ B19200,
25566 -+ #[cfg(any(target_os = "dragonfly",
25567 -+ target_os = "freebsd",
25568 -+ target_os = "macos",
25569 -+ target_os = "netbsd",
25570 -+ target_os = "openbsd"))]
25571 -+ B28800,
25572 -+ B38400,
25573 -+ B57600,
25574 -+ #[cfg(any(target_os = "dragonfly",
25575 -+ target_os = "freebsd",
25576 -+ target_os = "macos",
25577 -+ target_os = "netbsd",
25578 -+ target_os = "openbsd"))]
25579 -+ B76800,
25580 -+ B115200,
25581 -+ B230400,
25582 -+ #[cfg(any(target_os = "android",
25583 -+ target_os = "freebsd",
25584 -+ target_os = "linux",
25585 -+ target_os = "netbsd"))]
25586 -+ B460800,
25587 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25588 -+ B500000,
25589 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25590 -+ B576000,
25591 -+ #[cfg(any(target_os = "android",
25592 -+ target_os = "freebsd",
25593 -+ target_os = "linux",
25594 -+ target_os = "netbsd"))]
25595 -+ B921600,
25596 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25597 -+ B1000000,
25598 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25599 -+ B1152000,
25600 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25601 -+ B1500000,
25602 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25603 -+ B2000000,
25604 -+ #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
25605 -+ B2500000,
25606 -+ #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
25607 -+ B3000000,
25608 -+ #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
25609 -+ B3500000,
25610 -+ #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
25611 -+ B4000000,
25612 -+ }
25613 -+}
25614 -+
25615 -+impl From<libc::speed_t> for BaudRate {
25616 -+ fn from(s: libc::speed_t) -> BaudRate {
25617 -+
25618 -+ use libc::{B0, B50, B75, B110, B134, B150, B200, B300, B600, B1200, B1800, B2400, B4800,
25619 -+ B9600, B19200, B38400, B57600, B115200, B230400};
25620 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25621 -+ use libc::{B500000, B576000, B1000000, B1152000, B1500000, B2000000};
25622 -+ #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
25623 -+ use libc::{B2500000, B3000000, B3500000, B4000000};
25624 -+ #[cfg(any(target_os = "dragonfly",
25625 -+ target_os = "freebsd",
25626 -+ target_os = "macos",
25627 -+ target_os = "netbsd",
25628 -+ target_os = "openbsd"))]
25629 -+ use libc::{B7200, B14400, B28800, B76800};
25630 -+ #[cfg(any(target_os = "android",
25631 -+ target_os = "freebsd",
25632 -+ target_os = "linux",
25633 -+ target_os = "netbsd"))]
25634 -+ use libc::{B460800, B921600};
25635 -+
25636 -+ match s {
25637 -+ B0 => BaudRate::B0,
25638 -+ B50 => BaudRate::B50,
25639 -+ B75 => BaudRate::B75,
25640 -+ B110 => BaudRate::B110,
25641 -+ B134 => BaudRate::B134,
25642 -+ B150 => BaudRate::B150,
25643 -+ B200 => BaudRate::B200,
25644 -+ B300 => BaudRate::B300,
25645 -+ B600 => BaudRate::B600,
25646 -+ B1200 => BaudRate::B1200,
25647 -+ B1800 => BaudRate::B1800,
25648 -+ B2400 => BaudRate::B2400,
25649 -+ B4800 => BaudRate::B4800,
25650 -+ #[cfg(any(target_os = "dragonfly",
25651 -+ target_os = "freebsd",
25652 -+ target_os = "macos",
25653 -+ target_os = "netbsd",
25654 -+ target_os = "openbsd"))]
25655 -+ B7200 => BaudRate::B7200,
25656 -+ B9600 => BaudRate::B9600,
25657 -+ #[cfg(any(target_os = "dragonfly",
25658 -+ target_os = "freebsd",
25659 -+ target_os = "macos",
25660 -+ target_os = "netbsd",
25661 -+ target_os = "openbsd"))]
25662 -+ B14400 => BaudRate::B14400,
25663 -+ B19200 => BaudRate::B19200,
25664 -+ #[cfg(any(target_os = "dragonfly",
25665 -+ target_os = "freebsd",
25666 -+ target_os = "macos",
25667 -+ target_os = "netbsd",
25668 -+ target_os = "openbsd"))]
25669 -+ B28800 => BaudRate::B28800,
25670 -+ B38400 => BaudRate::B38400,
25671 -+ B57600 => BaudRate::B57600,
25672 -+ #[cfg(any(target_os = "dragonfly",
25673 -+ target_os = "freebsd",
25674 -+ target_os = "macos",
25675 -+ target_os = "netbsd",
25676 -+ target_os = "openbsd"))]
25677 -+ B76800 => BaudRate::B76800,
25678 -+ B115200 => BaudRate::B115200,
25679 -+ B230400 => BaudRate::B230400,
25680 -+ #[cfg(any(target_os = "android",
25681 -+ target_os = "freebsd",
25682 -+ target_os = "linux",
25683 -+ target_os = "netbsd"))]
25684 -+ B460800 => BaudRate::B460800,
25685 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25686 -+ B500000 => BaudRate::B500000,
25687 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25688 -+ B576000 => BaudRate::B576000,
25689 -+ #[cfg(any(target_os = "android",
25690 -+ target_os = "freebsd",
25691 -+ target_os = "linux",
25692 -+ target_os = "netbsd"))]
25693 -+ B921600 => BaudRate::B921600,
25694 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25695 -+ B1000000 => BaudRate::B1000000,
25696 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25697 -+ B1152000 => BaudRate::B1152000,
25698 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25699 -+ B1500000 => BaudRate::B1500000,
25700 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25701 -+ B2000000 => BaudRate::B2000000,
25702 -+ #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
25703 -+ B2500000 => BaudRate::B2500000,
25704 -+ #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
25705 -+ B3000000 => BaudRate::B3000000,
25706 -+ #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
25707 -+ B3500000 => BaudRate::B3500000,
25708 -+ #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
25709 -+ B4000000 => BaudRate::B4000000,
25710 -+ b => unreachable!("Invalid baud constant: {}", b),
25711 -+ }
25712 -+ }
25713 -+}
25714 -+
25715 -+// TODO: Include `TryFrom<u32> for BaudRate` once that API stabilizes
25716 -+#[cfg(any(target_os = "freebsd",
25717 -+ target_os = "dragonfly",
25718 -+ target_os = "ios",
25719 -+ target_os = "macos",
25720 -+ target_os = "netbsd",
25721 -+ target_os = "openbsd"))]
25722 -+impl From<BaudRate> for u32 {
25723 -+ fn from(b: BaudRate) -> u32 {
25724 -+ b as u32
25725 -+ }
25726 -+}
25727 -+
25728 -+// TODO: Add TCSASOFT, which will require treating this as a bitfield.
25729 -+libc_enum! {
25730 -+ /// Specify when a port configuration change should occur.
25731 -+ ///
25732 -+ /// Used as an argument to `tcsetattr()`
25733 -+ #[repr(i32)]
25734 -+ pub enum SetArg {
25735 -+ /// The change will occur immediately
25736 -+ TCSANOW,
25737 -+ /// The change occurs after all output has been written
25738 -+ TCSADRAIN,
25739 -+ /// Same as `TCSADRAIN`, but will also flush the input buffer
25740 -+ TCSAFLUSH,
25741 -+ }
25742 -+}
25743 -+
25744 -+libc_enum! {
25745 -+ /// Specify a combination of the input and output buffers to flush
25746 -+ ///
25747 -+ /// Used as an argument to `tcflush()`.
25748 -+ #[repr(i32)]
25749 -+ pub enum FlushArg {
25750 -+ /// Flush data that was received but not read
25751 -+ TCIFLUSH,
25752 -+ /// Flush data written but not transmitted
25753 -+ TCOFLUSH,
25754 -+ /// Flush both received data not read and written data not transmitted
25755 -+ TCIOFLUSH,
25756 -+ }
25757 -+}
25758 -+
25759 -+libc_enum! {
25760 -+ /// Specify how transmission flow should be altered
25761 -+ ///
25762 -+ /// Used as an argument to `tcflow()`.
25763 -+ #[repr(i32)]
25764 -+ pub enum FlowArg {
25765 -+ /// Suspend transmission
25766 -+ TCOOFF,
25767 -+ /// Resume transmission
25768 -+ TCOON,
25769 -+ /// Transmit a STOP character, which should disable a connected terminal device
25770 -+ TCIOFF,
25771 -+ /// Transmit a START character, which should re-enable a connected terminal device
25772 -+ TCION,
25773 -+ }
25774 -+}
25775 -+
25776 -+// TODO: Make this usable directly as a slice index.
25777 -+libc_enum! {
25778 -+ /// Indices into the `termios.c_cc` array for special characters.
25779 -+ #[repr(usize)]
25780 -+ pub enum SpecialCharacterIndices {
25781 -+ VDISCARD,
25782 -+ #[cfg(any(target_os = "dragonfly",
25783 -+ target_os = "freebsd",
25784 -+ target_os = "macos",
25785 -+ target_os = "netbsd",
25786 -+ target_os = "openbsd"))]
25787 -+ VDSUSP,
25788 -+ VEOF,
25789 -+ VEOL,
25790 -+ VEOL2,
25791 -+ VERASE,
25792 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
25793 -+ VERASE2,
25794 -+ VINTR,
25795 -+ VKILL,
25796 -+ VLNEXT,
25797 -+ #[cfg(not(all(target_os = "linux", target_arch = "sparc64")))]
25798 -+ VMIN,
25799 -+ VQUIT,
25800 -+ VREPRINT,
25801 -+ VSTART,
25802 -+ #[cfg(any(target_os = "dragonfly",
25803 -+ target_os = "freebsd",
25804 -+ target_os = "macos",
25805 -+ target_os = "netbsd",
25806 -+ target_os = "openbsd"))]
25807 -+ VSTATUS,
25808 -+ VSTOP,
25809 -+ VSUSP,
25810 -+ #[cfg(target_os = "linux")]
25811 -+ VSWTC,
25812 -+ #[cfg(target_os = "haiku")]
25813 -+ VSWTCH,
25814 -+ #[cfg(not(all(target_os = "linux", target_arch = "sparc64")))]
25815 -+ VTIME,
25816 -+ VWERASE,
25817 -+ #[cfg(target_os = "dragonfly")]
25818 -+ VCHECKPT,
25819 -+ }
25820 -+}
25821 -+
25822 -+pub use libc::NCCS;
25823 -+#[cfg(any(target_os = "dragonfly",
25824 -+ target_os = "freebsd",
25825 -+ target_os = "linux",
25826 -+ target_os = "macos",
25827 -+ target_os = "netbsd",
25828 -+ target_os = "openbsd"))]
25829 -+pub use libc::_POSIX_VDISABLE;
25830 -+
25831 -+libc_bitflags! {
25832 -+ /// Flags for configuring the input mode of a terminal
25833 -+ pub struct InputFlags: tcflag_t {
25834 -+ IGNBRK;
25835 -+ BRKINT;
25836 -+ IGNPAR;
25837 -+ PARMRK;
25838 -+ INPCK;
25839 -+ ISTRIP;
25840 -+ INLCR;
25841 -+ IGNCR;
25842 -+ ICRNL;
25843 -+ IXON;
25844 -+ IXOFF;
25845 -+ IXANY;
25846 -+ IMAXBEL;
25847 -+ #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
25848 -+ IUTF8;
25849 -+ }
25850 -+}
25851 -+
25852 -+libc_bitflags! {
25853 -+ /// Flags for configuring the output mode of a terminal
25854 -+ pub struct OutputFlags: tcflag_t {
25855 -+ OPOST;
25856 -+ #[cfg(any(target_os = "android",
25857 -+ target_os = "haiku",
25858 -+ target_os = "linux",
25859 -+ target_os = "openbsd"))]
25860 -+ OLCUC;
25861 -+ ONLCR;
25862 -+ OCRNL as tcflag_t;
25863 -+ ONOCR as tcflag_t;
25864 -+ ONLRET as tcflag_t;
25865 -+ #[cfg(any(target_os = "android",
25866 -+ target_os = "haiku",
25867 -+ target_os = "ios",
25868 -+ target_os = "linux",
25869 -+ target_os = "macos"))]
25870 -+ OFILL as tcflag_t;
25871 -+ #[cfg(any(target_os = "android",
25872 -+ target_os = "haiku",
25873 -+ target_os = "ios",
25874 -+ target_os = "linux",
25875 -+ target_os = "macos"))]
25876 -+ OFDEL as tcflag_t;
25877 -+ #[cfg(any(target_os = "android",
25878 -+ target_os = "haiku",
25879 -+ target_os = "ios",
25880 -+ target_os = "linux",
25881 -+ target_os = "macos"))]
25882 -+ NL0 as tcflag_t;
25883 -+ #[cfg(any(target_os = "android",
25884 -+ target_os = "haiku",
25885 -+ target_os = "ios",
25886 -+ target_os = "linux",
25887 -+ target_os = "macos"))]
25888 -+ NL1 as tcflag_t;
25889 -+ #[cfg(any(target_os = "android",
25890 -+ target_os = "haiku",
25891 -+ target_os = "ios",
25892 -+ target_os = "linux",
25893 -+ target_os = "macos"))]
25894 -+ CR0 as tcflag_t;
25895 -+ #[cfg(any(target_os = "android",
25896 -+ target_os = "haiku",
25897 -+ target_os = "ios",
25898 -+ target_os = "linux",
25899 -+ target_os = "macos"))]
25900 -+ CR1 as tcflag_t;
25901 -+ #[cfg(any(target_os = "android",
25902 -+ target_os = "haiku",
25903 -+ target_os = "ios",
25904 -+ target_os = "linux",
25905 -+ target_os = "macos"))]
25906 -+ CR2 as tcflag_t;
25907 -+ #[cfg(any(target_os = "android",
25908 -+ target_os = "haiku",
25909 -+ target_os = "ios",
25910 -+ target_os = "linux",
25911 -+ target_os = "macos"))]
25912 -+ CR3 as tcflag_t;
25913 -+ #[cfg(any(target_os = "android",
25914 -+ target_os = "freebsd",
25915 -+ target_os = "haiku",
25916 -+ target_os = "ios",
25917 -+ target_os = "linux",
25918 -+ target_os = "macos"))]
25919 -+ TAB0 as tcflag_t;
25920 -+ #[cfg(any(target_os = "android",
25921 -+ target_os = "haiku",
25922 -+ target_os = "ios",
25923 -+ target_os = "linux",
25924 -+ target_os = "macos"))]
25925 -+ TAB1 as tcflag_t;
25926 -+ #[cfg(any(target_os = "android",
25927 -+ target_os = "haiku",
25928 -+ target_os = "ios",
25929 -+ target_os = "linux",
25930 -+ target_os = "macos"))]
25931 -+ TAB2 as tcflag_t;
25932 -+ #[cfg(any(target_os = "android",
25933 -+ target_os = "freebsd",
25934 -+ target_os = "haiku",
25935 -+ target_os = "ios",
25936 -+ target_os = "linux",
25937 -+ target_os = "macos"))]
25938 -+ TAB3 as tcflag_t;
25939 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
25940 -+ XTABS;
25941 -+ #[cfg(any(target_os = "android",
25942 -+ target_os = "haiku",
25943 -+ target_os = "ios",
25944 -+ target_os = "linux",
25945 -+ target_os = "macos"))]
25946 -+ BS0 as tcflag_t;
25947 -+ #[cfg(any(target_os = "android",
25948 -+ target_os = "haiku",
25949 -+ target_os = "ios",
25950 -+ target_os = "linux",
25951 -+ target_os = "macos"))]
25952 -+ BS1 as tcflag_t;
25953 -+ #[cfg(any(target_os = "android",
25954 -+ target_os = "haiku",
25955 -+ target_os = "ios",
25956 -+ target_os = "linux",
25957 -+ target_os = "macos"))]
25958 -+ VT0 as tcflag_t;
25959 -+ #[cfg(any(target_os = "android",
25960 -+ target_os = "haiku",
25961 -+ target_os = "ios",
25962 -+ target_os = "linux",
25963 -+ target_os = "macos"))]
25964 -+ VT1 as tcflag_t;
25965 -+ #[cfg(any(target_os = "android",
25966 -+ target_os = "haiku",
25967 -+ target_os = "ios",
25968 -+ target_os = "linux",
25969 -+ target_os = "macos"))]
25970 -+ FF0 as tcflag_t;
25971 -+ #[cfg(any(target_os = "android",
25972 -+ target_os = "haiku",
25973 -+ target_os = "ios",
25974 -+ target_os = "linux",
25975 -+ target_os = "macos"))]
25976 -+ FF1 as tcflag_t;
25977 -+ #[cfg(any(target_os = "freebsd",
25978 -+ target_os = "dragonfly",
25979 -+ target_os = "ios",
25980 -+ target_os = "macos",
25981 -+ target_os = "netbsd",
25982 -+ target_os = "openbsd"))]
25983 -+ OXTABS;
25984 -+ #[cfg(any(target_os = "freebsd",
25985 -+ target_os = "dragonfly",
25986 -+ target_os = "macos",
25987 -+ target_os = "netbsd",
25988 -+ target_os = "openbsd"))]
25989 -+ ONOEOT as tcflag_t;
25990 -+
25991 -+ // Bitmasks for use with OutputFlags to select specific settings
25992 -+ // These should be moved to be a mask once https://github.com/rust-lang-nursery/bitflags/issues/110
25993 -+ // is resolved.
25994 -+
25995 -+ #[cfg(any(target_os = "android",
25996 -+ target_os = "haiku",
25997 -+ target_os = "ios",
25998 -+ target_os = "linux",
25999 -+ target_os = "macos"))]
26000 -+ NLDLY as tcflag_t; // FIXME: Datatype needs to be corrected in libc for mac
26001 -+ #[cfg(any(target_os = "android",
26002 -+ target_os = "haiku",
26003 -+ target_os = "ios",
26004 -+ target_os = "linux",
26005 -+ target_os = "macos"))]
26006 -+ CRDLY as tcflag_t;
26007 -+ #[cfg(any(target_os = "android",
26008 -+ target_os = "freebsd",
26009 -+ target_os = "haiku",
26010 -+ target_os = "ios",
26011 -+ target_os = "linux",
26012 -+ target_os = "macos"))]
26013 -+ TABDLY as tcflag_t;
26014 -+ #[cfg(any(target_os = "android",
26015 -+ target_os = "haiku",
26016 -+ target_os = "ios",
26017 -+ target_os = "linux",
26018 -+ target_os = "macos"))]
26019 -+ BSDLY as tcflag_t;
26020 -+ #[cfg(any(target_os = "android",
26021 -+ target_os = "haiku",
26022 -+ target_os = "ios",
26023 -+ target_os = "linux",
26024 -+ target_os = "macos"))]
26025 -+ VTDLY as tcflag_t;
26026 -+ #[cfg(any(target_os = "android",
26027 -+ target_os = "haiku",
26028 -+ target_os = "ios",
26029 -+ target_os = "linux",
26030 -+ target_os = "macos"))]
26031 -+ FFDLY as tcflag_t;
26032 -+ }
26033 -+}
26034 -+
26035 -+libc_bitflags! {
26036 -+ /// Flags for setting the control mode of a terminal
26037 -+ pub struct ControlFlags: tcflag_t {
26038 -+ #[cfg(any(target_os = "dragonfly",
26039 -+ target_os = "freebsd",
26040 -+ target_os = "ios",
26041 -+ target_os = "macos",
26042 -+ target_os = "netbsd",
26043 -+ target_os = "openbsd"))]
26044 -+ CIGNORE;
26045 -+ CS5;
26046 -+ CS6;
26047 -+ CS7;
26048 -+ CS8;
26049 -+ CSTOPB;
26050 -+ CREAD;
26051 -+ PARENB;
26052 -+ PARODD;
26053 -+ HUPCL;
26054 -+ CLOCAL;
26055 -+ CRTSCTS;
26056 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
26057 -+ CBAUD;
26058 -+ #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "mips"))))]
26059 -+ CMSPAR;
26060 -+ #[cfg(any(target_os = "android",
26061 -+ all(target_os = "linux",
26062 -+ not(any(target_arch = "powerpc", target_arch = "powerpc64")))))]
26063 -+ CIBAUD;
26064 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
26065 -+ CBAUDEX;
26066 -+ #[cfg(any(target_os = "dragonfly",
26067 -+ target_os = "freebsd",
26068 -+ target_os = "macos",
26069 -+ target_os = "netbsd",
26070 -+ target_os = "openbsd"))]
26071 -+ MDMBUF;
26072 -+ #[cfg(any(target_os = "netbsd", target_os = "openbsd"))]
26073 -+ CHWFLOW;
26074 -+ #[cfg(any(target_os = "dragonfly",
26075 -+ target_os = "freebsd",
26076 -+ target_os = "netbsd",
26077 -+ target_os = "openbsd"))]
26078 -+ CCTS_OFLOW;
26079 -+ #[cfg(any(target_os = "dragonfly",
26080 -+ target_os = "freebsd",
26081 -+ target_os = "netbsd",
26082 -+ target_os = "openbsd"))]
26083 -+ CRTS_IFLOW;
26084 -+ #[cfg(any(target_os = "dragonfly",
26085 -+ target_os = "freebsd"))]
26086 -+ CDTR_IFLOW;
26087 -+ #[cfg(any(target_os = "dragonfly",
26088 -+ target_os = "freebsd"))]
26089 -+ CDSR_OFLOW;
26090 -+ #[cfg(any(target_os = "dragonfly",
26091 -+ target_os = "freebsd"))]
26092 -+ CCAR_OFLOW;
26093 -+
26094 -+ // Bitmasks for use with ControlFlags to select specific settings
26095 -+ // These should be moved to be a mask once https://github.com/rust-lang-nursery/bitflags/issues/110
26096 -+ // is resolved.
26097 -+
26098 -+ CSIZE;
26099 -+ }
26100 -+}
26101 -+
26102 -+libc_bitflags! {
26103 -+ /// Flags for setting any local modes
26104 -+ pub struct LocalFlags: tcflag_t {
26105 -+ ECHOKE;
26106 -+ ECHOE;
26107 -+ ECHOK;
26108 -+ ECHO;
26109 -+ ECHONL;
26110 -+ ECHOPRT;
26111 -+ ECHOCTL;
26112 -+ ISIG;
26113 -+ ICANON;
26114 -+ #[cfg(any(target_os = "freebsd",
26115 -+ target_os = "dragonfly",
26116 -+ target_os = "ios",
26117 -+ target_os = "macos",
26118 -+ target_os = "netbsd",
26119 -+ target_os = "openbsd"))]
26120 -+ ALTWERASE;
26121 -+ IEXTEN;
26122 -+ EXTPROC;
26123 -+ TOSTOP;
26124 -+ FLUSHO;
26125 -+ #[cfg(any(target_os = "freebsd",
26126 -+ target_os = "dragonfly",
26127 -+ target_os = "ios",
26128 -+ target_os = "macos",
26129 -+ target_os = "netbsd",
26130 -+ target_os = "openbsd"))]
26131 -+ NOKERNINFO;
26132 -+ PENDIN;
26133 -+ NOFLSH;
26134 -+ }
26135 -+}
26136 -+
26137 -+cfg_if!{
26138 -+ if #[cfg(any(target_os = "freebsd",
26139 -+ target_os = "dragonfly",
26140 -+ target_os = "ios",
26141 -+ target_os = "macos",
26142 -+ target_os = "netbsd",
26143 -+ target_os = "openbsd"))] {
26144 -+ /// Get input baud rate (see
26145 -+ /// [cfgetispeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetispeed.html)).
26146 -+ ///
26147 -+ /// `cfgetispeed()` extracts the input baud rate from the given `Termios` structure.
26148 -+ pub fn cfgetispeed(termios: &Termios) -> u32 {
26149 -+ let inner_termios = termios.get_libc_termios();
26150 -+ unsafe { libc::cfgetispeed(&*inner_termios) as u32 }
26151 -+ }
26152 -+
26153 -+ /// Get output baud rate (see
26154 -+ /// [cfgetospeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetospeed.html)).
26155 -+ ///
26156 -+ /// `cfgetospeed()` extracts the output baud rate from the given `Termios` structure.
26157 -+ pub fn cfgetospeed(termios: &Termios) -> u32 {
26158 -+ let inner_termios = termios.get_libc_termios();
26159 -+ unsafe { libc::cfgetospeed(&*inner_termios) as u32 }
26160 -+ }
26161 -+
26162 -+ /// Set input baud rate (see
26163 -+ /// [cfsetispeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetispeed.html)).
26164 -+ ///
26165 -+ /// `cfsetispeed()` sets the intput baud rate in the given `Termios` structure.
26166 -+ pub fn cfsetispeed<T: Into<u32>>(termios: &mut Termios, baud: T) -> Result<()> {
26167 -+ let inner_termios = unsafe { termios.get_libc_termios_mut() };
26168 -+ let res = unsafe { libc::cfsetispeed(inner_termios, baud.into() as libc::speed_t) };
26169 -+ termios.update_wrapper();
26170 -+ Errno::result(res).map(drop)
26171 -+ }
26172 -+
26173 -+ /// Set output baud rate (see
26174 -+ /// [cfsetospeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetospeed.html)).
26175 -+ ///
26176 -+ /// `cfsetospeed()` sets the output baud rate in the given termios structure.
26177 -+ pub fn cfsetospeed<T: Into<u32>>(termios: &mut Termios, baud: T) -> Result<()> {
26178 -+ let inner_termios = unsafe { termios.get_libc_termios_mut() };
26179 -+ let res = unsafe { libc::cfsetospeed(inner_termios, baud.into() as libc::speed_t) };
26180 -+ termios.update_wrapper();
26181 -+ Errno::result(res).map(drop)
26182 -+ }
26183 -+
26184 -+ /// Set both the input and output baud rates (see
26185 -+ /// [termios(3)](https://www.freebsd.org/cgi/man.cgi?query=cfsetspeed)).
26186 -+ ///
26187 -+ /// `cfsetspeed()` sets the input and output baud rate in the given termios structure. Note that
26188 -+ /// this is part of the 4.4BSD standard and not part of POSIX.
26189 -+ pub fn cfsetspeed<T: Into<u32>>(termios: &mut Termios, baud: T) -> Result<()> {
26190 -+ let inner_termios = unsafe { termios.get_libc_termios_mut() };
26191 -+ let res = unsafe { libc::cfsetspeed(inner_termios, baud.into() as libc::speed_t) };
26192 -+ termios.update_wrapper();
26193 -+ Errno::result(res).map(drop)
26194 -+ }
26195 -+ } else {
26196 -+ /// Get input baud rate (see
26197 -+ /// [cfgetispeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetispeed.html)).
26198 -+ ///
26199 -+ /// `cfgetispeed()` extracts the input baud rate from the given `Termios` structure.
26200 -+ pub fn cfgetispeed(termios: &Termios) -> BaudRate {
26201 -+ let inner_termios = termios.get_libc_termios();
26202 -+ unsafe { libc::cfgetispeed(&*inner_termios) }.into()
26203 -+ }
26204 -+
26205 -+ /// Get output baud rate (see
26206 -+ /// [cfgetospeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetospeed.html)).
26207 -+ ///
26208 -+ /// `cfgetospeed()` extracts the output baud rate from the given `Termios` structure.
26209 -+ pub fn cfgetospeed(termios: &Termios) -> BaudRate {
26210 -+ let inner_termios = termios.get_libc_termios();
26211 -+ unsafe { libc::cfgetospeed(&*inner_termios) }.into()
26212 -+ }
26213 -+
26214 -+ /// Set input baud rate (see
26215 -+ /// [cfsetispeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetispeed.html)).
26216 -+ ///
26217 -+ /// `cfsetispeed()` sets the intput baud rate in the given `Termios` structure.
26218 -+ pub fn cfsetispeed(termios: &mut Termios, baud: BaudRate) -> Result<()> {
26219 -+ let inner_termios = unsafe { termios.get_libc_termios_mut() };
26220 -+ let res = unsafe { libc::cfsetispeed(inner_termios, baud as libc::speed_t) };
26221 -+ termios.update_wrapper();
26222 -+ Errno::result(res).map(drop)
26223 -+ }
26224 -+
26225 -+ /// Set output baud rate (see
26226 -+ /// [cfsetospeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetospeed.html)).
26227 -+ ///
26228 -+ /// `cfsetospeed()` sets the output baud rate in the given `Termios` structure.
26229 -+ pub fn cfsetospeed(termios: &mut Termios, baud: BaudRate) -> Result<()> {
26230 -+ let inner_termios = unsafe { termios.get_libc_termios_mut() };
26231 -+ let res = unsafe { libc::cfsetospeed(inner_termios, baud as libc::speed_t) };
26232 -+ termios.update_wrapper();
26233 -+ Errno::result(res).map(drop)
26234 -+ }
26235 -+
26236 -+ /// Set both the input and output baud rates (see
26237 -+ /// [termios(3)](https://www.freebsd.org/cgi/man.cgi?query=cfsetspeed)).
26238 -+ ///
26239 -+ /// `cfsetspeed()` sets the input and output baud rate in the given `Termios` structure. Note that
26240 -+ /// this is part of the 4.4BSD standard and not part of POSIX.
26241 -+ pub fn cfsetspeed(termios: &mut Termios, baud: BaudRate) -> Result<()> {
26242 -+ let inner_termios = unsafe { termios.get_libc_termios_mut() };
26243 -+ let res = unsafe { libc::cfsetspeed(inner_termios, baud as libc::speed_t) };
26244 -+ termios.update_wrapper();
26245 -+ Errno::result(res).map(drop)
26246 -+ }
26247 -+ }
26248 -+}
26249 -+
26250 -+/// Configures the port to something like the "raw" mode of the old Version 7 terminal driver (see
26251 -+/// [termios(3)](http://man7.org/linux/man-pages/man3/termios.3.html)).
26252 -+///
26253 -+/// `cfmakeraw()` configures the termios structure such that input is available character-by-
26254 -+/// character, echoing is disabled, and all special input and output processing is disabled. Note
26255 -+/// that this is a non-standard function, but is available on Linux and BSDs.
26256 -+pub fn cfmakeraw(termios: &mut Termios) {
26257 -+ let inner_termios = unsafe { termios.get_libc_termios_mut() };
26258 -+ unsafe {
26259 -+ libc::cfmakeraw(inner_termios);
26260 -+ }
26261 -+ termios.update_wrapper();
26262 -+}
26263 -+
26264 -+/// Configures the port to "sane" mode (like the configuration of a newly created terminal) (see
26265 -+/// [tcsetattr(3)](https://www.freebsd.org/cgi/man.cgi?query=tcsetattr)).
26266 -+///
26267 -+/// Note that this is a non-standard function, available on FreeBSD.
26268 -+#[cfg(target_os = "freebsd")]
26269 -+pub fn cfmakesane(termios: &mut Termios) {
26270 -+ let inner_termios = unsafe { termios.get_libc_termios_mut() };
26271 -+ unsafe {
26272 -+ libc::cfmakesane(inner_termios);
26273 -+ }
26274 -+ termios.update_wrapper();
26275 -+}
26276 -+
26277 -+/// Return the configuration of a port
26278 -+/// [tcgetattr(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetattr.html)).
26279 -+///
26280 -+/// `tcgetattr()` returns a `Termios` structure with the current configuration for a port. Modifying
26281 -+/// this structure *will not* reconfigure the port, instead the modifications should be done to
26282 -+/// the `Termios` structure and then the port should be reconfigured using `tcsetattr()`.
26283 -+pub fn tcgetattr(fd: RawFd) -> Result<Termios> {
26284 -+ let mut termios: libc::termios = unsafe { mem::uninitialized() };
26285 -+
26286 -+ let res = unsafe { libc::tcgetattr(fd, &mut termios) };
26287 -+
26288 -+ Errno::result(res)?;
26289 -+
26290 -+ Ok(termios.into())
26291 -+}
26292 -+
26293 -+/// Set the configuration for a terminal (see
26294 -+/// [tcsetattr(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsetattr.html)).
26295 -+///
26296 -+/// `tcsetattr()` reconfigures the given port based on a given `Termios` structure. This change
26297 -+/// takes affect at a time specified by `actions`. Note that this function may return success if
26298 -+/// *any* of the parameters were successfully set, not only if all were set successfully.
26299 -+pub fn tcsetattr(fd: RawFd, actions: SetArg, termios: &Termios) -> Result<()> {
26300 -+ let inner_termios = termios.get_libc_termios();
26301 -+ Errno::result(unsafe { libc::tcsetattr(fd, actions as c_int, &*inner_termios) }).map(drop)
26302 -+}
26303 -+
26304 -+/// Block until all output data is written (see
26305 -+/// [tcdrain(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcdrain.html)).
26306 -+pub fn tcdrain(fd: RawFd) -> Result<()> {
26307 -+ Errno::result(unsafe { libc::tcdrain(fd) }).map(drop)
26308 -+}
26309 -+
26310 -+/// Suspend or resume the transmission or reception of data (see
26311 -+/// [tcflow(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcflow.html)).
26312 -+///
26313 -+/// `tcflow()` suspends of resumes the transmission or reception of data for the given port
26314 -+/// depending on the value of `action`.
26315 -+pub fn tcflow(fd: RawFd, action: FlowArg) -> Result<()> {
26316 -+ Errno::result(unsafe { libc::tcflow(fd, action as c_int) }).map(drop)
26317 -+}
26318 -+
26319 -+/// Discard data in the output or input queue (see
26320 -+/// [tcflush(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcflush.html)).
26321 -+///
26322 -+/// `tcflush()` will discard data for a terminal port in the input queue, output queue, or both
26323 -+/// depending on the value of `action`.
26324 -+pub fn tcflush(fd: RawFd, action: FlushArg) -> Result<()> {
26325 -+ Errno::result(unsafe { libc::tcflush(fd, action as c_int) }).map(drop)
26326 -+}
26327 -+
26328 -+/// Send a break for a specific duration (see
26329 -+/// [tcsendbreak(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsendbreak.html)).
26330 -+///
26331 -+/// When using asynchronous data transmission `tcsendbreak()` will transmit a continuous stream
26332 -+/// of zero-valued bits for an implementation-defined duration.
26333 -+pub fn tcsendbreak(fd: RawFd, duration: c_int) -> Result<()> {
26334 -+ Errno::result(unsafe { libc::tcsendbreak(fd, duration) }).map(drop)
26335 -+}
26336 -+
26337 -+/// Get the session controlled by the given terminal (see
26338 -+/// [tcgetsid(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetsid.html)).
26339 -+pub fn tcgetsid(fd: RawFd) -> Result<Pid> {
26340 -+ let res = unsafe { libc::tcgetsid(fd) };
26341 -+
26342 -+ Errno::result(res).map(Pid::from_raw)
26343 -+}
26344 -diff --git a/third_party/rust/nix-0.15.0/src/sys/time.rs b/third_party/rust/nix-0.15.0/src/sys/time.rs
26345 -new file mode 100644
26346 -index 0000000000000..3ad57543b18a7
26347 ---- /dev/null
26348 -+++ b/third_party/rust/nix-0.15.0/src/sys/time.rs
26349 -@@ -0,0 +1,542 @@
26350 -+use std::{cmp, fmt, ops};
26351 -+use std::convert::From;
26352 -+use libc::{c_long, timespec, timeval};
26353 -+pub use libc::{time_t, suseconds_t};
26354 -+
26355 -+pub trait TimeValLike: Sized {
26356 -+ #[inline]
26357 -+ fn zero() -> Self {
26358 -+ Self::seconds(0)
26359 -+ }
26360 -+
26361 -+ #[inline]
26362 -+ fn hours(hours: i64) -> Self {
26363 -+ let secs = hours.checked_mul(SECS_PER_HOUR)
26364 -+ .expect("TimeValLike::hours ouf of bounds");
26365 -+ Self::seconds(secs)
26366 -+ }
26367 -+
26368 -+ #[inline]
26369 -+ fn minutes(minutes: i64) -> Self {
26370 -+ let secs = minutes.checked_mul(SECS_PER_MINUTE)
26371 -+ .expect("TimeValLike::minutes out of bounds");
26372 -+ Self::seconds(secs)
26373 -+ }
26374 -+
26375 -+ fn seconds(seconds: i64) -> Self;
26376 -+ fn milliseconds(milliseconds: i64) -> Self;
26377 -+ fn microseconds(microseconds: i64) -> Self;
26378 -+ fn nanoseconds(nanoseconds: i64) -> Self;
26379 -+
26380 -+ #[inline]
26381 -+ fn num_hours(&self) -> i64 {
26382 -+ self.num_seconds() / 3600
26383 -+ }
26384 -+
26385 -+ #[inline]
26386 -+ fn num_minutes(&self) -> i64 {
26387 -+ self.num_seconds() / 60
26388 -+ }
26389 -+
26390 -+ fn num_seconds(&self) -> i64;
26391 -+ fn num_milliseconds(&self) -> i64;
26392 -+ fn num_microseconds(&self) -> i64;
26393 -+ fn num_nanoseconds(&self) -> i64;
26394 -+}
26395 -+
26396 -+#[repr(C)]
26397 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
26398 -+pub struct TimeSpec(timespec);
26399 -+
26400 -+const NANOS_PER_SEC: i64 = 1_000_000_000;
26401 -+const SECS_PER_MINUTE: i64 = 60;
26402 -+const SECS_PER_HOUR: i64 = 3600;
26403 -+
26404 -+#[cfg(target_pointer_width = "64")]
26405 -+const TS_MAX_SECONDS: i64 = (::std::i64::MAX / NANOS_PER_SEC) - 1;
26406 -+
26407 -+#[cfg(target_pointer_width = "32")]
26408 -+const TS_MAX_SECONDS: i64 = ::std::isize::MAX as i64;
26409 -+
26410 -+const TS_MIN_SECONDS: i64 = -TS_MAX_SECONDS;
26411 -+
26412 -+
26413 -+impl AsRef<timespec> for TimeSpec {
26414 -+ fn as_ref(&self) -> &timespec {
26415 -+ &self.0
26416 -+ }
26417 -+}
26418 -+
26419 -+impl Ord for TimeSpec {
26420 -+ // The implementation of cmp is simplified by assuming that the struct is
26421 -+ // normalized. That is, tv_nsec must always be within [0, 1_000_000_000)
26422 -+ fn cmp(&self, other: &TimeSpec) -> cmp::Ordering {
26423 -+ if self.tv_sec() == other.tv_sec() {
26424 -+ self.tv_nsec().cmp(&other.tv_nsec())
26425 -+ } else {
26426 -+ self.tv_sec().cmp(&other.tv_sec())
26427 -+ }
26428 -+ }
26429 -+}
26430 -+
26431 -+impl PartialOrd for TimeSpec {
26432 -+ fn partial_cmp(&self, other: &TimeSpec) -> Option<cmp::Ordering> {
26433 -+ Some(self.cmp(other))
26434 -+ }
26435 -+}
26436 -+
26437 -+impl TimeValLike for TimeSpec {
26438 -+ #[inline]
26439 -+ fn seconds(seconds: i64) -> TimeSpec {
26440 -+ assert!(seconds >= TS_MIN_SECONDS && seconds <= TS_MAX_SECONDS,
26441 -+ "TimeSpec out of bounds; seconds={}", seconds);
26442 -+ TimeSpec(timespec {tv_sec: seconds as time_t, tv_nsec: 0 })
26443 -+ }
26444 -+
26445 -+ #[inline]
26446 -+ fn milliseconds(milliseconds: i64) -> TimeSpec {
26447 -+ let nanoseconds = milliseconds.checked_mul(1_000_000)
26448 -+ .expect("TimeSpec::milliseconds out of bounds");
26449 -+
26450 -+ TimeSpec::nanoseconds(nanoseconds)
26451 -+ }
26452 -+
26453 -+ /// Makes a new `TimeSpec` with given number of microseconds.
26454 -+ #[inline]
26455 -+ fn microseconds(microseconds: i64) -> TimeSpec {
26456 -+ let nanoseconds = microseconds.checked_mul(1_000)
26457 -+ .expect("TimeSpec::milliseconds out of bounds");
26458 -+
26459 -+ TimeSpec::nanoseconds(nanoseconds)
26460 -+ }
26461 -+
26462 -+ /// Makes a new `TimeSpec` with given number of nanoseconds.
26463 -+ #[inline]
26464 -+ fn nanoseconds(nanoseconds: i64) -> TimeSpec {
26465 -+ let (secs, nanos) = div_mod_floor_64(nanoseconds, NANOS_PER_SEC);
26466 -+ assert!(secs >= TS_MIN_SECONDS && secs <= TS_MAX_SECONDS,
26467 -+ "TimeSpec out of bounds");
26468 -+ TimeSpec(timespec {tv_sec: secs as time_t,
26469 -+ tv_nsec: nanos as c_long })
26470 -+ }
26471 -+
26472 -+ fn num_seconds(&self) -> i64 {
26473 -+ if self.tv_sec() < 0 && self.tv_nsec() > 0 {
26474 -+ (self.tv_sec() + 1) as i64
26475 -+ } else {
26476 -+ self.tv_sec() as i64
26477 -+ }
26478 -+ }
26479 -+
26480 -+ fn num_milliseconds(&self) -> i64 {
26481 -+ self.num_nanoseconds() / 1_000_000
26482 -+ }
26483 -+
26484 -+ fn num_microseconds(&self) -> i64 {
26485 -+ self.num_nanoseconds() / 1_000_000_000
26486 -+ }
26487 -+
26488 -+ fn num_nanoseconds(&self) -> i64 {
26489 -+ let secs = self.num_seconds() * 1_000_000_000;
26490 -+ let nsec = self.nanos_mod_sec();
26491 -+ secs + nsec as i64
26492 -+ }
26493 -+}
26494 -+
26495 -+impl TimeSpec {
26496 -+ fn nanos_mod_sec(&self) -> c_long {
26497 -+ if self.tv_sec() < 0 && self.tv_nsec() > 0 {
26498 -+ self.tv_nsec() - NANOS_PER_SEC as c_long
26499 -+ } else {
26500 -+ self.tv_nsec()
26501 -+ }
26502 -+ }
26503 -+
26504 -+ pub fn tv_sec(&self) -> time_t {
26505 -+ self.0.tv_sec
26506 -+ }
26507 -+
26508 -+ pub fn tv_nsec(&self) -> c_long {
26509 -+ self.0.tv_nsec
26510 -+ }
26511 -+}
26512 -+
26513 -+impl ops::Neg for TimeSpec {
26514 -+ type Output = TimeSpec;
26515 -+
26516 -+ fn neg(self) -> TimeSpec {
26517 -+ TimeSpec::nanoseconds(-self.num_nanoseconds())
26518 -+ }
26519 -+}
26520 -+
26521 -+impl ops::Add for TimeSpec {
26522 -+ type Output = TimeSpec;
26523 -+
26524 -+ fn add(self, rhs: TimeSpec) -> TimeSpec {
26525 -+ TimeSpec::nanoseconds(
26526 -+ self.num_nanoseconds() + rhs.num_nanoseconds())
26527 -+ }
26528 -+}
26529 -+
26530 -+impl ops::Sub for TimeSpec {
26531 -+ type Output = TimeSpec;
26532 -+
26533 -+ fn sub(self, rhs: TimeSpec) -> TimeSpec {
26534 -+ TimeSpec::nanoseconds(
26535 -+ self.num_nanoseconds() - rhs.num_nanoseconds())
26536 -+ }
26537 -+}
26538 -+
26539 -+impl ops::Mul<i32> for TimeSpec {
26540 -+ type Output = TimeSpec;
26541 -+
26542 -+ fn mul(self, rhs: i32) -> TimeSpec {
26543 -+ let usec = self.num_nanoseconds().checked_mul(rhs as i64)
26544 -+ .expect("TimeSpec multiply out of bounds");
26545 -+
26546 -+ TimeSpec::nanoseconds(usec)
26547 -+ }
26548 -+}
26549 -+
26550 -+impl ops::Div<i32> for TimeSpec {
26551 -+ type Output = TimeSpec;
26552 -+
26553 -+ fn div(self, rhs: i32) -> TimeSpec {
26554 -+ let usec = self.num_nanoseconds() / rhs as i64;
26555 -+ TimeSpec::nanoseconds(usec)
26556 -+ }
26557 -+}
26558 -+
26559 -+impl fmt::Display for TimeSpec {
26560 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26561 -+ let (abs, sign) = if self.tv_sec() < 0 {
26562 -+ (-*self, "-")
26563 -+ } else {
26564 -+ (*self, "")
26565 -+ };
26566 -+
26567 -+ let sec = abs.tv_sec();
26568 -+
26569 -+ write!(f, "{}", sign)?;
26570 -+
26571 -+ if abs.tv_nsec() == 0 {
26572 -+ if abs.tv_sec() == 1 {
26573 -+ write!(f, "{} second", sec)?;
26574 -+ } else {
26575 -+ write!(f, "{} seconds", sec)?;
26576 -+ }
26577 -+ } else if abs.tv_nsec() % 1_000_000 == 0 {
26578 -+ write!(f, "{}.{:03} seconds", sec, abs.tv_nsec() / 1_000_000)?;
26579 -+ } else if abs.tv_nsec() % 1_000 == 0 {
26580 -+ write!(f, "{}.{:06} seconds", sec, abs.tv_nsec() / 1_000)?;
26581 -+ } else {
26582 -+ write!(f, "{}.{:09} seconds", sec, abs.tv_nsec())?;
26583 -+ }
26584 -+
26585 -+ Ok(())
26586 -+ }
26587 -+}
26588 -+
26589 -+
26590 -+
26591 -+#[repr(C)]
26592 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
26593 -+pub struct TimeVal(timeval);
26594 -+
26595 -+const MICROS_PER_SEC: i64 = 1_000_000;
26596 -+
26597 -+#[cfg(target_pointer_width = "64")]
26598 -+const TV_MAX_SECONDS: i64 = (::std::i64::MAX / MICROS_PER_SEC) - 1;
26599 -+
26600 -+#[cfg(target_pointer_width = "32")]
26601 -+const TV_MAX_SECONDS: i64 = ::std::isize::MAX as i64;
26602 -+
26603 -+const TV_MIN_SECONDS: i64 = -TV_MAX_SECONDS;
26604 -+
26605 -+impl AsRef<timeval> for TimeVal {
26606 -+ fn as_ref(&self) -> &timeval {
26607 -+ &self.0
26608 -+ }
26609 -+}
26610 -+
26611 -+impl Ord for TimeVal {
26612 -+ // The implementation of cmp is simplified by assuming that the struct is
26613 -+ // normalized. That is, tv_usec must always be within [0, 1_000_000)
26614 -+ fn cmp(&self, other: &TimeVal) -> cmp::Ordering {
26615 -+ if self.tv_sec() == other.tv_sec() {
26616 -+ self.tv_usec().cmp(&other.tv_usec())
26617 -+ } else {
26618 -+ self.tv_sec().cmp(&other.tv_sec())
26619 -+ }
26620 -+ }
26621 -+}
26622 -+
26623 -+impl PartialOrd for TimeVal {
26624 -+ fn partial_cmp(&self, other: &TimeVal) -> Option<cmp::Ordering> {
26625 -+ Some(self.cmp(other))
26626 -+ }
26627 -+}
26628 -+
26629 -+impl TimeValLike for TimeVal {
26630 -+ #[inline]
26631 -+ fn seconds(seconds: i64) -> TimeVal {
26632 -+ assert!(seconds >= TV_MIN_SECONDS && seconds <= TV_MAX_SECONDS,
26633 -+ "TimeVal out of bounds; seconds={}", seconds);
26634 -+ TimeVal(timeval {tv_sec: seconds as time_t, tv_usec: 0 })
26635 -+ }
26636 -+
26637 -+ #[inline]
26638 -+ fn milliseconds(milliseconds: i64) -> TimeVal {
26639 -+ let microseconds = milliseconds.checked_mul(1_000)
26640 -+ .expect("TimeVal::milliseconds out of bounds");
26641 -+
26642 -+ TimeVal::microseconds(microseconds)
26643 -+ }
26644 -+
26645 -+ /// Makes a new `TimeVal` with given number of microseconds.
26646 -+ #[inline]
26647 -+ fn microseconds(microseconds: i64) -> TimeVal {
26648 -+ let (secs, micros) = div_mod_floor_64(microseconds, MICROS_PER_SEC);
26649 -+ assert!(secs >= TV_MIN_SECONDS && secs <= TV_MAX_SECONDS,
26650 -+ "TimeVal out of bounds");
26651 -+ TimeVal(timeval {tv_sec: secs as time_t,
26652 -+ tv_usec: micros as suseconds_t })
26653 -+ }
26654 -+
26655 -+ /// Makes a new `TimeVal` with given number of nanoseconds. Some precision
26656 -+ /// will be lost
26657 -+ #[inline]
26658 -+ fn nanoseconds(nanoseconds: i64) -> TimeVal {
26659 -+ let microseconds = nanoseconds / 1000;
26660 -+ let (secs, micros) = div_mod_floor_64(microseconds, MICROS_PER_SEC);
26661 -+ assert!(secs >= TV_MIN_SECONDS && secs <= TV_MAX_SECONDS,
26662 -+ "TimeVal out of bounds");
26663 -+ TimeVal(timeval {tv_sec: secs as time_t,
26664 -+ tv_usec: micros as suseconds_t })
26665 -+ }
26666 -+
26667 -+ fn num_seconds(&self) -> i64 {
26668 -+ if self.tv_sec() < 0 && self.tv_usec() > 0 {
26669 -+ (self.tv_sec() + 1) as i64
26670 -+ } else {
26671 -+ self.tv_sec() as i64
26672 -+ }
26673 -+ }
26674 -+
26675 -+ fn num_milliseconds(&self) -> i64 {
26676 -+ self.num_microseconds() / 1_000
26677 -+ }
26678 -+
26679 -+ fn num_microseconds(&self) -> i64 {
26680 -+ let secs = self.num_seconds() * 1_000_000;
26681 -+ let usec = self.micros_mod_sec();
26682 -+ secs + usec as i64
26683 -+ }
26684 -+
26685 -+ fn num_nanoseconds(&self) -> i64 {
26686 -+ self.num_microseconds() * 1_000
26687 -+ }
26688 -+}
26689 -+
26690 -+impl TimeVal {
26691 -+ fn micros_mod_sec(&self) -> suseconds_t {
26692 -+ if self.tv_sec() < 0 && self.tv_usec() > 0 {
26693 -+ self.tv_usec() - MICROS_PER_SEC as suseconds_t
26694 -+ } else {
26695 -+ self.tv_usec()
26696 -+ }
26697 -+ }
26698 -+
26699 -+ pub fn tv_sec(&self) -> time_t {
26700 -+ self.0.tv_sec
26701 -+ }
26702 -+
26703 -+ pub fn tv_usec(&self) -> suseconds_t {
26704 -+ self.0.tv_usec
26705 -+ }
26706 -+}
26707 -+
26708 -+impl ops::Neg for TimeVal {
26709 -+ type Output = TimeVal;
26710 -+
26711 -+ fn neg(self) -> TimeVal {
26712 -+ TimeVal::microseconds(-self.num_microseconds())
26713 -+ }
26714 -+}
26715 -+
26716 -+impl ops::Add for TimeVal {
26717 -+ type Output = TimeVal;
26718 -+
26719 -+ fn add(self, rhs: TimeVal) -> TimeVal {
26720 -+ TimeVal::microseconds(
26721 -+ self.num_microseconds() + rhs.num_microseconds())
26722 -+ }
26723 -+}
26724 -+
26725 -+impl ops::Sub for TimeVal {
26726 -+ type Output = TimeVal;
26727 -+
26728 -+ fn sub(self, rhs: TimeVal) -> TimeVal {
26729 -+ TimeVal::microseconds(
26730 -+ self.num_microseconds() - rhs.num_microseconds())
26731 -+ }
26732 -+}
26733 -+
26734 -+impl ops::Mul<i32> for TimeVal {
26735 -+ type Output = TimeVal;
26736 -+
26737 -+ fn mul(self, rhs: i32) -> TimeVal {
26738 -+ let usec = self.num_microseconds().checked_mul(rhs as i64)
26739 -+ .expect("TimeVal multiply out of bounds");
26740 -+
26741 -+ TimeVal::microseconds(usec)
26742 -+ }
26743 -+}
26744 -+
26745 -+impl ops::Div<i32> for TimeVal {
26746 -+ type Output = TimeVal;
26747 -+
26748 -+ fn div(self, rhs: i32) -> TimeVal {
26749 -+ let usec = self.num_microseconds() / rhs as i64;
26750 -+ TimeVal::microseconds(usec)
26751 -+ }
26752 -+}
26753 -+
26754 -+impl fmt::Display for TimeVal {
26755 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26756 -+ let (abs, sign) = if self.tv_sec() < 0 {
26757 -+ (-*self, "-")
26758 -+ } else {
26759 -+ (*self, "")
26760 -+ };
26761 -+
26762 -+ let sec = abs.tv_sec();
26763 -+
26764 -+ write!(f, "{}", sign)?;
26765 -+
26766 -+ if abs.tv_usec() == 0 {
26767 -+ if abs.tv_sec() == 1 {
26768 -+ write!(f, "{} second", sec)?;
26769 -+ } else {
26770 -+ write!(f, "{} seconds", sec)?;
26771 -+ }
26772 -+ } else if abs.tv_usec() % 1000 == 0 {
26773 -+ write!(f, "{}.{:03} seconds", sec, abs.tv_usec() / 1000)?;
26774 -+ } else {
26775 -+ write!(f, "{}.{:06} seconds", sec, abs.tv_usec())?;
26776 -+ }
26777 -+
26778 -+ Ok(())
26779 -+ }
26780 -+}
26781 -+
26782 -+impl From<timeval> for TimeVal {
26783 -+ fn from(tv: timeval) -> Self {
26784 -+ TimeVal(tv)
26785 -+ }
26786 -+}
26787 -+
26788 -+#[inline]
26789 -+fn div_mod_floor_64(this: i64, other: i64) -> (i64, i64) {
26790 -+ (div_floor_64(this, other), mod_floor_64(this, other))
26791 -+}
26792 -+
26793 -+#[inline]
26794 -+fn div_floor_64(this: i64, other: i64) -> i64 {
26795 -+ match div_rem_64(this, other) {
26796 -+ (d, r) if (r > 0 && other < 0)
26797 -+ || (r < 0 && other > 0) => d - 1,
26798 -+ (d, _) => d,
26799 -+ }
26800 -+}
26801 -+
26802 -+#[inline]
26803 -+fn mod_floor_64(this: i64, other: i64) -> i64 {
26804 -+ match this % other {
26805 -+ r if (r > 0 && other < 0)
26806 -+ || (r < 0 && other > 0) => r + other,
26807 -+ r => r,
26808 -+ }
26809 -+}
26810 -+
26811 -+#[inline]
26812 -+fn div_rem_64(this: i64, other: i64) -> (i64, i64) {
26813 -+ (this / other, this % other)
26814 -+}
26815 -+
26816 -+#[cfg(test)]
26817 -+mod test {
26818 -+ use super::{TimeSpec, TimeVal, TimeValLike};
26819 -+
26820 -+ #[test]
26821 -+ pub fn test_timespec() {
26822 -+ assert!(TimeSpec::seconds(1) != TimeSpec::zero());
26823 -+ assert_eq!(TimeSpec::seconds(1) + TimeSpec::seconds(2),
26824 -+ TimeSpec::seconds(3));
26825 -+ assert_eq!(TimeSpec::minutes(3) + TimeSpec::seconds(2),
26826 -+ TimeSpec::seconds(182));
26827 -+ }
26828 -+
26829 -+ #[test]
26830 -+ pub fn test_timespec_neg() {
26831 -+ let a = TimeSpec::seconds(1) + TimeSpec::nanoseconds(123);
26832 -+ let b = TimeSpec::seconds(-1) + TimeSpec::nanoseconds(-123);
26833 -+
26834 -+ assert_eq!(a, -b);
26835 -+ }
26836 -+
26837 -+ #[test]
26838 -+ pub fn test_timespec_ord() {
26839 -+ assert!(TimeSpec::seconds(1) == TimeSpec::nanoseconds(1_000_000_000));
26840 -+ assert!(TimeSpec::seconds(1) < TimeSpec::nanoseconds(1_000_000_001));
26841 -+ assert!(TimeSpec::seconds(1) > TimeSpec::nanoseconds(999_999_999));
26842 -+ assert!(TimeSpec::seconds(-1) < TimeSpec::nanoseconds(-999_999_999));
26843 -+ assert!(TimeSpec::seconds(-1) > TimeSpec::nanoseconds(-1_000_000_001));
26844 -+ }
26845 -+
26846 -+ #[test]
26847 -+ pub fn test_timespec_fmt() {
26848 -+ assert_eq!(TimeSpec::zero().to_string(), "0 seconds");
26849 -+ assert_eq!(TimeSpec::seconds(42).to_string(), "42 seconds");
26850 -+ assert_eq!(TimeSpec::milliseconds(42).to_string(), "0.042 seconds");
26851 -+ assert_eq!(TimeSpec::microseconds(42).to_string(), "0.000042 seconds");
26852 -+ assert_eq!(TimeSpec::nanoseconds(42).to_string(), "0.000000042 seconds");
26853 -+ assert_eq!(TimeSpec::seconds(-86401).to_string(), "-86401 seconds");
26854 -+ }
26855 -+
26856 -+ #[test]
26857 -+ pub fn test_timeval() {
26858 -+ assert!(TimeVal::seconds(1) != TimeVal::zero());
26859 -+ assert_eq!(TimeVal::seconds(1) + TimeVal::seconds(2),
26860 -+ TimeVal::seconds(3));
26861 -+ assert_eq!(TimeVal::minutes(3) + TimeVal::seconds(2),
26862 -+ TimeVal::seconds(182));
26863 -+ }
26864 -+
26865 -+ #[test]
26866 -+ pub fn test_timeval_ord() {
26867 -+ assert!(TimeVal::seconds(1) == TimeVal::microseconds(1_000_000));
26868 -+ assert!(TimeVal::seconds(1) < TimeVal::microseconds(1_000_001));
26869 -+ assert!(TimeVal::seconds(1) > TimeVal::microseconds(999_999));
26870 -+ assert!(TimeVal::seconds(-1) < TimeVal::microseconds(-999_999));
26871 -+ assert!(TimeVal::seconds(-1) > TimeVal::microseconds(-1_000_001));
26872 -+ }
26873 -+
26874 -+ #[test]
26875 -+ pub fn test_timeval_neg() {
26876 -+ let a = TimeVal::seconds(1) + TimeVal::microseconds(123);
26877 -+ let b = TimeVal::seconds(-1) + TimeVal::microseconds(-123);
26878 -+
26879 -+ assert_eq!(a, -b);
26880 -+ }
26881 -+
26882 -+ #[test]
26883 -+ pub fn test_timeval_fmt() {
26884 -+ assert_eq!(TimeVal::zero().to_string(), "0 seconds");
26885 -+ assert_eq!(TimeVal::seconds(42).to_string(), "42 seconds");
26886 -+ assert_eq!(TimeVal::milliseconds(42).to_string(), "0.042 seconds");
26887 -+ assert_eq!(TimeVal::microseconds(42).to_string(), "0.000042 seconds");
26888 -+ assert_eq!(TimeVal::nanoseconds(1402).to_string(), "0.000001 seconds");
26889 -+ assert_eq!(TimeVal::seconds(-86401).to_string(), "-86401 seconds");
26890 -+ }
26891 -+}
26892 -diff --git a/third_party/rust/nix-0.15.0/src/sys/uio.rs b/third_party/rust/nix-0.15.0/src/sys/uio.rs
26893 -new file mode 100644
26894 -index 0000000000000..d089084eed711
26895 ---- /dev/null
26896 -+++ b/third_party/rust/nix-0.15.0/src/sys/uio.rs
26897 -@@ -0,0 +1,194 @@
26898 -+// Silence invalid warnings due to rust-lang/rust#16719
26899 -+#![allow(improper_ctypes)]
26900 -+
26901 -+use Result;
26902 -+use errno::Errno;
26903 -+use libc::{self, c_int, c_void, size_t, off_t};
26904 -+use std::marker::PhantomData;
26905 -+use std::os::unix::io::RawFd;
26906 -+
26907 -+pub fn writev(fd: RawFd, iov: &[IoVec<&[u8]>]) -> Result<usize> {
26908 -+ let res = unsafe { libc::writev(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int) };
26909 -+
26910 -+ Errno::result(res).map(|r| r as usize)
26911 -+}
26912 -+
26913 -+pub fn readv(fd: RawFd, iov: &mut [IoVec<&mut [u8]>]) -> Result<usize> {
26914 -+ let res = unsafe { libc::readv(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int) };
26915 -+
26916 -+ Errno::result(res).map(|r| r as usize)
26917 -+}
26918 -+
26919 -+/// Write to `fd` at `offset` from buffers in `iov`.
26920 -+///
26921 -+/// Buffers in `iov` will be written in order until all buffers have been written
26922 -+/// or an error occurs. The file offset is not changed.
26923 -+///
26924 -+/// See also: [`writev`](fn.writev.html) and [`pwrite`](fn.pwrite.html)
26925 -+#[cfg(any(target_os = "dragonfly",
26926 -+ target_os = "freebsd",
26927 -+ target_os = "linux",
26928 -+ target_os = "netbsd",
26929 -+ target_os = "openbsd"))]
26930 -+pub fn pwritev(fd: RawFd, iov: &[IoVec<&[u8]>],
26931 -+ offset: off_t) -> Result<usize> {
26932 -+ let res = unsafe {
26933 -+ libc::pwritev(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int, offset)
26934 -+ };
26935 -+
26936 -+ Errno::result(res).map(|r| r as usize)
26937 -+}
26938 -+
26939 -+/// Read from `fd` at `offset` filling buffers in `iov`.
26940 -+///
26941 -+/// Buffers in `iov` will be filled in order until all buffers have been filled,
26942 -+/// no more bytes are available, or an error occurs. The file offset is not
26943 -+/// changed.
26944 -+///
26945 -+/// See also: [`readv`](fn.readv.html) and [`pread`](fn.pread.html)
26946 -+#[cfg(any(target_os = "dragonfly",
26947 -+ target_os = "freebsd",
26948 -+ target_os = "linux",
26949 -+ target_os = "netbsd",
26950 -+ target_os = "openbsd"))]
26951 -+pub fn preadv(fd: RawFd, iov: &[IoVec<&mut [u8]>],
26952 -+ offset: off_t) -> Result<usize> {
26953 -+ let res = unsafe {
26954 -+ libc::preadv(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int, offset)
26955 -+ };
26956 -+
26957 -+ Errno::result(res).map(|r| r as usize)
26958 -+}
26959 -+
26960 -+pub fn pwrite(fd: RawFd, buf: &[u8], offset: off_t) -> Result<usize> {
26961 -+ let res = unsafe {
26962 -+ libc::pwrite(fd, buf.as_ptr() as *const c_void, buf.len() as size_t,
26963 -+ offset)
26964 -+ };
26965 -+
26966 -+ Errno::result(res).map(|r| r as usize)
26967 -+}
26968 -+
26969 -+pub fn pread(fd: RawFd, buf: &mut [u8], offset: off_t) -> Result<usize>{
26970 -+ let res = unsafe {
26971 -+ libc::pread(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t,
26972 -+ offset)
26973 -+ };
26974 -+
26975 -+ Errno::result(res).map(|r| r as usize)
26976 -+}
26977 -+
26978 -+/// A slice of memory in a remote process, starting at address `base`
26979 -+/// and consisting of `len` bytes.
26980 -+///
26981 -+/// This is the same underlying C structure as [`IoVec`](struct.IoVec.html),
26982 -+/// except that it refers to memory in some other process, and is
26983 -+/// therefore not represented in Rust by an actual slice as `IoVec` is. It
26984 -+/// is used with [`process_vm_readv`](fn.process_vm_readv.html)
26985 -+/// and [`process_vm_writev`](fn.process_vm_writev.html).
26986 -+#[cfg(target_os = "linux")]
26987 -+#[repr(C)]
26988 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
26989 -+pub struct RemoteIoVec {
26990 -+ /// The starting address of this slice (`iov_base`).
26991 -+ pub base: usize,
26992 -+ /// The number of bytes in this slice (`iov_len`).
26993 -+ pub len: usize,
26994 -+}
26995 -+
26996 -+/// Write data directly to another process's virtual memory
26997 -+/// (see [`process_vm_writev`(2)]).
26998 -+///
26999 -+/// `local_iov` is a list of [`IoVec`]s containing the data to be written,
27000 -+/// and `remote_iov` is a list of [`RemoteIoVec`]s identifying where the
27001 -+/// data should be written in the target process. On success, returns the
27002 -+/// number of bytes written, which will always be a whole
27003 -+/// number of `remote_iov` chunks.
27004 -+///
27005 -+/// This requires the same permissions as debugging the process using
27006 -+/// [ptrace]: you must either be a privileged process (with
27007 -+/// `CAP_SYS_PTRACE`), or you must be running as the same user as the
27008 -+/// target process and the OS must have unprivileged debugging enabled.
27009 -+///
27010 -+/// This function is only available on Linux.
27011 -+///
27012 -+/// [`process_vm_writev`(2)]: http://man7.org/linux/man-pages/man2/process_vm_writev.2.html
27013 -+/// [ptrace]: ../ptrace/index.html
27014 -+/// [`IoVec`]: struct.IoVec.html
27015 -+/// [`RemoteIoVec`]: struct.RemoteIoVec.html
27016 -+#[cfg(target_os = "linux")]
27017 -+pub fn process_vm_writev(pid: ::unistd::Pid, local_iov: &[IoVec<&[u8]>], remote_iov: &[RemoteIoVec]) -> Result<usize> {
27018 -+ let res = unsafe {
27019 -+ libc::process_vm_writev(pid.into(),
27020 -+ local_iov.as_ptr() as *const libc::iovec, local_iov.len() as libc::c_ulong,
27021 -+ remote_iov.as_ptr() as *const libc::iovec, remote_iov.len() as libc::c_ulong, 0)
27022 -+ };
27023 -+
27024 -+ Errno::result(res).map(|r| r as usize)
27025 -+}
27026 -+
27027 -+/// Read data directly from another process's virtual memory
27028 -+/// (see [`process_vm_readv`(2)]).
27029 -+///
27030 -+/// `local_iov` is a list of [`IoVec`]s containing the buffer to copy
27031 -+/// data into, and `remote_iov` is a list of [`RemoteIoVec`]s identifying
27032 -+/// where the source data is in the target process. On success,
27033 -+/// returns the number of bytes written, which will always be a whole
27034 -+/// number of `remote_iov` chunks.
27035 -+///
27036 -+/// This requires the same permissions as debugging the process using
27037 -+/// [`ptrace`]: you must either be a privileged process (with
27038 -+/// `CAP_SYS_PTRACE`), or you must be running as the same user as the
27039 -+/// target process and the OS must have unprivileged debugging enabled.
27040 -+///
27041 -+/// This function is only available on Linux.
27042 -+///
27043 -+/// [`process_vm_readv`(2)]: http://man7.org/linux/man-pages/man2/process_vm_readv.2.html
27044 -+/// [`ptrace`]: ../ptrace/index.html
27045 -+/// [`IoVec`]: struct.IoVec.html
27046 -+/// [`RemoteIoVec`]: struct.RemoteIoVec.html
27047 -+#[cfg(any(target_os = "linux"))]
27048 -+pub fn process_vm_readv(pid: ::unistd::Pid, local_iov: &[IoVec<&mut [u8]>], remote_iov: &[RemoteIoVec]) -> Result<usize> {
27049 -+ let res = unsafe {
27050 -+ libc::process_vm_readv(pid.into(),
27051 -+ local_iov.as_ptr() as *const libc::iovec, local_iov.len() as libc::c_ulong,
27052 -+ remote_iov.as_ptr() as *const libc::iovec, remote_iov.len() as libc::c_ulong, 0)
27053 -+ };
27054 -+
27055 -+ Errno::result(res).map(|r| r as usize)
27056 -+}
27057 -+
27058 -+#[repr(C)]
27059 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
27060 -+pub struct IoVec<T>(libc::iovec, PhantomData<T>);
27061 -+
27062 -+impl<T> IoVec<T> {
27063 -+ #[inline]
27064 -+ pub fn as_slice(&self) -> &[u8] {
27065 -+ use std::slice;
27066 -+
27067 -+ unsafe {
27068 -+ slice::from_raw_parts(
27069 -+ self.0.iov_base as *const u8,
27070 -+ self.0.iov_len as usize)
27071 -+ }
27072 -+ }
27073 -+}
27074 -+
27075 -+impl<'a> IoVec<&'a [u8]> {
27076 -+ pub fn from_slice(buf: &'a [u8]) -> IoVec<&'a [u8]> {
27077 -+ IoVec(libc::iovec {
27078 -+ iov_base: buf.as_ptr() as *mut c_void,
27079 -+ iov_len: buf.len() as size_t,
27080 -+ }, PhantomData)
27081 -+ }
27082 -+}
27083 -+
27084 -+impl<'a> IoVec<&'a mut [u8]> {
27085 -+ pub fn from_mut_slice(buf: &'a mut [u8]) -> IoVec<&'a mut [u8]> {
27086 -+ IoVec(libc::iovec {
27087 -+ iov_base: buf.as_ptr() as *mut c_void,
27088 -+ iov_len: buf.len() as size_t,
27089 -+ }, PhantomData)
27090 -+ }
27091 -+}
27092 -diff --git a/third_party/rust/nix-0.15.0/src/sys/utsname.rs b/third_party/rust/nix-0.15.0/src/sys/utsname.rs
27093 -new file mode 100644
27094 -index 0000000000000..ab09c7d23232a
27095 ---- /dev/null
27096 -+++ b/third_party/rust/nix-0.15.0/src/sys/utsname.rs
27097 -@@ -0,0 +1,67 @@
27098 -+use std::mem;
27099 -+use libc::{self, c_char};
27100 -+use std::ffi::CStr;
27101 -+use std::str::from_utf8_unchecked;
27102 -+
27103 -+#[repr(C)]
27104 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
27105 -+pub struct UtsName(libc::utsname);
27106 -+
27107 -+impl UtsName {
27108 -+ pub fn sysname(&self) -> &str {
27109 -+ to_str(&(&self.0.sysname as *const c_char ) as *const *const c_char)
27110 -+ }
27111 -+
27112 -+ pub fn nodename(&self) -> &str {
27113 -+ to_str(&(&self.0.nodename as *const c_char ) as *const *const c_char)
27114 -+ }
27115 -+
27116 -+ pub fn release(&self) -> &str {
27117 -+ to_str(&(&self.0.release as *const c_char ) as *const *const c_char)
27118 -+ }
27119 -+
27120 -+ pub fn version(&self) -> &str {
27121 -+ to_str(&(&self.0.version as *const c_char ) as *const *const c_char)
27122 -+ }
27123 -+
27124 -+ pub fn machine(&self) -> &str {
27125 -+ to_str(&(&self.0.machine as *const c_char ) as *const *const c_char)
27126 -+ }
27127 -+}
27128 -+
27129 -+pub fn uname() -> UtsName {
27130 -+ unsafe {
27131 -+ let mut ret: UtsName = mem::uninitialized();
27132 -+ libc::uname(&mut ret.0);
27133 -+ ret
27134 -+ }
27135 -+}
27136 -+
27137 -+#[inline]
27138 -+fn to_str<'a>(s: *const *const c_char) -> &'a str {
27139 -+ unsafe {
27140 -+ let res = CStr::from_ptr(*s).to_bytes();
27141 -+ from_utf8_unchecked(res)
27142 -+ }
27143 -+}
27144 -+
27145 -+#[cfg(test)]
27146 -+mod test {
27147 -+ #[cfg(target_os = "linux")]
27148 -+ #[test]
27149 -+ pub fn test_uname_linux() {
27150 -+ assert_eq!(super::uname().sysname(), "Linux");
27151 -+ }
27152 -+
27153 -+ #[cfg(any(target_os = "macos", target_os = "ios"))]
27154 -+ #[test]
27155 -+ pub fn test_uname_darwin() {
27156 -+ assert_eq!(super::uname().sysname(), "Darwin");
27157 -+ }
27158 -+
27159 -+ #[cfg(target_os = "freebsd")]
27160 -+ #[test]
27161 -+ pub fn test_uname_freebsd() {
27162 -+ assert_eq!(super::uname().sysname(), "FreeBSD");
27163 -+ }
27164 -+}
27165 -diff --git a/third_party/rust/nix-0.15.0/src/sys/wait.rs b/third_party/rust/nix-0.15.0/src/sys/wait.rs
27166 -new file mode 100644
27167 -index 0000000000000..c54f7ec579667
27168 ---- /dev/null
27169 -+++ b/third_party/rust/nix-0.15.0/src/sys/wait.rs
27170 -@@ -0,0 +1,239 @@
27171 -+use libc::{self, c_int};
27172 -+use Result;
27173 -+use errno::Errno;
27174 -+use unistd::Pid;
27175 -+
27176 -+use sys::signal::Signal;
27177 -+
27178 -+libc_bitflags!(
27179 -+ pub struct WaitPidFlag: c_int {
27180 -+ WNOHANG;
27181 -+ WUNTRACED;
27182 -+ #[cfg(any(target_os = "android",
27183 -+ target_os = "freebsd",
27184 -+ target_os = "haiku",
27185 -+ target_os = "ios",
27186 -+ target_os = "linux",
27187 -+ target_os = "macos",
27188 -+ target_os = "netbsd"))]
27189 -+ WEXITED;
27190 -+ WCONTINUED;
27191 -+ #[cfg(any(target_os = "android",
27192 -+ target_os = "freebsd",
27193 -+ target_os = "haiku",
27194 -+ target_os = "ios",
27195 -+ target_os = "linux",
27196 -+ target_os = "macos",
27197 -+ target_os = "netbsd"))]
27198 -+ WSTOPPED;
27199 -+ /// Don't reap, just poll status.
27200 -+ #[cfg(any(target_os = "android",
27201 -+ target_os = "freebsd",
27202 -+ target_os = "haiku",
27203 -+ target_os = "ios",
27204 -+ target_os = "linux",
27205 -+ target_os = "macos",
27206 -+ target_os = "netbsd"))]
27207 -+ WNOWAIT;
27208 -+ /// Don't wait on children of other threads in this group
27209 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
27210 -+ __WNOTHREAD;
27211 -+ /// Wait on all children, regardless of type
27212 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
27213 -+ __WALL;
27214 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
27215 -+ __WCLONE;
27216 -+ }
27217 -+);
27218 -+
27219 -+/// Possible return values from `wait()` or `waitpid()`.
27220 -+///
27221 -+/// Each status (other than `StillAlive`) describes a state transition
27222 -+/// in a child process `Pid`, such as the process exiting or stopping,
27223 -+/// plus additional data about the transition if any.
27224 -+///
27225 -+/// Note that there are two Linux-specific enum variants, `PtraceEvent`
27226 -+/// and `PtraceSyscall`. Portable code should avoid exhaustively
27227 -+/// matching on `WaitStatus`.
27228 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
27229 -+pub enum WaitStatus {
27230 -+ /// The process exited normally (as with `exit()` or returning from
27231 -+ /// `main`) with the given exit code. This case matches the C macro
27232 -+ /// `WIFEXITED(status)`; the second field is `WEXITSTATUS(status)`.
27233 -+ Exited(Pid, i32),
27234 -+ /// The process was killed by the given signal. The third field
27235 -+ /// indicates whether the signal generated a core dump. This case
27236 -+ /// matches the C macro `WIFSIGNALED(status)`; the last two fields
27237 -+ /// correspond to `WTERMSIG(status)` and `WCOREDUMP(status)`.
27238 -+ Signaled(Pid, Signal, bool),
27239 -+ /// The process is alive, but was stopped by the given signal. This
27240 -+ /// is only reported if `WaitPidFlag::WUNTRACED` was passed. This
27241 -+ /// case matches the C macro `WIFSTOPPED(status)`; the second field
27242 -+ /// is `WSTOPSIG(status)`.
27243 -+ Stopped(Pid, Signal),
27244 -+ /// The traced process was stopped by a `PTRACE_EVENT_*` event. See
27245 -+ /// [`nix::sys::ptrace`] and [`ptrace`(2)] for more information. All
27246 -+ /// currently-defined events use `SIGTRAP` as the signal; the third
27247 -+ /// field is the `PTRACE_EVENT_*` value of the event.
27248 -+ ///
27249 -+ /// [`nix::sys::ptrace`]: ../ptrace/index.html
27250 -+ /// [`ptrace`(2)]: http://man7.org/linux/man-pages/man2/ptrace.2.html
27251 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
27252 -+ PtraceEvent(Pid, Signal, c_int),
27253 -+ /// The traced process was stopped by execution of a system call,
27254 -+ /// and `PTRACE_O_TRACESYSGOOD` is in effect. See [`ptrace`(2)] for
27255 -+ /// more information.
27256 -+ ///
27257 -+ /// [`ptrace`(2)]: http://man7.org/linux/man-pages/man2/ptrace.2.html
27258 -+ #[cfg(any(target_os = "linux", target_os = "android"))]
27259 -+ PtraceSyscall(Pid),
27260 -+ /// The process was previously stopped but has resumed execution
27261 -+ /// after receiving a `SIGCONT` signal. This is only reported if
27262 -+ /// `WaitPidFlag::WCONTINUED` was passed. This case matches the C
27263 -+ /// macro `WIFCONTINUED(status)`.
27264 -+ Continued(Pid),
27265 -+ /// There are currently no state changes to report in any awaited
27266 -+ /// child process. This is only returned if `WaitPidFlag::WNOHANG`
27267 -+ /// was used (otherwise `wait()` or `waitpid()` would block until
27268 -+ /// there was something to report).
27269 -+ StillAlive,
27270 -+}
27271 -+
27272 -+impl WaitStatus {
27273 -+ /// Extracts the PID from the WaitStatus unless it equals StillAlive.
27274 -+ pub fn pid(&self) -> Option<Pid> {
27275 -+ use self::WaitStatus::*;
27276 -+ match *self {
27277 -+ Exited(p, _) | Signaled(p, _, _) |
27278 -+ Stopped(p, _) | Continued(p) => Some(p),
27279 -+ StillAlive => None,
27280 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
27281 -+ PtraceEvent(p, _, _) | PtraceSyscall(p) => Some(p),
27282 -+ }
27283 -+ }
27284 -+}
27285 -+
27286 -+fn exited(status: i32) -> bool {
27287 -+ unsafe { libc::WIFEXITED(status) }
27288 -+}
27289 -+
27290 -+fn exit_status(status: i32) -> i32 {
27291 -+ unsafe { libc::WEXITSTATUS(status) }
27292 -+}
27293 -+
27294 -+fn signaled(status: i32) -> bool {
27295 -+ unsafe { libc::WIFSIGNALED(status) }
27296 -+}
27297 -+
27298 -+fn term_signal(status: i32) -> Result<Signal> {
27299 -+ Signal::from_c_int(unsafe { libc::WTERMSIG(status) })
27300 -+}
27301 -+
27302 -+fn dumped_core(status: i32) -> bool {
27303 -+ unsafe { libc::WCOREDUMP(status) }
27304 -+}
27305 -+
27306 -+fn stopped(status: i32) -> bool {
27307 -+ unsafe { libc::WIFSTOPPED(status) }
27308 -+}
27309 -+
27310 -+fn stop_signal(status: i32) -> Result<Signal> {
27311 -+ Signal::from_c_int(unsafe { libc::WSTOPSIG(status) })
27312 -+}
27313 -+
27314 -+#[cfg(any(target_os = "android", target_os = "linux"))]
27315 -+fn syscall_stop(status: i32) -> bool {
27316 -+ // From ptrace(2), setting PTRACE_O_TRACESYSGOOD has the effect
27317 -+ // of delivering SIGTRAP | 0x80 as the signal number for syscall
27318 -+ // stops. This allows easily distinguishing syscall stops from
27319 -+ // genuine SIGTRAP signals.
27320 -+ unsafe { libc::WSTOPSIG(status) == libc::SIGTRAP | 0x80 }
27321 -+}
27322 -+
27323 -+#[cfg(any(target_os = "android", target_os = "linux"))]
27324 -+fn stop_additional(status: i32) -> c_int {
27325 -+ (status >> 16) as c_int
27326 -+}
27327 -+
27328 -+fn continued(status: i32) -> bool {
27329 -+ unsafe { libc::WIFCONTINUED(status) }
27330 -+}
27331 -+
27332 -+impl WaitStatus {
27333 -+ /// Convert a raw `wstatus` as returned by `waitpid`/`wait` into a `WaitStatus`
27334 -+ ///
27335 -+ /// # Errors
27336 -+ ///
27337 -+ /// Returns an `Error` corresponding to `EINVAL` for invalid status values.
27338 -+ ///
27339 -+ /// # Examples
27340 -+ ///
27341 -+ /// Convert a `wstatus` obtained from `libc::waitpid` into a `WaitStatus`:
27342 -+ ///
27343 -+ /// ```
27344 -+ /// use nix::sys::wait::WaitStatus;
27345 -+ /// use nix::sys::signal::Signal;
27346 -+ /// let pid = nix::unistd::Pid::from_raw(1);
27347 -+ /// let status = WaitStatus::from_raw(pid, 0x0002);
27348 -+ /// assert_eq!(status, Ok(WaitStatus::Signaled(pid, Signal::SIGINT, false)));
27349 -+ /// ```
27350 -+ pub fn from_raw(pid: Pid, status: i32) -> Result<WaitStatus> {
27351 -+ Ok(if exited(status) {
27352 -+ WaitStatus::Exited(pid, exit_status(status))
27353 -+ } else if signaled(status) {
27354 -+ WaitStatus::Signaled(pid, term_signal(status)?, dumped_core(status))
27355 -+ } else if stopped(status) {
27356 -+ cfg_if! {
27357 -+ if #[cfg(any(target_os = "android", target_os = "linux"))] {
27358 -+ fn decode_stopped(pid: Pid, status: i32) -> Result<WaitStatus> {
27359 -+ let status_additional = stop_additional(status);
27360 -+ Ok(if syscall_stop(status) {
27361 -+ WaitStatus::PtraceSyscall(pid)
27362 -+ } else if status_additional == 0 {
27363 -+ WaitStatus::Stopped(pid, stop_signal(status)?)
27364 -+ } else {
27365 -+ WaitStatus::PtraceEvent(pid, stop_signal(status)?,
27366 -+ stop_additional(status))
27367 -+ })
27368 -+ }
27369 -+ } else {
27370 -+ fn decode_stopped(pid: Pid, status: i32) -> Result<WaitStatus> {
27371 -+ Ok(WaitStatus::Stopped(pid, stop_signal(status)?))
27372 -+ }
27373 -+ }
27374 -+ }
27375 -+ return decode_stopped(pid, status);
27376 -+ } else {
27377 -+ assert!(continued(status));
27378 -+ WaitStatus::Continued(pid)
27379 -+ })
27380 -+ }
27381 -+}
27382 -+
27383 -+pub fn waitpid<P: Into<Option<Pid>>>(pid: P, options: Option<WaitPidFlag>) -> Result<WaitStatus> {
27384 -+ use self::WaitStatus::*;
27385 -+
27386 -+ let mut status: i32 = 0;
27387 -+
27388 -+ let option_bits = match options {
27389 -+ Some(bits) => bits.bits(),
27390 -+ None => 0,
27391 -+ };
27392 -+
27393 -+ let res = unsafe {
27394 -+ libc::waitpid(
27395 -+ pid.into().unwrap_or(Pid::from_raw(-1)).into(),
27396 -+ &mut status as *mut c_int,
27397 -+ option_bits,
27398 -+ )
27399 -+ };
27400 -+
27401 -+ match Errno::result(res)? {
27402 -+ 0 => Ok(StillAlive),
27403 -+ res => WaitStatus::from_raw(Pid::from_raw(res), status),
27404 -+ }
27405 -+}
27406 -+
27407 -+pub fn wait() -> Result<WaitStatus> {
27408 -+ waitpid(None, None)
27409 -+}
27410 -diff --git a/third_party/rust/nix-0.15.0/src/ucontext.rs b/third_party/rust/nix-0.15.0/src/ucontext.rs
27411 -new file mode 100644
27412 -index 0000000000000..5e10e7d1f8934
27413 ---- /dev/null
27414 -+++ b/third_party/rust/nix-0.15.0/src/ucontext.rs
27415 -@@ -0,0 +1,39 @@
27416 -+use libc;
27417 -+#[cfg(not(target_env = "musl"))]
27418 -+use Result;
27419 -+#[cfg(not(target_env = "musl"))]
27420 -+use errno::Errno;
27421 -+use std::mem;
27422 -+use sys::signal::SigSet;
27423 -+
27424 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
27425 -+pub struct UContext {
27426 -+ context: libc::ucontext_t,
27427 -+}
27428 -+
27429 -+impl UContext {
27430 -+ #[cfg(not(target_env = "musl"))]
27431 -+ pub fn get() -> Result<UContext> {
27432 -+ let mut context: libc::ucontext_t = unsafe { mem::uninitialized() };
27433 -+ let res = unsafe {
27434 -+ libc::getcontext(&mut context as *mut libc::ucontext_t)
27435 -+ };
27436 -+ Errno::result(res).map(|_| UContext { context: context })
27437 -+ }
27438 -+
27439 -+ #[cfg(not(target_env = "musl"))]
27440 -+ pub fn set(&self) -> Result<()> {
27441 -+ let res = unsafe {
27442 -+ libc::setcontext(&self.context as *const libc::ucontext_t)
27443 -+ };
27444 -+ Errno::result(res).map(drop)
27445 -+ }
27446 -+
27447 -+ pub fn sigmask_mut(&mut self) -> &mut SigSet {
27448 -+ unsafe { mem::transmute(&mut self.context.uc_sigmask) }
27449 -+ }
27450 -+
27451 -+ pub fn sigmask(&self) -> &SigSet {
27452 -+ unsafe { mem::transmute(&self.context.uc_sigmask) }
27453 -+ }
27454 -+}
27455 -diff --git a/third_party/rust/nix-0.15.0/src/unistd.rs b/third_party/rust/nix-0.15.0/src/unistd.rs
27456 -new file mode 100644
27457 -index 0000000000000..f422f09198655
27458 ---- /dev/null
27459 -+++ b/third_party/rust/nix-0.15.0/src/unistd.rs
27460 -@@ -0,0 +1,2394 @@
27461 -+//! Safe wrappers around functions found in libc "unistd.h" header
27462 -+
27463 -+use errno::{self, Errno};
27464 -+use {Error, Result, NixPath};
27465 -+use fcntl::{AtFlags, at_rawfd, fcntl, FdFlag, OFlag};
27466 -+use fcntl::FcntlArg::F_SETFD;
27467 -+use libc::{self, c_char, c_void, c_int, c_long, c_uint, size_t, pid_t, off_t,
27468 -+ uid_t, gid_t, mode_t};
27469 -+use std::{fmt, mem, ptr};
27470 -+use std::ffi::{CString, CStr, OsString, OsStr};
27471 -+use std::os::unix::ffi::{OsStringExt, OsStrExt};
27472 -+use std::os::unix::io::RawFd;
27473 -+use std::path::PathBuf;
27474 -+use void::Void;
27475 -+use sys::stat::Mode;
27476 -+
27477 -+#[cfg(any(target_os = "android", target_os = "linux"))]
27478 -+pub use self::pivot_root::*;
27479 -+
27480 -+#[cfg(any(target_os = "android", target_os = "freebsd",
27481 -+ target_os = "linux", target_os = "openbsd"))]
27482 -+pub use self::setres::*;
27483 -+
27484 -+/// User identifier
27485 -+///
27486 -+/// Newtype pattern around `uid_t` (which is just alias). It prevents bugs caused by accidentally
27487 -+/// passing wrong value.
27488 -+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
27489 -+pub struct Uid(uid_t);
27490 -+
27491 -+impl Uid {
27492 -+ /// Creates `Uid` from raw `uid_t`.
27493 -+ pub fn from_raw(uid: uid_t) -> Self {
27494 -+ Uid(uid)
27495 -+ }
27496 -+
27497 -+ /// Returns Uid of calling process. This is practically a more Rusty alias for `getuid`.
27498 -+ pub fn current() -> Self {
27499 -+ getuid()
27500 -+ }
27501 -+
27502 -+ /// Returns effective Uid of calling process. This is practically a more Rusty alias for `geteuid`.
27503 -+ pub fn effective() -> Self {
27504 -+ geteuid()
27505 -+ }
27506 -+
27507 -+ /// Returns true if the `Uid` represents privileged user - root. (If it equals zero.)
27508 -+ pub fn is_root(&self) -> bool {
27509 -+ *self == ROOT
27510 -+ }
27511 -+
27512 -+ /// Get the raw `uid_t` wrapped by `self`.
27513 -+ pub fn as_raw(&self) -> uid_t {
27514 -+ self.0
27515 -+ }
27516 -+}
27517 -+
27518 -+impl From<Uid> for uid_t {
27519 -+ fn from(uid: Uid) -> Self {
27520 -+ uid.0
27521 -+ }
27522 -+}
27523 -+
27524 -+impl fmt::Display for Uid {
27525 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
27526 -+ fmt::Display::fmt(&self.0, f)
27527 -+ }
27528 -+}
27529 -+
27530 -+/// Constant for UID = 0
27531 -+pub const ROOT: Uid = Uid(0);
27532 -+
27533 -+/// Group identifier
27534 -+///
27535 -+/// Newtype pattern around `gid_t` (which is just alias). It prevents bugs caused by accidentally
27536 -+/// passing wrong value.
27537 -+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
27538 -+pub struct Gid(gid_t);
27539 -+
27540 -+impl Gid {
27541 -+ /// Creates `Gid` from raw `gid_t`.
27542 -+ pub fn from_raw(gid: gid_t) -> Self {
27543 -+ Gid(gid)
27544 -+ }
27545 -+
27546 -+ /// Returns Gid of calling process. This is practically a more Rusty alias for `getgid`.
27547 -+ pub fn current() -> Self {
27548 -+ getgid()
27549 -+ }
27550 -+
27551 -+ /// Returns effective Gid of calling process. This is practically a more Rusty alias for `getgid`.
27552 -+ pub fn effective() -> Self {
27553 -+ getegid()
27554 -+ }
27555 -+
27556 -+ /// Get the raw `gid_t` wrapped by `self`.
27557 -+ pub fn as_raw(&self) -> gid_t {
27558 -+ self.0
27559 -+ }
27560 -+}
27561 -+
27562 -+impl From<Gid> for gid_t {
27563 -+ fn from(gid: Gid) -> Self {
27564 -+ gid.0
27565 -+ }
27566 -+}
27567 -+
27568 -+impl fmt::Display for Gid {
27569 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
27570 -+ fmt::Display::fmt(&self.0, f)
27571 -+ }
27572 -+}
27573 -+
27574 -+/// Process identifier
27575 -+///
27576 -+/// Newtype pattern around `pid_t` (which is just alias). It prevents bugs caused by accidentally
27577 -+/// passing wrong value.
27578 -+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
27579 -+pub struct Pid(pid_t);
27580 -+
27581 -+impl Pid {
27582 -+ /// Creates `Pid` from raw `pid_t`.
27583 -+ pub fn from_raw(pid: pid_t) -> Self {
27584 -+ Pid(pid)
27585 -+ }
27586 -+
27587 -+ /// Returns PID of calling process
27588 -+ pub fn this() -> Self {
27589 -+ getpid()
27590 -+ }
27591 -+
27592 -+ /// Returns PID of parent of calling process
27593 -+ pub fn parent() -> Self {
27594 -+ getppid()
27595 -+ }
27596 -+
27597 -+ /// Get the raw `pid_t` wrapped by `self`.
27598 -+ pub fn as_raw(&self) -> pid_t {
27599 -+ self.0
27600 -+ }
27601 -+}
27602 -+
27603 -+impl From<Pid> for pid_t {
27604 -+ fn from(pid: Pid) -> Self {
27605 -+ pid.0
27606 -+ }
27607 -+}
27608 -+
27609 -+impl fmt::Display for Pid {
27610 -+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
27611 -+ fmt::Display::fmt(&self.0, f)
27612 -+ }
27613 -+}
27614 -+
27615 -+
27616 -+/// Represents the successful result of calling `fork`
27617 -+///
27618 -+/// When `fork` is called, the process continues execution in the parent process
27619 -+/// and in the new child. This return type can be examined to determine whether
27620 -+/// you are now executing in the parent process or in the child.
27621 -+#[derive(Clone, Copy, Debug)]
27622 -+pub enum ForkResult {
27623 -+ Parent { child: Pid },
27624 -+ Child,
27625 -+}
27626 -+
27627 -+impl ForkResult {
27628 -+
27629 -+ /// Return `true` if this is the child process of the `fork()`
27630 -+ #[inline]
27631 -+ pub fn is_child(&self) -> bool {
27632 -+ match *self {
27633 -+ ForkResult::Child => true,
27634 -+ _ => false
27635 -+ }
27636 -+ }
27637 -+
27638 -+ /// Returns `true` if this is the parent process of the `fork()`
27639 -+ #[inline]
27640 -+ pub fn is_parent(&self) -> bool {
27641 -+ !self.is_child()
27642 -+ }
27643 -+}
27644 -+
27645 -+/// Create a new child process duplicating the parent process ([see
27646 -+/// fork(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html)).
27647 -+///
27648 -+/// After calling the fork system call (successfully) two processes will
27649 -+/// be created that are identical with the exception of their pid and the
27650 -+/// return value of this function. As an example:
27651 -+///
27652 -+/// ```no_run
27653 -+/// use nix::unistd::{fork, ForkResult};
27654 -+///
27655 -+/// match fork() {
27656 -+/// Ok(ForkResult::Parent { child, .. }) => {
27657 -+/// println!("Continuing execution in parent process, new child has pid: {}", child);
27658 -+/// }
27659 -+/// Ok(ForkResult::Child) => println!("I'm a new child process"),
27660 -+/// Err(_) => println!("Fork failed"),
27661 -+/// }
27662 -+/// ```
27663 -+///
27664 -+/// This will print something like the following (order indeterministic). The
27665 -+/// thing to note is that you end up with two processes continuing execution
27666 -+/// immediately after the fork call but with different match arms.
27667 -+///
27668 -+/// ```text
27669 -+/// Continuing execution in parent process, new child has pid: 1234
27670 -+/// I'm a new child process
27671 -+/// ```
27672 -+///
27673 -+/// # Safety
27674 -+///
27675 -+/// In a multithreaded program, only [async-signal-safe] functions like `pause`
27676 -+/// and `_exit` may be called by the child (the parent isn't restricted). Note
27677 -+/// that memory allocation may **not** be async-signal-safe and thus must be
27678 -+/// prevented.
27679 -+///
27680 -+/// Those functions are only a small subset of your operating system's API, so
27681 -+/// special care must be taken to only invoke code you can control and audit.
27682 -+///
27683 -+/// [async-signal-safe]: http://man7.org/linux/man-pages/man7/signal-safety.7.html
27684 -+#[inline]
27685 -+pub fn fork() -> Result<ForkResult> {
27686 -+ use self::ForkResult::*;
27687 -+ let res = unsafe { libc::fork() };
27688 -+
27689 -+ Errno::result(res).map(|res| match res {
27690 -+ 0 => Child,
27691 -+ res => Parent { child: Pid(res) },
27692 -+ })
27693 -+}
27694 -+
27695 -+/// Get the pid of this process (see
27696 -+/// [getpid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpid.html)).
27697 -+///
27698 -+/// Since you are running code, there is always a pid to return, so there
27699 -+/// is no error case that needs to be handled.
27700 -+#[inline]
27701 -+pub fn getpid() -> Pid {
27702 -+ Pid(unsafe { libc::getpid() })
27703 -+}
27704 -+
27705 -+/// Get the pid of this processes' parent (see
27706 -+/// [getpid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getppid.html)).
27707 -+///
27708 -+/// There is always a parent pid to return, so there is no error case that needs
27709 -+/// to be handled.
27710 -+#[inline]
27711 -+pub fn getppid() -> Pid {
27712 -+ Pid(unsafe { libc::getppid() }) // no error handling, according to man page: "These functions are always successful."
27713 -+}
27714 -+
27715 -+/// Set a process group ID (see
27716 -+/// [setpgid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setpgid.html)).
27717 -+///
27718 -+/// Set the process group id (PGID) of a particular process. If a pid of zero
27719 -+/// is specified, then the pid of the calling process is used. Process groups
27720 -+/// may be used to group together a set of processes in order for the OS to
27721 -+/// apply some operations across the group.
27722 -+///
27723 -+/// `setsid()` may be used to create a new process group.
27724 -+#[inline]
27725 -+pub fn setpgid(pid: Pid, pgid: Pid) -> Result<()> {
27726 -+ let res = unsafe { libc::setpgid(pid.into(), pgid.into()) };
27727 -+ Errno::result(res).map(drop)
27728 -+}
27729 -+#[inline]
27730 -+pub fn getpgid(pid: Option<Pid>) -> Result<Pid> {
27731 -+ let res = unsafe { libc::getpgid(pid.unwrap_or(Pid(0)).into()) };
27732 -+ Errno::result(res).map(Pid)
27733 -+}
27734 -+
27735 -+/// Create new session and set process group id (see
27736 -+/// [setsid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsid.html)).
27737 -+#[inline]
27738 -+pub fn setsid() -> Result<Pid> {
27739 -+ Errno::result(unsafe { libc::setsid() }).map(Pid)
27740 -+}
27741 -+
27742 -+/// Get the process group ID of a session leader
27743 -+/// [getsid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsid.html).
27744 -+///
27745 -+/// Obtain the process group ID of the process that is the session leader of the process specified
27746 -+/// by pid. If pid is zero, it specifies the calling process.
27747 -+#[inline]
27748 -+pub fn getsid(pid: Option<Pid>) -> Result<Pid> {
27749 -+ let res = unsafe { libc::getsid(pid.unwrap_or(Pid(0)).into()) };
27750 -+ Errno::result(res).map(Pid)
27751 -+}
27752 -+
27753 -+
27754 -+/// Get the terminal foreground process group (see
27755 -+/// [tcgetpgrp(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetpgrp.html)).
27756 -+///
27757 -+/// Get the group process id (GPID) of the foreground process group on the
27758 -+/// terminal associated to file descriptor (FD).
27759 -+#[inline]
27760 -+pub fn tcgetpgrp(fd: c_int) -> Result<Pid> {
27761 -+ let res = unsafe { libc::tcgetpgrp(fd) };
27762 -+ Errno::result(res).map(Pid)
27763 -+}
27764 -+/// Set the terminal foreground process group (see
27765 -+/// [tcgetpgrp(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsetpgrp.html)).
27766 -+///
27767 -+/// Get the group process id (PGID) to the foreground process group on the
27768 -+/// terminal associated to file descriptor (FD).
27769 -+#[inline]
27770 -+pub fn tcsetpgrp(fd: c_int, pgrp: Pid) -> Result<()> {
27771 -+ let res = unsafe { libc::tcsetpgrp(fd, pgrp.into()) };
27772 -+ Errno::result(res).map(drop)
27773 -+}
27774 -+
27775 -+
27776 -+/// Get the group id of the calling process (see
27777 -+///[getpgrp(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpgrp.html)).
27778 -+///
27779 -+/// Get the process group id (PGID) of the calling process.
27780 -+/// According to the man page it is always successful.
27781 -+#[inline]
27782 -+pub fn getpgrp() -> Pid {
27783 -+ Pid(unsafe { libc::getpgrp() })
27784 -+}
27785 -+
27786 -+/// Get the caller's thread ID (see
27787 -+/// [gettid(2)](http://man7.org/linux/man-pages/man2/gettid.2.html).
27788 -+///
27789 -+/// This function is only available on Linux based systems. In a single
27790 -+/// threaded process, the main thread will have the same ID as the process. In
27791 -+/// a multithreaded process, each thread will have a unique thread id but the
27792 -+/// same process ID.
27793 -+///
27794 -+/// No error handling is required as a thread id should always exist for any
27795 -+/// process, even if threads are not being used.
27796 -+#[cfg(any(target_os = "linux", target_os = "android"))]
27797 -+#[inline]
27798 -+pub fn gettid() -> Pid {
27799 -+ Pid(unsafe { libc::syscall(libc::SYS_gettid) as pid_t })
27800 -+}
27801 -+
27802 -+/// Create a copy of the specified file descriptor (see
27803 -+/// [dup(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.html)).
27804 -+///
27805 -+/// The new file descriptor will be have a new index but refer to the same
27806 -+/// resource as the old file descriptor and the old and new file descriptors may
27807 -+/// be used interchangeably. The new and old file descriptor share the same
27808 -+/// underlying resource, offset, and file status flags. The actual index used
27809 -+/// for the file descriptor will be the lowest fd index that is available.
27810 -+///
27811 -+/// The two file descriptors do not share file descriptor flags (e.g. `OFlag::FD_CLOEXEC`).
27812 -+#[inline]
27813 -+pub fn dup(oldfd: RawFd) -> Result<RawFd> {
27814 -+ let res = unsafe { libc::dup(oldfd) };
27815 -+
27816 -+ Errno::result(res)
27817 -+}
27818 -+
27819 -+/// Create a copy of the specified file descriptor using the specified fd (see
27820 -+/// [dup(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.html)).
27821 -+///
27822 -+/// This function behaves similar to `dup()` except that it will try to use the
27823 -+/// specified fd instead of allocating a new one. See the man pages for more
27824 -+/// detail on the exact behavior of this function.
27825 -+#[inline]
27826 -+pub fn dup2(oldfd: RawFd, newfd: RawFd) -> Result<RawFd> {
27827 -+ let res = unsafe { libc::dup2(oldfd, newfd) };
27828 -+
27829 -+ Errno::result(res)
27830 -+}
27831 -+
27832 -+/// Create a new copy of the specified file descriptor using the specified fd
27833 -+/// and flags (see [dup(2)](http://man7.org/linux/man-pages/man2/dup.2.html)).
27834 -+///
27835 -+/// This function behaves similar to `dup2()` but allows for flags to be
27836 -+/// specified.
27837 -+pub fn dup3(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> {
27838 -+ dup3_polyfill(oldfd, newfd, flags)
27839 -+}
27840 -+
27841 -+#[inline]
27842 -+fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> {
27843 -+ if oldfd == newfd {
27844 -+ return Err(Error::Sys(Errno::EINVAL));
27845 -+ }
27846 -+
27847 -+ let fd = dup2(oldfd, newfd)?;
27848 -+
27849 -+ if flags.contains(OFlag::O_CLOEXEC) {
27850 -+ if let Err(e) = fcntl(fd, F_SETFD(FdFlag::FD_CLOEXEC)) {
27851 -+ let _ = close(fd);
27852 -+ return Err(e);
27853 -+ }
27854 -+ }
27855 -+
27856 -+ Ok(fd)
27857 -+}
27858 -+
27859 -+/// Change the current working directory of the calling process (see
27860 -+/// [chdir(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html)).
27861 -+///
27862 -+/// This function may fail in a number of different scenarios. See the man
27863 -+/// pages for additional details on possible failure cases.
27864 -+#[inline]
27865 -+pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> {
27866 -+ let res = path.with_nix_path(|cstr| {
27867 -+ unsafe { libc::chdir(cstr.as_ptr()) }
27868 -+ })?;
27869 -+
27870 -+ Errno::result(res).map(drop)
27871 -+}
27872 -+
27873 -+/// Change the current working directory of the process to the one
27874 -+/// given as an open file descriptor (see
27875 -+/// [fchdir(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchdir.html)).
27876 -+///
27877 -+/// This function may fail in a number of different scenarios. See the man
27878 -+/// pages for additional details on possible failure cases.
27879 -+#[inline]
27880 -+pub fn fchdir(dirfd: RawFd) -> Result<()> {
27881 -+ let res = unsafe { libc::fchdir(dirfd) };
27882 -+
27883 -+ Errno::result(res).map(drop)
27884 -+}
27885 -+
27886 -+/// Creates new directory `path` with access rights `mode`. (see [mkdir(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdir.html))
27887 -+///
27888 -+/// # Errors
27889 -+///
27890 -+/// There are several situations where mkdir might fail:
27891 -+///
27892 -+/// - current user has insufficient rights in the parent directory
27893 -+/// - the path already exists
27894 -+/// - the path name is too long (longer than `PATH_MAX`, usually 4096 on linux, 1024 on OS X)
27895 -+///
27896 -+/// # Example
27897 -+///
27898 -+/// ```rust
27899 -+/// extern crate tempfile;
27900 -+/// extern crate nix;
27901 -+///
27902 -+/// use nix::unistd;
27903 -+/// use nix::sys::stat;
27904 -+/// use tempfile::tempdir;
27905 -+///
27906 -+/// fn main() {
27907 -+/// let tmp_dir1 = tempdir().unwrap();
27908 -+/// let tmp_dir2 = tmp_dir1.path().join("new_dir");
27909 -+///
27910 -+/// // create new directory and give read, write and execute rights to the owner
27911 -+/// match unistd::mkdir(&tmp_dir2, stat::Mode::S_IRWXU) {
27912 -+/// Ok(_) => println!("created {:?}", tmp_dir2),
27913 -+/// Err(err) => println!("Error creating directory: {}", err),
27914 -+/// }
27915 -+/// }
27916 -+/// ```
27917 -+#[inline]
27918 -+pub fn mkdir<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
27919 -+ let res = path.with_nix_path(|cstr| {
27920 -+ unsafe { libc::mkdir(cstr.as_ptr(), mode.bits() as mode_t) }
27921 -+ })?;
27922 -+
27923 -+ Errno::result(res).map(drop)
27924 -+}
27925 -+
27926 -+/// Creates new fifo special file (named pipe) with path `path` and access rights `mode`.
27927 -+///
27928 -+/// # Errors
27929 -+///
27930 -+/// There are several situations where mkfifo might fail:
27931 -+///
27932 -+/// - current user has insufficient rights in the parent directory
27933 -+/// - the path already exists
27934 -+/// - the path name is too long (longer than `PATH_MAX`, usually 4096 on linux, 1024 on OS X)
27935 -+///
27936 -+/// For a full list consult
27937 -+/// [posix specification](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifo.html)
27938 -+///
27939 -+/// # Example
27940 -+///
27941 -+/// ```rust
27942 -+/// extern crate tempfile;
27943 -+/// extern crate nix;
27944 -+///
27945 -+/// use nix::unistd;
27946 -+/// use nix::sys::stat;
27947 -+/// use tempfile::tempdir;
27948 -+///
27949 -+/// fn main() {
27950 -+/// let tmp_dir = tempdir().unwrap();
27951 -+/// let fifo_path = tmp_dir.path().join("foo.pipe");
27952 -+///
27953 -+/// // create new fifo and give read, write and execute rights to the owner
27954 -+/// match unistd::mkfifo(&fifo_path, stat::Mode::S_IRWXU) {
27955 -+/// Ok(_) => println!("created {:?}", fifo_path),
27956 -+/// Err(err) => println!("Error creating fifo: {}", err),
27957 -+/// }
27958 -+/// }
27959 -+/// ```
27960 -+#[inline]
27961 -+pub fn mkfifo<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
27962 -+ let res = path.with_nix_path(|cstr| {
27963 -+ unsafe { libc::mkfifo(cstr.as_ptr(), mode.bits() as mode_t) }
27964 -+ })?;
27965 -+
27966 -+ Errno::result(res).map(drop)
27967 -+}
27968 -+
27969 -+/// Creates a symbolic link at `path2` which points to `path1`.
27970 -+///
27971 -+/// If `dirfd` has a value, then `path2` is relative to directory associated
27972 -+/// with the file descriptor.
27973 -+///
27974 -+/// If `dirfd` is `None`, then `path2` is relative to the current working
27975 -+/// directory. This is identical to `libc::symlink(path1, path2)`.
27976 -+///
27977 -+/// See also [symlinkat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/symlinkat.html).
27978 -+pub fn symlinkat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
27979 -+ path1: &P1,
27980 -+ dirfd: Option<RawFd>,
27981 -+ path2: &P2) -> Result<()> {
27982 -+ let res =
27983 -+ path1.with_nix_path(|path1| {
27984 -+ path2.with_nix_path(|path2| {
27985 -+ unsafe {
27986 -+ libc::symlinkat(
27987 -+ path1.as_ptr(),
27988 -+ dirfd.unwrap_or(libc::AT_FDCWD),
27989 -+ path2.as_ptr()
27990 -+ )
27991 -+ }
27992 -+ })
27993 -+ })??;
27994 -+ Errno::result(res).map(drop)
27995 -+}
27996 -+
27997 -+/// Returns the current directory as a `PathBuf`
27998 -+///
27999 -+/// Err is returned if the current user doesn't have the permission to read or search a component
28000 -+/// of the current path.
28001 -+///
28002 -+/// # Example
28003 -+///
28004 -+/// ```rust
28005 -+/// extern crate nix;
28006 -+///
28007 -+/// use nix::unistd;
28008 -+///
28009 -+/// fn main() {
28010 -+/// // assume that we are allowed to get current directory
28011 -+/// let dir = unistd::getcwd().unwrap();
28012 -+/// println!("The current directory is {:?}", dir);
28013 -+/// }
28014 -+/// ```
28015 -+#[inline]
28016 -+pub fn getcwd() -> Result<PathBuf> {
28017 -+ let mut buf = Vec::with_capacity(512);
28018 -+ loop {
28019 -+ unsafe {
28020 -+ let ptr = buf.as_mut_ptr() as *mut c_char;
28021 -+
28022 -+ // The buffer must be large enough to store the absolute pathname plus
28023 -+ // a terminating null byte, or else null is returned.
28024 -+ // To safely handle this we start with a reasonable size (512 bytes)
28025 -+ // and double the buffer size upon every error
28026 -+ if !libc::getcwd(ptr, buf.capacity()).is_null() {
28027 -+ let len = CStr::from_ptr(buf.as_ptr() as *const c_char).to_bytes().len();
28028 -+ buf.set_len(len);
28029 -+ buf.shrink_to_fit();
28030 -+ return Ok(PathBuf::from(OsString::from_vec(buf)));
28031 -+ } else {
28032 -+ let error = Errno::last();
28033 -+ // ERANGE means buffer was too small to store directory name
28034 -+ if error != Errno::ERANGE {
28035 -+ return Err(Error::Sys(error));
28036 -+ }
28037 -+ }
28038 -+
28039 -+ // Trigger the internal buffer resizing logic of `Vec` by requiring
28040 -+ // more space than the current capacity.
28041 -+ let cap = buf.capacity();
28042 -+ buf.set_len(cap);
28043 -+ buf.reserve(1);
28044 -+ }
28045 -+ }
28046 -+}
28047 -+
28048 -+/// Computes the raw UID and GID values to pass to a `*chown` call.
28049 -+fn chown_raw_ids(owner: Option<Uid>, group: Option<Gid>) -> (libc::uid_t, libc::gid_t) {
28050 -+ // According to the POSIX specification, -1 is used to indicate that owner and group
28051 -+ // are not to be changed. Since uid_t and gid_t are unsigned types, we have to wrap
28052 -+ // around to get -1.
28053 -+ let uid = owner.map(Into::into).unwrap_or((0 as uid_t).wrapping_sub(1));
28054 -+ let gid = group.map(Into::into).unwrap_or((0 as gid_t).wrapping_sub(1));
28055 -+ (uid, gid)
28056 -+}
28057 -+
28058 -+/// Change the ownership of the file at `path` to be owned by the specified
28059 -+/// `owner` (user) and `group` (see
28060 -+/// [chown(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/chown.html)).
28061 -+///
28062 -+/// The owner/group for the provided path name will not be modified if `None` is
28063 -+/// provided for that argument. Ownership change will be attempted for the path
28064 -+/// only if `Some` owner/group is provided.
28065 -+#[inline]
28066 -+pub fn chown<P: ?Sized + NixPath>(path: &P, owner: Option<Uid>, group: Option<Gid>) -> Result<()> {
28067 -+ let res = path.with_nix_path(|cstr| {
28068 -+ let (uid, gid) = chown_raw_ids(owner, group);
28069 -+ unsafe { libc::chown(cstr.as_ptr(), uid, gid) }
28070 -+ })?;
28071 -+
28072 -+ Errno::result(res).map(drop)
28073 -+}
28074 -+
28075 -+/// Flags for `fchownat` function.
28076 -+#[derive(Clone, Copy, Debug)]
28077 -+pub enum FchownatFlags {
28078 -+ FollowSymlink,
28079 -+ NoFollowSymlink,
28080 -+}
28081 -+
28082 -+/// Change the ownership of the file at `path` to be owned by the specified
28083 -+/// `owner` (user) and `group`.
28084 -+///
28085 -+/// The owner/group for the provided path name will not be modified if `None` is
28086 -+/// provided for that argument. Ownership change will be attempted for the path
28087 -+/// only if `Some` owner/group is provided.
28088 -+///
28089 -+/// The file to be changed is determined relative to the directory associated
28090 -+/// with the file descriptor `dirfd` or the current working directory
28091 -+/// if `dirfd` is `None`.
28092 -+///
28093 -+/// If `flag` is `FchownatFlags::NoFollowSymlink` and `path` names a symbolic link,
28094 -+/// then the mode of the symbolic link is changed.
28095 -+///
28096 -+/// `fchownat(None, path, mode, FchownatFlags::NoFollowSymlink)` is identical to
28097 -+/// a call `libc::lchown(path, mode)`. That's why `lchmod` is unimplemented in
28098 -+/// the `nix` crate.
28099 -+///
28100 -+/// # References
28101 -+///
28102 -+/// [fchownat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchownat.html).
28103 -+pub fn fchownat<P: ?Sized + NixPath>(
28104 -+ dirfd: Option<RawFd>,
28105 -+ path: &P,
28106 -+ owner: Option<Uid>,
28107 -+ group: Option<Gid>,
28108 -+ flag: FchownatFlags,
28109 -+) -> Result<()> {
28110 -+ let atflag =
28111 -+ match flag {
28112 -+ FchownatFlags::FollowSymlink => AtFlags::empty(),
28113 -+ FchownatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW,
28114 -+ };
28115 -+ let res = path.with_nix_path(|cstr| unsafe {
28116 -+ let (uid, gid) = chown_raw_ids(owner, group);
28117 -+ libc::fchownat(at_rawfd(dirfd), cstr.as_ptr(), uid, gid,
28118 -+ atflag.bits() as libc::c_int)
28119 -+ })?;
28120 -+
28121 -+ Errno::result(res).map(drop)
28122 -+}
28123 -+
28124 -+fn to_exec_array(args: &[CString]) -> Vec<*const c_char> {
28125 -+ let mut args_p: Vec<*const c_char> = args.iter().map(|s| s.as_ptr()).collect();
28126 -+ args_p.push(ptr::null());
28127 -+ args_p
28128 -+}
28129 -+
28130 -+/// Replace the current process image with a new one (see
28131 -+/// [exec(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)).
28132 -+///
28133 -+/// See the `::nix::unistd::execve` system call for additional details. `execv`
28134 -+/// performs the same action but does not allow for customization of the
28135 -+/// environment for the new process.
28136 -+#[inline]
28137 -+pub fn execv(path: &CString, argv: &[CString]) -> Result<Void> {
28138 -+ let args_p = to_exec_array(argv);
28139 -+
28140 -+ unsafe {
28141 -+ libc::execv(path.as_ptr(), args_p.as_ptr())
28142 -+ };
28143 -+
28144 -+ Err(Error::Sys(Errno::last()))
28145 -+}
28146 -+
28147 -+
28148 -+/// Replace the current process image with a new one (see
28149 -+/// [execve(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)).
28150 -+///
28151 -+/// The execve system call allows for another process to be "called" which will
28152 -+/// replace the current process image. That is, this process becomes the new
28153 -+/// command that is run. On success, this function will not return. Instead,
28154 -+/// the new program will run until it exits.
28155 -+///
28156 -+/// `::nix::unistd::execv` and `::nix::unistd::execve` take as arguments a slice
28157 -+/// of `::std::ffi::CString`s for `args` and `env` (for `execve`). Each element
28158 -+/// in the `args` list is an argument to the new process. Each element in the
28159 -+/// `env` list should be a string in the form "key=value".
28160 -+#[inline]
28161 -+pub fn execve(path: &CString, args: &[CString], env: &[CString]) -> Result<Void> {
28162 -+ let args_p = to_exec_array(args);
28163 -+ let env_p = to_exec_array(env);
28164 -+
28165 -+ unsafe {
28166 -+ libc::execve(path.as_ptr(), args_p.as_ptr(), env_p.as_ptr())
28167 -+ };
28168 -+
28169 -+ Err(Error::Sys(Errno::last()))
28170 -+}
28171 -+
28172 -+/// Replace the current process image with a new one and replicate shell `PATH`
28173 -+/// searching behavior (see
28174 -+/// [exec(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)).
28175 -+///
28176 -+/// See `::nix::unistd::execve` for additional details. `execvp` behaves the
28177 -+/// same as execv except that it will examine the `PATH` environment variables
28178 -+/// for file names not specified with a leading slash. For example, `execv`
28179 -+/// would not work if "bash" was specified for the path argument, but `execvp`
28180 -+/// would assuming that a bash executable was on the system `PATH`.
28181 -+#[inline]
28182 -+pub fn execvp(filename: &CString, args: &[CString]) -> Result<Void> {
28183 -+ let args_p = to_exec_array(args);
28184 -+
28185 -+ unsafe {
28186 -+ libc::execvp(filename.as_ptr(), args_p.as_ptr())
28187 -+ };
28188 -+
28189 -+ Err(Error::Sys(Errno::last()))
28190 -+}
28191 -+
28192 -+/// Replace the current process image with a new one and replicate shell `PATH`
28193 -+/// searching behavior (see
28194 -+/// [`execvpe(3)`](http://man7.org/linux/man-pages/man3/exec.3.html)).
28195 -+///
28196 -+/// This functions like a combination of `execvp(2)` and `execve(2)` to pass an
28197 -+/// environment and have a search path. See these two for additional
28198 -+/// information.
28199 -+#[cfg(any(target_os = "haiku",
28200 -+ target_os = "linux",
28201 -+ target_os = "openbsd"))]
28202 -+pub fn execvpe(filename: &CString, args: &[CString], env: &[CString]) -> Result<Void> {
28203 -+ let args_p = to_exec_array(args);
28204 -+ let env_p = to_exec_array(env);
28205 -+
28206 -+ unsafe {
28207 -+ libc::execvpe(filename.as_ptr(), args_p.as_ptr(), env_p.as_ptr())
28208 -+ };
28209 -+
28210 -+ Err(Error::Sys(Errno::last()))
28211 -+}
28212 -+
28213 -+/// Replace the current process image with a new one (see
28214 -+/// [fexecve(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fexecve.html)).
28215 -+///
28216 -+/// The `fexecve` function allows for another process to be "called" which will
28217 -+/// replace the current process image. That is, this process becomes the new
28218 -+/// command that is run. On success, this function will not return. Instead,
28219 -+/// the new program will run until it exits.
28220 -+///
28221 -+/// This function is similar to `execve`, except that the program to be executed
28222 -+/// is referenced as a file descriptor instead of a path.
28223 -+// Note for NetBSD and OpenBSD: although rust-lang/libc includes it (under
28224 -+// unix/bsd/netbsdlike/) fexecve is not currently implemented on NetBSD nor on
28225 -+// OpenBSD.
28226 -+#[cfg(any(target_os = "android",
28227 -+ target_os = "linux",
28228 -+ target_os = "freebsd"))]
28229 -+#[inline]
28230 -+pub fn fexecve(fd: RawFd, args: &[CString], env: &[CString]) -> Result<Void> {
28231 -+ let args_p = to_exec_array(args);
28232 -+ let env_p = to_exec_array(env);
28233 -+
28234 -+ unsafe {
28235 -+ libc::fexecve(fd, args_p.as_ptr(), env_p.as_ptr())
28236 -+ };
28237 -+
28238 -+ Err(Error::Sys(Errno::last()))
28239 -+}
28240 -+
28241 -+/// Execute program relative to a directory file descriptor (see
28242 -+/// [execveat(2)](http://man7.org/linux/man-pages/man2/execveat.2.html)).
28243 -+///
28244 -+/// The `execveat` function allows for another process to be "called" which will
28245 -+/// replace the current process image. That is, this process becomes the new
28246 -+/// command that is run. On success, this function will not return. Instead,
28247 -+/// the new program will run until it exits.
28248 -+///
28249 -+/// This function is similar to `execve`, except that the program to be executed
28250 -+/// is referenced as a file descriptor to the base directory plus a path.
28251 -+#[cfg(any(target_os = "android", target_os = "linux"))]
28252 -+#[inline]
28253 -+pub fn execveat(dirfd: RawFd, pathname: &CString, args: &[CString],
28254 -+ env: &[CString], flags: super::fcntl::AtFlags) -> Result<Void> {
28255 -+ let args_p = to_exec_array(args);
28256 -+ let env_p = to_exec_array(env);
28257 -+
28258 -+ unsafe {
28259 -+ libc::syscall(libc::SYS_execveat, dirfd, pathname.as_ptr(),
28260 -+ args_p.as_ptr(), env_p.as_ptr(), flags);
28261 -+ };
28262 -+
28263 -+ Err(Error::Sys(Errno::last()))
28264 -+}
28265 -+
28266 -+/// Daemonize this process by detaching from the controlling terminal (see
28267 -+/// [daemon(3)](http://man7.org/linux/man-pages/man3/daemon.3.html)).
28268 -+///
28269 -+/// When a process is launched it is typically associated with a parent and it,
28270 -+/// in turn, by its controlling terminal/process. In order for a process to run
28271 -+/// in the "background" it must daemonize itself by detaching itself. Under
28272 -+/// posix, this is done by doing the following:
28273 -+///
28274 -+/// 1. Parent process (this one) forks
28275 -+/// 2. Parent process exits
28276 -+/// 3. Child process continues to run.
28277 -+///
28278 -+/// `nochdir`:
28279 -+///
28280 -+/// * `nochdir = true`: The current working directory after daemonizing will
28281 -+/// be the current working directory.
28282 -+/// * `nochdir = false`: The current working directory after daemonizing will
28283 -+/// be the root direcory, `/`.
28284 -+///
28285 -+/// `noclose`:
28286 -+///
28287 -+/// * `noclose = true`: The process' current stdin, stdout, and stderr file
28288 -+/// descriptors will remain identical after daemonizing.
28289 -+/// * `noclose = false`: The process' stdin, stdout, and stderr will point to
28290 -+/// `/dev/null` after daemonizing.
28291 -+#[cfg_attr(any(target_os = "macos", target_os = "ios"), deprecated(
28292 -+ since="0.14.0",
28293 -+ note="Deprecated in MacOSX 10.5"
28294 -+))]
28295 -+#[cfg_attr(any(target_os = "macos", target_os = "ios"), allow(deprecated))]
28296 -+pub fn daemon(nochdir: bool, noclose: bool) -> Result<()> {
28297 -+ let res = unsafe { libc::daemon(nochdir as c_int, noclose as c_int) };
28298 -+ Errno::result(res).map(drop)
28299 -+}
28300 -+
28301 -+/// Set the system host name (see
28302 -+/// [sethostname(2)](http://man7.org/linux/man-pages/man2/gethostname.2.html)).
28303 -+///
28304 -+/// Given a name, attempt to update the system host name to the given string.
28305 -+/// On some systems, the host name is limited to as few as 64 bytes. An error
28306 -+/// will be return if the name is not valid or the current process does not have
28307 -+/// permissions to update the host name.
28308 -+pub fn sethostname<S: AsRef<OsStr>>(name: S) -> Result<()> {
28309 -+ // Handle some differences in type of the len arg across platforms.
28310 -+ cfg_if! {
28311 -+ if #[cfg(any(target_os = "dragonfly",
28312 -+ target_os = "freebsd",
28313 -+ target_os = "ios",
28314 -+ target_os = "macos", ))] {
28315 -+ type sethostname_len_t = c_int;
28316 -+ } else {
28317 -+ type sethostname_len_t = size_t;
28318 -+ }
28319 -+ }
28320 -+ let ptr = name.as_ref().as_bytes().as_ptr() as *const c_char;
28321 -+ let len = name.as_ref().len() as sethostname_len_t;
28322 -+
28323 -+ let res = unsafe { libc::sethostname(ptr, len) };
28324 -+ Errno::result(res).map(drop)
28325 -+}
28326 -+
28327 -+/// Get the host name and store it in the provided buffer, returning a pointer
28328 -+/// the `CStr` in that buffer on success (see
28329 -+/// [gethostname(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html)).
28330 -+///
28331 -+/// This function call attempts to get the host name for the running system and
28332 -+/// store it in a provided buffer. The buffer will be populated with bytes up
28333 -+/// to the length of the provided slice including a NUL terminating byte. If
28334 -+/// the hostname is longer than the length provided, no error will be provided.
28335 -+/// The posix specification does not specify whether implementations will
28336 -+/// null-terminate in this case, but the nix implementation will ensure that the
28337 -+/// buffer is null terminated in this case.
28338 -+///
28339 -+/// ```no_run
28340 -+/// use nix::unistd;
28341 -+///
28342 -+/// let mut buf = [0u8; 64];
28343 -+/// let hostname_cstr = unistd::gethostname(&mut buf).expect("Failed getting hostname");
28344 -+/// let hostname = hostname_cstr.to_str().expect("Hostname wasn't valid UTF-8");
28345 -+/// println!("Hostname: {}", hostname);
28346 -+/// ```
28347 -+pub fn gethostname(buffer: &mut [u8]) -> Result<&CStr> {
28348 -+ let ptr = buffer.as_mut_ptr() as *mut c_char;
28349 -+ let len = buffer.len() as size_t;
28350 -+
28351 -+ let res = unsafe { libc::gethostname(ptr, len) };
28352 -+ Errno::result(res).map(|_| {
28353 -+ buffer[len - 1] = 0; // ensure always null-terminated
28354 -+ unsafe { CStr::from_ptr(buffer.as_ptr() as *const c_char) }
28355 -+ })
28356 -+}
28357 -+
28358 -+/// Close a raw file descriptor
28359 -+///
28360 -+/// Be aware that many Rust types implicitly close-on-drop, including
28361 -+/// `std::fs::File`. Explicitly closing them with this method too can result in
28362 -+/// a double-close condition, which can cause confusing `EBADF` errors in
28363 -+/// seemingly unrelated code. Caveat programmer. See also
28364 -+/// [close(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html).
28365 -+///
28366 -+/// # Examples
28367 -+///
28368 -+/// ```no_run
28369 -+/// extern crate tempfile;
28370 -+/// extern crate nix;
28371 -+///
28372 -+/// use std::os::unix::io::AsRawFd;
28373 -+/// use nix::unistd::close;
28374 -+///
28375 -+/// fn main() {
28376 -+/// let f = tempfile::tempfile().unwrap();
28377 -+/// close(f.as_raw_fd()).unwrap(); // Bad! f will also close on drop!
28378 -+/// }
28379 -+/// ```
28380 -+///
28381 -+/// ```rust
28382 -+/// extern crate tempfile;
28383 -+/// extern crate nix;
28384 -+///
28385 -+/// use std::os::unix::io::IntoRawFd;
28386 -+/// use nix::unistd::close;
28387 -+///
28388 -+/// fn main() {
28389 -+/// let f = tempfile::tempfile().unwrap();
28390 -+/// close(f.into_raw_fd()).unwrap(); // Good. into_raw_fd consumes f
28391 -+/// }
28392 -+/// ```
28393 -+pub fn close(fd: RawFd) -> Result<()> {
28394 -+ let res = unsafe { libc::close(fd) };
28395 -+ Errno::result(res).map(drop)
28396 -+}
28397 -+
28398 -+/// Read from a raw file descriptor.
28399 -+///
28400 -+/// See also [read(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html)
28401 -+pub fn read(fd: RawFd, buf: &mut [u8]) -> Result<usize> {
28402 -+ let res = unsafe { libc::read(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t) };
28403 -+
28404 -+ Errno::result(res).map(|r| r as usize)
28405 -+}
28406 -+
28407 -+/// Write to a raw file descriptor.
28408 -+///
28409 -+/// See also [write(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html)
28410 -+pub fn write(fd: RawFd, buf: &[u8]) -> Result<usize> {
28411 -+ let res = unsafe { libc::write(fd, buf.as_ptr() as *const c_void, buf.len() as size_t) };
28412 -+
28413 -+ Errno::result(res).map(|r| r as usize)
28414 -+}
28415 -+
28416 -+/// Directive that tells [`lseek`] and [`lseek64`] what the offset is relative to.
28417 -+///
28418 -+/// [`lseek`]: ./fn.lseek.html
28419 -+/// [`lseek64`]: ./fn.lseek64.html
28420 -+#[repr(i32)]
28421 -+#[derive(Clone, Copy, Debug)]
28422 -+pub enum Whence {
28423 -+ /// Specify an offset relative to the start of the file.
28424 -+ SeekSet = libc::SEEK_SET,
28425 -+ /// Specify an offset relative to the current file location.
28426 -+ SeekCur = libc::SEEK_CUR,
28427 -+ /// Specify an offset relative to the end of the file.
28428 -+ SeekEnd = libc::SEEK_END,
28429 -+ /// Specify an offset relative to the next location in the file greater than or
28430 -+ /// equal to offset that contains some data. If offset points to
28431 -+ /// some data, then the file offset is set to offset.
28432 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
28433 -+ all(target_os = "linux", not(any(target_env = "musl",
28434 -+ target_arch = "mips",
28435 -+ target_arch = "mips64")))))]
28436 -+ SeekData = libc::SEEK_DATA,
28437 -+ /// Specify an offset relative to the next hole in the file greater than
28438 -+ /// or equal to offset. If offset points into the middle of a hole, then
28439 -+ /// the file offset should be set to offset. If there is no hole past offset,
28440 -+ /// then the file offset should be adjusted to the end of the file (i.e., there
28441 -+ /// is an implicit hole at the end of any file).
28442 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
28443 -+ all(target_os = "linux", not(any(target_env = "musl",
28444 -+ target_arch = "mips",
28445 -+ target_arch = "mips64")))))]
28446 -+ SeekHole = libc::SEEK_HOLE
28447 -+}
28448 -+
28449 -+/// Move the read/write file offset.
28450 -+///
28451 -+/// See also [lseek(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html)
28452 -+pub fn lseek(fd: RawFd, offset: off_t, whence: Whence) -> Result<off_t> {
28453 -+ let res = unsafe { libc::lseek(fd, offset, whence as i32) };
28454 -+
28455 -+ Errno::result(res).map(|r| r as off_t)
28456 -+}
28457 -+
28458 -+#[cfg(any(target_os = "linux", target_os = "android"))]
28459 -+pub fn lseek64(fd: RawFd, offset: libc::off64_t, whence: Whence) -> Result<libc::off64_t> {
28460 -+ let res = unsafe { libc::lseek64(fd, offset, whence as i32) };
28461 -+
28462 -+ Errno::result(res).map(|r| r as libc::off64_t)
28463 -+}
28464 -+
28465 -+/// Create an interprocess channel.
28466 -+///
28467 -+/// See also [pipe(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pipe.html)
28468 -+pub fn pipe() -> Result<(RawFd, RawFd)> {
28469 -+ unsafe {
28470 -+ let mut fds: [c_int; 2] = mem::uninitialized();
28471 -+
28472 -+ let res = libc::pipe(fds.as_mut_ptr());
28473 -+
28474 -+ Errno::result(res)?;
28475 -+
28476 -+ Ok((fds[0], fds[1]))
28477 -+ }
28478 -+}
28479 -+
28480 -+/// Like `pipe`, but allows setting certain file descriptor flags.
28481 -+///
28482 -+/// The following flags are supported, and will be set atomically as the pipe is
28483 -+/// created:
28484 -+///
28485 -+/// `O_CLOEXEC`: Set the close-on-exec flag for the new file descriptors.
28486 -+/// `O_NONBLOCK`: Set the non-blocking flag for the ends of the pipe.
28487 -+///
28488 -+/// See also [pipe(2)](http://man7.org/linux/man-pages/man2/pipe.2.html)
28489 -+#[cfg(any(target_os = "android",
28490 -+ target_os = "dragonfly",
28491 -+ target_os = "emscripten",
28492 -+ target_os = "freebsd",
28493 -+ target_os = "linux",
28494 -+ target_os = "netbsd",
28495 -+ target_os = "openbsd"))]
28496 -+pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
28497 -+ let mut fds: [c_int; 2] = unsafe { mem::uninitialized() };
28498 -+
28499 -+ let res = unsafe { libc::pipe2(fds.as_mut_ptr(), flags.bits()) };
28500 -+
28501 -+ Errno::result(res)?;
28502 -+
28503 -+ Ok((fds[0], fds[1]))
28504 -+}
28505 -+
28506 -+/// Like `pipe`, but allows setting certain file descriptor flags.
28507 -+///
28508 -+/// The following flags are supported, and will be set after the pipe is
28509 -+/// created:
28510 -+///
28511 -+/// `O_CLOEXEC`: Set the close-on-exec flag for the new file descriptors.
28512 -+/// `O_NONBLOCK`: Set the non-blocking flag for the ends of the pipe.
28513 -+#[cfg(any(target_os = "ios", target_os = "macos"))]
28514 -+#[deprecated(
28515 -+ since="0.10.0",
28516 -+ note="pipe2(2) is not actually atomic on these platforms. Use pipe(2) and fcntl(2) instead"
28517 -+)]
28518 -+pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
28519 -+ let mut fds: [c_int; 2] = unsafe { mem::uninitialized() };
28520 -+
28521 -+ let res = unsafe { libc::pipe(fds.as_mut_ptr()) };
28522 -+
28523 -+ Errno::result(res)?;
28524 -+
28525 -+ pipe2_setflags(fds[0], fds[1], flags)?;
28526 -+
28527 -+ Ok((fds[0], fds[1]))
28528 -+}
28529 -+
28530 -+#[cfg(any(target_os = "ios", target_os = "macos"))]
28531 -+fn pipe2_setflags(fd1: RawFd, fd2: RawFd, flags: OFlag) -> Result<()> {
28532 -+ use fcntl::FcntlArg::F_SETFL;
28533 -+
28534 -+ let mut res = Ok(0);
28535 -+
28536 -+ if flags.contains(OFlag::O_CLOEXEC) {
28537 -+ res = res
28538 -+ .and_then(|_| fcntl(fd1, F_SETFD(FdFlag::FD_CLOEXEC)))
28539 -+ .and_then(|_| fcntl(fd2, F_SETFD(FdFlag::FD_CLOEXEC)));
28540 -+ }
28541 -+
28542 -+ if flags.contains(OFlag::O_NONBLOCK) {
28543 -+ res = res
28544 -+ .and_then(|_| fcntl(fd1, F_SETFL(OFlag::O_NONBLOCK)))
28545 -+ .and_then(|_| fcntl(fd2, F_SETFL(OFlag::O_NONBLOCK)));
28546 -+ }
28547 -+
28548 -+ match res {
28549 -+ Ok(_) => Ok(()),
28550 -+ Err(e) => {
28551 -+ let _ = close(fd1);
28552 -+ let _ = close(fd2);
28553 -+ Err(e)
28554 -+ }
28555 -+ }
28556 -+}
28557 -+
28558 -+/// Truncate a file to a specified length
28559 -+///
28560 -+/// See also
28561 -+/// [truncate(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html)
28562 -+pub fn truncate<P: ?Sized + NixPath>(path: &P, len: off_t) -> Result<()> {
28563 -+ let res = path.with_nix_path(|cstr| {
28564 -+ unsafe {
28565 -+ libc::truncate(cstr.as_ptr(), len)
28566 -+ }
28567 -+ })?;
28568 -+
28569 -+ Errno::result(res).map(drop)
28570 -+}
28571 -+
28572 -+/// Truncate a file to a specified length
28573 -+///
28574 -+/// See also
28575 -+/// [ftruncate(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html)
28576 -+pub fn ftruncate(fd: RawFd, len: off_t) -> Result<()> {
28577 -+ Errno::result(unsafe { libc::ftruncate(fd, len) }).map(drop)
28578 -+}
28579 -+
28580 -+pub fn isatty(fd: RawFd) -> Result<bool> {
28581 -+ unsafe {
28582 -+ // ENOTTY means `fd` is a valid file descriptor, but not a TTY, so
28583 -+ // we return `Ok(false)`
28584 -+ if libc::isatty(fd) == 1 {
28585 -+ Ok(true)
28586 -+ } else {
28587 -+ match Errno::last() {
28588 -+ Errno::ENOTTY => Ok(false),
28589 -+ err => Err(Error::Sys(err)),
28590 -+ }
28591 -+ }
28592 -+ }
28593 -+}
28594 -+
28595 -+/// Remove a directory entry
28596 -+///
28597 -+/// See also [unlink(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html)
28598 -+pub fn unlink<P: ?Sized + NixPath>(path: &P) -> Result<()> {
28599 -+ let res = path.with_nix_path(|cstr| {
28600 -+ unsafe {
28601 -+ libc::unlink(cstr.as_ptr())
28602 -+ }
28603 -+ })?;
28604 -+ Errno::result(res).map(drop)
28605 -+}
28606 -+
28607 -+/// Flags for `unlinkat` function.
28608 -+#[derive(Clone, Copy, Debug)]
28609 -+pub enum UnlinkatFlags {
28610 -+ RemoveDir,
28611 -+ NoRemoveDir,
28612 -+}
28613 -+
28614 -+/// Remove a directory entry
28615 -+///
28616 -+/// In the case of a relative path, the directory entry to be removed is determined relative to
28617 -+/// the directory associated with the file descriptor `dirfd` or the current working directory
28618 -+/// if `dirfd` is `None`. In the case of an absolute `path` `dirfd` is ignored. If `flag` is
28619 -+/// `UnlinkatFlags::RemoveDir` then removal of the directory entry specified by `dirfd` and `path`
28620 -+/// is performed.
28621 -+///
28622 -+/// # References
28623 -+/// See also [unlinkat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlinkat.html)
28624 -+pub fn unlinkat<P: ?Sized + NixPath>(
28625 -+ dirfd: Option<RawFd>,
28626 -+ path: &P,
28627 -+ flag: UnlinkatFlags,
28628 -+) -> Result<()> {
28629 -+ let atflag =
28630 -+ match flag {
28631 -+ UnlinkatFlags::RemoveDir => AtFlags::AT_REMOVEDIR,
28632 -+ UnlinkatFlags::NoRemoveDir => AtFlags::empty(),
28633 -+ };
28634 -+ let res = path.with_nix_path(|cstr| {
28635 -+ unsafe {
28636 -+ libc::unlinkat(at_rawfd(dirfd), cstr.as_ptr(), atflag.bits() as libc::c_int)
28637 -+ }
28638 -+ })?;
28639 -+ Errno::result(res).map(drop)
28640 -+}
28641 -+
28642 -+
28643 -+#[inline]
28644 -+pub fn chroot<P: ?Sized + NixPath>(path: &P) -> Result<()> {
28645 -+ let res = path.with_nix_path(|cstr| {
28646 -+ unsafe { libc::chroot(cstr.as_ptr()) }
28647 -+ })?;
28648 -+
28649 -+ Errno::result(res).map(drop)
28650 -+}
28651 -+
28652 -+/// Commit filesystem caches to disk
28653 -+///
28654 -+/// See also [sync(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sync.html)
28655 -+#[cfg(any(
28656 -+ target_os = "dragonfly",
28657 -+ target_os = "freebsd",
28658 -+ target_os = "linux",
28659 -+ target_os = "netbsd",
28660 -+ target_os = "openbsd"
28661 -+))]
28662 -+pub fn sync() -> () {
28663 -+ unsafe { libc::sync() };
28664 -+}
28665 -+
28666 -+/// Synchronize changes to a file
28667 -+///
28668 -+/// See also [fsync(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html)
28669 -+#[inline]
28670 -+pub fn fsync(fd: RawFd) -> Result<()> {
28671 -+ let res = unsafe { libc::fsync(fd) };
28672 -+
28673 -+ Errno::result(res).map(drop)
28674 -+}
28675 -+
28676 -+/// Synchronize the data of a file
28677 -+///
28678 -+/// See also
28679 -+/// [fdatasync(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html)
28680 -+// `fdatasync(2) is in POSIX, but in libc it is only defined in `libc::notbsd`.
28681 -+// TODO: exclude only Apple systems after https://github.com/rust-lang/libc/pull/211
28682 -+#[cfg(any(target_os = "linux",
28683 -+ target_os = "android",
28684 -+ target_os = "emscripten"))]
28685 -+#[inline]
28686 -+pub fn fdatasync(fd: RawFd) -> Result<()> {
28687 -+ let res = unsafe { libc::fdatasync(fd) };
28688 -+
28689 -+ Errno::result(res).map(drop)
28690 -+}
28691 -+
28692 -+/// Get a real user ID
28693 -+///
28694 -+/// See also [getuid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getuid.html)
28695 -+// POSIX requires that getuid is always successful, so no need to check return
28696 -+// value or errno.
28697 -+#[inline]
28698 -+pub fn getuid() -> Uid {
28699 -+ Uid(unsafe { libc::getuid() })
28700 -+}
28701 -+
28702 -+/// Get the effective user ID
28703 -+///
28704 -+/// See also [geteuid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/geteuid.html)
28705 -+// POSIX requires that geteuid is always successful, so no need to check return
28706 -+// value or errno.
28707 -+#[inline]
28708 -+pub fn geteuid() -> Uid {
28709 -+ Uid(unsafe { libc::geteuid() })
28710 -+}
28711 -+
28712 -+/// Get the real group ID
28713 -+///
28714 -+/// See also [getgid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getgid.html)
28715 -+// POSIX requires that getgid is always successful, so no need to check return
28716 -+// value or errno.
28717 -+#[inline]
28718 -+pub fn getgid() -> Gid {
28719 -+ Gid(unsafe { libc::getgid() })
28720 -+}
28721 -+
28722 -+/// Get the effective group ID
28723 -+///
28724 -+/// See also [getegid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getegid.html)
28725 -+// POSIX requires that getegid is always successful, so no need to check return
28726 -+// value or errno.
28727 -+#[inline]
28728 -+pub fn getegid() -> Gid {
28729 -+ Gid(unsafe { libc::getegid() })
28730 -+}
28731 -+
28732 -+/// Set the effective user ID
28733 -+///
28734 -+/// See also [seteuid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/seteuid.html)
28735 -+#[inline]
28736 -+pub fn seteuid(euid: Uid) -> Result<()> {
28737 -+ let res = unsafe { libc::seteuid(euid.into()) };
28738 -+
28739 -+ Errno::result(res).map(drop)
28740 -+}
28741 -+
28742 -+/// Set the effective group ID
28743 -+///
28744 -+/// See also [setegid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setegid.html)
28745 -+#[inline]
28746 -+pub fn setegid(egid: Gid) -> Result<()> {
28747 -+ let res = unsafe { libc::setegid(egid.into()) };
28748 -+
28749 -+ Errno::result(res).map(drop)
28750 -+}
28751 -+
28752 -+/// Set the user ID
28753 -+///
28754 -+/// See also [setuid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setuid.html)
28755 -+#[inline]
28756 -+pub fn setuid(uid: Uid) -> Result<()> {
28757 -+ let res = unsafe { libc::setuid(uid.into()) };
28758 -+
28759 -+ Errno::result(res).map(drop)
28760 -+}
28761 -+
28762 -+/// Set the group ID
28763 -+///
28764 -+/// See also [setgid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setgid.html)
28765 -+#[inline]
28766 -+pub fn setgid(gid: Gid) -> Result<()> {
28767 -+ let res = unsafe { libc::setgid(gid.into()) };
28768 -+
28769 -+ Errno::result(res).map(drop)
28770 -+}
28771 -+
28772 -+/// Get the list of supplementary group IDs of the calling process.
28773 -+///
28774 -+/// [Further reading](http://pubs.opengroup.org/onlinepubs/009695399/functions/getgroups.html)
28775 -+///
28776 -+/// **Note:** This function is not available for Apple platforms. On those
28777 -+/// platforms, checking group membership should be achieved via communication
28778 -+/// with the `opendirectoryd` service.
28779 -+#[cfg(not(any(target_os = "ios", target_os = "macos")))]
28780 -+pub fn getgroups() -> Result<Vec<Gid>> {
28781 -+ // First get the number of groups so we can size our Vec
28782 -+ let ret = unsafe { libc::getgroups(0, ptr::null_mut()) };
28783 -+
28784 -+ // Now actually get the groups. We try multiple times in case the number of
28785 -+ // groups has changed since the first call to getgroups() and the buffer is
28786 -+ // now too small.
28787 -+ let mut groups = Vec::<Gid>::with_capacity(Errno::result(ret)? as usize);
28788 -+ loop {
28789 -+ // FIXME: On the platforms we currently support, the `Gid` struct has
28790 -+ // the same representation in memory as a bare `gid_t`. This is not
28791 -+ // necessarily the case on all Rust platforms, though. See RFC 1785.
28792 -+ let ret = unsafe {
28793 -+ libc::getgroups(groups.capacity() as c_int, groups.as_mut_ptr() as *mut gid_t)
28794 -+ };
28795 -+
28796 -+ match Errno::result(ret) {
28797 -+ Ok(s) => {
28798 -+ unsafe { groups.set_len(s as usize) };
28799 -+ return Ok(groups);
28800 -+ },
28801 -+ Err(Error::Sys(Errno::EINVAL)) => {
28802 -+ // EINVAL indicates that the buffer size was too small. Trigger
28803 -+ // the internal buffer resizing logic of `Vec` by requiring
28804 -+ // more space than the current capacity.
28805 -+ let cap = groups.capacity();
28806 -+ unsafe { groups.set_len(cap) };
28807 -+ groups.reserve(1);
28808 -+ },
28809 -+ Err(e) => return Err(e)
28810 -+ }
28811 -+ }
28812 -+}
28813 -+
28814 -+/// Set the list of supplementary group IDs for the calling process.
28815 -+///
28816 -+/// [Further reading](http://man7.org/linux/man-pages/man2/getgroups.2.html)
28817 -+///
28818 -+/// **Note:** This function is not available for Apple platforms. On those
28819 -+/// platforms, group membership management should be achieved via communication
28820 -+/// with the `opendirectoryd` service.
28821 -+///
28822 -+/// # Examples
28823 -+///
28824 -+/// `setgroups` can be used when dropping privileges from the root user to a
28825 -+/// specific user and group. For example, given the user `www-data` with UID
28826 -+/// `33` and the group `backup` with the GID `34`, one could switch the user as
28827 -+/// follows:
28828 -+///
28829 -+/// ```rust,no_run
28830 -+/// # use std::error::Error;
28831 -+/// # use nix::unistd::*;
28832 -+/// #
28833 -+/// # fn try_main() -> Result<(), Box<Error>> {
28834 -+/// let uid = Uid::from_raw(33);
28835 -+/// let gid = Gid::from_raw(34);
28836 -+/// setgroups(&[gid])?;
28837 -+/// setgid(gid)?;
28838 -+/// setuid(uid)?;
28839 -+/// #
28840 -+/// # Ok(())
28841 -+/// # }
28842 -+/// #
28843 -+/// # fn main() {
28844 -+/// # try_main().unwrap();
28845 -+/// # }
28846 -+/// ```
28847 -+#[cfg(not(any(target_os = "ios", target_os = "macos")))]
28848 -+pub fn setgroups(groups: &[Gid]) -> Result<()> {
28849 -+ cfg_if! {
28850 -+ if #[cfg(any(target_os = "dragonfly",
28851 -+ target_os = "freebsd",
28852 -+ target_os = "ios",
28853 -+ target_os = "macos",
28854 -+ target_os = "netbsd",
28855 -+ target_os = "openbsd"))] {
28856 -+ type setgroups_ngroups_t = c_int;
28857 -+ } else {
28858 -+ type setgroups_ngroups_t = size_t;
28859 -+ }
28860 -+ }
28861 -+ // FIXME: On the platforms we currently support, the `Gid` struct has the
28862 -+ // same representation in memory as a bare `gid_t`. This is not necessarily
28863 -+ // the case on all Rust platforms, though. See RFC 1785.
28864 -+ let res = unsafe {
28865 -+ libc::setgroups(groups.len() as setgroups_ngroups_t, groups.as_ptr() as *const gid_t)
28866 -+ };
28867 -+
28868 -+ Errno::result(res).map(drop)
28869 -+}
28870 -+
28871 -+/// Calculate the supplementary group access list.
28872 -+///
28873 -+/// Gets the group IDs of all groups that `user` is a member of. The additional
28874 -+/// group `group` is also added to the list.
28875 -+///
28876 -+/// [Further reading](http://man7.org/linux/man-pages/man3/getgrouplist.3.html)
28877 -+///
28878 -+/// **Note:** This function is not available for Apple platforms. On those
28879 -+/// platforms, checking group membership should be achieved via communication
28880 -+/// with the `opendirectoryd` service.
28881 -+///
28882 -+/// # Errors
28883 -+///
28884 -+/// Although the `getgrouplist()` call does not return any specific
28885 -+/// errors on any known platforms, this implementation will return a system
28886 -+/// error of `EINVAL` if the number of groups to be fetched exceeds the
28887 -+/// `NGROUPS_MAX` sysconf value. This mimics the behaviour of `getgroups()`
28888 -+/// and `setgroups()`. Additionally, while some implementations will return a
28889 -+/// partial list of groups when `NGROUPS_MAX` is exceeded, this implementation
28890 -+/// will only ever return the complete list or else an error.
28891 -+#[cfg(not(any(target_os = "ios", target_os = "macos")))]
28892 -+pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
28893 -+ let ngroups_max = match sysconf(SysconfVar::NGROUPS_MAX) {
28894 -+ Ok(Some(n)) => n as c_int,
28895 -+ Ok(None) | Err(_) => <c_int>::max_value(),
28896 -+ };
28897 -+ use std::cmp::min;
28898 -+ let mut ngroups = min(ngroups_max, 8);
28899 -+ let mut groups = Vec::<Gid>::with_capacity(ngroups as usize);
28900 -+ cfg_if! {
28901 -+ if #[cfg(any(target_os = "ios", target_os = "macos"))] {
28902 -+ type getgrouplist_group_t = c_int;
28903 -+ } else {
28904 -+ type getgrouplist_group_t = gid_t;
28905 -+ }
28906 -+ }
28907 -+ let gid: gid_t = group.into();
28908 -+ loop {
28909 -+ let ret = unsafe {
28910 -+ libc::getgrouplist(user.as_ptr(),
28911 -+ gid as getgrouplist_group_t,
28912 -+ groups.as_mut_ptr() as *mut getgrouplist_group_t,
28913 -+ &mut ngroups)
28914 -+ };
28915 -+
28916 -+ // BSD systems only return 0 or -1, Linux returns ngroups on success.
28917 -+ if ret >= 0 {
28918 -+ unsafe { groups.set_len(ngroups as usize) };
28919 -+ return Ok(groups);
28920 -+ } else if ret == -1 {
28921 -+ // Returns -1 if ngroups is too small, but does not set errno.
28922 -+ // BSD systems will still fill the groups buffer with as many
28923 -+ // groups as possible, but Linux manpages do not mention this
28924 -+ // behavior.
28925 -+
28926 -+ let cap = groups.capacity();
28927 -+ if cap >= ngroups_max as usize {
28928 -+ // We already have the largest capacity we can, give up
28929 -+ return Err(Error::invalid_argument());
28930 -+ }
28931 -+
28932 -+ // Reserve space for at least ngroups
28933 -+ groups.reserve(ngroups as usize);
28934 -+
28935 -+ // Even if the buffer gets resized to bigger than ngroups_max,
28936 -+ // don't ever ask for more than ngroups_max groups
28937 -+ ngroups = min(ngroups_max, groups.capacity() as c_int);
28938 -+ }
28939 -+ }
28940 -+}
28941 -+
28942 -+/// Initialize the supplementary group access list.
28943 -+///
28944 -+/// Sets the supplementary group IDs for the calling process using all groups
28945 -+/// that `user` is a member of. The additional group `group` is also added to
28946 -+/// the list.
28947 -+///
28948 -+/// [Further reading](http://man7.org/linux/man-pages/man3/initgroups.3.html)
28949 -+///
28950 -+/// **Note:** This function is not available for Apple platforms. On those
28951 -+/// platforms, group membership management should be achieved via communication
28952 -+/// with the `opendirectoryd` service.
28953 -+///
28954 -+/// # Examples
28955 -+///
28956 -+/// `initgroups` can be used when dropping privileges from the root user to
28957 -+/// another user. For example, given the user `www-data`, we could look up the
28958 -+/// UID and GID for the user in the system's password database (usually found
28959 -+/// in `/etc/passwd`). If the `www-data` user's UID and GID were `33` and `33`,
28960 -+/// respectively, one could switch the user as follows:
28961 -+///
28962 -+/// ```rust,no_run
28963 -+/// # use std::error::Error;
28964 -+/// # use std::ffi::CString;
28965 -+/// # use nix::unistd::*;
28966 -+/// #
28967 -+/// # fn try_main() -> Result<(), Box<Error>> {
28968 -+/// let user = CString::new("www-data").unwrap();
28969 -+/// let uid = Uid::from_raw(33);
28970 -+/// let gid = Gid::from_raw(33);
28971 -+/// initgroups(&user, gid)?;
28972 -+/// setgid(gid)?;
28973 -+/// setuid(uid)?;
28974 -+/// #
28975 -+/// # Ok(())
28976 -+/// # }
28977 -+/// #
28978 -+/// # fn main() {
28979 -+/// # try_main().unwrap();
28980 -+/// # }
28981 -+/// ```
28982 -+#[cfg(not(any(target_os = "ios", target_os = "macos")))]
28983 -+pub fn initgroups(user: &CStr, group: Gid) -> Result<()> {
28984 -+ cfg_if! {
28985 -+ if #[cfg(any(target_os = "ios", target_os = "macos"))] {
28986 -+ type initgroups_group_t = c_int;
28987 -+ } else {
28988 -+ type initgroups_group_t = gid_t;
28989 -+ }
28990 -+ }
28991 -+ let gid: gid_t = group.into();
28992 -+ let res = unsafe { libc::initgroups(user.as_ptr(), gid as initgroups_group_t) };
28993 -+
28994 -+ Errno::result(res).map(drop)
28995 -+}
28996 -+
28997 -+/// Suspend the thread until a signal is received.
28998 -+///
28999 -+/// See also [pause(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pause.html).
29000 -+#[inline]
29001 -+pub fn pause() {
29002 -+ unsafe { libc::pause() };
29003 -+}
29004 -+
29005 -+pub mod alarm {
29006 -+ //! Alarm signal scheduling.
29007 -+ //!
29008 -+ //! Scheduling an alarm will trigger a `SIGALRM` signal when the time has
29009 -+ //! elapsed, which has to be caught, because the default action for the
29010 -+ //! signal is to terminate the program. This signal also can't be ignored
29011 -+ //! because the system calls like `pause` will not be interrupted, see the
29012 -+ //! second example below.
29013 -+ //!
29014 -+ //! # Examples
29015 -+ //!
29016 -+ //! Canceling an alarm:
29017 -+ //!
29018 -+ //! ```
29019 -+ //! use nix::unistd::alarm;
29020 -+ //!
29021 -+ //! // Set an alarm for 60 seconds from now.
29022 -+ //! alarm::set(60);
29023 -+ //!
29024 -+ //! // Cancel the above set alarm, which returns the number of seconds left
29025 -+ //! // of the previously set alarm.
29026 -+ //! assert_eq!(alarm::cancel(), Some(60));
29027 -+ //! ```
29028 -+ //!
29029 -+ //! Scheduling an alarm and waiting for the signal:
29030 -+ //!
29031 -+ //! ```
29032 -+ //! use std::time::{Duration, Instant};
29033 -+ //!
29034 -+ //! use nix::unistd::{alarm, pause};
29035 -+ //! use nix::sys::signal::*;
29036 -+ //!
29037 -+ //! // We need to setup an empty signal handler to catch the alarm signal,
29038 -+ //! // otherwise the program will be terminated once the signal is delivered.
29039 -+ //! extern fn signal_handler(_: nix::libc::c_int) { }
29040 -+ //! unsafe { sigaction(Signal::SIGALRM, &SigAction::new(SigHandler::Handler(signal_handler), SaFlags::empty(), SigSet::empty())); }
29041 -+ //!
29042 -+ //! // Set an alarm for 1 second from now.
29043 -+ //! alarm::set(1);
29044 -+ //!
29045 -+ //! let start = Instant::now();
29046 -+ //! // Pause the process until the alarm signal is received.
29047 -+ //! pause();
29048 -+ //!
29049 -+ //! assert!(start.elapsed() >= Duration::from_secs(1));
29050 -+ //! ```
29051 -+ //!
29052 -+ //! # References
29053 -+ //!
29054 -+ //! See also [alarm(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/alarm.html).
29055 -+
29056 -+ use libc;
29057 -+
29058 -+ /// Schedule an alarm signal.
29059 -+ ///
29060 -+ /// This will cause the system to generate a `SIGALRM` signal for the
29061 -+ /// process after the specified number of seconds have elapsed.
29062 -+ ///
29063 -+ /// Returns the leftover time of a previously set alarm if there was one.
29064 -+ pub fn set(secs: libc::c_uint) -> Option<libc::c_uint> {
29065 -+ assert!(secs != 0, "passing 0 to `alarm::set` is not allowed, to cancel an alarm use `alarm::cancel`");
29066 -+ alarm(secs)
29067 -+ }
29068 -+
29069 -+ /// Cancel an previously set alarm signal.
29070 -+ ///
29071 -+ /// Returns the leftover time of a previously set alarm if there was one.
29072 -+ pub fn cancel() -> Option<libc::c_uint> {
29073 -+ alarm(0)
29074 -+ }
29075 -+
29076 -+ fn alarm(secs: libc::c_uint) -> Option<libc::c_uint> {
29077 -+ match unsafe { libc::alarm(secs) } {
29078 -+ 0 => None,
29079 -+ secs => Some(secs),
29080 -+ }
29081 -+ }
29082 -+}
29083 -+
29084 -+/// Suspend execution for an interval of time
29085 -+///
29086 -+/// See also [sleep(2)](http://pubs.opengroup.org/onlinepubs/009695399/functions/sleep.html#tag_03_705_05)
29087 -+// Per POSIX, does not fail
29088 -+#[inline]
29089 -+pub fn sleep(seconds: c_uint) -> c_uint {
29090 -+ unsafe { libc::sleep(seconds) }
29091 -+}
29092 -+
29093 -+pub mod acct {
29094 -+ use libc;
29095 -+ use {Result, NixPath};
29096 -+ use errno::Errno;
29097 -+ use std::ptr;
29098 -+
29099 -+ /// Enable process accounting
29100 -+ ///
29101 -+ /// See also [acct(2)](https://linux.die.net/man/2/acct)
29102 -+ pub fn enable<P: ?Sized + NixPath>(filename: &P) -> Result<()> {
29103 -+ let res = filename.with_nix_path(|cstr| {
29104 -+ unsafe { libc::acct(cstr.as_ptr()) }
29105 -+ })?;
29106 -+
29107 -+ Errno::result(res).map(drop)
29108 -+ }
29109 -+
29110 -+ /// Disable process accounting
29111 -+ pub fn disable() -> Result<()> {
29112 -+ let res = unsafe { libc::acct(ptr::null()) };
29113 -+
29114 -+ Errno::result(res).map(drop)
29115 -+ }
29116 -+}
29117 -+
29118 -+/// Creates a regular file which persists even after process termination
29119 -+///
29120 -+/// * `template`: a path whose 6 rightmost characters must be X, e.g. `/tmp/tmpfile_XXXXXX`
29121 -+/// * returns: tuple of file descriptor and filename
29122 -+///
29123 -+/// Err is returned either if no temporary filename could be created or the template doesn't
29124 -+/// end with XXXXXX
29125 -+///
29126 -+/// See also [mkstemp(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mkstemp.html)
29127 -+///
29128 -+/// # Example
29129 -+///
29130 -+/// ```rust
29131 -+/// use nix::unistd;
29132 -+///
29133 -+/// let _ = match unistd::mkstemp("/tmp/tempfile_XXXXXX") {
29134 -+/// Ok((fd, path)) => {
29135 -+/// unistd::unlink(path.as_path()).unwrap(); // flag file to be deleted at app termination
29136 -+/// fd
29137 -+/// }
29138 -+/// Err(e) => panic!("mkstemp failed: {}", e)
29139 -+/// };
29140 -+/// // do something with fd
29141 -+/// ```
29142 -+#[inline]
29143 -+pub fn mkstemp<P: ?Sized + NixPath>(template: &P) -> Result<(RawFd, PathBuf)> {
29144 -+ let mut path = template.with_nix_path(|path| {path.to_bytes_with_nul().to_owned()})?;
29145 -+ let p = path.as_mut_ptr() as *mut _;
29146 -+ let fd = unsafe { libc::mkstemp(p) };
29147 -+ let last = path.pop(); // drop the trailing nul
29148 -+ debug_assert!(last == Some(b'\0'));
29149 -+ let pathname = OsString::from_vec(path);
29150 -+ Errno::result(fd)?;
29151 -+ Ok((fd, PathBuf::from(pathname)))
29152 -+}
29153 -+
29154 -+/// Variable names for `pathconf`
29155 -+///
29156 -+/// Nix uses the same naming convention for these variables as the
29157 -+/// [getconf(1)](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getconf.html) utility.
29158 -+/// That is, `PathconfVar` variables have the same name as the abstract
29159 -+/// variables shown in the `pathconf(2)` man page. Usually, it's the same as
29160 -+/// the C variable name without the leading `_PC_`.
29161 -+///
29162 -+/// POSIX 1003.1-2008 standardizes all of these variables, but some OSes choose
29163 -+/// not to implement variables that cannot change at runtime.
29164 -+///
29165 -+/// # References
29166 -+///
29167 -+/// - [pathconf(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html)
29168 -+/// - [limits.h](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)
29169 -+/// - [unistd.h](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html)
29170 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
29171 -+#[repr(i32)]
29172 -+pub enum PathconfVar {
29173 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "linux",
29174 -+ target_os = "netbsd", target_os = "openbsd"))]
29175 -+ /// Minimum number of bits needed to represent, as a signed integer value,
29176 -+ /// the maximum size of a regular file allowed in the specified directory.
29177 -+ FILESIZEBITS = libc::_PC_FILESIZEBITS,
29178 -+ /// Maximum number of links to a single file.
29179 -+ LINK_MAX = libc::_PC_LINK_MAX,
29180 -+ /// Maximum number of bytes in a terminal canonical input line.
29181 -+ MAX_CANON = libc::_PC_MAX_CANON,
29182 -+ /// Minimum number of bytes for which space is available in a terminal input
29183 -+ /// queue; therefore, the maximum number of bytes a conforming application
29184 -+ /// may require to be typed as input before reading them.
29185 -+ MAX_INPUT = libc::_PC_MAX_INPUT,
29186 -+ /// Maximum number of bytes in a filename (not including the terminating
29187 -+ /// null of a filename string).
29188 -+ NAME_MAX = libc::_PC_NAME_MAX,
29189 -+ /// Maximum number of bytes the implementation will store as a pathname in a
29190 -+ /// user-supplied buffer of unspecified size, including the terminating null
29191 -+ /// character. Minimum number the implementation will accept as the maximum
29192 -+ /// number of bytes in a pathname.
29193 -+ PATH_MAX = libc::_PC_PATH_MAX,
29194 -+ /// Maximum number of bytes that is guaranteed to be atomic when writing to
29195 -+ /// a pipe.
29196 -+ PIPE_BUF = libc::_PC_PIPE_BUF,
29197 -+ #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "linux",
29198 -+ target_os = "netbsd", target_os = "openbsd"))]
29199 -+ /// Symbolic links can be created.
29200 -+ POSIX2_SYMLINKS = libc::_PC_2_SYMLINKS,
29201 -+ #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
29202 -+ target_os = "linux", target_os = "openbsd"))]
29203 -+ /// Minimum number of bytes of storage actually allocated for any portion of
29204 -+ /// a file.
29205 -+ POSIX_ALLOC_SIZE_MIN = libc::_PC_ALLOC_SIZE_MIN,
29206 -+ #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
29207 -+ target_os = "linux", target_os = "openbsd"))]
29208 -+ /// Recommended increment for file transfer sizes between the
29209 -+ /// `POSIX_REC_MIN_XFER_SIZE` and `POSIX_REC_MAX_XFER_SIZE` values.
29210 -+ POSIX_REC_INCR_XFER_SIZE = libc::_PC_REC_INCR_XFER_SIZE,
29211 -+ #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
29212 -+ target_os = "linux", target_os = "openbsd"))]
29213 -+ /// Maximum recommended file transfer size.
29214 -+ POSIX_REC_MAX_XFER_SIZE = libc::_PC_REC_MAX_XFER_SIZE,
29215 -+ #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
29216 -+ target_os = "linux", target_os = "openbsd"))]
29217 -+ /// Minimum recommended file transfer size.
29218 -+ POSIX_REC_MIN_XFER_SIZE = libc::_PC_REC_MIN_XFER_SIZE,
29219 -+ #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
29220 -+ target_os = "linux", target_os = "openbsd"))]
29221 -+ /// Recommended file transfer buffer alignment.
29222 -+ POSIX_REC_XFER_ALIGN = libc::_PC_REC_XFER_ALIGN,
29223 -+ #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
29224 -+ target_os = "linux", target_os = "netbsd", target_os = "openbsd"))]
29225 -+ /// Maximum number of bytes in a symbolic link.
29226 -+ SYMLINK_MAX = libc::_PC_SYMLINK_MAX,
29227 -+ /// The use of `chown` and `fchown` is restricted to a process with
29228 -+ /// appropriate privileges, and to changing the group ID of a file only to
29229 -+ /// the effective group ID of the process or to one of its supplementary
29230 -+ /// group IDs.
29231 -+ _POSIX_CHOWN_RESTRICTED = libc::_PC_CHOWN_RESTRICTED,
29232 -+ /// Pathname components longer than {NAME_MAX} generate an error.
29233 -+ _POSIX_NO_TRUNC = libc::_PC_NO_TRUNC,
29234 -+ /// This symbol shall be defined to be the value of a character that shall
29235 -+ /// disable terminal special character handling.
29236 -+ _POSIX_VDISABLE = libc::_PC_VDISABLE,
29237 -+ #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
29238 -+ target_os = "linux", target_os = "openbsd"))]
29239 -+ /// Asynchronous input or output operations may be performed for the
29240 -+ /// associated file.
29241 -+ _POSIX_ASYNC_IO = libc::_PC_ASYNC_IO,
29242 -+ #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
29243 -+ target_os = "linux", target_os = "openbsd"))]
29244 -+ /// Prioritized input or output operations may be performed for the
29245 -+ /// associated file.
29246 -+ _POSIX_PRIO_IO = libc::_PC_PRIO_IO,
29247 -+ #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
29248 -+ target_os = "linux", target_os = "netbsd", target_os = "openbsd"))]
29249 -+ /// Synchronized input or output operations may be performed for the
29250 -+ /// associated file.
29251 -+ _POSIX_SYNC_IO = libc::_PC_SYNC_IO,
29252 -+ #[cfg(any(target_os = "dragonfly", target_os = "openbsd"))]
29253 -+ /// The resolution in nanoseconds for all file timestamps.
29254 -+ _POSIX_TIMESTAMP_RESOLUTION = libc::_PC_TIMESTAMP_RESOLUTION
29255 -+}
29256 -+
29257 -+/// Like `pathconf`, but works with file descriptors instead of paths (see
29258 -+/// [fpathconf(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html))
29259 -+///
29260 -+/// # Parameters
29261 -+///
29262 -+/// - `fd`: The file descriptor whose variable should be interrogated
29263 -+/// - `var`: The pathconf variable to lookup
29264 -+///
29265 -+/// # Returns
29266 -+///
29267 -+/// - `Ok(Some(x))`: the variable's limit (for limit variables) or its
29268 -+/// implementation level (for option variables). Implementation levels are
29269 -+/// usually a decimal-coded date, such as 200112 for POSIX 2001.12
29270 -+/// - `Ok(None)`: the variable has no limit (for limit variables) or is
29271 -+/// unsupported (for option variables)
29272 -+/// - `Err(x)`: an error occurred
29273 -+pub fn fpathconf(fd: RawFd, var: PathconfVar) -> Result<Option<c_long>> {
29274 -+ let raw = unsafe {
29275 -+ Errno::clear();
29276 -+ libc::fpathconf(fd, var as c_int)
29277 -+ };
29278 -+ if raw == -1 {
29279 -+ if errno::errno() == 0 {
29280 -+ Ok(None)
29281 -+ } else {
29282 -+ Err(Error::Sys(Errno::last()))
29283 -+ }
29284 -+ } else {
29285 -+ Ok(Some(raw))
29286 -+ }
29287 -+}
29288 -+
29289 -+/// Get path-dependent configurable system variables (see
29290 -+/// [pathconf(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html))
29291 -+///
29292 -+/// Returns the value of a path-dependent configurable system variable. Most
29293 -+/// supported variables also have associated compile-time constants, but POSIX
29294 -+/// allows their values to change at runtime. There are generally two types of
29295 -+/// `pathconf` variables: options and limits. See [pathconf(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html) for more details.
29296 -+///
29297 -+/// # Parameters
29298 -+///
29299 -+/// - `path`: Lookup the value of `var` for this file or directory
29300 -+/// - `var`: The `pathconf` variable to lookup
29301 -+///
29302 -+/// # Returns
29303 -+///
29304 -+/// - `Ok(Some(x))`: the variable's limit (for limit variables) or its
29305 -+/// implementation level (for option variables). Implementation levels are
29306 -+/// usually a decimal-coded date, such as 200112 for POSIX 2001.12
29307 -+/// - `Ok(None)`: the variable has no limit (for limit variables) or is
29308 -+/// unsupported (for option variables)
29309 -+/// - `Err(x)`: an error occurred
29310 -+pub fn pathconf<P: ?Sized + NixPath>(path: &P, var: PathconfVar) -> Result<Option<c_long>> {
29311 -+ let raw = path.with_nix_path(|cstr| {
29312 -+ unsafe {
29313 -+ Errno::clear();
29314 -+ libc::pathconf(cstr.as_ptr(), var as c_int)
29315 -+ }
29316 -+ })?;
29317 -+ if raw == -1 {
29318 -+ if errno::errno() == 0 {
29319 -+ Ok(None)
29320 -+ } else {
29321 -+ Err(Error::Sys(Errno::last()))
29322 -+ }
29323 -+ } else {
29324 -+ Ok(Some(raw))
29325 -+ }
29326 -+}
29327 -+
29328 -+/// Variable names for `sysconf`
29329 -+///
29330 -+/// Nix uses the same naming convention for these variables as the
29331 -+/// [getconf(1)](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getconf.html) utility.
29332 -+/// That is, `SysconfVar` variables have the same name as the abstract variables
29333 -+/// shown in the `sysconf(3)` man page. Usually, it's the same as the C
29334 -+/// variable name without the leading `_SC_`.
29335 -+///
29336 -+/// All of these symbols are standardized by POSIX 1003.1-2008, but haven't been
29337 -+/// implemented by all platforms.
29338 -+///
29339 -+/// # References
29340 -+///
29341 -+/// - [sysconf(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html)
29342 -+/// - [unistd.h](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html)
29343 -+/// - [limits.h](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)
29344 -+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
29345 -+#[repr(i32)]
29346 -+pub enum SysconfVar {
29347 -+ /// Maximum number of I/O operations in a single list I/O call supported by
29348 -+ /// the implementation.
29349 -+ AIO_LISTIO_MAX = libc::_SC_AIO_LISTIO_MAX,
29350 -+ /// Maximum number of outstanding asynchronous I/O operations supported by
29351 -+ /// the implementation.
29352 -+ AIO_MAX = libc::_SC_AIO_MAX,
29353 -+ #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
29354 -+ target_os = "ios", target_os="linux", target_os = "macos",
29355 -+ target_os="openbsd"))]
29356 -+ /// The maximum amount by which a process can decrease its asynchronous I/O
29357 -+ /// priority level from its own scheduling priority.
29358 -+ AIO_PRIO_DELTA_MAX = libc::_SC_AIO_PRIO_DELTA_MAX,
29359 -+ /// Maximum length of argument to the exec functions including environment data.
29360 -+ ARG_MAX = libc::_SC_ARG_MAX,
29361 -+ /// Maximum number of functions that may be registered with `atexit`.
29362 -+ ATEXIT_MAX = libc::_SC_ATEXIT_MAX,
29363 -+ /// Maximum obase values allowed by the bc utility.
29364 -+ BC_BASE_MAX = libc::_SC_BC_BASE_MAX,
29365 -+ /// Maximum number of elements permitted in an array by the bc utility.
29366 -+ BC_DIM_MAX = libc::_SC_BC_DIM_MAX,
29367 -+ /// Maximum scale value allowed by the bc utility.
29368 -+ BC_SCALE_MAX = libc::_SC_BC_SCALE_MAX,
29369 -+ /// Maximum length of a string constant accepted by the bc utility.
29370 -+ BC_STRING_MAX = libc::_SC_BC_STRING_MAX,
29371 -+ /// Maximum number of simultaneous processes per real user ID.
29372 -+ CHILD_MAX = libc::_SC_CHILD_MAX,
29373 -+ // _SC_CLK_TCK is obsolete
29374 -+ /// Maximum number of weights that can be assigned to an entry of the
29375 -+ /// LC_COLLATE order keyword in the locale definition file
29376 -+ COLL_WEIGHTS_MAX = libc::_SC_COLL_WEIGHTS_MAX,
29377 -+ /// Maximum number of timer expiration overruns.
29378 -+ DELAYTIMER_MAX = libc::_SC_DELAYTIMER_MAX,
29379 -+ /// Maximum number of expressions that can be nested within parentheses by
29380 -+ /// the expr utility.
29381 -+ EXPR_NEST_MAX = libc::_SC_EXPR_NEST_MAX,
29382 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29383 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29384 -+ target_os="openbsd"))]
29385 -+ /// Maximum length of a host name (not including the terminating null) as
29386 -+ /// returned from the `gethostname` function
29387 -+ HOST_NAME_MAX = libc::_SC_HOST_NAME_MAX,
29388 -+ /// Maximum number of iovec structures that one process has available for
29389 -+ /// use with `readv` or `writev`.
29390 -+ IOV_MAX = libc::_SC_IOV_MAX,
29391 -+ /// Unless otherwise noted, the maximum length, in bytes, of a utility's
29392 -+ /// input line (either standard input or another file), when the utility is
29393 -+ /// described as processing text files. The length includes room for the
29394 -+ /// trailing <newline>.
29395 -+ LINE_MAX = libc::_SC_LINE_MAX,
29396 -+ /// Maximum length of a login name.
29397 -+ LOGIN_NAME_MAX = libc::_SC_LOGIN_NAME_MAX,
29398 -+ /// Maximum number of simultaneous supplementary group IDs per process.
29399 -+ NGROUPS_MAX = libc::_SC_NGROUPS_MAX,
29400 -+ /// Initial size of `getgrgid_r` and `getgrnam_r` data buffers
29401 -+ GETGR_R_SIZE_MAX = libc::_SC_GETGR_R_SIZE_MAX,
29402 -+ /// Initial size of `getpwuid_r` and `getpwnam_r` data buffers
29403 -+ GETPW_R_SIZE_MAX = libc::_SC_GETPW_R_SIZE_MAX,
29404 -+ /// The maximum number of open message queue descriptors a process may hold.
29405 -+ MQ_OPEN_MAX = libc::_SC_MQ_OPEN_MAX,
29406 -+ /// The maximum number of message priorities supported by the implementation.
29407 -+ MQ_PRIO_MAX = libc::_SC_MQ_PRIO_MAX,
29408 -+ /// A value one greater than the maximum value that the system may assign to
29409 -+ /// a newly-created file descriptor.
29410 -+ OPEN_MAX = libc::_SC_OPEN_MAX,
29411 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29412 -+ target_os="linux", target_os = "macos", target_os="openbsd"))]
29413 -+ /// The implementation supports the Advisory Information option.
29414 -+ _POSIX_ADVISORY_INFO = libc::_SC_ADVISORY_INFO,
29415 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29416 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29417 -+ target_os="openbsd"))]
29418 -+ /// The implementation supports barriers.
29419 -+ _POSIX_BARRIERS = libc::_SC_BARRIERS,
29420 -+ /// The implementation supports asynchronous input and output.
29421 -+ _POSIX_ASYNCHRONOUS_IO = libc::_SC_ASYNCHRONOUS_IO,
29422 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29423 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29424 -+ target_os="openbsd"))]
29425 -+ /// The implementation supports clock selection.
29426 -+ _POSIX_CLOCK_SELECTION = libc::_SC_CLOCK_SELECTION,
29427 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29428 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29429 -+ target_os="openbsd"))]
29430 -+ /// The implementation supports the Process CPU-Time Clocks option.
29431 -+ _POSIX_CPUTIME = libc::_SC_CPUTIME,
29432 -+ /// The implementation supports the File Synchronization option.
29433 -+ _POSIX_FSYNC = libc::_SC_FSYNC,
29434 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29435 -+ target_os="linux", target_os = "macos", target_os="openbsd"))]
29436 -+ /// The implementation supports the IPv6 option.
29437 -+ _POSIX_IPV6 = libc::_SC_IPV6,
29438 -+ /// The implementation supports job control.
29439 -+ _POSIX_JOB_CONTROL = libc::_SC_JOB_CONTROL,
29440 -+ /// The implementation supports memory mapped Files.
29441 -+ _POSIX_MAPPED_FILES = libc::_SC_MAPPED_FILES,
29442 -+ /// The implementation supports the Process Memory Locking option.
29443 -+ _POSIX_MEMLOCK = libc::_SC_MEMLOCK,
29444 -+ /// The implementation supports the Range Memory Locking option.
29445 -+ _POSIX_MEMLOCK_RANGE = libc::_SC_MEMLOCK_RANGE,
29446 -+ /// The implementation supports memory protection.
29447 -+ _POSIX_MEMORY_PROTECTION = libc::_SC_MEMORY_PROTECTION,
29448 -+ /// The implementation supports the Message Passing option.
29449 -+ _POSIX_MESSAGE_PASSING = libc::_SC_MESSAGE_PASSING,
29450 -+ /// The implementation supports the Monotonic Clock option.
29451 -+ _POSIX_MONOTONIC_CLOCK = libc::_SC_MONOTONIC_CLOCK,
29452 -+ #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
29453 -+ target_os = "ios", target_os="linux", target_os = "macos",
29454 -+ target_os="openbsd"))]
29455 -+ /// The implementation supports the Prioritized Input and Output option.
29456 -+ _POSIX_PRIORITIZED_IO = libc::_SC_PRIORITIZED_IO,
29457 -+ /// The implementation supports the Process Scheduling option.
29458 -+ _POSIX_PRIORITY_SCHEDULING = libc::_SC_PRIORITY_SCHEDULING,
29459 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29460 -+ target_os="linux", target_os = "macos", target_os="openbsd"))]
29461 -+ /// The implementation supports the Raw Sockets option.
29462 -+ _POSIX_RAW_SOCKETS = libc::_SC_RAW_SOCKETS,
29463 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29464 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29465 -+ target_os="openbsd"))]
29466 -+ /// The implementation supports read-write locks.
29467 -+ _POSIX_READER_WRITER_LOCKS = libc::_SC_READER_WRITER_LOCKS,
29468 -+ #[cfg(any(target_os = "android", target_os="dragonfly", target_os="freebsd",
29469 -+ target_os = "ios", target_os="linux", target_os = "macos",
29470 -+ target_os = "openbsd"))]
29471 -+ /// The implementation supports realtime signals.
29472 -+ _POSIX_REALTIME_SIGNALS = libc::_SC_REALTIME_SIGNALS,
29473 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29474 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29475 -+ target_os="openbsd"))]
29476 -+ /// The implementation supports the Regular Expression Handling option.
29477 -+ _POSIX_REGEXP = libc::_SC_REGEXP,
29478 -+ /// Each process has a saved set-user-ID and a saved set-group-ID.
29479 -+ _POSIX_SAVED_IDS = libc::_SC_SAVED_IDS,
29480 -+ /// The implementation supports semaphores.
29481 -+ _POSIX_SEMAPHORES = libc::_SC_SEMAPHORES,
29482 -+ /// The implementation supports the Shared Memory Objects option.
29483 -+ _POSIX_SHARED_MEMORY_OBJECTS = libc::_SC_SHARED_MEMORY_OBJECTS,
29484 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29485 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29486 -+ target_os="openbsd"))]
29487 -+ /// The implementation supports the POSIX shell.
29488 -+ _POSIX_SHELL = libc::_SC_SHELL,
29489 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29490 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29491 -+ target_os="openbsd"))]
29492 -+ /// The implementation supports the Spawn option.
29493 -+ _POSIX_SPAWN = libc::_SC_SPAWN,
29494 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29495 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29496 -+ target_os="openbsd"))]
29497 -+ /// The implementation supports spin locks.
29498 -+ _POSIX_SPIN_LOCKS = libc::_SC_SPIN_LOCKS,
29499 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29500 -+ target_os="linux", target_os = "macos", target_os="openbsd"))]
29501 -+ /// The implementation supports the Process Sporadic Server option.
29502 -+ _POSIX_SPORADIC_SERVER = libc::_SC_SPORADIC_SERVER,
29503 -+ #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
29504 -+ target_os="openbsd"))]
29505 -+ _POSIX_SS_REPL_MAX = libc::_SC_SS_REPL_MAX,
29506 -+ /// The implementation supports the Synchronized Input and Output option.
29507 -+ _POSIX_SYNCHRONIZED_IO = libc::_SC_SYNCHRONIZED_IO,
29508 -+ /// The implementation supports the Thread Stack Address Attribute option.
29509 -+ _POSIX_THREAD_ATTR_STACKADDR = libc::_SC_THREAD_ATTR_STACKADDR,
29510 -+ /// The implementation supports the Thread Stack Size Attribute option.
29511 -+ _POSIX_THREAD_ATTR_STACKSIZE = libc::_SC_THREAD_ATTR_STACKSIZE,
29512 -+ #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
29513 -+ target_os="netbsd", target_os="openbsd"))]
29514 -+ /// The implementation supports the Thread CPU-Time Clocks option.
29515 -+ _POSIX_THREAD_CPUTIME = libc::_SC_THREAD_CPUTIME,
29516 -+ /// The implementation supports the Non-Robust Mutex Priority Inheritance
29517 -+ /// option.
29518 -+ _POSIX_THREAD_PRIO_INHERIT = libc::_SC_THREAD_PRIO_INHERIT,
29519 -+ /// The implementation supports the Non-Robust Mutex Priority Protection option.
29520 -+ _POSIX_THREAD_PRIO_PROTECT = libc::_SC_THREAD_PRIO_PROTECT,
29521 -+ /// The implementation supports the Thread Execution Scheduling option.
29522 -+ _POSIX_THREAD_PRIORITY_SCHEDULING = libc::_SC_THREAD_PRIORITY_SCHEDULING,
29523 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29524 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29525 -+ target_os="openbsd"))]
29526 -+ /// The implementation supports the Thread Process-Shared Synchronization
29527 -+ /// option.
29528 -+ _POSIX_THREAD_PROCESS_SHARED = libc::_SC_THREAD_PROCESS_SHARED,
29529 -+ #[cfg(any(target_os="dragonfly", target_os="linux", target_os="openbsd"))]
29530 -+ /// The implementation supports the Robust Mutex Priority Inheritance option.
29531 -+ _POSIX_THREAD_ROBUST_PRIO_INHERIT = libc::_SC_THREAD_ROBUST_PRIO_INHERIT,
29532 -+ #[cfg(any(target_os="dragonfly", target_os="linux", target_os="openbsd"))]
29533 -+ /// The implementation supports the Robust Mutex Priority Protection option.
29534 -+ _POSIX_THREAD_ROBUST_PRIO_PROTECT = libc::_SC_THREAD_ROBUST_PRIO_PROTECT,
29535 -+ /// The implementation supports thread-safe functions.
29536 -+ _POSIX_THREAD_SAFE_FUNCTIONS = libc::_SC_THREAD_SAFE_FUNCTIONS,
29537 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29538 -+ target_os="linux", target_os = "macos", target_os="openbsd"))]
29539 -+ /// The implementation supports the Thread Sporadic Server option.
29540 -+ _POSIX_THREAD_SPORADIC_SERVER = libc::_SC_THREAD_SPORADIC_SERVER,
29541 -+ /// The implementation supports threads.
29542 -+ _POSIX_THREADS = libc::_SC_THREADS,
29543 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29544 -+ target_os="linux", target_os = "macos", target_os="openbsd"))]
29545 -+ /// The implementation supports timeouts.
29546 -+ _POSIX_TIMEOUTS = libc::_SC_TIMEOUTS,
29547 -+ /// The implementation supports timers.
29548 -+ _POSIX_TIMERS = libc::_SC_TIMERS,
29549 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29550 -+ target_os="linux", target_os = "macos", target_os="openbsd"))]
29551 -+ /// The implementation supports the Trace option.
29552 -+ _POSIX_TRACE = libc::_SC_TRACE,
29553 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29554 -+ target_os="linux", target_os = "macos", target_os="openbsd"))]
29555 -+ /// The implementation supports the Trace Event Filter option.
29556 -+ _POSIX_TRACE_EVENT_FILTER = libc::_SC_TRACE_EVENT_FILTER,
29557 -+ #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
29558 -+ target_os="openbsd"))]
29559 -+ _POSIX_TRACE_EVENT_NAME_MAX = libc::_SC_TRACE_EVENT_NAME_MAX,
29560 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29561 -+ target_os="linux", target_os = "macos", target_os="openbsd"))]
29562 -+ /// The implementation supports the Trace Inherit option.
29563 -+ _POSIX_TRACE_INHERIT = libc::_SC_TRACE_INHERIT,
29564 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29565 -+ target_os="linux", target_os = "macos", target_os="openbsd"))]
29566 -+ /// The implementation supports the Trace Log option.
29567 -+ _POSIX_TRACE_LOG = libc::_SC_TRACE_LOG,
29568 -+ #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
29569 -+ target_os="openbsd"))]
29570 -+ _POSIX_TRACE_NAME_MAX = libc::_SC_TRACE_NAME_MAX,
29571 -+ #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
29572 -+ target_os="openbsd"))]
29573 -+ _POSIX_TRACE_SYS_MAX = libc::_SC_TRACE_SYS_MAX,
29574 -+ #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
29575 -+ target_os="openbsd"))]
29576 -+ _POSIX_TRACE_USER_EVENT_MAX = libc::_SC_TRACE_USER_EVENT_MAX,
29577 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29578 -+ target_os="linux", target_os = "macos", target_os="openbsd"))]
29579 -+ /// The implementation supports the Typed Memory Objects option.
29580 -+ _POSIX_TYPED_MEMORY_OBJECTS = libc::_SC_TYPED_MEMORY_OBJECTS,
29581 -+ /// Integer value indicating version of this standard (C-language binding)
29582 -+ /// to which the implementation conforms. For implementations conforming to
29583 -+ /// POSIX.1-2008, the value shall be 200809L.
29584 -+ _POSIX_VERSION = libc::_SC_VERSION,
29585 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29586 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29587 -+ target_os="openbsd"))]
29588 -+ /// The implementation provides a C-language compilation environment with
29589 -+ /// 32-bit `int`, `long`, `pointer`, and `off_t` types.
29590 -+ _POSIX_V6_ILP32_OFF32 = libc::_SC_V6_ILP32_OFF32,
29591 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29592 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29593 -+ target_os="openbsd"))]
29594 -+ /// The implementation provides a C-language compilation environment with
29595 -+ /// 32-bit `int`, `long`, and pointer types and an `off_t` type using at
29596 -+ /// least 64 bits.
29597 -+ _POSIX_V6_ILP32_OFFBIG = libc::_SC_V6_ILP32_OFFBIG,
29598 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29599 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29600 -+ target_os="openbsd"))]
29601 -+ /// The implementation provides a C-language compilation environment with
29602 -+ /// 32-bit `int` and 64-bit `long`, `pointer`, and `off_t` types.
29603 -+ _POSIX_V6_LP64_OFF64 = libc::_SC_V6_LP64_OFF64,
29604 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29605 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29606 -+ target_os="openbsd"))]
29607 -+ /// The implementation provides a C-language compilation environment with an
29608 -+ /// `int` type using at least 32 bits and `long`, pointer, and `off_t` types
29609 -+ /// using at least 64 bits.
29610 -+ _POSIX_V6_LPBIG_OFFBIG = libc::_SC_V6_LPBIG_OFFBIG,
29611 -+ /// The implementation supports the C-Language Binding option.
29612 -+ _POSIX2_C_BIND = libc::_SC_2_C_BIND,
29613 -+ /// The implementation supports the C-Language Development Utilities option.
29614 -+ _POSIX2_C_DEV = libc::_SC_2_C_DEV,
29615 -+ /// The implementation supports the Terminal Characteristics option.
29616 -+ _POSIX2_CHAR_TERM = libc::_SC_2_CHAR_TERM,
29617 -+ /// The implementation supports the FORTRAN Development Utilities option.
29618 -+ _POSIX2_FORT_DEV = libc::_SC_2_FORT_DEV,
29619 -+ /// The implementation supports the FORTRAN Runtime Utilities option.
29620 -+ _POSIX2_FORT_RUN = libc::_SC_2_FORT_RUN,
29621 -+ /// The implementation supports the creation of locales by the localedef
29622 -+ /// utility.
29623 -+ _POSIX2_LOCALEDEF = libc::_SC_2_LOCALEDEF,
29624 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29625 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29626 -+ target_os="openbsd"))]
29627 -+ /// The implementation supports the Batch Environment Services and Utilities
29628 -+ /// option.
29629 -+ _POSIX2_PBS = libc::_SC_2_PBS,
29630 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29631 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29632 -+ target_os="openbsd"))]
29633 -+ /// The implementation supports the Batch Accounting option.
29634 -+ _POSIX2_PBS_ACCOUNTING = libc::_SC_2_PBS_ACCOUNTING,
29635 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29636 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29637 -+ target_os="openbsd"))]
29638 -+ /// The implementation supports the Batch Checkpoint/Restart option.
29639 -+ _POSIX2_PBS_CHECKPOINT = libc::_SC_2_PBS_CHECKPOINT,
29640 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29641 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29642 -+ target_os="openbsd"))]
29643 -+ /// The implementation supports the Locate Batch Job Request option.
29644 -+ _POSIX2_PBS_LOCATE = libc::_SC_2_PBS_LOCATE,
29645 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29646 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29647 -+ target_os="openbsd"))]
29648 -+ /// The implementation supports the Batch Job Message Request option.
29649 -+ _POSIX2_PBS_MESSAGE = libc::_SC_2_PBS_MESSAGE,
29650 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29651 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29652 -+ target_os="openbsd"))]
29653 -+ /// The implementation supports the Track Batch Job Request option.
29654 -+ _POSIX2_PBS_TRACK = libc::_SC_2_PBS_TRACK,
29655 -+ /// The implementation supports the Software Development Utilities option.
29656 -+ _POSIX2_SW_DEV = libc::_SC_2_SW_DEV,
29657 -+ /// The implementation supports the User Portability Utilities option.
29658 -+ _POSIX2_UPE = libc::_SC_2_UPE,
29659 -+ /// Integer value indicating version of the Shell and Utilities volume of
29660 -+ /// POSIX.1 to which the implementation conforms.
29661 -+ _POSIX2_VERSION = libc::_SC_2_VERSION,
29662 -+ /// The size of a system page in bytes.
29663 -+ ///
29664 -+ /// POSIX also defines an alias named `PAGESIZE`, but Rust does not allow two
29665 -+ /// enum constants to have the same value, so nix omits `PAGESIZE`.
29666 -+ PAGE_SIZE = libc::_SC_PAGE_SIZE,
29667 -+ PTHREAD_DESTRUCTOR_ITERATIONS = libc::_SC_THREAD_DESTRUCTOR_ITERATIONS,
29668 -+ PTHREAD_KEYS_MAX = libc::_SC_THREAD_KEYS_MAX,
29669 -+ PTHREAD_STACK_MIN = libc::_SC_THREAD_STACK_MIN,
29670 -+ PTHREAD_THREADS_MAX = libc::_SC_THREAD_THREADS_MAX,
29671 -+ RE_DUP_MAX = libc::_SC_RE_DUP_MAX,
29672 -+ #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
29673 -+ target_os = "ios", target_os="linux", target_os = "macos",
29674 -+ target_os="openbsd"))]
29675 -+ RTSIG_MAX = libc::_SC_RTSIG_MAX,
29676 -+ SEM_NSEMS_MAX = libc::_SC_SEM_NSEMS_MAX,
29677 -+ #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
29678 -+ target_os = "ios", target_os="linux", target_os = "macos",
29679 -+ target_os="openbsd"))]
29680 -+ SEM_VALUE_MAX = libc::_SC_SEM_VALUE_MAX,
29681 -+ #[cfg(any(target_os = "android", target_os="dragonfly", target_os="freebsd",
29682 -+ target_os = "ios", target_os="linux", target_os = "macos",
29683 -+ target_os = "openbsd"))]
29684 -+ SIGQUEUE_MAX = libc::_SC_SIGQUEUE_MAX,
29685 -+ STREAM_MAX = libc::_SC_STREAM_MAX,
29686 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29687 -+ target_os="linux", target_os = "macos", target_os="netbsd",
29688 -+ target_os="openbsd"))]
29689 -+ SYMLOOP_MAX = libc::_SC_SYMLOOP_MAX,
29690 -+ TIMER_MAX = libc::_SC_TIMER_MAX,
29691 -+ TTY_NAME_MAX = libc::_SC_TTY_NAME_MAX,
29692 -+ TZNAME_MAX = libc::_SC_TZNAME_MAX,
29693 -+ #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
29694 -+ target_os = "ios", target_os="linux", target_os = "macos",
29695 -+ target_os="openbsd"))]
29696 -+ /// The implementation supports the X/Open Encryption Option Group.
29697 -+ _XOPEN_CRYPT = libc::_SC_XOPEN_CRYPT,
29698 -+ #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
29699 -+ target_os = "ios", target_os="linux", target_os = "macos",
29700 -+ target_os="openbsd"))]
29701 -+ /// The implementation supports the Issue 4, Version 2 Enhanced
29702 -+ /// Internationalization Option Group.
29703 -+ _XOPEN_ENH_I18N = libc::_SC_XOPEN_ENH_I18N,
29704 -+ #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
29705 -+ target_os = "ios", target_os="linux", target_os = "macos",
29706 -+ target_os="openbsd"))]
29707 -+ _XOPEN_LEGACY = libc::_SC_XOPEN_LEGACY,
29708 -+ #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
29709 -+ target_os = "ios", target_os="linux", target_os = "macos",
29710 -+ target_os="openbsd"))]
29711 -+ /// The implementation supports the X/Open Realtime Option Group.
29712 -+ _XOPEN_REALTIME = libc::_SC_XOPEN_REALTIME,
29713 -+ #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
29714 -+ target_os = "ios", target_os="linux", target_os = "macos",
29715 -+ target_os="openbsd"))]
29716 -+ /// The implementation supports the X/Open Realtime Threads Option Group.
29717 -+ _XOPEN_REALTIME_THREADS = libc::_SC_XOPEN_REALTIME_THREADS,
29718 -+ /// The implementation supports the Issue 4, Version 2 Shared Memory Option
29719 -+ /// Group.
29720 -+ _XOPEN_SHM = libc::_SC_XOPEN_SHM,
29721 -+ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
29722 -+ target_os="linux", target_os = "macos", target_os="openbsd"))]
29723 -+ /// The implementation supports the XSI STREAMS Option Group.
29724 -+ _XOPEN_STREAMS = libc::_SC_XOPEN_STREAMS,
29725 -+ #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
29726 -+ target_os = "ios", target_os="linux", target_os = "macos",
29727 -+ target_os="openbsd"))]
29728 -+ /// The implementation supports the XSI option
29729 -+ _XOPEN_UNIX = libc::_SC_XOPEN_UNIX,
29730 -+ #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
29731 -+ target_os = "ios", target_os="linux", target_os = "macos",
29732 -+ target_os="openbsd"))]
29733 -+ /// Integer value indicating version of the X/Open Portability Guide to
29734 -+ /// which the implementation conforms.
29735 -+ _XOPEN_VERSION = libc::_SC_XOPEN_VERSION,
29736 -+}
29737 -+
29738 -+/// Get configurable system variables (see
29739 -+/// [sysconf(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html))
29740 -+///
29741 -+/// Returns the value of a configurable system variable. Most supported
29742 -+/// variables also have associated compile-time constants, but POSIX
29743 -+/// allows their values to change at runtime. There are generally two types of
29744 -+/// sysconf variables: options and limits. See sysconf(3) for more details.
29745 -+///
29746 -+/// # Returns
29747 -+///
29748 -+/// - `Ok(Some(x))`: the variable's limit (for limit variables) or its
29749 -+/// implementation level (for option variables). Implementation levels are
29750 -+/// usually a decimal-coded date, such as 200112 for POSIX 2001.12
29751 -+/// - `Ok(None)`: the variable has no limit (for limit variables) or is
29752 -+/// unsupported (for option variables)
29753 -+/// - `Err(x)`: an error occurred
29754 -+pub fn sysconf(var: SysconfVar) -> Result<Option<c_long>> {
29755 -+ let raw = unsafe {
29756 -+ Errno::clear();
29757 -+ libc::sysconf(var as c_int)
29758 -+ };
29759 -+ if raw == -1 {
29760 -+ if errno::errno() == 0 {
29761 -+ Ok(None)
29762 -+ } else {
29763 -+ Err(Error::Sys(Errno::last()))
29764 -+ }
29765 -+ } else {
29766 -+ Ok(Some(raw))
29767 -+ }
29768 -+}
29769 -+
29770 -+#[cfg(any(target_os = "android", target_os = "linux"))]
29771 -+mod pivot_root {
29772 -+ use libc;
29773 -+ use {Result, NixPath};
29774 -+ use errno::Errno;
29775 -+
29776 -+ pub fn pivot_root<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
29777 -+ new_root: &P1, put_old: &P2) -> Result<()> {
29778 -+ let res = new_root.with_nix_path(|new_root| {
29779 -+ put_old.with_nix_path(|put_old| {
29780 -+ unsafe {
29781 -+ libc::syscall(libc::SYS_pivot_root, new_root.as_ptr(), put_old.as_ptr())
29782 -+ }
29783 -+ })
29784 -+ })??;
29785 -+
29786 -+ Errno::result(res).map(drop)
29787 -+ }
29788 -+}
29789 -+
29790 -+#[cfg(any(target_os = "android", target_os = "freebsd",
29791 -+ target_os = "linux", target_os = "openbsd"))]
29792 -+mod setres {
29793 -+ use libc;
29794 -+ use Result;
29795 -+ use errno::Errno;
29796 -+ use super::{Uid, Gid};
29797 -+
29798 -+ /// Sets the real, effective, and saved uid.
29799 -+ /// ([see setresuid(2)](http://man7.org/linux/man-pages/man2/setresuid.2.html))
29800 -+ ///
29801 -+ /// * `ruid`: real user id
29802 -+ /// * `euid`: effective user id
29803 -+ /// * `suid`: saved user id
29804 -+ /// * returns: Ok or libc error code.
29805 -+ ///
29806 -+ /// Err is returned if the user doesn't have permission to set this UID.
29807 -+ #[inline]
29808 -+ pub fn setresuid(ruid: Uid, euid: Uid, suid: Uid) -> Result<()> {
29809 -+ let res = unsafe { libc::setresuid(ruid.into(), euid.into(), suid.into()) };
29810 -+
29811 -+ Errno::result(res).map(drop)
29812 -+ }
29813 -+
29814 -+ /// Sets the real, effective, and saved gid.
29815 -+ /// ([see setresuid(2)](http://man7.org/linux/man-pages/man2/setresuid.2.html))
29816 -+ ///
29817 -+ /// * `rgid`: real group id
29818 -+ /// * `egid`: effective group id
29819 -+ /// * `sgid`: saved group id
29820 -+ /// * returns: Ok or libc error code.
29821 -+ ///
29822 -+ /// Err is returned if the user doesn't have permission to set this GID.
29823 -+ #[inline]
29824 -+ pub fn setresgid(rgid: Gid, egid: Gid, sgid: Gid) -> Result<()> {
29825 -+ let res = unsafe { libc::setresgid(rgid.into(), egid.into(), sgid.into()) };
29826 -+
29827 -+ Errno::result(res).map(drop)
29828 -+ }
29829 -+}
29830 -+
29831 -+libc_bitflags!{
29832 -+ /// Options for access()
29833 -+ pub struct AccessFlags : c_int {
29834 -+ /// Test for existence of file.
29835 -+ F_OK;
29836 -+ /// Test for read permission.
29837 -+ R_OK;
29838 -+ /// Test for write permission.
29839 -+ W_OK;
29840 -+ /// Test for execute (search) permission.
29841 -+ X_OK;
29842 -+ }
29843 -+}
29844 -+
29845 -+/// Checks the file named by `path` for accessibility according to the flags given by `amode`
29846 -+/// See [access(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html)
29847 -+pub fn access<P: ?Sized + NixPath>(path: &P, amode: AccessFlags) -> Result<()> {
29848 -+ let res = path.with_nix_path(|cstr| {
29849 -+ unsafe {
29850 -+ libc::access(cstr.as_ptr(), amode.bits)
29851 -+ }
29852 -+ })?;
29853 -+ Errno::result(res).map(drop)
29854 -+}
29855 -diff --git a/third_party/rust/nix-0.15.0/test/sys/mod.rs b/third_party/rust/nix-0.15.0/test/sys/mod.rs
29856 -new file mode 100644
29857 -index 0000000000000..60a58dd106f19
29858 ---- /dev/null
29859 -+++ b/third_party/rust/nix-0.15.0/test/sys/mod.rs
29860 -@@ -0,0 +1,38 @@
29861 -+mod test_signal;
29862 -+
29863 -+// NOTE: DragonFly lacks a kernel-level implementation of Posix AIO as of
29864 -+// this writing. There is an user-level implementation, but whether aio
29865 -+// works or not heavily depends on which pthread implementation is chosen
29866 -+// by the user at link time. For this reason we do not want to run aio test
29867 -+// cases on DragonFly.
29868 -+#[cfg(any(target_os = "freebsd",
29869 -+ target_os = "ios",
29870 -+ target_os = "linux",
29871 -+ target_os = "macos",
29872 -+ target_os = "netbsd"))]
29873 -+mod test_aio;
29874 -+#[cfg(target_os = "linux")]
29875 -+mod test_signalfd;
29876 -+mod test_socket;
29877 -+mod test_sockopt;
29878 -+mod test_select;
29879 -+#[cfg(any(target_os = "android", target_os = "linux"))]
29880 -+mod test_sysinfo;
29881 -+mod test_termios;
29882 -+mod test_ioctl;
29883 -+mod test_wait;
29884 -+mod test_uio;
29885 -+
29886 -+#[cfg(target_os = "linux")]
29887 -+mod test_epoll;
29888 -+#[cfg(target_os = "linux")]
29889 -+mod test_inotify;
29890 -+mod test_pthread;
29891 -+#[cfg(any(target_os = "android",
29892 -+ target_os = "dragonfly",
29893 -+ target_os = "freebsd",
29894 -+ target_os = "linux",
29895 -+ target_os = "macos",
29896 -+ target_os = "netbsd",
29897 -+ target_os = "openbsd"))]
29898 -+mod test_ptrace;
29899 -diff --git a/third_party/rust/nix-0.15.0/test/sys/test_aio.rs b/third_party/rust/nix-0.15.0/test/sys/test_aio.rs
29900 -new file mode 100644
29901 -index 0000000000000..d4b09b0b81905
29902 ---- /dev/null
29903 -+++ b/third_party/rust/nix-0.15.0/test/sys/test_aio.rs
29904 -@@ -0,0 +1,654 @@
29905 -+use bytes::{Bytes, BytesMut};
29906 -+use libc::{c_int, c_void};
29907 -+use nix::{Error, Result};
29908 -+use nix::errno::*;
29909 -+use nix::sys::aio::*;
29910 -+use nix::sys::signal::{SaFlags, SigAction, sigaction, SigevNotify, SigHandler, Signal, SigSet};
29911 -+use nix::sys::time::{TimeSpec, TimeValLike};
29912 -+use std::io::{Write, Read, Seek, SeekFrom};
29913 -+use std::ops::Deref;
29914 -+use std::os::unix::io::AsRawFd;
29915 -+use std::sync::atomic::{AtomicBool, Ordering};
29916 -+use std::{thread, time};
29917 -+use tempfile::tempfile;
29918 -+
29919 -+// Helper that polls an AioCb for completion or error
29920 -+fn poll_aio(aiocb: &mut AioCb) -> Result<()> {
29921 -+ loop {
29922 -+ let err = aiocb.error();
29923 -+ if err != Err(Error::from(Errno::EINPROGRESS)) { return err; };
29924 -+ thread::sleep(time::Duration::from_millis(10));
29925 -+ }
29926 -+}
29927 -+
29928 -+#[test]
29929 -+fn test_accessors() {
29930 -+ let mut rbuf = vec![0; 4];
29931 -+ let aiocb = AioCb::from_mut_slice( 1001,
29932 -+ 2, //offset
29933 -+ &mut rbuf,
29934 -+ 42, //priority
29935 -+ SigevNotify::SigevSignal {
29936 -+ signal: Signal::SIGUSR2,
29937 -+ si_value: 99
29938 -+ },
29939 -+ LioOpcode::LIO_NOP);
29940 -+ assert_eq!(1001, aiocb.fd());
29941 -+ assert_eq!(Some(LioOpcode::LIO_NOP), aiocb.lio_opcode());
29942 -+ assert_eq!(4, aiocb.nbytes());
29943 -+ assert_eq!(2, aiocb.offset());
29944 -+ assert_eq!(42, aiocb.priority());
29945 -+ let sev = aiocb.sigevent().sigevent();
29946 -+ assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo);
29947 -+ assert_eq!(99, sev.sigev_value.sival_ptr as i64);
29948 -+}
29949 -+
29950 -+// Tests AioCb.cancel. We aren't trying to test the OS's implementation, only
29951 -+// our bindings. So it's sufficient to check that AioCb.cancel returned any
29952 -+// AioCancelStat value.
29953 -+#[test]
29954 -+#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
29955 -+fn test_cancel() {
29956 -+ let wbuf: &[u8] = b"CDEF";
29957 -+
29958 -+ let f = tempfile().unwrap();
29959 -+ let mut aiocb = AioCb::from_slice( f.as_raw_fd(),
29960 -+ 0, //offset
29961 -+ wbuf,
29962 -+ 0, //priority
29963 -+ SigevNotify::SigevNone,
29964 -+ LioOpcode::LIO_NOP);
29965 -+ aiocb.write().unwrap();
29966 -+ let err = aiocb.error();
29967 -+ assert!(err == Ok(()) || err == Err(Error::from(Errno::EINPROGRESS)));
29968 -+
29969 -+ let cancelstat = aiocb.cancel();
29970 -+ assert!(cancelstat.is_ok());
29971 -+
29972 -+ // Wait for aiocb to complete, but don't care whether it succeeded
29973 -+ let _ = poll_aio(&mut aiocb);
29974 -+ let _ = aiocb.aio_return();
29975 -+}
29976 -+
29977 -+// Tests using aio_cancel_all for all outstanding IOs.
29978 -+#[test]
29979 -+#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
29980 -+fn test_aio_cancel_all() {
29981 -+ let wbuf: &[u8] = b"CDEF";
29982 -+
29983 -+ let f = tempfile().unwrap();
29984 -+ let mut aiocb = AioCb::from_slice(f.as_raw_fd(),
29985 -+ 0, //offset
29986 -+ wbuf,
29987 -+ 0, //priority
29988 -+ SigevNotify::SigevNone,
29989 -+ LioOpcode::LIO_NOP);
29990 -+ aiocb.write().unwrap();
29991 -+ let err = aiocb.error();
29992 -+ assert!(err == Ok(()) || err == Err(Error::from(Errno::EINPROGRESS)));
29993 -+
29994 -+ let cancelstat = aio_cancel_all(f.as_raw_fd());
29995 -+ assert!(cancelstat.is_ok());
29996 -+
29997 -+ // Wait for aiocb to complete, but don't care whether it succeeded
29998 -+ let _ = poll_aio(&mut aiocb);
29999 -+ let _ = aiocb.aio_return();
30000 -+}
30001 -+
30002 -+#[test]
30003 -+#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
30004 -+fn test_fsync() {
30005 -+ const INITIAL: &[u8] = b"abcdef123456";
30006 -+ let mut f = tempfile().unwrap();
30007 -+ f.write_all(INITIAL).unwrap();
30008 -+ let mut aiocb = AioCb::from_fd( f.as_raw_fd(),
30009 -+ 0, //priority
30010 -+ SigevNotify::SigevNone);
30011 -+ let err = aiocb.fsync(AioFsyncMode::O_SYNC);
30012 -+ assert!(err.is_ok());
30013 -+ poll_aio(&mut aiocb).unwrap();
30014 -+ aiocb.aio_return().unwrap();
30015 -+}
30016 -+
30017 -+/// `AioCb::fsync` should not modify the `AioCb` object if `libc::aio_fsync` returns
30018 -+/// an error
30019 -+// Skip on Linux, because Linux's AIO implementation can't detect errors
30020 -+// synchronously
30021 -+#[test]
30022 -+#[cfg(any(target_os = "freebsd", target_os = "macos"))]
30023 -+fn test_fsync_error() {
30024 -+ use std::mem;
30025 -+
30026 -+ const INITIAL: &[u8] = b"abcdef123456";
30027 -+ // Create an invalid AioFsyncMode
30028 -+ let mode = unsafe { mem::transmute(666) };
30029 -+ let mut f = tempfile().unwrap();
30030 -+ f.write_all(INITIAL).unwrap();
30031 -+ let mut aiocb = AioCb::from_fd( f.as_raw_fd(),
30032 -+ 0, //priority
30033 -+ SigevNotify::SigevNone);
30034 -+ let err = aiocb.fsync(mode);
30035 -+ assert!(err.is_err());
30036 -+}
30037 -+
30038 -+#[test]
30039 -+#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
30040 -+fn test_aio_suspend() {
30041 -+ const INITIAL: &[u8] = b"abcdef123456";
30042 -+ const WBUF: &[u8] = b"CDEFG";
30043 -+ let timeout = TimeSpec::seconds(10);
30044 -+ let mut rbuf = vec![0; 4];
30045 -+ let rlen = rbuf.len();
30046 -+ let mut f = tempfile().unwrap();
30047 -+ f.write_all(INITIAL).unwrap();
30048 -+
30049 -+ let mut wcb = AioCb::from_slice( f.as_raw_fd(),
30050 -+ 2, //offset
30051 -+ WBUF,
30052 -+ 0, //priority
30053 -+ SigevNotify::SigevNone,
30054 -+ LioOpcode::LIO_WRITE);
30055 -+
30056 -+ let mut rcb = AioCb::from_mut_slice( f.as_raw_fd(),
30057 -+ 8, //offset
30058 -+ &mut rbuf,
30059 -+ 0, //priority
30060 -+ SigevNotify::SigevNone,
30061 -+ LioOpcode::LIO_READ);
30062 -+ wcb.write().unwrap();
30063 -+ rcb.read().unwrap();
30064 -+ loop {
30065 -+ {
30066 -+ let cbbuf = [&wcb, &rcb];
30067 -+ assert!(aio_suspend(&cbbuf[..], Some(timeout)).is_ok());
30068 -+ }
30069 -+ if rcb.error() != Err(Error::from(Errno::EINPROGRESS)) &&
30070 -+ wcb.error() != Err(Error::from(Errno::EINPROGRESS)) {
30071 -+ break
30072 -+ }
30073 -+ }
30074 -+
30075 -+ assert!(wcb.aio_return().unwrap() as usize == WBUF.len());
30076 -+ assert!(rcb.aio_return().unwrap() as usize == rlen);
30077 -+}
30078 -+
30079 -+// Test a simple aio operation with no completion notification. We must poll
30080 -+// for completion
30081 -+#[test]
30082 -+#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
30083 -+fn test_read() {
30084 -+ const INITIAL: &[u8] = b"abcdef123456";
30085 -+ let mut rbuf = vec![0; 4];
30086 -+ const EXPECT: &[u8] = b"cdef";
30087 -+ let mut f = tempfile().unwrap();
30088 -+ f.write_all(INITIAL).unwrap();
30089 -+ {
30090 -+ let mut aiocb = AioCb::from_mut_slice( f.as_raw_fd(),
30091 -+ 2, //offset
30092 -+ &mut rbuf,
30093 -+ 0, //priority
30094 -+ SigevNotify::SigevNone,
30095 -+ LioOpcode::LIO_NOP);
30096 -+ aiocb.read().unwrap();
30097 -+
30098 -+ let err = poll_aio(&mut aiocb);
30099 -+ assert!(err == Ok(()));
30100 -+ assert!(aiocb.aio_return().unwrap() as usize == EXPECT.len());
30101 -+ }
30102 -+
30103 -+ assert!(EXPECT == rbuf.deref().deref());
30104 -+}
30105 -+
30106 -+/// `AioCb::read` should not modify the `AioCb` object if `libc::aio_read`
30107 -+/// returns an error
30108 -+// Skip on Linux, because Linux's AIO implementation can't detect errors
30109 -+// synchronously
30110 -+#[test]
30111 -+#[cfg(any(target_os = "freebsd", target_os = "macos"))]
30112 -+fn test_read_error() {
30113 -+ const INITIAL: &[u8] = b"abcdef123456";
30114 -+ let mut rbuf = vec![0; 4];
30115 -+ let mut f = tempfile().unwrap();
30116 -+ f.write_all(INITIAL).unwrap();
30117 -+ let mut aiocb = AioCb::from_mut_slice( f.as_raw_fd(),
30118 -+ -1, //an invalid offset
30119 -+ &mut rbuf,
30120 -+ 0, //priority
30121 -+ SigevNotify::SigevNone,
30122 -+ LioOpcode::LIO_NOP);
30123 -+ assert!(aiocb.read().is_err());
30124 -+}
30125 -+
30126 -+// Tests from_mut_slice
30127 -+#[test]
30128 -+#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
30129 -+fn test_read_into_mut_slice() {
30130 -+ const INITIAL: &[u8] = b"abcdef123456";
30131 -+ let mut rbuf = vec![0; 4];
30132 -+ const EXPECT: &[u8] = b"cdef";
30133 -+ let mut f = tempfile().unwrap();
30134 -+ f.write_all(INITIAL).unwrap();
30135 -+ {
30136 -+ let mut aiocb = AioCb::from_mut_slice( f.as_raw_fd(),
30137 -+ 2, //offset
30138 -+ &mut rbuf,
30139 -+ 0, //priority
30140 -+ SigevNotify::SigevNone,
30141 -+ LioOpcode::LIO_NOP);
30142 -+ aiocb.read().unwrap();
30143 -+
30144 -+ let err = poll_aio(&mut aiocb);
30145 -+ assert!(err == Ok(()));
30146 -+ assert!(aiocb.aio_return().unwrap() as usize == EXPECT.len());
30147 -+ }
30148 -+
30149 -+ assert!(rbuf == EXPECT);
30150 -+}
30151 -+
30152 -+// Tests from_ptr
30153 -+#[test]
30154 -+#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
30155 -+fn test_read_into_pointer() {
30156 -+ const INITIAL: &[u8] = b"abcdef123456";
30157 -+ let mut rbuf = vec![0; 4];
30158 -+ const EXPECT: &[u8] = b"cdef";
30159 -+ let mut f = tempfile().unwrap();
30160 -+ f.write_all(INITIAL).unwrap();
30161 -+ {
30162 -+ // Safety: ok because rbuf lives until after poll_aio
30163 -+ let mut aiocb = unsafe {
30164 -+ AioCb::from_mut_ptr( f.as_raw_fd(),
30165 -+ 2, //offset
30166 -+ rbuf.as_mut_ptr() as *mut c_void,
30167 -+ rbuf.len(),
30168 -+ 0, //priority
30169 -+ SigevNotify::SigevNone,
30170 -+ LioOpcode::LIO_NOP)
30171 -+ };
30172 -+ aiocb.read().unwrap();
30173 -+
30174 -+ let err = poll_aio(&mut aiocb);
30175 -+ assert!(err == Ok(()));
30176 -+ assert!(aiocb.aio_return().unwrap() as usize == EXPECT.len());
30177 -+ }
30178 -+
30179 -+ assert!(rbuf == EXPECT);
30180 -+}
30181 -+
30182 -+// Test reading into an immutable buffer. It should fail
30183 -+// FIXME: This test fails to panic on Linux/musl
30184 -+#[test]
30185 -+#[should_panic(expected = "Can't read into an immutable buffer")]
30186 -+#[cfg_attr(target_env = "musl", ignore)]
30187 -+fn test_read_immutable_buffer() {
30188 -+ let rbuf: &[u8] = b"CDEF";
30189 -+ let f = tempfile().unwrap();
30190 -+ let mut aiocb = AioCb::from_slice( f.as_raw_fd(),
30191 -+ 2, //offset
30192 -+ rbuf,
30193 -+ 0, //priority
30194 -+ SigevNotify::SigevNone,
30195 -+ LioOpcode::LIO_NOP);
30196 -+ aiocb.read().unwrap();
30197 -+}
30198 -+
30199 -+
30200 -+// Test a simple aio operation with no completion notification. We must poll
30201 -+// for completion. Unlike test_aio_read, this test uses AioCb::from_slice
30202 -+#[test]
30203 -+#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
30204 -+fn test_write() {
30205 -+ const INITIAL: &[u8] = b"abcdef123456";
30206 -+ let wbuf = "CDEF".to_string().into_bytes();
30207 -+ let mut rbuf = Vec::new();
30208 -+ const EXPECT: &[u8] = b"abCDEF123456";
30209 -+
30210 -+ let mut f = tempfile().unwrap();
30211 -+ f.write_all(INITIAL).unwrap();
30212 -+ let mut aiocb = AioCb::from_slice( f.as_raw_fd(),
30213 -+ 2, //offset
30214 -+ &wbuf,
30215 -+ 0, //priority
30216 -+ SigevNotify::SigevNone,
30217 -+ LioOpcode::LIO_NOP);
30218 -+ aiocb.write().unwrap();
30219 -+
30220 -+ let err = poll_aio(&mut aiocb);
30221 -+ assert!(err == Ok(()));
30222 -+ assert!(aiocb.aio_return().unwrap() as usize == wbuf.len());
30223 -+
30224 -+ f.seek(SeekFrom::Start(0)).unwrap();
30225 -+ let len = f.read_to_end(&mut rbuf).unwrap();
30226 -+ assert!(len == EXPECT.len());
30227 -+ assert!(rbuf == EXPECT);
30228 -+}
30229 -+
30230 -+// Tests `AioCb::from_boxed_slice` with `Bytes`
30231 -+#[test]
30232 -+#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
30233 -+fn test_write_bytes() {
30234 -+ const INITIAL: &[u8] = b"abcdef123456";
30235 -+ let wbuf = Box::new(Bytes::from(&b"CDEF"[..]));
30236 -+ let mut rbuf = Vec::new();
30237 -+ const EXPECT: &[u8] = b"abCDEF123456";
30238 -+ let expected_len = wbuf.len();
30239 -+
30240 -+ let mut f = tempfile().unwrap();
30241 -+ f.write_all(INITIAL).unwrap();
30242 -+ let mut aiocb = AioCb::from_boxed_slice( f.as_raw_fd(),
30243 -+ 2, //offset
30244 -+ wbuf,
30245 -+ 0, //priority
30246 -+ SigevNotify::SigevNone,
30247 -+ LioOpcode::LIO_NOP);
30248 -+ aiocb.write().unwrap();
30249 -+
30250 -+ let err = poll_aio(&mut aiocb);
30251 -+ assert!(err == Ok(()));
30252 -+ assert!(aiocb.aio_return().unwrap() as usize == expected_len);
30253 -+
30254 -+ f.seek(SeekFrom::Start(0)).unwrap();
30255 -+ let len = f.read_to_end(&mut rbuf).unwrap();
30256 -+ assert!(len == EXPECT.len());
30257 -+ assert!(rbuf == EXPECT);
30258 -+}
30259 -+
30260 -+// Tests `AioCb::from_boxed_mut_slice` with `BytesMut`
30261 -+#[test]
30262 -+#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
30263 -+fn test_read_bytes_mut_small() {
30264 -+ const INITIAL: &[u8] = b"abcdef";
30265 -+ let rbuf = Box::new(BytesMut::from(vec![0; 4]));
30266 -+ const EXPECT: &[u8] = b"cdef";
30267 -+ let mut f = tempfile().unwrap();
30268 -+ f.write_all(INITIAL).unwrap();
30269 -+
30270 -+ let mut aiocb = AioCb::from_boxed_mut_slice( f.as_raw_fd(),
30271 -+ 2, //offset
30272 -+ rbuf,
30273 -+ 0, //priority
30274 -+ SigevNotify::SigevNone,
30275 -+ LioOpcode::LIO_NOP);
30276 -+ aiocb.read().unwrap();
30277 -+
30278 -+ let err = poll_aio(&mut aiocb);
30279 -+ assert_eq!(err, Ok(()));
30280 -+ assert_eq!(aiocb.aio_return().unwrap() as usize, EXPECT.len());
30281 -+ let buffer = aiocb.boxed_mut_slice().unwrap();
30282 -+ assert_eq!(buffer.borrow(), EXPECT);
30283 -+}
30284 -+
30285 -+// Tests `AioCb::from_ptr`
30286 -+#[test]
30287 -+#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
30288 -+fn test_write_from_pointer() {
30289 -+ const INITIAL: &[u8] = b"abcdef123456";
30290 -+ let wbuf = "CDEF".to_string().into_bytes();
30291 -+ let mut rbuf = Vec::new();
30292 -+ const EXPECT: &[u8] = b"abCDEF123456";
30293 -+
30294 -+ let mut f = tempfile().unwrap();
30295 -+ f.write_all(INITIAL).unwrap();
30296 -+ // Safety: ok because aiocb outlives poll_aio
30297 -+ let mut aiocb = unsafe {
30298 -+ AioCb::from_ptr( f.as_raw_fd(),
30299 -+ 2, //offset
30300 -+ wbuf.as_ptr() as *const c_void,
30301 -+ wbuf.len(),
30302 -+ 0, //priority
30303 -+ SigevNotify::SigevNone,
30304 -+ LioOpcode::LIO_NOP)
30305 -+ };
30306 -+ aiocb.write().unwrap();
30307 -+
30308 -+ let err = poll_aio(&mut aiocb);
30309 -+ assert!(err == Ok(()));
30310 -+ assert!(aiocb.aio_return().unwrap() as usize == wbuf.len());
30311 -+
30312 -+ f.seek(SeekFrom::Start(0)).unwrap();
30313 -+ let len = f.read_to_end(&mut rbuf).unwrap();
30314 -+ assert!(len == EXPECT.len());
30315 -+ assert!(rbuf == EXPECT);
30316 -+}
30317 -+
30318 -+/// `AioCb::write` should not modify the `AioCb` object if `libc::aio_write`
30319 -+/// returns an error
30320 -+// Skip on Linux, because Linux's AIO implementation can't detect errors
30321 -+// synchronously
30322 -+#[test]
30323 -+#[cfg(any(target_os = "freebsd", target_os = "macos"))]
30324 -+fn test_write_error() {
30325 -+ let wbuf = "CDEF".to_string().into_bytes();
30326 -+ let mut aiocb = AioCb::from_slice( 666, // An invalid file descriptor
30327 -+ 0, //offset
30328 -+ &wbuf,
30329 -+ 0, //priority
30330 -+ SigevNotify::SigevNone,
30331 -+ LioOpcode::LIO_NOP);
30332 -+ assert!(aiocb.write().is_err());
30333 -+}
30334 -+
30335 -+lazy_static! {
30336 -+ pub static ref SIGNALED: AtomicBool = AtomicBool::new(false);
30337 -+}
30338 -+
30339 -+extern fn sigfunc(_: c_int) {
30340 -+ SIGNALED.store(true, Ordering::Relaxed);
30341 -+}
30342 -+
30343 -+// Test an aio operation with completion delivered by a signal
30344 -+// FIXME: This test is ignored on mips because of failures in qemu in CI
30345 -+#[test]
30346 -+#[cfg_attr(any(all(target_env = "musl", target_arch = "x86_64"), target_arch = "mips", target_arch = "mips64"), ignore)]
30347 -+fn test_write_sigev_signal() {
30348 -+ let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
30349 -+ let sa = SigAction::new(SigHandler::Handler(sigfunc),
30350 -+ SaFlags::SA_RESETHAND,
30351 -+ SigSet::empty());
30352 -+ SIGNALED.store(false, Ordering::Relaxed);
30353 -+ unsafe { sigaction(Signal::SIGUSR2, &sa) }.unwrap();
30354 -+
30355 -+ const INITIAL: &[u8] = b"abcdef123456";
30356 -+ const WBUF: &[u8] = b"CDEF";
30357 -+ let mut rbuf = Vec::new();
30358 -+ const EXPECT: &[u8] = b"abCDEF123456";
30359 -+
30360 -+ let mut f = tempfile().unwrap();
30361 -+ f.write_all(INITIAL).unwrap();
30362 -+ let mut aiocb = AioCb::from_slice( f.as_raw_fd(),
30363 -+ 2, //offset
30364 -+ WBUF,
30365 -+ 0, //priority
30366 -+ SigevNotify::SigevSignal {
30367 -+ signal: Signal::SIGUSR2,
30368 -+ si_value: 0 //TODO: validate in sigfunc
30369 -+ },
30370 -+ LioOpcode::LIO_NOP);
30371 -+ aiocb.write().unwrap();
30372 -+ while !SIGNALED.load(Ordering::Relaxed) {
30373 -+ thread::sleep(time::Duration::from_millis(10));
30374 -+ }
30375 -+
30376 -+ assert!(aiocb.aio_return().unwrap() as usize == WBUF.len());
30377 -+ f.seek(SeekFrom::Start(0)).unwrap();
30378 -+ let len = f.read_to_end(&mut rbuf).unwrap();
30379 -+ assert!(len == EXPECT.len());
30380 -+ assert!(rbuf == EXPECT);
30381 -+}
30382 -+
30383 -+// Test LioCb::listio with LIO_WAIT, so all AIO ops should be complete by the
30384 -+// time listio returns.
30385 -+#[test]
30386 -+#[cfg(not(any(target_os = "ios", target_os = "macos")))]
30387 -+#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
30388 -+fn test_liocb_listio_wait() {
30389 -+ const INITIAL: &[u8] = b"abcdef123456";
30390 -+ const WBUF: &[u8] = b"CDEF";
30391 -+ let mut rbuf = vec![0; 4];
30392 -+ let rlen = rbuf.len();
30393 -+ let mut rbuf2 = Vec::new();
30394 -+ const EXPECT: &[u8] = b"abCDEF123456";
30395 -+ let mut f = tempfile().unwrap();
30396 -+
30397 -+ f.write_all(INITIAL).unwrap();
30398 -+
30399 -+ {
30400 -+ let wcb = AioCb::from_slice( f.as_raw_fd(),
30401 -+ 2, //offset
30402 -+ WBUF,
30403 -+ 0, //priority
30404 -+ SigevNotify::SigevNone,
30405 -+ LioOpcode::LIO_WRITE);
30406 -+
30407 -+ let rcb = AioCb::from_mut_slice( f.as_raw_fd(),
30408 -+ 8, //offset
30409 -+ &mut rbuf,
30410 -+ 0, //priority
30411 -+ SigevNotify::SigevNone,
30412 -+ LioOpcode::LIO_READ);
30413 -+ let mut liocb = LioCb::with_capacity(2);
30414 -+ liocb.aiocbs.push(wcb);
30415 -+ liocb.aiocbs.push(rcb);
30416 -+ let err = liocb.listio(LioMode::LIO_WAIT, SigevNotify::SigevNone);
30417 -+ err.expect("lio_listio");
30418 -+
30419 -+ assert!(liocb.aio_return(0).unwrap() as usize == WBUF.len());
30420 -+ assert!(liocb.aio_return(1).unwrap() as usize == rlen);
30421 -+ }
30422 -+ assert!(rbuf.deref().deref() == b"3456");
30423 -+
30424 -+ f.seek(SeekFrom::Start(0)).unwrap();
30425 -+ let len = f.read_to_end(&mut rbuf2).unwrap();
30426 -+ assert!(len == EXPECT.len());
30427 -+ assert!(rbuf2 == EXPECT);
30428 -+}
30429 -+
30430 -+// Test LioCb::listio with LIO_NOWAIT and no SigEvent, so we must use some other
30431 -+// mechanism to check for the individual AioCb's completion.
30432 -+#[test]
30433 -+#[cfg(not(any(target_os = "ios", target_os = "macos")))]
30434 -+#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
30435 -+fn test_liocb_listio_nowait() {
30436 -+ const INITIAL: &[u8] = b"abcdef123456";
30437 -+ const WBUF: &[u8] = b"CDEF";
30438 -+ let mut rbuf = vec![0; 4];
30439 -+ let rlen = rbuf.len();
30440 -+ let mut rbuf2 = Vec::new();
30441 -+ const EXPECT: &[u8] = b"abCDEF123456";
30442 -+ let mut f = tempfile().unwrap();
30443 -+
30444 -+ f.write_all(INITIAL).unwrap();
30445 -+
30446 -+ {
30447 -+ let wcb = AioCb::from_slice( f.as_raw_fd(),
30448 -+ 2, //offset
30449 -+ WBUF,
30450 -+ 0, //priority
30451 -+ SigevNotify::SigevNone,
30452 -+ LioOpcode::LIO_WRITE);
30453 -+
30454 -+ let rcb = AioCb::from_mut_slice( f.as_raw_fd(),
30455 -+ 8, //offset
30456 -+ &mut rbuf,
30457 -+ 0, //priority
30458 -+ SigevNotify::SigevNone,
30459 -+ LioOpcode::LIO_READ);
30460 -+ let mut liocb = LioCb::with_capacity(2);
30461 -+ liocb.aiocbs.push(wcb);
30462 -+ liocb.aiocbs.push(rcb);
30463 -+ let err = liocb.listio(LioMode::LIO_NOWAIT, SigevNotify::SigevNone);
30464 -+ err.expect("lio_listio");
30465 -+
30466 -+ poll_aio(&mut liocb.aiocbs[0]).unwrap();
30467 -+ poll_aio(&mut liocb.aiocbs[1]).unwrap();
30468 -+ assert!(liocb.aiocbs[0].aio_return().unwrap() as usize == WBUF.len());
30469 -+ assert!(liocb.aiocbs[1].aio_return().unwrap() as usize == rlen);
30470 -+ }
30471 -+ assert!(rbuf.deref().deref() == b"3456");
30472 -+
30473 -+ f.seek(SeekFrom::Start(0)).unwrap();
30474 -+ let len = f.read_to_end(&mut rbuf2).unwrap();
30475 -+ assert!(len == EXPECT.len());
30476 -+ assert!(rbuf2 == EXPECT);
30477 -+}
30478 -+
30479 -+// Test LioCb::listio with LIO_NOWAIT and a SigEvent to indicate when all
30480 -+// AioCb's are complete.
30481 -+// FIXME: This test is ignored on mips/mips64 because of failures in qemu in CI.
30482 -+#[test]
30483 -+#[cfg(not(any(target_os = "ios", target_os = "macos")))]
30484 -+#[cfg_attr(any(target_arch = "mips", target_arch = "mips64", target_env = "musl"), ignore)]
30485 -+fn test_liocb_listio_signal() {
30486 -+ let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
30487 -+ const INITIAL: &[u8] = b"abcdef123456";
30488 -+ const WBUF: &[u8] = b"CDEF";
30489 -+ let mut rbuf = vec![0; 4];
30490 -+ let rlen = rbuf.len();
30491 -+ let mut rbuf2 = Vec::new();
30492 -+ const EXPECT: &[u8] = b"abCDEF123456";
30493 -+ let mut f = tempfile().unwrap();
30494 -+ let sa = SigAction::new(SigHandler::Handler(sigfunc),
30495 -+ SaFlags::SA_RESETHAND,
30496 -+ SigSet::empty());
30497 -+ let sigev_notify = SigevNotify::SigevSignal { signal: Signal::SIGUSR2,
30498 -+ si_value: 0 };
30499 -+
30500 -+ f.write_all(INITIAL).unwrap();
30501 -+
30502 -+ {
30503 -+ let wcb = AioCb::from_slice( f.as_raw_fd(),
30504 -+ 2, //offset
30505 -+ WBUF,
30506 -+ 0, //priority
30507 -+ SigevNotify::SigevNone,
30508 -+ LioOpcode::LIO_WRITE);
30509 -+
30510 -+ let rcb = AioCb::from_mut_slice( f.as_raw_fd(),
30511 -+ 8, //offset
30512 -+ &mut rbuf,
30513 -+ 0, //priority
30514 -+ SigevNotify::SigevNone,
30515 -+ LioOpcode::LIO_READ);
30516 -+ let mut liocb = LioCb::with_capacity(2);
30517 -+ liocb.aiocbs.push(wcb);
30518 -+ liocb.aiocbs.push(rcb);
30519 -+ SIGNALED.store(false, Ordering::Relaxed);
30520 -+ unsafe { sigaction(Signal::SIGUSR2, &sa) }.unwrap();
30521 -+ let err = liocb.listio(LioMode::LIO_NOWAIT, sigev_notify);
30522 -+ err.expect("lio_listio");
30523 -+ while !SIGNALED.load(Ordering::Relaxed) {
30524 -+ thread::sleep(time::Duration::from_millis(10));
30525 -+ }
30526 -+
30527 -+ assert!(liocb.aiocbs[0].aio_return().unwrap() as usize == WBUF.len());
30528 -+ assert!(liocb.aiocbs[1].aio_return().unwrap() as usize == rlen);
30529 -+ }
30530 -+ assert!(rbuf.deref().deref() == b"3456");
30531 -+
30532 -+ f.seek(SeekFrom::Start(0)).unwrap();
30533 -+ let len = f.read_to_end(&mut rbuf2).unwrap();
30534 -+ assert!(len == EXPECT.len());
30535 -+ assert!(rbuf2 == EXPECT);
30536 -+}
30537 -+
30538 -+// Try to use LioCb::listio to read into an immutable buffer. It should fail
30539 -+// FIXME: This test fails to panic on Linux/musl
30540 -+#[test]
30541 -+#[cfg(not(any(target_os = "ios", target_os = "macos")))]
30542 -+#[should_panic(expected = "Can't read into an immutable buffer")]
30543 -+#[cfg_attr(target_env = "musl", ignore)]
30544 -+fn test_liocb_listio_read_immutable() {
30545 -+ let rbuf: &[u8] = b"abcd";
30546 -+ let f = tempfile().unwrap();
30547 -+
30548 -+
30549 -+ let mut liocb = LioCb::from(vec![
30550 -+ AioCb::from_slice( f.as_raw_fd(),
30551 -+ 2, //offset
30552 -+ rbuf,
30553 -+ 0, //priority
30554 -+ SigevNotify::SigevNone,
30555 -+ LioOpcode::LIO_READ)
30556 -+ ]);
30557 -+ let _ = liocb.listio(LioMode::LIO_NOWAIT, SigevNotify::SigevNone);
30558 -+}
30559 -diff --git a/third_party/rust/nix-0.15.0/test/sys/test_aio_drop.rs b/third_party/rust/nix-0.15.0/test/sys/test_aio_drop.rs
30560 -new file mode 100644
30561 -index 0000000000000..492da401ef726
30562 ---- /dev/null
30563 -+++ b/third_party/rust/nix-0.15.0/test/sys/test_aio_drop.rs
30564 -@@ -0,0 +1,32 @@
30565 -+extern crate nix;
30566 -+extern crate tempfile;
30567 -+
30568 -+// Test dropping an AioCb that hasn't yet finished.
30569 -+// This must happen in its own process, because on OSX this test seems to hose
30570 -+// the AIO subsystem and causes subsequent tests to fail
30571 -+#[test]
30572 -+#[should_panic(expected = "Dropped an in-progress AioCb")]
30573 -+#[cfg(all(not(target_env = "musl"),
30574 -+ any(target_os = "linux",
30575 -+ target_os = "ios",
30576 -+ target_os = "macos",
30577 -+ target_os = "freebsd",
30578 -+ target_os = "netbsd")))]
30579 -+fn test_drop() {
30580 -+ use nix::sys::aio::*;
30581 -+ use nix::sys::signal::*;
30582 -+ use std::os::unix::io::AsRawFd;
30583 -+ use tempfile::tempfile;
30584 -+
30585 -+ const WBUF: &[u8] = b"CDEF";
30586 -+
30587 -+ let f = tempfile().unwrap();
30588 -+ f.set_len(6).unwrap();
30589 -+ let mut aiocb = AioCb::from_slice( f.as_raw_fd(),
30590 -+ 2, //offset
30591 -+ WBUF,
30592 -+ 0, //priority
30593 -+ SigevNotify::SigevNone,
30594 -+ LioOpcode::LIO_NOP);
30595 -+ aiocb.write().unwrap();
30596 -+}
30597 -diff --git a/third_party/rust/nix-0.15.0/test/sys/test_epoll.rs b/third_party/rust/nix-0.15.0/test/sys/test_epoll.rs
30598 -new file mode 100644
30599 -index 0000000000000..e0dc5131defe0
30600 ---- /dev/null
30601 -+++ b/third_party/rust/nix-0.15.0/test/sys/test_epoll.rs
30602 -@@ -0,0 +1,24 @@
30603 -+use nix::sys::epoll::{EpollCreateFlags, EpollFlags, EpollOp, EpollEvent};
30604 -+use nix::sys::epoll::{epoll_create1, epoll_ctl};
30605 -+use nix::Error;
30606 -+use nix::errno::Errno;
30607 -+
30608 -+#[test]
30609 -+pub fn test_epoll_errno() {
30610 -+ let efd = epoll_create1(EpollCreateFlags::empty()).unwrap();
30611 -+ let result = epoll_ctl(efd, EpollOp::EpollCtlDel, 1, None);
30612 -+ assert!(result.is_err());
30613 -+ assert_eq!(result.unwrap_err(), Error::Sys(Errno::ENOENT));
30614 -+
30615 -+ let result = epoll_ctl(efd, EpollOp::EpollCtlAdd, 1, None);
30616 -+ assert!(result.is_err());
30617 -+ assert_eq!(result.unwrap_err(), Error::Sys(Errno::EINVAL));
30618 -+}
30619 -+
30620 -+#[test]
30621 -+pub fn test_epoll_ctl() {
30622 -+ let efd = epoll_create1(EpollCreateFlags::empty()).unwrap();
30623 -+ let mut event = EpollEvent::new(EpollFlags::EPOLLIN | EpollFlags::EPOLLERR, 1);
30624 -+ epoll_ctl(efd, EpollOp::EpollCtlAdd, 1, &mut event).unwrap();
30625 -+ epoll_ctl(efd, EpollOp::EpollCtlDel, 1, None).unwrap();
30626 -+}
30627 -diff --git a/third_party/rust/nix-0.15.0/test/sys/test_inotify.rs b/third_party/rust/nix-0.15.0/test/sys/test_inotify.rs
30628 -new file mode 100644
30629 -index 0000000000000..a8ead46d487ba
30630 ---- /dev/null
30631 -+++ b/third_party/rust/nix-0.15.0/test/sys/test_inotify.rs
30632 -@@ -0,0 +1,65 @@
30633 -+use nix::sys::inotify::{AddWatchFlags,InitFlags,Inotify};
30634 -+use nix::Error;
30635 -+use nix::errno::Errno;
30636 -+use tempfile;
30637 -+use std::ffi::OsString;
30638 -+use std::fs::{rename, File};
30639 -+
30640 -+#[test]
30641 -+pub fn test_inotify() {
30642 -+ let instance = Inotify::init(InitFlags::IN_NONBLOCK)
30643 -+ .unwrap();
30644 -+ let tempdir = tempfile::tempdir().unwrap();
30645 -+
30646 -+ instance.add_watch(tempdir.path(), AddWatchFlags::IN_ALL_EVENTS).unwrap();
30647 -+
30648 -+ let events = instance.read_events();
30649 -+ assert_eq!(events.unwrap_err(), Error::Sys(Errno::EAGAIN));
30650 -+
30651 -+ File::create(tempdir.path().join("test")).unwrap();
30652 -+
30653 -+ let events = instance.read_events().unwrap();
30654 -+ assert_eq!(events[0].name, Some(OsString::from("test")));
30655 -+}
30656 -+
30657 -+#[test]
30658 -+pub fn test_inotify_multi_events() {
30659 -+ let instance = Inotify::init(InitFlags::IN_NONBLOCK)
30660 -+ .unwrap();
30661 -+ let tempdir = tempfile::tempdir().unwrap();
30662 -+
30663 -+ instance.add_watch(tempdir.path(), AddWatchFlags::IN_ALL_EVENTS).unwrap();
30664 -+
30665 -+ let events = instance.read_events();
30666 -+ assert_eq!(events.unwrap_err(), Error::Sys(Errno::EAGAIN));
30667 -+
30668 -+ File::create(tempdir.path().join("test")).unwrap();
30669 -+ rename(tempdir.path().join("test"), tempdir.path().join("test2")).unwrap();
30670 -+
30671 -+ // Now there should be 5 events in queue:
30672 -+ // - IN_CREATE on test
30673 -+ // - IN_OPEN on test
30674 -+ // - IN_CLOSE_WRITE on test
30675 -+ // - IN_MOVED_FROM on test with a cookie
30676 -+ // - IN_MOVED_TO on test2 with the same cookie
30677 -+
30678 -+ let events = instance.read_events().unwrap();
30679 -+ assert_eq!(events.len(), 5);
30680 -+
30681 -+ assert_eq!(events[0].mask, AddWatchFlags::IN_CREATE);
30682 -+ assert_eq!(events[0].name, Some(OsString::from("test")));
30683 -+
30684 -+ assert_eq!(events[1].mask, AddWatchFlags::IN_OPEN);
30685 -+ assert_eq!(events[1].name, Some(OsString::from("test")));
30686 -+
30687 -+ assert_eq!(events[2].mask, AddWatchFlags::IN_CLOSE_WRITE);
30688 -+ assert_eq!(events[2].name, Some(OsString::from("test")));
30689 -+
30690 -+ assert_eq!(events[3].mask, AddWatchFlags::IN_MOVED_FROM);
30691 -+ assert_eq!(events[3].name, Some(OsString::from("test")));
30692 -+
30693 -+ assert_eq!(events[4].mask, AddWatchFlags::IN_MOVED_TO);
30694 -+ assert_eq!(events[4].name, Some(OsString::from("test2")));
30695 -+
30696 -+ assert_eq!(events[3].cookie, events[4].cookie);
30697 -+}
30698 -diff --git a/third_party/rust/nix-0.15.0/test/sys/test_ioctl.rs b/third_party/rust/nix-0.15.0/test/sys/test_ioctl.rs
30699 -new file mode 100644
30700 -index 0000000000000..0a439b3346f53
30701 ---- /dev/null
30702 -+++ b/third_party/rust/nix-0.15.0/test/sys/test_ioctl.rs
30703 -@@ -0,0 +1,334 @@
30704 -+#![allow(dead_code)]
30705 -+
30706 -+// Simple tests to ensure macro generated fns compile
30707 -+ioctl_none_bad!(do_bad, 0x1234);
30708 -+ioctl_read_bad!(do_bad_read, 0x1234, u16);
30709 -+ioctl_write_int_bad!(do_bad_write_int, 0x1234);
30710 -+ioctl_write_ptr_bad!(do_bad_write_ptr, 0x1234, u8);
30711 -+ioctl_readwrite_bad!(do_bad_readwrite, 0x1234, u32);
30712 -+ioctl_none!(do_none, 0, 0);
30713 -+ioctl_read!(read_test, 0, 0, u32);
30714 -+ioctl_write_int!(write_ptr_int, 0, 0);
30715 -+ioctl_write_ptr!(write_ptr_u8, 0, 0, u8);
30716 -+ioctl_write_ptr!(write_ptr_u32, 0, 0, u32);
30717 -+ioctl_write_ptr!(write_ptr_u64, 0, 0, u64);
30718 -+ioctl_readwrite!(readwrite_test, 0, 0, u64);
30719 -+ioctl_read_buf!(readbuf_test, 0, 0, u32);
30720 -+const SPI_IOC_MAGIC: u8 = b'k';
30721 -+const SPI_IOC_MESSAGE: u8 = 0;
30722 -+ioctl_write_buf!(writebuf_test_consts, SPI_IOC_MAGIC, SPI_IOC_MESSAGE, u8);
30723 -+ioctl_write_buf!(writebuf_test_u8, 0, 0, u8);
30724 -+ioctl_write_buf!(writebuf_test_u32, 0, 0, u32);
30725 -+ioctl_write_buf!(writebuf_test_u64, 0, 0, u64);
30726 -+ioctl_readwrite_buf!(readwritebuf_test, 0, 0, u32);
30727 -+
30728 -+// See C code for source of values for op calculations (does NOT work for mips/powerpc):
30729 -+// https://gist.github.com/posborne/83ea6880770a1aef332e
30730 -+//
30731 -+// TODO: Need a way to compute these constants at test time. Using precomputed
30732 -+// values is fragile and needs to be maintained.
30733 -+
30734 -+#[cfg(any(target_os = "linux", target_os = "android"))]
30735 -+mod linux {
30736 -+ #[test]
30737 -+ fn test_op_none() {
30738 -+ if cfg!(any(target_arch = "mips", target_arch = "mips64", target_arch="powerpc", target_arch="powerpc64")){
30739 -+ assert_eq!(request_code_none!(b'q', 10), 0x2000_710A);
30740 -+ assert_eq!(request_code_none!(b'a', 255), 0x2000_61FF);
30741 -+ } else {
30742 -+ assert_eq!(request_code_none!(b'q', 10), 0x0000_710A);
30743 -+ assert_eq!(request_code_none!(b'a', 255), 0x0000_61FF);
30744 -+ }
30745 -+ }
30746 -+
30747 -+ #[test]
30748 -+ fn test_op_write() {
30749 -+ if cfg!(any(target_arch = "mips", target_arch = "mips64", target_arch="powerpc", target_arch="powerpc64")){
30750 -+ assert_eq!(request_code_write!(b'z', 10, 1), 0x8001_7A0A);
30751 -+ assert_eq!(request_code_write!(b'z', 10, 512), 0x8200_7A0A);
30752 -+ } else {
30753 -+ assert_eq!(request_code_write!(b'z', 10, 1), 0x4001_7A0A);
30754 -+ assert_eq!(request_code_write!(b'z', 10, 512), 0x4200_7A0A);
30755 -+ }
30756 -+ }
30757 -+
30758 -+ #[cfg(target_pointer_width = "64")]
30759 -+ #[test]
30760 -+ fn test_op_write_64() {
30761 -+ if cfg!(any(target_arch = "mips64", target_arch="powerpc64")){
30762 -+ assert_eq!(request_code_write!(b'z', 10, (1 as u64) << 32), 0x8000_7A0A);
30763 -+ } else {
30764 -+ assert_eq!(request_code_write!(b'z', 10, (1 as u64) << 32), 0x4000_7A0A);
30765 -+ }
30766 -+
30767 -+ }
30768 -+
30769 -+ #[test]
30770 -+ fn test_op_read() {
30771 -+ if cfg!(any(target_arch = "mips", target_arch = "mips64", target_arch="powerpc", target_arch="powerpc64")){
30772 -+ assert_eq!(request_code_read!(b'z', 10, 1), 0x4001_7A0A);
30773 -+ assert_eq!(request_code_read!(b'z', 10, 512), 0x4200_7A0A);
30774 -+ } else {
30775 -+ assert_eq!(request_code_read!(b'z', 10, 1), 0x8001_7A0A);
30776 -+ assert_eq!(request_code_read!(b'z', 10, 512), 0x8200_7A0A);
30777 -+ }
30778 -+ }
30779 -+
30780 -+ #[cfg(target_pointer_width = "64")]
30781 -+ #[test]
30782 -+ fn test_op_read_64() {
30783 -+ if cfg!(any(target_arch = "mips64", target_arch="powerpc64")){
30784 -+ assert_eq!(request_code_read!(b'z', 10, (1 as u64) << 32), 0x4000_7A0A);
30785 -+ } else {
30786 -+ assert_eq!(request_code_read!(b'z', 10, (1 as u64) << 32), 0x8000_7A0A);
30787 -+ }
30788 -+ }
30789 -+
30790 -+ #[test]
30791 -+ fn test_op_read_write() {
30792 -+ assert_eq!(request_code_readwrite!(b'z', 10, 1), 0xC001_7A0A);
30793 -+ assert_eq!(request_code_readwrite!(b'z', 10, 512), 0xC200_7A0A);
30794 -+ }
30795 -+
30796 -+ #[cfg(target_pointer_width = "64")]
30797 -+ #[test]
30798 -+ fn test_op_read_write_64() {
30799 -+ assert_eq!(request_code_readwrite!(b'z', 10, (1 as u64) << 32), 0xC000_7A0A);
30800 -+ }
30801 -+}
30802 -+
30803 -+#[cfg(any(target_os = "dragonfly",
30804 -+ target_os = "freebsd",
30805 -+ target_os = "ios",
30806 -+ target_os = "macos",
30807 -+ target_os = "netbsd",
30808 -+ target_os = "openbsd"))]
30809 -+mod bsd {
30810 -+ #[test]
30811 -+ fn test_op_none() {
30812 -+ assert_eq!(request_code_none!(b'q', 10), 0x2000_710A);
30813 -+ assert_eq!(request_code_none!(b'a', 255), 0x2000_61FF);
30814 -+ }
30815 -+
30816 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
30817 -+ #[test]
30818 -+ fn test_op_write_int() {
30819 -+ assert_eq!(request_code_write_int!(b'v', 4), 0x2004_7604);
30820 -+ assert_eq!(request_code_write_int!(b'p', 2), 0x2004_7002);
30821 -+ }
30822 -+
30823 -+ #[test]
30824 -+ fn test_op_write() {
30825 -+ assert_eq!(request_code_write!(b'z', 10, 1), 0x8001_7A0A);
30826 -+ assert_eq!(request_code_write!(b'z', 10, 512), 0x8200_7A0A);
30827 -+ }
30828 -+
30829 -+ #[cfg(target_pointer_width = "64")]
30830 -+ #[test]
30831 -+ fn test_op_write_64() {
30832 -+ assert_eq!(request_code_write!(b'z', 10, (1 as u64) << 32), 0x8000_7A0A);
30833 -+ }
30834 -+
30835 -+ #[test]
30836 -+ fn test_op_read() {
30837 -+ assert_eq!(request_code_read!(b'z', 10, 1), 0x4001_7A0A);
30838 -+ assert_eq!(request_code_read!(b'z', 10, 512), 0x4200_7A0A);
30839 -+ }
30840 -+
30841 -+ #[cfg(target_pointer_width = "64")]
30842 -+ #[test]
30843 -+ fn test_op_read_64() {
30844 -+ assert_eq!(request_code_read!(b'z', 10, (1 as u64) << 32), 0x4000_7A0A);
30845 -+ }
30846 -+
30847 -+ #[test]
30848 -+ fn test_op_read_write() {
30849 -+ assert_eq!(request_code_readwrite!(b'z', 10, 1), 0xC001_7A0A);
30850 -+ assert_eq!(request_code_readwrite!(b'z', 10, 512), 0xC200_7A0A);
30851 -+ }
30852 -+
30853 -+ #[cfg(target_pointer_width = "64")]
30854 -+ #[test]
30855 -+ fn test_op_read_write_64() {
30856 -+ assert_eq!(request_code_readwrite!(b'z', 10, (1 as u64) << 32), 0xC000_7A0A);
30857 -+ }
30858 -+}
30859 -+
30860 -+#[cfg(any(target_os = "android", target_os = "linux"))]
30861 -+mod linux_ioctls {
30862 -+ use std::mem;
30863 -+ use std::os::unix::io::AsRawFd;
30864 -+
30865 -+ use tempfile::tempfile;
30866 -+ use libc::{TCGETS, TCSBRK, TCSETS, TIOCNXCL, termios};
30867 -+
30868 -+ use nix::Error::Sys;
30869 -+ use nix::errno::Errno::{ENOTTY, ENOSYS};
30870 -+
30871 -+ ioctl_none_bad!(tiocnxcl, TIOCNXCL);
30872 -+ #[test]
30873 -+ fn test_ioctl_none_bad() {
30874 -+ let file = tempfile().unwrap();
30875 -+ let res = unsafe { tiocnxcl(file.as_raw_fd()) };
30876 -+ assert_eq!(res, Err(Sys(ENOTTY)));
30877 -+ }
30878 -+
30879 -+ ioctl_read_bad!(tcgets, TCGETS, termios);
30880 -+ #[test]
30881 -+ fn test_ioctl_read_bad() {
30882 -+ let file = tempfile().unwrap();
30883 -+ let mut termios = unsafe { mem::uninitialized() };
30884 -+ let res = unsafe { tcgets(file.as_raw_fd(), &mut termios) };
30885 -+ assert_eq!(res, Err(Sys(ENOTTY)));
30886 -+ }
30887 -+
30888 -+ ioctl_write_int_bad!(tcsbrk, TCSBRK);
30889 -+ #[test]
30890 -+ fn test_ioctl_write_int_bad() {
30891 -+ let file = tempfile().unwrap();
30892 -+ let res = unsafe { tcsbrk(file.as_raw_fd(), 0) };
30893 -+ assert_eq!(res, Err(Sys(ENOTTY)));
30894 -+ }
30895 -+
30896 -+ ioctl_write_ptr_bad!(tcsets, TCSETS, termios);
30897 -+ #[test]
30898 -+ fn test_ioctl_write_ptr_bad() {
30899 -+ let file = tempfile().unwrap();
30900 -+ let termios: termios = unsafe { mem::uninitialized() };
30901 -+ let res = unsafe { tcsets(file.as_raw_fd(), &termios) };
30902 -+ assert_eq!(res, Err(Sys(ENOTTY)));
30903 -+ }
30904 -+
30905 -+ // FIXME: Find a suitable example for `ioctl_readwrite_bad`
30906 -+
30907 -+ // From linux/videodev2.h
30908 -+ ioctl_none!(log_status, b'V', 70);
30909 -+ #[test]
30910 -+ fn test_ioctl_none() {
30911 -+ let file = tempfile().unwrap();
30912 -+ let res = unsafe { log_status(file.as_raw_fd()) };
30913 -+ assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
30914 -+ }
30915 -+
30916 -+ #[repr(C)]
30917 -+ pub struct v4l2_audio {
30918 -+ index: u32,
30919 -+ name: [u8; 32],
30920 -+ capability: u32,
30921 -+ mode: u32,
30922 -+ reserved: [u32; 2],
30923 -+ }
30924 -+
30925 -+ // From linux/videodev2.h
30926 -+ ioctl_write_ptr!(s_audio, b'V', 34, v4l2_audio);
30927 -+ #[test]
30928 -+ fn test_ioctl_write_ptr() {
30929 -+ let file = tempfile().unwrap();
30930 -+ let data: v4l2_audio = unsafe { mem::zeroed() };
30931 -+ let res = unsafe { s_audio(file.as_raw_fd(), &data) };
30932 -+ assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
30933 -+ }
30934 -+
30935 -+ // From linux/net/bluetooth/hci_sock.h
30936 -+ const HCI_IOC_MAGIC: u8 = b'H';
30937 -+ const HCI_IOC_HCIDEVUP: u8 = 201;
30938 -+ ioctl_write_int!(hcidevup, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
30939 -+ #[test]
30940 -+ fn test_ioctl_write_int() {
30941 -+ let file = tempfile().unwrap();
30942 -+ let res = unsafe { hcidevup(file.as_raw_fd(), 0) };
30943 -+ assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
30944 -+ }
30945 -+
30946 -+ // From linux/videodev2.h
30947 -+ ioctl_read!(g_audio, b'V', 33, v4l2_audio);
30948 -+ #[test]
30949 -+ fn test_ioctl_read() {
30950 -+ let file = tempfile().unwrap();
30951 -+ let mut data: v4l2_audio = unsafe { mem::uninitialized() };
30952 -+ let res = unsafe { g_audio(file.as_raw_fd(), &mut data) };
30953 -+ assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
30954 -+ }
30955 -+
30956 -+ // From linux/videodev2.h
30957 -+ ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio);
30958 -+ #[test]
30959 -+ fn test_ioctl_readwrite() {
30960 -+ let file = tempfile().unwrap();
30961 -+ let mut data: v4l2_audio = unsafe { mem::uninitialized() };
30962 -+ let res = unsafe { enum_audio(file.as_raw_fd(), &mut data) };
30963 -+ assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
30964 -+ }
30965 -+
30966 -+ // FIXME: Find a suitable example for `ioctl_read_buf`.
30967 -+
30968 -+ #[repr(C)]
30969 -+ pub struct spi_ioc_transfer {
30970 -+ tx_buf: u64,
30971 -+ rx_buf: u64,
30972 -+ len: u32,
30973 -+ speed_hz: u32,
30974 -+ delay_usecs: u16,
30975 -+ bits_per_word: u8,
30976 -+ cs_change: u8,
30977 -+ tx_nbits: u8,
30978 -+ rx_nbits: u8,
30979 -+ pad: u16,
30980 -+ }
30981 -+
30982 -+ // From linux/spi/spidev.h
30983 -+ ioctl_write_buf!(spi_ioc_message, super::SPI_IOC_MAGIC, super::SPI_IOC_MESSAGE, spi_ioc_transfer);
30984 -+ #[test]
30985 -+ fn test_ioctl_write_buf() {
30986 -+ let file = tempfile().unwrap();
30987 -+ let data: [spi_ioc_transfer; 4] = unsafe { mem::zeroed() };
30988 -+ let res = unsafe { spi_ioc_message(file.as_raw_fd(), &data[..]) };
30989 -+ assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
30990 -+ }
30991 -+
30992 -+ // FIXME: Find a suitable example for `ioctl_readwrite_buf`.
30993 -+}
30994 -+
30995 -+#[cfg(target_os = "freebsd")]
30996 -+mod freebsd_ioctls {
30997 -+ use std::mem;
30998 -+ use std::os::unix::io::AsRawFd;
30999 -+
31000 -+ use tempfile::tempfile;
31001 -+ use libc::termios;
31002 -+
31003 -+ use nix::Error::Sys;
31004 -+ use nix::errno::Errno::ENOTTY;
31005 -+
31006 -+ // From sys/sys/ttycom.h
31007 -+ const TTY_IOC_MAGIC: u8 = b't';
31008 -+ const TTY_IOC_TYPE_NXCL: u8 = 14;
31009 -+ const TTY_IOC_TYPE_GETA: u8 = 19;
31010 -+ const TTY_IOC_TYPE_SETA: u8 = 20;
31011 -+
31012 -+ ioctl_none!(tiocnxcl, TTY_IOC_MAGIC, TTY_IOC_TYPE_NXCL);
31013 -+ #[test]
31014 -+ fn test_ioctl_none() {
31015 -+ let file = tempfile().unwrap();
31016 -+ let res = unsafe { tiocnxcl(file.as_raw_fd()) };
31017 -+ assert_eq!(res, Err(Sys(ENOTTY)));
31018 -+ }
31019 -+
31020 -+ ioctl_read!(tiocgeta, TTY_IOC_MAGIC, TTY_IOC_TYPE_GETA, termios);
31021 -+ #[test]
31022 -+ fn test_ioctl_read() {
31023 -+ let file = tempfile().unwrap();
31024 -+ let mut termios = unsafe { mem::uninitialized() };
31025 -+ let res = unsafe { tiocgeta(file.as_raw_fd(), &mut termios) };
31026 -+ assert_eq!(res, Err(Sys(ENOTTY)));
31027 -+ }
31028 -+
31029 -+ ioctl_write_ptr!(tiocseta, TTY_IOC_MAGIC, TTY_IOC_TYPE_SETA, termios);
31030 -+ #[test]
31031 -+ fn test_ioctl_write_ptr() {
31032 -+ let file = tempfile().unwrap();
31033 -+ let termios: termios = unsafe { mem::uninitialized() };
31034 -+ let res = unsafe { tiocseta(file.as_raw_fd(), &termios) };
31035 -+ assert_eq!(res, Err(Sys(ENOTTY)));
31036 -+ }
31037 -+}
31038 -diff --git a/third_party/rust/nix-0.15.0/test/sys/test_lio_listio_resubmit.rs b/third_party/rust/nix-0.15.0/test/sys/test_lio_listio_resubmit.rs
31039 -new file mode 100644
31040 -index 0000000000000..19ee3facf87d7
31041 ---- /dev/null
31042 -+++ b/third_party/rust/nix-0.15.0/test/sys/test_lio_listio_resubmit.rs
31043 -@@ -0,0 +1,111 @@
31044 -+// vim: tw=80
31045 -+
31046 -+// Annoyingly, Cargo is unable to conditionally build an entire test binary. So
31047 -+// we must disable the test here rather than in Cargo.toml
31048 -+#![cfg(target_os = "freebsd")]
31049 -+
31050 -+extern crate nix;
31051 -+extern crate sysctl;
31052 -+extern crate tempfile;
31053 -+
31054 -+use nix::Error;
31055 -+use nix::errno::*;
31056 -+use nix::libc::off_t;
31057 -+use nix::sys::aio::*;
31058 -+use nix::sys::signal::SigevNotify;
31059 -+use nix::unistd::{SysconfVar, sysconf};
31060 -+use std::os::unix::io::AsRawFd;
31061 -+use std::{thread, time};
31062 -+use sysctl::CtlValue;
31063 -+use tempfile::tempfile;
31064 -+
31065 -+const BYTES_PER_OP: usize = 512;
31066 -+
31067 -+/// Attempt to collect final status for all of `liocb`'s operations, freeing
31068 -+/// system resources
31069 -+fn finish_liocb(liocb: &mut LioCb) {
31070 -+ for j in 0..liocb.aiocbs.len() {
31071 -+ loop {
31072 -+ let e = liocb.error(j);
31073 -+ match e {
31074 -+ Ok(()) => break,
31075 -+ Err(Error::Sys(Errno::EINPROGRESS)) =>
31076 -+ thread::sleep(time::Duration::from_millis(10)),
31077 -+ Err(x) => panic!("aio_error({:?})", x)
31078 -+ }
31079 -+ }
31080 -+ assert_eq!(liocb.aio_return(j).unwrap(), BYTES_PER_OP as isize);
31081 -+ }
31082 -+}
31083 -+
31084 -+// Deliberately exceed system resource limits, causing lio_listio to return EIO.
31085 -+// This test must run in its own process since it deliberately uses all AIO
31086 -+// resources. ATM it is only enabled on FreeBSD, because I don't know how to
31087 -+// check system AIO limits on other operating systems.
31088 -+#[test]
31089 -+fn test_lio_listio_resubmit() {
31090 -+ let mut resubmit_count = 0;
31091 -+
31092 -+ // Lookup system resource limits
31093 -+ let alm = sysconf(SysconfVar::AIO_LISTIO_MAX)
31094 -+ .expect("sysconf").unwrap() as usize;
31095 -+ let maqpp = if let CtlValue::Int(x) = sysctl::value(
31096 -+ "vfs.aio.max_aio_queue_per_proc").unwrap(){
31097 -+ x as usize
31098 -+ } else {
31099 -+ panic!("unknown sysctl");
31100 -+ };
31101 -+
31102 -+ // Find lio_listio sizes that satisfy the AIO_LISTIO_MAX constraint and also
31103 -+ // result in a final lio_listio call that can only partially be queued
31104 -+ let target_ops = maqpp + alm / 2;
31105 -+ let num_listios = (target_ops + alm - 3) / (alm - 2);
31106 -+ let ops_per_listio = (target_ops + num_listios - 1) / num_listios;
31107 -+ assert!((num_listios - 1) * ops_per_listio < maqpp,
31108 -+ "the last lio_listio won't make any progress; fix the algorithm");
31109 -+ println!("Using {:?} LioCbs of {:?} operations apiece", num_listios,
31110 -+ ops_per_listio);
31111 -+
31112 -+ let f = tempfile().unwrap();
31113 -+ let buffer_set = (0..num_listios).map(|_| {
31114 -+ (0..ops_per_listio).map(|_| {
31115 -+ vec![0u8; BYTES_PER_OP]
31116 -+ }).collect::<Vec<_>>()
31117 -+ }).collect::<Vec<_>>();
31118 -+
31119 -+ let mut liocbs = (0..num_listios).map(|i| {
31120 -+ let mut liocb = LioCb::with_capacity(ops_per_listio);
31121 -+ for j in 0..ops_per_listio {
31122 -+ let offset = (BYTES_PER_OP * (i * ops_per_listio + j)) as off_t;
31123 -+ let wcb = AioCb::from_slice( f.as_raw_fd(),
31124 -+ offset,
31125 -+ &buffer_set[i][j][..],
31126 -+ 0, //priority
31127 -+ SigevNotify::SigevNone,
31128 -+ LioOpcode::LIO_WRITE);
31129 -+ liocb.aiocbs.push(wcb);
31130 -+ }
31131 -+ let mut err = liocb.listio(LioMode::LIO_NOWAIT, SigevNotify::SigevNone);
31132 -+ while err == Err(Error::Sys(Errno::EIO)) ||
31133 -+ err == Err(Error::Sys(Errno::EAGAIN)) ||
31134 -+ err == Err(Error::Sys(Errno::EINTR)) {
31135 -+ //
31136 -+ thread::sleep(time::Duration::from_millis(10));
31137 -+ resubmit_count += 1;
31138 -+ err = liocb.listio_resubmit(LioMode::LIO_NOWAIT,
31139 -+ SigevNotify::SigevNone);
31140 -+ }
31141 -+ liocb
31142 -+ }).collect::<Vec<_>>();
31143 -+
31144 -+ // Ensure that every AioCb completed
31145 -+ for liocb in liocbs.iter_mut() {
31146 -+ finish_liocb(liocb);
31147 -+ }
31148 -+
31149 -+ if resubmit_count > 0 {
31150 -+ println!("Resubmitted {:?} times, test passed", resubmit_count);
31151 -+ } else {
31152 -+ println!("Never resubmitted. Test ambiguous");
31153 -+ }
31154 -+}
31155 -diff --git a/third_party/rust/nix-0.15.0/test/sys/test_pthread.rs b/third_party/rust/nix-0.15.0/test/sys/test_pthread.rs
31156 -new file mode 100644
31157 -index 0000000000000..8928010087a13
31158 ---- /dev/null
31159 -+++ b/third_party/rust/nix-0.15.0/test/sys/test_pthread.rs
31160 -@@ -0,0 +1,15 @@
31161 -+use nix::sys::pthread::*;
31162 -+
31163 -+#[cfg(target_env = "musl")]
31164 -+#[test]
31165 -+fn test_pthread_self() {
31166 -+ let tid = pthread_self();
31167 -+ assert!(tid != ::std::ptr::null_mut());
31168 -+}
31169 -+
31170 -+#[cfg(not(target_env = "musl"))]
31171 -+#[test]
31172 -+fn test_pthread_self() {
31173 -+ let tid = pthread_self();
31174 -+ assert!(tid != 0);
31175 -+}
31176 -diff --git a/third_party/rust/nix-0.15.0/test/sys/test_ptrace.rs b/third_party/rust/nix-0.15.0/test/sys/test_ptrace.rs
31177 -new file mode 100644
31178 -index 0000000000000..24d9b522ee4e5
31179 ---- /dev/null
31180 -+++ b/third_party/rust/nix-0.15.0/test/sys/test_ptrace.rs
31181 -@@ -0,0 +1,107 @@
31182 -+use nix::Error;
31183 -+use nix::errno::Errno;
31184 -+use nix::unistd::getpid;
31185 -+use nix::sys::ptrace;
31186 -+#[cfg(any(target_os = "android", target_os = "linux"))]
31187 -+use nix::sys::ptrace::Options;
31188 -+
31189 -+#[cfg(any(target_os = "android", target_os = "linux"))]
31190 -+use std::mem;
31191 -+
31192 -+#[test]
31193 -+fn test_ptrace() {
31194 -+ // Just make sure ptrace can be called at all, for now.
31195 -+ // FIXME: qemu-user doesn't implement ptrace on all arches, so permit ENOSYS
31196 -+ let err = ptrace::attach(getpid()).unwrap_err();
31197 -+ assert!(err == Error::Sys(Errno::EPERM) || err == Error::Sys(Errno::EINVAL) ||
31198 -+ err == Error::Sys(Errno::ENOSYS));
31199 -+}
31200 -+
31201 -+// Just make sure ptrace_setoptions can be called at all, for now.
31202 -+#[test]
31203 -+#[cfg(any(target_os = "android", target_os = "linux"))]
31204 -+fn test_ptrace_setoptions() {
31205 -+ let err = ptrace::setoptions(getpid(), Options::PTRACE_O_TRACESYSGOOD).unwrap_err();
31206 -+ assert!(err != Error::UnsupportedOperation);
31207 -+}
31208 -+
31209 -+// Just make sure ptrace_getevent can be called at all, for now.
31210 -+#[test]
31211 -+#[cfg(any(target_os = "android", target_os = "linux"))]
31212 -+fn test_ptrace_getevent() {
31213 -+ let err = ptrace::getevent(getpid()).unwrap_err();
31214 -+ assert!(err != Error::UnsupportedOperation);
31215 -+}
31216 -+
31217 -+// Just make sure ptrace_getsiginfo can be called at all, for now.
31218 -+#[test]
31219 -+#[cfg(any(target_os = "android", target_os = "linux"))]
31220 -+fn test_ptrace_getsiginfo() {
31221 -+ if let Err(Error::UnsupportedOperation) = ptrace::getsiginfo(getpid()) {
31222 -+ panic!("ptrace_getsiginfo returns Error::UnsupportedOperation!");
31223 -+ }
31224 -+}
31225 -+
31226 -+// Just make sure ptrace_setsiginfo can be called at all, for now.
31227 -+#[test]
31228 -+#[cfg(any(target_os = "android", target_os = "linux"))]
31229 -+fn test_ptrace_setsiginfo() {
31230 -+ let siginfo = unsafe { mem::uninitialized() };
31231 -+ if let Err(Error::UnsupportedOperation) = ptrace::setsiginfo(getpid(), &siginfo) {
31232 -+ panic!("ptrace_setsiginfo returns Error::UnsupportedOperation!");
31233 -+ }
31234 -+}
31235 -+
31236 -+
31237 -+#[test]
31238 -+fn test_ptrace_cont() {
31239 -+ use nix::sys::ptrace;
31240 -+ use nix::sys::signal::{raise, Signal};
31241 -+ use nix::sys::wait::{waitpid, WaitPidFlag, WaitStatus};
31242 -+ use nix::unistd::fork;
31243 -+ use nix::unistd::ForkResult::*;
31244 -+
31245 -+ let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
31246 -+
31247 -+ // FIXME: qemu-user doesn't implement ptrace on all architectures
31248 -+ // and retunrs ENOSYS in this case.
31249 -+ // We (ab)use this behavior to detect the affected platforms
31250 -+ // and skip the test then.
31251 -+ // On valid platforms the ptrace call should return Errno::EPERM, this
31252 -+ // is already tested by `test_ptrace`.
31253 -+ let err = ptrace::attach(getpid()).unwrap_err();
31254 -+ if err == Error::Sys(Errno::ENOSYS) {
31255 -+ return;
31256 -+ }
31257 -+
31258 -+ match fork().expect("Error: Fork Failed") {
31259 -+ Child => {
31260 -+ ptrace::traceme().unwrap();
31261 -+ // As recommended by ptrace(2), raise SIGTRAP to pause the child
31262 -+ // until the parent is ready to continue
31263 -+ loop {
31264 -+ raise(Signal::SIGTRAP).unwrap();
31265 -+ }
31266 -+
31267 -+ },
31268 -+ Parent { child } => {
31269 -+ assert_eq!(waitpid(child, None), Ok(WaitStatus::Stopped(child, Signal::SIGTRAP)));
31270 -+ ptrace::cont(child, None).unwrap();
31271 -+ assert_eq!(waitpid(child, None), Ok(WaitStatus::Stopped(child, Signal::SIGTRAP)));
31272 -+ ptrace::cont(child, Some(Signal::SIGKILL)).unwrap();
31273 -+ match waitpid(child, None) {
31274 -+ Ok(WaitStatus::Signaled(pid, Signal::SIGKILL, _)) if pid == child => {
31275 -+ // FIXME It's been observed on some systems (apple) the
31276 -+ // tracee may not be killed but remain as a zombie process
31277 -+ // affecting other wait based tests. Add an extra kill just
31278 -+ // to make sure there are no zombies.
31279 -+ let _ = waitpid(child, Some(WaitPidFlag::WNOHANG));
31280 -+ while ptrace::cont(child, Some(Signal::SIGKILL)).is_ok() {
31281 -+ let _ = waitpid(child, Some(WaitPidFlag::WNOHANG));
31282 -+ }
31283 -+ }
31284 -+ _ => panic!("The process should have been killed"),
31285 -+ }
31286 -+ },
31287 -+ }
31288 -+}
31289 -diff --git a/third_party/rust/nix-0.15.0/test/sys/test_select.rs b/third_party/rust/nix-0.15.0/test/sys/test_select.rs
31290 -new file mode 100644
31291 -index 0000000000000..cf68700c5e16f
31292 ---- /dev/null
31293 -+++ b/third_party/rust/nix-0.15.0/test/sys/test_select.rs
31294 -@@ -0,0 +1,54 @@
31295 -+use nix::sys::select::*;
31296 -+use nix::unistd::{pipe, write};
31297 -+use nix::sys::signal::SigSet;
31298 -+use nix::sys::time::{TimeSpec, TimeValLike};
31299 -+
31300 -+#[test]
31301 -+pub fn test_pselect() {
31302 -+ let _mtx = ::SIGNAL_MTX
31303 -+ .lock()
31304 -+ .expect("Mutex got poisoned by another test");
31305 -+
31306 -+ let (r1, w1) = pipe().unwrap();
31307 -+ write(w1, b"hi!").unwrap();
31308 -+ let (r2, _w2) = pipe().unwrap();
31309 -+
31310 -+ let mut fd_set = FdSet::new();
31311 -+ fd_set.insert(r1);
31312 -+ fd_set.insert(r2);
31313 -+
31314 -+ let timeout = TimeSpec::seconds(10);
31315 -+ let sigmask = SigSet::empty();
31316 -+ assert_eq!(
31317 -+ 1,
31318 -+ pselect(None, &mut fd_set, None, None, &timeout, &sigmask).unwrap()
31319 -+ );
31320 -+ assert!(fd_set.contains(r1));
31321 -+ assert!(!fd_set.contains(r2));
31322 -+}
31323 -+
31324 -+#[test]
31325 -+pub fn test_pselect_nfds2() {
31326 -+ let (r1, w1) = pipe().unwrap();
31327 -+ write(w1, b"hi!").unwrap();
31328 -+ let (r2, _w2) = pipe().unwrap();
31329 -+
31330 -+ let mut fd_set = FdSet::new();
31331 -+ fd_set.insert(r1);
31332 -+ fd_set.insert(r2);
31333 -+
31334 -+ let timeout = TimeSpec::seconds(10);
31335 -+ assert_eq!(
31336 -+ 1,
31337 -+ pselect(
31338 -+ ::std::cmp::max(r1, r2) + 1,
31339 -+ &mut fd_set,
31340 -+ None,
31341 -+ None,
31342 -+ &timeout,
31343 -+ None
31344 -+ ).unwrap()
31345 -+ );
31346 -+ assert!(fd_set.contains(r1));
31347 -+ assert!(!fd_set.contains(r2));
31348 -+}
31349 -diff --git a/third_party/rust/nix-0.15.0/test/sys/test_signal.rs b/third_party/rust/nix-0.15.0/test/sys/test_signal.rs
31350 -new file mode 100644
31351 -index 0000000000000..8780763f773ef
31352 ---- /dev/null
31353 -+++ b/third_party/rust/nix-0.15.0/test/sys/test_signal.rs
31354 -@@ -0,0 +1,104 @@
31355 -+use libc;
31356 -+use nix::Error;
31357 -+use nix::sys::signal::*;
31358 -+use nix::unistd::*;
31359 -+use std::sync::atomic::{AtomicBool, Ordering};
31360 -+
31361 -+#[test]
31362 -+fn test_kill_none() {
31363 -+ kill(getpid(), None).expect("Should be able to send signal to myself.");
31364 -+}
31365 -+
31366 -+#[test]
31367 -+fn test_killpg_none() {
31368 -+ killpg(getpgrp(), None)
31369 -+ .expect("Should be able to send signal to my process group.");
31370 -+}
31371 -+
31372 -+#[test]
31373 -+fn test_old_sigaction_flags() {
31374 -+ extern "C" fn handler(_: ::libc::c_int) {}
31375 -+ let act = SigAction::new(
31376 -+ SigHandler::Handler(handler),
31377 -+ SaFlags::empty(),
31378 -+ SigSet::empty(),
31379 -+ );
31380 -+ let oact = unsafe { sigaction(SIGINT, &act) }.unwrap();
31381 -+ let _flags = oact.flags();
31382 -+ let oact = unsafe { sigaction(SIGINT, &act) }.unwrap();
31383 -+ let _flags = oact.flags();
31384 -+}
31385 -+
31386 -+#[test]
31387 -+fn test_sigprocmask_noop() {
31388 -+ sigprocmask(SigmaskHow::SIG_BLOCK, None, None)
31389 -+ .expect("this should be an effective noop");
31390 -+}
31391 -+
31392 -+#[test]
31393 -+fn test_sigprocmask() {
31394 -+ let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
31395 -+
31396 -+ // This needs to be a signal that rust doesn't use in the test harness.
31397 -+ const SIGNAL: Signal = Signal::SIGCHLD;
31398 -+
31399 -+ let mut old_signal_set = SigSet::empty();
31400 -+ sigprocmask(SigmaskHow::SIG_BLOCK, None, Some(&mut old_signal_set))
31401 -+ .expect("expect to be able to retrieve old signals");
31402 -+
31403 -+ // Make sure the old set doesn't contain the signal, otherwise the following
31404 -+ // test don't make sense.
31405 -+ assert_eq!(old_signal_set.contains(SIGNAL), false,
31406 -+ "the {:?} signal is already blocked, please change to a \
31407 -+ different one", SIGNAL);
31408 -+
31409 -+ // Now block the signal.
31410 -+ let mut signal_set = SigSet::empty();
31411 -+ signal_set.add(SIGNAL);
31412 -+ sigprocmask(SigmaskHow::SIG_BLOCK, Some(&signal_set), None)
31413 -+ .expect("expect to be able to block signals");
31414 -+
31415 -+ // And test it again, to make sure the change was effective.
31416 -+ old_signal_set.clear();
31417 -+ sigprocmask(SigmaskHow::SIG_BLOCK, None, Some(&mut old_signal_set))
31418 -+ .expect("expect to be able to retrieve old signals");
31419 -+ assert_eq!(old_signal_set.contains(SIGNAL), true,
31420 -+ "expected the {:?} to be blocked", SIGNAL);
31421 -+
31422 -+ // Reset the signal.
31423 -+ sigprocmask(SigmaskHow::SIG_UNBLOCK, Some(&signal_set), None)
31424 -+ .expect("expect to be able to block signals");
31425 -+}
31426 -+
31427 -+lazy_static! {
31428 -+ static ref SIGNALED: AtomicBool = AtomicBool::new(false);
31429 -+}
31430 -+
31431 -+extern fn test_sigaction_handler(signal: libc::c_int) {
31432 -+ let signal = Signal::from_c_int(signal).unwrap();
31433 -+ SIGNALED.store(signal == Signal::SIGINT, Ordering::Relaxed);
31434 -+}
31435 -+
31436 -+extern fn test_sigaction_action(_: libc::c_int, _: *mut libc::siginfo_t, _: *mut libc::c_void) {
31437 -+}
31438 -+
31439 -+#[test]
31440 -+fn test_signal() {
31441 -+ let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
31442 -+
31443 -+ unsafe { signal(Signal::SIGINT, SigHandler::SigIgn) }.unwrap();
31444 -+ raise(Signal::SIGINT).unwrap();
31445 -+ assert_eq!(unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(), SigHandler::SigIgn);
31446 -+
31447 -+ let handler = SigHandler::Handler(test_sigaction_handler);
31448 -+ assert_eq!(unsafe { signal(Signal::SIGINT, handler) }.unwrap(), SigHandler::SigDfl);
31449 -+ raise(Signal::SIGINT).unwrap();
31450 -+ assert!(SIGNALED.load(Ordering::Relaxed));
31451 -+ assert_eq!(unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(), handler);
31452 -+
31453 -+ let action_handler = SigHandler::SigAction(test_sigaction_action);
31454 -+ assert_eq!(unsafe { signal(Signal::SIGINT, action_handler) }.unwrap_err(), Error::UnsupportedOperation);
31455 -+
31456 -+ // Restore default signal handler
31457 -+ unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap();
31458 -+}
31459 -diff --git a/third_party/rust/nix-0.15.0/test/sys/test_signalfd.rs b/third_party/rust/nix-0.15.0/test/sys/test_signalfd.rs
31460 -new file mode 100644
31461 -index 0000000000000..a3b6098841f1c
31462 ---- /dev/null
31463 -+++ b/third_party/rust/nix-0.15.0/test/sys/test_signalfd.rs
31464 -@@ -0,0 +1,25 @@
31465 -+#[test]
31466 -+fn test_signalfd() {
31467 -+ use nix::sys::signalfd::SignalFd;
31468 -+ use nix::sys::signal::{self, raise, Signal, SigSet};
31469 -+
31470 -+ // Grab the mutex for altering signals so we don't interfere with other tests.
31471 -+ let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
31472 -+
31473 -+ // Block the SIGUSR1 signal from automatic processing for this thread
31474 -+ let mut mask = SigSet::empty();
31475 -+ mask.add(signal::SIGUSR1);
31476 -+ mask.thread_block().unwrap();
31477 -+
31478 -+ let mut fd = SignalFd::new(&mask).unwrap();
31479 -+
31480 -+ // Send a SIGUSR1 signal to the current process. Note that this uses `raise` instead of `kill`
31481 -+ // because `kill` with `getpid` isn't correct during multi-threaded execution like during a
31482 -+ // cargo test session. Instead use `raise` which does the correct thing by default.
31483 -+ raise(signal::SIGUSR1).expect("Error: raise(SIGUSR1) failed");
31484 -+
31485 -+ // And now catch that same signal.
31486 -+ let res = fd.read_signal().unwrap().unwrap();
31487 -+ let signo = Signal::from_c_int(res.ssi_signo as i32).unwrap();
31488 -+ assert_eq!(signo, signal::SIGUSR1);
31489 -+}
31490 -diff --git a/third_party/rust/nix-0.15.0/test/sys/test_socket.rs b/third_party/rust/nix-0.15.0/test/sys/test_socket.rs
31491 -new file mode 100644
31492 -index 0000000000000..7e64d2b77f071
31493 ---- /dev/null
31494 -+++ b/third_party/rust/nix-0.15.0/test/sys/test_socket.rs
31495 -@@ -0,0 +1,1066 @@
31496 -+use nix::ifaddrs::InterfaceAddress;
31497 -+use nix::sys::socket::{AddressFamily, InetAddr, UnixAddr, getsockname};
31498 -+use std::collections::hash_map::DefaultHasher;
31499 -+use std::hash::{Hash, Hasher};
31500 -+use std::net::{self, Ipv6Addr, SocketAddr, SocketAddrV6};
31501 -+use std::os::unix::io::RawFd;
31502 -+use std::path::Path;
31503 -+use std::slice;
31504 -+use std::str::FromStr;
31505 -+use libc::c_char;
31506 -+use tempfile;
31507 -+
31508 -+#[test]
31509 -+pub fn test_inetv4_addr_to_sock_addr() {
31510 -+ let actual: net::SocketAddr = FromStr::from_str("127.0.0.1:3000").unwrap();
31511 -+ let addr = InetAddr::from_std(&actual);
31512 -+
31513 -+ match addr {
31514 -+ InetAddr::V4(addr) => {
31515 -+ let ip: u32 = 0x7f00_0001;
31516 -+ let port: u16 = 3000;
31517 -+ let saddr = addr.sin_addr.s_addr;
31518 -+
31519 -+ assert_eq!(saddr, ip.to_be());
31520 -+ assert_eq!(addr.sin_port, port.to_be());
31521 -+ }
31522 -+ _ => panic!("nope"),
31523 -+ }
31524 -+
31525 -+ assert_eq!(addr.to_str(), "127.0.0.1:3000");
31526 -+
31527 -+ let inet = addr.to_std();
31528 -+ assert_eq!(actual, inet);
31529 -+}
31530 -+
31531 -+#[test]
31532 -+pub fn test_inetv6_addr_to_sock_addr() {
31533 -+ let port: u16 = 3000;
31534 -+ let flowinfo: u32 = 1;
31535 -+ let scope_id: u32 = 2;
31536 -+ let ip: Ipv6Addr = "fe80::1".parse().unwrap();
31537 -+
31538 -+ let actual = SocketAddr::V6(SocketAddrV6::new(ip, port, flowinfo, scope_id));
31539 -+ let addr = InetAddr::from_std(&actual);
31540 -+
31541 -+ match addr {
31542 -+ InetAddr::V6(addr) => {
31543 -+ assert_eq!(addr.sin6_port, port.to_be());
31544 -+ assert_eq!(addr.sin6_flowinfo, flowinfo);
31545 -+ assert_eq!(addr.sin6_scope_id, scope_id);
31546 -+ }
31547 -+ _ => panic!("nope"),
31548 -+ }
31549 -+
31550 -+ assert_eq!(actual, addr.to_std());
31551 -+}
31552 -+
31553 -+#[test]
31554 -+pub fn test_path_to_sock_addr() {
31555 -+ let path = "/foo/bar";
31556 -+ let actual = Path::new(path);
31557 -+ let addr = UnixAddr::new(actual).unwrap();
31558 -+
31559 -+ let expect: &[c_char] = unsafe {
31560 -+ slice::from_raw_parts(path.as_bytes().as_ptr() as *const c_char, path.len())
31561 -+ };
31562 -+ assert_eq!(&addr.0.sun_path[..8], expect);
31563 -+
31564 -+ assert_eq!(addr.path(), Some(actual));
31565 -+}
31566 -+
31567 -+fn calculate_hash<T: Hash>(t: &T) -> u64 {
31568 -+ let mut s = DefaultHasher::new();
31569 -+ t.hash(&mut s);
31570 -+ s.finish()
31571 -+}
31572 -+
31573 -+#[test]
31574 -+pub fn test_addr_equality_path() {
31575 -+ let path = "/foo/bar";
31576 -+ let actual = Path::new(path);
31577 -+ let addr1 = UnixAddr::new(actual).unwrap();
31578 -+ let mut addr2 = addr1.clone();
31579 -+
31580 -+ addr2.0.sun_path[10] = 127;
31581 -+
31582 -+ assert_eq!(addr1, addr2);
31583 -+ assert_eq!(calculate_hash(&addr1), calculate_hash(&addr2));
31584 -+}
31585 -+
31586 -+#[cfg(any(target_os = "android", target_os = "linux"))]
31587 -+#[test]
31588 -+pub fn test_abstract_sun_path_too_long() {
31589 -+ let name = String::from("nix\0abstract\0tesnix\0abstract\0tesnix\0abstract\0tesnix\0abstract\0tesnix\0abstract\0testttttnix\0abstract\0test\0make\0sure\0this\0is\0long\0enough");
31590 -+ let addr = UnixAddr::new_abstract(name.as_bytes());
31591 -+ assert!(addr.is_err());
31592 -+}
31593 -+
31594 -+#[cfg(any(target_os = "android", target_os = "linux"))]
31595 -+#[test]
31596 -+pub fn test_addr_equality_abstract() {
31597 -+ let name = String::from("nix\0abstract\0test");
31598 -+ let addr1 = UnixAddr::new_abstract(name.as_bytes()).unwrap();
31599 -+ let mut addr2 = addr1.clone();
31600 -+
31601 -+ assert_eq!(addr1, addr2);
31602 -+ assert_eq!(calculate_hash(&addr1), calculate_hash(&addr2));
31603 -+
31604 -+ addr2.0.sun_path[18] = 127;
31605 -+ assert_ne!(addr1, addr2);
31606 -+ assert_ne!(calculate_hash(&addr1), calculate_hash(&addr2));
31607 -+}
31608 -+
31609 -+// Test getting/setting abstract addresses (without unix socket creation)
31610 -+#[cfg(target_os = "linux")]
31611 -+#[test]
31612 -+pub fn test_abstract_uds_addr() {
31613 -+ let empty = String::new();
31614 -+ let addr = UnixAddr::new_abstract(empty.as_bytes()).unwrap();
31615 -+ let sun_path = [0u8; 107];
31616 -+ assert_eq!(addr.as_abstract(), Some(&sun_path[..]));
31617 -+
31618 -+ let name = String::from("nix\0abstract\0test");
31619 -+ let addr = UnixAddr::new_abstract(name.as_bytes()).unwrap();
31620 -+ let sun_path = [
31621 -+ 110u8, 105, 120, 0, 97, 98, 115, 116, 114, 97, 99, 116, 0, 116, 101, 115, 116, 0, 0, 0, 0,
31622 -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31623 -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31624 -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31625 -+ ];
31626 -+ assert_eq!(addr.as_abstract(), Some(&sun_path[..]));
31627 -+ assert_eq!(addr.path(), None);
31628 -+
31629 -+ // Internally, name is null-prefixed (abstract namespace)
31630 -+ assert_eq!(addr.0.sun_path[0], 0);
31631 -+}
31632 -+
31633 -+#[test]
31634 -+pub fn test_getsockname() {
31635 -+ use nix::sys::socket::{socket, AddressFamily, SockType, SockFlag};
31636 -+ use nix::sys::socket::{bind, SockAddr};
31637 -+
31638 -+ let tempdir = tempfile::tempdir().unwrap();
31639 -+ let sockname = tempdir.path().join("sock");
31640 -+ let sock = socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(), None)
31641 -+ .expect("socket failed");
31642 -+ let sockaddr = SockAddr::new_unix(&sockname).unwrap();
31643 -+ bind(sock, &sockaddr).expect("bind failed");
31644 -+ assert_eq!(sockaddr.to_str(),
31645 -+ getsockname(sock).expect("getsockname failed").to_str());
31646 -+}
31647 -+
31648 -+#[test]
31649 -+pub fn test_socketpair() {
31650 -+ use nix::unistd::{read, write};
31651 -+ use nix::sys::socket::{socketpair, AddressFamily, SockType, SockFlag};
31652 -+
31653 -+ let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
31654 -+ .unwrap();
31655 -+ write(fd1, b"hello").unwrap();
31656 -+ let mut buf = [0;5];
31657 -+ read(fd2, &mut buf).unwrap();
31658 -+
31659 -+ assert_eq!(&buf[..], b"hello");
31660 -+}
31661 -+
31662 -+// Test error handling of our recvmsg wrapper
31663 -+#[test]
31664 -+pub fn test_recvmsg_ebadf() {
31665 -+ use nix::Error;
31666 -+ use nix::errno::Errno;
31667 -+ use nix::sys::socket::{MsgFlags, recvmsg};
31668 -+ use nix::sys::uio::IoVec;
31669 -+
31670 -+ let mut buf = [0u8; 5];
31671 -+ let iov = [IoVec::from_mut_slice(&mut buf[..])];
31672 -+ let fd = -1; // Bad file descriptor
31673 -+ let r = recvmsg(fd, &iov, None, MsgFlags::empty());
31674 -+ assert_eq!(r.err().unwrap(), Error::Sys(Errno::EBADF));
31675 -+}
31676 -+
31677 -+// Disable the test on emulated platforms due to a bug in QEMU versions <
31678 -+// 2.12.0. https://bugs.launchpad.net/qemu/+bug/1701808
31679 -+#[cfg_attr(not(any(target_arch = "x86_64", target_arch="i686")), ignore)]
31680 -+#[test]
31681 -+pub fn test_scm_rights() {
31682 -+ use nix::sys::uio::IoVec;
31683 -+ use nix::unistd::{pipe, read, write, close};
31684 -+ use nix::sys::socket::{socketpair, sendmsg, recvmsg,
31685 -+ AddressFamily, SockType, SockFlag,
31686 -+ ControlMessage, ControlMessageOwned, MsgFlags};
31687 -+
31688 -+ let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
31689 -+ .unwrap();
31690 -+ let (r, w) = pipe().unwrap();
31691 -+ let mut received_r: Option<RawFd> = None;
31692 -+
31693 -+ {
31694 -+ let iov = [IoVec::from_slice(b"hello")];
31695 -+ let fds = [r];
31696 -+ let cmsg = ControlMessage::ScmRights(&fds);
31697 -+ assert_eq!(sendmsg(fd1, &iov, &[cmsg], MsgFlags::empty(), None).unwrap(), 5);
31698 -+ close(r).unwrap();
31699 -+ close(fd1).unwrap();
31700 -+ }
31701 -+
31702 -+ {
31703 -+ let mut buf = [0u8; 5];
31704 -+ let iov = [IoVec::from_mut_slice(&mut buf[..])];
31705 -+ let mut cmsgspace = cmsg_space!([RawFd; 1]);
31706 -+ let msg = recvmsg(fd2, &iov, Some(&mut cmsgspace), MsgFlags::empty()).unwrap();
31707 -+
31708 -+ for cmsg in msg.cmsgs() {
31709 -+ if let ControlMessageOwned::ScmRights(fd) = cmsg {
31710 -+ assert_eq!(received_r, None);
31711 -+ assert_eq!(fd.len(), 1);
31712 -+ received_r = Some(fd[0]);
31713 -+ } else {
31714 -+ panic!("unexpected cmsg");
31715 -+ }
31716 -+ }
31717 -+ assert_eq!(msg.bytes, 5);
31718 -+ assert!(!msg.flags.intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
31719 -+ close(fd2).unwrap();
31720 -+ }
31721 -+
31722 -+ let received_r = received_r.expect("Did not receive passed fd");
31723 -+ // Ensure that the received file descriptor works
31724 -+ write(w, b"world").unwrap();
31725 -+ let mut buf = [0u8; 5];
31726 -+ read(received_r, &mut buf).unwrap();
31727 -+ assert_eq!(&buf[..], b"world");
31728 -+ close(received_r).unwrap();
31729 -+ close(w).unwrap();
31730 -+}
31731 -+
31732 -+// Disable the test on emulated platforms due to not enabled support of AF_ALG in QEMU from rust cross
31733 -+#[cfg_attr(not(any(target_arch = "x86_64", target_arch = "i686")), ignore)]
31734 -+#[cfg(any(target_os = "linux", target_os= "android"))]
31735 -+#[test]
31736 -+pub fn test_af_alg_cipher() {
31737 -+ use libc;
31738 -+ use nix::sys::uio::IoVec;
31739 -+ use nix::unistd::read;
31740 -+ use nix::sys::socket::{socket, sendmsg, bind, accept, setsockopt,
31741 -+ AddressFamily, SockType, SockFlag, SockAddr,
31742 -+ ControlMessage, MsgFlags};
31743 -+ use nix::sys::socket::sockopt::AlgSetKey;
31744 -+
31745 -+ let alg_type = "skcipher";
31746 -+ let alg_name = "ctr(aes)";
31747 -+ // 256-bits secret key
31748 -+ let key = vec![0u8; 32];
31749 -+ // 16-bytes IV
31750 -+ let iv_len = 16;
31751 -+ let iv = vec![1u8; iv_len];
31752 -+ // 256-bytes plain payload
31753 -+ let payload_len = 256;
31754 -+ let payload = vec![2u8; payload_len];
31755 -+
31756 -+ let sock = socket(AddressFamily::Alg, SockType::SeqPacket, SockFlag::empty(), None)
31757 -+ .expect("socket failed");
31758 -+
31759 -+ let sockaddr = SockAddr::new_alg(alg_type, alg_name);
31760 -+ bind(sock, &sockaddr).expect("bind failed");
31761 -+
31762 -+ if let SockAddr::Alg(alg) = sockaddr {
31763 -+ assert_eq!(alg.alg_name().to_string_lossy(), alg_name);
31764 -+ assert_eq!(alg.alg_type().to_string_lossy(), alg_type);
31765 -+ } else {
31766 -+ panic!("unexpected SockAddr");
31767 -+ }
31768 -+
31769 -+ setsockopt(sock, AlgSetKey::default(), &key).expect("setsockopt");
31770 -+ let session_socket = accept(sock).expect("accept failed");
31771 -+
31772 -+ let msgs = [ControlMessage::AlgSetOp(&libc::ALG_OP_ENCRYPT), ControlMessage::AlgSetIv(iv.as_slice())];
31773 -+ let iov = IoVec::from_slice(&payload);
31774 -+ sendmsg(session_socket, &[iov], &msgs, MsgFlags::empty(), None).expect("sendmsg encrypt");
31775 -+
31776 -+ // allocate buffer for encrypted data
31777 -+ let mut encrypted = vec![0u8; payload_len];
31778 -+ let num_bytes = read(session_socket, &mut encrypted).expect("read encrypt");
31779 -+ assert_eq!(num_bytes, payload_len);
31780 -+
31781 -+ let iov = IoVec::from_slice(&encrypted);
31782 -+
31783 -+ let iv = vec![1u8; iv_len];
31784 -+
31785 -+ let msgs = [ControlMessage::AlgSetOp(&libc::ALG_OP_DECRYPT), ControlMessage::AlgSetIv(iv.as_slice())];
31786 -+ sendmsg(session_socket, &[iov], &msgs, MsgFlags::empty(), None).expect("sendmsg decrypt");
31787 -+
31788 -+ // allocate buffer for decrypted data
31789 -+ let mut decrypted = vec![0u8; payload_len];
31790 -+ let num_bytes = read(session_socket, &mut decrypted).expect("read decrypt");
31791 -+
31792 -+ assert_eq!(num_bytes, payload_len);
31793 -+ assert_eq!(decrypted, payload);
31794 -+}
31795 -+
31796 -+// Disable the test on emulated platforms due to not enabled support of AF_ALG in QEMU from rust cross
31797 -+#[cfg_attr(not(any(target_arch = "x86_64", target_arch = "i686")), ignore)]
31798 -+#[cfg(any(target_os = "linux", target_os= "android"))]
31799 -+#[test]
31800 -+pub fn test_af_alg_aead() {
31801 -+ use libc::{ALG_OP_DECRYPT, ALG_OP_ENCRYPT};
31802 -+ use nix::sys::uio::IoVec;
31803 -+ use nix::unistd::{read, close};
31804 -+ use nix::sys::socket::{socket, sendmsg, bind, accept, setsockopt,
31805 -+ AddressFamily, SockType, SockFlag, SockAddr,
31806 -+ ControlMessage, MsgFlags};
31807 -+ use nix::sys::socket::sockopt::{AlgSetKey, AlgSetAeadAuthSize};
31808 -+
31809 -+ let auth_size = 4usize;
31810 -+ let assoc_size = 16u32;
31811 -+
31812 -+ let alg_type = "aead";
31813 -+ let alg_name = "gcm(aes)";
31814 -+ // 256-bits secret key
31815 -+ let key = vec![0u8; 32];
31816 -+ // 12-bytes IV
31817 -+ let iv_len = 12;
31818 -+ let iv = vec![1u8; iv_len];
31819 -+ // 256-bytes plain payload
31820 -+ let payload_len = 256;
31821 -+ let mut payload = vec![2u8; payload_len + (assoc_size as usize) + auth_size];
31822 -+
31823 -+ for i in 0..assoc_size {
31824 -+ payload[i as usize] = 10;
31825 -+ }
31826 -+
31827 -+ let len = payload.len();
31828 -+
31829 -+ for i in 0..auth_size {
31830 -+ payload[len - 1 - i] = 0;
31831 -+ }
31832 -+
31833 -+ let sock = socket(AddressFamily::Alg, SockType::SeqPacket, SockFlag::empty(), None)
31834 -+ .expect("socket failed");
31835 -+
31836 -+ let sockaddr = SockAddr::new_alg(alg_type, alg_name);
31837 -+ bind(sock, &sockaddr).expect("bind failed");
31838 -+
31839 -+ setsockopt(sock, AlgSetAeadAuthSize, &auth_size).expect("setsockopt AlgSetAeadAuthSize");
31840 -+ setsockopt(sock, AlgSetKey::default(), &key).expect("setsockopt AlgSetKey");
31841 -+ let session_socket = accept(sock).expect("accept failed");
31842 -+
31843 -+ let msgs = [
31844 -+ ControlMessage::AlgSetOp(&ALG_OP_ENCRYPT),
31845 -+ ControlMessage::AlgSetIv(iv.as_slice()),
31846 -+ ControlMessage::AlgSetAeadAssoclen(&assoc_size)];
31847 -+ let iov = IoVec::from_slice(&payload);
31848 -+ sendmsg(session_socket, &[iov], &msgs, MsgFlags::empty(), None).expect("sendmsg encrypt");
31849 -+
31850 -+ // allocate buffer for encrypted data
31851 -+ let mut encrypted = vec![0u8; (assoc_size as usize) + payload_len + auth_size];
31852 -+ let num_bytes = read(session_socket, &mut encrypted).expect("read encrypt");
31853 -+ assert_eq!(num_bytes, payload_len + auth_size + (assoc_size as usize));
31854 -+ close(session_socket).expect("close");
31855 -+
31856 -+ for i in 0..assoc_size {
31857 -+ encrypted[i as usize] = 10;
31858 -+ }
31859 -+
31860 -+ let iov = IoVec::from_slice(&encrypted);
31861 -+
31862 -+ let iv = vec![1u8; iv_len];
31863 -+
31864 -+ let session_socket = accept(sock).expect("accept failed");
31865 -+
31866 -+ let msgs = [
31867 -+ ControlMessage::AlgSetOp(&ALG_OP_DECRYPT),
31868 -+ ControlMessage::AlgSetIv(iv.as_slice()),
31869 -+ ControlMessage::AlgSetAeadAssoclen(&assoc_size),
31870 -+ ];
31871 -+ sendmsg(session_socket, &[iov], &msgs, MsgFlags::empty(), None).expect("sendmsg decrypt");
31872 -+
31873 -+ // allocate buffer for decrypted data
31874 -+ let mut decrypted = vec![0u8; payload_len + (assoc_size as usize) + auth_size];
31875 -+ let num_bytes = read(session_socket, &mut decrypted).expect("read decrypt");
31876 -+
31877 -+ assert!(num_bytes >= payload_len + (assoc_size as usize));
31878 -+ assert_eq!(decrypted[(assoc_size as usize)..(payload_len + (assoc_size as usize))], payload[(assoc_size as usize)..payload_len + (assoc_size as usize)]);
31879 -+}
31880 -+
31881 -+/// Tests that passing multiple fds using a single `ControlMessage` works.
31882 -+// Disable the test on emulated platforms due to a bug in QEMU versions <
31883 -+// 2.12.0. https://bugs.launchpad.net/qemu/+bug/1701808
31884 -+#[cfg_attr(not(any(target_arch = "x86_64", target_arch="i686")), ignore)]
31885 -+#[test]
31886 -+fn test_scm_rights_single_cmsg_multiple_fds() {
31887 -+ use std::os::unix::net::UnixDatagram;
31888 -+ use std::os::unix::io::{RawFd, AsRawFd};
31889 -+ use std::thread;
31890 -+ use nix::sys::socket::{ControlMessage, ControlMessageOwned, MsgFlags,
31891 -+ sendmsg, recvmsg};
31892 -+ use nix::sys::uio::IoVec;
31893 -+ use libc;
31894 -+
31895 -+ let (send, receive) = UnixDatagram::pair().unwrap();
31896 -+ let thread = thread::spawn(move || {
31897 -+ let mut buf = [0u8; 8];
31898 -+ let iovec = [IoVec::from_mut_slice(&mut buf)];
31899 -+ let mut space = cmsg_space!([RawFd; 2]);
31900 -+ let msg = recvmsg(
31901 -+ receive.as_raw_fd(),
31902 -+ &iovec,
31903 -+ Some(&mut space),
31904 -+ MsgFlags::empty()
31905 -+ ).unwrap();
31906 -+ assert!(!msg.flags.intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
31907 -+
31908 -+ let mut cmsgs = msg.cmsgs();
31909 -+ match cmsgs.next() {
31910 -+ Some(ControlMessageOwned::ScmRights(fds)) => {
31911 -+ assert_eq!(fds.len(), 2,
31912 -+ "unexpected fd count (expected 2 fds, got {})",
31913 -+ fds.len());
31914 -+ },
31915 -+ _ => panic!(),
31916 -+ }
31917 -+ assert!(cmsgs.next().is_none(), "unexpected control msg");
31918 -+
31919 -+ assert_eq!(msg.bytes, 8);
31920 -+ assert_eq!(iovec[0].as_slice(), [1u8, 2, 3, 4, 5, 6, 7, 8]);
31921 -+ });
31922 -+
31923 -+ let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
31924 -+ let iov = [IoVec::from_slice(&slice)];
31925 -+ let fds = [libc::STDIN_FILENO, libc::STDOUT_FILENO]; // pass stdin and stdout
31926 -+ let cmsg = [ControlMessage::ScmRights(&fds)];
31927 -+ sendmsg(send.as_raw_fd(), &iov, &cmsg, MsgFlags::empty(), None).unwrap();
31928 -+ thread.join().unwrap();
31929 -+}
31930 -+
31931 -+// Verify `sendmsg` builds a valid `msghdr` when passing an empty
31932 -+// `cmsgs` argument. This should result in a msghdr with a nullptr
31933 -+// msg_control field and a msg_controllen of 0 when calling into the
31934 -+// raw `sendmsg`.
31935 -+#[test]
31936 -+pub fn test_sendmsg_empty_cmsgs() {
31937 -+ use nix::sys::uio::IoVec;
31938 -+ use nix::unistd::close;
31939 -+ use nix::sys::socket::{socketpair, sendmsg, recvmsg,
31940 -+ AddressFamily, SockType, SockFlag, MsgFlags};
31941 -+
31942 -+ let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
31943 -+ .unwrap();
31944 -+
31945 -+ {
31946 -+ let iov = [IoVec::from_slice(b"hello")];
31947 -+ assert_eq!(sendmsg(fd1, &iov, &[], MsgFlags::empty(), None).unwrap(), 5);
31948 -+ close(fd1).unwrap();
31949 -+ }
31950 -+
31951 -+ {
31952 -+ let mut buf = [0u8; 5];
31953 -+ let iov = [IoVec::from_mut_slice(&mut buf[..])];
31954 -+ let mut cmsgspace = cmsg_space!([RawFd; 1]);
31955 -+ let msg = recvmsg(fd2, &iov, Some(&mut cmsgspace), MsgFlags::empty()).unwrap();
31956 -+
31957 -+ for _ in msg.cmsgs() {
31958 -+ panic!("unexpected cmsg");
31959 -+ }
31960 -+ assert!(!msg.flags.intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
31961 -+ assert_eq!(msg.bytes, 5);
31962 -+ close(fd2).unwrap();
31963 -+ }
31964 -+}
31965 -+
31966 -+#[cfg(any(target_os = "android", target_os = "linux"))]
31967 -+#[test]
31968 -+fn test_scm_credentials() {
31969 -+ use libc;
31970 -+ use nix::sys::uio::IoVec;
31971 -+ use nix::unistd::{close, getpid, getuid, getgid};
31972 -+ use nix::sys::socket::{socketpair, sendmsg, recvmsg, setsockopt,
31973 -+ AddressFamily, SockType, SockFlag,
31974 -+ ControlMessage, ControlMessageOwned, MsgFlags};
31975 -+ use nix::sys::socket::sockopt::PassCred;
31976 -+
31977 -+ let (send, recv) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
31978 -+ .unwrap();
31979 -+ setsockopt(recv, PassCred, &true).unwrap();
31980 -+
31981 -+ {
31982 -+ let iov = [IoVec::from_slice(b"hello")];
31983 -+ let cred = libc::ucred {
31984 -+ pid: getpid().as_raw(),
31985 -+ uid: getuid().as_raw(),
31986 -+ gid: getgid().as_raw(),
31987 -+ };
31988 -+ let cmsg = ControlMessage::ScmCredentials(&cred);
31989 -+ assert_eq!(sendmsg(send, &iov, &[cmsg], MsgFlags::empty(), None).unwrap(), 5);
31990 -+ close(send).unwrap();
31991 -+ }
31992 -+
31993 -+ {
31994 -+ let mut buf = [0u8; 5];
31995 -+ let iov = [IoVec::from_mut_slice(&mut buf[..])];
31996 -+ let mut cmsgspace = cmsg_space!(libc::ucred);
31997 -+ let msg = recvmsg(recv, &iov, Some(&mut cmsgspace), MsgFlags::empty()).unwrap();
31998 -+ let mut received_cred = None;
31999 -+
32000 -+ for cmsg in msg.cmsgs() {
32001 -+ if let ControlMessageOwned::ScmCredentials(cred) = cmsg {
32002 -+ assert!(received_cred.is_none());
32003 -+ assert_eq!(cred.pid, getpid().as_raw());
32004 -+ assert_eq!(cred.uid, getuid().as_raw());
32005 -+ assert_eq!(cred.gid, getgid().as_raw());
32006 -+ received_cred = Some(cred);
32007 -+ } else {
32008 -+ panic!("unexpected cmsg");
32009 -+ }
32010 -+ }
32011 -+ received_cred.expect("no creds received");
32012 -+ assert_eq!(msg.bytes, 5);
32013 -+ assert!(!msg.flags.intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
32014 -+ close(recv).unwrap();
32015 -+ }
32016 -+}
32017 -+
32018 -+/// Ensure that we can send `SCM_CREDENTIALS` and `SCM_RIGHTS` with a single
32019 -+/// `sendmsg` call.
32020 -+#[cfg(any(target_os = "android", target_os = "linux"))]
32021 -+// qemu's handling of multiple cmsgs is bugged, ignore tests on non-x86
32022 -+// see https://bugs.launchpad.net/qemu/+bug/1781280
32023 -+#[cfg_attr(not(any(target_arch = "x86_64", target_arch = "x86")), ignore)]
32024 -+#[test]
32025 -+fn test_scm_credentials_and_rights() {
32026 -+ use libc;
32027 -+
32028 -+ let space = cmsg_space!(libc::ucred, RawFd);
32029 -+ test_impl_scm_credentials_and_rights(space);
32030 -+}
32031 -+
32032 -+/// Ensure that passing a an oversized control message buffer to recvmsg
32033 -+/// still works.
32034 -+#[cfg(any(target_os = "android", target_os = "linux"))]
32035 -+// qemu's handling of multiple cmsgs is bugged, ignore tests on non-x86
32036 -+// see https://bugs.launchpad.net/qemu/+bug/1781280
32037 -+#[cfg_attr(not(any(target_arch = "x86_64", target_arch = "x86")), ignore)]
32038 -+#[test]
32039 -+fn test_too_large_cmsgspace() {
32040 -+ let space = vec![0u8; 1024];
32041 -+ test_impl_scm_credentials_and_rights(space);
32042 -+}
32043 -+
32044 -+#[cfg(any(target_os = "android", target_os = "linux"))]
32045 -+fn test_impl_scm_credentials_and_rights(mut space: Vec<u8>) {
32046 -+ use libc::ucred;
32047 -+ use nix::sys::uio::IoVec;
32048 -+ use nix::unistd::{pipe, read, write, close, getpid, getuid, getgid};
32049 -+ use nix::sys::socket::{socketpair, sendmsg, recvmsg, setsockopt,
32050 -+ SockType, SockFlag,
32051 -+ ControlMessage, ControlMessageOwned, MsgFlags};
32052 -+ use nix::sys::socket::sockopt::PassCred;
32053 -+
32054 -+ let (send, recv) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
32055 -+ .unwrap();
32056 -+ setsockopt(recv, PassCred, &true).unwrap();
32057 -+
32058 -+ let (r, w) = pipe().unwrap();
32059 -+ let mut received_r: Option<RawFd> = None;
32060 -+
32061 -+ {
32062 -+ let iov = [IoVec::from_slice(b"hello")];
32063 -+ let cred = ucred {
32064 -+ pid: getpid().as_raw(),
32065 -+ uid: getuid().as_raw(),
32066 -+ gid: getgid().as_raw(),
32067 -+ };
32068 -+ let fds = [r];
32069 -+ let cmsgs = [
32070 -+ ControlMessage::ScmCredentials(&cred),
32071 -+ ControlMessage::ScmRights(&fds),
32072 -+ ];
32073 -+ assert_eq!(sendmsg(send, &iov, &cmsgs, MsgFlags::empty(), None).unwrap(), 5);
32074 -+ close(r).unwrap();
32075 -+ close(send).unwrap();
32076 -+ }
32077 -+
32078 -+ {
32079 -+ let mut buf = [0u8; 5];
32080 -+ let iov = [IoVec::from_mut_slice(&mut buf[..])];
32081 -+ let msg = recvmsg(recv, &iov, Some(&mut space), MsgFlags::empty()).unwrap();
32082 -+ let mut received_cred = None;
32083 -+
32084 -+ assert_eq!(msg.cmsgs().count(), 2, "expected 2 cmsgs");
32085 -+
32086 -+ for cmsg in msg.cmsgs() {
32087 -+ match cmsg {
32088 -+ ControlMessageOwned::ScmRights(fds) => {
32089 -+ assert_eq!(received_r, None, "already received fd");
32090 -+ assert_eq!(fds.len(), 1);
32091 -+ received_r = Some(fds[0]);
32092 -+ }
32093 -+ ControlMessageOwned::ScmCredentials(cred) => {
32094 -+ assert!(received_cred.is_none());
32095 -+ assert_eq!(cred.pid, getpid().as_raw());
32096 -+ assert_eq!(cred.uid, getuid().as_raw());
32097 -+ assert_eq!(cred.gid, getgid().as_raw());
32098 -+ received_cred = Some(cred);
32099 -+ }
32100 -+ _ => panic!("unexpected cmsg"),
32101 -+ }
32102 -+ }
32103 -+ received_cred.expect("no creds received");
32104 -+ assert_eq!(msg.bytes, 5);
32105 -+ assert!(!msg.flags.intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
32106 -+ close(recv).unwrap();
32107 -+ }
32108 -+
32109 -+ let received_r = received_r.expect("Did not receive passed fd");
32110 -+ // Ensure that the received file descriptor works
32111 -+ write(w, b"world").unwrap();
32112 -+ let mut buf = [0u8; 5];
32113 -+ read(received_r, &mut buf).unwrap();
32114 -+ assert_eq!(&buf[..], b"world");
32115 -+ close(received_r).unwrap();
32116 -+ close(w).unwrap();
32117 -+}
32118 -+
32119 -+// Test creating and using named unix domain sockets
32120 -+#[test]
32121 -+pub fn test_unixdomain() {
32122 -+ use nix::sys::socket::{SockType, SockFlag};
32123 -+ use nix::sys::socket::{bind, socket, connect, listen, accept, SockAddr};
32124 -+ use nix::unistd::{read, write, close};
32125 -+ use std::thread;
32126 -+
32127 -+ let tempdir = tempfile::tempdir().unwrap();
32128 -+ let sockname = tempdir.path().join("sock");
32129 -+ let s1 = socket(AddressFamily::Unix, SockType::Stream,
32130 -+ SockFlag::empty(), None).expect("socket failed");
32131 -+ let sockaddr = SockAddr::new_unix(&sockname).unwrap();
32132 -+ bind(s1, &sockaddr).expect("bind failed");
32133 -+ listen(s1, 10).expect("listen failed");
32134 -+
32135 -+ let thr = thread::spawn(move || {
32136 -+ let s2 = socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(), None)
32137 -+ .expect("socket failed");
32138 -+ connect(s2, &sockaddr).expect("connect failed");
32139 -+ write(s2, b"hello").expect("write failed");
32140 -+ close(s2).unwrap();
32141 -+ });
32142 -+
32143 -+ let s3 = accept(s1).expect("accept failed");
32144 -+
32145 -+ let mut buf = [0;5];
32146 -+ read(s3, &mut buf).unwrap();
32147 -+ close(s3).unwrap();
32148 -+ close(s1).unwrap();
32149 -+ thr.join().unwrap();
32150 -+
32151 -+ assert_eq!(&buf[..], b"hello");
32152 -+}
32153 -+
32154 -+// Test creating and using named system control sockets
32155 -+#[cfg(any(target_os = "macos", target_os = "ios"))]
32156 -+#[test]
32157 -+pub fn test_syscontrol() {
32158 -+ use nix::Error;
32159 -+ use nix::errno::Errno;
32160 -+ use nix::sys::socket::{socket, SockAddr, SockType, SockFlag, SockProtocol};
32161 -+
32162 -+ let fd = socket(AddressFamily::System, SockType::Datagram,
32163 -+ SockFlag::empty(), SockProtocol::KextControl)
32164 -+ .expect("socket failed");
32165 -+ let _sockaddr = SockAddr::new_sys_control(fd, "com.apple.net.utun_control", 0).expect("resolving sys_control name failed");
32166 -+ assert_eq!(SockAddr::new_sys_control(fd, "foo.bar.lol", 0).err(), Some(Error::Sys(Errno::ENOENT)));
32167 -+
32168 -+ // requires root privileges
32169 -+ // connect(fd, &sockaddr).expect("connect failed");
32170 -+}
32171 -+
32172 -+#[cfg(any(
32173 -+ target_os = "android",
32174 -+ target_os = "freebsd",
32175 -+ target_os = "ios",
32176 -+ target_os = "linux",
32177 -+ target_os = "macos",
32178 -+ target_os = "netbsd",
32179 -+ target_os = "openbsd",
32180 -+))]
32181 -+fn loopback_address(family: AddressFamily) -> Option<InterfaceAddress> {
32182 -+ use std::io;
32183 -+ use std::io::Write;
32184 -+ use nix::ifaddrs::getifaddrs;
32185 -+ use nix::sys::socket::SockAddr;
32186 -+ use nix::net::if_::*;
32187 -+
32188 -+ let addrs = match getifaddrs() {
32189 -+ Ok(iter) => iter,
32190 -+ Err(e) => {
32191 -+ let stdioerr = io::stderr();
32192 -+ let mut handle = stdioerr.lock();
32193 -+ writeln!(handle, "getifaddrs: {:?}", e).unwrap();
32194 -+ return None;
32195 -+ },
32196 -+ };
32197 -+ // return first address matching family
32198 -+ for ifaddr in addrs {
32199 -+ if ifaddr.flags.contains(InterfaceFlags::IFF_LOOPBACK) {
32200 -+ match ifaddr.address {
32201 -+ Some(SockAddr::Inet(InetAddr::V4(..))) => {
32202 -+ match family {
32203 -+ AddressFamily::Inet => return Some(ifaddr),
32204 -+ _ => continue
32205 -+ }
32206 -+ },
32207 -+ Some(SockAddr::Inet(InetAddr::V6(..))) => {
32208 -+ match family {
32209 -+ AddressFamily::Inet6 => return Some(ifaddr),
32210 -+ _ => continue
32211 -+ }
32212 -+ },
32213 -+ _ => continue,
32214 -+ }
32215 -+ }
32216 -+ }
32217 -+ None
32218 -+}
32219 -+
32220 -+#[cfg(any(
32221 -+ target_os = "android",
32222 -+ target_os = "ios",
32223 -+ target_os = "linux",
32224 -+ target_os = "macos",
32225 -+ target_os = "netbsd",
32226 -+))]
32227 -+// qemu doesn't seem to be emulating this correctly in these architectures
32228 -+#[cfg_attr(any(
32229 -+ target_arch = "mips",
32230 -+ target_arch = "mips64",
32231 -+ target_arch = "powerpc64",
32232 -+), ignore)]
32233 -+#[test]
32234 -+pub fn test_recv_ipv4pktinfo() {
32235 -+ use libc;
32236 -+ use nix::sys::socket::sockopt::Ipv4PacketInfo;
32237 -+ use nix::sys::socket::{bind, SockFlag, SockType};
32238 -+ use nix::sys::socket::{getsockname, setsockopt, socket};
32239 -+ use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags};
32240 -+ use nix::sys::uio::IoVec;
32241 -+ use nix::net::if_::*;
32242 -+
32243 -+ let lo_ifaddr = loopback_address(AddressFamily::Inet);
32244 -+ let (lo_name, lo) = match lo_ifaddr {
32245 -+ Some(ifaddr) => (ifaddr.interface_name,
32246 -+ ifaddr.address.expect("Expect IPv4 address on interface")),
32247 -+ None => return,
32248 -+ };
32249 -+ let receive = socket(
32250 -+ AddressFamily::Inet,
32251 -+ SockType::Datagram,
32252 -+ SockFlag::empty(),
32253 -+ None,
32254 -+ ).expect("receive socket failed");
32255 -+ bind(receive, &lo).expect("bind failed");
32256 -+ let sa = getsockname(receive).expect("getsockname failed");
32257 -+ setsockopt(receive, Ipv4PacketInfo, &true).expect("setsockopt failed");
32258 -+
32259 -+ {
32260 -+ let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
32261 -+ let iov = [IoVec::from_slice(&slice)];
32262 -+
32263 -+ let send = socket(
32264 -+ AddressFamily::Inet,
32265 -+ SockType::Datagram,
32266 -+ SockFlag::empty(),
32267 -+ None,
32268 -+ ).expect("send socket failed");
32269 -+ sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa)).expect("sendmsg failed");
32270 -+ }
32271 -+
32272 -+ {
32273 -+ let mut buf = [0u8; 8];
32274 -+ let iovec = [IoVec::from_mut_slice(&mut buf)];
32275 -+ let mut space = cmsg_space!(libc::in_pktinfo);
32276 -+ let msg = recvmsg(
32277 -+ receive,
32278 -+ &iovec,
32279 -+ Some(&mut space),
32280 -+ MsgFlags::empty(),
32281 -+ ).expect("recvmsg failed");
32282 -+ assert!(
32283 -+ !msg.flags
32284 -+ .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)
32285 -+ );
32286 -+
32287 -+ let mut cmsgs = msg.cmsgs();
32288 -+ match cmsgs.next() {
32289 -+ Some(ControlMessageOwned::Ipv4PacketInfo(pktinfo)) => {
32290 -+ let i = if_nametoindex(lo_name.as_bytes()).expect("if_nametoindex");
32291 -+ assert_eq!(
32292 -+ pktinfo.ipi_ifindex as libc::c_uint,
32293 -+ i,
32294 -+ "unexpected ifindex (expected {}, got {})",
32295 -+ i,
32296 -+ pktinfo.ipi_ifindex
32297 -+ );
32298 -+ }
32299 -+ _ => (),
32300 -+ }
32301 -+ assert!(cmsgs.next().is_none(), "unexpected additional control msg");
32302 -+ assert_eq!(msg.bytes, 8);
32303 -+ assert_eq!(
32304 -+ iovec[0].as_slice(),
32305 -+ [1u8, 2, 3, 4, 5, 6, 7, 8]
32306 -+ );
32307 -+ }
32308 -+}
32309 -+
32310 -+#[cfg(any(
32311 -+ target_os = "freebsd",
32312 -+ target_os = "ios",
32313 -+ target_os = "macos",
32314 -+ target_os = "netbsd",
32315 -+ target_os = "openbsd",
32316 -+))]
32317 -+// qemu doesn't seem to be emulating this correctly in these architectures
32318 -+#[cfg_attr(any(
32319 -+ target_arch = "mips",
32320 -+ target_arch = "mips64",
32321 -+ target_arch = "powerpc64",
32322 -+), ignore)]
32323 -+#[test]
32324 -+pub fn test_recvif() {
32325 -+ use libc;
32326 -+ use nix::net::if_::*;
32327 -+ use nix::sys::socket::sockopt::{Ipv4RecvIf, Ipv4RecvDstAddr};
32328 -+ use nix::sys::socket::{bind, SockFlag, SockType};
32329 -+ use nix::sys::socket::{getsockname, setsockopt, socket, SockAddr};
32330 -+ use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags};
32331 -+ use nix::sys::uio::IoVec;
32332 -+
32333 -+ let lo_ifaddr = loopback_address(AddressFamily::Inet);
32334 -+ let (lo_name, lo) = match lo_ifaddr {
32335 -+ Some(ifaddr) => (ifaddr.interface_name,
32336 -+ ifaddr.address.expect("Expect IPv4 address on interface")),
32337 -+ None => return,
32338 -+ };
32339 -+ let receive = socket(
32340 -+ AddressFamily::Inet,
32341 -+ SockType::Datagram,
32342 -+ SockFlag::empty(),
32343 -+ None,
32344 -+ ).expect("receive socket failed");
32345 -+ bind(receive, &lo).expect("bind failed");
32346 -+ let sa = getsockname(receive).expect("getsockname failed");
32347 -+ setsockopt(receive, Ipv4RecvIf, &true).expect("setsockopt IP_RECVIF failed");
32348 -+ setsockopt(receive, Ipv4RecvDstAddr, &true).expect("setsockopt IP_RECVDSTADDR failed");
32349 -+
32350 -+ {
32351 -+ let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
32352 -+ let iov = [IoVec::from_slice(&slice)];
32353 -+
32354 -+ let send = socket(
32355 -+ AddressFamily::Inet,
32356 -+ SockType::Datagram,
32357 -+ SockFlag::empty(),
32358 -+ None,
32359 -+ ).expect("send socket failed");
32360 -+ sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa)).expect("sendmsg failed");
32361 -+ }
32362 -+
32363 -+ {
32364 -+ let mut buf = [0u8; 8];
32365 -+ let iovec = [IoVec::from_mut_slice(&mut buf)];
32366 -+ let mut space = cmsg_space!(libc::sockaddr_dl, libc::in_addr);
32367 -+ let msg = recvmsg(
32368 -+ receive,
32369 -+ &iovec,
32370 -+ Some(&mut space),
32371 -+ MsgFlags::empty(),
32372 -+ ).expect("recvmsg failed");
32373 -+ assert!(
32374 -+ !msg.flags
32375 -+ .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)
32376 -+ );
32377 -+ assert_eq!(msg.cmsgs().count(), 2, "expected 2 cmsgs");
32378 -+
32379 -+ let mut rx_recvif = false;
32380 -+ let mut rx_recvdstaddr = false;
32381 -+ for cmsg in msg.cmsgs() {
32382 -+ match cmsg {
32383 -+ ControlMessageOwned::Ipv4RecvIf(dl) => {
32384 -+ rx_recvif = true;
32385 -+ let i = if_nametoindex(lo_name.as_bytes()).expect("if_nametoindex");
32386 -+ assert_eq!(
32387 -+ dl.sdl_index as libc::c_uint,
32388 -+ i,
32389 -+ "unexpected ifindex (expected {}, got {})",
32390 -+ i,
32391 -+ dl.sdl_index
32392 -+ );
32393 -+ },
32394 -+ ControlMessageOwned::Ipv4RecvDstAddr(addr) => {
32395 -+ rx_recvdstaddr = true;
32396 -+ if let SockAddr::Inet(InetAddr::V4(a)) = lo {
32397 -+ assert_eq!(a.sin_addr.s_addr,
32398 -+ addr.s_addr,
32399 -+ "unexpected destination address (expected {}, got {})",
32400 -+ a.sin_addr.s_addr,
32401 -+ addr.s_addr);
32402 -+ } else {
32403 -+ panic!("unexpected Sockaddr");
32404 -+ }
32405 -+ },
32406 -+ _ => panic!("unexpected additional control msg"),
32407 -+ }
32408 -+ }
32409 -+ assert_eq!(rx_recvif, true);
32410 -+ assert_eq!(rx_recvdstaddr, true);
32411 -+ assert_eq!(msg.bytes, 8);
32412 -+ assert_eq!(
32413 -+ iovec[0].as_slice(),
32414 -+ [1u8, 2, 3, 4, 5, 6, 7, 8]
32415 -+ );
32416 -+ }
32417 -+}
32418 -+
32419 -+#[cfg(any(
32420 -+ target_os = "android",
32421 -+ target_os = "freebsd",
32422 -+ target_os = "ios",
32423 -+ target_os = "linux",
32424 -+ target_os = "macos",
32425 -+ target_os = "netbsd",
32426 -+ target_os = "openbsd",
32427 -+))]
32428 -+// qemu doesn't seem to be emulating this correctly in these architectures
32429 -+#[cfg_attr(any(
32430 -+ target_arch = "mips",
32431 -+ target_arch = "mips64",
32432 -+ target_arch = "powerpc64",
32433 -+), ignore)]
32434 -+#[test]
32435 -+pub fn test_recv_ipv6pktinfo() {
32436 -+ use libc;
32437 -+ use nix::net::if_::*;
32438 -+ use nix::sys::socket::sockopt::Ipv6RecvPacketInfo;
32439 -+ use nix::sys::socket::{bind, SockFlag, SockType};
32440 -+ use nix::sys::socket::{getsockname, setsockopt, socket};
32441 -+ use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags};
32442 -+ use nix::sys::uio::IoVec;
32443 -+
32444 -+ let lo_ifaddr = loopback_address(AddressFamily::Inet6);
32445 -+ let (lo_name, lo) = match lo_ifaddr {
32446 -+ Some(ifaddr) => (ifaddr.interface_name,
32447 -+ ifaddr.address.expect("Expect IPv4 address on interface")),
32448 -+ None => return,
32449 -+ };
32450 -+ let receive = socket(
32451 -+ AddressFamily::Inet6,
32452 -+ SockType::Datagram,
32453 -+ SockFlag::empty(),
32454 -+ None,
32455 -+ ).expect("receive socket failed");
32456 -+ bind(receive, &lo).expect("bind failed");
32457 -+ let sa = getsockname(receive).expect("getsockname failed");
32458 -+ setsockopt(receive, Ipv6RecvPacketInfo, &true).expect("setsockopt failed");
32459 -+
32460 -+ {
32461 -+ let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
32462 -+ let iov = [IoVec::from_slice(&slice)];
32463 -+
32464 -+ let send = socket(
32465 -+ AddressFamily::Inet6,
32466 -+ SockType::Datagram,
32467 -+ SockFlag::empty(),
32468 -+ None,
32469 -+ ).expect("send socket failed");
32470 -+ sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa)).expect("sendmsg failed");
32471 -+ }
32472 -+
32473 -+ {
32474 -+ let mut buf = [0u8; 8];
32475 -+ let iovec = [IoVec::from_mut_slice(&mut buf)];
32476 -+ let mut space = cmsg_space!(libc::in6_pktinfo);
32477 -+ let msg = recvmsg(
32478 -+ receive,
32479 -+ &iovec,
32480 -+ Some(&mut space),
32481 -+ MsgFlags::empty(),
32482 -+ ).expect("recvmsg failed");
32483 -+ assert!(
32484 -+ !msg.flags
32485 -+ .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)
32486 -+ );
32487 -+
32488 -+ let mut cmsgs = msg.cmsgs();
32489 -+ match cmsgs.next() {
32490 -+ Some(ControlMessageOwned::Ipv6PacketInfo(pktinfo)) => {
32491 -+ let i = if_nametoindex(lo_name.as_bytes()).expect("if_nametoindex");
32492 -+ assert_eq!(
32493 -+ pktinfo.ipi6_ifindex,
32494 -+ i,
32495 -+ "unexpected ifindex (expected {}, got {})",
32496 -+ i,
32497 -+ pktinfo.ipi6_ifindex
32498 -+ );
32499 -+ }
32500 -+ _ => (),
32501 -+ }
32502 -+ assert!(cmsgs.next().is_none(), "unexpected additional control msg");
32503 -+ assert_eq!(msg.bytes, 8);
32504 -+ assert_eq!(
32505 -+ iovec[0].as_slice(),
32506 -+ [1u8, 2, 3, 4, 5, 6, 7, 8]
32507 -+ );
32508 -+ }
32509 -+}
32510 -+
32511 -+#[cfg(target_os = "linux")]
32512 -+#[test]
32513 -+pub fn test_vsock() {
32514 -+ use libc;
32515 -+ use nix::Error;
32516 -+ use nix::errno::Errno;
32517 -+ use nix::sys::socket::{AddressFamily, socket, bind, connect, listen,
32518 -+ SockAddr, SockType, SockFlag};
32519 -+ use nix::unistd::{close};
32520 -+ use std::thread;
32521 -+
32522 -+ let port: u32 = 3000;
32523 -+
32524 -+ let s1 = socket(AddressFamily::Vsock, SockType::Stream,
32525 -+ SockFlag::empty(), None)
32526 -+ .expect("socket failed");
32527 -+
32528 -+ // VMADDR_CID_HYPERVISOR and VMADDR_CID_RESERVED are reserved, so we expect
32529 -+ // an EADDRNOTAVAIL error.
32530 -+ let sockaddr = SockAddr::new_vsock(libc::VMADDR_CID_HYPERVISOR, port);
32531 -+ assert_eq!(bind(s1, &sockaddr).err(),
32532 -+ Some(Error::Sys(Errno::EADDRNOTAVAIL)));
32533 -+
32534 -+ let sockaddr = SockAddr::new_vsock(libc::VMADDR_CID_RESERVED, port);
32535 -+ assert_eq!(bind(s1, &sockaddr).err(),
32536 -+ Some(Error::Sys(Errno::EADDRNOTAVAIL)));
32537 -+
32538 -+
32539 -+ let sockaddr = SockAddr::new_vsock(libc::VMADDR_CID_ANY, port);
32540 -+ assert_eq!(bind(s1, &sockaddr), Ok(()));
32541 -+ listen(s1, 10).expect("listen failed");
32542 -+
32543 -+ let thr = thread::spawn(move || {
32544 -+ let cid: u32 = libc::VMADDR_CID_HOST;
32545 -+
32546 -+ let s2 = socket(AddressFamily::Vsock, SockType::Stream,
32547 -+ SockFlag::empty(), None)
32548 -+ .expect("socket failed");
32549 -+
32550 -+ let sockaddr = SockAddr::new_vsock(cid, port);
32551 -+
32552 -+ // The current implementation does not support loopback devices, so,
32553 -+ // for now, we expect a failure on the connect.
32554 -+ assert_ne!(connect(s2, &sockaddr), Ok(()));
32555 -+
32556 -+ close(s2).unwrap();
32557 -+ });
32558 -+
32559 -+ close(s1).unwrap();
32560 -+ thr.join().unwrap();
32561 -+}
32562 -diff --git a/third_party/rust/nix-0.15.0/test/sys/test_sockopt.rs b/third_party/rust/nix-0.15.0/test/sys/test_sockopt.rs
32563 -new file mode 100644
32564 -index 0000000000000..c4860c0d61d3d
32565 ---- /dev/null
32566 -+++ b/third_party/rust/nix-0.15.0/test/sys/test_sockopt.rs
32567 -@@ -0,0 +1,53 @@
32568 -+use rand::{thread_rng, Rng};
32569 -+use nix::sys::socket::{socket, sockopt, getsockopt, setsockopt, AddressFamily, SockType, SockFlag, SockProtocol};
32570 -+
32571 -+#[cfg(target_os = "linux")]
32572 -+#[test]
32573 -+fn is_so_mark_functional() {
32574 -+ use nix::sys::socket::sockopt;
32575 -+
32576 -+ require_capability!(CAP_NET_ADMIN);
32577 -+
32578 -+ let s = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), None).unwrap();
32579 -+ setsockopt(s, sockopt::Mark, &1337).unwrap();
32580 -+ let mark = getsockopt(s, sockopt::Mark).unwrap();
32581 -+ assert_eq!(mark, 1337);
32582 -+}
32583 -+
32584 -+#[test]
32585 -+fn test_so_buf() {
32586 -+ let fd = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), SockProtocol::Udp)
32587 -+ .unwrap();
32588 -+ let bufsize: usize = thread_rng().gen_range(4096, 131_072);
32589 -+ setsockopt(fd, sockopt::SndBuf, &bufsize).unwrap();
32590 -+ let actual = getsockopt(fd, sockopt::SndBuf).unwrap();
32591 -+ assert!(actual >= bufsize);
32592 -+ setsockopt(fd, sockopt::RcvBuf, &bufsize).unwrap();
32593 -+ let actual = getsockopt(fd, sockopt::RcvBuf).unwrap();
32594 -+ assert!(actual >= bufsize);
32595 -+}
32596 -+
32597 -+// The CI doesn't supported getsockopt and setsockopt on emulated processors.
32598 -+// It's beleived that a QEMU issue, the tests run ok on a fully emulated system.
32599 -+// Current CI just run the binary with QEMU but the Kernel remains the same as the host.
32600 -+// So the syscall doesn't work properly unless the kernel is also emulated.
32601 -+#[test]
32602 -+#[cfg(all(
32603 -+ any(target_arch = "x86", target_arch = "x86_64"),
32604 -+ any(target_os = "freebsd", target_os = "linux")
32605 -+))]
32606 -+fn test_tcp_congestion() {
32607 -+ use std::ffi::OsString;
32608 -+
32609 -+ let fd = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), None).unwrap();
32610 -+
32611 -+ let val = getsockopt(fd, sockopt::TcpCongestion).unwrap();
32612 -+ setsockopt(fd, sockopt::TcpCongestion, &val).unwrap();
32613 -+
32614 -+ setsockopt(fd, sockopt::TcpCongestion, &OsString::from("tcp_congestion_does_not_exist")).unwrap_err();
32615 -+
32616 -+ assert_eq!(
32617 -+ getsockopt(fd, sockopt::TcpCongestion).unwrap(),
32618 -+ val
32619 -+ );
32620 -+}
32621 -diff --git a/third_party/rust/nix-0.15.0/test/sys/test_sysinfo.rs b/third_party/rust/nix-0.15.0/test/sys/test_sysinfo.rs
32622 -new file mode 100644
32623 -index 0000000000000..73e6586f6223e
32624 ---- /dev/null
32625 -+++ b/third_party/rust/nix-0.15.0/test/sys/test_sysinfo.rs
32626 -@@ -0,0 +1,18 @@
32627 -+use nix::sys::sysinfo::*;
32628 -+
32629 -+#[test]
32630 -+fn sysinfo_works() {
32631 -+ let info = sysinfo().unwrap();
32632 -+
32633 -+ let (l1, l5, l15) = info.load_average();
32634 -+ assert!(l1 >= 0.0);
32635 -+ assert!(l5 >= 0.0);
32636 -+ assert!(l15 >= 0.0);
32637 -+
32638 -+ info.uptime(); // just test Duration construction
32639 -+
32640 -+ assert!(info.swap_free() <= info.swap_total(),
32641 -+ "more swap available than installed (free: {}, total: {})",
32642 -+ info.swap_free(),
32643 -+ info.swap_total());
32644 -+}
32645 -diff --git a/third_party/rust/nix-0.15.0/test/sys/test_termios.rs b/third_party/rust/nix-0.15.0/test/sys/test_termios.rs
32646 -new file mode 100644
32647 -index 0000000000000..a14b8ce1a23cb
32648 ---- /dev/null
32649 -+++ b/third_party/rust/nix-0.15.0/test/sys/test_termios.rs
32650 -@@ -0,0 +1,136 @@
32651 -+use std::os::unix::prelude::*;
32652 -+use tempfile::tempfile;
32653 -+
32654 -+use nix::{Error, fcntl};
32655 -+use nix::errno::Errno;
32656 -+use nix::pty::openpty;
32657 -+use nix::sys::termios::{self, LocalFlags, OutputFlags, Termios, tcgetattr};
32658 -+use nix::unistd::{read, write, close};
32659 -+
32660 -+/// Helper function analogous to `std::io::Write::write_all`, but for `RawFd`s
32661 -+fn write_all(f: RawFd, buf: &[u8]) {
32662 -+ let mut len = 0;
32663 -+ while len < buf.len() {
32664 -+ len += write(f, &buf[len..]).unwrap();
32665 -+ }
32666 -+}
32667 -+
32668 -+// Test tcgetattr on a terminal
32669 -+#[test]
32670 -+fn test_tcgetattr_pty() {
32671 -+ // openpty uses ptname(3) internally
32672 -+ let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
32673 -+
32674 -+ let pty = openpty(None, None).expect("openpty failed");
32675 -+ assert!(termios::tcgetattr(pty.master).is_ok());
32676 -+ close(pty.master).expect("closing the master failed");
32677 -+ close(pty.slave).expect("closing the slave failed");
32678 -+}
32679 -+
32680 -+// Test tcgetattr on something that isn't a terminal
32681 -+#[test]
32682 -+fn test_tcgetattr_enotty() {
32683 -+ let file = tempfile().unwrap();
32684 -+ assert_eq!(termios::tcgetattr(file.as_raw_fd()).err(),
32685 -+ Some(Error::Sys(Errno::ENOTTY)));
32686 -+}
32687 -+
32688 -+// Test tcgetattr on an invalid file descriptor
32689 -+#[test]
32690 -+fn test_tcgetattr_ebadf() {
32691 -+ assert_eq!(termios::tcgetattr(-1).err(),
32692 -+ Some(Error::Sys(Errno::EBADF)));
32693 -+}
32694 -+
32695 -+// Test modifying output flags
32696 -+#[test]
32697 -+fn test_output_flags() {
32698 -+ // openpty uses ptname(3) internally
32699 -+ let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
32700 -+
32701 -+ // Open one pty to get attributes for the second one
32702 -+ let mut termios = {
32703 -+ let pty = openpty(None, None).expect("openpty failed");
32704 -+ assert!(pty.master > 0);
32705 -+ assert!(pty.slave > 0);
32706 -+ let termios = tcgetattr(pty.master).expect("tcgetattr failed");
32707 -+ close(pty.master).unwrap();
32708 -+ close(pty.slave).unwrap();
32709 -+ termios
32710 -+ };
32711 -+
32712 -+ // Make sure postprocessing '\r' isn't specified by default or this test is useless.
32713 -+ assert!(!termios.output_flags.contains(OutputFlags::OPOST | OutputFlags::OCRNL));
32714 -+
32715 -+ // Specify that '\r' characters should be transformed to '\n'
32716 -+ // OPOST is specified to enable post-processing
32717 -+ termios.output_flags.insert(OutputFlags::OPOST | OutputFlags::OCRNL);
32718 -+
32719 -+ // Open a pty
32720 -+ let pty = openpty(None, &termios).unwrap();
32721 -+ assert!(pty.master > 0);
32722 -+ assert!(pty.slave > 0);
32723 -+
32724 -+ // Write into the master
32725 -+ let string = "foofoofoo\r";
32726 -+ write_all(pty.master, string.as_bytes());
32727 -+
32728 -+ // Read from the slave verifying that the output has been properly transformed
32729 -+ let mut buf = [0u8; 10];
32730 -+ ::read_exact(pty.slave, &mut buf);
32731 -+ let transformed_string = "foofoofoo\n";
32732 -+ close(pty.master).unwrap();
32733 -+ close(pty.slave).unwrap();
32734 -+ assert_eq!(&buf, transformed_string.as_bytes());
32735 -+}
32736 -+
32737 -+// Test modifying local flags
32738 -+#[test]
32739 -+fn test_local_flags() {
32740 -+ // openpty uses ptname(3) internally
32741 -+ let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
32742 -+
32743 -+ // Open one pty to get attributes for the second one
32744 -+ let mut termios = {
32745 -+ let pty = openpty(None, None).unwrap();
32746 -+ assert!(pty.master > 0);
32747 -+ assert!(pty.slave > 0);
32748 -+ let termios = tcgetattr(pty.master).unwrap();
32749 -+ close(pty.master).unwrap();
32750 -+ close(pty.slave).unwrap();
32751 -+ termios
32752 -+ };
32753 -+
32754 -+ // Make sure echo is specified by default or this test is useless.
32755 -+ assert!(termios.local_flags.contains(LocalFlags::ECHO));
32756 -+
32757 -+ // Disable local echo
32758 -+ termios.local_flags.remove(LocalFlags::ECHO);
32759 -+
32760 -+ // Open a new pty with our modified termios settings
32761 -+ let pty = openpty(None, &termios).unwrap();
32762 -+ assert!(pty.master > 0);
32763 -+ assert!(pty.slave > 0);
32764 -+
32765 -+ // Set the master is in nonblocking mode or reading will never return.
32766 -+ let flags = fcntl::fcntl(pty.master, fcntl::F_GETFL).unwrap();
32767 -+ let new_flags = fcntl::OFlag::from_bits_truncate(flags) | fcntl::OFlag::O_NONBLOCK;
32768 -+ fcntl::fcntl(pty.master, fcntl::F_SETFL(new_flags)).unwrap();
32769 -+
32770 -+ // Write into the master
32771 -+ let string = "foofoofoo\r";
32772 -+ write_all(pty.master, string.as_bytes());
32773 -+
32774 -+ // Try to read from the master, which should not have anything as echoing was disabled.
32775 -+ let mut buf = [0u8; 10];
32776 -+ let read = read(pty.master, &mut buf).unwrap_err();
32777 -+ close(pty.master).unwrap();
32778 -+ close(pty.slave).unwrap();
32779 -+ assert_eq!(read, Error::Sys(Errno::EAGAIN));
32780 -+}
32781 -+
32782 -+#[test]
32783 -+fn test_cfmakeraw() {
32784 -+ let mut termios = unsafe { Termios::default_uninit() };
32785 -+ termios::cfmakeraw(&mut termios);
32786 -+}
32787 -diff --git a/third_party/rust/nix-0.15.0/test/sys/test_uio.rs b/third_party/rust/nix-0.15.0/test/sys/test_uio.rs
32788 -new file mode 100644
32789 -index 0000000000000..3e4fc28ceb0e4
32790 ---- /dev/null
32791 -+++ b/third_party/rust/nix-0.15.0/test/sys/test_uio.rs
32792 -@@ -0,0 +1,241 @@
32793 -+use nix::sys::uio::*;
32794 -+use nix::unistd::*;
32795 -+use rand::{thread_rng, Rng};
32796 -+use rand::distributions::Alphanumeric;
32797 -+use std::{cmp, iter};
32798 -+use std::fs::{OpenOptions};
32799 -+use std::os::unix::io::AsRawFd;
32800 -+
32801 -+use tempfile::{tempfile, tempdir};
32802 -+
32803 -+#[test]
32804 -+fn test_writev() {
32805 -+ let mut to_write = Vec::with_capacity(16 * 128);
32806 -+ for _ in 0..16 {
32807 -+ let s: String = thread_rng().sample_iter(&Alphanumeric).take(128).collect();
32808 -+ let b = s.as_bytes();
32809 -+ to_write.extend(b.iter().cloned());
32810 -+ }
32811 -+ // Allocate and fill iovecs
32812 -+ let mut iovecs = Vec::new();
32813 -+ let mut consumed = 0;
32814 -+ while consumed < to_write.len() {
32815 -+ let left = to_write.len() - consumed;
32816 -+ let slice_len = if left <= 64 { left } else { thread_rng().gen_range(64, cmp::min(256, left)) };
32817 -+ let b = &to_write[consumed..consumed+slice_len];
32818 -+ iovecs.push(IoVec::from_slice(b));
32819 -+ consumed += slice_len;
32820 -+ }
32821 -+ let pipe_res = pipe();
32822 -+ assert!(pipe_res.is_ok());
32823 -+ let (reader, writer) = pipe_res.ok().unwrap();
32824 -+ // FileDesc will close its filedesc (reader).
32825 -+ let mut read_buf: Vec<u8> = iter::repeat(0u8).take(128 * 16).collect();
32826 -+ // Blocking io, should write all data.
32827 -+ let write_res = writev(writer, &iovecs);
32828 -+ // Successful write
32829 -+ assert!(write_res.is_ok());
32830 -+ let written = write_res.ok().unwrap();
32831 -+ // Check whether we written all data
32832 -+ assert_eq!(to_write.len(), written);
32833 -+ let read_res = read(reader, &mut read_buf[..]);
32834 -+ // Successful read
32835 -+ assert!(read_res.is_ok());
32836 -+ let read = read_res.ok().unwrap() as usize;
32837 -+ // Check we have read as much as we written
32838 -+ assert_eq!(read, written);
32839 -+ // Check equality of written and read data
32840 -+ assert_eq!(&to_write, &read_buf);
32841 -+ let close_res = close(writer);
32842 -+ assert!(close_res.is_ok());
32843 -+ let close_res = close(reader);
32844 -+ assert!(close_res.is_ok());
32845 -+}
32846 -+
32847 -+#[test]
32848 -+fn test_readv() {
32849 -+ let s:String = thread_rng().sample_iter(&Alphanumeric).take(128).collect();
32850 -+ let to_write = s.as_bytes().to_vec();
32851 -+ let mut storage = Vec::new();
32852 -+ let mut allocated = 0;
32853 -+ while allocated < to_write.len() {
32854 -+ let left = to_write.len() - allocated;
32855 -+ let vec_len = if left <= 64 { left } else { thread_rng().gen_range(64, cmp::min(256, left)) };
32856 -+ let v: Vec<u8> = iter::repeat(0u8).take(vec_len).collect();
32857 -+ storage.push(v);
32858 -+ allocated += vec_len;
32859 -+ }
32860 -+ let mut iovecs = Vec::with_capacity(storage.len());
32861 -+ for v in &mut storage {
32862 -+ iovecs.push(IoVec::from_mut_slice(&mut v[..]));
32863 -+ }
32864 -+ let pipe_res = pipe();
32865 -+ assert!(pipe_res.is_ok());
32866 -+ let (reader, writer) = pipe_res.ok().unwrap();
32867 -+ // Blocking io, should write all data.
32868 -+ let write_res = write(writer, &to_write);
32869 -+ // Successful write
32870 -+ assert!(write_res.is_ok());
32871 -+ let read_res = readv(reader, &mut iovecs[..]);
32872 -+ assert!(read_res.is_ok());
32873 -+ let read = read_res.ok().unwrap();
32874 -+ // Check whether we've read all data
32875 -+ assert_eq!(to_write.len(), read);
32876 -+ // Cccumulate data from iovecs
32877 -+ let mut read_buf = Vec::with_capacity(to_write.len());
32878 -+ for iovec in &iovecs {
32879 -+ read_buf.extend(iovec.as_slice().iter().cloned());
32880 -+ }
32881 -+ // Check whether iovecs contain all written data
32882 -+ assert_eq!(read_buf.len(), to_write.len());
32883 -+ // Check equality of written and read data
32884 -+ assert_eq!(&read_buf, &to_write);
32885 -+ let close_res = close(reader);
32886 -+ assert!(close_res.is_ok());
32887 -+ let close_res = close(writer);
32888 -+ assert!(close_res.is_ok());
32889 -+}
32890 -+
32891 -+#[test]
32892 -+fn test_pwrite() {
32893 -+ use std::io::Read;
32894 -+
32895 -+ let mut file = tempfile().unwrap();
32896 -+ let buf = [1u8;8];
32897 -+ assert_eq!(Ok(8), pwrite(file.as_raw_fd(), &buf, 8));
32898 -+ let mut file_content = Vec::new();
32899 -+ file.read_to_end(&mut file_content).unwrap();
32900 -+ let mut expected = vec![0u8;8];
32901 -+ expected.extend(vec![1;8]);
32902 -+ assert_eq!(file_content, expected);
32903 -+}
32904 -+
32905 -+#[test]
32906 -+fn test_pread() {
32907 -+ use std::io::Write;
32908 -+
32909 -+ let tempdir = tempdir().unwrap();
32910 -+
32911 -+ let path = tempdir.path().join("pread_test_file");
32912 -+ let mut file = OpenOptions::new().write(true).read(true).create(true)
32913 -+ .truncate(true).open(path).unwrap();
32914 -+ let file_content: Vec<u8> = (0..64).collect();
32915 -+ file.write_all(&file_content).unwrap();
32916 -+
32917 -+ let mut buf = [0u8;16];
32918 -+ assert_eq!(Ok(16), pread(file.as_raw_fd(), &mut buf, 16));
32919 -+ let expected: Vec<_> = (16..32).collect();
32920 -+ assert_eq!(&buf[..], &expected[..]);
32921 -+}
32922 -+
32923 -+#[test]
32924 -+#[cfg(target_os = "linux")]
32925 -+fn test_pwritev() {
32926 -+ use std::io::Read;
32927 -+
32928 -+ let to_write: Vec<u8> = (0..128).collect();
32929 -+ let expected: Vec<u8> = [vec![0;100], to_write.clone()].concat();
32930 -+
32931 -+ let iovecs = [
32932 -+ IoVec::from_slice(&to_write[0..17]),
32933 -+ IoVec::from_slice(&to_write[17..64]),
32934 -+ IoVec::from_slice(&to_write[64..128]),
32935 -+ ];
32936 -+
32937 -+ let tempdir = tempdir().unwrap();
32938 -+
32939 -+ // pwritev them into a temporary file
32940 -+ let path = tempdir.path().join("pwritev_test_file");
32941 -+ let mut file = OpenOptions::new().write(true).read(true).create(true)
32942 -+ .truncate(true).open(path).unwrap();
32943 -+
32944 -+ let written = pwritev(file.as_raw_fd(), &iovecs, 100).ok().unwrap();
32945 -+ assert_eq!(written, to_write.len());
32946 -+
32947 -+ // Read the data back and make sure it matches
32948 -+ let mut contents = Vec::new();
32949 -+ file.read_to_end(&mut contents).unwrap();
32950 -+ assert_eq!(contents, expected);
32951 -+}
32952 -+
32953 -+#[test]
32954 -+#[cfg(target_os = "linux")]
32955 -+fn test_preadv() {
32956 -+ use std::io::Write;
32957 -+
32958 -+ let to_write: Vec<u8> = (0..200).collect();
32959 -+ let expected: Vec<u8> = (100..200).collect();
32960 -+
32961 -+ let tempdir = tempdir().unwrap();
32962 -+
32963 -+ let path = tempdir.path().join("preadv_test_file");
32964 -+
32965 -+ let mut file = OpenOptions::new().read(true).write(true).create(true)
32966 -+ .truncate(true).open(path).unwrap();
32967 -+ file.write_all(&to_write).unwrap();
32968 -+
32969 -+ let mut buffers: Vec<Vec<u8>> = vec![
32970 -+ vec![0; 24],
32971 -+ vec![0; 1],
32972 -+ vec![0; 75],
32973 -+ ];
32974 -+
32975 -+ {
32976 -+ // Borrow the buffers into IoVecs and preadv into them
32977 -+ let iovecs: Vec<_> = buffers.iter_mut().map(
32978 -+ |buf| IoVec::from_mut_slice(&mut buf[..])).collect();
32979 -+ assert_eq!(Ok(100), preadv(file.as_raw_fd(), &iovecs, 100));
32980 -+ }
32981 -+
32982 -+ let all = buffers.concat();
32983 -+ assert_eq!(all, expected);
32984 -+}
32985 -+
32986 -+#[test]
32987 -+#[cfg(target_os = "linux")]
32988 -+// FIXME: qemu-user doesn't implement process_vm_readv/writev on most arches
32989 -+#[cfg_attr(not(any(target_arch = "x86", target_arch = "x86_64")), ignore)]
32990 -+fn test_process_vm_readv() {
32991 -+ use nix::unistd::ForkResult::*;
32992 -+ use nix::sys::signal::*;
32993 -+ use nix::sys::wait::*;
32994 -+
32995 -+ let _ = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
32996 -+
32997 -+ // Pre-allocate memory in the child, since allocation isn't safe
32998 -+ // post-fork (~= async-signal-safe)
32999 -+ let mut vector = vec![1u8, 2, 3, 4, 5];
33000 -+
33001 -+ let (r, w) = pipe().unwrap();
33002 -+ match fork().expect("Error: Fork Failed") {
33003 -+ Parent { child } => {
33004 -+ close(w).unwrap();
33005 -+ // wait for child
33006 -+ read(r, &mut [0u8]).unwrap();
33007 -+ close(r).unwrap();
33008 -+
33009 -+ let ptr = vector.as_ptr() as usize;
33010 -+ let remote_iov = RemoteIoVec { base: ptr, len: 5 };
33011 -+ let mut buf = vec![0u8; 5];
33012 -+
33013 -+ let ret = process_vm_readv(child,
33014 -+ &[IoVec::from_mut_slice(&mut buf)],
33015 -+ &[remote_iov]);
33016 -+
33017 -+ kill(child, SIGTERM).unwrap();
33018 -+ waitpid(child, None).unwrap();
33019 -+
33020 -+ assert_eq!(Ok(5), ret);
33021 -+ assert_eq!(20u8, buf.iter().sum());
33022 -+ },
33023 -+ Child => {
33024 -+ let _ = close(r);
33025 -+ for i in &mut vector {
33026 -+ *i += 1;
33027 -+ }
33028 -+ let _ = write(w, b"\0");
33029 -+ let _ = close(w);
33030 -+ loop { let _ = pause(); }
33031 -+ },
33032 -+ }
33033 -+}
33034 -diff --git a/third_party/rust/nix-0.15.0/test/sys/test_wait.rs b/third_party/rust/nix-0.15.0/test/sys/test_wait.rs
33035 -new file mode 100644
33036 -index 0000000000000..d07d82f0d9075
33037 ---- /dev/null
33038 -+++ b/third_party/rust/nix-0.15.0/test/sys/test_wait.rs
33039 -@@ -0,0 +1,104 @@
33040 -+use nix::Error;
33041 -+use nix::unistd::*;
33042 -+use nix::unistd::ForkResult::*;
33043 -+use nix::sys::signal::*;
33044 -+use nix::sys::wait::*;
33045 -+use libc::_exit;
33046 -+
33047 -+#[test]
33048 -+fn test_wait_signal() {
33049 -+ let _ = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
33050 -+
33051 -+ // Safe: The child only calls `pause` and/or `_exit`, which are async-signal-safe.
33052 -+ match fork().expect("Error: Fork Failed") {
33053 -+ Child => {
33054 -+ pause();
33055 -+ unsafe { _exit(123) }
33056 -+ },
33057 -+ Parent { child } => {
33058 -+ kill(child, Some(SIGKILL)).expect("Error: Kill Failed");
33059 -+ assert_eq!(waitpid(child, None), Ok(WaitStatus::Signaled(child, SIGKILL, false)));
33060 -+ },
33061 -+ }
33062 -+}
33063 -+
33064 -+#[test]
33065 -+fn test_wait_exit() {
33066 -+ let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
33067 -+
33068 -+ // Safe: Child only calls `_exit`, which is async-signal-safe.
33069 -+ match fork().expect("Error: Fork Failed") {
33070 -+ Child => unsafe { _exit(12); },
33071 -+ Parent { child } => {
33072 -+ assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 12)));
33073 -+ },
33074 -+ }
33075 -+}
33076 -+
33077 -+#[test]
33078 -+fn test_waitstatus_from_raw() {
33079 -+ let pid = Pid::from_raw(1);
33080 -+ assert_eq!(WaitStatus::from_raw(pid, 0x0002), Ok(WaitStatus::Signaled(pid, Signal::SIGINT, false)));
33081 -+ assert_eq!(WaitStatus::from_raw(pid, 0x0200), Ok(WaitStatus::Exited(pid, 2)));
33082 -+ assert_eq!(WaitStatus::from_raw(pid, 0x7f7f), Err(Error::invalid_argument()));
33083 -+}
33084 -+
33085 -+#[test]
33086 -+fn test_waitstatus_pid() {
33087 -+ let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
33088 -+
33089 -+ match fork().unwrap() {
33090 -+ Child => unsafe { _exit(0) },
33091 -+ Parent { child } => {
33092 -+ let status = waitpid(child, None).unwrap();
33093 -+ assert_eq!(status.pid(), Some(child));
33094 -+ }
33095 -+ }
33096 -+}
33097 -+
33098 -+#[cfg(any(target_os = "linux", target_os = "android"))]
33099 -+// FIXME: qemu-user doesn't implement ptrace on most arches
33100 -+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
33101 -+mod ptrace {
33102 -+ use nix::sys::ptrace::{self, Options, Event};
33103 -+ use nix::sys::signal::*;
33104 -+ use nix::sys::wait::*;
33105 -+ use nix::unistd::*;
33106 -+ use nix::unistd::ForkResult::*;
33107 -+ use libc::_exit;
33108 -+
33109 -+ fn ptrace_child() -> ! {
33110 -+ ptrace::traceme().unwrap();
33111 -+ // As recommended by ptrace(2), raise SIGTRAP to pause the child
33112 -+ // until the parent is ready to continue
33113 -+ raise(SIGTRAP).unwrap();
33114 -+ unsafe { _exit(0) }
33115 -+ }
33116 -+
33117 -+ fn ptrace_parent(child: Pid) {
33118 -+ // Wait for the raised SIGTRAP
33119 -+ assert_eq!(waitpid(child, None), Ok(WaitStatus::Stopped(child, SIGTRAP)));
33120 -+ // We want to test a syscall stop and a PTRACE_EVENT stop
33121 -+ assert!(ptrace::setoptions(child, Options::PTRACE_O_TRACESYSGOOD | Options::PTRACE_O_TRACEEXIT).is_ok());
33122 -+
33123 -+ // First, stop on the next system call, which will be exit()
33124 -+ assert!(ptrace::syscall(child).is_ok());
33125 -+ assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceSyscall(child)));
33126 -+ // Then get the ptrace event for the process exiting
33127 -+ assert!(ptrace::cont(child, None).is_ok());
33128 -+ assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceEvent(child, SIGTRAP, Event::PTRACE_EVENT_EXIT as i32)));
33129 -+ // Finally get the normal wait() result, now that the process has exited
33130 -+ assert!(ptrace::cont(child, None).is_ok());
33131 -+ assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 0)));
33132 -+ }
33133 -+
33134 -+ #[test]
33135 -+ fn test_wait_ptrace() {
33136 -+ let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
33137 -+
33138 -+ match fork().expect("Error: Fork Failed") {
33139 -+ Child => ptrace_child(),
33140 -+ Parent { child } => ptrace_parent(child),
33141 -+ }
33142 -+ }
33143 -+}
33144 -diff --git a/third_party/rust/nix-0.15.0/test/test.rs b/third_party/rust/nix-0.15.0/test/test.rs
33145 -new file mode 100644
33146 -index 0000000000000..6a71d261b5712
33147 ---- /dev/null
33148 -+++ b/third_party/rust/nix-0.15.0/test/test.rs
33149 -@@ -0,0 +1,149 @@
33150 -+// XXX Allow deprecated items until release 0.16.0. See issue #1096.
33151 -+#![allow(deprecated)]
33152 -+extern crate bytes;
33153 -+#[cfg(any(target_os = "android", target_os = "linux"))]
33154 -+extern crate caps;
33155 -+#[macro_use]
33156 -+extern crate cfg_if;
33157 -+#[macro_use]
33158 -+extern crate nix;
33159 -+#[macro_use]
33160 -+extern crate lazy_static;
33161 -+extern crate libc;
33162 -+extern crate rand;
33163 -+#[cfg(target_os = "freebsd")]
33164 -+extern crate sysctl;
33165 -+extern crate tempfile;
33166 -+
33167 -+#[cfg(any(target_os = "android", target_os = "linux"))]
33168 -+macro_rules! require_capability {
33169 -+ ($capname:ident) => {
33170 -+ use ::caps::{Capability, CapSet, has_cap};
33171 -+ use ::std::io::{self, Write};
33172 -+
33173 -+ if !has_cap(None, CapSet::Effective, Capability::$capname).unwrap() {
33174 -+ let stderr = io::stderr();
33175 -+ let mut handle = stderr.lock();
33176 -+ writeln!(handle, "Insufficient capabilities. Skipping test.")
33177 -+ .unwrap();
33178 -+ return;
33179 -+ }
33180 -+ }
33181 -+}
33182 -+
33183 -+#[cfg(target_os = "freebsd")]
33184 -+macro_rules! skip_if_jailed {
33185 -+ ($name:expr) => {
33186 -+ use ::sysctl::CtlValue;
33187 -+
33188 -+ if let CtlValue::Int(1) = ::sysctl::value("security.jail.jailed")
33189 -+ .unwrap()
33190 -+ {
33191 -+ use ::std::io::Write;
33192 -+ let stderr = ::std::io::stderr();
33193 -+ let mut handle = stderr.lock();
33194 -+ writeln!(handle, "{} cannot run in a jail. Skipping test.", $name)
33195 -+ .unwrap();
33196 -+ return;
33197 -+ }
33198 -+ }
33199 -+}
33200 -+
33201 -+macro_rules! skip_if_not_root {
33202 -+ ($name:expr) => {
33203 -+ use nix::unistd::Uid;
33204 -+
33205 -+ if !Uid::current().is_root() {
33206 -+ use ::std::io::Write;
33207 -+ let stderr = ::std::io::stderr();
33208 -+ let mut handle = stderr.lock();
33209 -+ writeln!(handle, "{} requires root privileges. Skipping test.", $name).unwrap();
33210 -+ return;
33211 -+ }
33212 -+ };
33213 -+}
33214 -+
33215 -+mod sys;
33216 -+mod test_dir;
33217 -+mod test_fcntl;
33218 -+#[cfg(any(target_os = "android",
33219 -+ target_os = "linux"))]
33220 -+mod test_kmod;
33221 -+#[cfg(any(target_os = "dragonfly",
33222 -+ target_os = "freebsd",
33223 -+ target_os = "fushsia",
33224 -+ target_os = "linux",
33225 -+ target_os = "netbsd"))]
33226 -+mod test_mq;
33227 -+mod test_net;
33228 -+mod test_nix_path;
33229 -+mod test_poll;
33230 -+mod test_pty;
33231 -+#[cfg(any(target_os = "android",
33232 -+ target_os = "freebsd",
33233 -+ target_os = "ios",
33234 -+ target_os = "linux",
33235 -+ target_os = "macos"))]
33236 -+mod test_sendfile;
33237 -+mod test_stat;
33238 -+mod test_unistd;
33239 -+
33240 -+use std::os::unix::io::RawFd;
33241 -+use std::path::PathBuf;
33242 -+use std::sync::{Mutex, RwLock, RwLockWriteGuard};
33243 -+use nix::unistd::{chdir, getcwd, read};
33244 -+
33245 -+/// Helper function analogous to `std::io::Read::read_exact`, but for `RawFD`s
33246 -+fn read_exact(f: RawFd, buf: &mut [u8]) {
33247 -+ let mut len = 0;
33248 -+ while len < buf.len() {
33249 -+ // get_mut would be better than split_at_mut, but it requires nightly
33250 -+ let (_, remaining) = buf.split_at_mut(len);
33251 -+ len += read(f, remaining).unwrap();
33252 -+ }
33253 -+}
33254 -+
33255 -+lazy_static! {
33256 -+ /// Any test that changes the process's current working directory must grab
33257 -+ /// the RwLock exclusively. Any process that cares about the current
33258 -+ /// working directory must grab it shared.
33259 -+ pub static ref CWD_LOCK: RwLock<()> = RwLock::new(());
33260 -+ /// Any test that creates child processes must grab this mutex, regardless
33261 -+ /// of what it does with those children.
33262 -+ pub static ref FORK_MTX: Mutex<()> = Mutex::new(());
33263 -+ /// Any test that changes the process's supplementary groups must grab this
33264 -+ /// mutex
33265 -+ pub static ref GROUPS_MTX: Mutex<()> = Mutex::new(());
33266 -+ /// Any tests that loads or unloads kernel modules must grab this mutex
33267 -+ pub static ref KMOD_MTX: Mutex<()> = Mutex::new(());
33268 -+ /// Any test that calls ptsname(3) must grab this mutex.
33269 -+ pub static ref PTSNAME_MTX: Mutex<()> = Mutex::new(());
33270 -+ /// Any test that alters signal handling must grab this mutex.
33271 -+ pub static ref SIGNAL_MTX: Mutex<()> = Mutex::new(());
33272 -+}
33273 -+
33274 -+/// RAII object that restores a test's original directory on drop
33275 -+struct DirRestore<'a> {
33276 -+ d: PathBuf,
33277 -+ _g: RwLockWriteGuard<'a, ()>
33278 -+}
33279 -+
33280 -+impl<'a> DirRestore<'a> {
33281 -+ fn new() -> Self {
33282 -+ let guard = ::CWD_LOCK.write()
33283 -+ .expect("Lock got poisoned by another test");
33284 -+ DirRestore{
33285 -+ _g: guard,
33286 -+ d: getcwd().unwrap(),
33287 -+ }
33288 -+ }
33289 -+}
33290 -+
33291 -+impl<'a> Drop for DirRestore<'a> {
33292 -+ fn drop(&mut self) {
33293 -+ let r = chdir(&self.d);
33294 -+ if std::thread::panicking() {
33295 -+ r.unwrap();
33296 -+ }
33297 -+ }
33298 -+}
33299 -diff --git a/third_party/rust/nix-0.15.0/test/test_dir.rs b/third_party/rust/nix-0.15.0/test/test_dir.rs
33300 -new file mode 100644
33301 -index 0000000000000..c42fbcd18a29d
33302 ---- /dev/null
33303 -+++ b/third_party/rust/nix-0.15.0/test/test_dir.rs
33304 -@@ -0,0 +1,46 @@
33305 -+extern crate nix;
33306 -+extern crate tempfile;
33307 -+
33308 -+use nix::dir::{Dir, Type};
33309 -+use nix::fcntl::OFlag;
33310 -+use nix::sys::stat::Mode;
33311 -+use std::fs::File;
33312 -+use self::tempfile::tempdir;
33313 -+
33314 -+#[test]
33315 -+fn read() {
33316 -+ let tmp = tempdir().unwrap();
33317 -+ File::create(&tmp.path().join("foo")).unwrap();
33318 -+ ::std::os::unix::fs::symlink("foo", tmp.path().join("bar")).unwrap();
33319 -+ let mut dir = Dir::open(tmp.path(), OFlag::O_DIRECTORY | OFlag::O_RDONLY | OFlag::O_CLOEXEC,
33320 -+ Mode::empty()).unwrap();
33321 -+ let mut entries: Vec<_> = dir.iter().map(|e| e.unwrap()).collect();
33322 -+ entries.sort_by(|a, b| a.file_name().cmp(b.file_name()));
33323 -+ let entry_names: Vec<_> = entries
33324 -+ .iter()
33325 -+ .map(|e| e.file_name().to_str().unwrap().to_owned())
33326 -+ .collect();
33327 -+ assert_eq!(&entry_names[..], &[".", "..", "bar", "foo"]);
33328 -+
33329 -+ // Check file types. The system is allowed to return DT_UNKNOWN (aka None here) but if it does
33330 -+ // return a type, ensure it's correct.
33331 -+ assert!(&[Some(Type::Directory), None].contains(&entries[0].file_type())); // .: dir
33332 -+ assert!(&[Some(Type::Directory), None].contains(&entries[1].file_type())); // ..: dir
33333 -+ assert!(&[Some(Type::Symlink), None].contains(&entries[2].file_type())); // bar: symlink
33334 -+ assert!(&[Some(Type::File), None].contains(&entries[3].file_type())); // foo: regular file
33335 -+}
33336 -+
33337 -+#[test]
33338 -+fn rewind() {
33339 -+ let tmp = tempdir().unwrap();
33340 -+ let mut dir = Dir::open(tmp.path(), OFlag::O_DIRECTORY | OFlag::O_RDONLY | OFlag::O_CLOEXEC,
33341 -+ Mode::empty()).unwrap();
33342 -+ let entries1: Vec<_> = dir.iter().map(|e| e.unwrap().file_name().to_owned()).collect();
33343 -+ let entries2: Vec<_> = dir.iter().map(|e| e.unwrap().file_name().to_owned()).collect();
33344 -+ assert_eq!(entries1, entries2);
33345 -+}
33346 -+
33347 -+#[test]
33348 -+fn ebadf() {
33349 -+ assert_eq!(Dir::from_fd(-1).unwrap_err(), nix::Error::Sys(nix::errno::Errno::EBADF));
33350 -+}
33351 -diff --git a/third_party/rust/nix-0.15.0/test/test_fcntl.rs b/third_party/rust/nix-0.15.0/test/test_fcntl.rs
33352 -new file mode 100644
33353 -index 0000000000000..6b2bbd679fc31
33354 ---- /dev/null
33355 -+++ b/third_party/rust/nix-0.15.0/test/test_fcntl.rs
33356 -@@ -0,0 +1,234 @@
33357 -+use nix::Error;
33358 -+use nix::errno::*;
33359 -+use nix::fcntl::{openat, open, OFlag, readlink, readlinkat, renameat};
33360 -+use nix::sys::stat::Mode;
33361 -+use nix::unistd::{close, read};
33362 -+use tempfile::{self, NamedTempFile};
33363 -+use std::fs::File;
33364 -+use std::io::prelude::*;
33365 -+use std::os::unix::fs;
33366 -+
33367 -+#[test]
33368 -+fn test_openat() {
33369 -+ const CONTENTS: &[u8] = b"abcd";
33370 -+ let mut tmp = NamedTempFile::new().unwrap();
33371 -+ tmp.write_all(CONTENTS).unwrap();
33372 -+
33373 -+ let dirfd = open(tmp.path().parent().unwrap(),
33374 -+ OFlag::empty(),
33375 -+ Mode::empty()).unwrap();
33376 -+ let fd = openat(dirfd,
33377 -+ tmp.path().file_name().unwrap(),
33378 -+ OFlag::O_RDONLY,
33379 -+ Mode::empty()).unwrap();
33380 -+
33381 -+ let mut buf = [0u8; 1024];
33382 -+ assert_eq!(4, read(fd, &mut buf).unwrap());
33383 -+ assert_eq!(CONTENTS, &buf[0..4]);
33384 -+
33385 -+ close(fd).unwrap();
33386 -+ close(dirfd).unwrap();
33387 -+}
33388 -+
33389 -+#[test]
33390 -+fn test_renameat() {
33391 -+ let old_dir = tempfile::tempdir().unwrap();
33392 -+ let old_dirfd = open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap();
33393 -+ let old_path = old_dir.path().join("old");
33394 -+ File::create(&old_path).unwrap();
33395 -+ let new_dir = tempfile::tempdir().unwrap();
33396 -+ let new_dirfd = open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap();
33397 -+ renameat(Some(old_dirfd), "old", Some(new_dirfd), "new").unwrap();
33398 -+ assert_eq!(renameat(Some(old_dirfd), "old", Some(new_dirfd), "new").unwrap_err(),
33399 -+ Error::Sys(Errno::ENOENT));
33400 -+ close(old_dirfd).unwrap();
33401 -+ close(new_dirfd).unwrap();
33402 -+ assert!(new_dir.path().join("new").exists());
33403 -+}
33404 -+
33405 -+#[test]
33406 -+fn test_readlink() {
33407 -+ let tempdir = tempfile::tempdir().unwrap();
33408 -+ let src = tempdir.path().join("a");
33409 -+ let dst = tempdir.path().join("b");
33410 -+ println!("a: {:?}, b: {:?}", &src, &dst);
33411 -+ fs::symlink(&src.as_path(), &dst.as_path()).unwrap();
33412 -+ let dirfd = open(tempdir.path(),
33413 -+ OFlag::empty(),
33414 -+ Mode::empty()).unwrap();
33415 -+
33416 -+ let mut buf = vec![0; src.to_str().unwrap().len() + 1];
33417 -+ assert_eq!(readlink(&dst, &mut buf).unwrap().to_str().unwrap(),
33418 -+ src.to_str().unwrap());
33419 -+ assert_eq!(readlinkat(dirfd, "b", &mut buf).unwrap().to_str().unwrap(),
33420 -+ src.to_str().unwrap());
33421 -+}
33422 -+
33423 -+#[cfg(any(target_os = "linux", target_os = "android"))]
33424 -+mod linux_android {
33425 -+ use std::io::prelude::*;
33426 -+ use std::io::SeekFrom;
33427 -+ use std::os::unix::prelude::*;
33428 -+
33429 -+ use libc::loff_t;
33430 -+
33431 -+ use nix::fcntl::*;
33432 -+ use nix::sys::uio::IoVec;
33433 -+ use nix::unistd::{close, pipe, read, write};
33434 -+
33435 -+ use tempfile::{tempfile, NamedTempFile};
33436 -+
33437 -+ /// This test creates a temporary file containing the contents
33438 -+ /// 'foobarbaz' and uses the `copy_file_range` call to transfer
33439 -+ /// 3 bytes at offset 3 (`bar`) to another empty file at offset 0. The
33440 -+ /// resulting file is read and should contain the contents `bar`.
33441 -+ /// The from_offset should be updated by the call to reflect
33442 -+ /// the 3 bytes read (6).
33443 -+ ///
33444 -+ /// FIXME: This test is disabled for linux based builds, because Travis
33445 -+ /// Linux version is too old for `copy_file_range`.
33446 -+ #[test]
33447 -+ #[ignore]
33448 -+ fn test_copy_file_range() {
33449 -+ const CONTENTS: &[u8] = b"foobarbaz";
33450 -+
33451 -+ let mut tmp1 = tempfile().unwrap();
33452 -+ let mut tmp2 = tempfile().unwrap();
33453 -+
33454 -+ tmp1.write_all(CONTENTS).unwrap();
33455 -+ tmp1.flush().unwrap();
33456 -+
33457 -+ let mut from_offset: i64 = 3;
33458 -+ copy_file_range(
33459 -+ tmp1.as_raw_fd(),
33460 -+ Some(&mut from_offset),
33461 -+ tmp2.as_raw_fd(),
33462 -+ None,
33463 -+ 3,
33464 -+ )
33465 -+ .unwrap();
33466 -+
33467 -+ let mut res: String = String::new();
33468 -+ tmp2.seek(SeekFrom::Start(0)).unwrap();
33469 -+ tmp2.read_to_string(&mut res).unwrap();
33470 -+
33471 -+ assert_eq!(res, String::from("bar"));
33472 -+ assert_eq!(from_offset, 6);
33473 -+ }
33474 -+
33475 -+ #[test]
33476 -+ fn test_splice() {
33477 -+ const CONTENTS: &[u8] = b"abcdef123456";
33478 -+ let mut tmp = tempfile().unwrap();
33479 -+ tmp.write_all(CONTENTS).unwrap();
33480 -+
33481 -+ let (rd, wr) = pipe().unwrap();
33482 -+ let mut offset: loff_t = 5;
33483 -+ let res = splice(tmp.as_raw_fd(), Some(&mut offset),
33484 -+ wr, None, 2, SpliceFFlags::empty()).unwrap();
33485 -+
33486 -+ assert_eq!(2, res);
33487 -+
33488 -+ let mut buf = [0u8; 1024];
33489 -+ assert_eq!(2, read(rd, &mut buf).unwrap());
33490 -+ assert_eq!(b"f1", &buf[0..2]);
33491 -+ assert_eq!(7, offset);
33492 -+
33493 -+ close(rd).unwrap();
33494 -+ close(wr).unwrap();
33495 -+ }
33496 -+
33497 -+ #[test]
33498 -+ fn test_tee() {
33499 -+ let (rd1, wr1) = pipe().unwrap();
33500 -+ let (rd2, wr2) = pipe().unwrap();
33501 -+
33502 -+ write(wr1, b"abc").unwrap();
33503 -+ let res = tee(rd1, wr2, 2, SpliceFFlags::empty()).unwrap();
33504 -+
33505 -+ assert_eq!(2, res);
33506 -+
33507 -+ let mut buf = [0u8; 1024];
33508 -+
33509 -+ // Check the tee'd bytes are at rd2.
33510 -+ assert_eq!(2, read(rd2, &mut buf).unwrap());
33511 -+ assert_eq!(b"ab", &buf[0..2]);
33512 -+
33513 -+ // Check all the bytes are still at rd1.
33514 -+ assert_eq!(3, read(rd1, &mut buf).unwrap());
33515 -+ assert_eq!(b"abc", &buf[0..3]);
33516 -+
33517 -+ close(rd1).unwrap();
33518 -+ close(wr1).unwrap();
33519 -+ close(rd2).unwrap();
33520 -+ close(wr2).unwrap();
33521 -+ }
33522 -+
33523 -+ #[test]
33524 -+ fn test_vmsplice() {
33525 -+ let (rd, wr) = pipe().unwrap();
33526 -+
33527 -+ let buf1 = b"abcdef";
33528 -+ let buf2 = b"defghi";
33529 -+ let mut iovecs = Vec::with_capacity(2);
33530 -+ iovecs.push(IoVec::from_slice(&buf1[0..3]));
33531 -+ iovecs.push(IoVec::from_slice(&buf2[0..3]));
33532 -+
33533 -+ let res = vmsplice(wr, &iovecs[..], SpliceFFlags::empty()).unwrap();
33534 -+
33535 -+ assert_eq!(6, res);
33536 -+
33537 -+ // Check the bytes can be read at rd.
33538 -+ let mut buf = [0u8; 32];
33539 -+ assert_eq!(6, read(rd, &mut buf).unwrap());
33540 -+ assert_eq!(b"abcdef", &buf[0..6]);
33541 -+
33542 -+ close(rd).unwrap();
33543 -+ close(wr).unwrap();
33544 -+ }
33545 -+
33546 -+ #[test]
33547 -+ fn test_fallocate() {
33548 -+ let tmp = NamedTempFile::new().unwrap();
33549 -+
33550 -+ let fd = tmp.as_raw_fd();
33551 -+ fallocate(fd, FallocateFlags::empty(), 0, 100).unwrap();
33552 -+
33553 -+ // Check if we read exactly 100 bytes
33554 -+ let mut buf = [0u8; 200];
33555 -+ assert_eq!(100, read(fd, &mut buf).unwrap());
33556 -+ }
33557 -+}
33558 -+
33559 -+#[cfg(any(target_os = "linux",
33560 -+ target_os = "android",
33561 -+ target_os = "emscripten",
33562 -+ target_os = "fuchsia",
33563 -+ any(target_os = "wasi", target_env = "wasi"),
33564 -+ target_env = "uclibc",
33565 -+ target_env = "freebsd"))]
33566 -+mod test_posix_fadvise {
33567 -+
33568 -+ use tempfile::NamedTempFile;
33569 -+ use std::os::unix::io::{RawFd, AsRawFd};
33570 -+ use nix::errno::Errno;
33571 -+ use nix::fcntl::*;
33572 -+ use nix::unistd::pipe;
33573 -+
33574 -+ #[test]
33575 -+ fn test_success() {
33576 -+ let tmp = NamedTempFile::new().unwrap();
33577 -+ let fd = tmp.as_raw_fd();
33578 -+ let res = posix_fadvise(fd, 0, 100, PosixFadviseAdvice::POSIX_FADV_WILLNEED).unwrap();
33579 -+
33580 -+ assert_eq!(res, 0);
33581 -+ }
33582 -+
33583 -+ #[test]
33584 -+ fn test_errno() {
33585 -+ let (rd, _wr) = pipe().unwrap();
33586 -+ let errno = posix_fadvise(rd as RawFd, 0, 100, PosixFadviseAdvice::POSIX_FADV_WILLNEED)
33587 -+ .unwrap();
33588 -+ assert_eq!(errno, Errno::ESPIPE as i32);
33589 -+ }
33590 -+}
33591 -diff --git a/third_party/rust/nix-0.15.0/test/test_kmod/hello_mod/Makefile b/third_party/rust/nix-0.15.0/test/test_kmod/hello_mod/Makefile
33592 -new file mode 100644
33593 -index 0000000000000..74c99b77e96e1
33594 ---- /dev/null
33595 -+++ b/third_party/rust/nix-0.15.0/test/test_kmod/hello_mod/Makefile
33596 -@@ -0,0 +1,7 @@
33597 -+obj-m += hello.o
33598 -+
33599 -+all:
33600 -+ make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
33601 -+
33602 -+clean:
33603 -+ make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean
33604 -diff --git a/third_party/rust/nix-0.15.0/test/test_kmod/hello_mod/hello.c b/third_party/rust/nix-0.15.0/test/test_kmod/hello_mod/hello.c
33605 -new file mode 100644
33606 -index 0000000000000..1c34987d2ac39
33607 ---- /dev/null
33608 -+++ b/third_party/rust/nix-0.15.0/test/test_kmod/hello_mod/hello.c
33609 -@@ -0,0 +1,26 @@
33610 -+/*
33611 -+ * SPDX-License-Identifier: GPL-2.0+ or MIT
33612 -+ */
33613 -+#include <linux/module.h>
33614 -+#include <linux/kernel.h>
33615 -+
33616 -+static int number= 1;
33617 -+static char *who = "World";
33618 -+
33619 -+module_param(number, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
33620 -+MODULE_PARM_DESC(myint, "Just some number");
33621 -+module_param(who, charp, 0000);
33622 -+MODULE_PARM_DESC(who, "Whot to greet");
33623 -+
33624 -+int init_module(void)
33625 -+{
33626 -+ printk(KERN_INFO "Hello %s (%d)!\n", who, number);
33627 -+ return 0;
33628 -+}
33629 -+
33630 -+void cleanup_module(void)
33631 -+{
33632 -+ printk(KERN_INFO "Goodbye %s (%d)!\n", who, number);
33633 -+}
33634 -+
33635 -+MODULE_LICENSE("Dual MIT/GPL");
33636 -diff --git a/third_party/rust/nix-0.15.0/test/test_kmod/mod.rs b/third_party/rust/nix-0.15.0/test/test_kmod/mod.rs
33637 -new file mode 100644
33638 -index 0000000000000..ad406357b06d2
33639 ---- /dev/null
33640 -+++ b/third_party/rust/nix-0.15.0/test/test_kmod/mod.rs
33641 -@@ -0,0 +1,166 @@
33642 -+use std::fs::copy;
33643 -+use std::path::PathBuf;
33644 -+use std::process::Command;
33645 -+use tempfile::{tempdir, TempDir};
33646 -+
33647 -+fn compile_kernel_module() -> (PathBuf, String, TempDir) {
33648 -+ let _m = ::FORK_MTX
33649 -+ .lock()
33650 -+ .expect("Mutex got poisoned by another test");
33651 -+
33652 -+ let tmp_dir = tempdir().expect("unable to create temporary build directory");
33653 -+
33654 -+ copy(
33655 -+ "test/test_kmod/hello_mod/hello.c",
33656 -+ &tmp_dir.path().join("hello.c"),
33657 -+ ).expect("unable to copy hello.c to temporary build directory");
33658 -+ copy(
33659 -+ "test/test_kmod/hello_mod/Makefile",
33660 -+ &tmp_dir.path().join("Makefile"),
33661 -+ ).expect("unable to copy Makefile to temporary build directory");
33662 -+
33663 -+ let status = Command::new("make")
33664 -+ .current_dir(tmp_dir.path())
33665 -+ .status()
33666 -+ .expect("failed to run make");
33667 -+
33668 -+ assert!(status.success());
33669 -+
33670 -+ // Return the relative path of the build kernel module
33671 -+ (tmp_dir.path().join("hello.ko"), "hello".to_owned(), tmp_dir)
33672 -+}
33673 -+
33674 -+use nix::errno::Errno;
33675 -+use nix::kmod::{delete_module, DeleteModuleFlags};
33676 -+use nix::kmod::{finit_module, init_module, ModuleInitFlags};
33677 -+use nix::Error;
33678 -+use std::ffi::CString;
33679 -+use std::fs::File;
33680 -+use std::io::Read;
33681 -+
33682 -+#[test]
33683 -+fn test_finit_and_delete_module() {
33684 -+ require_capability!(CAP_SYS_MODULE);
33685 -+ let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
33686 -+ let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test");
33687 -+
33688 -+ let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
33689 -+
33690 -+ let f = File::open(kmod_path).expect("unable to open kernel module");
33691 -+ finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty())
33692 -+ .expect("unable to load kernel module");
33693 -+
33694 -+ delete_module(
33695 -+ &CString::new(kmod_name).unwrap(),
33696 -+ DeleteModuleFlags::empty(),
33697 -+ ).expect("unable to unload kernel module");
33698 -+}
33699 -+
33700 -+#[test]
33701 -+fn test_finit_and_delete_modul_with_params() {
33702 -+ require_capability!(CAP_SYS_MODULE);
33703 -+ let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
33704 -+ let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test");
33705 -+
33706 -+ let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
33707 -+
33708 -+ let f = File::open(kmod_path).expect("unable to open kernel module");
33709 -+ finit_module(
33710 -+ &f,
33711 -+ &CString::new("who=Rust number=2018").unwrap(),
33712 -+ ModuleInitFlags::empty(),
33713 -+ ).expect("unable to load kernel module");
33714 -+
33715 -+ delete_module(
33716 -+ &CString::new(kmod_name).unwrap(),
33717 -+ DeleteModuleFlags::empty(),
33718 -+ ).expect("unable to unload kernel module");
33719 -+}
33720 -+
33721 -+#[test]
33722 -+fn test_init_and_delete_module() {
33723 -+ require_capability!(CAP_SYS_MODULE);
33724 -+ let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
33725 -+ let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test");
33726 -+
33727 -+ let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
33728 -+
33729 -+ let mut f = File::open(kmod_path).expect("unable to open kernel module");
33730 -+ let mut contents: Vec<u8> = Vec::new();
33731 -+ f.read_to_end(&mut contents)
33732 -+ .expect("unable to read kernel module content to buffer");
33733 -+ init_module(&mut contents, &CString::new("").unwrap()).expect("unable to load kernel module");
33734 -+
33735 -+ delete_module(
33736 -+ &CString::new(kmod_name).unwrap(),
33737 -+ DeleteModuleFlags::empty(),
33738 -+ ).expect("unable to unload kernel module");
33739 -+}
33740 -+
33741 -+#[test]
33742 -+fn test_init_and_delete_module_with_params() {
33743 -+ require_capability!(CAP_SYS_MODULE);
33744 -+ let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
33745 -+ let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test");
33746 -+
33747 -+ let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
33748 -+
33749 -+ let mut f = File::open(kmod_path).expect("unable to open kernel module");
33750 -+ let mut contents: Vec<u8> = Vec::new();
33751 -+ f.read_to_end(&mut contents)
33752 -+ .expect("unable to read kernel module content to buffer");
33753 -+ init_module(&mut contents, &CString::new("who=Nix number=2015").unwrap())
33754 -+ .expect("unable to load kernel module");
33755 -+
33756 -+ delete_module(
33757 -+ &CString::new(kmod_name).unwrap(),
33758 -+ DeleteModuleFlags::empty(),
33759 -+ ).expect("unable to unload kernel module");
33760 -+}
33761 -+
33762 -+#[test]
33763 -+fn test_finit_module_invalid() {
33764 -+ require_capability!(CAP_SYS_MODULE);
33765 -+ let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
33766 -+ let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test");
33767 -+
33768 -+ let kmod_path = "/dev/zero";
33769 -+
33770 -+ let f = File::open(kmod_path).expect("unable to open kernel module");
33771 -+ let result = finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty());
33772 -+
33773 -+ assert_eq!(result.unwrap_err(), Error::Sys(Errno::EINVAL));
33774 -+}
33775 -+
33776 -+#[test]
33777 -+fn test_finit_module_twice_and_delete_module() {
33778 -+ require_capability!(CAP_SYS_MODULE);
33779 -+ let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
33780 -+ let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test");
33781 -+
33782 -+ let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
33783 -+
33784 -+ let f = File::open(kmod_path).expect("unable to open kernel module");
33785 -+ finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty())
33786 -+ .expect("unable to load kernel module");
33787 -+
33788 -+ let result = finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty());
33789 -+
33790 -+ assert_eq!(result.unwrap_err(), Error::Sys(Errno::EEXIST));
33791 -+
33792 -+ delete_module(
33793 -+ &CString::new(kmod_name).unwrap(),
33794 -+ DeleteModuleFlags::empty(),
33795 -+ ).expect("unable to unload kernel module");
33796 -+}
33797 -+
33798 -+#[test]
33799 -+fn test_delete_module_not_loaded() {
33800 -+ require_capability!(CAP_SYS_MODULE);
33801 -+ let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
33802 -+ let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test");
33803 -+
33804 -+ let result = delete_module(&CString::new("hello").unwrap(), DeleteModuleFlags::empty());
33805 -+
33806 -+ assert_eq!(result.unwrap_err(), Error::Sys(Errno::ENOENT));
33807 -+}
33808 -diff --git a/third_party/rust/nix-0.15.0/test/test_mount.rs b/third_party/rust/nix-0.15.0/test/test_mount.rs
33809 -new file mode 100644
33810 -index 0000000000000..d2e08bc42855d
33811 ---- /dev/null
33812 -+++ b/third_party/rust/nix-0.15.0/test/test_mount.rs
33813 -@@ -0,0 +1,238 @@
33814 -+// Impelmentation note: to allow unprivileged users to run it, this test makes
33815 -+// use of user and mount namespaces. On systems that allow unprivileged user
33816 -+// namespaces (Linux >= 3.8 compiled with CONFIG_USER_NS), the test should run
33817 -+// without root.
33818 -+
33819 -+extern crate libc;
33820 -+extern crate nix;
33821 -+extern crate tempfile;
33822 -+
33823 -+#[cfg(target_os = "linux")]
33824 -+mod test_mount {
33825 -+ use std::fs::{self, File};
33826 -+ use std::io::{self, Read, Write};
33827 -+ use std::os::unix::fs::OpenOptionsExt;
33828 -+ use std::os::unix::fs::PermissionsExt;
33829 -+ use std::process::{self, Command};
33830 -+
33831 -+ use libc::{EACCES, EROFS};
33832 -+
33833 -+ use nix::errno::Errno;
33834 -+ use nix::mount::{mount, umount, MsFlags};
33835 -+ use nix::sched::{unshare, CloneFlags};
33836 -+ use nix::sys::stat::{self, Mode};
33837 -+ use nix::unistd::getuid;
33838 -+
33839 -+ use tempfile;
33840 -+
33841 -+ static SCRIPT_CONTENTS: &'static [u8] = b"#!/bin/sh
33842 -+exit 23";
33843 -+
33844 -+ const EXPECTED_STATUS: i32 = 23;
33845 -+
33846 -+ const NONE: Option<&'static [u8]> = None;
33847 -+ pub fn test_mount_tmpfs_without_flags_allows_rwx() {
33848 -+ let tempdir = tempfile::tempdir().unwrap();
33849 -+
33850 -+ mount(NONE,
33851 -+ tempdir.path(),
33852 -+ Some(b"tmpfs".as_ref()),
33853 -+ MsFlags::empty(),
33854 -+ NONE)
33855 -+ .unwrap_or_else(|e| panic!("mount failed: {}", e));
33856 -+
33857 -+ let test_path = tempdir.path().join("test");
33858 -+
33859 -+ // Verify write.
33860 -+ fs::OpenOptions::new()
33861 -+ .create(true)
33862 -+ .write(true)
33863 -+ .mode((Mode::S_IRWXU | Mode::S_IRWXG | Mode::S_IRWXO).bits())
33864 -+ .open(&test_path)
33865 -+ .or_else(|e|
33866 -+ if Errno::from_i32(e.raw_os_error().unwrap()) == Errno::EOVERFLOW {
33867 -+ // Skip tests on certain Linux kernels which have a bug
33868 -+ // regarding tmpfs in namespaces.
33869 -+ // Ubuntu 14.04 and 16.04 are known to be affected; 16.10 is
33870 -+ // not. There is no legitimate reason for open(2) to return
33871 -+ // EOVERFLOW here.
33872 -+ // https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1659087
33873 -+ let stderr = io::stderr();
33874 -+ let mut handle = stderr.lock();
33875 -+ writeln!(handle, "Buggy Linux kernel detected. Skipping test.")
33876 -+ .unwrap();
33877 -+ process::exit(0);
33878 -+ } else {
33879 -+ panic!("open failed: {}", e);
33880 -+ }
33881 -+ )
33882 -+ .and_then(|mut f| f.write(SCRIPT_CONTENTS))
33883 -+ .unwrap_or_else(|e| panic!("write failed: {}", e));
33884 -+
33885 -+ // Verify read.
33886 -+ let mut buf = Vec::new();
33887 -+ File::open(&test_path)
33888 -+ .and_then(|mut f| f.read_to_end(&mut buf))
33889 -+ .unwrap_or_else(|e| panic!("read failed: {}", e));
33890 -+ assert_eq!(buf, SCRIPT_CONTENTS);
33891 -+
33892 -+ // Verify execute.
33893 -+ assert_eq!(EXPECTED_STATUS,
33894 -+ Command::new(&test_path)
33895 -+ .status()
33896 -+ .unwrap_or_else(|e| panic!("exec failed: {}", e))
33897 -+ .code()
33898 -+ .unwrap_or_else(|| panic!("child killed by signal")));
33899 -+
33900 -+ umount(tempdir.path()).unwrap_or_else(|e| panic!("umount failed: {}", e));
33901 -+ }
33902 -+
33903 -+ pub fn test_mount_rdonly_disallows_write() {
33904 -+ let tempdir = tempfile::tempdir().unwrap();
33905 -+
33906 -+ mount(NONE,
33907 -+ tempdir.path(),
33908 -+ Some(b"tmpfs".as_ref()),
33909 -+ MsFlags::MS_RDONLY,
33910 -+ NONE)
33911 -+ .unwrap_or_else(|e| panic!("mount failed: {}", e));
33912 -+
33913 -+ // EROFS: Read-only file system
33914 -+ assert_eq!(EROFS as i32,
33915 -+ File::create(tempdir.path().join("test")).unwrap_err().raw_os_error().unwrap());
33916 -+
33917 -+ umount(tempdir.path()).unwrap_or_else(|e| panic!("umount failed: {}", e));
33918 -+ }
33919 -+
33920 -+ pub fn test_mount_noexec_disallows_exec() {
33921 -+ let tempdir = tempfile::tempdir().unwrap();
33922 -+
33923 -+ mount(NONE,
33924 -+ tempdir.path(),
33925 -+ Some(b"tmpfs".as_ref()),
33926 -+ MsFlags::MS_NOEXEC,
33927 -+ NONE)
33928 -+ .unwrap_or_else(|e| panic!("mount failed: {}", e));
33929 -+
33930 -+ let test_path = tempdir.path().join("test");
33931 -+
33932 -+ fs::OpenOptions::new()
33933 -+ .create(true)
33934 -+ .write(true)
33935 -+ .mode((Mode::S_IRWXU | Mode::S_IRWXG | Mode::S_IRWXO).bits())
33936 -+ .open(&test_path)
33937 -+ .and_then(|mut f| f.write(SCRIPT_CONTENTS))
33938 -+ .unwrap_or_else(|e| panic!("write failed: {}", e));
33939 -+
33940 -+ // Verify that we cannot execute despite a+x permissions being set.
33941 -+ let mode = stat::Mode::from_bits_truncate(fs::metadata(&test_path)
33942 -+ .map(|md| md.permissions().mode())
33943 -+ .unwrap_or_else(|e| {
33944 -+ panic!("metadata failed: {}", e)
33945 -+ }));
33946 -+
33947 -+ assert!(mode.contains(Mode::S_IXUSR | Mode::S_IXGRP | Mode::S_IXOTH),
33948 -+ "{:?} did not have execute permissions",
33949 -+ &test_path);
33950 -+
33951 -+ // EACCES: Permission denied
33952 -+ assert_eq!(EACCES as i32,
33953 -+ Command::new(&test_path).status().unwrap_err().raw_os_error().unwrap());
33954 -+
33955 -+ umount(tempdir.path()).unwrap_or_else(|e| panic!("umount failed: {}", e));
33956 -+ }
33957 -+
33958 -+ pub fn test_mount_bind() {
33959 -+ let tempdir = tempfile::tempdir().unwrap();
33960 -+ let file_name = "test";
33961 -+
33962 -+ {
33963 -+ let mount_point = tempfile::tempdir().unwrap();
33964 -+
33965 -+ mount(Some(tempdir.path()),
33966 -+ mount_point.path(),
33967 -+ NONE,
33968 -+ MsFlags::MS_BIND,
33969 -+ NONE)
33970 -+ .unwrap_or_else(|e| panic!("mount failed: {}", e));
33971 -+
33972 -+ fs::OpenOptions::new()
33973 -+ .create(true)
33974 -+ .write(true)
33975 -+ .mode((Mode::S_IRWXU | Mode::S_IRWXG | Mode::S_IRWXO).bits())
33976 -+ .open(mount_point.path().join(file_name))
33977 -+ .and_then(|mut f| f.write(SCRIPT_CONTENTS))
33978 -+ .unwrap_or_else(|e| panic!("write failed: {}", e));
33979 -+
33980 -+ umount(mount_point.path()).unwrap_or_else(|e| panic!("umount failed: {}", e));
33981 -+ }
33982 -+
33983 -+ // Verify the file written in the mount shows up in source directory, even
33984 -+ // after unmounting.
33985 -+
33986 -+ let mut buf = Vec::new();
33987 -+ File::open(tempdir.path().join(file_name))
33988 -+ .and_then(|mut f| f.read_to_end(&mut buf))
33989 -+ .unwrap_or_else(|e| panic!("read failed: {}", e));
33990 -+ assert_eq!(buf, SCRIPT_CONTENTS);
33991 -+ }
33992 -+
33993 -+ pub fn setup_namespaces() {
33994 -+ // Hold on to the uid in the parent namespace.
33995 -+ let uid = getuid();
33996 -+
33997 -+ unshare(CloneFlags::CLONE_NEWNS | CloneFlags::CLONE_NEWUSER).unwrap_or_else(|e| {
33998 -+ let stderr = io::stderr();
33999 -+ let mut handle = stderr.lock();
34000 -+ writeln!(handle,
34001 -+ "unshare failed: {}. Are unprivileged user namespaces available?",
34002 -+ e).unwrap();
34003 -+ writeln!(handle, "mount is not being tested").unwrap();
34004 -+ // Exit with success because not all systems support unprivileged user namespaces, and
34005 -+ // that's not what we're testing for.
34006 -+ process::exit(0);
34007 -+ });
34008 -+
34009 -+ // Map user as uid 1000.
34010 -+ fs::OpenOptions::new()
34011 -+ .write(true)
34012 -+ .open("/proc/self/uid_map")
34013 -+ .and_then(|mut f| f.write(format!("1000 {} 1\n", uid).as_bytes()))
34014 -+ .unwrap_or_else(|e| panic!("could not write uid map: {}", e));
34015 -+ }
34016 -+}
34017 -+
34018 -+
34019 -+// Test runner
34020 -+
34021 -+/// Mimic normal test output (hackishly).
34022 -+#[cfg(target_os = "linux")]
34023 -+macro_rules! run_tests {
34024 -+ ( $($test_fn:ident),* ) => {{
34025 -+ println!();
34026 -+
34027 -+ $(
34028 -+ print!("test test_mount::{} ... ", stringify!($test_fn));
34029 -+ $test_fn();
34030 -+ println!("ok");
34031 -+ )*
34032 -+
34033 -+ println!();
34034 -+ }}
34035 -+}
34036 -+
34037 -+#[cfg(target_os = "linux")]
34038 -+fn main() {
34039 -+ use test_mount::{setup_namespaces, test_mount_tmpfs_without_flags_allows_rwx,
34040 -+ test_mount_rdonly_disallows_write, test_mount_noexec_disallows_exec,
34041 -+ test_mount_bind};
34042 -+ setup_namespaces();
34043 -+
34044 -+ run_tests!(test_mount_tmpfs_without_flags_allows_rwx,
34045 -+ test_mount_rdonly_disallows_write,
34046 -+ test_mount_noexec_disallows_exec,
34047 -+ test_mount_bind);
34048 -+}
34049 -+
34050 -+#[cfg(not(target_os = "linux"))]
34051 -+fn main() {}
34052 -diff --git a/third_party/rust/nix-0.15.0/test/test_mq.rs b/third_party/rust/nix-0.15.0/test/test_mq.rs
34053 -new file mode 100644
34054 -index 0000000000000..caac4fc261cd6
34055 ---- /dev/null
34056 -+++ b/third_party/rust/nix-0.15.0/test/test_mq.rs
34057 -@@ -0,0 +1,152 @@
34058 -+use libc::c_long;
34059 -+
34060 -+use std::ffi::CString;
34061 -+use std::str;
34062 -+
34063 -+use nix::errno::Errno::*;
34064 -+use nix::Error::Sys;
34065 -+use nix::mqueue::{mq_open, mq_close, mq_send, mq_receive};
34066 -+use nix::mqueue::{MqAttr, MQ_OFlag};
34067 -+use nix::sys::stat::Mode;
34068 -+
34069 -+#[test]
34070 -+fn test_mq_send_and_receive() {
34071 -+ const MSG_SIZE: c_long = 32;
34072 -+ let attr = MqAttr::new(0, 10, MSG_SIZE, 0);
34073 -+ let mq_name= &CString::new(b"/a_nix_test_queue".as_ref()).unwrap();
34074 -+
34075 -+ let oflag0 = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
34076 -+ let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
34077 -+ let r0 = mq_open(mq_name, oflag0, mode, Some(&attr));
34078 -+ if let Err(Sys(ENOSYS)) = r0 {
34079 -+ println!("message queues not supported or module not loaded?");
34080 -+ return;
34081 -+ };
34082 -+ let mqd0 = r0.unwrap();
34083 -+ let msg_to_send = "msg_1";
34084 -+ mq_send(mqd0, msg_to_send.as_bytes(), 1).unwrap();
34085 -+
34086 -+ let oflag1 = MQ_OFlag::O_CREAT | MQ_OFlag::O_RDONLY;
34087 -+ let mqd1 = mq_open(mq_name, oflag1, mode, Some(&attr)).unwrap();
34088 -+ let mut buf = [0u8; 32];
34089 -+ let mut prio = 0u32;
34090 -+ let len = mq_receive(mqd1, &mut buf, &mut prio).unwrap();
34091 -+ assert!(prio == 1);
34092 -+
34093 -+ mq_close(mqd1).unwrap();
34094 -+ mq_close(mqd0).unwrap();
34095 -+ assert_eq!(msg_to_send, str::from_utf8(&buf[0..len]).unwrap());
34096 -+}
34097 -+
34098 -+
34099 -+#[test]
34100 -+#[cfg(not(any(target_os = "netbsd")))]
34101 -+fn test_mq_getattr() {
34102 -+ use nix::mqueue::mq_getattr;
34103 -+ const MSG_SIZE: c_long = 32;
34104 -+ let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0);
34105 -+ let mq_name = &CString::new(b"/attr_test_get_attr".as_ref()).unwrap();
34106 -+ let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
34107 -+ let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
34108 -+ let r = mq_open(mq_name, oflag, mode, Some(&initial_attr));
34109 -+ if let Err(Sys(ENOSYS)) = r {
34110 -+ println!("message queues not supported or module not loaded?");
34111 -+ return;
34112 -+ };
34113 -+ let mqd = r.unwrap();
34114 -+
34115 -+ let read_attr = mq_getattr(mqd).unwrap();
34116 -+ assert_eq!(read_attr, initial_attr);
34117 -+ mq_close(mqd).unwrap();
34118 -+}
34119 -+
34120 -+// FIXME: Fix failures for mips in QEMU
34121 -+#[test]
34122 -+#[cfg(not(any(target_os = "netbsd")))]
34123 -+#[cfg_attr(any(target_arch = "mips", target_arch = "mips64"), ignore)]
34124 -+fn test_mq_setattr() {
34125 -+ use nix::mqueue::{mq_getattr, mq_setattr};
34126 -+ const MSG_SIZE: c_long = 32;
34127 -+ let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0);
34128 -+ let mq_name = &CString::new(b"/attr_test_get_attr".as_ref()).unwrap();
34129 -+ let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
34130 -+ let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
34131 -+ let r = mq_open(mq_name, oflag, mode, Some(&initial_attr));
34132 -+ if let Err(Sys(ENOSYS)) = r {
34133 -+ println!("message queues not supported or module not loaded?");
34134 -+ return;
34135 -+ };
34136 -+ let mqd = r.unwrap();
34137 -+
34138 -+ let new_attr = MqAttr::new(0, 20, MSG_SIZE * 2, 100);
34139 -+ let old_attr = mq_setattr(mqd, &new_attr).unwrap();
34140 -+ assert_eq!(old_attr, initial_attr);
34141 -+
34142 -+ let new_attr_get = mq_getattr(mqd).unwrap();
34143 -+ // The following tests make sense. No changes here because according to the Linux man page only
34144 -+ // O_NONBLOCK can be set (see tests below)
34145 -+ assert_ne!(new_attr_get, new_attr);
34146 -+
34147 -+ let new_attr_non_blocking = MqAttr::new(MQ_OFlag::O_NONBLOCK.bits() as c_long, 10, MSG_SIZE, 0);
34148 -+ mq_setattr(mqd, &new_attr_non_blocking).unwrap();
34149 -+ let new_attr_get = mq_getattr(mqd).unwrap();
34150 -+
34151 -+ // now the O_NONBLOCK flag has been set
34152 -+ assert_ne!(new_attr_get, initial_attr);
34153 -+ assert_eq!(new_attr_get, new_attr_non_blocking);
34154 -+ mq_close(mqd).unwrap();
34155 -+}
34156 -+
34157 -+// FIXME: Fix failures for mips in QEMU
34158 -+#[test]
34159 -+#[cfg(not(any(target_os = "netbsd")))]
34160 -+#[cfg_attr(any(target_arch = "mips", target_arch = "mips64"), ignore)]
34161 -+fn test_mq_set_nonblocking() {
34162 -+ use nix::mqueue::{mq_getattr, mq_set_nonblock, mq_remove_nonblock};
34163 -+ const MSG_SIZE: c_long = 32;
34164 -+ let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0);
34165 -+ let mq_name = &CString::new(b"/attr_test_get_attr".as_ref()).unwrap();
34166 -+ let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
34167 -+ let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
34168 -+ let r = mq_open(mq_name, oflag, mode, Some(&initial_attr));
34169 -+ if let Err(Sys(ENOSYS)) = r {
34170 -+ println!("message queues not supported or module not loaded?");
34171 -+ return;
34172 -+ };
34173 -+ let mqd = r.unwrap();
34174 -+ mq_set_nonblock(mqd).unwrap();
34175 -+ let new_attr = mq_getattr(mqd);
34176 -+ assert!(new_attr.unwrap().flags() == MQ_OFlag::O_NONBLOCK.bits() as c_long);
34177 -+ mq_remove_nonblock(mqd).unwrap();
34178 -+ let new_attr = mq_getattr(mqd);
34179 -+ assert!(new_attr.unwrap().flags() == 0);
34180 -+ mq_close(mqd).unwrap();
34181 -+}
34182 -+
34183 -+#[test]
34184 -+#[cfg(not(any(target_os = "netbsd")))]
34185 -+fn test_mq_unlink() {
34186 -+ use nix::mqueue::mq_unlink;
34187 -+ const MSG_SIZE: c_long = 32;
34188 -+ let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0);
34189 -+ let mq_name_opened = &CString::new(b"/mq_unlink_test".as_ref()).unwrap();
34190 -+ let mq_name_not_opened = &CString::new(b"/mq_unlink_test".as_ref()).unwrap();
34191 -+ let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
34192 -+ let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
34193 -+ let r = mq_open(mq_name_opened, oflag, mode, Some(&initial_attr));
34194 -+ if let Err(Sys(ENOSYS)) = r {
34195 -+ println!("message queues not supported or module not loaded?");
34196 -+ return;
34197 -+ };
34198 -+ let mqd = r.unwrap();
34199 -+
34200 -+ let res_unlink = mq_unlink(mq_name_opened);
34201 -+ assert!(res_unlink == Ok(()) );
34202 -+
34203 -+ let res_unlink_not_opened = mq_unlink(mq_name_not_opened);
34204 -+ assert!(res_unlink_not_opened == Err(Sys(ENOENT)) );
34205 -+
34206 -+ mq_close(mqd).unwrap();
34207 -+ let res_unlink_after_close = mq_unlink(mq_name_opened);
34208 -+ assert!(res_unlink_after_close == Err(Sys(ENOENT)) );
34209 -+}
34210 -diff --git a/third_party/rust/nix-0.15.0/test/test_net.rs b/third_party/rust/nix-0.15.0/test/test_net.rs
34211 -new file mode 100644
34212 -index 0000000000000..b8940e718bdf3
34213 ---- /dev/null
34214 -+++ b/third_party/rust/nix-0.15.0/test/test_net.rs
34215 -@@ -0,0 +1,12 @@
34216 -+use nix::net::if_::*;
34217 -+
34218 -+#[cfg(any(target_os = "android", target_os = "linux"))]
34219 -+const LOOPBACK: &[u8] = b"lo";
34220 -+
34221 -+#[cfg(not(any(target_os = "android", target_os = "linux")))]
34222 -+const LOOPBACK: &[u8] = b"lo0";
34223 -+
34224 -+#[test]
34225 -+fn test_if_nametoindex() {
34226 -+ assert!(if_nametoindex(&LOOPBACK[..]).is_ok());
34227 -+}
34228 -diff --git a/third_party/rust/nix-0.15.0/test/test_nix_path.rs b/third_party/rust/nix-0.15.0/test/test_nix_path.rs
34229 -new file mode 100644
34230 -index 0000000000000..e69de29bb2d1d
34231 -diff --git a/third_party/rust/nix-0.15.0/test/test_poll.rs b/third_party/rust/nix-0.15.0/test/test_poll.rs
34232 -new file mode 100644
34233 -index 0000000000000..aef40e4792b5a
34234 ---- /dev/null
34235 -+++ b/third_party/rust/nix-0.15.0/test/test_poll.rs
34236 -@@ -0,0 +1,50 @@
34237 -+use nix::poll::{PollFlags, poll, PollFd};
34238 -+use nix::unistd::{write, pipe};
34239 -+
34240 -+#[test]
34241 -+fn test_poll() {
34242 -+ let (r, w) = pipe().unwrap();
34243 -+ let mut fds = [PollFd::new(r, PollFlags::POLLIN)];
34244 -+
34245 -+ // Poll an idle pipe. Should timeout
34246 -+ let nfds = poll(&mut fds, 100).unwrap();
34247 -+ assert_eq!(nfds, 0);
34248 -+ assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN));
34249 -+
34250 -+ write(w, b".").unwrap();
34251 -+
34252 -+ // Poll a readable pipe. Should return an event.
34253 -+ let nfds = poll(&mut fds, 100).unwrap();
34254 -+ assert_eq!(nfds, 1);
34255 -+ assert!(fds[0].revents().unwrap().contains(PollFlags::POLLIN));
34256 -+}
34257 -+
34258 -+// ppoll(2) is the same as poll except for how it handles timeouts and signals.
34259 -+// Repeating the test for poll(2) should be sufficient to check that our
34260 -+// bindings are correct.
34261 -+#[cfg(any(target_os = "android",
34262 -+ target_os = "dragonfly",
34263 -+ target_os = "freebsd",
34264 -+ target_os = "linux"))]
34265 -+#[test]
34266 -+fn test_ppoll() {
34267 -+ use nix::poll::ppoll;
34268 -+ use nix::sys::signal::SigSet;
34269 -+ use nix::sys::time::{TimeSpec, TimeValLike};
34270 -+
34271 -+ let timeout = TimeSpec::milliseconds(1);
34272 -+ let (r, w) = pipe().unwrap();
34273 -+ let mut fds = [PollFd::new(r, PollFlags::POLLIN)];
34274 -+
34275 -+ // Poll an idle pipe. Should timeout
34276 -+ let nfds = ppoll(&mut fds, timeout, SigSet::empty()).unwrap();
34277 -+ assert_eq!(nfds, 0);
34278 -+ assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN));
34279 -+
34280 -+ write(w, b".").unwrap();
34281 -+
34282 -+ // Poll a readable pipe. Should return an event.
34283 -+ let nfds = ppoll(&mut fds, timeout, SigSet::empty()).unwrap();
34284 -+ assert_eq!(nfds, 1);
34285 -+ assert!(fds[0].revents().unwrap().contains(PollFlags::POLLIN));
34286 -+}
34287 -diff --git a/third_party/rust/nix-0.15.0/test/test_pty.rs b/third_party/rust/nix-0.15.0/test/test_pty.rs
34288 -new file mode 100644
34289 -index 0000000000000..476b15c10128c
34290 ---- /dev/null
34291 -+++ b/third_party/rust/nix-0.15.0/test/test_pty.rs
34292 -@@ -0,0 +1,235 @@
34293 -+use std::io::Write;
34294 -+use std::path::Path;
34295 -+use std::os::unix::prelude::*;
34296 -+use tempfile::tempfile;
34297 -+
34298 -+use libc::{_exit, STDOUT_FILENO};
34299 -+use nix::fcntl::{OFlag, open};
34300 -+use nix::pty::*;
34301 -+use nix::sys::stat;
34302 -+use nix::sys::termios::*;
34303 -+use nix::unistd::{write, close, pause};
34304 -+
34305 -+/// Regression test for Issue #659
34306 -+/// This is the correct way to explicitly close a `PtyMaster`
34307 -+#[test]
34308 -+fn test_explicit_close() {
34309 -+ let mut f = {
34310 -+ let m = posix_openpt(OFlag::O_RDWR).unwrap();
34311 -+ close(m.into_raw_fd()).unwrap();
34312 -+ tempfile().unwrap()
34313 -+ };
34314 -+ // This should work. But if there's been a double close, then it will
34315 -+ // return EBADF
34316 -+ f.write_all(b"whatever").unwrap();
34317 -+}
34318 -+
34319 -+/// Test equivalence of `ptsname` and `ptsname_r`
34320 -+#[test]
34321 -+#[cfg(any(target_os = "android", target_os = "linux"))]
34322 -+fn test_ptsname_equivalence() {
34323 -+ let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
34324 -+
34325 -+ // Open a new PTTY master
34326 -+ let master_fd = posix_openpt(OFlag::O_RDWR).unwrap();
34327 -+ assert!(master_fd.as_raw_fd() > 0);
34328 -+
34329 -+ // Get the name of the slave
34330 -+ let slave_name = unsafe { ptsname(&master_fd) }.unwrap() ;
34331 -+ let slave_name_r = ptsname_r(&master_fd).unwrap();
34332 -+ assert_eq!(slave_name, slave_name_r);
34333 -+}
34334 -+
34335 -+/// Test data copying of `ptsname`
34336 -+// TODO need to run in a subprocess, since ptsname is non-reentrant
34337 -+#[test]
34338 -+#[cfg(any(target_os = "android", target_os = "linux"))]
34339 -+fn test_ptsname_copy() {
34340 -+ let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
34341 -+
34342 -+ // Open a new PTTY master
34343 -+ let master_fd = posix_openpt(OFlag::O_RDWR).unwrap();
34344 -+ assert!(master_fd.as_raw_fd() > 0);
34345 -+
34346 -+ // Get the name of the slave
34347 -+ let slave_name1 = unsafe { ptsname(&master_fd) }.unwrap();
34348 -+ let slave_name2 = unsafe { ptsname(&master_fd) }.unwrap();
34349 -+ assert!(slave_name1 == slave_name2);
34350 -+ // Also make sure that the string was actually copied and they point to different parts of
34351 -+ // memory.
34352 -+ assert!(slave_name1.as_ptr() != slave_name2.as_ptr());
34353 -+}
34354 -+
34355 -+/// Test data copying of `ptsname_r`
34356 -+#[test]
34357 -+#[cfg(any(target_os = "android", target_os = "linux"))]
34358 -+fn test_ptsname_r_copy() {
34359 -+ // Open a new PTTY master
34360 -+ let master_fd = posix_openpt(OFlag::O_RDWR).unwrap();
34361 -+ assert!(master_fd.as_raw_fd() > 0);
34362 -+
34363 -+ // Get the name of the slave
34364 -+ let slave_name1 = ptsname_r(&master_fd).unwrap();
34365 -+ let slave_name2 = ptsname_r(&master_fd).unwrap();
34366 -+ assert!(slave_name1 == slave_name2);
34367 -+ assert!(slave_name1.as_ptr() != slave_name2.as_ptr());
34368 -+}
34369 -+
34370 -+/// Test that `ptsname` returns different names for different devices
34371 -+#[test]
34372 -+#[cfg(any(target_os = "android", target_os = "linux"))]
34373 -+fn test_ptsname_unique() {
34374 -+ let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
34375 -+
34376 -+ // Open a new PTTY master
34377 -+ let master1_fd = posix_openpt(OFlag::O_RDWR).unwrap();
34378 -+ assert!(master1_fd.as_raw_fd() > 0);
34379 -+
34380 -+ // Open a second PTTY master
34381 -+ let master2_fd = posix_openpt(OFlag::O_RDWR).unwrap();
34382 -+ assert!(master2_fd.as_raw_fd() > 0);
34383 -+
34384 -+ // Get the name of the slave
34385 -+ let slave_name1 = unsafe { ptsname(&master1_fd) }.unwrap();
34386 -+ let slave_name2 = unsafe { ptsname(&master2_fd) }.unwrap();
34387 -+ assert!(slave_name1 != slave_name2);
34388 -+}
34389 -+
34390 -+/// Test opening a master/slave PTTY pair
34391 -+///
34392 -+/// This is a single larger test because much of these functions aren't useful by themselves. So for
34393 -+/// this test we perform the basic act of getting a file handle for a connect master/slave PTTY
34394 -+/// pair.
34395 -+#[test]
34396 -+fn test_open_ptty_pair() {
34397 -+ let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
34398 -+
34399 -+ // Open a new PTTY master
34400 -+ let master_fd = posix_openpt(OFlag::O_RDWR).expect("posix_openpt failed");
34401 -+ assert!(master_fd.as_raw_fd() > 0);
34402 -+
34403 -+ // Allow a slave to be generated for it
34404 -+ grantpt(&master_fd).expect("grantpt failed");
34405 -+ unlockpt(&master_fd).expect("unlockpt failed");
34406 -+
34407 -+ // Get the name of the slave
34408 -+ let slave_name = unsafe { ptsname(&master_fd) }.expect("ptsname failed");
34409 -+
34410 -+ // Open the slave device
34411 -+ let slave_fd = open(Path::new(&slave_name), OFlag::O_RDWR, stat::Mode::empty()).unwrap();
34412 -+ assert!(slave_fd > 0);
34413 -+}
34414 -+
34415 -+#[test]
34416 -+fn test_openpty() {
34417 -+ // openpty uses ptname(3) internally
34418 -+ let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
34419 -+
34420 -+ let pty = openpty(None, None).unwrap();
34421 -+ assert!(pty.master > 0);
34422 -+ assert!(pty.slave > 0);
34423 -+
34424 -+ // Writing to one should be readable on the other one
34425 -+ let string = "foofoofoo\n";
34426 -+ let mut buf = [0u8; 10];
34427 -+ write(pty.master, string.as_bytes()).unwrap();
34428 -+ ::read_exact(pty.slave, &mut buf);
34429 -+
34430 -+ assert_eq!(&buf, string.as_bytes());
34431 -+
34432 -+ // Read the echo as well
34433 -+ let echoed_string = "foofoofoo\r\n";
34434 -+ let mut buf = [0u8; 11];
34435 -+ ::read_exact(pty.master, &mut buf);
34436 -+ assert_eq!(&buf, echoed_string.as_bytes());
34437 -+
34438 -+ let string2 = "barbarbarbar\n";
34439 -+ let echoed_string2 = "barbarbarbar\r\n";
34440 -+ let mut buf = [0u8; 14];
34441 -+ write(pty.slave, string2.as_bytes()).unwrap();
34442 -+ ::read_exact(pty.master, &mut buf);
34443 -+
34444 -+ assert_eq!(&buf, echoed_string2.as_bytes());
34445 -+
34446 -+ close(pty.master).unwrap();
34447 -+ close(pty.slave).unwrap();
34448 -+}
34449 -+
34450 -+#[test]
34451 -+fn test_openpty_with_termios() {
34452 -+ // openpty uses ptname(3) internally
34453 -+ let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
34454 -+
34455 -+ // Open one pty to get attributes for the second one
34456 -+ let mut termios = {
34457 -+ let pty = openpty(None, None).unwrap();
34458 -+ assert!(pty.master > 0);
34459 -+ assert!(pty.slave > 0);
34460 -+ let termios = tcgetattr(pty.master).unwrap();
34461 -+ close(pty.master).unwrap();
34462 -+ close(pty.slave).unwrap();
34463 -+ termios
34464 -+ };
34465 -+ // Make sure newlines are not transformed so the data is preserved when sent.
34466 -+ termios.output_flags.remove(OutputFlags::ONLCR);
34467 -+
34468 -+ let pty = openpty(None, &termios).unwrap();
34469 -+ // Must be valid file descriptors
34470 -+ assert!(pty.master > 0);
34471 -+ assert!(pty.slave > 0);
34472 -+
34473 -+ // Writing to one should be readable on the other one
34474 -+ let string = "foofoofoo\n";
34475 -+ let mut buf = [0u8; 10];
34476 -+ write(pty.master, string.as_bytes()).unwrap();
34477 -+ ::read_exact(pty.slave, &mut buf);
34478 -+
34479 -+ assert_eq!(&buf, string.as_bytes());
34480 -+
34481 -+ // read the echo as well
34482 -+ let echoed_string = "foofoofoo\n";
34483 -+ ::read_exact(pty.master, &mut buf);
34484 -+ assert_eq!(&buf, echoed_string.as_bytes());
34485 -+
34486 -+ let string2 = "barbarbarbar\n";
34487 -+ let echoed_string2 = "barbarbarbar\n";
34488 -+ let mut buf = [0u8; 13];
34489 -+ write(pty.slave, string2.as_bytes()).unwrap();
34490 -+ ::read_exact(pty.master, &mut buf);
34491 -+
34492 -+ assert_eq!(&buf, echoed_string2.as_bytes());
34493 -+
34494 -+ close(pty.master).unwrap();
34495 -+ close(pty.slave).unwrap();
34496 -+}
34497 -+
34498 -+#[test]
34499 -+fn test_forkpty() {
34500 -+ use nix::unistd::ForkResult::*;
34501 -+ use nix::sys::signal::*;
34502 -+ use nix::sys::wait::wait;
34503 -+ // forkpty calls openpty which uses ptname(3) internally.
34504 -+ let _m0 = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
34505 -+ // forkpty spawns a child process
34506 -+ let _m1 = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
34507 -+
34508 -+ let string = "naninani\n";
34509 -+ let echoed_string = "naninani\r\n";
34510 -+ let pty = forkpty(None, None).unwrap();
34511 -+ match pty.fork_result {
34512 -+ Child => {
34513 -+ write(STDOUT_FILENO, string.as_bytes()).unwrap();
34514 -+ pause(); // we need the child to stay alive until the parent calls read
34515 -+ unsafe { _exit(0); }
34516 -+ },
34517 -+ Parent { child } => {
34518 -+ let mut buf = [0u8; 10];
34519 -+ assert!(child.as_raw() > 0);
34520 -+ ::read_exact(pty.master, &mut buf);
34521 -+ kill(child, SIGTERM).unwrap();
34522 -+ wait().unwrap(); // keep other tests using generic wait from getting our child
34523 -+ assert_eq!(&buf, echoed_string.as_bytes());
34524 -+ close(pty.master).unwrap();
34525 -+ },
34526 -+ }
34527 -+}
34528 -diff --git a/third_party/rust/nix-0.15.0/test/test_ptymaster_drop.rs b/third_party/rust/nix-0.15.0/test/test_ptymaster_drop.rs
34529 -new file mode 100644
34530 -index 0000000000000..9b59d66435ed0
34531 ---- /dev/null
34532 -+++ b/third_party/rust/nix-0.15.0/test/test_ptymaster_drop.rs
34533 -@@ -0,0 +1,21 @@
34534 -+extern crate nix;
34535 -+
34536 -+use nix::fcntl::OFlag;
34537 -+use nix::pty::*;
34538 -+use nix::unistd::close;
34539 -+use std::os::unix::io::AsRawFd;
34540 -+
34541 -+/// Regression test for Issue #659
34542 -+/// `PtyMaster` should panic rather than double close the file descriptor
34543 -+/// This must run in its own test process because it deliberately creates a race
34544 -+/// condition.
34545 -+#[test]
34546 -+#[should_panic(expected = "Closing an invalid file descriptor!")]
34547 -+// In Travis on i686-unknown-linux-musl, this test gets SIGABRT. I don't know
34548 -+// why. It doesn't happen on any other target, and it doesn't happen on my PC.
34549 -+#[cfg_attr(all(target_env = "musl", target_arch = "x86"), ignore)]
34550 -+fn test_double_close() {
34551 -+ let m = posix_openpt(OFlag::O_RDWR).unwrap();
34552 -+ close(m.as_raw_fd()).unwrap();
34553 -+ drop(m); // should panic here
34554 -+}
34555 -diff --git a/third_party/rust/nix-0.15.0/test/test_sendfile.rs b/third_party/rust/nix-0.15.0/test/test_sendfile.rs
34556 -new file mode 100644
34557 -index 0000000000000..3bc7932f4c84f
34558 ---- /dev/null
34559 -+++ b/third_party/rust/nix-0.15.0/test/test_sendfile.rs
34560 -@@ -0,0 +1,129 @@
34561 -+use std::io::prelude::*;
34562 -+use std::os::unix::prelude::*;
34563 -+
34564 -+use libc::off_t;
34565 -+use nix::sys::sendfile::*;
34566 -+use tempfile::tempfile;
34567 -+
34568 -+cfg_if! {
34569 -+ if #[cfg(any(target_os = "android", target_os = "linux"))] {
34570 -+ use nix::unistd::{close, pipe, read};
34571 -+ } else if #[cfg(any(target_os = "freebsd", target_os = "ios", target_os = "macos"))] {
34572 -+ use std::net::Shutdown;
34573 -+ use std::os::unix::net::UnixStream;
34574 -+ }
34575 -+}
34576 -+
34577 -+#[cfg(any(target_os = "android", target_os = "linux"))]
34578 -+#[test]
34579 -+fn test_sendfile_linux() {
34580 -+ const CONTENTS: &[u8] = b"abcdef123456";
34581 -+ let mut tmp = tempfile().unwrap();
34582 -+ tmp.write_all(CONTENTS).unwrap();
34583 -+
34584 -+ let (rd, wr) = pipe().unwrap();
34585 -+ let mut offset: off_t = 5;
34586 -+ let res = sendfile(wr, tmp.as_raw_fd(), Some(&mut offset), 2).unwrap();
34587 -+
34588 -+ assert_eq!(2, res);
34589 -+
34590 -+ let mut buf = [0u8; 1024];
34591 -+ assert_eq!(2, read(rd, &mut buf).unwrap());
34592 -+ assert_eq!(b"f1", &buf[0..2]);
34593 -+ assert_eq!(7, offset);
34594 -+
34595 -+ close(rd).unwrap();
34596 -+ close(wr).unwrap();
34597 -+}
34598 -+
34599 -+#[cfg(target_os = "freebsd")]
34600 -+#[test]
34601 -+fn test_sendfile_freebsd() {
34602 -+ // Declare the content
34603 -+ let header_strings = vec!["HTTP/1.1 200 OK\n", "Content-Type: text/plain\n", "\n"];
34604 -+ let body = "Xabcdef123456";
34605 -+ let body_offset = 1;
34606 -+ let trailer_strings = vec!["\n", "Served by Make Believe\n"];
34607 -+
34608 -+ // Write the body to a file
34609 -+ let mut tmp = tempfile().unwrap();
34610 -+ tmp.write_all(body.as_bytes()).unwrap();
34611 -+
34612 -+ // Prepare headers and trailers for sendfile
34613 -+ let headers: Vec<&[u8]> = header_strings.iter().map(|s| s.as_bytes()).collect();
34614 -+ let trailers: Vec<&[u8]> = trailer_strings.iter().map(|s| s.as_bytes()).collect();
34615 -+
34616 -+ // Prepare socket pair
34617 -+ let (mut rd, wr) = UnixStream::pair().unwrap();
34618 -+
34619 -+ // Call the test method
34620 -+ let (res, bytes_written) = sendfile(
34621 -+ tmp.as_raw_fd(),
34622 -+ wr.as_raw_fd(),
34623 -+ body_offset as off_t,
34624 -+ None,
34625 -+ Some(headers.as_slice()),
34626 -+ Some(trailers.as_slice()),
34627 -+ SfFlags::empty(),
34628 -+ 0,
34629 -+ );
34630 -+ assert!(res.is_ok());
34631 -+ wr.shutdown(Shutdown::Both).unwrap();
34632 -+
34633 -+ // Prepare the expected result
34634 -+ let expected_string =
34635 -+ header_strings.concat() + &body[body_offset..] + &trailer_strings.concat();
34636 -+
34637 -+ // Verify the message that was sent
34638 -+ assert_eq!(bytes_written as usize, expected_string.as_bytes().len());
34639 -+
34640 -+ let mut read_string = String::new();
34641 -+ let bytes_read = rd.read_to_string(&mut read_string).unwrap();
34642 -+ assert_eq!(bytes_written as usize, bytes_read);
34643 -+ assert_eq!(expected_string, read_string);
34644 -+}
34645 -+
34646 -+#[cfg(any(target_os = "ios", target_os = "macos"))]
34647 -+#[test]
34648 -+fn test_sendfile_darwin() {
34649 -+ // Declare the content
34650 -+ let header_strings = vec!["HTTP/1.1 200 OK\n", "Content-Type: text/plain\n", "\n"];
34651 -+ let body = "Xabcdef123456";
34652 -+ let body_offset = 1;
34653 -+ let trailer_strings = vec!["\n", "Served by Make Believe\n"];
34654 -+
34655 -+ // Write the body to a file
34656 -+ let mut tmp = tempfile().unwrap();
34657 -+ tmp.write_all(body.as_bytes()).unwrap();
34658 -+
34659 -+ // Prepare headers and trailers for sendfile
34660 -+ let headers: Vec<&[u8]> = header_strings.iter().map(|s| s.as_bytes()).collect();
34661 -+ let trailers: Vec<&[u8]> = trailer_strings.iter().map(|s| s.as_bytes()).collect();
34662 -+
34663 -+ // Prepare socket pair
34664 -+ let (mut rd, wr) = UnixStream::pair().unwrap();
34665 -+
34666 -+ // Call the test method
34667 -+ let (res, bytes_written) = sendfile(
34668 -+ tmp.as_raw_fd(),
34669 -+ wr.as_raw_fd(),
34670 -+ body_offset as off_t,
34671 -+ None,
34672 -+ Some(headers.as_slice()),
34673 -+ Some(trailers.as_slice()),
34674 -+ );
34675 -+ assert!(res.is_ok());
34676 -+ wr.shutdown(Shutdown::Both).unwrap();
34677 -+
34678 -+ // Prepare the expected result
34679 -+ let expected_string =
34680 -+ header_strings.concat() + &body[body_offset..] + &trailer_strings.concat();
34681 -+
34682 -+ // Verify the message that was sent
34683 -+ assert_eq!(bytes_written as usize, expected_string.as_bytes().len());
34684 -+
34685 -+ let mut read_string = String::new();
34686 -+ let bytes_read = rd.read_to_string(&mut read_string).unwrap();
34687 -+ assert_eq!(bytes_written as usize, bytes_read);
34688 -+ assert_eq!(expected_string, read_string);
34689 -+}
34690 -diff --git a/third_party/rust/nix-0.15.0/test/test_stat.rs b/third_party/rust/nix-0.15.0/test/test_stat.rs
34691 -new file mode 100644
34692 -index 0000000000000..1173455fae8db
34693 ---- /dev/null
34694 -+++ b/third_party/rust/nix-0.15.0/test/test_stat.rs
34695 -@@ -0,0 +1,296 @@
34696 -+use std::fs::{self, File};
34697 -+use std::os::unix::fs::{symlink, PermissionsExt};
34698 -+use std::os::unix::prelude::AsRawFd;
34699 -+use std::time::{Duration, UNIX_EPOCH};
34700 -+use std::path::Path;
34701 -+
34702 -+#[cfg(not(any(target_os = "netbsd")))]
34703 -+use libc::{S_IFMT, S_IFLNK, mode_t};
34704 -+
34705 -+use nix::{fcntl, Error};
34706 -+use nix::errno::{Errno};
34707 -+use nix::sys::stat::{self, fchmod, fchmodat, futimens, stat, utimes, utimensat, mkdirat};
34708 -+#[cfg(any(target_os = "linux",
34709 -+ target_os = "haiku",
34710 -+ target_os = "ios",
34711 -+ target_os = "macos",
34712 -+ target_os = "freebsd",
34713 -+ target_os = "netbsd"))]
34714 -+use nix::sys::stat::lutimes;
34715 -+use nix::sys::stat::{Mode, FchmodatFlags, UtimensatFlags};
34716 -+
34717 -+#[cfg(not(any(target_os = "netbsd")))]
34718 -+use nix::sys::stat::FileStat;
34719 -+
34720 -+use nix::sys::time::{TimeSpec, TimeVal, TimeValLike};
34721 -+use nix::unistd::chdir;
34722 -+
34723 -+#[cfg(not(any(target_os = "netbsd")))]
34724 -+use nix::Result;
34725 -+use tempfile;
34726 -+
34727 -+#[allow(unused_comparisons)]
34728 -+// uid and gid are signed on Windows, but not on other platforms. This function
34729 -+// allows warning free compiles on all platforms, and can be removed when
34730 -+// expression-level #[allow] is available.
34731 -+#[cfg(not(any(target_os = "netbsd")))]
34732 -+fn valid_uid_gid(stat: FileStat) -> bool {
34733 -+ // uid could be 0 for the `root` user. This quite possible when
34734 -+ // the tests are being run on a rooted Android device.
34735 -+ stat.st_uid >= 0 && stat.st_gid >= 0
34736 -+}
34737 -+
34738 -+#[cfg(not(any(target_os = "netbsd")))]
34739 -+fn assert_stat_results(stat_result: Result<FileStat>) {
34740 -+ let stats = stat_result.expect("stat call failed");
34741 -+ assert!(stats.st_dev > 0); // must be positive integer, exact number machine dependent
34742 -+ assert!(stats.st_ino > 0); // inode is positive integer, exact number machine dependent
34743 -+ assert!(stats.st_mode > 0); // must be positive integer
34744 -+ assert!(stats.st_nlink == 1); // there links created, must be 1
34745 -+ assert!(valid_uid_gid(stats)); // must be positive integers
34746 -+ assert!(stats.st_size == 0); // size is 0 because we did not write anything to the file
34747 -+ assert!(stats.st_blksize > 0); // must be positive integer, exact number machine dependent
34748 -+ assert!(stats.st_blocks <= 16); // Up to 16 blocks can be allocated for a blank file
34749 -+}
34750 -+
34751 -+#[cfg(not(any(target_os = "netbsd")))]
34752 -+fn assert_lstat_results(stat_result: Result<FileStat>) {
34753 -+ let stats = stat_result.expect("stat call failed");
34754 -+ assert!(stats.st_dev > 0); // must be positive integer, exact number machine dependent
34755 -+ assert!(stats.st_ino > 0); // inode is positive integer, exact number machine dependent
34756 -+ assert!(stats.st_mode > 0); // must be positive integer
34757 -+
34758 -+ // st_mode is c_uint (u32 on Android) while S_IFMT is mode_t
34759 -+ // (u16 on Android), and that will be a compile error.
34760 -+ // On other platforms they are the same (either both are u16 or u32).
34761 -+ assert!((stats.st_mode as usize) & (S_IFMT as usize) == S_IFLNK as usize); // should be a link
34762 -+ assert!(stats.st_nlink == 1); // there links created, must be 1
34763 -+ assert!(valid_uid_gid(stats)); // must be positive integers
34764 -+ assert!(stats.st_size > 0); // size is > 0 because it points to another file
34765 -+ assert!(stats.st_blksize > 0); // must be positive integer, exact number machine dependent
34766 -+
34767 -+ // st_blocks depends on whether the machine's file system uses fast
34768 -+ // or slow symlinks, so just make sure it's not negative
34769 -+ // (Android's st_blocks is ulonglong which is always non-negative.)
34770 -+ assert!(stats.st_blocks >= 0);
34771 -+}
34772 -+
34773 -+#[test]
34774 -+#[cfg(not(any(target_os = "netbsd")))]
34775 -+fn test_stat_and_fstat() {
34776 -+ use nix::sys::stat::fstat;
34777 -+
34778 -+ let tempdir = tempfile::tempdir().unwrap();
34779 -+ let filename = tempdir.path().join("foo.txt");
34780 -+ let file = File::create(&filename).unwrap();
34781 -+
34782 -+ let stat_result = stat(&filename);
34783 -+ assert_stat_results(stat_result);
34784 -+
34785 -+ let fstat_result = fstat(file.as_raw_fd());
34786 -+ assert_stat_results(fstat_result);
34787 -+}
34788 -+
34789 -+#[test]
34790 -+#[cfg(not(any(target_os = "netbsd")))]
34791 -+fn test_fstatat() {
34792 -+ let tempdir = tempfile::tempdir().unwrap();
34793 -+ let filename = tempdir.path().join("foo.txt");
34794 -+ File::create(&filename).unwrap();
34795 -+ let dirfd = fcntl::open(tempdir.path(),
34796 -+ fcntl::OFlag::empty(),
34797 -+ stat::Mode::empty());
34798 -+
34799 -+ let result = stat::fstatat(dirfd.unwrap(),
34800 -+ &filename,
34801 -+ fcntl::AtFlags::empty());
34802 -+ assert_stat_results(result);
34803 -+}
34804 -+
34805 -+#[test]
34806 -+#[cfg(not(any(target_os = "netbsd")))]
34807 -+fn test_stat_fstat_lstat() {
34808 -+ use nix::sys::stat::{fstat, lstat};
34809 -+
34810 -+ let tempdir = tempfile::tempdir().unwrap();
34811 -+ let filename = tempdir.path().join("bar.txt");
34812 -+ let linkname = tempdir.path().join("barlink");
34813 -+
34814 -+ File::create(&filename).unwrap();
34815 -+ symlink("bar.txt", &linkname).unwrap();
34816 -+ let link = File::open(&linkname).unwrap();
34817 -+
34818 -+ // should be the same result as calling stat,
34819 -+ // since it's a regular file
34820 -+ let stat_result = stat(&filename);
34821 -+ assert_stat_results(stat_result);
34822 -+
34823 -+ let lstat_result = lstat(&linkname);
34824 -+ assert_lstat_results(lstat_result);
34825 -+
34826 -+ let fstat_result = fstat(link.as_raw_fd());
34827 -+ assert_stat_results(fstat_result);
34828 -+}
34829 -+
34830 -+#[test]
34831 -+fn test_fchmod() {
34832 -+ let tempdir = tempfile::tempdir().unwrap();
34833 -+ let filename = tempdir.path().join("foo.txt");
34834 -+ let file = File::create(&filename).unwrap();
34835 -+
34836 -+ let mut mode1 = Mode::empty();
34837 -+ mode1.insert(Mode::S_IRUSR);
34838 -+ mode1.insert(Mode::S_IWUSR);
34839 -+ fchmod(file.as_raw_fd(), mode1).unwrap();
34840 -+
34841 -+ let file_stat1 = stat(&filename).unwrap();
34842 -+ assert_eq!(file_stat1.st_mode & 0o7777, mode1.bits());
34843 -+
34844 -+ let mut mode2 = Mode::empty();
34845 -+ mode2.insert(Mode::S_IROTH);
34846 -+ fchmod(file.as_raw_fd(), mode2).unwrap();
34847 -+
34848 -+ let file_stat2 = stat(&filename).unwrap();
34849 -+ assert_eq!(file_stat2.st_mode & 0o7777, mode2.bits());
34850 -+}
34851 -+
34852 -+#[test]
34853 -+fn test_fchmodat() {
34854 -+ let _dr = ::DirRestore::new();
34855 -+ let tempdir = tempfile::tempdir().unwrap();
34856 -+ let filename = "foo.txt";
34857 -+ let fullpath = tempdir.path().join(filename);
34858 -+ File::create(&fullpath).unwrap();
34859 -+
34860 -+ let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap();
34861 -+
34862 -+ let mut mode1 = Mode::empty();
34863 -+ mode1.insert(Mode::S_IRUSR);
34864 -+ mode1.insert(Mode::S_IWUSR);
34865 -+ fchmodat(Some(dirfd), filename, mode1, FchmodatFlags::FollowSymlink).unwrap();
34866 -+
34867 -+ let file_stat1 = stat(&fullpath).unwrap();
34868 -+ assert_eq!(file_stat1.st_mode & 0o7777, mode1.bits());
34869 -+
34870 -+ chdir(tempdir.path()).unwrap();
34871 -+
34872 -+ let mut mode2 = Mode::empty();
34873 -+ mode2.insert(Mode::S_IROTH);
34874 -+ fchmodat(None, filename, mode2, FchmodatFlags::FollowSymlink).unwrap();
34875 -+
34876 -+ let file_stat2 = stat(&fullpath).unwrap();
34877 -+ assert_eq!(file_stat2.st_mode & 0o7777, mode2.bits());
34878 -+}
34879 -+
34880 -+/// Asserts that the atime and mtime in a file's metadata match expected values.
34881 -+///
34882 -+/// The atime and mtime are expressed with a resolution of seconds because some file systems
34883 -+/// (like macOS's HFS+) do not have higher granularity.
34884 -+fn assert_times_eq(exp_atime_sec: u64, exp_mtime_sec: u64, attr: &fs::Metadata) {
34885 -+ assert_eq!(
34886 -+ Duration::new(exp_atime_sec, 0),
34887 -+ attr.accessed().unwrap().duration_since(UNIX_EPOCH).unwrap());
34888 -+ assert_eq!(
34889 -+ Duration::new(exp_mtime_sec, 0),
34890 -+ attr.modified().unwrap().duration_since(UNIX_EPOCH).unwrap());
34891 -+}
34892 -+
34893 -+#[test]
34894 -+fn test_utimes() {
34895 -+ let tempdir = tempfile::tempdir().unwrap();
34896 -+ let fullpath = tempdir.path().join("file");
34897 -+ drop(File::create(&fullpath).unwrap());
34898 -+
34899 -+ utimes(&fullpath, &TimeVal::seconds(9990), &TimeVal::seconds(5550)).unwrap();
34900 -+ assert_times_eq(9990, 5550, &fs::metadata(&fullpath).unwrap());
34901 -+}
34902 -+
34903 -+#[test]
34904 -+#[cfg(any(target_os = "linux",
34905 -+ target_os = "haiku",
34906 -+ target_os = "ios",
34907 -+ target_os = "macos",
34908 -+ target_os = "freebsd",
34909 -+ target_os = "netbsd"))]
34910 -+fn test_lutimes() {
34911 -+ let tempdir = tempfile::tempdir().unwrap();
34912 -+ let target = tempdir.path().join("target");
34913 -+ let fullpath = tempdir.path().join("symlink");
34914 -+ drop(File::create(&target).unwrap());
34915 -+ symlink(&target, &fullpath).unwrap();
34916 -+
34917 -+ let exp_target_metadata = fs::symlink_metadata(&target).unwrap();
34918 -+ lutimes(&fullpath, &TimeVal::seconds(4560), &TimeVal::seconds(1230)).unwrap();
34919 -+ assert_times_eq(4560, 1230, &fs::symlink_metadata(&fullpath).unwrap());
34920 -+
34921 -+ let target_metadata = fs::symlink_metadata(&target).unwrap();
34922 -+ assert_eq!(exp_target_metadata.accessed().unwrap(), target_metadata.accessed().unwrap(),
34923 -+ "atime of symlink target was unexpectedly modified");
34924 -+ assert_eq!(exp_target_metadata.modified().unwrap(), target_metadata.modified().unwrap(),
34925 -+ "mtime of symlink target was unexpectedly modified");
34926 -+}
34927 -+
34928 -+#[test]
34929 -+fn test_futimens() {
34930 -+ let tempdir = tempfile::tempdir().unwrap();
34931 -+ let fullpath = tempdir.path().join("file");
34932 -+ drop(File::create(&fullpath).unwrap());
34933 -+
34934 -+ let fd = fcntl::open(&fullpath, fcntl::OFlag::empty(), stat::Mode::empty()).unwrap();
34935 -+
34936 -+ futimens(fd, &TimeSpec::seconds(10), &TimeSpec::seconds(20)).unwrap();
34937 -+ assert_times_eq(10, 20, &fs::metadata(&fullpath).unwrap());
34938 -+}
34939 -+
34940 -+#[test]
34941 -+fn test_utimensat() {
34942 -+ let _dr = ::DirRestore::new();
34943 -+ let tempdir = tempfile::tempdir().unwrap();
34944 -+ let filename = "foo.txt";
34945 -+ let fullpath = tempdir.path().join(filename);
34946 -+ drop(File::create(&fullpath).unwrap());
34947 -+
34948 -+ let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap();
34949 -+
34950 -+ utimensat(Some(dirfd), filename, &TimeSpec::seconds(12345), &TimeSpec::seconds(678),
34951 -+ UtimensatFlags::FollowSymlink).unwrap();
34952 -+ assert_times_eq(12345, 678, &fs::metadata(&fullpath).unwrap());
34953 -+
34954 -+ chdir(tempdir.path()).unwrap();
34955 -+
34956 -+ utimensat(None, filename, &TimeSpec::seconds(500), &TimeSpec::seconds(800),
34957 -+ UtimensatFlags::FollowSymlink).unwrap();
34958 -+ assert_times_eq(500, 800, &fs::metadata(&fullpath).unwrap());
34959 -+}
34960 -+
34961 -+#[test]
34962 -+fn test_mkdirat_success_path() {
34963 -+ let tempdir = tempfile::tempdir().unwrap();
34964 -+ let filename = "example_subdir";
34965 -+ let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap();
34966 -+ assert!((mkdirat(dirfd, filename, Mode::S_IRWXU)).is_ok());
34967 -+ assert!(Path::exists(&tempdir.path().join(filename)));
34968 -+}
34969 -+
34970 -+#[test]
34971 -+fn test_mkdirat_success_mode() {
34972 -+ let expected_bits = stat::SFlag::S_IFDIR.bits() | stat::Mode::S_IRWXU.bits();
34973 -+ let tempdir = tempfile::tempdir().unwrap();
34974 -+ let filename = "example_subdir";
34975 -+ let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap();
34976 -+ assert!((mkdirat(dirfd, filename, Mode::S_IRWXU)).is_ok());
34977 -+ let permissions = fs::metadata(tempdir.path().join(filename)).unwrap().permissions();
34978 -+ let mode = permissions.mode();
34979 -+ assert_eq!(mode as mode_t, expected_bits)
34980 -+}
34981 -+
34982 -+#[test]
34983 -+fn test_mkdirat_fail() {
34984 -+ let tempdir = tempfile::tempdir().unwrap();
34985 -+ let not_dir_filename= "example_not_dir";
34986 -+ let filename = "example_subdir_dir";
34987 -+ let dirfd = fcntl::open(&tempdir.path().join(not_dir_filename), fcntl::OFlag::O_CREAT,
34988 -+ stat::Mode::empty()).unwrap();
34989 -+ let result = mkdirat(dirfd, filename, Mode::S_IRWXU).unwrap_err();
34990 -+ assert_eq!(result, Error::Sys(Errno::ENOTDIR));
34991 -+}
34992 -diff --git a/third_party/rust/nix-0.15.0/test/test_unistd.rs b/third_party/rust/nix-0.15.0/test/test_unistd.rs
34993 -new file mode 100644
34994 -index 0000000000000..46196dec7ccce
34995 ---- /dev/null
34996 -+++ b/third_party/rust/nix-0.15.0/test/test_unistd.rs
34997 -@@ -0,0 +1,669 @@
34998 -+use nix::fcntl::{self, fcntl, FcntlArg, FdFlag, open, OFlag, readlink};
34999 -+use nix::unistd::*;
35000 -+use nix::unistd::ForkResult::*;
35001 -+use nix::sys::signal::{SaFlags, SigAction, SigHandler, SigSet, Signal, sigaction};
35002 -+use nix::sys::wait::*;
35003 -+use nix::sys::stat::{self, Mode, SFlag};
35004 -+use nix::errno::Errno;
35005 -+use nix::Error;
35006 -+use std::{env, iter};
35007 -+use std::ffi::CString;
35008 -+use std::fs::{self, DirBuilder, File};
35009 -+use std::io::Write;
35010 -+use std::os::unix::prelude::*;
35011 -+use tempfile::{self, tempfile};
35012 -+use libc::{self, _exit, off_t};
35013 -+
35014 -+#[test]
35015 -+#[cfg(not(any(target_os = "netbsd")))]
35016 -+fn test_fork_and_waitpid() {
35017 -+ let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
35018 -+
35019 -+ // Safe: Child only calls `_exit`, which is signal-safe
35020 -+ match fork().expect("Error: Fork Failed") {
35021 -+ Child => unsafe { _exit(0) },
35022 -+ Parent { child } => {
35023 -+ // assert that child was created and pid > 0
35024 -+ let child_raw: ::libc::pid_t = child.into();
35025 -+ assert!(child_raw > 0);
35026 -+ let wait_status = waitpid(child, None);
35027 -+ match wait_status {
35028 -+ // assert that waitpid returned correct status and the pid is the one of the child
35029 -+ Ok(WaitStatus::Exited(pid_t, _)) => assert!(pid_t == child),
35030 -+
35031 -+ // panic, must never happen
35032 -+ s @ Ok(_) => panic!("Child exited {:?}, should never happen", s),
35033 -+
35034 -+ // panic, waitpid should never fail
35035 -+ Err(s) => panic!("Error: waitpid returned Err({:?}", s)
35036 -+ }
35037 -+
35038 -+ },
35039 -+ }
35040 -+}
35041 -+
35042 -+#[test]
35043 -+fn test_wait() {
35044 -+ // Grab FORK_MTX so wait doesn't reap a different test's child process
35045 -+ let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
35046 -+
35047 -+ // Safe: Child only calls `_exit`, which is signal-safe
35048 -+ match fork().expect("Error: Fork Failed") {
35049 -+ Child => unsafe { _exit(0) },
35050 -+ Parent { child } => {
35051 -+ let wait_status = wait();
35052 -+
35053 -+ // just assert that (any) one child returns with WaitStatus::Exited
35054 -+ assert_eq!(wait_status, Ok(WaitStatus::Exited(child, 0)));
35055 -+ },
35056 -+ }
35057 -+}
35058 -+
35059 -+#[test]
35060 -+fn test_mkstemp() {
35061 -+ let mut path = env::temp_dir();
35062 -+ path.push("nix_tempfile.XXXXXX");
35063 -+
35064 -+ let result = mkstemp(&path);
35065 -+ match result {
35066 -+ Ok((fd, path)) => {
35067 -+ close(fd).unwrap();
35068 -+ unlink(path.as_path()).unwrap();
35069 -+ },
35070 -+ Err(e) => panic!("mkstemp failed: {}", e)
35071 -+ }
35072 -+}
35073 -+
35074 -+#[test]
35075 -+fn test_mkstemp_directory() {
35076 -+ // mkstemp should fail if a directory is given
35077 -+ assert!(mkstemp(&env::temp_dir()).is_err());
35078 -+}
35079 -+
35080 -+#[test]
35081 -+fn test_mkfifo() {
35082 -+ let tempdir = tempfile::tempdir().unwrap();
35083 -+ let mkfifo_fifo = tempdir.path().join("mkfifo_fifo");
35084 -+
35085 -+ mkfifo(&mkfifo_fifo, Mode::S_IRUSR).unwrap();
35086 -+
35087 -+ let stats = stat::stat(&mkfifo_fifo).unwrap();
35088 -+ let typ = stat::SFlag::from_bits_truncate(stats.st_mode);
35089 -+ assert!(typ == SFlag::S_IFIFO);
35090 -+}
35091 -+
35092 -+#[test]
35093 -+fn test_mkfifo_directory() {
35094 -+ // mkfifo should fail if a directory is given
35095 -+ assert!(mkfifo(&env::temp_dir(), Mode::S_IRUSR).is_err());
35096 -+}
35097 -+
35098 -+#[test]
35099 -+fn test_getpid() {
35100 -+ let pid: ::libc::pid_t = getpid().into();
35101 -+ let ppid: ::libc::pid_t = getppid().into();
35102 -+ assert!(pid > 0);
35103 -+ assert!(ppid > 0);
35104 -+}
35105 -+
35106 -+#[test]
35107 -+fn test_getsid() {
35108 -+ let none_sid: ::libc::pid_t = getsid(None).unwrap().into();
35109 -+ let pid_sid: ::libc::pid_t = getsid(Some(getpid())).unwrap().into();
35110 -+ assert!(none_sid > 0);
35111 -+ assert!(none_sid == pid_sid);
35112 -+}
35113 -+
35114 -+#[cfg(any(target_os = "linux", target_os = "android"))]
35115 -+mod linux_android {
35116 -+ use nix::unistd::gettid;
35117 -+
35118 -+ #[test]
35119 -+ fn test_gettid() {
35120 -+ let tid: ::libc::pid_t = gettid().into();
35121 -+ assert!(tid > 0);
35122 -+ }
35123 -+}
35124 -+
35125 -+#[test]
35126 -+// `getgroups()` and `setgroups()` do not behave as expected on Apple platforms
35127 -+#[cfg(not(any(target_os = "ios", target_os = "macos")))]
35128 -+fn test_setgroups() {
35129 -+ // Skip this test when not run as root as `setgroups()` requires root.
35130 -+ skip_if_not_root!("test_setgroups");
35131 -+
35132 -+ let _m = ::GROUPS_MTX.lock().expect("Mutex got poisoned by another test");
35133 -+
35134 -+ // Save the existing groups
35135 -+ let old_groups = getgroups().unwrap();
35136 -+
35137 -+ // Set some new made up groups
35138 -+ let groups = [Gid::from_raw(123), Gid::from_raw(456)];
35139 -+ setgroups(&groups).unwrap();
35140 -+
35141 -+ let new_groups = getgroups().unwrap();
35142 -+ assert_eq!(new_groups, groups);
35143 -+
35144 -+ // Revert back to the old groups
35145 -+ setgroups(&old_groups).unwrap();
35146 -+}
35147 -+
35148 -+#[test]
35149 -+// `getgroups()` and `setgroups()` do not behave as expected on Apple platforms
35150 -+#[cfg(not(any(target_os = "ios", target_os = "macos")))]
35151 -+fn test_initgroups() {
35152 -+ // Skip this test when not run as root as `initgroups()` and `setgroups()`
35153 -+ // require root.
35154 -+ skip_if_not_root!("test_initgroups");
35155 -+
35156 -+ let _m = ::GROUPS_MTX.lock().expect("Mutex got poisoned by another test");
35157 -+
35158 -+ // Save the existing groups
35159 -+ let old_groups = getgroups().unwrap();
35160 -+
35161 -+ // It doesn't matter if the root user is not called "root" or if a user
35162 -+ // called "root" doesn't exist. We are just checking that the extra,
35163 -+ // made-up group, `123`, is set.
35164 -+ // FIXME: Test the other half of initgroups' functionality: whether the
35165 -+ // groups that the user belongs to are also set.
35166 -+ let user = CString::new("root").unwrap();
35167 -+ let group = Gid::from_raw(123);
35168 -+ let group_list = getgrouplist(&user, group).unwrap();
35169 -+ assert!(group_list.contains(&group));
35170 -+
35171 -+ initgroups(&user, group).unwrap();
35172 -+
35173 -+ let new_groups = getgroups().unwrap();
35174 -+ assert_eq!(new_groups, group_list);
35175 -+
35176 -+ // Revert back to the old groups
35177 -+ setgroups(&old_groups).unwrap();
35178 -+}
35179 -+
35180 -+macro_rules! execve_test_factory(
35181 -+ ($test_name:ident, $syscall:ident, $exe: expr $(, $pathname:expr, $flags:expr)*) => (
35182 -+ #[test]
35183 -+ fn $test_name() {
35184 -+ let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
35185 -+ // The `exec`d process will write to `writer`, and we'll read that
35186 -+ // data from `reader`.
35187 -+ let (reader, writer) = pipe().unwrap();
35188 -+
35189 -+ // Safe: Child calls `exit`, `dup`, `close` and the provided `exec*` family function.
35190 -+ // NOTE: Technically, this makes the macro unsafe to use because you could pass anything.
35191 -+ // The tests make sure not to do that, though.
35192 -+ match fork().unwrap() {
35193 -+ Child => {
35194 -+ // Close stdout.
35195 -+ close(1).unwrap();
35196 -+ // Make `writer` be the stdout of the new process.
35197 -+ dup(writer).unwrap();
35198 -+ // exec!
35199 -+ $syscall(
35200 -+ $exe,
35201 -+ $(&CString::new($pathname).unwrap(), )*
35202 -+ &[CString::new(b"".as_ref()).unwrap(),
35203 -+ CString::new(b"-c".as_ref()).unwrap(),
35204 -+ CString::new(b"echo nix!!! && echo foo=$foo && echo baz=$baz"
35205 -+ .as_ref()).unwrap()],
35206 -+ &[CString::new(b"foo=bar".as_ref()).unwrap(),
35207 -+ CString::new(b"baz=quux".as_ref()).unwrap()]
35208 -+ $(, $flags)*).unwrap();
35209 -+ },
35210 -+ Parent { child } => {
35211 -+ // Wait for the child to exit.
35212 -+ waitpid(child, None).unwrap();
35213 -+ // Read 1024 bytes.
35214 -+ let mut buf = [0u8; 1024];
35215 -+ read(reader, &mut buf).unwrap();
35216 -+ // It should contain the things we printed using `/bin/sh`.
35217 -+ let string = String::from_utf8_lossy(&buf);
35218 -+ assert!(string.contains("nix!!!"));
35219 -+ assert!(string.contains("foo=bar"));
35220 -+ assert!(string.contains("baz=quux"));
35221 -+ }
35222 -+ }
35223 -+ }
35224 -+ )
35225 -+);
35226 -+
35227 -+cfg_if!{
35228 -+ if #[cfg(target_os = "android")] {
35229 -+ execve_test_factory!(test_execve, execve, &CString::new("/system/bin/sh").unwrap());
35230 -+ execve_test_factory!(test_fexecve, fexecve, File::open("/system/bin/sh").unwrap().into_raw_fd());
35231 -+ } else if #[cfg(any(target_os = "freebsd",
35232 -+ target_os = "linux"))] {
35233 -+ execve_test_factory!(test_execve, execve, &CString::new("/bin/sh").unwrap());
35234 -+ execve_test_factory!(test_fexecve, fexecve, File::open("/bin/sh").unwrap().into_raw_fd());
35235 -+ } else if #[cfg(any(target_os = "dragonfly",
35236 -+ target_os = "ios",
35237 -+ target_os = "macos",
35238 -+ target_os = "netbsd",
35239 -+ target_os = "openbsd"))] {
35240 -+ execve_test_factory!(test_execve, execve, &CString::new("/bin/sh").unwrap());
35241 -+ // No fexecve() on DragonFly, ios, macos, NetBSD, OpenBSD.
35242 -+ //
35243 -+ // Note for NetBSD and OpenBSD: although rust-lang/libc includes it
35244 -+ // (under unix/bsd/netbsdlike/) fexecve is not currently implemented on
35245 -+ // NetBSD nor on OpenBSD.
35246 -+ }
35247 -+}
35248 -+
35249 -+#[cfg(any(target_os = "haiku", target_os = "linux", target_os = "openbsd"))]
35250 -+execve_test_factory!(test_execvpe, execvpe, &CString::new("sh").unwrap());
35251 -+
35252 -+cfg_if!{
35253 -+ if #[cfg(target_os = "android")] {
35254 -+ use nix::fcntl::AtFlags;
35255 -+ execve_test_factory!(test_execveat_empty, execveat, File::open("/system/bin/sh").unwrap().into_raw_fd(),
35256 -+ "", AtFlags::AT_EMPTY_PATH);
35257 -+ execve_test_factory!(test_execveat_relative, execveat, File::open("/system/bin/").unwrap().into_raw_fd(),
35258 -+ "./sh", AtFlags::empty());
35259 -+ execve_test_factory!(test_execveat_absolute, execveat, File::open("/").unwrap().into_raw_fd(),
35260 -+ "/system/bin/sh", AtFlags::empty());
35261 -+ } else if #[cfg(all(target_os = "linux"), any(target_arch ="x86_64", target_arch ="x86"))] {
35262 -+ use nix::fcntl::AtFlags;
35263 -+ execve_test_factory!(test_execveat_empty, execveat, File::open("/bin/sh").unwrap().into_raw_fd(),
35264 -+ "", AtFlags::AT_EMPTY_PATH);
35265 -+ execve_test_factory!(test_execveat_relative, execveat, File::open("/bin/").unwrap().into_raw_fd(),
35266 -+ "./sh", AtFlags::empty());
35267 -+ execve_test_factory!(test_execveat_absolute, execveat, File::open("/").unwrap().into_raw_fd(),
35268 -+ "/bin/sh", AtFlags::empty());
35269 -+ }
35270 -+}
35271 -+
35272 -+#[test]
35273 -+fn test_fchdir() {
35274 -+ // fchdir changes the process's cwd
35275 -+ let _dr = ::DirRestore::new();
35276 -+
35277 -+ let tmpdir = tempfile::tempdir().unwrap();
35278 -+ let tmpdir_path = tmpdir.path().canonicalize().unwrap();
35279 -+ let tmpdir_fd = File::open(&tmpdir_path).unwrap().into_raw_fd();
35280 -+
35281 -+ assert!(fchdir(tmpdir_fd).is_ok());
35282 -+ assert_eq!(getcwd().unwrap(), tmpdir_path);
35283 -+
35284 -+ assert!(close(tmpdir_fd).is_ok());
35285 -+}
35286 -+
35287 -+#[test]
35288 -+fn test_getcwd() {
35289 -+ // chdir changes the process's cwd
35290 -+ let _dr = ::DirRestore::new();
35291 -+
35292 -+ let tmpdir = tempfile::tempdir().unwrap();
35293 -+ let tmpdir_path = tmpdir.path().canonicalize().unwrap();
35294 -+ assert!(chdir(&tmpdir_path).is_ok());
35295 -+ assert_eq!(getcwd().unwrap(), tmpdir_path);
35296 -+
35297 -+ // make path 500 chars longer so that buffer doubling in getcwd
35298 -+ // kicks in. Note: One path cannot be longer than 255 bytes
35299 -+ // (NAME_MAX) whole path cannot be longer than PATH_MAX (usually
35300 -+ // 4096 on linux, 1024 on macos)
35301 -+ let mut inner_tmp_dir = tmpdir_path.to_path_buf();
35302 -+ for _ in 0..5 {
35303 -+ let newdir = iter::repeat("a").take(100).collect::<String>();
35304 -+ inner_tmp_dir.push(newdir);
35305 -+ assert!(mkdir(inner_tmp_dir.as_path(), Mode::S_IRWXU).is_ok());
35306 -+ }
35307 -+ assert!(chdir(inner_tmp_dir.as_path()).is_ok());
35308 -+ assert_eq!(getcwd().unwrap(), inner_tmp_dir.as_path());
35309 -+}
35310 -+
35311 -+#[test]
35312 -+fn test_chown() {
35313 -+ // Testing for anything other than our own UID/GID is hard.
35314 -+ let uid = Some(getuid());
35315 -+ let gid = Some(getgid());
35316 -+
35317 -+ let tempdir = tempfile::tempdir().unwrap();
35318 -+ let path = tempdir.path().join("file");
35319 -+ {
35320 -+ File::create(&path).unwrap();
35321 -+ }
35322 -+
35323 -+ chown(&path, uid, gid).unwrap();
35324 -+ chown(&path, uid, None).unwrap();
35325 -+ chown(&path, None, gid).unwrap();
35326 -+
35327 -+ fs::remove_file(&path).unwrap();
35328 -+ chown(&path, uid, gid).unwrap_err();
35329 -+}
35330 -+
35331 -+#[test]
35332 -+fn test_fchownat() {
35333 -+ let _dr = ::DirRestore::new();
35334 -+ // Testing for anything other than our own UID/GID is hard.
35335 -+ let uid = Some(getuid());
35336 -+ let gid = Some(getgid());
35337 -+
35338 -+ let tempdir = tempfile::tempdir().unwrap();
35339 -+ let path = tempdir.path().join("file");
35340 -+ {
35341 -+ File::create(&path).unwrap();
35342 -+ }
35343 -+
35344 -+ let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap();
35345 -+
35346 -+ fchownat(Some(dirfd), "file", uid, gid, FchownatFlags::FollowSymlink).unwrap();
35347 -+
35348 -+ chdir(tempdir.path()).unwrap();
35349 -+ fchownat(None, "file", uid, gid, FchownatFlags::FollowSymlink).unwrap();
35350 -+
35351 -+ fs::remove_file(&path).unwrap();
35352 -+ fchownat(None, "file", uid, gid, FchownatFlags::FollowSymlink).unwrap_err();
35353 -+}
35354 -+
35355 -+#[test]
35356 -+fn test_lseek() {
35357 -+ const CONTENTS: &[u8] = b"abcdef123456";
35358 -+ let mut tmp = tempfile().unwrap();
35359 -+ tmp.write_all(CONTENTS).unwrap();
35360 -+ let tmpfd = tmp.into_raw_fd();
35361 -+
35362 -+ let offset: off_t = 5;
35363 -+ lseek(tmpfd, offset, Whence::SeekSet).unwrap();
35364 -+
35365 -+ let mut buf = [0u8; 7];
35366 -+ ::read_exact(tmpfd, &mut buf);
35367 -+ assert_eq!(b"f123456", &buf);
35368 -+
35369 -+ close(tmpfd).unwrap();
35370 -+}
35371 -+
35372 -+#[cfg(any(target_os = "linux", target_os = "android"))]
35373 -+#[test]
35374 -+fn test_lseek64() {
35375 -+ const CONTENTS: &[u8] = b"abcdef123456";
35376 -+ let mut tmp = tempfile().unwrap();
35377 -+ tmp.write_all(CONTENTS).unwrap();
35378 -+ let tmpfd = tmp.into_raw_fd();
35379 -+
35380 -+ lseek64(tmpfd, 5, Whence::SeekSet).unwrap();
35381 -+
35382 -+ let mut buf = [0u8; 7];
35383 -+ ::read_exact(tmpfd, &mut buf);
35384 -+ assert_eq!(b"f123456", &buf);
35385 -+
35386 -+ close(tmpfd).unwrap();
35387 -+}
35388 -+
35389 -+cfg_if!{
35390 -+ if #[cfg(any(target_os = "android", target_os = "linux"))] {
35391 -+ macro_rules! require_acct{
35392 -+ () => {
35393 -+ require_capability!(CAP_SYS_PACCT);
35394 -+ }
35395 -+ }
35396 -+ } else if #[cfg(target_os = "freebsd")] {
35397 -+ macro_rules! require_acct{
35398 -+ () => {
35399 -+ skip_if_not_root!("test_acct");
35400 -+ skip_if_jailed!("test_acct");
35401 -+ }
35402 -+ }
35403 -+ } else {
35404 -+ macro_rules! require_acct{
35405 -+ () => {
35406 -+ skip_if_not_root!("test_acct");
35407 -+ }
35408 -+ }
35409 -+ }
35410 -+}
35411 -+
35412 -+#[test]
35413 -+fn test_acct() {
35414 -+ use tempfile::NamedTempFile;
35415 -+ use std::process::Command;
35416 -+ use std::{thread, time};
35417 -+
35418 -+ let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
35419 -+ require_acct!();
35420 -+
35421 -+ let file = NamedTempFile::new().unwrap();
35422 -+ let path = file.path().to_str().unwrap();
35423 -+
35424 -+ acct::enable(path).unwrap();
35425 -+
35426 -+ loop {
35427 -+ Command::new("echo").arg("Hello world");
35428 -+ let len = fs::metadata(path).unwrap().len();
35429 -+ if len > 0 { break; }
35430 -+ thread::sleep(time::Duration::from_millis(10));
35431 -+ }
35432 -+ acct::disable().unwrap();
35433 -+}
35434 -+
35435 -+#[test]
35436 -+fn test_fpathconf_limited() {
35437 -+ let f = tempfile().unwrap();
35438 -+ // AFAIK, PATH_MAX is limited on all platforms, so it makes a good test
35439 -+ let path_max = fpathconf(f.as_raw_fd(), PathconfVar::PATH_MAX);
35440 -+ assert!(path_max.expect("fpathconf failed").expect("PATH_MAX is unlimited") > 0);
35441 -+}
35442 -+
35443 -+#[test]
35444 -+fn test_pathconf_limited() {
35445 -+ // AFAIK, PATH_MAX is limited on all platforms, so it makes a good test
35446 -+ let path_max = pathconf("/", PathconfVar::PATH_MAX);
35447 -+ assert!(path_max.expect("pathconf failed").expect("PATH_MAX is unlimited") > 0);
35448 -+}
35449 -+
35450 -+#[test]
35451 -+fn test_sysconf_limited() {
35452 -+ // AFAIK, OPEN_MAX is limited on all platforms, so it makes a good test
35453 -+ let open_max = sysconf(SysconfVar::OPEN_MAX);
35454 -+ assert!(open_max.expect("sysconf failed").expect("OPEN_MAX is unlimited") > 0);
35455 -+}
35456 -+
35457 -+#[cfg(target_os = "freebsd")]
35458 -+#[test]
35459 -+fn test_sysconf_unsupported() {
35460 -+ // I know of no sysconf variables that are unsupported everywhere, but
35461 -+ // _XOPEN_CRYPT is unsupported on FreeBSD 11.0, which is one of the platforms
35462 -+ // we test.
35463 -+ let open_max = sysconf(SysconfVar::_XOPEN_CRYPT);
35464 -+ assert!(open_max.expect("sysconf failed").is_none())
35465 -+}
35466 -+
35467 -+// Test that we can create a pair of pipes. No need to verify that they pass
35468 -+// data; that's the domain of the OS, not nix.
35469 -+#[test]
35470 -+fn test_pipe() {
35471 -+ let (fd0, fd1) = pipe().unwrap();
35472 -+ let m0 = stat::SFlag::from_bits_truncate(stat::fstat(fd0).unwrap().st_mode);
35473 -+ // S_IFIFO means it's a pipe
35474 -+ assert_eq!(m0, SFlag::S_IFIFO);
35475 -+ let m1 = stat::SFlag::from_bits_truncate(stat::fstat(fd1).unwrap().st_mode);
35476 -+ assert_eq!(m1, SFlag::S_IFIFO);
35477 -+}
35478 -+
35479 -+// pipe2(2) is the same as pipe(2), except it allows setting some flags. Check
35480 -+// that we can set a flag.
35481 -+#[test]
35482 -+fn test_pipe2() {
35483 -+ let (fd0, fd1) = pipe2(OFlag::O_CLOEXEC).unwrap();
35484 -+ let f0 = FdFlag::from_bits_truncate(fcntl(fd0, FcntlArg::F_GETFD).unwrap());
35485 -+ assert!(f0.contains(FdFlag::FD_CLOEXEC));
35486 -+ let f1 = FdFlag::from_bits_truncate(fcntl(fd1, FcntlArg::F_GETFD).unwrap());
35487 -+ assert!(f1.contains(FdFlag::FD_CLOEXEC));
35488 -+}
35489 -+
35490 -+#[test]
35491 -+fn test_truncate() {
35492 -+ let tempdir = tempfile::tempdir().unwrap();
35493 -+ let path = tempdir.path().join("file");
35494 -+
35495 -+ {
35496 -+ let mut tmp = File::create(&path).unwrap();
35497 -+ const CONTENTS: &[u8] = b"12345678";
35498 -+ tmp.write_all(CONTENTS).unwrap();
35499 -+ }
35500 -+
35501 -+ truncate(&path, 4).unwrap();
35502 -+
35503 -+ let metadata = fs::metadata(&path).unwrap();
35504 -+ assert_eq!(4, metadata.len());
35505 -+}
35506 -+
35507 -+#[test]
35508 -+fn test_ftruncate() {
35509 -+ let tempdir = tempfile::tempdir().unwrap();
35510 -+ let path = tempdir.path().join("file");
35511 -+
35512 -+ let tmpfd = {
35513 -+ let mut tmp = File::create(&path).unwrap();
35514 -+ const CONTENTS: &[u8] = b"12345678";
35515 -+ tmp.write_all(CONTENTS).unwrap();
35516 -+ tmp.into_raw_fd()
35517 -+ };
35518 -+
35519 -+ ftruncate(tmpfd, 2).unwrap();
35520 -+ close(tmpfd).unwrap();
35521 -+
35522 -+ let metadata = fs::metadata(&path).unwrap();
35523 -+ assert_eq!(2, metadata.len());
35524 -+}
35525 -+
35526 -+// Used in `test_alarm`.
35527 -+static mut ALARM_CALLED: bool = false;
35528 -+
35529 -+// Used in `test_alarm`.
35530 -+pub extern fn alarm_signal_handler(raw_signal: libc::c_int) {
35531 -+ assert_eq!(raw_signal, libc::SIGALRM, "unexpected signal: {}", raw_signal);
35532 -+ unsafe { ALARM_CALLED = true };
35533 -+}
35534 -+
35535 -+#[test]
35536 -+fn test_alarm() {
35537 -+ let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
35538 -+
35539 -+ let handler = SigHandler::Handler(alarm_signal_handler);
35540 -+ let signal_action = SigAction::new(handler, SaFlags::SA_RESTART, SigSet::empty());
35541 -+ let old_handler = unsafe {
35542 -+ sigaction(Signal::SIGALRM, &signal_action)
35543 -+ .expect("unable to set signal handler for alarm")
35544 -+ };
35545 -+
35546 -+ // Set an alarm.
35547 -+ assert_eq!(alarm::set(60), None);
35548 -+
35549 -+ // Overwriting an alarm should return the old alarm.
35550 -+ assert_eq!(alarm::set(1), Some(60));
35551 -+
35552 -+ // We should be woken up after 1 second by the alarm, so we'll sleep for 2
35553 -+ // seconds to be sure.
35554 -+ sleep(2);
35555 -+ assert_eq!(unsafe { ALARM_CALLED }, true, "expected our alarm signal handler to be called");
35556 -+
35557 -+ // Reset the signal.
35558 -+ unsafe {
35559 -+ sigaction(Signal::SIGALRM, &old_handler)
35560 -+ .expect("unable to set signal handler for alarm");
35561 -+ }
35562 -+}
35563 -+
35564 -+#[test]
35565 -+fn test_canceling_alarm() {
35566 -+ let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
35567 -+
35568 -+ assert_eq!(alarm::cancel(), None);
35569 -+
35570 -+ assert_eq!(alarm::set(60), None);
35571 -+ assert_eq!(alarm::cancel(), Some(60));
35572 -+}
35573 -+
35574 -+#[test]
35575 -+fn test_symlinkat() {
35576 -+ let mut buf = [0; 1024];
35577 -+ let tempdir = tempfile::tempdir().unwrap();
35578 -+
35579 -+ let target = tempdir.path().join("a");
35580 -+ let linkpath = tempdir.path().join("b");
35581 -+ symlinkat(&target, None, &linkpath).unwrap();
35582 -+ assert_eq!(
35583 -+ readlink(&linkpath, &mut buf).unwrap().to_str().unwrap(),
35584 -+ target.to_str().unwrap()
35585 -+ );
35586 -+
35587 -+ let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap();
35588 -+ let target = "c";
35589 -+ let linkpath = "d";
35590 -+ symlinkat(target, Some(dirfd), linkpath).unwrap();
35591 -+ assert_eq!(
35592 -+ readlink(&tempdir.path().join(linkpath), &mut buf)
35593 -+ .unwrap()
35594 -+ .to_str()
35595 -+ .unwrap(),
35596 -+ target
35597 -+ );
35598 -+}
35599 -+
35600 -+
35601 -+#[test]
35602 -+fn test_unlinkat_dir_noremovedir() {
35603 -+ let tempdir = tempfile::tempdir().unwrap();
35604 -+ let dirname = "foo_dir";
35605 -+ let dirpath = tempdir.path().join(dirname);
35606 -+
35607 -+ // Create dir
35608 -+ DirBuilder::new().recursive(true).create(&dirpath).unwrap();
35609 -+
35610 -+ // Get file descriptor for base directory
35611 -+ let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap();
35612 -+
35613 -+ // Attempt unlink dir at relative path without proper flag
35614 -+ let err_result = unlinkat(Some(dirfd), dirname, UnlinkatFlags::NoRemoveDir).unwrap_err();
35615 -+ assert!(err_result == Error::Sys(Errno::EISDIR) || err_result == Error::Sys(Errno::EPERM));
35616 -+ }
35617 -+
35618 -+#[test]
35619 -+fn test_unlinkat_dir_removedir() {
35620 -+ let tempdir = tempfile::tempdir().unwrap();
35621 -+ let dirname = "foo_dir";
35622 -+ let dirpath = tempdir.path().join(dirname);
35623 -+
35624 -+ // Create dir
35625 -+ DirBuilder::new().recursive(true).create(&dirpath).unwrap();
35626 -+
35627 -+ // Get file descriptor for base directory
35628 -+ let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap();
35629 -+
35630 -+ // Attempt unlink dir at relative path with proper flag
35631 -+ unlinkat(Some(dirfd), dirname, UnlinkatFlags::RemoveDir).unwrap();
35632 -+ assert!(!dirpath.exists());
35633 -+ }
35634 -+
35635 -+#[test]
35636 -+fn test_unlinkat_file() {
35637 -+ let tempdir = tempfile::tempdir().unwrap();
35638 -+ let filename = "foo.txt";
35639 -+ let filepath = tempdir.path().join(filename);
35640 -+
35641 -+ // Create file
35642 -+ File::create(&filepath).unwrap();
35643 -+
35644 -+ // Get file descriptor for base directory
35645 -+ let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap();
35646 -+
35647 -+ // Attempt unlink file at relative path
35648 -+ unlinkat(Some(dirfd), filename, UnlinkatFlags::NoRemoveDir).unwrap();
35649 -+ assert!(!filepath.exists());
35650 -+ }
35651 -+
35652 -+#[test]
35653 -+fn test_access_not_existing() {
35654 -+ let tempdir = tempfile::tempdir().unwrap();
35655 -+ let dir = tempdir.path().join("does_not_exist.txt");
35656 -+ assert_eq!(access(&dir, AccessFlags::F_OK).err().unwrap().as_errno().unwrap(),
35657 -+ Errno::ENOENT);
35658 -+}
35659 -+
35660 -+#[test]
35661 -+fn test_access_file_exists() {
35662 -+ let tempdir = tempfile::tempdir().unwrap();
35663 -+ let path = tempdir.path().join("does_exist.txt");
35664 -+ let _file = File::create(path.clone()).unwrap();
35665 -+ assert!(access(&path, AccessFlags::R_OK | AccessFlags::W_OK).is_ok());
35666 -+}
35667 -diff --git a/third_party/rust/nix/.cargo-checksum.json b/third_party/rust/nix/.cargo-checksum.json
35668 -index e5f2bc789185a..85adbc1eae931 100644
35669 ---- a/third_party/rust/nix/.cargo-checksum.json
35670 -+++ b/third_party/rust/nix/.cargo-checksum.json
35671 -@@ -1 +1 @@
35672 --{"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","
35673 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/e
35674 poll.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":"8a7eacfc172b55763ae
35675 32109bf9b252669ba68b72cd5122f7504eb35c0c08345","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":"c663505d6a7a7ae9d76e03fbc17e5
35676 3d308ea6b1eae92212812e1d76b2bf2916f","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.
35677 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":"84ae63c2baa49eebeabe5bbd347b9c5417e14ba97f342719d7
35678 53dc1c1c768d60","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":"0219f7bce0603f97d997fb377ca071966c903
35679 33ecc665e78a54dfeb97a9c811b","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":"1dc420d3119bf4d863a7ae0ba63efa7f1416f6e46e4
35680 100ea161003fe1c3f66ba","test/test_unistd.rs":"0325c998acca1e826e9e2b3d351d55ab9723a6cb2ca2072245978e7f5a9acee8"},"package":"3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229"}
35681 -\ No newline at end of file
35682 -+{"files":{"CHANGELOG.md":"9294216482039acf0dd5911548feaaf04d410298fc5cd3df450d8d36c914756e","CONTRIBUTING.md":"7da4f8c2ff8e06850bdd9ebc0a3552419fd21d2c6bb0c6f0719566e263b0a1b9","CONVENTIONS.md":"df0d4fe9fe65af0bfa4723dc7b641d5130087259799e6b404ad63884f79031cb","Cargo.toml":"03e8c7ae8afb88e9d698712e2428d19a367c19079e994a170cb16dca985cc48d","LICENSE":"66e3ee1fa7f909ad3c612d556f2a0cdabcd809ad6e66f3b0605015ac64841b70","README.md":"d7a8568ffb72d76acc2812d8f545ad71b24a7c1301d2a258f49057fcaded0b9f","src/dir.rs":"52170e8bfc8c4bc1996db2f5cd5a2aace71beac59e4a0e7c1817fdecbf8bd6a7","src/env.rs":"bc52e80d3fa6c5388e3e23767d214a72f88d2927c5604246016c4cf978bbbeb7","src/errno.rs":"1aab33e5dcab9c6f83e48e452f361840645ce6a434bc13bd8ab9abb0e0ef25c3","src/fcntl.rs":"7f3f95baad70ceb1231b8a647988a8e54292d84176820eb6a9f89d40f309c3a6","src/features.rs":"2cb080da3f26eca2d2e18282a41afec921426423a6354a50b840cf20f3f153f6","src/ifaddrs.rs":"4f19ed3b15f5059c2859958c6aa313d6fa75703e68f8608359ef8e0089508ed3","src/k
35683 mod.rs":"873bec7f32e30a552a4fd86d5f884c2b3a0cd73012121dfe1587b508475beb0a","src/lib.rs":"ae1a16e142c47afc3f52a07a2afb2fc013cfd427df955aa42e4bd372c77c49d5","src/macros.rs":"7c6c81441c967d73a75a975bb660ae48efde22c6f5ae2705c62a8db446ce0d39","src/mount.rs":"cde7c59b79a8e535c4d8c57c53d7825384b110be244803b1f895d5a3b97bc72f","src/mqueue.rs":"3520495f6a881a7239fba19e90234f7fc9df6729b6bc150bd2e6664b7c98d6a1","src/net/if_.rs":"928066a6ec473ce565e2323858ff64e179e4b81b80768d830dd29008f2fafb7f","src/net/mod.rs":"577f70170e53d4a6de1abb70bf8f1031ec3e65c0e63ef5fcf05c907125e7ac17","src/poll.rs":"ba635fbed688a165279a9851269310220befd211c8fcf5761d1a62dab39ba52b","src/pty.rs":"7a73ba21b2ec8910f7932e456d2fb097a0553c5fe07717238c58455e3de7b275","src/sched.rs":"2bdb5ce449bc093a8eecdd8964e5d05feee3e7b804e4271e40d674178295df79","src/sys/aio.rs":"bbcc1d8639a9c89c66c00357353dde94d0f48b516b4354ab3d3dcfc16a2e0b56","src/sys/epoll.rs":"a3ace2282e77989e9b927dcdca8ad2070d4fb7710398af0763ea6eb26d431968","src/sys/even
35684 t.rs":"075e84e5a5d1fd922fbcac8c01c8e7cd7f1a1c1f8f60ede8f7ebc5fe6d5e76ac","src/sys/eventfd.rs":"b5301029e95f77f280cc169bb8aa247352efbb600c749f26e2fffa0474c872bb","src/sys/inotify.rs":"114be3860c9daaee1c781df90b63abb87cd82d677c4470b359bbf0787a25d302","src/sys/ioctl/bsd.rs":"853b50c3539dc4a1284c847f2689fde3dbed5dca7a8599db36193048e030296a","src/sys/ioctl/linux.rs":"642b25d3997518815dea454fa976e9067ad5fe4ed75622e7540e3f0d0c7d320a","src/sys/ioctl/mod.rs":"dd3435e44c42f55a600e40599038bebc7417934dade00113ef0f3b6318bf54de","src/sys/memfd.rs":"35dba6c3eeb4f74edbf86530ba1696d9251495b82b814a36b76e6d2b26490e3c","src/sys/mman.rs":"bdca4a151dc31d27c7435e30a5030ad2edef9dd3ac69a33363454cada8466ca3","src/sys/mod.rs":"b8d7d9e3cb331f1d972699cfbaa54fff34a9f26eaba38b8ee49e84bfeee22bd3","src/sys/personality.rs":"2019e58aa69c5ad68ae060e1b9a399138a2e4742f37a868e2681588963ca8acf","src/sys/pthread.rs":"cfa9ccd6f3b86c0c3fe012773c9c82a7813b298c2f20f8ab629781db627ce56b","src/sys/ptrace/bsd.rs":"feced79575c5dbea
35685 f0a0877ba888761675310b277f477acee820c785e132dbe9","src/sys/ptrace/linux.rs":"34524ad4911d2ef7ec0e21a49e479d6fd91d4ef5c660e0b7e2afa4878b27367a","src/sys/ptrace/mod.rs":"671a6ccac955e75d5998f7e53ffc45ed4c7b6522a0f24a0937d60141f692dd39","src/sys/quota.rs":"4ceb895896bbd0bb67ce98e91dec3bd40c9a7d5936abbe13b74691c6afa07f9f","src/sys/reboot.rs":"1fd26955bc095bd4f8804c850183f527560803cbceaf345c3760c8f32fe1224f","src/sys/select.rs":"02226a733d160701f07d27384f87bf21032f3cc4d5a6214dc61e398dd1606b60","src/sys/sendfile.rs":"110955788e3f5f36a7e563c334c6fe400edfb93d6cb2fdce6b8a79d2e892f8ce","src/sys/signal.rs":"53232ef1165272d109173fbba769cde77f3446050dbdaf36e56c4c0fde084348","src/sys/signalfd.rs":"37704804eb75571d03bbc1c99bd90846ae50ce361cc9998777744f8265d51074","src/sys/socket/addr.rs":"0513e0fbe57c19f8f9538e31074a4ed50c443fd45dd66ce1fa56db2dee46b371","src/sys/socket/mod.rs":"7d0d0b2da45d45493c494ad8669f53577439510914777b03febb6d2f18dcc787","src/sys/socket/sockopt.rs":"42b335e7a2e2b8cf1605065244
35686 90bb685bd2488ebff65921aa10f60363ffda7b","src/sys/stat.rs":"a969ae88221a50c89d54f97987d108d3c017339d7eedd66ac7218463d2bb07db","src/sys/statfs.rs":"6bd23f941107dc79ec34dc50516ff5eb18d9fad108ad976796669505692c1582","src/sys/statvfs.rs":"09a7268f3f6f321961e4f25943236fe103fe8c7661ea841f4e71014fda0d8952","src/sys/sysinfo.rs":"1aa6f402bc10689c5dd7ad454ecb60834e2b065dddbd3d87d1daecf88cb2b3ee","src/sys/termios.rs":"c3c310cdec9c7c80e7b11ada25d3dc87c0d0fc6c30fcda8f94edab1d27132300","src/sys/time.rs":"cc955b6b6647ca1db33ac076780ca6c984200e3cc47df5d836b1528489cdef70","src/sys/timerfd.rs":"51443f37b1dd4b03f16e1b569945f0ae715db4028f69e3ddd6c311db00e67ab3","src/sys/uio.rs":"a25dd7a84135ea50a671a7a06a8989dc9d53d3e755d36cef9f37cdc79a123d9d","src/sys/utsname.rs":"9509a092c837d1700f9f4ac30e4568e5b9b63ad8925a56cd8ad7add05d0ac452","src/sys/wait.rs":"ab18e66acaf161750394d802409ee8c95707dbd68d2fb59c88f7d4ed8936a1be","src/time.rs":"957845f8c689aec3c5dcf1af8bbc274a28ed5a214e4ee31ec8a89ed5eea0d3f1","src/ucont
35687 ext.rs":"10fdfebcecafa8d1c6cf573a5768adc07b87e9ff52a0bdc2527e77f73608f264","src/unistd.rs":"9c2b170f2b217393e571fb8021e000dfec4a5d99e170e11532a665163ecf3d54","test/common/mod.rs":"a26ecf30fc06008bab21d96eabf711bb0c41e8b50fe4c1f35cb2797ef405296c","test/sys/mod.rs":"c6f6a376fca73025bd76043a1739f54d24e856d4d0af9c58cc2b9d730ab87144","test/sys/test_aio.rs":"f21c157a07a29d60b0d68baa78ce24b352a19a35eaced0a792f62fa16d38617f","test/sys/test_aio_drop.rs":"eb086fcebd53ec82359ed7323f039b16ef7abced66b111f4876486fb058476e5","test/sys/test_epoll.rs":"35093d0cb1096a934dfc4f6efc737eadc4bdc2e2134d2a879061374a51b10c97","test/sys/test_inotify.rs":"a4f804bcf414b6635d9863c8534769a609009c451c3476cc839cdc30c439b3b1","test/sys/test_ioctl.rs":"39ddd52b27d942ab1b4018d213a378fb221598febc8fc7759ae5e6f746364396","test/sys/test_lio_listio_resubmit.rs":"29718e5fd04ef041125db4963f518f6f518b50436ea2df91e44c9c6b9418b704","test/sys/test_mman.rs":"b129b1d40d7a6e23cfc10956f9aa689d578a745f82fa267d24c40475063b592c","test/
35688 sys/test_pthread.rs":"891726053083bf488655eca1518630b08fa7c5937433fb5e446a9eed181ff7c5","test/sys/test_ptrace.rs":"46e51267cc93e45894a1e5a194563af5fb65a170dca95ad7cf9110520d764703","test/sys/test_select.rs":"7ece285a78cb66852ba8e89cac82c2d4fcff7d17a5f35e282cc52a09f5820daf","test/sys/test_signal.rs":"753f2ccbfcf2c5353a75b1e48d746a07c1949defba515c0ceee589ad1ed0aff6","test/sys/test_signalfd.rs":"2068a028c88395ff51c09e43b18c03d16e2d851f1d26ca1d121cdb5cb050f5c5","test/sys/test_socket.rs":"0f5fe9637f196cef459aadee27e449e5f9f968c10bf8dd017763c607cb6261d3","test/sys/test_sockopt.rs":"3334e12322e8b4e7c095ddc4a40a2d0e73a0d3a6e1820a6e0970eb8e1136c6de","test/sys/test_sysinfo.rs":"1e1bea9130fe38ccb07cd0ad7334c7be1e45efc33f7656a5973f8cad7126f225","test/sys/test_termios.rs":"93cd5cc181f1d8cef5c69aa23ddfabbf0480369cffab523e677c81e208998328","test/sys/test_timerfd.rs":"fcada956abd981e4d846da58e5640c5705b16026d47bccd1d603fae765ad10db","test/sys/test_uio.rs":"ae915c03e4f64ce370ae46f5dbe37834dae2849bb9
35689 fa7961872cec50f45de1f4","test/sys/test_wait.rs":"1fefed60ea3f9c5d8d4518e1d7a122d50aad44c2bd87873ac9ddc31ecdcc5a39","test/test.rs":"be9c29b8a8c9669b6674746ac8065c828a5d1d40ba41226846fe964310a18188","test/test_clearenv.rs":"45ca548035b3c20ec87314715feaba2be973709a635d85b8cde46fd1d9f1ecd4","test/test_dir.rs":"e0dc7c317871eda3873a5d9df801c2ebb34cd958210c42a15f8dff623f05cae0","test/test_fcntl.rs":"e60c1dde6d0a6fde7a52cf98332e5b96fef5749868f0313cb7082bda7a66adb9","test/test_kmod/hello_mod/Makefile":"0219f7bce0603f97d997fb377ca071966c90333ecc665e78a54dfeb97a9c811b","test/test_kmod/hello_mod/hello.c":"bcac6b19c5bd807e1f3878c15e426acc85785a8ade9840c3bb4d068635c9188c","test/test_kmod/mod.rs":"07f5445812593c994d1c25d5c8669aa3c4b1750f3b8ed2c1ddb1c661809983dc","test/test_mount.rs":"55503e8b28f77b45d755d549375cab34fa3a3cc9b94cbb23cfbd4426c5d9cb9c","test/test_mq.rs":"1020a4eb2f88cc29c59c44ad965d0573fba2beeb4c8986060aac56de99eea63c","test/test_net.rs":"ec6d580b87292519d514b0236bdd5abdd576fcf4835cfe
35690 49ed1ddb47c5f1aea3","test/test_nix_path.rs":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","test/test_poll.rs":"fbcf1780447f75a0177b4f47ba3d99b68f4324059ff66d993034ae5035c6d3ef","test/test_pty.rs":"56198cb9537ec3409717acecb133a49eb48bfc180c135ff0296974ec466d1171","test/test_ptymaster_drop.rs":"d162510cc96b8b7389d8bc34e097db1c80b84b5070c1d16f15b053ffd20cfa17","test/test_sched.rs":"f8ad92eb554164b0f92428f716db99040186d741cc6e1976f7930f099652f70c","test/test_sendfile.rs":"e0cbabbd34052ccaa03d6555d5631686aa076728f6378ee90f7ecec68f891144","test/test_stat.rs":"9668fc1f894b7f8a60dfddbdaef4bc833463e4e0cf04c1cff7f8c0569a226ad2","test/test_time.rs":"199b1c89d373e9398cca97f83ecd6459c6bd5ba7adca28013d9109d5cbad03f3","test/test_unistd.rs":"9bf047d877fd7c0826a2241737574923c3fd102a6b143b6d9710f52af5655588"},"package":"f5e06129fb611568ef4e868c14b326274959aa70ff7776e9d55323531c374945"}
35691 -\ No newline at end of file
35692 -diff --git a/third_party/rust/nix/CHANGELOG.md b/third_party/rust/nix/CHANGELOG.md
35693 -index d93a5ce6bbfc9..234f2307c6d36 100644
35694 ---- a/third_party/rust/nix/CHANGELOG.md
35695 -+++ b/third_party/rust/nix/CHANGELOG.md
35696 -@@ -2,12 +2,316 @@
35697 -
35698 - All notable changes to this project will be documented in this file.
35699 - This project adheres to [Semantic Versioning](http://semver.org/).
35700 -+This project adheres to [Semantic Versioning](https://semver.org/).
35701 -
35702 --## [Unreleased] - ReleaseDate
35703 -+## [0.20.2] - 28 September 2021
35704 - ### Added
35705 - ### Changed
35706 - ### Fixed
35707 -+
35708 -+- Fixed buffer overflow in `unistd::getgrouplist`.
35709 -+ (#[1545](https://github.com/nix-rust/nix/pull/1545))
35710 -+
35711 -+## [0.20.1] - 13 August 2021
35712 -+### Added
35713 -+### Changed
35714 -+### Fixed
35715 -+
35716 -+- Locked bitflags to < 1.3.0 to fix the build with rust < 1.46.0.
35717 -+
35718 -+### Removed
35719 -+
35720 -+- Removed a couple of termios constants on redox that were never actually
35721 -+ supported.
35722 -+ (#[1483](https://github.com/nix-rust/nix/pull/1483))
35723 -+
35724 -+## [0.20.0] - 20 February 2021
35725 -+### Added
35726 -+
35727 -+- Added a `passwd` field to `Group` (#[1338](https://github.com/nix-rust/nix/pull/1338))
35728 -+- Added `mremap` (#[1306](https://github.com/nix-rust/nix/pull/1306))
35729 -+- Added `personality` (#[1331](https://github.com/nix-rust/nix/pull/1331))
35730 -+- Added limited Fuchsia support (#[1285](https://github.com/nix-rust/nix/pull/1285))
35731 -+- Added `getpeereid` (#[1342](https://github.com/nix-rust/nix/pull/1342))
35732 -+- Implemented `IntoIterator` for `Dir`
35733 -+ (#[1333](https://github.com/nix-rust/nix/pull/1333)).
35734 -+
35735 -+### Changed
35736 -+
35737 -+- Minimum supported Rust version is now 1.40.0.
35738 -+ ([#1356](https://github.com/nix-rust/nix/pull/1356))
35739 -+- i686-apple-darwin has been demoted to Tier 2 support, because it's deprecated
35740 -+ by Xcode.
35741 -+ (#[1350](https://github.com/nix-rust/nix/pull/1350))
35742 -+- Fixed calling `recvfrom` on an `AddrFamily::Packet` socket
35743 -+ (#[1344](https://github.com/nix-rust/nix/pull/1344))
35744 -+
35745 -+### Fixed
35746 -+- `TimerFd` now closes the underlying fd on drop.
35747 -+ ([#1381](https://github.com/nix-rust/nix/pull/1381))
35748 -+- Define `*_MAGIC` filesystem constants on Linux s390x
35749 -+ (#[1372](https://github.com/nix-rust/nix/pull/1372))
35750 -+- mqueue, sysinfo, timespec, statfs, test_ptrace_syscall() on x32
35751 -+ (#[1366](https://github.com/nix-rust/nix/pull/1366))
35752 -+
35753 -+### Removed
35754 -+
35755 -+- `Dir`, `SignalFd`, and `PtyMaster` are no longer `Clone`.
35756 -+ (#[1382](https://github.com/nix-rust/nix/pull/1382))
35757 -+- Removed `SockLevel`, which hasn't been used for a few years
35758 -+ (#[1362](https://github.com/nix-rust/nix/pull/1362))
35759 -+- Removed both `Copy` and `Clone` from `TimerFd`.
35760 -+ ([#1381](https://github.com/nix-rust/nix/pull/1381))
35761 -+
35762 -+## [0.19.1] - 28 November 2020
35763 -+### Fixed
35764 -+- Fixed bugs in `recvmmsg`.
35765 -+ (#[1341](https://github.com/nix-rust/nix/pull/1341))
35766 -+
35767 -+## [0.19.0] - 6 October 2020
35768 -+### Added
35769 -+- Added Netlink protocol families to the `SockProtocol` enum
35770 -+ (#[1289](https://github.com/nix-rust/nix/pull/1289))
35771 -+- Added `clock_gettime`, `clock_settime`, `clock_getres`,
35772 -+ `clock_getcpuclockid` functions and `ClockId` struct.
35773 -+ (#[1281](https://github.com/nix-rust/nix/pull/1281))
35774 -+- Added wrapper functions for `PTRACE_SYSEMU` and `PTRACE_SYSEMU_SINGLESTEP`.
35775 -+ (#[1300](https://github.com/nix-rust/nix/pull/1300))
35776 -+- Add support for Vsock on Android rather than just Linux.
35777 -+ (#[1301](https://github.com/nix-rust/nix/pull/1301))
35778 -+- Added `TCP_KEEPCNT` and `TCP_KEEPINTVL` TCP keepalive options.
35779 -+ (#[1283](https://github.com/nix-rust/nix/pull/1283))
35780 -+### Changed
35781 -+- Expose `SeekData` and `SeekHole` on all Linux targets
35782 -+ (#[1284](https://github.com/nix-rust/nix/pull/1284))
35783 -+- Changed unistd::{execv,execve,execvp,execvpe,fexecve,execveat} to take both `&[&CStr]` and `&[CString]` as its list argument(s).
35784 -+ (#[1278](https://github.com/nix-rust/nix/pull/1278))
35785 -+- Made `unistd::fork` an unsafe funtion, bringing it in line with [libstd's decision](https://github.com/rust-lang/rust/pull/58059).
35786 -+ (#[1293](https://github.com/nix-rust/nix/pull/1293))
35787 -+### Fixed
35788 -+### Removed
35789 -+
35790 -+## [0.18.0] - 26 July 2020
35791 -+### Added
35792 -+- Added `fchown(2)` wrapper.
35793 -+ (#[1257](https://github.com/nix-rust/nix/pull/1257))
35794 -+- Added support on linux systems for `MAP_HUGE_`_`SIZE`_ family of flags.
35795 -+ (#[1211](https://github.com/nix-rust/nix/pull/1211))
35796 -+- Added support for `F_OFD_*` `fcntl` commands on Linux and Android.
35797 -+ (#[1195](https://github.com/nix-rust/nix/pull/1195))
35798 -+- Added `env::clearenv()`: calls `libc::clearenv` on platforms
35799 -+ where it's available, and clears the environment of all variables
35800 -+ via `std::env::vars` and `std::env::remove_var` on others.
35801 -+ (#[1185](https://github.com/nix-rust/nix/pull/1185))
35802 -+- `FsType` inner value made public.
35803 -+ (#[1187](https://github.com/nix-rust/nix/pull/1187))
35804 -+- Added `unistd::setfsuid` and `unistd::setfsgid` to set the user or group
35805 -+ identity for filesystem checks per-thread.
35806 -+ (#[1163](https://github.com/nix-rust/nix/pull/1163))
35807 -+- Derived `Ord`, `PartialOrd` for `unistd::Pid` (#[1189](https://github.com/nix-rust/nix/pull/1189))
35808 -+- Added `select::FdSet::fds` method to iterate over file descriptors in a set.
35809 -+ ([#1207](https://github.com/nix-rust/nix/pull/1207))
35810 -+- Added support for UDP generic segmentation offload (GSO) and generic
35811 -+ receive offload (GRO) ([#1209](https://github.com/nix-rust/nix/pull/1209))
35812 -+- Added support for `sendmmsg` and `recvmmsg` calls
35813 -+ (#[1208](https://github.com/nix-rust/nix/pull/1208))
35814 -+- Added support for `SCM_CREDS` messages (`UnixCredentials`) on FreeBSD/DragonFly
35815 -+ (#[1216](https://github.com/nix-rust/nix/pull/1216))
35816 -+- Added `BindToDevice` socket option (sockopt) on Linux
35817 -+ (#[1233](https://github.com/nix-rust/nix/pull/1233))
35818 -+- Added `EventFilter` bitflags for `EV_DISPATCH` and `EV_RECEIPT` on OpenBSD.
35819 -+ (#[1252](https://github.com/nix-rust/nix/pull/1252))
35820 -+- Added support for `Ipv4PacketInfo` and `Ipv6PacketInfo` to `ControlMessage`.
35821 -+ (#[1222](https://github.com/nix-rust/nix/pull/1222))
35822 -+- `CpuSet` and `UnixCredentials` now implement `Default`.
35823 -+ (#[1244](https://github.com/nix-rust/nix/pull/1244))
35824 -+- Added `unistd::ttyname`
35825 -+ (#[1259](https://github.com/nix-rust/nix/pull/1259))
35826 -+- Added support for `Ipv4PacketInfo` and `Ipv6PacketInfo` to `ControlMessage` for iOS and Android.
35827 -+ (#[1265](https://github.com/nix-rust/nix/pull/1265))
35828 -+- Added support for `TimerFd`.
35829 -+ (#[1261](https://github.com/nix-rust/nix/pull/1261))
35830 -+
35831 -+### Changed
35832 -+- Changed `fallocate` return type from `c_int` to `()` (#[1201](https://github.com/nix-rust/nix/pull/1201))
35833 -+- Enabled `sys::ptrace::setregs` and `sys::ptrace::getregs` on x86_64-unknown-linux-musl target
35834 -+ (#[1198](https://github.com/nix-rust/nix/pull/1198))
35835 -+- On Linux, `ptrace::write` is now an `unsafe` function. Caveat programmer.
35836 -+ (#[1245](https://github.com/nix-rust/nix/pull/1245))
35837 -+- `execv`, `execve`, `execvp` and `execveat` in `::nix::unistd` and `reboot` in
35838 -+ `::nix::sys::reboot` now return `Result<Infallible>` instead of `Result<Void>` (#[1239](https://github.com/nix-rust/nix/pull/1239))
35839 -+- `sys::socket::sockaddr_storage_to_addr` is no longer `unsafe`. So is
35840 -+ `offset_of!`.
35841 -+- `sys::socket::sockaddr_storage_to_addr`, `offset_of!`, and `Errno::clear` are
35842 -+ no longer `unsafe`.
35843 -+- `SockAddr::as_ffi_pair`,`sys::socket::sockaddr_storage_to_addr`, `offset_of!`,
35844 -+ and `Errno::clear` are no longer `unsafe`.
35845 -+ (#[1244](https://github.com/nix-rust/nix/pull/1244))
35846 -+- Several `Inotify` methods now take `self` by value instead of by reference
35847 -+ (#[1244](https://github.com/nix-rust/nix/pull/1244))
35848 -+- `nix::poll::ppoll`: `timeout` parameter is now optional, None is equivalent for infinite timeout.
35849 -+
35850 -+### Fixed
35851 -+
35852 -+- Fixed `getsockopt`. The old code produced UB which triggers a panic with
35853 -+ Rust 1.44.0.
35854 -+ (#[1214](https://github.com/nix-rust/nix/pull/1214))
35855 -+
35856 -+- Fixed a bug in nix::unistd that would result in an infinite loop
35857 -+ when a group or user lookup required a buffer larger than
35858 -+ 16KB. (#[1198](https://github.com/nix-rust/nix/pull/1198))
35859 -+- Fixed unaligned casting of `cmsg_data` to `af_alg_iv` (#[1206](https://github.com/nix-rust/nix/pull/1206))
35860 -+- Fixed `readlink`/`readlinkat` when reading symlinks longer than `PATH_MAX` (#[1231](https://github.com/nix-rust/nix/pull/1231))
35861 -+- `PollFd`, `EpollEvent`, `IpMembershipRequest`, `Ipv6MembershipRequest`,
35862 -+ `TimeVal`, and `IoVec` are now `repr(transparent)`. This is required for
35863 -+ correctness's sake across all architectures and compilers, though now bugs
35864 -+ have been reported so far.
35865 -+ (#[1243](https://github.com/nix-rust/nix/pull/1243))
35866 -+- Fixed unaligned pointer read in `Inotify::read_events`.
35867 -+ (#[1244](https://github.com/nix-rust/nix/pull/1244))
35868 -+
35869 -+### Removed
35870 -+
35871 -+- Removed `sys::socket::addr::from_libc_sockaddr` from the public API.
35872 -+ (#[1215](https://github.com/nix-rust/nix/pull/1215))
35873 -+- Removed `sys::termios::{get_libc_termios, get_libc_termios_mut, update_wrapper`
35874 -+ from the public API. These were previously hidden in the docs but still usable
35875 -+ by downstream.
35876 -+ (#[1235](https://github.com/nix-rust/nix/pull/1235))
35877 -+
35878 -+- Nix no longer implements `NixPath` for `Option<P> where P: NixPath`. Most
35879 -+ Nix functions that accept `NixPath` arguments can't do anything useful with
35880 -+ `None`. The exceptions (`mount` and `quotactl_sync`) already take explicitly
35881 -+ optional arguments.
35882 -+ (#[1242](https://github.com/nix-rust/nix/pull/1242))
35883 -+
35884 -+- Removed `unistd::daemon` and `unistd::pipe2` on OSX and ios
35885 -+ (#[1255](https://github.com/nix-rust/nix/pull/1255))
35886 -+
35887 -+- Removed `sys::event::FilterFlag::NOTE_EXIT_REPARENTED` and
35888 -+ `sys::event::FilterFlag::NOTE_REAP` on OSX and ios.
35889 -+ (#[1255](https://github.com/nix-rust/nix/pull/1255))
35890 -+
35891 -+- Removed `sys::ptrace::ptrace` on Android and Linux.
35892 -+ (#[1255](https://github.com/nix-rust/nix/pull/1255))
35893 -+
35894 -+- Dropped support for powerpc64-unknown-linux-gnu
35895 -+ (#[1266](https://github.com/nix-rust/nix/pull/1268))
35896 -+
35897 -+## [0.17.0] - 3 February 2020
35898 -+### Added
35899 -+- Add `CLK_TCK` to `SysconfVar`
35900 -+ (#[1177](https://github.com/nix-rust/nix/pull/1177))
35901 -+### Changed
35902 -+### Fixed
35903 -+### Removed
35904 -+- Removed deprecated Error::description from error types
35905 -+ (#[1175](https://github.com/nix-rust/nix/pull/1175))
35906 -+
35907 -+## [0.16.1] - 23 December 2019
35908 -+### Added
35909 -+### Changed
35910 -+### Fixed
35911 -+
35912 -+- Fixed the build for OpenBSD
35913 -+ (#[1168](https://github.com/nix-rust/nix/pull/1168))
35914 -+
35915 -+### Removed
35916 -+
35917 -+## [0.16.0] - 1 December 2019
35918 -+### Added
35919 -+- Added `ptrace::seize()`: similar to `attach()` on Linux
35920 -+ but with better-defined semantics.
35921 -+ (#[1154](https://github.com/nix-rust/nix/pull/1154))
35922 -+
35923 -+- Added `Signal::as_str()`: returns signal name as `&'static str`
35924 -+ (#[1138](https://github.com/nix-rust/nix/pull/1138))
35925 -+
35926 -+- Added `posix_fallocate`.
35927 -+ ([#1105](https://github.com/nix-rust/nix/pull/1105))
35928 -+
35929 -+- Implemented `Default` for `FdSet`
35930 -+ ([#1107](https://github.com/nix-rust/nix/pull/1107))
35931 -+
35932 -+- Added `NixPath::is_empty`.
35933 -+ ([#1107](https://github.com/nix-rust/nix/pull/1107))
35934 -+
35935 -+- Added `mkfifoat`
35936 -+ ([#1133](https://github.com/nix-rust/nix/pull/1133))
35937 -+
35938 -+- Added `User::from_uid`, `User::from_name`, `User::from_gid` and
35939 -+ `Group::from_name`,
35940 -+ ([#1139](https://github.com/nix-rust/nix/pull/1139))
35941 -+
35942 -+- Added `linkat`
35943 -+ ([#1101](https://github.com/nix-rust/nix/pull/1101))
35944 -+
35945 -+- Added `sched_getaffinity`.
35946 -+ ([#1148](https://github.com/nix-rust/nix/pull/1148))
35947 -+
35948 -+- Added optional `Signal` argument to `ptrace::{detach, syscall}` for signal
35949 -+ injection. ([#1083](https://github.com/nix-rust/nix/pull/1083))
35950 -+
35951 -+### Changed
35952 -+- `sys::termios::BaudRate` now implements `TryFrom<speed_t>` instead of
35953 -+ `From<speed_t>`. The old `From` implementation would panic on failure.
35954 -+ ([#1159](https://github.com/nix-rust/nix/pull/1159))
35955 -+
35956 -+- `sys::socket::ControlMessage::ScmCredentials` and
35957 -+ `sys::socket::ControlMessageOwned::ScmCredentials` now wrap `UnixCredentials`
35958 -+ rather than `libc::ucred`.
35959 -+ ([#1160](https://github.com/nix-rust/nix/pull/1160))
35960 -+
35961 -+- `sys::socket::recvmsg` now takes a plain `Vec` instead of a `CmsgBuffer`
35962 -+ implementor. If you were already using `cmsg_space!`, then you needn't worry.
35963 -+ ([#1156](https://github.com/nix-rust/nix/pull/1156))
35964 -+
35965 -+- `sys::socket::recvfrom` now returns
35966 -+ `Result<(usize, Option<SockAddr>)>` instead of `Result<(usize, SockAddr)>`.
35967 -+ ([#1145](https://github.com/nix-rust/nix/pull/1145))
35968 -+
35969 -+- `Signal::from_c_int` has been replaced by `Signal::try_from`
35970 -+ ([#1113](https://github.com/nix-rust/nix/pull/1113))
35971 -+
35972 -+- Changed `readlink` and `readlinkat` to return `OsString`
35973 -+ ([#1109](https://github.com/nix-rust/nix/pull/1109))
35974 -+
35975 -+ ```rust
35976 -+ # use nix::fcntl::{readlink, readlinkat};
35977 -+ // the buffer argument of `readlink` and `readlinkat` has been removed,
35978 -+ // and the return value is now an owned type (`OsString`).
35979 -+ // Existing code can be updated by removing the buffer argument
35980 -+ // and removing any clone or similar operation on the output
35981 -+
35982 -+ // old code `readlink(&path, &mut buf)` can be replaced with the following
35983 -+ let _: OsString = readlink(&path);
35984 -+
35985 -+ // old code `readlinkat(dirfd, &path, &mut buf)` can be replaced with the following
35986 -+ let _: OsString = readlinkat(dirfd, &path);
35987 -+ ```
35988 -+
35989 -+- Minimum supported Rust version is now 1.36.0.
35990 -+ ([#1108](https://github.com/nix-rust/nix/pull/1108))
35991 -+
35992 -+- `Ipv4Addr::octets`, `Ipv4Addr::to_std`, `Error::as_errno`,
35993 -+ `ForkResult::is_child`, `ForkResult::is_parent`, `Gid::as_raw`,
35994 -+ `Uid::is_root`, `Uid::as_raw`, `Pid::as_raw`, and `PollFd::revents` now take
35995 -+ `self` by value.
35996 -+ ([#1107](https://github.com/nix-rust/nix/pull/1107))
35997 -+
35998 -+- Type `&CString` for parameters of `exec(v|ve|vp|vpe|veat)` are changed to `&CStr`.
35999 -+ ([#1121](https://github.com/nix-rust/nix/pull/1121))
36000 -+
36001 -+### Fixed
36002 -+- Fix length of abstract socket addresses
36003 -+ ([#1120](https://github.com/nix-rust/nix/pull/1120))
36004 -+
36005 -+- Fix initialization of msghdr in recvmsg/sendmsg when built with musl
36006 -+ ([#1136](https://github.com/nix-rust/nix/pull/1136))
36007 -+
36008 - ### Removed
36009 -+- Remove the deprecated `CmsgSpace`.
36010 -+ ([#1156](https://github.com/nix-rust/nix/pull/1156))
36011 -
36012 - ## [0.15.0] - 10 August 2019
36013 - ### Added
36014 -diff --git a/third_party/rust/nix/CONTRIBUTING.md b/third_party/rust/nix/CONTRIBUTING.md
36015 -index 03a1f630dbb06..55990c4f1a24f 100644
36016 ---- a/third_party/rust/nix/CONTRIBUTING.md
36017 -+++ b/third_party/rust/nix/CONTRIBUTING.md
36018 -@@ -76,21 +76,21 @@ add a test that would have failed without the fix.
36019 -
36020 - After you've made your change, make sure the tests pass in your development
36021 - environment. We also have [continuous integration set up on
36022 --Travis-CI][travis-ci], which might find some issues on other platforms. The CI
36023 -+Cirrus-CI][cirrus-ci], which might find some issues on other platforms. The CI
36024 - will run once you open a pull request.
36025 -
36026 - There is also infrastructure for running tests for other targets
36027 - locally. More information is available in the [CI Readme][ci-readme].
36028 -
36029 --[travis-ci]: https://travis-ci.org/nix-rust/nix
36030 -+[cirrus-ci]: https://cirrus-ci.com/github/nix-rust/nix
36031 - [ci-readme]: ci/README.md
36032 -
36033 - ### Disabling a test in the CI environment
36034 -
36035 - Sometimes there are features that cannot be tested in the CI environment.
36036 --To stop a test from running under CI, add `#[cfg_attr(travis, ignore)]`
36037 --to it. Please include a comment describing the reason it shouldn't run
36038 --under CI, and a link to an upstream issue if possible!
36039 -+To stop a test from running under CI, add `skip_if_cirrus!()` to it. Please
36040 -+describe the reason it shouldn't run under CI, and a link to an issue if
36041 -+possible!
36042 -
36043 - ## bors, the bot who merges all the PRs
36044 -
36045 -diff --git a/third_party/rust/nix/CONVENTIONS.md b/third_party/rust/nix/CONVENTIONS.md
36046 -index 48daa937345d2..2461085eb664a 100644
36047 ---- a/third_party/rust/nix/CONVENTIONS.md
36048 -+++ b/third_party/rust/nix/CONVENTIONS.md
36049 -@@ -76,12 +76,11 @@ to parameters of functions by [enumerations][enum].
36050 -
36051 - Whenever we need to use a [libc][libc] function to properly initialize a
36052 - variable and said function allows us to use uninitialized memory, we use
36053 --[`std::mem::uninitialized`][std_uninitialized] (or [`core::mem::uninitialized`][core_uninitialized])
36054 --when defining the variable. This allows us to avoid the overhead incurred by
36055 --zeroing or otherwise initializing the variable.
36056 -+[`std::mem::MaybeUninit`][std_MaybeUninit] when defining the variable. This
36057 -+allows us to avoid the overhead incurred by zeroing or otherwise initializing
36058 -+the variable.
36059 -
36060 - [bitflags]: https://crates.io/crates/bitflags/
36061 --[core_uninitialized]: https://doc.rust-lang.org/core/mem/fn.uninitialized.html
36062 - [enum]: https://doc.rust-lang.org/reference.html#enumerations
36063 - [libc]: https://crates.io/crates/libc/
36064 --[std_uninitialized]: https://doc.rust-lang.org/std/mem/fn.uninitialized.html
36065 -+[std_MaybeUninit]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html
36066 -diff --git a/third_party/rust/nix/Cargo.toml b/third_party/rust/nix/Cargo.toml
36067 -index 555b99020d68f..456bdca9c2599 100644
36068 ---- a/third_party/rust/nix/Cargo.toml
36069 -+++ b/third_party/rust/nix/Cargo.toml
36070 -@@ -3,22 +3,24 @@
36071 - # When uploading crates to the registry Cargo will automatically
36072 - # "normalize" Cargo.toml files for maximal compatibility
36073 - # with all versions of Cargo and also rewrite `path` dependencies
36074 --# to registry (e.g., crates.io) dependencies
36075 -+# to registry (e.g., crates.io) dependencies.
36076 - #
36077 --# If you believe there's an error in this file please file an
36078 --# issue against the rust-lang/cargo repository. If you're
36079 --# editing this file be aware that the upstream Cargo.toml
36080 --# will likely look very different (and much more reasonable)
36081 -+# If you are reading this file be aware that the original Cargo.toml
36082 -+# will likely look very different (and much more reasonable).
36083 -+# See Cargo.toml.orig for the original contents.
36084 -
36085 - [package]
36086 -+edition = "2018"
36087 - name = "nix"
36088 --version = "0.15.0"
36089 -+version = "0.20.2"
36090 - authors = ["The nix-rust Project Developers"]
36091 --exclude = ["/.gitignore", "/.travis.yml", "/ci/*", "/Cross.toml", "/RELEASE_PROCEDURE.md", "/bors.toml"]
36092 -+exclude = ["/.gitignore", "/.cirrus.yml", "/ci/*", "/Cross.toml", "/RELEASE_PROCEDURE.md", "/bors.toml"]
36093 - description = "Rust friendly bindings to *nix APIs"
36094 - categories = ["os::unix-apis"]
36095 - license = "MIT"
36096 - repository = "https://github.com/nix-rust/nix"
36097 -+[package.metadata.docs.rs]
36098 -+targets = ["x86_64-unknown-linux-gnu", "aarch64-linux-android", "x86_64-apple-darwin", "aarch64-apple-ios", "x86_64-unknown-freebsd", "x86_64-unknown-openbsd", "x86_64-unknown-netbsd", "x86_64-unknown-dragonfly", "x86_64-fuchsia", "x86_64-unknown-redox"]
36099 -
36100 - [[test]]
36101 - name = "test"
36102 -@@ -28,6 +30,10 @@ path = "test/test.rs"
36103 - name = "test-aio-drop"
36104 - path = "test/sys/test_aio_drop.rs"
36105 -
36106 -+[[test]]
36107 -+name = "test-clearenv"
36108 -+path = "test/test_clearenv.rs"
36109 -+
36110 - [[test]]
36111 - name = "test-lio-listio-resubmit"
36112 - path = "test/sys/test_lio_listio_resubmit.rs"
36113 -@@ -41,17 +47,14 @@ harness = false
36114 - name = "test-ptymaster-drop"
36115 - path = "test/test_ptymaster_drop.rs"
36116 - [dependencies.bitflags]
36117 --version = "1.0"
36118 -+version = ">= 1.1.0, < 1.3.0"
36119 -
36120 - [dependencies.cfg-if]
36121 --version = "0.1.2"
36122 -+version = "1.0"
36123 -
36124 - [dependencies.libc]
36125 --version = "0.2.60"
36126 -+version = "0.2.99"
36127 - features = ["extra_traits"]
36128 --
36129 --[dependencies.void]
36130 --version = "1.0.2"
36131 - [dev-dependencies.bytes]
36132 - version = "0.4.8"
36133 -
36134 -@@ -59,12 +62,17 @@ version = "0.4.8"
36135 - version = "1.2"
36136 -
36137 - [dev-dependencies.rand]
36138 --version = ">= 0.6, < 0.7"
36139 -+version = "0.6"
36140 -+
36141 -+[dev-dependencies.semver]
36142 -+version = "0.9.0"
36143 -
36144 - [dev-dependencies.tempfile]
36145 --version = ">= 3.0.5, < 3.0.9"
36146 -+version = "3.0.5"
36147 - [target."cfg(any(target_os = \"android\", target_os = \"linux\"))".dev-dependencies.caps]
36148 --version = "0.3.1"
36149 -+version = "0.5.1"
36150 -+[target."cfg(not(target_os = \"redox\"))".dependencies.memoffset]
36151 -+version = "0.6.3"
36152 - [target."cfg(target_os = \"dragonfly\")".build-dependencies.cc]
36153 - version = "1"
36154 - [target."cfg(target_os = \"freebsd\")".dev-dependencies.sysctl]
36155 -diff --git a/third_party/rust/nix/README.md b/third_party/rust/nix/README.md
36156 -index 0e540ba5b968e..b4909ea4345cc 100644
36157 ---- a/third_party/rust/nix/README.md
36158 -+++ b/third_party/rust/nix/README.md
36159 -@@ -1,6 +1,6 @@
36160 - # Rust bindings to *nix APIs
36161 -
36162 --[![Build Status](https://travis-ci.org/nix-rust/nix.svg?branch=master)](https://travis-ci.org/nix-rust/nix)
36163 -+[![Cirrus Build Status](https://api.cirrus-ci.com/github/nix-rust/nix.svg)](https://cirrus-ci.com/github/nix-rust/nix)
36164 - [![crates.io](http://meritbadge.herokuapp.com/nix)](https://crates.io/crates/nix)
36165 -
36166 - [Documentation (Releases)](https://docs.rs/nix/)
36167 -@@ -50,7 +50,6 @@ Tier 1:
36168 - * aarch64-unknown-linux-gnu
36169 - * arm-unknown-linux-gnueabi
36170 - * armv7-unknown-linux-gnueabihf
36171 -- * i686-apple-darwin
36172 - * i686-unknown-freebsd
36173 - * i686-unknown-linux-gnu
36174 - * i686-unknown-linux-musl
36175 -@@ -58,7 +57,6 @@ Tier 1:
36176 - * mips64-unknown-linux-gnuabi64
36177 - * mips64el-unknown-linux-gnuabi64
36178 - * mipsel-unknown-linux-gnu
36179 -- * powerpc64-unknown-linux-gnu
36180 - * powerpc64le-unknown-linux-gnu
36181 - * x86_64-apple-darwin
36182 - * x86_64-unknown-freebsd
36183 -@@ -74,6 +72,7 @@ Tier 2:
36184 - * armv7-linux-androideabi
36185 - * armv7s-apple-ios
36186 - * i386-apple-ios
36187 -+ * i686-apple-darwin
36188 - * i686-linux-android
36189 - * powerpc-unknown-linux-gnu
36190 - * s390x-unknown-linux-gnu
36191 -@@ -81,21 +80,20 @@ Tier 2:
36192 - * x86_64-linux-android
36193 - * x86_64-unknown-netbsd
36194 -
36195 -+Tier 3:
36196 -+ * x86_64-fuchsia
36197 -+ * x86_64-unknown-redox
36198 -+ * x86_64-unknown-linux-gnux32
36199 -+
36200 - ## Usage
36201 -
36202 --`nix` requires Rust 1.31.0 or newer.
36203 -+`nix` requires Rust 1.40.0 or newer.
36204 -
36205 --To use `nix`, first add this to your `Cargo.toml`:
36206 -+To use `nix`, add this to your `Cargo.toml`:
36207 -
36208 - ```toml
36209 - [dependencies]
36210 --nix = "0.15.0"
36211 --```
36212 --
36213 --Then, add this to your crate root:
36214 --
36215 --```rust,ignore
36216 --extern crate nix;
36217 -+nix = "0.20.2"
36218 - ```
36219 -
36220 - ## Contributing
36221 -diff --git a/third_party/rust/nix/src/dir.rs b/third_party/rust/nix/src/dir.rs
36222 -index 1820b5330ff60..7d4ab82f79e0d 100644
36223 ---- a/third_party/rust/nix/src/dir.rs
36224 -+++ b/third_party/rust/nix/src/dir.rs
36225 -@@ -1,10 +1,10 @@
36226 --use {Error, NixPath, Result};
36227 --use errno::Errno;
36228 --use fcntl::{self, OFlag};
36229 --use libc;
36230 -+use crate::{Error, NixPath, Result};
36231 -+use crate::errno::Errno;
36232 -+use crate::fcntl::{self, OFlag};
36233 - use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
36234 --use std::{ffi, ptr};
36235 --use sys;
36236 -+use std::ptr;
36237 -+use std::ffi;
36238 -+use crate::sys;
36239 -
36240 - #[cfg(target_os = "linux")]
36241 - use libc::{dirent64 as dirent, readdir64_r as readdir_r};
36242 -@@ -25,7 +25,7 @@ use libc::{dirent, readdir_r};
36243 - /// * returns entries for `.` (current directory) and `..` (parent directory).
36244 - /// * returns entries' names as a `CStr` (no allocation or conversion beyond whatever libc
36245 - /// does).
36246 --#[derive(Clone, Debug, Eq, Hash, PartialEq)]
36247 -+#[derive(Debug, Eq, Hash, PartialEq)]
36248 - pub struct Dir(
36249 - ptr::NonNull<libc::DIR>
36250 - );
36251 -@@ -85,7 +85,32 @@ impl AsRawFd for Dir {
36252 -
36253 - impl Drop for Dir {
36254 - fn drop(&mut self) {
36255 -- unsafe { libc::closedir(self.0.as_ptr()) };
36256 -+ let e = Errno::result(unsafe { libc::closedir(self.0.as_ptr()) });
36257 -+ if !std::thread::panicking() && e == Err(Error::Sys(Errno::EBADF)) {
36258 -+ panic!("Closing an invalid file descriptor!");
36259 -+ };
36260 -+ }
36261 -+}
36262 -+
36263 -+fn next(dir: &mut Dir) -> Option<Result<Entry>> {
36264 -+ unsafe {
36265 -+ // Note: POSIX specifies that portable applications should dynamically allocate a
36266 -+ // buffer with room for a `d_name` field of size `pathconf(..., _PC_NAME_MAX)` plus 1
36267 -+ // for the NUL byte. It doesn't look like the std library does this; it just uses
36268 -+ // fixed-sized buffers (and libc's dirent seems to be sized so this is appropriate).
36269 -+ // Probably fine here too then.
36270 -+ let mut ent = std::mem::MaybeUninit::<dirent>::uninit();
36271 -+ let mut result = ptr::null_mut();
36272 -+ if let Err(e) = Errno::result(
36273 -+ readdir_r(dir.0.as_ptr(), ent.as_mut_ptr(), &mut result))
36274 -+ {
36275 -+ return Some(Err(e));
36276 -+ }
36277 -+ if result.is_null() {
36278 -+ return None;
36279 -+ }
36280 -+ assert_eq!(result, ent.as_mut_ptr());
36281 -+ Some(Ok(Entry(ent.assume_init())))
36282 - }
36283 - }
36284 -
36285 -@@ -96,23 +121,7 @@ impl<'d> Iterator for Iter<'d> {
36286 - type Item = Result<Entry>;
36287 -
36288 - fn next(&mut self) -> Option<Self::Item> {
36289 -- unsafe {
36290 -- // Note: POSIX specifies that portable applications should dynamically allocate a
36291 -- // buffer with room for a `d_name` field of size `pathconf(..., _PC_NAME_MAX)` plus 1
36292 -- // for the NUL byte. It doesn't look like the std library does this; it just uses
36293 -- // fixed-sized buffers (and libc's dirent seems to be sized so this is appropriate).
36294 -- // Probably fine here too then.
36295 -- let mut ent: Entry = Entry(::std::mem::uninitialized());
36296 -- let mut result = ptr::null_mut();
36297 -- if let Err(e) = Errno::result(readdir_r((self.0).0.as_ptr(), &mut ent.0, &mut result)) {
36298 -- return Some(Err(e));
36299 -- }
36300 -- if result == ptr::null_mut() {
36301 -- return None;
36302 -- }
36303 -- assert_eq!(result, &mut ent.0 as *mut dirent);
36304 -- return Some(Ok(ent));
36305 -- }
36306 -+ next(self.0)
36307 - }
36308 - }
36309 -
36310 -@@ -122,10 +131,48 @@ impl<'d> Drop for Iter<'d> {
36311 - }
36312 - }
36313 -
36314 -+/// The return type of [Dir::into_iter]
36315 -+#[derive(Debug, Eq, Hash, PartialEq)]
36316 -+pub struct OwningIter(Dir);
36317 -+
36318 -+impl Iterator for OwningIter {
36319 -+ type Item = Result<Entry>;
36320 -+
36321 -+ fn next(&mut self) -> Option<Self::Item> {
36322 -+ next(&mut self.0)
36323 -+ }
36324 -+}
36325 -+
36326 -+impl IntoIterator for Dir {
36327 -+ type Item = Result<Entry>;
36328 -+ type IntoIter = OwningIter;
36329 -+
36330 -+ /// Creates a owning iterator, that is, one that takes ownership of the
36331 -+ /// `Dir`. The `Dir` cannot be used after calling this. This can be useful
36332 -+ /// when you have a function that both creates a `Dir` instance and returns
36333 -+ /// an `Iterator`.
36334 -+ ///
36335 -+ /// Example:
36336 -+ ///
36337 -+ /// ```
36338 -+ /// use nix::{dir::Dir, fcntl::OFlag, sys::stat::Mode};
36339 -+ /// use std::{iter::Iterator, string::String};
36340 -+ ///
36341 -+ /// fn ls_upper(dirname: &str) -> impl Iterator<Item=String> {
36342 -+ /// let d = Dir::open(dirname, OFlag::O_DIRECTORY, Mode::S_IXUSR).unwrap();
36343 -+ /// d.into_iter().map(|x| x.unwrap().file_name().as_ref().to_string_lossy().to_ascii_uppercase())
36344 -+ /// }
36345 -+ /// ```
36346 -+ fn into_iter(self) -> Self::IntoIter {
36347 -+ OwningIter(self)
36348 -+ }
36349 -+}
36350 -+
36351 - /// A directory entry, similar to `std::fs::DirEntry`.
36352 - ///
36353 - /// Note that unlike the std version, this may represent the `.` or `..` entries.
36354 - #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
36355 -+#[repr(transparent)]
36356 - pub struct Entry(dirent);
36357 -
36358 - #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
36359 -@@ -165,7 +212,7 @@ impl Entry {
36360 - target_os = "macos",
36361 - target_os = "solaris")))]
36362 - pub fn ino(&self) -> u64 {
36363 -- self.0.d_fileno as u64
36364 -+ u64::from(self.0.d_fileno)
36365 - }
36366 -
36367 - /// Returns the bare file name of this directory entry without any other leading path component.
36368 -diff --git a/third_party/rust/nix/src/env.rs b/third_party/rust/nix/src/env.rs
36369 -new file mode 100644
36370 -index 0000000000000..f144dfedd0c1a
36371 ---- /dev/null
36372 -+++ b/third_party/rust/nix/src/env.rs
36373 -@@ -0,0 +1,53 @@
36374 -+use cfg_if::cfg_if;
36375 -+use crate::{Error, Result};
36376 -+
36377 -+/// Clear the environment of all name-value pairs.
36378 -+///
36379 -+/// On platforms where libc provides `clearenv()`, it will be used. libc's
36380 -+/// `clearenv()` is documented to return an error code but not set errno; if the
36381 -+/// return value indicates a failure, this function will return
36382 -+/// `Error::UnsupportedOperation`.
36383 -+///
36384 -+/// On platforms where libc does not provide `clearenv()`, a fallback
36385 -+/// implementation will be used that iterates over all environment variables and
36386 -+/// removes them one-by-one.
36387 -+///
36388 -+/// # Safety
36389 -+///
36390 -+/// This function is not threadsafe and can cause undefined behavior in
36391 -+/// combination with `std::env` or other program components that access the
36392 -+/// environment. See, for example, the discussion on `std::env::remove_var`; this
36393 -+/// function is a case of an "inherently unsafe non-threadsafe API" dealing with
36394 -+/// the environment.
36395 -+///
36396 -+/// The caller must ensure no other threads access the process environment while
36397 -+/// this function executes and that no raw pointers to an element of libc's
36398 -+/// `environ` is currently held. The latter is not an issue if the only other
36399 -+/// environment access in the program is via `std::env`, but the requirement on
36400 -+/// thread safety must still be upheld.
36401 -+pub unsafe fn clearenv() -> Result<()> {
36402 -+ let ret;
36403 -+ cfg_if! {
36404 -+ if #[cfg(any(target_os = "fuchsia",
36405 -+ target_os = "wasi",
36406 -+ target_env = "wasi",
36407 -+ target_env = "uclibc",
36408 -+ target_os = "linux",
36409 -+ target_os = "android",
36410 -+ target_os = "emscripten"))] {
36411 -+ ret = libc::clearenv();
36412 -+ } else {
36413 -+ use std::env;
36414 -+ for (name, _) in env::vars_os() {
36415 -+ env::remove_var(name);
36416 -+ }
36417 -+ ret = 0;
36418 -+ }
36419 -+ }
36420 -+
36421 -+ if ret == 0 {
36422 -+ Ok(())
36423 -+ } else {
36424 -+ Err(Error::UnsupportedOperation)
36425 -+ }
36426 -+}
36427 -diff --git a/third_party/rust/nix/src/errno.rs b/third_party/rust/nix/src/errno.rs
36428 -index 6a2447bc52675..e5c709252025c 100644
36429 ---- a/third_party/rust/nix/src/errno.rs
36430 -+++ b/third_party/rust/nix/src/errno.rs
36431 -@@ -1,8 +1,7 @@
36432 --#[cfg(not(target_os = "dragonfly"))]
36433 --use libc;
36434 -+use cfg_if::cfg_if;
36435 - use libc::{c_int, c_void};
36436 - use std::{fmt, io, error};
36437 --use {Error, Result};
36438 -+use crate::{Error, Result};
36439 -
36440 - pub use self::consts::*;
36441 -
36442 -@@ -13,32 +12,16 @@ cfg_if! {
36443 - unsafe fn errno_location() -> *mut c_int {
36444 - libc::__error()
36445 - }
36446 -- } else if #[cfg(target_os = "dragonfly")] {
36447 -- // DragonFly uses a thread-local errno variable, but #[thread_local] is
36448 -- // feature-gated and not available in stable Rust as of this writing
36449 -- // (Rust 1.21.0). We have to use a C extension to access it
36450 -- // (src/errno_dragonfly.c).
36451 -- //
36452 -- // Tracking issue for `thread_local` stabilization:
36453 -- //
36454 -- // https://github.com/rust-lang/rust/issues/29594
36455 -- //
36456 -- // Once this becomes stable, we can remove build.rs,
36457 -- // src/errno_dragonfly.c, and use:
36458 -- //
36459 -- // extern { #[thread_local] static errno: c_int; }
36460 -- //
36461 -- #[link(name="errno_dragonfly", kind="static")]
36462 -- extern {
36463 -- pub fn errno_location() -> *mut c_int;
36464 -- }
36465 - } else if #[cfg(any(target_os = "android",
36466 - target_os = "netbsd",
36467 - target_os = "openbsd"))] {
36468 - unsafe fn errno_location() -> *mut c_int {
36469 - libc::__errno()
36470 - }
36471 -- } else if #[cfg(target_os = "linux")] {
36472 -+ } else if #[cfg(any(target_os = "linux",
36473 -+ target_os = "redox",
36474 -+ target_os = "dragonfly",
36475 -+ target_os = "fuchsia"))] {
36476 - unsafe fn errno_location() -> *mut c_int {
36477 - libc::__errno_location()
36478 - }
36479 -@@ -46,8 +29,11 @@ cfg_if! {
36480 - }
36481 -
36482 - /// Sets the platform-specific errno to no-error
36483 --unsafe fn clear() -> () {
36484 -- *errno_location() = 0;
36485 -+fn clear() {
36486 -+ // Safe because errno is a thread-local variable
36487 -+ unsafe {
36488 -+ *errno_location() = 0;
36489 -+ }
36490 - }
36491 -
36492 - /// Returns the platform-specific value of errno
36493 -@@ -70,7 +56,7 @@ impl Errno {
36494 - from_i32(err)
36495 - }
36496 -
36497 -- pub unsafe fn clear() -> () {
36498 -+ pub fn clear() {
36499 - clear()
36500 - }
36501 -
36502 -@@ -111,11 +97,7 @@ impl ErrnoSentinel for libc::sighandler_t {
36503 - fn sentinel() -> Self { libc::SIG_ERR }
36504 - }
36505 -
36506 --impl error::Error for Errno {
36507 -- fn description(&self) -> &str {
36508 -- self.desc()
36509 -- }
36510 --}
36511 -+impl error::Error for Errno {}
36512 -
36513 - impl fmt::Display for Errno {
36514 - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36515 -@@ -207,200 +189,263 @@ fn desc(errno: Errno) -> &'static str {
36516 - EHOSTDOWN => "Host is down",
36517 - EHOSTUNREACH => "No route to host",
36518 -
36519 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36520 -+ #[cfg(any(target_os = "linux", target_os = "android",
36521 -+ target_os = "fuchsia"))]
36522 - ECHRNG => "Channel number out of range",
36523 -
36524 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36525 -+ #[cfg(any(target_os = "linux", target_os = "android",
36526 -+ target_os = "fuchsia"))]
36527 - EL2NSYNC => "Level 2 not synchronized",
36528 -
36529 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36530 -+ #[cfg(any(target_os = "linux", target_os = "android",
36531 -+ target_os = "fuchsia"))]
36532 - EL3HLT => "Level 3 halted",
36533 -
36534 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36535 -+ #[cfg(any(target_os = "linux", target_os = "android",
36536 -+ target_os = "fuchsia"))]
36537 - EL3RST => "Level 3 reset",
36538 -
36539 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36540 -+ #[cfg(any(target_os = "linux", target_os = "android",
36541 -+ target_os = "fuchsia"))]
36542 - ELNRNG => "Link number out of range",
36543 -
36544 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36545 -+ #[cfg(any(target_os = "linux", target_os = "android",
36546 -+ target_os = "fuchsia"))]
36547 - EUNATCH => "Protocol driver not attached",
36548 -
36549 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36550 -+ #[cfg(any(target_os = "linux", target_os = "android",
36551 -+ target_os = "fuchsia"))]
36552 - ENOCSI => "No CSI structure available",
36553 -
36554 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36555 -+ #[cfg(any(target_os = "linux", target_os = "android",
36556 -+ target_os = "fuchsia"))]
36557 - EL2HLT => "Level 2 halted",
36558 -
36559 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36560 -+ #[cfg(any(target_os = "linux", target_os = "android",
36561 -+ target_os = "fuchsia"))]
36562 - EBADE => "Invalid exchange",
36563 -
36564 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36565 -+ #[cfg(any(target_os = "linux", target_os = "android",
36566 -+ target_os = "fuchsia"))]
36567 - EBADR => "Invalid request descriptor",
36568 -
36569 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36570 -+ #[cfg(any(target_os = "linux", target_os = "android",
36571 -+ target_os = "fuchsia"))]
36572 - EXFULL => "Exchange full",
36573 -
36574 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36575 -+ #[cfg(any(target_os = "linux", target_os = "android",
36576 -+ target_os = "fuchsia"))]
36577 - ENOANO => "No anode",
36578 -
36579 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36580 -+ #[cfg(any(target_os = "linux", target_os = "android",
36581 -+ target_os = "fuchsia"))]
36582 - EBADRQC => "Invalid request code",
36583 -
36584 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36585 -+ #[cfg(any(target_os = "linux", target_os = "android",
36586 -+ target_os = "fuchsia"))]
36587 - EBADSLT => "Invalid slot",
36588 -
36589 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36590 -+ #[cfg(any(target_os = "linux", target_os = "android",
36591 -+ target_os = "fuchsia"))]
36592 - EBFONT => "Bad font file format",
36593 -
36594 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36595 -+ #[cfg(any(target_os = "linux", target_os = "android",
36596 -+ target_os = "fuchsia"))]
36597 - ENOSTR => "Device not a stream",
36598 -
36599 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36600 -+ #[cfg(any(target_os = "linux", target_os = "android",
36601 -+ target_os = "fuchsia"))]
36602 - ENODATA => "No data available",
36603 -
36604 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36605 -+ #[cfg(any(target_os = "linux", target_os = "android",
36606 -+ target_os = "fuchsia"))]
36607 - ETIME => "Timer expired",
36608 -
36609 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36610 -+ #[cfg(any(target_os = "linux", target_os = "android",
36611 -+ target_os = "fuchsia"))]
36612 - ENOSR => "Out of streams resources",
36613 -
36614 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36615 -+ #[cfg(any(target_os = "linux", target_os = "android",
36616 -+ target_os = "fuchsia"))]
36617 - ENONET => "Machine is not on the network",
36618 -
36619 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36620 -+ #[cfg(any(target_os = "linux", target_os = "android",
36621 -+ target_os = "fuchsia"))]
36622 - ENOPKG => "Package not installed",
36623 -
36624 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36625 -+ #[cfg(any(target_os = "linux", target_os = "android",
36626 -+ target_os = "fuchsia"))]
36627 - EREMOTE => "Object is remote",
36628 -
36629 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36630 -+ #[cfg(any(target_os = "linux", target_os = "android",
36631 -+ target_os = "fuchsia"))]
36632 - ENOLINK => "Link has been severed",
36633 -
36634 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36635 -+ #[cfg(any(target_os = "linux", target_os = "android",
36636 -+ target_os = "fuchsia"))]
36637 - EADV => "Advertise error",
36638 -
36639 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36640 -+ #[cfg(any(target_os = "linux", target_os = "android",
36641 -+ target_os = "fuchsia"))]
36642 - ESRMNT => "Srmount error",
36643 -
36644 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36645 -+ #[cfg(any(target_os = "linux", target_os = "android",
36646 -+ target_os = "fuchsia"))]
36647 - ECOMM => "Communication error on send",
36648 -
36649 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36650 -+ #[cfg(any(target_os = "linux", target_os = "android",
36651 -+ target_os = "fuchsia"))]
36652 - EPROTO => "Protocol error",
36653 -
36654 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36655 -+ #[cfg(any(target_os = "linux", target_os = "android",
36656 -+ target_os = "fuchsia"))]
36657 - EMULTIHOP => "Multihop attempted",
36658 -
36659 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36660 -+ #[cfg(any(target_os = "linux", target_os = "android",
36661 -+ target_os = "fuchsia"))]
36662 - EDOTDOT => "RFS specific error",
36663 -
36664 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36665 -+ #[cfg(any(target_os = "linux", target_os = "android",
36666 -+ target_os = "fuchsia"))]
36667 - EBADMSG => "Not a data message",
36668 -
36669 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36670 -+ #[cfg(any(target_os = "linux", target_os = "android",
36671 -+ target_os = "fuchsia"))]
36672 - EOVERFLOW => "Value too large for defined data type",
36673 -
36674 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36675 -+ #[cfg(any(target_os = "linux", target_os = "android",
36676 -+ target_os = "fuchsia"))]
36677 - ENOTUNIQ => "Name not unique on network",
36678 -
36679 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36680 -+ #[cfg(any(target_os = "linux", target_os = "android",
36681 -+ target_os = "fuchsia"))]
36682 - EBADFD => "File descriptor in bad state",
36683 -
36684 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36685 -+ #[cfg(any(target_os = "linux", target_os = "android",
36686 -+ target_os = "fuchsia"))]
36687 - EREMCHG => "Remote address changed",
36688 -
36689 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36690 -+ #[cfg(any(target_os = "linux", target_os = "android",
36691 -+ target_os = "fuchsia"))]
36692 - ELIBACC => "Can not access a needed shared library",
36693 -
36694 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36695 -+ #[cfg(any(target_os = "linux", target_os = "android",
36696 -+ target_os = "fuchsia"))]
36697 - ELIBBAD => "Accessing a corrupted shared library",
36698 -
36699 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36700 -+ #[cfg(any(target_os = "linux", target_os = "android",
36701 -+ target_os = "fuchsia"))]
36702 - ELIBSCN => ".lib section in a.out corrupted",
36703 -
36704 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36705 -+ #[cfg(any(target_os = "linux", target_os = "android",
36706 -+ target_os = "fuchsia"))]
36707 - ELIBMAX => "Attempting to link in too many shared libraries",
36708 -
36709 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36710 -+ #[cfg(any(target_os = "linux", target_os = "android",
36711 -+ target_os = "fuchsia"))]
36712 - ELIBEXEC => "Cannot exec a shared library directly",
36713 -
36714 -- #[cfg(any(target_os = "linux", target_os = "android", target_os = "openbsd"))]
36715 -+ #[cfg(any(target_os = "linux", target_os = "android",
36716 -+ target_os = "fuchsia", target_os = "openbsd"))]
36717 - EILSEQ => "Illegal byte sequence",
36718 -
36719 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36720 -+ #[cfg(any(target_os = "linux", target_os = "android",
36721 -+ target_os = "fuchsia"))]
36722 - ERESTART => "Interrupted system call should be restarted",
36723 -
36724 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36725 -+ #[cfg(any(target_os = "linux", target_os = "android",
36726 -+ target_os = "fuchsia"))]
36727 - ESTRPIPE => "Streams pipe error",
36728 -
36729 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36730 -+ #[cfg(any(target_os = "linux", target_os = "android",
36731 -+ target_os = "fuchsia"))]
36732 - EUSERS => "Too many users",
36733 -
36734 -- #[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))]
36735 -+ #[cfg(any(target_os = "linux", target_os = "android",
36736 -+ target_os = "fuchsia", target_os = "netbsd",
36737 -+ target_os = "redox"))]
36738 - EOPNOTSUPP => "Operation not supported on transport endpoint",
36739 -
36740 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36741 -+ #[cfg(any(target_os = "linux", target_os = "android",
36742 -+ target_os = "fuchsia"))]
36743 - ESTALE => "Stale file handle",
36744 -
36745 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36746 -+ #[cfg(any(target_os = "linux", target_os = "android",
36747 -+ target_os = "fuchsia"))]
36748 - EUCLEAN => "Structure needs cleaning",
36749 -
36750 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36751 -+ #[cfg(any(target_os = "linux", target_os = "android",
36752 -+ target_os = "fuchsia"))]
36753 - ENOTNAM => "Not a XENIX named type file",
36754 -
36755 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36756 -+ #[cfg(any(target_os = "linux", target_os = "android",
36757 -+ target_os = "fuchsia"))]
36758 - ENAVAIL => "No XENIX semaphores available",
36759 -
36760 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36761 -+ #[cfg(any(target_os = "linux", target_os = "android",
36762 -+ target_os = "fuchsia"))]
36763 - EISNAM => "Is a named type file",
36764 -
36765 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36766 -+ #[cfg(any(target_os = "linux", target_os = "android",
36767 -+ target_os = "fuchsia"))]
36768 - EREMOTEIO => "Remote I/O error",
36769 -
36770 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36771 -+ #[cfg(any(target_os = "linux", target_os = "android",
36772 -+ target_os = "fuchsia"))]
36773 - EDQUOT => "Quota exceeded",
36774 -
36775 - #[cfg(any(target_os = "linux", target_os = "android",
36776 -- target_os = "openbsd", target_os = "dragonfly"))]
36777 -+ target_os = "fuchsia", target_os = "openbsd",
36778 -+ target_os = "dragonfly"))]
36779 - ENOMEDIUM => "No medium found",
36780 -
36781 -- #[cfg(any(target_os = "linux", target_os = "android", target_os = "openbsd"))]
36782 -+ #[cfg(any(target_os = "linux", target_os = "android",
36783 -+ target_os = "fuchsia", target_os = "openbsd"))]
36784 - EMEDIUMTYPE => "Wrong medium type",
36785 -
36786 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36787 -+ #[cfg(any(target_os = "linux", target_os = "android",
36788 -+ target_os = "fuchsia"))]
36789 - ECANCELED => "Operation canceled",
36790 -
36791 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36792 -+ #[cfg(any(target_os = "linux", target_os = "android",
36793 -+ target_os = "fuchsia"))]
36794 - ENOKEY => "Required key not available",
36795 -
36796 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36797 -+ #[cfg(any(target_os = "linux", target_os = "android",
36798 -+ target_os = "fuchsia"))]
36799 - EKEYEXPIRED => "Key has expired",
36800 -
36801 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36802 -+ #[cfg(any(target_os = "linux", target_os = "android",
36803 -+ target_os = "fuchsia"))]
36804 - EKEYREVOKED => "Key has been revoked",
36805 -
36806 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36807 -+ #[cfg(any(target_os = "linux", target_os = "android",
36808 -+ target_os = "fuchsia"))]
36809 - EKEYREJECTED => "Key was rejected by service",
36810 -
36811 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36812 -+ #[cfg(any(target_os = "linux", target_os = "android",
36813 -+ target_os = "fuchsia"))]
36814 - EOWNERDEAD => "Owner died",
36815 -
36816 -- #[cfg(any(target_os = "linux", target_os = "android"))]
36817 -+ #[cfg(any(target_os = "linux", target_os = "android",
36818 -+ target_os = "fuchsia"))]
36819 - ENOTRECOVERABLE => "State not recoverable",
36820 -
36821 -- #[cfg(all(target_os = "linux", not(target_arch="mips")))]
36822 -+ #[cfg(any(all(target_os = "linux", not(target_arch="mips")),
36823 -+ target_os = "fuchsia"))]
36824 - ERFKILL => "Operation not possible due to RF-kill",
36825 -
36826 -- #[cfg(all(target_os = "linux", not(target_arch="mips")))]
36827 -+ #[cfg(any(all(target_os = "linux", not(target_arch="mips")),
36828 -+ target_os = "fuchsia"))]
36829 - EHWPOISON => "Memory page has hardware error",
36830 -
36831 - #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
36832 - EDOOFUS => "Programming error",
36833 -
36834 -- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
36835 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "redox"))]
36836 - EMULTIHOP => "Multihop attempted",
36837 -
36838 -- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
36839 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "redox"))]
36840 - ENOLINK => "Link has been severed",
36841 -
36842 - #[cfg(target_os = "freebsd")]
36843 -@@ -416,12 +461,13 @@ fn desc(errno: Errno) -> &'static str {
36844 -
36845 - #[cfg(any(target_os = "macos", target_os = "freebsd",
36846 - target_os = "dragonfly", target_os = "ios",
36847 -- target_os = "openbsd", target_os = "netbsd"))]
36848 -+ target_os = "openbsd", target_os = "netbsd",
36849 -+ target_os = "redox"))]
36850 - EOVERFLOW => "Value too large to be stored in data type",
36851 -
36852 - #[cfg(any(target_os = "macos", target_os = "freebsd",
36853 - target_os = "dragonfly", target_os = "ios",
36854 -- target_os = "netbsd"))]
36855 -+ target_os = "netbsd", target_os = "redox"))]
36856 - EILSEQ => "Illegal byte sequence",
36857 -
36858 - #[cfg(any(target_os = "macos", target_os = "freebsd",
36859 -@@ -431,12 +477,14 @@ fn desc(errno: Errno) -> &'static str {
36860 -
36861 - #[cfg(any(target_os = "macos", target_os = "freebsd",
36862 - target_os = "dragonfly", target_os = "ios",
36863 -- target_os = "openbsd", target_os = "netbsd"))]
36864 -+ target_os = "openbsd", target_os = "netbsd",
36865 -+ target_os = "redox"))]
36866 - EBADMSG => "Bad message",
36867 -
36868 - #[cfg(any(target_os = "macos", target_os = "freebsd",
36869 - target_os = "dragonfly", target_os = "ios",
36870 -- target_os = "openbsd", target_os = "netbsd"))]
36871 -+ target_os = "openbsd", target_os = "netbsd",
36872 -+ target_os = "redox"))]
36873 - EPROTO => "Protocol error",
36874 -
36875 - #[cfg(any(target_os = "macos", target_os = "freebsd",
36876 -@@ -459,22 +507,26 @@ fn desc(errno: Errno) -> &'static str {
36877 -
36878 - #[cfg(any(target_os = "macos", target_os = "freebsd",
36879 - target_os = "dragonfly", target_os = "ios",
36880 -- target_os = "openbsd", target_os = "netbsd"))]
36881 -+ target_os = "openbsd", target_os = "netbsd",
36882 -+ target_os = "redox"))]
36883 - EUSERS => "Too many users",
36884 -
36885 - #[cfg(any(target_os = "macos", target_os = "freebsd",
36886 - target_os = "dragonfly", target_os = "ios",
36887 -- target_os = "openbsd", target_os = "netbsd"))]
36888 -+ target_os = "openbsd", target_os = "netbsd",
36889 -+ target_os = "redox"))]
36890 - EDQUOT => "Disc quota exceeded",
36891 -
36892 - #[cfg(any(target_os = "macos", target_os = "freebsd",
36893 - target_os = "dragonfly", target_os = "ios",
36894 -- target_os = "openbsd", target_os = "netbsd"))]
36895 -+ target_os = "openbsd", target_os = "netbsd",
36896 -+ target_os = "redox"))]
36897 - ESTALE => "Stale NFS file handle",
36898 -
36899 - #[cfg(any(target_os = "macos", target_os = "freebsd",
36900 - target_os = "dragonfly", target_os = "ios",
36901 -- target_os = "openbsd", target_os = "netbsd"))]
36902 -+ target_os = "openbsd", target_os = "netbsd",
36903 -+ target_os = "redox"))]
36904 - EREMOTE => "Too many levels of remote in path",
36905 -
36906 - #[cfg(any(target_os = "macos", target_os = "freebsd",
36907 -@@ -514,7 +566,8 @@ fn desc(errno: Errno) -> &'static str {
36908 -
36909 - #[cfg(any(target_os = "macos", target_os = "freebsd",
36910 - target_os = "dragonfly", target_os = "ios",
36911 -- target_os = "openbsd", target_os = "netbsd"))]
36912 -+ target_os = "openbsd", target_os = "netbsd",
36913 -+ target_os = "redox"))]
36914 - ECANCELED => "Operation canceled",
36915 -
36916 - #[cfg(any(target_os = "macos", target_os = "ios"))]
36917 -@@ -538,19 +591,23 @@ fn desc(errno: Errno) -> &'static str {
36918 - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
36919 - EMULTIHOP => "Reserved",
36920 -
36921 -- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
36922 -+ #[cfg(any(target_os = "macos", target_os = "ios",
36923 -+ target_os = "netbsd", target_os = "redox"))]
36924 - ENODATA => "No message available on STREAM",
36925 -
36926 - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
36927 - ENOLINK => "Reserved",
36928 -
36929 -- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
36930 -+ #[cfg(any(target_os = "macos", target_os = "ios",
36931 -+ target_os = "netbsd", target_os = "redox"))]
36932 - ENOSR => "No STREAM resources",
36933 -
36934 -- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
36935 -+ #[cfg(any(target_os = "macos", target_os = "ios",
36936 -+ target_os = "netbsd", target_os = "redox"))]
36937 - ENOSTR => "Not a STREAM",
36938 -
36939 -- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))]
36940 -+ #[cfg(any(target_os = "macos", target_os = "ios",
36941 -+ target_os = "netbsd", target_os = "redox"))]
36942 - ETIME => "STREAM ioctl timeout",
36943 -
36944 - #[cfg(any(target_os = "macos", target_os = "ios"))]
36945 -@@ -573,10 +630,9 @@ fn desc(errno: Errno) -> &'static str {
36946 - }
36947 - }
36948 -
36949 --#[cfg(any(target_os = "linux", target_os = "android"))]
36950 -+#[cfg(any(target_os = "linux", target_os = "android",
36951 -+ target_os = "fuchsia"))]
36952 - mod consts {
36953 -- use libc;
36954 --
36955 - #[derive(Clone, Copy, Debug, Eq, PartialEq)]
36956 - #[repr(i32)]
36957 - pub enum Errno {
36958 -@@ -864,8 +920,6 @@ mod consts {
36959 -
36960 - #[cfg(any(target_os = "macos", target_os = "ios"))]
36961 - mod consts {
36962 -- use libc;
36963 --
36964 - #[derive(Clone, Copy, Debug, Eq, PartialEq)]
36965 - #[repr(i32)]
36966 - pub enum Errno {
36967 -@@ -1101,8 +1155,6 @@ mod consts {
36968 -
36969 - #[cfg(target_os = "freebsd")]
36970 - mod consts {
36971 -- use libc;
36972 --
36973 - #[derive(Clone, Copy, Debug, Eq, PartialEq)]
36974 - #[repr(i32)]
36975 - pub enum Errno {
36976 -@@ -1319,8 +1371,6 @@ mod consts {
36977 -
36978 - #[cfg(target_os = "dragonfly")]
36979 - mod consts {
36980 -- use libc;
36981 --
36982 - #[derive(Clone, Copy, Debug, Eq, PartialEq)]
36983 - #[repr(i32)]
36984 - pub enum Errno {
36985 -@@ -1534,8 +1584,6 @@ mod consts {
36986 -
36987 - #[cfg(target_os = "openbsd")]
36988 - mod consts {
36989 -- use libc;
36990 --
36991 - #[derive(Clone, Copy, Debug, Eq, PartialEq)]
36992 - #[repr(i32)]
36993 - pub enum Errno {
36994 -@@ -1748,8 +1796,6 @@ mod consts {
36995 -
36996 - #[cfg(target_os = "netbsd")]
36997 - mod consts {
36998 -- use libc;
36999 --
37000 - #[derive(Clone, Copy, Debug, Eq, PartialEq)]
37001 - #[repr(i32)]
37002 - pub enum Errno {
37003 -@@ -1961,3 +2007,195 @@ mod consts {
37004 - }
37005 - }
37006 - }
37007 -+
37008 -+#[cfg(target_os = "redox")]
37009 -+mod consts {
37010 -+ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
37011 -+ #[repr(i32)]
37012 -+ pub enum Errno {
37013 -+ UnknownErrno = 0,
37014 -+ EPERM = libc::EPERM,
37015 -+ ENOENT = libc::ENOENT,
37016 -+ ESRCH = libc::ESRCH,
37017 -+ EINTR = libc::EINTR,
37018 -+ EIO = libc::EIO,
37019 -+ ENXIO = libc::ENXIO,
37020 -+ E2BIG = libc::E2BIG,
37021 -+ ENOEXEC = libc::ENOEXEC,
37022 -+ EBADF = libc::EBADF,
37023 -+ ECHILD = libc::ECHILD,
37024 -+ EDEADLK = libc::EDEADLK,
37025 -+ ENOMEM = libc::ENOMEM,
37026 -+ EACCES = libc::EACCES,
37027 -+ EFAULT = libc::EFAULT,
37028 -+ ENOTBLK = libc::ENOTBLK,
37029 -+ EBUSY = libc::EBUSY,
37030 -+ EEXIST = libc::EEXIST,
37031 -+ EXDEV = libc::EXDEV,
37032 -+ ENODEV = libc::ENODEV,
37033 -+ ENOTDIR = libc::ENOTDIR,
37034 -+ EISDIR = libc::EISDIR,
37035 -+ EINVAL = libc::EINVAL,
37036 -+ ENFILE = libc::ENFILE,
37037 -+ EMFILE = libc::EMFILE,
37038 -+ ENOTTY = libc::ENOTTY,
37039 -+ ETXTBSY = libc::ETXTBSY,
37040 -+ EFBIG = libc::EFBIG,
37041 -+ ENOSPC = libc::ENOSPC,
37042 -+ ESPIPE = libc::ESPIPE,
37043 -+ EROFS = libc::EROFS,
37044 -+ EMLINK = libc::EMLINK,
37045 -+ EPIPE = libc::EPIPE,
37046 -+ EDOM = libc::EDOM,
37047 -+ ERANGE = libc::ERANGE,
37048 -+ EAGAIN = libc::EAGAIN,
37049 -+ EINPROGRESS = libc::EINPROGRESS,
37050 -+ EALREADY = libc::EALREADY,
37051 -+ ENOTSOCK = libc::ENOTSOCK,
37052 -+ EDESTADDRREQ = libc::EDESTADDRREQ,
37053 -+ EMSGSIZE = libc::EMSGSIZE,
37054 -+ EPROTOTYPE = libc::EPROTOTYPE,
37055 -+ ENOPROTOOPT = libc::ENOPROTOOPT,
37056 -+ EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
37057 -+ ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
37058 -+ EOPNOTSUPP = libc::EOPNOTSUPP,
37059 -+ EPFNOSUPPORT = libc::EPFNOSUPPORT,
37060 -+ EAFNOSUPPORT = libc::EAFNOSUPPORT,
37061 -+ EADDRINUSE = libc::EADDRINUSE,
37062 -+ EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
37063 -+ ENETDOWN = libc::ENETDOWN,
37064 -+ ENETUNREACH = libc::ENETUNREACH,
37065 -+ ENETRESET = libc::ENETRESET,
37066 -+ ECONNABORTED = libc::ECONNABORTED,
37067 -+ ECONNRESET = libc::ECONNRESET,
37068 -+ ENOBUFS = libc::ENOBUFS,
37069 -+ EISCONN = libc::EISCONN,
37070 -+ ENOTCONN = libc::ENOTCONN,
37071 -+ ESHUTDOWN = libc::ESHUTDOWN,
37072 -+ ETOOMANYREFS = libc::ETOOMANYREFS,
37073 -+ ETIMEDOUT = libc::ETIMEDOUT,
37074 -+ ECONNREFUSED = libc::ECONNREFUSED,
37075 -+ ELOOP = libc::ELOOP,
37076 -+ ENAMETOOLONG = libc::ENAMETOOLONG,
37077 -+ EHOSTDOWN = libc::EHOSTDOWN,
37078 -+ EHOSTUNREACH = libc::EHOSTUNREACH,
37079 -+ ENOTEMPTY = libc::ENOTEMPTY,
37080 -+ EUSERS = libc::EUSERS,
37081 -+ EDQUOT = libc::EDQUOT,
37082 -+ ESTALE = libc::ESTALE,
37083 -+ EREMOTE = libc::EREMOTE,
37084 -+ ENOLCK = libc::ENOLCK,
37085 -+ ENOSYS = libc::ENOSYS,
37086 -+ EIDRM = libc::EIDRM,
37087 -+ ENOMSG = libc::ENOMSG,
37088 -+ EOVERFLOW = libc::EOVERFLOW,
37089 -+ EILSEQ = libc::EILSEQ,
37090 -+ ECANCELED = libc::ECANCELED,
37091 -+ EBADMSG = libc::EBADMSG,
37092 -+ ENODATA = libc::ENODATA,
37093 -+ ENOSR = libc::ENOSR,
37094 -+ ENOSTR = libc::ENOSTR,
37095 -+ ETIME = libc::ETIME,
37096 -+ EMULTIHOP = libc::EMULTIHOP,
37097 -+ ENOLINK = libc::ENOLINK,
37098 -+ EPROTO = libc::EPROTO,
37099 -+ }
37100 -+
37101 -+ pub const ELAST: Errno = Errno::UnknownErrno;
37102 -+ pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
37103 -+
37104 -+ pub const EL2NSYNC: Errno = Errno::UnknownErrno;
37105 -+
37106 -+ pub fn from_i32(e: i32) -> Errno {
37107 -+ use self::Errno::*;
37108 -+
37109 -+ match e {
37110 -+ libc::EPERM => EPERM,
37111 -+ libc::ENOENT => ENOENT,
37112 -+ libc::ESRCH => ESRCH,
37113 -+ libc::EINTR => EINTR,
37114 -+ libc::EIO => EIO,
37115 -+ libc::ENXIO => ENXIO,
37116 -+ libc::E2BIG => E2BIG,
37117 -+ libc::ENOEXEC => ENOEXEC,
37118 -+ libc::EBADF => EBADF,
37119 -+ libc::ECHILD => ECHILD,
37120 -+ libc::EDEADLK => EDEADLK,
37121 -+ libc::ENOMEM => ENOMEM,
37122 -+ libc::EACCES => EACCES,
37123 -+ libc::EFAULT => EFAULT,
37124 -+ libc::ENOTBLK => ENOTBLK,
37125 -+ libc::EBUSY => EBUSY,
37126 -+ libc::EEXIST => EEXIST,
37127 -+ libc::EXDEV => EXDEV,
37128 -+ libc::ENODEV => ENODEV,
37129 -+ libc::ENOTDIR => ENOTDIR,
37130 -+ libc::EISDIR => EISDIR,
37131 -+ libc::EINVAL => EINVAL,
37132 -+ libc::ENFILE => ENFILE,
37133 -+ libc::EMFILE => EMFILE,
37134 -+ libc::ENOTTY => ENOTTY,
37135 -+ libc::ETXTBSY => ETXTBSY,
37136 -+ libc::EFBIG => EFBIG,
37137 -+ libc::ENOSPC => ENOSPC,
37138 -+ libc::ESPIPE => ESPIPE,
37139 -+ libc::EROFS => EROFS,
37140 -+ libc::EMLINK => EMLINK,
37141 -+ libc::EPIPE => EPIPE,
37142 -+ libc::EDOM => EDOM,
37143 -+ libc::ERANGE => ERANGE,
37144 -+ libc::EAGAIN => EAGAIN,
37145 -+ libc::EINPROGRESS => EINPROGRESS,
37146 -+ libc::EALREADY => EALREADY,
37147 -+ libc::ENOTSOCK => ENOTSOCK,
37148 -+ libc::EDESTADDRREQ => EDESTADDRREQ,
37149 -+ libc::EMSGSIZE => EMSGSIZE,
37150 -+ libc::EPROTOTYPE => EPROTOTYPE,
37151 -+ libc::ENOPROTOOPT => ENOPROTOOPT,
37152 -+ libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
37153 -+ libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
37154 -+ libc::EOPNOTSUPP => EOPNOTSUPP,
37155 -+ libc::EPFNOSUPPORT => EPFNOSUPPORT,
37156 -+ libc::EAFNOSUPPORT => EAFNOSUPPORT,
37157 -+ libc::EADDRINUSE => EADDRINUSE,
37158 -+ libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
37159 -+ libc::ENETDOWN => ENETDOWN,
37160 -+ libc::ENETUNREACH => ENETUNREACH,
37161 -+ libc::ENETRESET => ENETRESET,
37162 -+ libc::ECONNABORTED => ECONNABORTED,
37163 -+ libc::ECONNRESET => ECONNRESET,
37164 -+ libc::ENOBUFS => ENOBUFS,
37165 -+ libc::EISCONN => EISCONN,
37166 -+ libc::ENOTCONN => ENOTCONN,
37167 -+ libc::ESHUTDOWN => ESHUTDOWN,
37168 -+ libc::ETOOMANYREFS => ETOOMANYREFS,
37169 -+ libc::ETIMEDOUT => ETIMEDOUT,
37170 -+ libc::ECONNREFUSED => ECONNREFUSED,
37171 -+ libc::ELOOP => ELOOP,
37172 -+ libc::ENAMETOOLONG => ENAMETOOLONG,
37173 -+ libc::EHOSTDOWN => EHOSTDOWN,
37174 -+ libc::EHOSTUNREACH => EHOSTUNREACH,
37175 -+ libc::ENOTEMPTY => ENOTEMPTY,
37176 -+ libc::EUSERS => EUSERS,
37177 -+ libc::EDQUOT => EDQUOT,
37178 -+ libc::ESTALE => ESTALE,
37179 -+ libc::EREMOTE => EREMOTE,
37180 -+ libc::ENOLCK => ENOLCK,
37181 -+ libc::ENOSYS => ENOSYS,
37182 -+ libc::EIDRM => EIDRM,
37183 -+ libc::ENOMSG => ENOMSG,
37184 -+ libc::EOVERFLOW => EOVERFLOW,
37185 -+ libc::EILSEQ => EILSEQ,
37186 -+ libc::ECANCELED => ECANCELED,
37187 -+ libc::EBADMSG => EBADMSG,
37188 -+ libc::ENODATA => ENODATA,
37189 -+ libc::ENOSR => ENOSR,
37190 -+ libc::ENOSTR => ENOSTR,
37191 -+ libc::ETIME => ETIME,
37192 -+ libc::EMULTIHOP => EMULTIHOP,
37193 -+ libc::ENOLINK => ENOLINK,
37194 -+ libc::EPROTO => EPROTO,
37195 -+ _ => UnknownErrno,
37196 -+ }
37197 -+ }
37198 -+}
37199 -diff --git a/third_party/rust/nix/src/fcntl.rs b/third_party/rust/nix/src/fcntl.rs
37200 -index be6ee0f73a8be..d2242dacd61b0 100644
37201 ---- a/third_party/rust/nix/src/fcntl.rs
37202 -+++ b/third_party/rust/nix/src/fcntl.rs
37203 -@@ -1,29 +1,34 @@
37204 --use {Error, Result, NixPath};
37205 --use errno::Errno;
37206 --use libc::{self, c_int, c_uint, c_char, size_t, ssize_t};
37207 --use sys::stat::Mode;
37208 -+use crate::errno::Errno;
37209 -+use libc::{self, c_char, c_int, c_uint, size_t, ssize_t};
37210 -+use std::ffi::OsString;
37211 -+#[cfg(not(target_os = "redox"))]
37212 - use std::os::raw;
37213 -+use std::os::unix::ffi::OsStringExt;
37214 - use std::os::unix::io::RawFd;
37215 --use std::ffi::OsStr;
37216 --use std::os::unix::ffi::OsStrExt;
37217 -+use crate::sys::stat::Mode;
37218 -+use crate::{NixPath, Result};
37219 -
37220 - #[cfg(any(target_os = "android", target_os = "linux"))]
37221 - use std::ptr; // For splice and copy_file_range
37222 - #[cfg(any(target_os = "android", target_os = "linux"))]
37223 --use sys::uio::IoVec; // For vmsplice
37224 --
37225 --#[cfg(any(target_os = "linux",
37226 -- target_os = "android",
37227 -- target_os = "emscripten",
37228 -- target_os = "fuchsia",
37229 -- any(target_os = "wasi", target_env = "wasi"),
37230 -- target_env = "uclibc",
37231 -- target_env = "freebsd"))]
37232 -+use crate::sys::uio::IoVec; // For vmsplice
37233 -+
37234 -+#[cfg(any(
37235 -+ target_os = "linux",
37236 -+ target_os = "android",
37237 -+ target_os = "emscripten",
37238 -+ target_os = "fuchsia",
37239 -+ any(target_os = "wasi", target_env = "wasi"),
37240 -+ target_env = "uclibc",
37241 -+ target_os = "freebsd"
37242 -+))]
37243 - pub use self::posix_fadvise::*;
37244 -
37245 --libc_bitflags!{
37246 -+#[cfg(not(target_os = "redox"))]
37247 -+libc_bitflags! {
37248 - pub struct AtFlags: c_int {
37249 - AT_REMOVEDIR;
37250 -+ AT_SYMLINK_FOLLOW;
37251 - AT_SYMLINK_NOFOLLOW;
37252 - #[cfg(any(target_os = "android", target_os = "linux"))]
37253 - AT_NO_AUTOMOUNT;
37254 -@@ -78,7 +83,8 @@ libc_bitflags!(
37255 - target_os = "ios",
37256 - target_os = "macos",
37257 - target_os = "netbsd",
37258 -- target_os = "openbsd"))]
37259 -+ target_os = "openbsd",
37260 -+ target_os = "redox"))]
37261 - O_EXLOCK;
37262 - /// Same as `O_SYNC`.
37263 - #[cfg(any(target_os = "dragonfly",
37264 -@@ -87,7 +93,8 @@ libc_bitflags!(
37265 - all(target_os = "linux", not(target_env = "musl")),
37266 - target_os = "macos",
37267 - target_os = "netbsd",
37268 -- target_os = "openbsd"))]
37269 -+ target_os = "openbsd",
37270 -+ target_os = "redox"))]
37271 - O_FSYNC;
37272 - /// Allow files whose sizes can't be represented in an `off_t` to be opened.
37273 - #[cfg(any(target_os = "android", target_os = "linux"))]
37274 -@@ -96,8 +103,10 @@ libc_bitflags!(
37275 - #[cfg(any(target_os = "android", target_os = "linux"))]
37276 - O_NOATIME;
37277 - /// Don't attach the device as the process' controlling terminal.
37278 -+ #[cfg(not(target_os = "redox"))]
37279 - O_NOCTTY;
37280 - /// Same as `O_NONBLOCK`.
37281 -+ #[cfg(not(target_os = "redox"))]
37282 - O_NDELAY;
37283 - /// `open()` will fail if the given path is a symbolic link.
37284 - O_NOFOLLOW;
37285 -@@ -109,7 +118,7 @@ libc_bitflags!(
37286 - /// Obtain a file descriptor for low-level access.
37287 - ///
37288 - /// The file itself is not opened and other file operations will fail.
37289 -- #[cfg(any(target_os = "android", target_os = "linux"))]
37290 -+ #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
37291 - O_PATH;
37292 - /// Only allow reading.
37293 - ///
37294 -@@ -131,9 +140,11 @@ libc_bitflags!(
37295 - target_os = "ios",
37296 - target_os = "macos",
37297 - target_os = "netbsd",
37298 -- target_os = "openbsd"))]
37299 -+ target_os = "openbsd",
37300 -+ target_os = "redox"))]
37301 - O_SHLOCK;
37302 - /// Implicitly follow each `write()` with an `fsync()`.
37303 -+ #[cfg(not(target_os = "redox"))]
37304 - O_SYNC;
37305 - /// Create an unnamed temporary file.
37306 - #[cfg(any(target_os = "android", target_os = "linux"))]
37307 -@@ -150,6 +161,8 @@ libc_bitflags!(
37308 - }
37309 - );
37310 -
37311 -+// The conversion is not identical on all operating systems.
37312 -+#[allow(clippy::identity_conversion)]
37313 - pub fn open<P: ?Sized + NixPath>(path: &P, oflag: OFlag, mode: Mode) -> Result<RawFd> {
37314 - let fd = path.with_nix_path(|cstr| {
37315 - unsafe { libc::open(cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
37316 -@@ -158,56 +171,125 @@ pub fn open<P: ?Sized + NixPath>(path: &P, oflag: OFlag, mode: Mode) -> Result<R
37317 - Errno::result(fd)
37318 - }
37319 -
37320 --pub fn openat<P: ?Sized + NixPath>(dirfd: RawFd, path: &P, oflag: OFlag, mode: Mode) -> Result<RawFd> {
37321 -+// The conversion is not identical on all operating systems.
37322 -+#[allow(clippy::identity_conversion)]
37323 -+#[cfg(not(target_os = "redox"))]
37324 -+pub fn openat<P: ?Sized + NixPath>(
37325 -+ dirfd: RawFd,
37326 -+ path: &P,
37327 -+ oflag: OFlag,
37328 -+ mode: Mode,
37329 -+) -> Result<RawFd> {
37330 - let fd = path.with_nix_path(|cstr| {
37331 - unsafe { libc::openat(dirfd, cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
37332 - })?;
37333 - Errno::result(fd)
37334 - }
37335 -
37336 --pub fn renameat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(old_dirfd: Option<RawFd>, old_path: &P1,
37337 -- new_dirfd: Option<RawFd>, new_path: &P2)
37338 -- -> Result<()> {
37339 -+#[cfg(not(target_os = "redox"))]
37340 -+pub fn renameat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
37341 -+ old_dirfd: Option<RawFd>,
37342 -+ old_path: &P1,
37343 -+ new_dirfd: Option<RawFd>,
37344 -+ new_path: &P2,
37345 -+) -> Result<()> {
37346 - let res = old_path.with_nix_path(|old_cstr| {
37347 - new_path.with_nix_path(|new_cstr| unsafe {
37348 -- libc::renameat(at_rawfd(old_dirfd), old_cstr.as_ptr(),
37349 -- at_rawfd(new_dirfd), new_cstr.as_ptr())
37350 -+ libc::renameat(
37351 -+ at_rawfd(old_dirfd),
37352 -+ old_cstr.as_ptr(),
37353 -+ at_rawfd(new_dirfd),
37354 -+ new_cstr.as_ptr(),
37355 -+ )
37356 - })
37357 - })??;
37358 - Errno::result(res).map(drop)
37359 - }
37360 -
37361 --fn wrap_readlink_result(buffer: &mut[u8], res: ssize_t) -> Result<&OsStr> {
37362 -- match Errno::result(res) {
37363 -- Err(err) => Err(err),
37364 -- Ok(len) => {
37365 -- if (len as usize) >= buffer.len() {
37366 -- Err(Error::Sys(Errno::ENAMETOOLONG))
37367 -- } else {
37368 -- Ok(OsStr::from_bytes(&buffer[..(len as usize)]))
37369 -+fn wrap_readlink_result(mut v: Vec<u8>, len: ssize_t) -> Result<OsString> {
37370 -+ unsafe { v.set_len(len as usize) }
37371 -+ v.shrink_to_fit();
37372 -+ Ok(OsString::from_vec(v.to_vec()))
37373 -+}
37374 -+
37375 -+fn readlink_maybe_at<P: ?Sized + NixPath>(
37376 -+ dirfd: Option<RawFd>,
37377 -+ path: &P,
37378 -+ v: &mut Vec<u8>,
37379 -+) -> Result<libc::ssize_t> {
37380 -+ path.with_nix_path(|cstr| unsafe {
37381 -+ match dirfd {
37382 -+ #[cfg(target_os = "redox")]
37383 -+ Some(_) => unreachable!(),
37384 -+ #[cfg(not(target_os = "redox"))]
37385 -+ Some(dirfd) => libc::readlinkat(
37386 -+ dirfd,
37387 -+ cstr.as_ptr(),
37388 -+ v.as_mut_ptr() as *mut c_char,
37389 -+ v.capacity() as size_t,
37390 -+ ),
37391 -+ None => libc::readlink(
37392 -+ cstr.as_ptr(),
37393 -+ v.as_mut_ptr() as *mut c_char,
37394 -+ v.capacity() as size_t,
37395 -+ ),
37396 -+ }
37397 -+ })
37398 -+}
37399 -+
37400 -+fn inner_readlink<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P) -> Result<OsString> {
37401 -+ let mut v = Vec::with_capacity(libc::PATH_MAX as usize);
37402 -+ // simple case: result is strictly less than `PATH_MAX`
37403 -+ let res = readlink_maybe_at(dirfd, path, &mut v)?;
37404 -+ let len = Errno::result(res)?;
37405 -+ debug_assert!(len >= 0);
37406 -+ if (len as usize) < v.capacity() {
37407 -+ return wrap_readlink_result(v, res);
37408 -+ }
37409 -+ // Uh oh, the result is too long...
37410 -+ // Let's try to ask lstat how many bytes to allocate.
37411 -+ let reported_size = super::sys::stat::lstat(path)
37412 -+ .and_then(|x| Ok(x.st_size))
37413 -+ .unwrap_or(0);
37414 -+ let mut try_size = if reported_size > 0 {
37415 -+ // Note: even if `lstat`'s apparently valid answer turns out to be
37416 -+ // wrong, we will still read the full symlink no matter what.
37417 -+ reported_size as usize + 1
37418 -+ } else {
37419 -+ // If lstat doesn't cooperate, or reports an error, be a little less
37420 -+ // precise.
37421 -+ (libc::PATH_MAX as usize).max(128) << 1
37422 -+ };
37423 -+ loop {
37424 -+ v.reserve_exact(try_size);
37425 -+ let res = readlink_maybe_at(dirfd, path, &mut v)?;
37426 -+ let len = Errno::result(res)?;
37427 -+ debug_assert!(len >= 0);
37428 -+ if (len as usize) < v.capacity() {
37429 -+ break wrap_readlink_result(v, res);
37430 -+ } else {
37431 -+ // Ugh! Still not big enough!
37432 -+ match try_size.checked_shl(1) {
37433 -+ Some(next_size) => try_size = next_size,
37434 -+ // It's absurd that this would happen, but handle it sanely
37435 -+ // anyway.
37436 -+ None => break Err(super::Error::Sys(Errno::ENAMETOOLONG)),
37437 - }
37438 - }
37439 - }
37440 - }
37441 -
37442 --pub fn readlink<'a, P: ?Sized + NixPath>(path: &P, buffer: &'a mut [u8]) -> Result<&'a OsStr> {
37443 -- let res = path.with_nix_path(|cstr| {
37444 -- unsafe { libc::readlink(cstr.as_ptr(), buffer.as_mut_ptr() as *mut c_char, buffer.len() as size_t) }
37445 -- })?;
37446 --
37447 -- wrap_readlink_result(buffer, res)
37448 -+pub fn readlink<P: ?Sized + NixPath>(path: &P) -> Result<OsString> {
37449 -+ inner_readlink(None, path)
37450 - }
37451 -
37452 --
37453 --pub fn readlinkat<'a, P: ?Sized + NixPath>(dirfd: RawFd, path: &P, buffer: &'a mut [u8]) -> Result<&'a OsStr> {
37454 -- let res = path.with_nix_path(|cstr| {
37455 -- unsafe { libc::readlinkat(dirfd, cstr.as_ptr(), buffer.as_mut_ptr() as *mut c_char, buffer.len() as size_t) }
37456 -- })?;
37457 --
37458 -- wrap_readlink_result(buffer, res)
37459 -+#[cfg(not(target_os = "redox"))]
37460 -+pub fn readlinkat<P: ?Sized + NixPath>(dirfd: RawFd, path: &P) -> Result<OsString> {
37461 -+ inner_readlink(Some(dirfd), path)
37462 - }
37463 -
37464 - /// Computes the raw fd consumed by a function of the form `*at`.
37465 -+#[cfg(not(target_os = "redox"))]
37466 - pub(crate) fn at_rawfd(fd: Option<RawFd>) -> raw::c_int {
37467 - match fd {
37468 - None => libc::AT_FDCWD,
37469 -@@ -238,6 +320,7 @@ libc_bitflags!(
37470 - }
37471 - );
37472 -
37473 -+#[cfg(not(target_os = "redox"))]
37474 - #[derive(Debug, Eq, Hash, PartialEq)]
37475 - pub enum FcntlArg<'a> {
37476 - F_DUPFD(RawFd),
37477 -@@ -265,9 +348,19 @@ pub enum FcntlArg<'a> {
37478 - F_GETPIPE_SZ,
37479 - #[cfg(any(target_os = "linux", target_os = "android"))]
37480 - F_SETPIPE_SZ(c_int),
37481 --
37482 - // TODO: Rest of flags
37483 - }
37484 -+
37485 -+#[cfg(target_os = "redox")]
37486 -+#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)]
37487 -+pub enum FcntlArg {
37488 -+ F_DUPFD(RawFd),
37489 -+ F_DUPFD_CLOEXEC(RawFd),
37490 -+ F_GETFD,
37491 -+ F_SETFD(FdFlag), // FD_FLAGS
37492 -+ F_GETFL,
37493 -+ F_SETFL(OFlag), // O_NONBLOCK
37494 -+}
37495 - pub use self::FcntlArg::*;
37496 -
37497 - // TODO: Figure out how to handle value fcntl returns
37498 -@@ -280,10 +373,19 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
37499 - F_SETFD(flag) => libc::fcntl(fd, libc::F_SETFD, flag.bits()),
37500 - F_GETFL => libc::fcntl(fd, libc::F_GETFL),
37501 - F_SETFL(flag) => libc::fcntl(fd, libc::F_SETFL, flag.bits()),
37502 -+ #[cfg(not(target_os = "redox"))]
37503 - F_SETLK(flock) => libc::fcntl(fd, libc::F_SETLK, flock),
37504 -+ #[cfg(not(target_os = "redox"))]
37505 - F_SETLKW(flock) => libc::fcntl(fd, libc::F_SETLKW, flock),
37506 -+ #[cfg(not(target_os = "redox"))]
37507 - F_GETLK(flock) => libc::fcntl(fd, libc::F_GETLK, flock),
37508 - #[cfg(any(target_os = "android", target_os = "linux"))]
37509 -+ F_OFD_SETLK(flock) => libc::fcntl(fd, libc::F_OFD_SETLK, flock),
37510 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
37511 -+ F_OFD_SETLKW(flock) => libc::fcntl(fd, libc::F_OFD_SETLKW, flock),
37512 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
37513 -+ F_OFD_GETLK(flock) => libc::fcntl(fd, libc::F_OFD_GETLK, flock),
37514 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
37515 - F_ADD_SEALS(flag) => libc::fcntl(fd, libc::F_ADD_SEALS, flag.bits()),
37516 - #[cfg(any(target_os = "android", target_os = "linux"))]
37517 - F_GET_SEALS => libc::fcntl(fd, libc::F_GET_SEALS),
37518 -@@ -293,8 +395,6 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
37519 - F_GETPIPE_SZ => libc::fcntl(fd, libc::F_GETPIPE_SZ),
37520 - #[cfg(any(target_os = "linux", target_os = "android"))]
37521 - F_SETPIPE_SZ(size) => libc::fcntl(fd, libc::F_SETPIPE_SZ, size),
37522 -- #[cfg(any(target_os = "linux", target_os = "android"))]
37523 -- _ => unimplemented!()
37524 - }
37525 - };
37526 -
37527 -@@ -311,6 +411,7 @@ pub enum FlockArg {
37528 - UnlockNonblock,
37529 - }
37530 -
37531 -+#[cfg(not(target_os = "redox"))]
37532 - pub fn flock(fd: RawFd, arg: FlockArg) -> Result<()> {
37533 - use self::FlockArg::*;
37534 -
37535 -@@ -410,9 +511,7 @@ pub fn splice(
37536 - .map(|offset| offset as *mut libc::loff_t)
37537 - .unwrap_or(ptr::null_mut());
37538 -
37539 -- let ret = unsafe {
37540 -- libc::splice(fd_in, off_in, fd_out, off_out, len, flags.bits())
37541 -- };
37542 -+ let ret = unsafe { libc::splice(fd_in, off_in, fd_out, off_out, len, flags.bits()) };
37543 - Errno::result(ret).map(|r| r as usize)
37544 - }
37545 -
37546 -@@ -425,7 +524,12 @@ pub fn tee(fd_in: RawFd, fd_out: RawFd, len: usize, flags: SpliceFFlags) -> Resu
37547 - #[cfg(any(target_os = "linux", target_os = "android"))]
37548 - pub fn vmsplice(fd: RawFd, iov: &[IoVec<&[u8]>], flags: SpliceFFlags) -> Result<usize> {
37549 - let ret = unsafe {
37550 -- libc::vmsplice(fd, iov.as_ptr() as *const libc::iovec, iov.len(), flags.bits())
37551 -+ libc::vmsplice(
37552 -+ fd,
37553 -+ iov.as_ptr() as *const libc::iovec,
37554 -+ iov.len(),
37555 -+ flags.bits(),
37556 -+ )
37557 - };
37558 - Errno::result(ret).map(|r| r as usize)
37559 - }
37560 -@@ -466,23 +570,30 @@ libc_bitflags!(
37561 - /// Allows the caller to directly manipulate the allocated disk space for the
37562 - /// file referred to by fd.
37563 - #[cfg(any(target_os = "linux"))]
37564 --pub fn fallocate(fd: RawFd, mode: FallocateFlags, offset: libc::off_t, len: libc::off_t) -> Result<c_int> {
37565 -+pub fn fallocate(
37566 -+ fd: RawFd,
37567 -+ mode: FallocateFlags,
37568 -+ offset: libc::off_t,
37569 -+ len: libc::off_t,
37570 -+) -> Result<()> {
37571 - let res = unsafe { libc::fallocate(fd, mode.bits(), offset, len) };
37572 -- Errno::result(res)
37573 -+ Errno::result(res).map(drop)
37574 - }
37575 -
37576 --#[cfg(any(target_os = "linux",
37577 -- target_os = "android",
37578 -- target_os = "emscripten",
37579 -- target_os = "fuchsia",
37580 -- any(target_os = "wasi", target_env = "wasi"),
37581 -- target_env = "uclibc",
37582 -- target_env = "freebsd"))]
37583 -+#[cfg(any(
37584 -+ target_os = "linux",
37585 -+ target_os = "android",
37586 -+ target_os = "emscripten",
37587 -+ target_os = "fuchsia",
37588 -+ any(target_os = "wasi", target_env = "wasi"),
37589 -+ target_env = "uclibc",
37590 -+ target_os = "freebsd"
37591 -+))]
37592 - mod posix_fadvise {
37593 -- use Result;
37594 -+ use crate::errno::Errno;
37595 - use libc;
37596 -- use errno::Errno;
37597 - use std::os::unix::io::RawFd;
37598 -+ use crate::Result;
37599 -
37600 - libc_enum! {
37601 - #[repr(i32)]
37602 -@@ -496,11 +607,30 @@ mod posix_fadvise {
37603 - }
37604 - }
37605 -
37606 -- pub fn posix_fadvise(fd: RawFd,
37607 -- offset: libc::off_t,
37608 -- len: libc::off_t,
37609 -- advice: PosixFadviseAdvice) -> Result<libc::c_int> {
37610 -+ pub fn posix_fadvise(
37611 -+ fd: RawFd,
37612 -+ offset: libc::off_t,
37613 -+ len: libc::off_t,
37614 -+ advice: PosixFadviseAdvice,
37615 -+ ) -> Result<libc::c_int> {
37616 - let res = unsafe { libc::posix_fadvise(fd, offset, len, advice as libc::c_int) };
37617 - Errno::result(res)
37618 - }
37619 - }
37620 -+
37621 -+#[cfg(any(
37622 -+ target_os = "linux",
37623 -+ target_os = "android",
37624 -+ target_os = "emscripten",
37625 -+ target_os = "fuchsia",
37626 -+ any(target_os = "wasi", target_env = "wasi"),
37627 -+ target_os = "freebsd"
37628 -+))]
37629 -+pub fn posix_fallocate(fd: RawFd, offset: libc::off_t, len: libc::off_t) -> Result<()> {
37630 -+ let res = unsafe { libc::posix_fallocate(fd, offset, len) };
37631 -+ match Errno::result(res) {
37632 -+ Err(err) => Err(err),
37633 -+ Ok(0) => Ok(()),
37634 -+ Ok(errno) => Err(crate::Error::Sys(Errno::from_i32(errno))),
37635 -+ }
37636 -+}
37637 -diff --git a/third_party/rust/nix/src/features.rs b/third_party/rust/nix/src/features.rs
37638 -index 76cdfd3a1a6f1..6b1cff5deed1d 100644
37639 ---- a/third_party/rust/nix/src/features.rs
37640 -+++ b/third_party/rust/nix/src/features.rs
37641 -@@ -3,7 +3,7 @@ pub use self::os::*;
37642 -
37643 - #[cfg(any(target_os = "linux", target_os = "android"))]
37644 - mod os {
37645 -- use sys::utsname::uname;
37646 -+ use crate::sys::utsname::uname;
37647 -
37648 - // Features:
37649 - // * atomic cloexec on socket: 2.6.27
37650 -@@ -94,7 +94,10 @@ mod os {
37651 - }
37652 - }
37653 -
37654 --#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "dragonfly", target_os = "ios", target_os = "openbsd", target_os = "netbsd"))]
37655 -+#[cfg(any(target_os = "macos", target_os = "freebsd",
37656 -+ target_os = "dragonfly", target_os = "ios",
37657 -+ target_os = "openbsd", target_os = "netbsd",
37658 -+ target_os = "redox", target_os = "fuchsia"))]
37659 - mod os {
37660 - /// Check if the OS supports atomic close-on-exec for sockets
37661 - pub fn socket_atomic_cloexec() -> bool {
37662 -diff --git a/third_party/rust/nix/src/ifaddrs.rs b/third_party/rust/nix/src/ifaddrs.rs
37663 -index 12b59bcc92bef..ed6328f3efab2 100644
37664 ---- a/third_party/rust/nix/src/ifaddrs.rs
37665 -+++ b/third_party/rust/nix/src/ifaddrs.rs
37666 -@@ -3,16 +3,15 @@
37667 - //! Uses the Linux and/or BSD specific function `getifaddrs` to query the list
37668 - //! of interfaces and their associated addresses.
37669 -
37670 -+use cfg_if::cfg_if;
37671 - use std::ffi;
37672 - use std::iter::Iterator;
37673 - use std::mem;
37674 - use std::option::Option;
37675 -
37676 --use libc;
37677 --
37678 --use {Result, Errno};
37679 --use sys::socket::SockAddr;
37680 --use net::if_::*;
37681 -+use crate::{Result, Errno};
37682 -+use crate::sys::socket::SockAddr;
37683 -+use crate::net::if_::*;
37684 -
37685 - /// Describes a single address for an interface as returned by `getifaddrs`.
37686 - #[derive(Clone, Debug, Eq, Hash, PartialEq)]
37687 -@@ -52,8 +51,8 @@ impl InterfaceAddress {
37688 - let mut addr = InterfaceAddress {
37689 - interface_name: ifname.to_string_lossy().to_string(),
37690 - flags: InterfaceFlags::from_bits_truncate(info.ifa_flags as i32),
37691 -- address: address,
37692 -- netmask: netmask,
37693 -+ address,
37694 -+ netmask,
37695 - broadcast: None,
37696 - destination: None,
37697 - };
37698 -@@ -125,13 +124,15 @@ impl Iterator for InterfaceAddressIterator {
37699 - /// }
37700 - /// ```
37701 - pub fn getifaddrs() -> Result<InterfaceAddressIterator> {
37702 -- let mut addrs: *mut libc::ifaddrs = unsafe { mem::uninitialized() };
37703 -- Errno::result(unsafe { libc::getifaddrs(&mut addrs) }).map(|_| {
37704 -- InterfaceAddressIterator {
37705 -- base: addrs,
37706 -- next: addrs,
37707 -- }
37708 -- })
37709 -+ let mut addrs = mem::MaybeUninit::<*mut libc::ifaddrs>::uninit();
37710 -+ unsafe {
37711 -+ Errno::result(libc::getifaddrs(addrs.as_mut_ptr())).map(|_| {
37712 -+ InterfaceAddressIterator {
37713 -+ base: addrs.assume_init(),
37714 -+ next: addrs.assume_init(),
37715 -+ }
37716 -+ })
37717 -+ }
37718 - }
37719 -
37720 - #[cfg(test)]
37721 -diff --git a/third_party/rust/nix/src/kmod.rs b/third_party/rust/nix/src/kmod.rs
37722 -index e853261b14f9d..8789cb69f4617 100644
37723 ---- a/third_party/rust/nix/src/kmod.rs
37724 -+++ b/third_party/rust/nix/src/kmod.rs
37725 -@@ -6,8 +6,8 @@ use libc;
37726 - use std::ffi::CStr;
37727 - use std::os::unix::io::AsRawFd;
37728 -
37729 --use errno::Errno;
37730 --use Result;
37731 -+use crate::errno::Errno;
37732 -+use crate::Result;
37733 -
37734 - /// Loads a kernel module from a buffer.
37735 - ///
37736 -diff --git a/third_party/rust/nix/src/lib.rs b/third_party/rust/nix/src/lib.rs
37737 -index 71485d2af1824..e62c158c8bc9b 100644
37738 ---- a/third_party/rust/nix/src/lib.rs
37739 -+++ b/third_party/rust/nix/src/lib.rs
37740 -@@ -14,24 +14,17 @@
37741 - #![deny(unstable_features)]
37742 - #![deny(missing_copy_implementations)]
37743 - #![deny(missing_debug_implementations)]
37744 --// XXX Allow deprecated items until release 0.16.0. See issue #1096.
37745 --#![allow(deprecated)]
37746 --
37747 --// External crates
37748 --#[macro_use]
37749 --extern crate bitflags;
37750 --#[macro_use]
37751 --extern crate cfg_if;
37752 --extern crate void;
37753 -
37754 - // Re-exported external crates
37755 --pub extern crate libc;
37756 -+pub use libc;
37757 -
37758 - // Private internal modules
37759 - #[macro_use] mod macros;
37760 -
37761 - // Public crates
37762 -+#[cfg(not(target_os = "redox"))]
37763 - pub mod dir;
37764 -+pub mod env;
37765 - pub mod errno;
37766 - #[deny(missing_docs)]
37767 - pub mod features;
37768 -@@ -59,13 +52,16 @@ pub mod mount;
37769 - target_os = "netbsd"))]
37770 - pub mod mqueue;
37771 - #[deny(missing_docs)]
37772 -+#[cfg(not(target_os = "redox"))]
37773 - pub mod net;
37774 - #[deny(missing_docs)]
37775 - pub mod poll;
37776 - #[deny(missing_docs)]
37777 -+#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
37778 - pub mod pty;
37779 - pub mod sched;
37780 - pub mod sys;
37781 -+pub mod time;
37782 - // This can be implemented for other platforms as soon as libc
37783 - // provides bindings for them.
37784 - #[cfg(all(target_os = "linux",
37785 -@@ -121,9 +117,9 @@ impl Error {
37786 - /// let e = Error::from(Errno::EPERM);
37787 - /// assert_eq!(Some(Errno::EPERM), e.as_errno());
37788 - /// ```
37789 -- pub fn as_errno(&self) -> Option<Errno> {
37790 -- if let &Error::Sys(ref e) = self {
37791 -- Some(*e)
37792 -+ pub fn as_errno(self) -> Option<Errno> {
37793 -+ if let Error::Sys(e) = self {
37794 -+ Some(e)
37795 - } else {
37796 - None
37797 - }
37798 -@@ -154,16 +150,7 @@ impl From<std::string::FromUtf8Error> for Error {
37799 - fn from(_: std::string::FromUtf8Error) -> Error { Error::InvalidUtf8 }
37800 - }
37801 -
37802 --impl error::Error for Error {
37803 -- fn description(&self) -> &str {
37804 -- match *self {
37805 -- Error::InvalidPath => "Invalid path",
37806 -- Error::InvalidUtf8 => "Invalid UTF-8 string",
37807 -- Error::UnsupportedOperation => "Unsupported Operation",
37808 -- Error::Sys(ref errno) => errno.desc(),
37809 -- }
37810 -- }
37811 --}
37812 -+impl error::Error for Error {}
37813 -
37814 - impl fmt::Display for Error {
37815 - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37816 -@@ -177,6 +164,8 @@ impl fmt::Display for Error {
37817 - }
37818 -
37819 - pub trait NixPath {
37820 -+ fn is_empty(&self) -> bool;
37821 -+
37822 - fn len(&self) -> usize;
37823 -
37824 - fn with_nix_path<T, F>(&self, f: F) -> Result<T>
37825 -@@ -184,6 +173,10 @@ pub trait NixPath {
37826 - }
37827 -
37828 - impl NixPath for str {
37829 -+ fn is_empty(&self) -> bool {
37830 -+ NixPath::is_empty(OsStr::new(self))
37831 -+ }
37832 -+
37833 - fn len(&self) -> usize {
37834 - NixPath::len(OsStr::new(self))
37835 - }
37836 -@@ -195,6 +188,10 @@ impl NixPath for str {
37837 - }
37838 -
37839 - impl NixPath for OsStr {
37840 -+ fn is_empty(&self) -> bool {
37841 -+ self.as_bytes().is_empty()
37842 -+ }
37843 -+
37844 - fn len(&self) -> usize {
37845 - self.as_bytes().len()
37846 - }
37847 -@@ -206,6 +203,10 @@ impl NixPath for OsStr {
37848 - }
37849 -
37850 - impl NixPath for CStr {
37851 -+ fn is_empty(&self) -> bool {
37852 -+ self.to_bytes().is_empty()
37853 -+ }
37854 -+
37855 - fn len(&self) -> usize {
37856 - self.to_bytes().len()
37857 - }
37858 -@@ -222,6 +223,10 @@ impl NixPath for CStr {
37859 - }
37860 -
37861 - impl NixPath for [u8] {
37862 -+ fn is_empty(&self) -> bool {
37863 -+ self.is_empty()
37864 -+ }
37865 -+
37866 - fn len(&self) -> usize {
37867 - self.len()
37868 - }
37869 -@@ -249,6 +254,10 @@ impl NixPath for [u8] {
37870 - }
37871 -
37872 - impl NixPath for Path {
37873 -+ fn is_empty(&self) -> bool {
37874 -+ NixPath::is_empty(self.as_os_str())
37875 -+ }
37876 -+
37877 - fn len(&self) -> usize {
37878 - NixPath::len(self.as_os_str())
37879 - }
37880 -@@ -259,26 +268,15 @@ impl NixPath for Path {
37881 - }
37882 -
37883 - impl NixPath for PathBuf {
37884 -- fn len(&self) -> usize {
37885 -- NixPath::len(self.as_os_str())
37886 -+ fn is_empty(&self) -> bool {
37887 -+ NixPath::is_empty(self.as_os_str())
37888 - }
37889 -
37890 -- fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
37891 -- self.as_os_str().with_nix_path(f)
37892 -- }
37893 --}
37894 --
37895 --/// Treats `None` as an empty string.
37896 --impl<'a, NP: ?Sized + NixPath> NixPath for Option<&'a NP> {
37897 - fn len(&self) -> usize {
37898 -- self.map_or(0, NixPath::len)
37899 -+ NixPath::len(self.as_os_str())
37900 - }
37901 -
37902 - fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
37903 -- if let Some(nix_path) = *self {
37904 -- nix_path.with_nix_path(f)
37905 -- } else {
37906 -- unsafe { CStr::from_ptr("\0".as_ptr() as *const _).with_nix_path(f) }
37907 -- }
37908 -+ self.as_os_str().with_nix_path(f)
37909 - }
37910 - }
37911 -diff --git a/third_party/rust/nix/src/macros.rs b/third_party/rust/nix/src/macros.rs
37912 -index 3d1b0e4b7699c..7d6ac8dfbf5f7 100644
37913 ---- a/third_party/rust/nix/src/macros.rs
37914 -+++ b/third_party/rust/nix/src/macros.rs
37915 -@@ -48,7 +48,7 @@ macro_rules! libc_bitflags {
37916 - )+
37917 - }
37918 - ) => {
37919 -- bitflags! {
37920 -+ ::bitflags::bitflags! {
37921 - $(#[$outer])*
37922 - pub struct $BitFlags: $T {
37923 - $(
37924 -@@ -81,9 +81,10 @@ macro_rules! libc_bitflags {
37925 - /// }
37926 - /// ```
37927 - macro_rules! libc_enum {
37928 -- // (non-pub) Exit rule.
37929 -+ // Exit rule.
37930 - (@make_enum
37931 - {
37932 -+ $v:vis
37933 - name: $BitFlags:ident,
37934 - attrs: [$($attrs:tt)*],
37935 - entries: [$($entries:tt)*],
37936 -@@ -91,49 +92,15 @@ macro_rules! libc_enum {
37937 - ) => {
37938 - $($attrs)*
37939 - #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
37940 -- enum $BitFlags {
37941 -+ $v enum $BitFlags {
37942 - $($entries)*
37943 - }
37944 - };
37945 -
37946 -- // (pub) Exit rule.
37947 -- (@make_enum
37948 -- {
37949 -- pub,
37950 -- name: $BitFlags:ident,
37951 -- attrs: [$($attrs:tt)*],
37952 -- entries: [$($entries:tt)*],
37953 -- }
37954 -- ) => {
37955 -- $($attrs)*
37956 -- #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
37957 -- pub enum $BitFlags {
37958 -- $($entries)*
37959 -- }
37960 -- };
37961 --
37962 -- // (non-pub) Done accumulating.
37963 -- (@accumulate_entries
37964 -- {
37965 -- name: $BitFlags:ident,
37966 -- attrs: $attrs:tt,
37967 -- },
37968 -- $entries:tt;
37969 -- ) => {
37970 -- libc_enum! {
37971 -- @make_enum
37972 -- {
37973 -- name: $BitFlags,
37974 -- attrs: $attrs,
37975 -- entries: $entries,
37976 -- }
37977 -- }
37978 -- };
37979 --
37980 -- // (pub) Done accumulating.
37981 -+ // Done accumulating.
37982 - (@accumulate_entries
37983 - {
37984 -- pub,
37985 -+ $v:vis
37986 - name: $BitFlags:ident,
37987 - attrs: $attrs:tt,
37988 - },
37989 -@@ -142,7 +109,7 @@ macro_rules! libc_enum {
37990 - libc_enum! {
37991 - @make_enum
37992 - {
37993 -- pub,
37994 -+ $v
37995 - name: $BitFlags,
37996 - attrs: $attrs,
37997 - entries: $entries,
37998 -@@ -217,35 +184,17 @@ macro_rules! libc_enum {
37999 - }
38000 - };
38001 -
38002 -- // (non-pub) Entry rule.
38003 -- (
38004 -- $(#[$attr:meta])*
38005 -- enum $BitFlags:ident {
38006 -- $($vals:tt)*
38007 -- }
38008 -- ) => {
38009 -- libc_enum! {
38010 -- @accumulate_entries
38011 -- {
38012 -- name: $BitFlags,
38013 -- attrs: [$(#[$attr])*],
38014 -- },
38015 -- [];
38016 -- $($vals)*
38017 -- }
38018 -- };
38019 --
38020 -- // (pub) Entry rule.
38021 -+ // Entry rule.
38022 - (
38023 - $(#[$attr:meta])*
38024 -- pub enum $BitFlags:ident {
38025 -+ $v:vis enum $BitFlags:ident {
38026 - $($vals:tt)*
38027 - }
38028 - ) => {
38029 - libc_enum! {
38030 - @accumulate_entries
38031 - {
38032 -- pub,
38033 -+ $v
38034 - name: $BitFlags,
38035 - attrs: [$(#[$attr])*],
38036 - },
38037 -@@ -254,11 +203,3 @@ macro_rules! libc_enum {
38038 - }
38039 - };
38040 - }
38041 --
38042 --/// A Rust version of the familiar C `offset_of` macro. It returns the byte
38043 --/// offset of `field` within struct `ty`
38044 --macro_rules! offset_of {
38045 -- ($ty:ty, $field:ident) => {
38046 -- &(*(0 as *const $ty)).$field as *const _ as usize
38047 -- }
38048 --}
38049 -diff --git a/third_party/rust/nix/src/mount.rs b/third_party/rust/nix/src/mount.rs
38050 -index a9902b170ace8..2c54761e2bb0c 100644
38051 ---- a/third_party/rust/nix/src/mount.rs
38052 -+++ b/third_party/rust/nix/src/mount.rs
38053 -@@ -1,6 +1,6 @@
38054 - use libc::{self, c_ulong, c_int};
38055 --use {Result, NixPath};
38056 --use errno::Errno;
38057 -+use crate::{Result, NixPath};
38058 -+use crate::errno::Errno;
38059 -
38060 - libc_bitflags!(
38061 - pub struct MsFlags: c_ulong {
38062 -@@ -61,22 +61,33 @@ pub fn mount<P1: ?Sized + NixPath, P2: ?Sized + NixPath, P3: ?Sized + NixPath, P
38063 - flags: MsFlags,
38064 - data: Option<&P4>) -> Result<()> {
38065 -
38066 -- let res =
38067 -- source.with_nix_path(|source| {
38068 -- target.with_nix_path(|target| {
38069 -- fstype.with_nix_path(|fstype| {
38070 -- data.with_nix_path(|data| {
38071 -- unsafe {
38072 -- libc::mount(source.as_ptr(),
38073 -- target.as_ptr(),
38074 -- fstype.as_ptr(),
38075 -- flags.bits,
38076 -- data.as_ptr() as *const libc::c_void)
38077 -- }
38078 -- })
38079 -+ fn with_opt_nix_path<P, T, F>(p: Option<&P>, f: F) -> Result<T>
38080 -+ where P: ?Sized + NixPath,
38081 -+ F: FnOnce(*const libc::c_char) -> T
38082 -+ {
38083 -+ match p {
38084 -+ Some(path) => path.with_nix_path(|p_str| f(p_str.as_ptr())),
38085 -+ None => Ok(f(std::ptr::null()))
38086 -+ }
38087 -+ }
38088 -+
38089 -+ let res = with_opt_nix_path(source, |s| {
38090 -+ target.with_nix_path(|t| {
38091 -+ with_opt_nix_path(fstype, |ty| {
38092 -+ with_opt_nix_path(data, |d| {
38093 -+ unsafe {
38094 -+ libc::mount(
38095 -+ s,
38096 -+ t.as_ptr(),
38097 -+ ty,
38098 -+ flags.bits,
38099 -+ d as *const libc::c_void
38100 -+ )
38101 -+ }
38102 - })
38103 - })
38104 -- })????;
38105 -+ })
38106 -+ })????;
38107 -
38108 - Errno::result(res).map(drop)
38109 - }
38110 -diff --git a/third_party/rust/nix/src/mqueue.rs b/third_party/rust/nix/src/mqueue.rs
38111 -index b958b71cddb46..0215de5af214b 100644
38112 ---- a/third_party/rust/nix/src/mqueue.rs
38113 -+++ b/third_party/rust/nix/src/mqueue.rs
38114 -@@ -2,12 +2,12 @@
38115 - //!
38116 - //! [Further reading and details on the C API](http://man7.org/linux/man-pages/man7/mq_overview.7.html)
38117 -
38118 --use Result;
38119 --use errno::Errno;
38120 -+use crate::Result;
38121 -+use crate::errno::Errno;
38122 -
38123 --use libc::{self, c_char, c_long, mqd_t, size_t};
38124 -+use libc::{self, c_char, mqd_t, size_t};
38125 - use std::ffi::CString;
38126 --use sys::stat::Mode;
38127 -+use crate::sys::stat::Mode;
38128 - use std::mem;
38129 -
38130 - libc_bitflags!{
38131 -@@ -34,21 +34,32 @@ pub struct MqAttr {
38132 - mq_attr: libc::mq_attr,
38133 - }
38134 -
38135 -+// x32 compatibility
38136 -+// See https://sourceware.org/bugzilla/show_bug.cgi?id=21279
38137 -+#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
38138 -+pub type mq_attr_member_t = i64;
38139 -+#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
38140 -+pub type mq_attr_member_t = libc::c_long;
38141 -+
38142 - impl MqAttr {
38143 -- pub fn new(mq_flags: c_long,
38144 -- mq_maxmsg: c_long,
38145 -- mq_msgsize: c_long,
38146 -- mq_curmsgs: c_long)
38147 -- -> MqAttr {
38148 -- let mut attr = unsafe { mem::uninitialized::<libc::mq_attr>() };
38149 -- attr.mq_flags = mq_flags;
38150 -- attr.mq_maxmsg = mq_maxmsg;
38151 -- attr.mq_msgsize = mq_msgsize;
38152 -- attr.mq_curmsgs = mq_curmsgs;
38153 -- MqAttr { mq_attr: attr }
38154 -+ pub fn new(mq_flags: mq_attr_member_t,
38155 -+ mq_maxmsg: mq_attr_member_t,
38156 -+ mq_msgsize: mq_attr_member_t,
38157 -+ mq_curmsgs: mq_attr_member_t)
38158 -+ -> MqAttr
38159 -+ {
38160 -+ let mut attr = mem::MaybeUninit::<libc::mq_attr>::uninit();
38161 -+ unsafe {
38162 -+ let p = attr.as_mut_ptr();
38163 -+ (*p).mq_flags = mq_flags;
38164 -+ (*p).mq_maxmsg = mq_maxmsg;
38165 -+ (*p).mq_msgsize = mq_msgsize;
38166 -+ (*p).mq_curmsgs = mq_curmsgs;
38167 -+ MqAttr { mq_attr: attr.assume_init() }
38168 -+ }
38169 - }
38170 -
38171 -- pub fn flags(&self) -> c_long {
38172 -+ pub fn flags(&self) -> mq_attr_member_t {
38173 - self.mq_attr.mq_flags
38174 - }
38175 - }
38176 -@@ -57,6 +68,8 @@ impl MqAttr {
38177 - /// Open a message queue
38178 - ///
38179 - /// See also [`mq_open(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_open.html)
38180 -+// The mode.bits cast is only lossless on some OSes
38181 -+#[allow(clippy::cast_lossless)]
38182 - pub fn mq_open(name: &CString,
38183 - oflag: MQ_OFlag,
38184 - mode: Mode,
38185 -@@ -121,9 +134,9 @@ pub fn mq_send(mqdes: mqd_t, message: &[u8], msq_prio: u32) -> Result<()> {
38186 - ///
38187 - /// See also [`mq_getattr(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_getattr.html)
38188 - pub fn mq_getattr(mqd: mqd_t) -> Result<MqAttr> {
38189 -- let mut attr = unsafe { mem::uninitialized::<libc::mq_attr>() };
38190 -- let res = unsafe { libc::mq_getattr(mqd, &mut attr) };
38191 -- Errno::result(res).map(|_| MqAttr { mq_attr: attr })
38192 -+ let mut attr = mem::MaybeUninit::<libc::mq_attr>::uninit();
38193 -+ let res = unsafe { libc::mq_getattr(mqd, attr.as_mut_ptr()) };
38194 -+ Errno::result(res).map(|_| unsafe{MqAttr { mq_attr: attr.assume_init() }})
38195 - }
38196 -
38197 - /// Set the attributes of the message queue. Only `O_NONBLOCK` can be set, everything else will be ignored
38198 -@@ -132,17 +145,19 @@ pub fn mq_getattr(mqd: mqd_t) -> Result<MqAttr> {
38199 - ///
38200 - /// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_setattr.html)
38201 - pub fn mq_setattr(mqd: mqd_t, newattr: &MqAttr) -> Result<MqAttr> {
38202 -- let mut attr = unsafe { mem::uninitialized::<libc::mq_attr>() };
38203 -- let res = unsafe { libc::mq_setattr(mqd, &newattr.mq_attr as *const libc::mq_attr, &mut attr) };
38204 -- Errno::result(res).map(|_| MqAttr { mq_attr: attr })
38205 -+ let mut attr = mem::MaybeUninit::<libc::mq_attr>::uninit();
38206 -+ let res = unsafe {
38207 -+ libc::mq_setattr(mqd, &newattr.mq_attr as *const libc::mq_attr, attr.as_mut_ptr())
38208 -+ };
38209 -+ Errno::result(res).map(|_| unsafe{ MqAttr { mq_attr: attr.assume_init() }})
38210 - }
38211 -
38212 - /// Convenience function.
38213 - /// Sets the `O_NONBLOCK` attribute for a given message queue descriptor
38214 - /// Returns the old attributes
38215 --pub fn mq_set_nonblock(mqd: mqd_t) -> Result<(MqAttr)> {
38216 -+pub fn mq_set_nonblock(mqd: mqd_t) -> Result<MqAttr> {
38217 - let oldattr = mq_getattr(mqd)?;
38218 -- let newattr = MqAttr::new(MQ_OFlag::O_NONBLOCK.bits() as c_long,
38219 -+ let newattr = MqAttr::new(mq_attr_member_t::from(MQ_OFlag::O_NONBLOCK.bits()),
38220 - oldattr.mq_attr.mq_maxmsg,
38221 - oldattr.mq_attr.mq_msgsize,
38222 - oldattr.mq_attr.mq_curmsgs);
38223 -@@ -152,7 +167,7 @@ pub fn mq_set_nonblock(mqd: mqd_t) -> Result<(MqAttr)> {
38224 - /// Convenience function.
38225 - /// Removes `O_NONBLOCK` attribute for a given message queue descriptor
38226 - /// Returns the old attributes
38227 --pub fn mq_remove_nonblock(mqd: mqd_t) -> Result<(MqAttr)> {
38228 -+pub fn mq_remove_nonblock(mqd: mqd_t) -> Result<MqAttr> {
38229 - let oldattr = mq_getattr(mqd)?;
38230 - let newattr = MqAttr::new(0,
38231 - oldattr.mq_attr.mq_maxmsg,
38232 -diff --git a/third_party/rust/nix/src/net/if_.rs b/third_party/rust/nix/src/net/if_.rs
38233 -index 58d677ae343d1..96364884e39cb 100644
38234 ---- a/third_party/rust/nix/src/net/if_.rs
38235 -+++ b/third_party/rust/nix/src/net/if_.rs
38236 -@@ -3,9 +3,8 @@
38237 - //! Uses Linux and/or POSIX functions to resolve interface names like "eth0"
38238 - //! or "socan1" into device numbers.
38239 -
38240 --use libc;
38241 - use libc::c_uint;
38242 --use {Result, Error, NixPath};
38243 -+use crate::{Result, Error, NixPath};
38244 -
38245 - /// Resolve an interface into a interface number.
38246 - pub fn if_nametoindex<P: ?Sized + NixPath>(name: &P) -> Result<c_uint> {
38247 -diff --git a/third_party/rust/nix/src/poll.rs b/third_party/rust/nix/src/poll.rs
38248 -index c603611e3176f..be5bf224990f2 100644
38249 ---- a/third_party/rust/nix/src/poll.rs
38250 -+++ b/third_party/rust/nix/src/poll.rs
38251 -@@ -1,13 +1,12 @@
38252 - //! Wait for events to trigger on specific file descriptors
38253 - #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
38254 --use sys::time::TimeSpec;
38255 -+use crate::sys::time::TimeSpec;
38256 - #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
38257 --use sys::signal::SigSet;
38258 -+use crate::sys::signal::SigSet;
38259 - use std::os::unix::io::RawFd;
38260 -
38261 --use libc;
38262 --use Result;
38263 --use errno::Errno;
38264 -+use crate::Result;
38265 -+use crate::errno::Errno;
38266 -
38267 - /// This is a wrapper around `libc::pollfd`.
38268 - ///
38269 -@@ -17,7 +16,7 @@ use errno::Errno;
38270 - ///
38271 - /// After a call to `poll` or `ppoll`, the events that occured can be
38272 - /// retrieved by calling [`revents()`](#method.revents) on the `PollFd`.
38273 --#[repr(C)]
38274 -+#[repr(transparent)]
38275 - #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
38276 - pub struct PollFd {
38277 - pollfd: libc::pollfd,
38278 -@@ -29,7 +28,7 @@ impl PollFd {
38279 - pub fn new(fd: RawFd, events: PollFlags) -> PollFd {
38280 - PollFd {
38281 - pollfd: libc::pollfd {
38282 -- fd: fd,
38283 -+ fd,
38284 - events: events.bits(),
38285 - revents: PollFlags::empty().bits(),
38286 - },
38287 -@@ -37,7 +36,7 @@ impl PollFd {
38288 - }
38289 -
38290 - /// Returns the events that occured in the last call to `poll` or `ppoll`.
38291 -- pub fn revents(&self) -> Option<PollFlags> {
38292 -+ pub fn revents(self) -> Option<PollFlags> {
38293 - PollFlags::from_bits(self.pollfd.revents)
38294 - }
38295 - }
38296 -@@ -64,12 +63,16 @@ libc_bitflags! {
38297 - /// `O_NONBLOCK` is set).
38298 - POLLOUT;
38299 - /// Equivalent to [`POLLIN`](constant.POLLIN.html)
38300 -+ #[cfg(not(target_os = "redox"))]
38301 - POLLRDNORM;
38302 -+ #[cfg(not(target_os = "redox"))]
38303 - /// Equivalent to [`POLLOUT`](constant.POLLOUT.html)
38304 - POLLWRNORM;
38305 - /// Priority band data can be read (generally unused on Linux).
38306 -+ #[cfg(not(target_os = "redox"))]
38307 - POLLRDBAND;
38308 - /// Priority data may be written.
38309 -+ #[cfg(not(target_os = "redox"))]
38310 - POLLWRBAND;
38311 - /// Error condition (only returned in
38312 - /// [`PollFd::revents`](struct.PollFd.html#method.revents);
38313 -@@ -127,16 +130,16 @@ pub fn poll(fds: &mut [PollFd], timeout: libc::c_int) -> Result<libc::c_int> {
38314 - /// ([`poll(2)`](http://man7.org/linux/man-pages/man2/poll.2.html))
38315 - ///
38316 - /// `ppoll` behaves like `poll`, but let you specify what signals may interrupt it
38317 --/// with the `sigmask` argument.
38318 -+/// with the `sigmask` argument. If you want `ppoll` to block indefinitely,
38319 -+/// specify `None` as `timeout` (it is like `timeout = -1` for `poll`).
38320 - ///
38321 - #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
38322 --pub fn ppoll(fds: &mut [PollFd], timeout: TimeSpec, sigmask: SigSet) -> Result<libc::c_int> {
38323 --
38324 --
38325 -+pub fn ppoll(fds: &mut [PollFd], timeout: Option<TimeSpec>, sigmask: SigSet) -> Result<libc::c_int> {
38326 -+ let timeout = timeout.as_ref().map_or(core::ptr::null(), |r| r.as_ref());
38327 - let res = unsafe {
38328 - libc::ppoll(fds.as_mut_ptr() as *mut libc::pollfd,
38329 - fds.len() as libc::nfds_t,
38330 -- timeout.as_ref(),
38331 -+ timeout,
38332 - sigmask.as_ref())
38333 - };
38334 - Errno::result(res)
38335 -diff --git a/third_party/rust/nix/src/pty.rs b/third_party/rust/nix/src/pty.rs
38336 -index db012d8158c53..d67518f4744f3 100644
38337 ---- a/third_party/rust/nix/src/pty.rs
38338 -+++ b/third_party/rust/nix/src/pty.rs
38339 -@@ -1,18 +1,17 @@
38340 - //! Create master and slave virtual pseudo-terminals (PTYs)
38341 -
38342 --use libc;
38343 --
38344 - pub use libc::pid_t as SessionId;
38345 - pub use libc::winsize as Winsize;
38346 -
38347 - use std::ffi::CStr;
38348 -+use std::io;
38349 - use std::mem;
38350 - use std::os::unix::prelude::*;
38351 -
38352 --use sys::termios::Termios;
38353 --use unistd::ForkResult;
38354 --use {Result, Error, fcntl};
38355 --use errno::Errno;
38356 -+use crate::sys::termios::Termios;
38357 -+use crate::unistd::{self, ForkResult, Pid};
38358 -+use crate::{Result, Error, fcntl};
38359 -+use crate::errno::Errno;
38360 -
38361 - /// Representation of a master/slave pty pair
38362 - ///
38363 -@@ -44,7 +43,7 @@ pub struct ForkptyResult {
38364 - /// While this datatype is a thin wrapper around `RawFd`, it enforces that the available PTY
38365 - /// functions are given the correct file descriptor. Additionally this type implements `Drop`,
38366 - /// so that when it's consumed or goes out of scope, it's automatically cleaned-up.
38367 --#[derive(Clone, Debug, Eq, Hash, PartialEq)]
38368 -+#[derive(Debug, Eq, Hash, PartialEq)]
38369 - pub struct PtyMaster(RawFd);
38370 -
38371 - impl AsRawFd for PtyMaster {
38372 -@@ -70,13 +69,28 @@ impl Drop for PtyMaster {
38373 - // invalid file descriptor. That frequently indicates a double-close
38374 - // condition, which can cause confusing errors for future I/O
38375 - // operations.
38376 -- let e = ::unistd::close(self.0);
38377 -+ let e = unistd::close(self.0);
38378 - if e == Err(Error::Sys(Errno::EBADF)) {
38379 - panic!("Closing an invalid file descriptor!");
38380 - };
38381 - }
38382 - }
38383 -
38384 -+impl io::Read for PtyMaster {
38385 -+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
38386 -+ unistd::read(self.0, buf).map_err(|e| e.as_errno().unwrap().into())
38387 -+ }
38388 -+}
38389 -+
38390 -+impl io::Write for PtyMaster {
38391 -+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
38392 -+ unistd::write(self.0, buf).map_err(|e| e.as_errno().unwrap().into())
38393 -+ }
38394 -+ fn flush(&mut self) -> io::Result<()> {
38395 -+ Ok(())
38396 -+ }
38397 -+}
38398 -+
38399 - /// Grant access to a slave pseudoterminal (see
38400 - /// [`grantpt(3)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/grantpt.html))
38401 - ///
38402 -@@ -218,16 +232,16 @@ pub fn unlockpt(fd: &PtyMaster) -> Result<()> {
38403 - pub fn openpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b Termios>>>(winsize: T, termios: U) -> Result<OpenptyResult> {
38404 - use std::ptr;
38405 -
38406 -- let mut slave: libc::c_int = unsafe { mem::uninitialized() };
38407 -- let mut master: libc::c_int = unsafe { mem::uninitialized() };
38408 -+ let mut slave = mem::MaybeUninit::<libc::c_int>::uninit();
38409 -+ let mut master = mem::MaybeUninit::<libc::c_int>::uninit();
38410 - let ret = {
38411 - match (termios.into(), winsize.into()) {
38412 - (Some(termios), Some(winsize)) => {
38413 - let inner_termios = termios.get_libc_termios();
38414 - unsafe {
38415 - libc::openpty(
38416 -- &mut master,
38417 -- &mut slave,
38418 -+ master.as_mut_ptr(),
38419 -+ slave.as_mut_ptr(),
38420 - ptr::null_mut(),
38421 - &*inner_termios as *const libc::termios as *mut _,
38422 - winsize as *const Winsize as *mut _,
38423 -@@ -237,8 +251,8 @@ pub fn openpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b Termios>
38424 - (None, Some(winsize)) => {
38425 - unsafe {
38426 - libc::openpty(
38427 -- &mut master,
38428 -- &mut slave,
38429 -+ master.as_mut_ptr(),
38430 -+ slave.as_mut_ptr(),
38431 - ptr::null_mut(),
38432 - ptr::null_mut(),
38433 - winsize as *const Winsize as *mut _,
38434 -@@ -249,8 +263,8 @@ pub fn openpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b Termios>
38435 - let inner_termios = termios.get_libc_termios();
38436 - unsafe {
38437 - libc::openpty(
38438 -- &mut master,
38439 -- &mut slave,
38440 -+ master.as_mut_ptr(),
38441 -+ slave.as_mut_ptr(),
38442 - ptr::null_mut(),
38443 - &*inner_termios as *const libc::termios as *mut _,
38444 - ptr::null_mut(),
38445 -@@ -260,8 +274,8 @@ pub fn openpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b Termios>
38446 - (None, None) => {
38447 - unsafe {
38448 - libc::openpty(
38449 -- &mut master,
38450 -- &mut slave,
38451 -+ master.as_mut_ptr(),
38452 -+ slave.as_mut_ptr(),
38453 - ptr::null_mut(),
38454 - ptr::null_mut(),
38455 - ptr::null_mut(),
38456 -@@ -273,10 +287,12 @@ pub fn openpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b Termios>
38457 -
38458 - Errno::result(ret)?;
38459 -
38460 -- Ok(OpenptyResult {
38461 -- master: master,
38462 -- slave: slave,
38463 -- })
38464 -+ unsafe {
38465 -+ Ok(OpenptyResult {
38466 -+ master: master.assume_init(),
38467 -+ slave: slave.assume_init(),
38468 -+ })
38469 -+ }
38470 - }
38471 -
38472 - /// Create a new pseudoterminal, returning the master file descriptor and forked pid.
38473 -@@ -291,10 +307,8 @@ pub fn forkpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b Termios>
38474 - termios: U,
38475 - ) -> Result<ForkptyResult> {
38476 - use std::ptr;
38477 -- use unistd::Pid;
38478 -- use unistd::ForkResult::*;
38479 -
38480 -- let mut master: libc::c_int = unsafe { mem::uninitialized() };
38481 -+ let mut master = mem::MaybeUninit::<libc::c_int>::uninit();
38482 -
38483 - let term = match termios.into() {
38484 - Some(termios) => {
38485 -@@ -310,17 +324,19 @@ pub fn forkpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b Termios>
38486 - .unwrap_or(ptr::null_mut());
38487 -
38488 - let res = unsafe {
38489 -- libc::forkpty(&mut master, ptr::null_mut(), term, win)
38490 -+ libc::forkpty(master.as_mut_ptr(), ptr::null_mut(), term, win)
38491 - };
38492 -
38493 - let fork_result = Errno::result(res).map(|res| match res {
38494 -- 0 => Child,
38495 -- res => Parent { child: Pid::from_raw(res) },
38496 -+ 0 => ForkResult::Child,
38497 -+ res => ForkResult::Parent { child: Pid::from_raw(res) },
38498 - })?;
38499 -
38500 -- Ok(ForkptyResult {
38501 -- master: master,
38502 -- fork_result: fork_result,
38503 -- })
38504 -+ unsafe {
38505 -+ Ok(ForkptyResult {
38506 -+ master: master.assume_init(),
38507 -+ fork_result,
38508 -+ })
38509 -+ }
38510 - }
38511 -
38512 -diff --git a/third_party/rust/nix/src/sched.rs b/third_party/rust/nix/src/sched.rs
38513 -index 67188c57eef7d..3b48b4adf6d05 100644
38514 ---- a/third_party/rust/nix/src/sched.rs
38515 -+++ b/third_party/rust/nix/src/sched.rs
38516 -@@ -1,18 +1,17 @@
38517 --use libc;
38518 --use {Errno, Result};
38519 -+use crate::{Errno, Result};
38520 -
38521 - #[cfg(any(target_os = "android", target_os = "linux"))]
38522 - pub use self::sched_linux_like::*;
38523 -
38524 - #[cfg(any(target_os = "android", target_os = "linux"))]
38525 - mod sched_linux_like {
38526 -- use errno::Errno;
38527 -+ use crate::errno::Errno;
38528 - use libc::{self, c_int, c_void};
38529 - use std::mem;
38530 - use std::option::Option;
38531 - use std::os::unix::io::RawFd;
38532 -- use unistd::Pid;
38533 -- use {Error, Result};
38534 -+ use crate::unistd::Pid;
38535 -+ use crate::{Error, Result};
38536 -
38537 - // For some functions taking with a parameter of type CloneFlags,
38538 - // only a subset of these flags have an effect.
38539 -@@ -46,6 +45,11 @@ mod sched_linux_like {
38540 -
38541 - pub type CloneCb<'a> = Box<dyn FnMut() -> isize + 'a>;
38542 -
38543 -+ /// CpuSet represent a bit-mask of CPUs.
38544 -+ /// CpuSets are used by sched_setaffinity and
38545 -+ /// sched_getaffinity for example.
38546 -+ ///
38547 -+ /// This is a wrapper around `libc::cpu_set_t`.
38548 - #[repr(C)]
38549 - #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
38550 - pub struct CpuSet {
38551 -@@ -53,37 +57,78 @@ mod sched_linux_like {
38552 - }
38553 -
38554 - impl CpuSet {
38555 -+ /// Create a new and empty CpuSet.
38556 - pub fn new() -> CpuSet {
38557 - CpuSet {
38558 - cpu_set: unsafe { mem::zeroed() },
38559 - }
38560 - }
38561 -
38562 -+ /// Test to see if a CPU is in the CpuSet.
38563 -+ /// `field` is the CPU id to test
38564 - pub fn is_set(&self, field: usize) -> Result<bool> {
38565 -- if field >= 8 * mem::size_of::<libc::cpu_set_t>() {
38566 -+ if field >= CpuSet::count() {
38567 - Err(Error::Sys(Errno::EINVAL))
38568 - } else {
38569 - Ok(unsafe { libc::CPU_ISSET(field, &self.cpu_set) })
38570 - }
38571 - }
38572 -
38573 -+ /// Add a CPU to CpuSet.
38574 -+ /// `field` is the CPU id to add
38575 - pub fn set(&mut self, field: usize) -> Result<()> {
38576 -- if field >= 8 * mem::size_of::<libc::cpu_set_t>() {
38577 -+ if field >= CpuSet::count() {
38578 - Err(Error::Sys(Errno::EINVAL))
38579 - } else {
38580 -- Ok(unsafe { libc::CPU_SET(field, &mut self.cpu_set) })
38581 -+ unsafe { libc::CPU_SET(field, &mut self.cpu_set); }
38582 -+ Ok(())
38583 - }
38584 - }
38585 -
38586 -+ /// Remove a CPU from CpuSet.
38587 -+ /// `field` is the CPU id to remove
38588 - pub fn unset(&mut self, field: usize) -> Result<()> {
38589 -- if field >= 8 * mem::size_of::<libc::cpu_set_t>() {
38590 -+ if field >= CpuSet::count() {
38591 - Err(Error::Sys(Errno::EINVAL))
38592 - } else {
38593 -- Ok(unsafe { libc::CPU_CLR(field, &mut self.cpu_set) })
38594 -+ unsafe { libc::CPU_CLR(field, &mut self.cpu_set);}
38595 -+ Ok(())
38596 - }
38597 - }
38598 -+
38599 -+ /// Return the maximum number of CPU in CpuSet
38600 -+ pub fn count() -> usize {
38601 -+ 8 * mem::size_of::<libc::cpu_set_t>()
38602 -+ }
38603 - }
38604 -
38605 -+ impl Default for CpuSet {
38606 -+ fn default() -> Self {
38607 -+ Self::new()
38608 -+ }
38609 -+ }
38610 -+
38611 -+ /// `sched_setaffinity` set a thread's CPU affinity mask
38612 -+ /// ([`sched_setaffinity(2)`](http://man7.org/linux/man-pages/man2/sched_setaffinity.2.html))
38613 -+ ///
38614 -+ /// `pid` is the thread ID to update.
38615 -+ /// If pid is zero, then the calling thread is updated.
38616 -+ ///
38617 -+ /// The `cpuset` argument specifies the set of CPUs on which the thread
38618 -+ /// will be eligible to run.
38619 -+ ///
38620 -+ /// # Example
38621 -+ ///
38622 -+ /// Binding the current thread to CPU 0 can be done as follows:
38623 -+ ///
38624 -+ /// ```rust,no_run
38625 -+ /// use nix::sched::{CpuSet, sched_setaffinity};
38626 -+ /// use nix::unistd::Pid;
38627 -+ ///
38628 -+ /// let mut cpu_set = CpuSet::new();
38629 -+ /// cpu_set.set(0);
38630 -+ /// sched_setaffinity(Pid::from_raw(0), &cpu_set);
38631 -+ /// ```
38632 - pub fn sched_setaffinity(pid: Pid, cpuset: &CpuSet) -> Result<()> {
38633 - let res = unsafe {
38634 - libc::sched_setaffinity(
38635 -@@ -96,6 +141,41 @@ mod sched_linux_like {
38636 - Errno::result(res).map(drop)
38637 - }
38638 -
38639 -+ /// `sched_getaffinity` get a thread's CPU affinity mask
38640 -+ /// ([`sched_getaffinity(2)`](http://man7.org/linux/man-pages/man2/sched_getaffinity.2.html))
38641 -+ ///
38642 -+ /// `pid` is the thread ID to check.
38643 -+ /// If pid is zero, then the calling thread is checked.
38644 -+ ///
38645 -+ /// Returned `cpuset` is the set of CPUs on which the thread
38646 -+ /// is eligible to run.
38647 -+ ///
38648 -+ /// # Example
38649 -+ ///
38650 -+ /// Checking if the current thread can run on CPU 0 can be done as follows:
38651 -+ ///
38652 -+ /// ```rust,no_run
38653 -+ /// use nix::sched::sched_getaffinity;
38654 -+ /// use nix::unistd::Pid;
38655 -+ ///
38656 -+ /// let cpu_set = sched_getaffinity(Pid::from_raw(0)).unwrap();
38657 -+ /// if cpu_set.is_set(0).unwrap() {
38658 -+ /// println!("Current thread can run on CPU 0");
38659 -+ /// }
38660 -+ /// ```
38661 -+ pub fn sched_getaffinity(pid: Pid) -> Result<CpuSet> {
38662 -+ let mut cpuset = CpuSet::new();
38663 -+ let res = unsafe {
38664 -+ libc::sched_getaffinity(
38665 -+ pid.into(),
38666 -+ mem::size_of::<CpuSet>() as libc::size_t,
38667 -+ &mut cpuset.cpu_set,
38668 -+ )
38669 -+ };
38670 -+
38671 -+ Errno::result(res).and(Ok(cpuset))
38672 -+ }
38673 -+
38674 - pub fn clone(
38675 - mut cb: CloneCb,
38676 - stack: &mut [u8],
38677 -@@ -109,8 +189,8 @@ mod sched_linux_like {
38678 -
38679 - let res = unsafe {
38680 - let combined = flags.bits() | signal.unwrap_or(0);
38681 -- let ptr = stack.as_mut_ptr().offset(stack.len() as isize);
38682 -- let ptr_aligned = ptr.offset((ptr as usize % 16) as isize * -1);
38683 -+ let ptr = stack.as_mut_ptr().add(stack.len());
38684 -+ let ptr_aligned = ptr.sub(ptr as usize % 16);
38685 - libc::clone(
38686 - mem::transmute(
38687 - callback as extern "C" fn(*mut Box<dyn FnMut() -> isize>) -> i32,
38688 -diff --git a/third_party/rust/nix/src/sys/aio.rs b/third_party/rust/nix/src/sys/aio.rs
38689 -index 9258a0657cc8a..1afdb35866c28 100644
38690 ---- a/third_party/rust/nix/src/sys/aio.rs
38691 -+++ b/third_party/rust/nix/src/sys/aio.rs
38692 -@@ -21,20 +21,19 @@
38693 - //! [`aio_cancel_all`](fn.aio_cancel_all.html), though the operating system may
38694 - //! not support this for all filesystems and devices.
38695 -
38696 --use {Error, Result};
38697 --use errno::Errno;
38698 -+use crate::{Error, Result};
38699 -+use crate::errno::Errno;
38700 - use std::os::unix::io::RawFd;
38701 - use libc::{c_void, off_t, size_t};
38702 --use libc;
38703 - use std::borrow::{Borrow, BorrowMut};
38704 - use std::fmt;
38705 - use std::fmt::Debug;
38706 - use std::marker::PhantomData;
38707 - use std::mem;
38708 - use std::ptr::{null, null_mut};
38709 --use sys::signal::*;
38710 -+use crate::sys::signal::*;
38711 - use std::thread;
38712 --use sys::time::TimeSpec;
38713 -+use crate::sys::time::TimeSpec;
38714 -
38715 - libc_enum! {
38716 - /// Mode for `AioCb::fsync`. Controls whether only data or both data and
38717 -@@ -226,8 +225,6 @@ impl<'a> AioCb<'a> {
38718 - /// [`fsync`](#method.fsync) operation.
38719 - ///
38720 - /// ```
38721 -- /// # extern crate tempfile;
38722 -- /// # extern crate nix;
38723 - /// # use nix::errno::Errno;
38724 - /// # use nix::Error;
38725 - /// # use nix::sys::aio::*;
38726 -@@ -287,8 +284,6 @@ impl<'a> AioCb<'a> {
38727 - /// Create an `AioCb` from a mutable slice and read into it.
38728 - ///
38729 - /// ```
38730 -- /// # extern crate tempfile;
38731 -- /// # extern crate nix;
38732 - /// # use nix::errno::Errno;
38733 - /// # use nix::Error;
38734 - /// # use nix::sys::aio::*;
38735 -@@ -363,8 +358,6 @@ impl<'a> AioCb<'a> {
38736 - /// Create an `AioCb` from a Vector and use it for writing
38737 - ///
38738 - /// ```
38739 -- /// # extern crate tempfile;
38740 -- /// # extern crate nix;
38741 - /// # use nix::errno::Errno;
38742 - /// # use nix::Error;
38743 - /// # use nix::sys::aio::*;
38744 -@@ -394,9 +387,6 @@ impl<'a> AioCb<'a> {
38745 - /// Create an `AioCb` from a `Bytes` object
38746 - ///
38747 - /// ```
38748 -- /// # extern crate bytes;
38749 -- /// # extern crate tempfile;
38750 -- /// # extern crate nix;
38751 - /// # use bytes::Bytes;
38752 - /// # use nix::sys::aio::*;
38753 - /// # use nix::sys::signal::SigevNotify;
38754 -@@ -419,9 +409,6 @@ impl<'a> AioCb<'a> {
38755 - /// using an un`Box`ed `Bytes` object.
38756 - ///
38757 - /// ```
38758 -- /// # extern crate bytes;
38759 -- /// # extern crate tempfile;
38760 -- /// # extern crate nix;
38761 - /// # use bytes::Bytes;
38762 - /// # use nix::sys::aio::*;
38763 - /// # use nix::sys::signal::SigevNotify;
38764 -@@ -480,8 +467,6 @@ impl<'a> AioCb<'a> {
38765 - /// Create an `AioCb` from a Vector and use it for reading
38766 - ///
38767 - /// ```
38768 -- /// # extern crate tempfile;
38769 -- /// # extern crate nix;
38770 - /// # use nix::errno::Errno;
38771 - /// # use nix::Error;
38772 - /// # use nix::sys::aio::*;
38773 -@@ -642,8 +627,6 @@ impl<'a> AioCb<'a> {
38774 - /// Construct an `AioCb` from a slice and use it for writing.
38775 - ///
38776 - /// ```
38777 -- /// # extern crate tempfile;
38778 -- /// # extern crate nix;
38779 - /// # use nix::errno::Errno;
38780 - /// # use nix::Error;
38781 - /// # use nix::sys::aio::*;
38782 -@@ -726,8 +709,6 @@ impl<'a> AioCb<'a> {
38783 - /// result.
38784 - ///
38785 - /// ```
38786 -- /// # extern crate tempfile;
38787 -- /// # extern crate nix;
38788 - /// # use nix::errno::Errno;
38789 - /// # use nix::Error;
38790 - /// # use nix::sys::aio::*;
38791 -@@ -781,8 +762,6 @@ impl<'a> AioCb<'a> {
38792 - /// is an alternative to `aio_suspend`, used by most of the other examples.
38793 - ///
38794 - /// ```
38795 -- /// # extern crate tempfile;
38796 -- /// # extern crate nix;
38797 - /// # use nix::errno::Errno;
38798 - /// # use nix::Error;
38799 - /// # use nix::sys::aio::*;
38800 -@@ -925,8 +904,6 @@ impl<'a> AioCb<'a> {
38801 - /// descriptor.
38802 - ///
38803 - /// ```
38804 --/// # extern crate tempfile;
38805 --/// # extern crate nix;
38806 - /// # use nix::errno::Errno;
38807 - /// # use nix::Error;
38808 - /// # use nix::sys::aio::*;
38809 -@@ -978,13 +955,7 @@ pub fn aio_cancel_all(fd: RawFd) -> Result<AioCancelStat> {
38810 - ///
38811 - /// Use `aio_suspend` to block until an aio operation completes.
38812 - ///
38813 --// Disable doctest due to a known bug in FreeBSD's 32-bit emulation. The fix
38814 --// will be included in release 11.2.
38815 --// FIXME reenable the doc test when the CI machine gets upgraded to that release.
38816 --// https://svnweb.freebsd.org/base?view=revision&revision=325018
38817 --/// ```no_run
38818 --/// # extern crate tempfile;
38819 --/// # extern crate nix;
38820 -+/// ```
38821 - /// # use nix::sys::aio::*;
38822 - /// # use nix::sys::signal::SigevNotify;
38823 - /// # use std::os::unix::io::AsRawFd;
38824 -@@ -1091,8 +1062,6 @@ impl<'a> LioCb<'a> {
38825 - /// [`AioCb::error`] to poll.
38826 - ///
38827 - /// ```
38828 -- /// # extern crate tempfile;
38829 -- /// # extern crate nix;
38830 - /// # use nix::sys::aio::*;
38831 - /// # use nix::sys::signal::SigevNotify;
38832 - /// # use std::os::unix::io::AsRawFd;
38833 -@@ -1148,8 +1117,6 @@ impl<'a> LioCb<'a> {
38834 - ///
38835 - /// # Examples
38836 - /// ```no_run
38837 -- /// # extern crate tempfile;
38838 -- /// # extern crate nix;
38839 - /// # use nix::Error;
38840 - /// # use nix::errno::Errno;
38841 - /// # use nix::sys::aio::*;
38842 -@@ -1213,7 +1180,6 @@ impl<'a> LioCb<'a> {
38843 - },
38844 - Err(Error::Sys(Errno::EINPROGRESS)) => {
38845 - // aiocb is was successfully queued; no need to do anything
38846 -- ()
38847 - },
38848 - Err(Error::Sys(Errno::EINVAL)) => panic!(
38849 - "AioCb was never submitted, or already finalized"),
38850 -diff --git a/third_party/rust/nix/src/sys/epoll.rs b/third_party/rust/nix/src/sys/epoll.rs
38851 -index fef6f4e3ec92c..2437bbe2ddb3b 100644
38852 ---- a/third_party/rust/nix/src/sys/epoll.rs
38853 -+++ b/third_party/rust/nix/src/sys/epoll.rs
38854 -@@ -1,10 +1,10 @@
38855 --use Result;
38856 --use errno::Errno;
38857 -+use crate::Result;
38858 -+use crate::errno::Errno;
38859 - use libc::{self, c_int};
38860 - use std::os::unix::io::RawFd;
38861 - use std::ptr;
38862 - use std::mem;
38863 --use ::Error;
38864 -+use crate::Error;
38865 -
38866 - libc_bitflags!(
38867 - pub struct EpollFlags: c_int {
38868 -@@ -43,7 +43,7 @@ libc_bitflags!{
38869 - }
38870 -
38871 - #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
38872 --#[repr(C)]
38873 -+#[repr(transparent)]
38874 - pub struct EpollEvent {
38875 - event: libc::epoll_event,
38876 - }
38877 -diff --git a/third_party/rust/nix/src/sys/event.rs b/third_party/rust/nix/src/sys/event.rs
38878 -index 8cd7372f88188..8050af313245d 100644
38879 ---- a/third_party/rust/nix/src/sys/event.rs
38880 -+++ b/third_party/rust/nix/src/sys/event.rs
38881 -@@ -1,12 +1,11 @@
38882 - /* TOOD: Implement for other kqueue based systems
38883 - */
38884 -
38885 --use {Errno, Result};
38886 -+use crate::{Errno, Result};
38887 - #[cfg(not(target_os = "netbsd"))]
38888 - use libc::{timespec, time_t, c_int, c_long, intptr_t, uintptr_t};
38889 - #[cfg(target_os = "netbsd")]
38890 - use libc::{timespec, time_t, c_long, intptr_t, uintptr_t, size_t};
38891 --use libc;
38892 - use std::os::unix::io::RawFd;
38893 - use std::ptr;
38894 - use std::mem;
38895 -@@ -28,7 +27,7 @@ type type_of_data = intptr_t;
38896 - #[cfg(any(target_os = "netbsd"))]
38897 - type type_of_udata = intptr_t;
38898 - #[cfg(any(target_os = "netbsd", target_os = "openbsd"))]
38899 --type type_of_data = libc::int64_t;
38900 -+type type_of_data = i64;
38901 -
38902 - #[cfg(target_os = "netbsd")]
38903 - type type_of_event_filter = u32;
38904 -@@ -90,14 +89,9 @@ libc_bitflags!{
38905 - EV_CLEAR;
38906 - EV_DELETE;
38907 - EV_DISABLE;
38908 -- // No released version of OpenBSD supports EV_DISPATCH or EV_RECEIPT.
38909 -- // These have been commited to the -current branch though and are
38910 -- // expected to be part of the OpenBSD 6.2 release in Nov 2017.
38911 -- // See: https://marc.info/?l=openbsd-tech&m=149621427511219&w=2
38912 -- // https://github.com/rust-lang/libc/pull/613
38913 - #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
38914 - target_os = "ios", target_os = "macos",
38915 -- target_os = "netbsd"))]
38916 -+ target_os = "netbsd", target_os = "openbsd"))]
38917 - EV_DISPATCH;
38918 - #[cfg(target_os = "freebsd")]
38919 - EV_DROP;
38920 -@@ -116,7 +110,7 @@ libc_bitflags!{
38921 - EV_POLL;
38922 - #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
38923 - target_os = "ios", target_os = "macos",
38924 -- target_os = "netbsd"))]
38925 -+ target_os = "netbsd", target_os = "openbsd"))]
38926 - EV_RECEIPT;
38927 - EV_SYSFLAGS;
38928 - }
38929 -@@ -134,10 +128,6 @@ libc_bitflags!(
38930 - NOTE_EXEC;
38931 - NOTE_EXIT;
38932 - #[cfg(any(target_os = "macos", target_os = "ios"))]
38933 -- #[deprecated( since="0.14.0", note="Deprecated since OSX 10.9")]
38934 -- #[allow(deprecated)]
38935 -- NOTE_EXIT_REPARENTED;
38936 -- #[cfg(any(target_os = "macos", target_os = "ios"))]
38937 - NOTE_EXITSTATUS;
38938 - NOTE_EXTEND;
38939 - #[cfg(any(target_os = "macos",
38940 -@@ -183,11 +173,6 @@ libc_bitflags!(
38941 - NOTE_OOB;
38942 - NOTE_PCTRLMASK;
38943 - NOTE_PDATAMASK;
38944 -- #[cfg(any(target_os = "macos", target_os = "ios"))]
38945 -- #[cfg(any(target_os = "macos", target_os = "ios"))]
38946 -- #[deprecated( since="0.14.0", note="Deprecated since OSX 10.9")]
38947 -- #[allow(deprecated)]
38948 -- NOTE_REAP;
38949 - NOTE_RENAME;
38950 - NOTE_REVOKE;
38951 - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))]
38952 -@@ -234,7 +219,7 @@ impl KEvent {
38953 - pub fn new(ident: uintptr_t, filter: EventFilter, flags: EventFlag,
38954 - fflags:FilterFlag, data: intptr_t, udata: intptr_t) -> KEvent {
38955 - KEvent { kevent: libc::kevent {
38956 -- ident: ident,
38957 -+ ident,
38958 - filter: filter as type_of_event_filter,
38959 - flags: flags.bits(),
38960 - fflags: fflags.bits(),
38961 -@@ -329,23 +314,17 @@ pub fn ev_set(ev: &mut KEvent,
38962 - fn test_struct_kevent() {
38963 - let udata : intptr_t = 12345;
38964 -
38965 -- let expected = libc::kevent{ident: 0xdead_beef,
38966 -- filter: libc::EVFILT_READ,
38967 -- flags: libc::EV_ONESHOT | libc::EV_ADD,
38968 -- fflags: libc::NOTE_CHILD | libc::NOTE_EXIT,
38969 -- data: 0x1337,
38970 -- udata: udata as type_of_udata};
38971 - let actual = KEvent::new(0xdead_beef,
38972 - EventFilter::EVFILT_READ,
38973 - EventFlag::EV_ONESHOT | EventFlag::EV_ADD,
38974 - FilterFlag::NOTE_CHILD | FilterFlag::NOTE_EXIT,
38975 - 0x1337,
38976 - udata);
38977 -- assert!(expected.ident == actual.ident());
38978 -- assert!(expected.filter == actual.filter() as type_of_event_filter);
38979 -- assert!(expected.flags == actual.flags().bits());
38980 -- assert!(expected.fflags == actual.fflags().bits());
38981 -- assert!(expected.data == actual.data() as type_of_data);
38982 -- assert!(expected.udata == actual.udata() as type_of_udata);
38983 -- assert!(mem::size_of::<libc::kevent>() == mem::size_of::<KEvent>());
38984 -+ assert_eq!(0xdead_beef, actual.ident());
38985 -+ assert_eq!(libc::EVFILT_READ, actual.filter() as type_of_event_filter);
38986 -+ assert_eq!(libc::EV_ONESHOT | libc::EV_ADD, actual.flags().bits());
38987 -+ assert_eq!(libc::NOTE_CHILD | libc::NOTE_EXIT, actual.fflags().bits());
38988 -+ assert_eq!(0x1337, actual.data() as type_of_data);
38989 -+ assert_eq!(udata as type_of_udata, actual.udata() as type_of_udata);
38990 -+ assert_eq!(mem::size_of::<libc::kevent>(), mem::size_of::<KEvent>());
38991 - }
38992 -diff --git a/third_party/rust/nix/src/sys/eventfd.rs b/third_party/rust/nix/src/sys/eventfd.rs
38993 -index c5a54e46a1735..baaaa89ddd52e 100644
38994 ---- a/third_party/rust/nix/src/sys/eventfd.rs
38995 -+++ b/third_party/rust/nix/src/sys/eventfd.rs
38996 -@@ -1,7 +1,7 @@
38997 - use libc;
38998 - use std::os::unix::io::RawFd;
38999 --use Result;
39000 --use errno::Errno;
39001 -+use crate::Result;
39002 -+use crate::errno::Errno;
39003 -
39004 - libc_bitflags! {
39005 - pub struct EfdFlags: libc::c_int {
39006 -diff --git a/third_party/rust/nix/src/sys/inotify.rs b/third_party/rust/nix/src/sys/inotify.rs
39007 -index e6c2cf64d29dc..4880a4a514e77 100644
39008 ---- a/third_party/rust/nix/src/sys/inotify.rs
39009 -+++ b/third_party/rust/nix/src/sys/inotify.rs
39010 -@@ -23,19 +23,19 @@
39011 - //! }
39012 - //! ```
39013 -
39014 --use libc;
39015 - use libc::{
39016 - c_char,
39017 - c_int,
39018 - };
39019 - use std::ffi::{OsString,OsStr,CStr};
39020 - use std::os::unix::ffi::OsStrExt;
39021 --use std::mem::size_of;
39022 -+use std::mem::{MaybeUninit, size_of};
39023 - use std::os::unix::io::{RawFd,AsRawFd,FromRawFd};
39024 --use unistd::read;
39025 --use Result;
39026 --use NixPath;
39027 --use errno::Errno;
39028 -+use std::ptr;
39029 -+use crate::unistd::read;
39030 -+use crate::Result;
39031 -+use crate::NixPath;
39032 -+use crate::errno::Errno;
39033 -
39034 - libc_bitflags! {
39035 - /// Configuration options for [`inotify_add_watch`](fn.inotify_add_watch.html).
39036 -@@ -131,7 +131,7 @@ impl Inotify {
39037 - /// Returns a watch descriptor. This is not a File Descriptor!
39038 - ///
39039 - /// For more information see, [inotify_add_watch(2)](http://man7.org/linux/man-pages/man2/inotify_add_watch.2.html).
39040 -- pub fn add_watch<P: ?Sized + NixPath>(&self,
39041 -+ pub fn add_watch<P: ?Sized + NixPath>(self,
39042 - path: &P,
39043 - mask: AddWatchFlags)
39044 - -> Result<WatchDescriptor>
39045 -@@ -152,14 +152,14 @@ impl Inotify {
39046 - ///
39047 - /// For more information see, [inotify_rm_watch(2)](http://man7.org/linux/man-pages/man2/inotify_rm_watch.2.html).
39048 - #[cfg(target_os = "linux")]
39049 -- pub fn rm_watch(&self, wd: WatchDescriptor) -> Result<()> {
39050 -+ pub fn rm_watch(self, wd: WatchDescriptor) -> Result<()> {
39051 - let res = unsafe { libc::inotify_rm_watch(self.fd, wd.wd) };
39052 -
39053 - Errno::result(res).map(drop)
39054 - }
39055 -
39056 - #[cfg(target_os = "android")]
39057 -- pub fn rm_watch(&self, wd: WatchDescriptor) -> Result<()> {
39058 -+ pub fn rm_watch(self, wd: WatchDescriptor) -> Result<()> {
39059 - let res = unsafe { libc::inotify_rm_watch(self.fd, wd.wd as u32) };
39060 -
39061 - Errno::result(res).map(drop)
39062 -@@ -171,9 +171,10 @@ impl Inotify {
39063 - ///
39064 - /// Returns as many events as available. If the call was non blocking and no
39065 - /// events could be read then the EAGAIN error is returned.
39066 -- pub fn read_events(&self) -> Result<Vec<InotifyEvent>> {
39067 -+ pub fn read_events(self) -> Result<Vec<InotifyEvent>> {
39068 - let header_size = size_of::<libc::inotify_event>();
39069 -- let mut buffer = [0u8; 4096];
39070 -+ const BUFSIZ: usize = 4096;
39071 -+ let mut buffer = [0u8; BUFSIZ];
39072 - let mut events = Vec::new();
39073 - let mut offset = 0;
39074 -
39075 -@@ -181,11 +182,13 @@ impl Inotify {
39076 -
39077 - while (nread - offset) >= header_size {
39078 - let event = unsafe {
39079 -- &*(
39080 -- buffer
39081 -- .as_ptr()
39082 -- .offset(offset as isize) as *const libc::inotify_event
39083 -- )
39084 -+ let mut event = MaybeUninit::<libc::inotify_event>::uninit();
39085 -+ ptr::copy_nonoverlapping(
39086 -+ buffer.as_ptr().add(offset),
39087 -+ event.as_mut_ptr() as *mut u8,
39088 -+ (BUFSIZ - offset).min(header_size)
39089 -+ );
39090 -+ event.assume_init()
39091 - };
39092 -
39093 - let name = match event.len {
39094 -@@ -194,7 +197,7 @@ impl Inotify {
39095 - let ptr = unsafe {
39096 - buffer
39097 - .as_ptr()
39098 -- .offset(offset as isize + header_size as isize)
39099 -+ .add(offset + header_size)
39100 - as *const c_char
39101 - };
39102 - let cstr = unsafe { CStr::from_ptr(ptr) };
39103 -diff --git a/third_party/rust/nix/src/sys/ioctl/bsd.rs b/third_party/rust/nix/src/sys/ioctl/bsd.rs
39104 -index 9b8b0ff1a155f..f39c0eb688f8a 100644
39105 ---- a/third_party/rust/nix/src/sys/ioctl/bsd.rs
39106 -+++ b/third_party/rust/nix/src/sys/ioctl/bsd.rs
39107 -@@ -6,7 +6,7 @@ pub type ioctl_num_type = ::libc::c_ulong;
39108 - pub type ioctl_param_type = ::libc::c_int;
39109 -
39110 - mod consts {
39111 -- use ::sys::ioctl::ioctl_num_type;
39112 -+ use crate::sys::ioctl::ioctl_num_type;
39113 - #[doc(hidden)]
39114 - pub const VOID: ioctl_num_type = 0x2000_0000;
39115 - #[doc(hidden)]
39116 -@@ -14,7 +14,7 @@ mod consts {
39117 - #[doc(hidden)]
39118 - pub const IN: ioctl_num_type = 0x8000_0000;
39119 - #[doc(hidden)]
39120 -- pub const INOUT: ioctl_num_type = (IN|OUT);
39121 -+ pub const INOUT: ioctl_num_type = IN|OUT;
39122 - #[doc(hidden)]
39123 - pub const IOCPARM_MASK: ioctl_num_type = 0x1fff;
39124 - }
39125 -diff --git a/third_party/rust/nix/src/sys/ioctl/linux.rs b/third_party/rust/nix/src/sys/ioctl/linux.rs
39126 -index 9cdac72a4b80b..68ebaba9bf496 100644
39127 ---- a/third_party/rust/nix/src/sys/ioctl/linux.rs
39128 -+++ b/third_party/rust/nix/src/sys/ioctl/linux.rs
39129 -@@ -33,7 +33,8 @@ mod consts {
39130 - target_arch = "arm",
39131 - target_arch = "s390x",
39132 - target_arch = "x86_64",
39133 -- target_arch = "aarch64"))]
39134 -+ target_arch = "aarch64",
39135 -+ target_arch = "riscv64"))]
39136 - mod consts {
39137 - #[doc(hidden)]
39138 - pub const NONE: u8 = 0;
39139 -diff --git a/third_party/rust/nix/src/sys/ioctl/mod.rs b/third_party/rust/nix/src/sys/ioctl/mod.rs
39140 -index 4513bf877434a..8858a9d57779f 100644
39141 ---- a/third_party/rust/nix/src/sys/ioctl/mod.rs
39142 -+++ b/third_party/rust/nix/src/sys/ioctl/mod.rs
39143 -@@ -29,7 +29,7 @@
39144 - //! Historically `ioctl` numbers were arbitrary hard-coded values. In Linux (before 2.6) and some
39145 - //! unices this has changed to a more-ordered system where the ioctl numbers are partitioned into
39146 - //! subcomponents (For linux this is documented in
39147 --//! [`Documentation/ioctl/ioctl-number.txt`](http://elixir.free-electrons.com/linux/latest/source/Documentation/ioctl/ioctl-number.txt)):
39148 -+//! [`Documentation/ioctl/ioctl-number.rst`](https://elixir.bootlin.com/linux/latest/source/Documentation/userspace-api/ioctl/ioctl-number.rst)):
39149 - //!
39150 - //! * Number: The actual ioctl ID
39151 - //! * Type: A grouping of ioctls for a common purpose or driver
39152 -@@ -221,11 +221,13 @@
39153 - //!
39154 - //! # fn main() {}
39155 - //! ```
39156 --#[cfg(any(target_os = "android", target_os = "linux"))]
39157 -+use cfg_if::cfg_if;
39158 -+
39159 -+#[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
39160 - #[macro_use]
39161 - mod linux;
39162 -
39163 --#[cfg(any(target_os = "android", target_os = "linux"))]
39164 -+#[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
39165 - pub use self::linux::*;
39166 -
39167 - #[cfg(any(target_os = "dragonfly",
39168 -@@ -317,7 +319,6 @@ macro_rules! ioctl_none {
39169 - ///
39170 - /// ```no_run
39171 - /// # #[macro_use] extern crate nix;
39172 --/// # extern crate libc;
39173 - /// # use libc::TIOCNXCL;
39174 - /// # use std::fs::File;
39175 - /// # use std::os::unix::io::AsRawFd;
39176 -@@ -396,7 +397,6 @@ macro_rules! ioctl_read {
39177 - /// # Example
39178 - ///
39179 - /// ```
39180 --/// # extern crate libc;
39181 - /// # #[macro_use] extern crate nix;
39182 - /// # #[cfg(any(target_os = "android", target_os = "linux"))]
39183 - /// ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios);
39184 -@@ -470,7 +470,6 @@ macro_rules! ioctl_write_ptr {
39185 - /// # Example
39186 - ///
39187 - /// ```
39188 --/// # extern crate libc;
39189 - /// # #[macro_use] extern crate nix;
39190 - /// # #[cfg(any(target_os = "android", target_os = "linux"))]
39191 - /// ioctl_write_ptr_bad!(tcsets, libc::TCSETS, libc::termios);
39192 -@@ -590,7 +589,6 @@ cfg_if!{
39193 - /// # Examples
39194 - ///
39195 - /// ```
39196 --/// # extern crate libc;
39197 - /// # #[macro_use] extern crate nix;
39198 - /// # #[cfg(any(target_os = "android", target_os = "linux"))]
39199 - /// ioctl_write_int_bad!(tcsbrk, libc::TCSBRK);
39200 -diff --git a/third_party/rust/nix/src/sys/memfd.rs b/third_party/rust/nix/src/sys/memfd.rs
39201 -index 9672429b31e7f..51b7e6b18849b 100644
39202 ---- a/third_party/rust/nix/src/sys/memfd.rs
39203 -+++ b/third_party/rust/nix/src/sys/memfd.rs
39204 -@@ -1,7 +1,7 @@
39205 - use libc;
39206 - use std::os::unix::io::RawFd;
39207 --use Result;
39208 --use errno::Errno;
39209 -+use crate::Result;
39210 -+use crate::errno::Errno;
39211 - use std::ffi::CStr;
39212 -
39213 - libc_bitflags!(
39214 -diff --git a/third_party/rust/nix/src/sys/mman.rs b/third_party/rust/nix/src/sys/mman.rs
39215 -index 4e250501dd0f0..63a0779c19382 100644
39216 ---- a/third_party/rust/nix/src/sys/mman.rs
39217 -+++ b/third_party/rust/nix/src/sys/mman.rs
39218 -@@ -1,12 +1,12 @@
39219 --use {Error, Result};
39220 -+use crate::{Error, Result};
39221 - #[cfg(not(target_os = "android"))]
39222 --use NixPath;
39223 --use errno::Errno;
39224 -+use crate::NixPath;
39225 -+use crate::errno::Errno;
39226 - #[cfg(not(target_os = "android"))]
39227 --use fcntl::OFlag;
39228 -+use crate::fcntl::OFlag;
39229 - use libc::{self, c_int, c_void, size_t, off_t};
39230 - #[cfg(not(target_os = "android"))]
39231 --use sys::stat::Mode;
39232 -+use crate::sys::stat::Mode;
39233 - use std::os::unix::io::RawFd;
39234 -
39235 - libc_bitflags!{
39236 -@@ -77,6 +77,43 @@ libc_bitflags!{
39237 - /// Allocate the mapping using "huge pages."
39238 - #[cfg(any(target_os = "android", target_os = "linux"))]
39239 - MAP_HUGETLB;
39240 -+ /// Make use of 64KB huge page (must be supported by the system)
39241 -+ #[cfg(target_os = "linux")]
39242 -+ MAP_HUGE_64KB;
39243 -+ /// Make use of 512KB huge page (must be supported by the system)
39244 -+ #[cfg(target_os = "linux")]
39245 -+ MAP_HUGE_512KB;
39246 -+ /// Make use of 1MB huge page (must be supported by the system)
39247 -+ #[cfg(target_os = "linux")]
39248 -+ MAP_HUGE_1MB;
39249 -+ /// Make use of 2MB huge page (must be supported by the system)
39250 -+ #[cfg(target_os = "linux")]
39251 -+ MAP_HUGE_2MB;
39252 -+ /// Make use of 8MB huge page (must be supported by the system)
39253 -+ #[cfg(target_os = "linux")]
39254 -+ MAP_HUGE_8MB;
39255 -+ /// Make use of 16MB huge page (must be supported by the system)
39256 -+ #[cfg(target_os = "linux")]
39257 -+ MAP_HUGE_16MB;
39258 -+ /// Make use of 32MB huge page (must be supported by the system)
39259 -+ #[cfg(target_os = "linux")]
39260 -+ MAP_HUGE_32MB;
39261 -+ /// Make use of 256MB huge page (must be supported by the system)
39262 -+ #[cfg(target_os = "linux")]
39263 -+ MAP_HUGE_256MB;
39264 -+ /// Make use of 512MB huge page (must be supported by the system)
39265 -+ #[cfg(target_os = "linux")]
39266 -+ MAP_HUGE_512MB;
39267 -+ /// Make use of 1GB huge page (must be supported by the system)
39268 -+ #[cfg(target_os = "linux")]
39269 -+ MAP_HUGE_1GB;
39270 -+ /// Make use of 2GB huge page (must be supported by the system)
39271 -+ #[cfg(target_os = "linux")]
39272 -+ MAP_HUGE_2GB;
39273 -+ /// Make use of 16GB huge page (must be supported by the system)
39274 -+ #[cfg(target_os = "linux")]
39275 -+ MAP_HUGE_16GB;
39276 -+
39277 - /// Lock the mapped region into memory as with `mlock(2)`.
39278 - #[cfg(target_os = "netbsd")]
39279 - MAP_WIRED;
39280 -@@ -102,6 +139,17 @@ libc_bitflags!{
39281 - }
39282 - }
39283 -
39284 -+#[cfg(target_os = "linux")]
39285 -+libc_bitflags!{
39286 -+ /// Options for `mremap()`.
39287 -+ pub struct MRemapFlags: c_int {
39288 -+ /// Permit the kernel to relocate the mapping to a new virtual address, if necessary.
39289 -+ MREMAP_MAYMOVE;
39290 -+ /// Place the mapping at exactly the address specified in `new_address`.
39291 -+ MREMAP_FIXED;
39292 -+ }
39293 -+}
39294 -+
39295 - libc_enum!{
39296 - /// Usage information for a range of memory to allow for performance optimizations by the kernel.
39297 - ///
39298 -@@ -223,20 +271,37 @@ libc_bitflags!{
39299 - }
39300 - }
39301 -
39302 --/// Locks all memory pages that contain part of the address range with `length` bytes starting at
39303 --/// `addr`. Locked pages never move to the swap area.
39304 -+/// Locks all memory pages that contain part of the address range with `length`
39305 -+/// bytes starting at `addr`.
39306 -+///
39307 -+/// Locked pages never move to the swap area.
39308 -+///
39309 -+/// # Safety
39310 -+///
39311 -+/// `addr` must meet all the requirements described in the `mlock(2)` man page.
39312 - pub unsafe fn mlock(addr: *const c_void, length: size_t) -> Result<()> {
39313 - Errno::result(libc::mlock(addr, length)).map(drop)
39314 - }
39315 -
39316 --/// Unlocks all memory pages that contain part of the address range with `length` bytes starting at
39317 --/// `addr`.
39318 -+/// Unlocks all memory pages that contain part of the address range with
39319 -+/// `length` bytes starting at `addr`.
39320 -+///
39321 -+/// # Safety
39322 -+///
39323 -+/// `addr` must meet all the requirements described in the `munlock(2)` man
39324 -+/// page.
39325 - pub unsafe fn munlock(addr: *const c_void, length: size_t) -> Result<()> {
39326 - Errno::result(libc::munlock(addr, length)).map(drop)
39327 - }
39328 -
39329 --/// Locks all memory pages mapped into this process' address space. Locked pages never move to the
39330 --/// swap area.
39331 -+/// Locks all memory pages mapped into this process' address space.
39332 -+///
39333 -+/// Locked pages never move to the swap area.
39334 -+///
39335 -+/// # Safety
39336 -+///
39337 -+/// `addr` must meet all the requirements described in the `mlockall(2)` man
39338 -+/// page.
39339 - pub fn mlockall(flags: MlockAllFlags) -> Result<()> {
39340 - unsafe { Errno::result(libc::mlockall(flags.bits())) }.map(drop)
39341 - }
39342 -@@ -246,8 +311,11 @@ pub fn munlockall() -> Result<()> {
39343 - unsafe { Errno::result(libc::munlockall()) }.map(drop)
39344 - }
39345 -
39346 --/// Calls to mmap are inherently unsafe, so they must be made in an unsafe block. Typically
39347 --/// a higher-level abstraction will hide the unsafe interactions with the mmap'd region.
39348 -+/// allocate memory, or map files or devices into memory
39349 -+///
39350 -+/// # Safety
39351 -+///
39352 -+/// See the `mmap(2)` man page for detailed requirements.
39353 - pub unsafe fn mmap(addr: *mut c_void, length: size_t, prot: ProtFlags, flags: MapFlags, fd: RawFd, offset: off_t) -> Result<*mut c_void> {
39354 - let ret = libc::mmap(addr, length, prot.bits(), flags.bits(), fd, offset);
39355 -
39356 -@@ -258,10 +326,46 @@ pub unsafe fn mmap(addr: *mut c_void, length: size_t, prot: ProtFlags, flags: Ma
39357 - }
39358 - }
39359 -
39360 -+/// Expands (or shrinks) an existing memory mapping, potentially moving it at
39361 -+/// the same time.
39362 -+///
39363 -+/// # Safety
39364 -+///
39365 -+/// See the `mremap(2)` [man page](https://man7.org/linux/man-pages/man2/mremap.2.html) for
39366 -+/// detailed requirements.
39367 -+#[cfg(target_os = "linux")]
39368 -+pub unsafe fn mremap(
39369 -+ addr: *mut c_void,
39370 -+ old_size: size_t,
39371 -+ new_size: size_t,
39372 -+ flags: MRemapFlags,
39373 -+ new_address: Option<* mut c_void>,
39374 -+) -> Result<*mut c_void> {
39375 -+ let ret = libc::mremap(addr, old_size, new_size, flags.bits(), new_address.unwrap_or(std::ptr::null_mut()));
39376 -+
39377 -+ if ret == libc::MAP_FAILED {
39378 -+ Err(Error::Sys(Errno::last()))
39379 -+ } else {
39380 -+ Ok(ret)
39381 -+ }
39382 -+}
39383 -+
39384 -+/// remove a mapping
39385 -+///
39386 -+/// # Safety
39387 -+///
39388 -+/// `addr` must meet all the requirements described in the `munmap(2)` man
39389 -+/// page.
39390 - pub unsafe fn munmap(addr: *mut c_void, len: size_t) -> Result<()> {
39391 - Errno::result(libc::munmap(addr, len)).map(drop)
39392 - }
39393 -
39394 -+/// give advice about use of memory
39395 -+///
39396 -+/// # Safety
39397 -+///
39398 -+/// See the `madvise(2)` man page. Take special care when using
39399 -+/// `MmapAdvise::MADV_FREE`.
39400 - pub unsafe fn madvise(addr: *mut c_void, length: size_t, advise: MmapAdvise) -> Result<()> {
39401 - Errno::result(libc::madvise(addr, length, advise as i32)).map(drop)
39402 - }
39403 -@@ -295,6 +399,12 @@ pub unsafe fn mprotect(addr: *mut c_void, length: size_t, prot: ProtFlags) -> Re
39404 - Errno::result(libc::mprotect(addr, length, prot.bits())).map(drop)
39405 - }
39406 -
39407 -+/// synchronize a mapped region
39408 -+///
39409 -+/// # Safety
39410 -+///
39411 -+/// `addr` must meet all the requirements described in the `msync(2)` man
39412 -+/// page.
39413 - pub unsafe fn msync(addr: *mut c_void, length: size_t, flags: MsFlags) -> Result<()> {
39414 - Errno::result(libc::msync(addr, length, flags.bits())).map(drop)
39415 - }
39416 -diff --git a/third_party/rust/nix/src/sys/mod.rs b/third_party/rust/nix/src/sys/mod.rs
39417 -index d3c2f92bbaaea..438fb4fdcb438 100644
39418 ---- a/third_party/rust/nix/src/sys/mod.rs
39419 -+++ b/third_party/rust/nix/src/sys/mod.rs
39420 -@@ -25,6 +25,7 @@ pub mod eventfd;
39421 - target_os = "freebsd",
39422 - target_os = "ios",
39423 - target_os = "linux",
39424 -+ target_os = "redox",
39425 - target_os = "macos",
39426 - target_os = "netbsd",
39427 - target_os = "openbsd"))]
39428 -@@ -34,8 +35,12 @@ pub mod ioctl;
39429 - #[cfg(target_os = "linux")]
39430 - pub mod memfd;
39431 -
39432 -+#[cfg(not(target_os = "redox"))]
39433 - pub mod mman;
39434 -
39435 -+#[cfg(target_os = "linux")]
39436 -+pub mod personality;
39437 -+
39438 - pub mod pthread;
39439 -
39440 - #[cfg(any(target_os = "android",
39441 -@@ -53,6 +58,7 @@ pub mod quota;
39442 - #[cfg(any(target_os = "linux"))]
39443 - pub mod reboot;
39444 -
39445 -+#[cfg(not(target_os = "redox"))]
39446 - pub mod select;
39447 -
39448 - #[cfg(any(target_os = "android",
39449 -@@ -67,6 +73,7 @@ pub mod signal;
39450 - #[cfg(any(target_os = "android", target_os = "linux"))]
39451 - pub mod signalfd;
39452 -
39453 -+#[cfg(not(target_os = "redox"))]
39454 - pub mod socket;
39455 -
39456 - pub mod stat;
39457 -@@ -98,3 +105,6 @@ pub mod wait;
39458 -
39459 - #[cfg(any(target_os = "android", target_os = "linux"))]
39460 - pub mod inotify;
39461 -+
39462 -+#[cfg(target_os = "linux")]
39463 -+pub mod timerfd;
39464 -diff --git a/third_party/rust/nix/src/sys/personality.rs b/third_party/rust/nix/src/sys/personality.rs
39465 -new file mode 100644
39466 -index 0000000000000..6548b654aa1f4
39467 ---- /dev/null
39468 -+++ b/third_party/rust/nix/src/sys/personality.rs
39469 -@@ -0,0 +1,70 @@
39470 -+use crate::Result;
39471 -+use crate::errno::Errno;
39472 -+
39473 -+use libc::{self, c_int, c_ulong};
39474 -+
39475 -+libc_bitflags! {
39476 -+ /// Flags used and returned by [`get()`](fn.get.html) and
39477 -+ /// [`set()`](fn.set.html).
39478 -+ pub struct Persona: c_int {
39479 -+ ADDR_COMPAT_LAYOUT;
39480 -+ ADDR_NO_RANDOMIZE;
39481 -+ ADDR_LIMIT_32BIT;
39482 -+ ADDR_LIMIT_3GB;
39483 -+ #[cfg(not(target_env = "musl"))]
39484 -+ FDPIC_FUNCPTRS;
39485 -+ MMAP_PAGE_ZERO;
39486 -+ READ_IMPLIES_EXEC;
39487 -+ SHORT_INODE;
39488 -+ STICKY_TIMEOUTS;
39489 -+ #[cfg(not(target_env = "musl"))]
39490 -+ UNAME26;
39491 -+ WHOLE_SECONDS;
39492 -+ }
39493 -+}
39494 -+
39495 -+/// Retrieve the current process personality.
39496 -+///
39497 -+/// Returns a Result containing a Persona instance.
39498 -+///
39499 -+/// Example:
39500 -+///
39501 -+/// ```
39502 -+/// # use nix::sys::personality::{self, Persona};
39503 -+/// let pers = personality::get().unwrap();
39504 -+/// assert!(!pers.contains(Persona::WHOLE_SECONDS));
39505 -+/// ```
39506 -+pub fn get() -> Result<Persona> {
39507 -+ let res = unsafe {
39508 -+ libc::personality(0xFFFFFFFF)
39509 -+ };
39510 -+
39511 -+ Errno::result(res).map(|r| Persona::from_bits_truncate(r))
39512 -+}
39513 -+
39514 -+/// Set the current process personality.
39515 -+///
39516 -+/// Returns a Result containing the *previous* personality for the
39517 -+/// process, as a Persona.
39518 -+///
39519 -+/// For more information, see [personality(2)](https://man7.org/linux/man-pages/man2/personality.2.html)
39520 -+///
39521 -+/// **NOTE**: This call **replaces** the current personality entirely.
39522 -+/// To **update** the personality, first call `get()` and then `set()`
39523 -+/// with the modified persona.
39524 -+///
39525 -+/// Example:
39526 -+///
39527 -+/// ```
39528 -+/// # use nix::sys::personality::{self, Persona};
39529 -+/// let mut pers = personality::get().unwrap();
39530 -+/// assert!(!pers.contains(Persona::ADDR_NO_RANDOMIZE));
39531 -+/// personality::set(pers | Persona::ADDR_NO_RANDOMIZE);
39532 -+/// ```
39533 -+pub fn set(persona: Persona) -> Result<Persona> {
39534 -+ let res = unsafe {
39535 -+ libc::personality(persona.bits() as c_ulong)
39536 -+ };
39537 -+
39538 -+ Errno::result(res).map(|r| Persona::from_bits_truncate(r))
39539 -+}
39540 -diff --git a/third_party/rust/nix/src/sys/ptrace/bsd.rs b/third_party/rust/nix/src/sys/ptrace/bsd.rs
39541 -index 7797d10647ef4..e85afc761198b 100644
39542 ---- a/third_party/rust/nix/src/sys/ptrace/bsd.rs
39543 -+++ b/third_party/rust/nix/src/sys/ptrace/bsd.rs
39544 -@@ -1,9 +1,10 @@
39545 --use errno::Errno;
39546 -+use cfg_if::cfg_if;
39547 -+use crate::errno::Errno;
39548 - use libc::{self, c_int};
39549 - use std::ptr;
39550 --use sys::signal::Signal;
39551 --use unistd::Pid;
39552 --use Result;
39553 -+use crate::sys::signal::Signal;
39554 -+use crate::unistd::Pid;
39555 -+use crate::Result;
39556 -
39557 - pub type RequestType = c_int;
39558 -
39559 -@@ -77,16 +78,23 @@ pub fn traceme() -> Result<()> {
39560 -
39561 - /// Attach to a running process, as with `ptrace(PT_ATTACH, ...)`
39562 - ///
39563 --/// Attaches to the process specified in pid, making it a tracee of the calling process.
39564 -+/// Attaches to the process specified by `pid`, making it a tracee of the calling process.
39565 - pub fn attach(pid: Pid) -> Result<()> {
39566 - unsafe { ptrace_other(Request::PT_ATTACH, pid, ptr::null_mut(), 0).map(drop) }
39567 - }
39568 -
39569 - /// Detaches the current running process, as with `ptrace(PT_DETACH, ...)`
39570 - ///
39571 --/// Detaches from the process specified in pid allowing it to run freely
39572 --pub fn detach(pid: Pid) -> Result<()> {
39573 -- unsafe { ptrace_other(Request::PT_DETACH, pid, ptr::null_mut(), 0).map(drop) }
39574 -+/// Detaches from the process specified by `pid` allowing it to run freely, optionally delivering a
39575 -+/// signal specified by `sig`.
39576 -+pub fn detach<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
39577 -+ let data = match sig.into() {
39578 -+ Some(s) => s as c_int,
39579 -+ None => 0,
39580 -+ };
39581 -+ unsafe {
39582 -+ ptrace_other(Request::PT_DETACH, pid, ptr::null_mut(), data).map(drop)
39583 -+ }
39584 - }
39585 -
39586 - /// Restart the stopped tracee process, as with `ptrace(PTRACE_CONT, ...)`
39587 -@@ -121,7 +129,6 @@ pub fn kill(pid: Pid) -> Result<()> {
39588 - ///
39589 - /// # Example
39590 - /// ```rust
39591 --/// extern crate nix;
39592 - /// use nix::sys::ptrace::step;
39593 - /// use nix::unistd::Pid;
39594 - /// use nix::sys::signal::Signal;
39595 -diff --git a/third_party/rust/nix/src/sys/ptrace/linux.rs b/third_party/rust/nix/src/sys/ptrace/linux.rs
39596 -index df15e66527562..8d1dd16e5dd76 100644
39597 ---- a/third_party/rust/nix/src/sys/ptrace/linux.rs
39598 -+++ b/third_party/rust/nix/src/sys/ptrace/linux.rs
39599 -@@ -1,18 +1,21 @@
39600 - //! For detailed description of the ptrace requests, consult `man ptrace`.
39601 -
39602 -+use cfg_if::cfg_if;
39603 - use std::{mem, ptr};
39604 --use {Error, Result};
39605 --use errno::Errno;
39606 -+use crate::{Error, Result};
39607 -+use crate::errno::Errno;
39608 - use libc::{self, c_void, c_long, siginfo_t};
39609 --use ::unistd::Pid;
39610 --use sys::signal::Signal;
39611 -+use crate::unistd::Pid;
39612 -+use crate::sys::signal::Signal;
39613 -
39614 - pub type AddressType = *mut ::libc::c_void;
39615 -
39616 --#[cfg(all(target_os = "linux",
39617 -- any(target_arch = "x86_64",
39618 -- target_arch = "x86"),
39619 -- target_env = "gnu"))]
39620 -+#[cfg(all(
39621 -+ target_os = "linux",
39622 -+ any(all(target_arch = "x86_64",
39623 -+ any(target_env = "gnu", target_env = "musl")),
39624 -+ all(target_arch = "x86", target_env = "gnu"))
39625 -+))]
39626 - use libc::user_regs_struct;
39627 -
39628 - cfg_if! {
39629 -@@ -106,6 +109,12 @@ libc_enum!{
39630 - #[cfg(all(target_os = "linux", not(any(target_arch = "mips",
39631 - target_arch = "mips64"))))]
39632 - PTRACE_PEEKSIGINFO,
39633 -+ #[cfg(all(target_os = "linux", target_env = "gnu",
39634 -+ any(target_arch = "x86", target_arch = "x86_64")))]
39635 -+ PTRACE_SYSEMU,
39636 -+ #[cfg(all(target_os = "linux", target_env = "gnu",
39637 -+ any(target_arch = "x86", target_arch = "x86_64")))]
39638 -+ PTRACE_SYSEMU_SINGLESTEP,
39639 - }
39640 - }
39641 -
39642 -@@ -165,22 +174,6 @@ libc_bitflags! {
39643 - }
39644 - }
39645 -
39646 --/// Performs a ptrace request. If the request in question is provided by a specialised function
39647 --/// this function will return an unsupported operation error.
39648 --#[deprecated(
39649 -- since="0.10.0",
39650 -- note="usages of `ptrace()` should be replaced with the specialized helper functions instead"
39651 --)]
39652 --pub unsafe fn ptrace(request: Request, pid: Pid, addr: AddressType, data: *mut c_void) -> Result<c_long> {
39653 -- use self::Request::*;
39654 -- match request {
39655 -- PTRACE_PEEKTEXT | PTRACE_PEEKDATA | PTRACE_GETSIGINFO |
39656 -- PTRACE_GETEVENTMSG | PTRACE_SETSIGINFO | PTRACE_SETOPTIONS |
39657 -- PTRACE_POKETEXT | PTRACE_POKEDATA | PTRACE_KILL => Err(Error::UnsupportedOperation),
39658 -- _ => ptrace_other(request, pid, addr, data)
39659 -- }
39660 --}
39661 --
39662 - fn ptrace_peek(request: Request, pid: Pid, addr: AddressType, data: *mut c_void) -> Result<c_long> {
39663 - let ret = unsafe {
39664 - Errno::clear();
39665 -@@ -193,19 +186,23 @@ fn ptrace_peek(request: Request, pid: Pid, addr: AddressType, data: *mut c_void)
39666 - }
39667 -
39668 - /// Get user registers, as with `ptrace(PTRACE_GETREGS, ...)`
39669 --#[cfg(all(target_os = "linux",
39670 -- any(target_arch = "x86_64",
39671 -- target_arch = "x86"),
39672 -- target_env = "gnu"))]
39673 -+#[cfg(all(
39674 -+ target_os = "linux",
39675 -+ any(all(target_arch = "x86_64",
39676 -+ any(target_env = "gnu", target_env = "musl")),
39677 -+ all(target_arch = "x86", target_env = "gnu"))
39678 -+))]
39679 - pub fn getregs(pid: Pid) -> Result<user_regs_struct> {
39680 - ptrace_get_data::<user_regs_struct>(Request::PTRACE_GETREGS, pid)
39681 - }
39682 -
39683 - /// Set user registers, as with `ptrace(PTRACE_SETREGS, ...)`
39684 --#[cfg(all(target_os = "linux",
39685 -- any(target_arch = "x86_64",
39686 -- target_arch = "x86"),
39687 -- target_env = "gnu"))]
39688 -+#[cfg(all(
39689 -+ target_os = "linux",
39690 -+ any(all(target_arch = "x86_64",
39691 -+ any(target_env = "gnu", target_env = "musl")),
39692 -+ all(target_arch = "x86", target_env = "gnu"))
39693 -+))]
39694 - pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> {
39695 - let res = unsafe {
39696 - libc::ptrace(Request::PTRACE_SETREGS as RequestType,
39697 -@@ -221,16 +218,15 @@ pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> {
39698 - /// and therefore use the data field to return values. This function handles these
39699 - /// requests.
39700 - fn ptrace_get_data<T>(request: Request, pid: Pid) -> Result<T> {
39701 -- // Creates an uninitialized pointer to store result in
39702 -- let data: T = unsafe { mem::uninitialized() };
39703 -+ let mut data = mem::MaybeUninit::uninit();
39704 - let res = unsafe {
39705 - libc::ptrace(request as RequestType,
39706 - libc::pid_t::from(pid),
39707 - ptr::null_mut::<T>(),
39708 -- &data as *const _ as *const c_void)
39709 -+ data.as_mut_ptr() as *const _ as *const c_void)
39710 - };
39711 - Errno::result(res)?;
39712 -- Ok(data)
39713 -+ Ok(unsafe{ data.assume_init() })
39714 - }
39715 -
39716 - unsafe fn ptrace_other(request: Request, pid: Pid, addr: AddressType, data: *mut c_void) -> Result<c_long> {
39717 -@@ -288,23 +284,45 @@ pub fn traceme() -> Result<()> {
39718 - }
39719 - }
39720 -
39721 --/// Ask for next syscall, as with `ptrace(PTRACE_SYSCALL, ...)`
39722 -+/// Continue execution until the next syscall, as with `ptrace(PTRACE_SYSCALL, ...)`
39723 - ///
39724 --/// Arranges for the tracee to be stopped at the next entry to or exit from a system call.
39725 --pub fn syscall(pid: Pid) -> Result<()> {
39726 -+/// Arranges for the tracee to be stopped at the next entry to or exit from a system call,
39727 -+/// optionally delivering a signal specified by `sig`.
39728 -+pub fn syscall<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
39729 -+ let data = match sig.into() {
39730 -+ Some(s) => s as i32 as *mut c_void,
39731 -+ None => ptr::null_mut(),
39732 -+ };
39733 - unsafe {
39734 - ptrace_other(
39735 - Request::PTRACE_SYSCALL,
39736 - pid,
39737 - ptr::null_mut(),
39738 -- ptr::null_mut(),
39739 -+ data,
39740 - ).map(drop) // ignore the useless return value
39741 - }
39742 - }
39743 -
39744 -+/// Continue execution until the next syscall, as with `ptrace(PTRACE_SYSEMU, ...)`
39745 -+///
39746 -+/// In contrast to the `syscall` function, the syscall stopped at will not be executed.
39747 -+/// Thus the the tracee will only be stopped once per syscall,
39748 -+/// optionally delivering a signal specified by `sig`.
39749 -+#[cfg(all(target_os = "linux", target_env = "gnu", any(target_arch = "x86", target_arch = "x86_64")))]
39750 -+pub fn sysemu<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
39751 -+ let data = match sig.into() {
39752 -+ Some(s) => s as i32 as *mut c_void,
39753 -+ None => ptr::null_mut(),
39754 -+ };
39755 -+ unsafe {
39756 -+ ptrace_other(Request::PTRACE_SYSEMU, pid, ptr::null_mut(), data).map(drop)
39757 -+ // ignore the useless return value
39758 -+ }
39759 -+}
39760 -+
39761 - /// Attach to a running process, as with `ptrace(PTRACE_ATTACH, ...)`
39762 - ///
39763 --/// Attaches to the process specified in pid, making it a tracee of the calling process.
39764 -+/// Attaches to the process specified by `pid`, making it a tracee of the calling process.
39765 - pub fn attach(pid: Pid) -> Result<()> {
39766 - unsafe {
39767 - ptrace_other(
39768 -@@ -316,16 +334,36 @@ pub fn attach(pid: Pid) -> Result<()> {
39769 - }
39770 - }
39771 -
39772 -+/// Attach to a running process, as with `ptrace(PTRACE_SEIZE, ...)`
39773 -+///
39774 -+/// Attaches to the process specified in pid, making it a tracee of the calling process.
39775 -+#[cfg(all(target_os = "linux", not(any(target_arch = "mips", target_arch = "mips64"))))]
39776 -+pub fn seize(pid: Pid, options: Options) -> Result<()> {
39777 -+ unsafe {
39778 -+ ptrace_other(
39779 -+ Request::PTRACE_SEIZE,
39780 -+ pid,
39781 -+ ptr::null_mut(),
39782 -+ options.bits() as *mut c_void,
39783 -+ ).map(drop) // ignore the useless return value
39784 -+ }
39785 -+}
39786 -+
39787 - /// Detaches the current running process, as with `ptrace(PTRACE_DETACH, ...)`
39788 - ///
39789 --/// Detaches from the process specified in pid allowing it to run freely
39790 --pub fn detach(pid: Pid) -> Result<()> {
39791 -+/// Detaches from the process specified by `pid` allowing it to run freely, optionally delivering a
39792 -+/// signal specified by `sig`.
39793 -+pub fn detach<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
39794 -+ let data = match sig.into() {
39795 -+ Some(s) => s as i32 as *mut c_void,
39796 -+ None => ptr::null_mut(),
39797 -+ };
39798 - unsafe {
39799 - ptrace_other(
39800 - Request::PTRACE_DETACH,
39801 - pid,
39802 - ptr::null_mut(),
39803 -- ptr::null_mut()
39804 -+ data
39805 - ).map(drop)
39806 - }
39807 - }
39808 -@@ -361,7 +399,6 @@ pub fn kill(pid: Pid) -> Result<()> {
39809 - ///
39810 - /// # Example
39811 - /// ```rust
39812 --/// extern crate nix;
39813 - /// use nix::sys::ptrace::step;
39814 - /// use nix::unistd::Pid;
39815 - /// use nix::sys::signal::Signal;
39816 -@@ -388,6 +425,28 @@ pub fn step<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
39817 - }
39818 - }
39819 -
39820 -+/// Move the stopped tracee process forward by a single step or stop at the next syscall
39821 -+/// as with `ptrace(PTRACE_SYSEMU_SINGLESTEP, ...)`
39822 -+///
39823 -+/// Advances the execution by a single step or until the next syscall.
39824 -+/// In case the tracee is stopped at a syscall, the syscall will not be executed.
39825 -+/// Optionally, the signal specified by `sig` is delivered to the tracee upon continuation.
39826 -+#[cfg(all(target_os = "linux", target_env = "gnu", any(target_arch = "x86", target_arch = "x86_64")))]
39827 -+pub fn sysemu_step<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
39828 -+ let data = match sig.into() {
39829 -+ Some(s) => s as i32 as *mut c_void,
39830 -+ None => ptr::null_mut(),
39831 -+ };
39832 -+ unsafe {
39833 -+ ptrace_other(
39834 -+ Request::PTRACE_SYSEMU_SINGLESTEP,
39835 -+ pid,
39836 -+ ptr::null_mut(),
39837 -+ data,
39838 -+ )
39839 -+ .map(drop) // ignore the useless return value
39840 -+ }
39841 -+}
39842 -
39843 - /// Reads a word from a processes memory at the given address
39844 - pub fn read(pid: Pid, addr: AddressType) -> Result<c_long> {
39845 -@@ -395,8 +454,15 @@ pub fn read(pid: Pid, addr: AddressType) -> Result<c_long> {
39846 - }
39847 -
39848 - /// Writes a word into the processes memory at the given address
39849 --pub fn write(pid: Pid, addr: AddressType, data: *mut c_void) -> Result<()> {
39850 -- unsafe {
39851 -- ptrace_other(Request::PTRACE_POKEDATA, pid, addr, data).map(drop)
39852 -- }
39853 -+///
39854 -+/// # Safety
39855 -+///
39856 -+/// The `data` argument is passed directly to `ptrace(2)`. Read that man page
39857 -+/// for guidance.
39858 -+pub unsafe fn write(
39859 -+ pid: Pid,
39860 -+ addr: AddressType,
39861 -+ data: *mut c_void) -> Result<()>
39862 -+{
39863 -+ ptrace_other(Request::PTRACE_POKEDATA, pid, addr, data).map(drop)
39864 - }
39865 -diff --git a/third_party/rust/nix/src/sys/quota.rs b/third_party/rust/nix/src/sys/quota.rs
39866 -index 8946fca2213c8..1933013219102 100644
39867 ---- a/third_party/rust/nix/src/sys/quota.rs
39868 -+++ b/third_party/rust/nix/src/sys/quota.rs
39869 -@@ -15,12 +15,13 @@
39870 - use std::default::Default;
39871 - use std::{mem, ptr};
39872 - use libc::{self, c_int, c_char};
39873 --use {Result, NixPath};
39874 --use errno::Errno;
39875 -+use crate::{Result, NixPath};
39876 -+use crate::errno::Errno;
39877 -
39878 - struct QuotaCmd(QuotaSubCmd, QuotaType);
39879 -
39880 - impl QuotaCmd {
39881 -+ #[allow(unused_unsafe)]
39882 - fn as_int(&self) -> c_int {
39883 - unsafe { libc::QCMD(self.0 as i32, self.1 as i32) }
39884 - }
39885 -@@ -94,8 +95,7 @@ libc_bitflags!(
39886 - );
39887 -
39888 - /// Wrapper type for `if_dqblk`
39889 --// FIXME: Change to repr(transparent)
39890 --#[repr(C)]
39891 -+#[repr(transparent)]
39892 - #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
39893 - pub struct Dqblk(libc::dqblk);
39894 -
39895 -@@ -254,15 +254,17 @@ pub fn quotactl_off<P: ?Sized + NixPath>(which: QuotaType, special: &P) -> Resul
39896 - }
39897 -
39898 - /// Update the on-disk copy of quota usages for a filesystem.
39899 -+///
39900 -+/// If `special` is `None`, then all file systems with active quotas are sync'd.
39901 - pub fn quotactl_sync<P: ?Sized + NixPath>(which: QuotaType, special: Option<&P>) -> Result<()> {
39902 - quotactl(QuotaCmd(QuotaSubCmd::Q_SYNC, which), special, 0, ptr::null_mut())
39903 - }
39904 -
39905 - /// Get disk quota limits and current usage for the given user/group id.
39906 - pub fn quotactl_get<P: ?Sized + NixPath>(which: QuotaType, special: &P, id: c_int) -> Result<Dqblk> {
39907 -- let mut dqblk = unsafe { mem::uninitialized() };
39908 -- quotactl(QuotaCmd(QuotaSubCmd::Q_GETQUOTA, which), Some(special), id, &mut dqblk as *mut _ as *mut c_char)?;
39909 -- dqblk
39910 -+ let mut dqblk = mem::MaybeUninit::uninit();
39911 -+ quotactl(QuotaCmd(QuotaSubCmd::Q_GETQUOTA, which), Some(special), id, dqblk.as_mut_ptr() as *mut c_char)?;
39912 -+ Ok(unsafe{ Dqblk(dqblk.assume_init())})
39913 - }
39914 -
39915 - /// Configure quota values for the specified fields for a given user/group id.
39916 -diff --git a/third_party/rust/nix/src/sys/reboot.rs b/third_party/rust/nix/src/sys/reboot.rs
39917 -index bafa8fc11996d..e319130698e82 100644
39918 ---- a/third_party/rust/nix/src/sys/reboot.rs
39919 -+++ b/third_party/rust/nix/src/sys/reboot.rs
39920 -@@ -1,9 +1,9 @@
39921 - //! Reboot/shutdown or enable/disable Ctrl-Alt-Delete.
39922 -
39923 --use {Error, Result};
39924 --use errno::Errno;
39925 -+use crate::{Error, Result};
39926 -+use crate::errno::Errno;
39927 - use libc;
39928 --use void::Void;
39929 -+use std::convert::Infallible;
39930 - use std::mem::drop;
39931 -
39932 - libc_enum! {
39933 -@@ -22,7 +22,7 @@ libc_enum! {
39934 - }
39935 - }
39936 -
39937 --pub fn reboot(how: RebootMode) -> Result<Void> {
39938 -+pub fn reboot(how: RebootMode) -> Result<Infallible> {
39939 - unsafe {
39940 - libc::reboot(how as libc::c_int)
39941 - };
39942 -diff --git a/third_party/rust/nix/src/sys/select.rs b/third_party/rust/nix/src/sys/select.rs
39943 -index 1b518e29f67a6..a576c7e4929c4 100644
39944 ---- a/third_party/rust/nix/src/sys/select.rs
39945 -+++ b/third_party/rust/nix/src/sys/select.rs
39946 -@@ -1,24 +1,27 @@
39947 -+use std::iter::FusedIterator;
39948 - use std::mem;
39949 -+use std::ops::Range;
39950 - use std::os::unix::io::RawFd;
39951 - use std::ptr::{null, null_mut};
39952 - use libc::{self, c_int};
39953 --use Result;
39954 --use errno::Errno;
39955 --use sys::signal::SigSet;
39956 --use sys::time::{TimeSpec, TimeVal};
39957 -+use crate::Result;
39958 -+use crate::errno::Errno;
39959 -+use crate::sys::signal::SigSet;
39960 -+use crate::sys::time::{TimeSpec, TimeVal};
39961 -
39962 - pub use libc::FD_SETSIZE;
39963 -
39964 --// FIXME: Change to repr(transparent) once it's stable
39965 --#[repr(C)]
39966 -+#[repr(transparent)]
39967 - #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
39968 - pub struct FdSet(libc::fd_set);
39969 -
39970 - impl FdSet {
39971 - pub fn new() -> FdSet {
39972 -- let mut fdset = unsafe { mem::uninitialized() };
39973 -- unsafe { libc::FD_ZERO(&mut fdset) };
39974 -- FdSet(fdset)
39975 -+ let mut fdset = mem::MaybeUninit::uninit();
39976 -+ unsafe {
39977 -+ libc::FD_ZERO(fdset.as_mut_ptr());
39978 -+ FdSet(fdset.assume_init())
39979 -+ }
39980 - }
39981 -
39982 - pub fn insert(&mut self, fd: RawFd) {
39983 -@@ -46,7 +49,6 @@ impl FdSet {
39984 - /// # Example
39985 - ///
39986 - /// ```
39987 -- /// # extern crate nix;
39988 - /// # use nix::sys::select::FdSet;
39989 - /// # fn main() {
39990 - /// let mut set = FdSet::new();
39991 -@@ -58,17 +60,81 @@ impl FdSet {
39992 - ///
39993 - /// [`select`]: fn.select.html
39994 - pub fn highest(&mut self) -> Option<RawFd> {
39995 -- for i in (0..FD_SETSIZE).rev() {
39996 -- let i = i as RawFd;
39997 -- if unsafe { libc::FD_ISSET(i, self as *mut _ as *mut libc::fd_set) } {
39998 -- return Some(i)
39999 -+ self.fds(None).next_back()
40000 -+ }
40001 -+
40002 -+ /// Returns an iterator over the file descriptors in the set.
40003 -+ ///
40004 -+ /// For performance, it takes an optional higher bound: the iterator will
40005 -+ /// not return any elements of the set greater than the given file
40006 -+ /// descriptor.
40007 -+ ///
40008 -+ /// # Examples
40009 -+ ///
40010 -+ /// ```
40011 -+ /// # use nix::sys::select::FdSet;
40012 -+ /// # use std::os::unix::io::RawFd;
40013 -+ /// let mut set = FdSet::new();
40014 -+ /// set.insert(4);
40015 -+ /// set.insert(9);
40016 -+ /// let fds: Vec<RawFd> = set.fds(None).collect();
40017 -+ /// assert_eq!(fds, vec![4, 9]);
40018 -+ /// ```
40019 -+ #[inline]
40020 -+ pub fn fds(&mut self, highest: Option<RawFd>) -> Fds {
40021 -+ Fds {
40022 -+ set: self,
40023 -+ range: 0..highest.map(|h| h as usize + 1).unwrap_or(FD_SETSIZE),
40024 -+ }
40025 -+ }
40026 -+}
40027 -+
40028 -+impl Default for FdSet {
40029 -+ fn default() -> Self {
40030 -+ Self::new()
40031 -+ }
40032 -+}
40033 -+
40034 -+/// Iterator over `FdSet`.
40035 -+#[derive(Debug)]
40036 -+pub struct Fds<'a> {
40037 -+ set: &'a mut FdSet,
40038 -+ range: Range<usize>,
40039 -+}
40040 -+
40041 -+impl<'a> Iterator for Fds<'a> {
40042 -+ type Item = RawFd;
40043 -+
40044 -+ fn next(&mut self) -> Option<RawFd> {
40045 -+ while let Some(i) = self.range.next() {
40046 -+ if self.set.contains(i as RawFd) {
40047 -+ return Some(i as RawFd);
40048 - }
40049 - }
40050 -+ None
40051 -+ }
40052 -+
40053 -+ #[inline]
40054 -+ fn size_hint(&self) -> (usize, Option<usize>) {
40055 -+ let (_, upper) = self.range.size_hint();
40056 -+ (0, upper)
40057 -+ }
40058 -+}
40059 -
40060 -+impl<'a> DoubleEndedIterator for Fds<'a> {
40061 -+ #[inline]
40062 -+ fn next_back(&mut self) -> Option<RawFd> {
40063 -+ while let Some(i) = self.range.next_back() {
40064 -+ if self.set.contains(i as RawFd) {
40065 -+ return Some(i as RawFd);
40066 -+ }
40067 -+ }
40068 - None
40069 - }
40070 - }
40071 -
40072 -+impl<'a> FusedIterator for Fds<'a> {}
40073 -+
40074 - /// Monitors file descriptors for readiness
40075 - ///
40076 - /// Returns the total number of ready file descriptors in all sets. The sets are changed so that all
40077 -@@ -93,9 +159,9 @@ impl FdSet {
40078 - ///
40079 - /// [`FdSet::highest`]: struct.FdSet.html#method.highest
40080 - pub fn select<'a, N, R, W, E, T>(nfds: N,
40081 -- readfds: R,
40082 -- writefds: W,
40083 -- errorfds: E,
40084 -+ readfds: R,
40085 -+ writefds: W,
40086 -+ errorfds: E,
40087 - timeout: T) -> Result<c_int>
40088 - where
40089 - N: Into<Option<c_int>>,
40090 -@@ -122,7 +188,7 @@ where
40091 - let writefds = writefds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
40092 - let errorfds = errorfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
40093 - let timeout = timeout.map(|tv| tv as *mut _ as *mut libc::timeval)
40094 -- .unwrap_or(null_mut());
40095 -+ .unwrap_or(null_mut());
40096 -
40097 - let res = unsafe {
40098 - libc::select(nfds, readfds, writefds, errorfds, timeout)
40099 -@@ -161,10 +227,10 @@ where
40100 - ///
40101 - /// [`FdSet::highest`]: struct.FdSet.html#method.highest
40102 - pub fn pselect<'a, N, R, W, E, T, S>(nfds: N,
40103 -- readfds: R,
40104 -- writefds: W,
40105 -- errorfds: E,
40106 -- timeout: T,
40107 -+ readfds: R,
40108 -+ writefds: W,
40109 -+ errorfds: E,
40110 -+ timeout: T,
40111 - sigmask: S) -> Result<c_int>
40112 - where
40113 - N: Into<Option<c_int>>,
40114 -@@ -207,8 +273,8 @@ where
40115 - mod tests {
40116 - use super::*;
40117 - use std::os::unix::io::RawFd;
40118 -- use sys::time::{TimeVal, TimeValLike};
40119 -- use unistd::{write, pipe};
40120 -+ use crate::sys::time::{TimeVal, TimeValLike};
40121 -+ use crate::unistd::{write, pipe};
40122 -
40123 - #[test]
40124 - fn fdset_insert() {
40125 -@@ -272,6 +338,20 @@ mod tests {
40126 - assert_eq!(set.highest(), Some(7));
40127 - }
40128 -
40129 -+ #[test]
40130 -+ fn fdset_fds() {
40131 -+ let mut set = FdSet::new();
40132 -+ assert_eq!(set.fds(None).collect::<Vec<_>>(), vec![]);
40133 -+ set.insert(0);
40134 -+ assert_eq!(set.fds(None).collect::<Vec<_>>(), vec![0]);
40135 -+ set.insert(90);
40136 -+ assert_eq!(set.fds(None).collect::<Vec<_>>(), vec![0, 90]);
40137 -+
40138 -+ // highest limit
40139 -+ assert_eq!(set.fds(Some(89)).collect::<Vec<_>>(), vec![0]);
40140 -+ assert_eq!(set.fds(Some(90)).collect::<Vec<_>>(), vec![0, 90]);
40141 -+ }
40142 -+
40143 - #[test]
40144 - fn test_select() {
40145 - let (r1, w1) = pipe().unwrap();
40146 -@@ -304,9 +384,9 @@ mod tests {
40147 -
40148 - let mut timeout = TimeVal::seconds(10);
40149 - assert_eq!(1, select(Some(fd_set.highest().unwrap() + 1),
40150 -- &mut fd_set,
40151 -- None,
40152 -- None,
40153 -+ &mut fd_set,
40154 -+ None,
40155 -+ None,
40156 - &mut timeout).unwrap());
40157 - assert!(fd_set.contains(r1));
40158 - assert!(!fd_set.contains(r2));
40159 -@@ -324,9 +404,9 @@ mod tests {
40160 -
40161 - let mut timeout = TimeVal::seconds(10);
40162 - assert_eq!(1, select(::std::cmp::max(r1, r2) + 1,
40163 -- &mut fd_set,
40164 -- None,
40165 -- None,
40166 -+ &mut fd_set,
40167 -+ None,
40168 -+ None,
40169 - &mut timeout).unwrap());
40170 - assert!(fd_set.contains(r1));
40171 - assert!(!fd_set.contains(r2));
40172 -diff --git a/third_party/rust/nix/src/sys/sendfile.rs b/third_party/rust/nix/src/sys/sendfile.rs
40173 -index a47d8962f73fb..84fe2a919e8b4 100644
40174 ---- a/third_party/rust/nix/src/sys/sendfile.rs
40175 -+++ b/third_party/rust/nix/src/sys/sendfile.rs
40176 -@@ -1,10 +1,11 @@
40177 -+use cfg_if::cfg_if;
40178 - use std::os::unix::io::RawFd;
40179 - use std::ptr;
40180 -
40181 - use libc::{self, off_t};
40182 -
40183 --use Result;
40184 --use errno::Errno;
40185 -+use crate::Result;
40186 -+use crate::errno::Errno;
40187 -
40188 - /// Copy up to `count` bytes to `out_fd` from `in_fd` starting at `offset`.
40189 - ///
40190 -@@ -36,7 +37,7 @@ cfg_if! {
40191 - if #[cfg(any(target_os = "freebsd",
40192 - target_os = "ios",
40193 - target_os = "macos"))] {
40194 -- use sys::uio::IoVec;
40195 -+ use crate::sys::uio::IoVec;
40196 -
40197 - #[derive(Clone, Debug, Eq, Hash, PartialEq)]
40198 - struct SendfileHeaderTrailer<'a>(
40199 -@@ -123,6 +124,7 @@ cfg_if! {
40200 - ///
40201 - /// For more information, see
40202 - /// [the sendfile(2) man page.](https://www.freebsd.org/cgi/man.cgi?query=sendfile&sektion=2)
40203 -+ #[allow(clippy::too_many_arguments)]
40204 - pub fn sendfile(
40205 - in_fd: RawFd,
40206 - out_sock: RawFd,
40207 -@@ -136,7 +138,8 @@ cfg_if! {
40208 - // Readahead goes in upper 16 bits
40209 - // Flags goes in lower 16 bits
40210 - // see `man 2 sendfile`
40211 -- let flags: u32 = ((readahead as u32) << 16) | (flags.bits() as u32);
40212 -+ let ra32 = u32::from(readahead);
40213 -+ let flags: u32 = (ra32 << 16) | (flags.bits() as u32);
40214 - let mut bytes_sent: off_t = 0;
40215 - let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers));
40216 - let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr);
40217 -diff --git a/third_party/rust/nix/src/sys/signal.rs b/third_party/rust/nix/src/sys/signal.rs
40218 -index 1013a77fd4b40..2f8b5fa88823d 100644
40219 ---- a/third_party/rust/nix/src/sys/signal.rs
40220 -+++ b/third_party/rust/nix/src/sys/signal.rs
40221 -@@ -3,9 +3,10 @@
40222 -
40223 - ///! Operating system signals.
40224 -
40225 --use libc;
40226 --use {Error, Result};
40227 --use errno::Errno;
40228 -+use crate::{Error, Result};
40229 -+use crate::errno::Errno;
40230 -+use crate::unistd::Pid;
40231 -+use std::convert::TryFrom;
40232 - use std::mem;
40233 - use std::fmt;
40234 - use std::str::FromStr;
40235 -@@ -13,7 +14,7 @@ use std::str::FromStr;
40236 - use std::os::unix::io::RawFd;
40237 - use std::ptr;
40238 -
40239 --#[cfg(not(target_os = "openbsd"))]
40240 -+#[cfg(not(any(target_os = "openbsd", target_os = "redox")))]
40241 - pub use self::sigevent::*;
40242 -
40243 - libc_enum!{
40244 -@@ -38,8 +39,10 @@ libc_enum!{
40245 - SIGPIPE,
40246 - SIGALRM,
40247 - SIGTERM,
40248 -- #[cfg(all(any(target_os = "android", target_os = "emscripten", target_os = "linux"),
40249 -- not(any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64"))))]
40250 -+ #[cfg(all(any(target_os = "android", target_os = "emscripten",
40251 -+ target_os = "fuchsia", target_os = "linux"),
40252 -+ not(any(target_arch = "mips", target_arch = "mips64",
40253 -+ target_arch = "sparc64"))))]
40254 - SIGSTKFLT,
40255 - SIGCHLD,
40256 - SIGCONT,
40257 -@@ -54,12 +57,17 @@ libc_enum!{
40258 - SIGPROF,
40259 - SIGWINCH,
40260 - SIGIO,
40261 -- #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux"))]
40262 -+ #[cfg(any(target_os = "android", target_os = "emscripten",
40263 -+ target_os = "fuchsia", target_os = "linux"))]
40264 - SIGPWR,
40265 - SIGSYS,
40266 -- #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
40267 -+ #[cfg(not(any(target_os = "android", target_os = "emscripten",
40268 -+ target_os = "fuchsia", target_os = "linux",
40269 -+ target_os = "redox")))]
40270 - SIGEMT,
40271 -- #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
40272 -+ #[cfg(not(any(target_os = "android", target_os = "emscripten",
40273 -+ target_os = "fuchsia", target_os = "linux",
40274 -+ target_os = "redox")))]
40275 - SIGINFO,
40276 - }
40277 - }
40278 -@@ -83,8 +91,10 @@ impl FromStr for Signal {
40279 - "SIGPIPE" => Signal::SIGPIPE,
40280 - "SIGALRM" => Signal::SIGALRM,
40281 - "SIGTERM" => Signal::SIGTERM,
40282 -- #[cfg(all(any(target_os = "android", target_os = "emscripten", target_os = "linux"),
40283 -- not(any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64"))))]
40284 -+ #[cfg(all(any(target_os = "android", target_os = "emscripten",
40285 -+ target_os = "fuchsia", target_os = "linux"),
40286 -+ not(any(target_arch = "mips", target_arch = "mips64",
40287 -+ target_arch = "sparc64"))))]
40288 - "SIGSTKFLT" => Signal::SIGSTKFLT,
40289 - "SIGCHLD" => Signal::SIGCHLD,
40290 - "SIGCONT" => Signal::SIGCONT,
40291 -@@ -99,21 +109,31 @@ impl FromStr for Signal {
40292 - "SIGPROF" => Signal::SIGPROF,
40293 - "SIGWINCH" => Signal::SIGWINCH,
40294 - "SIGIO" => Signal::SIGIO,
40295 -- #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux"))]
40296 -+ #[cfg(any(target_os = "android", target_os = "emscripten",
40297 -+ target_os = "fuchsia", target_os = "linux"))]
40298 - "SIGPWR" => Signal::SIGPWR,
40299 - "SIGSYS" => Signal::SIGSYS,
40300 -- #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
40301 -+ #[cfg(not(any(target_os = "android", target_os = "emscripten",
40302 -+ target_os = "fuchsia", target_os = "linux",
40303 -+ target_os = "redox")))]
40304 - "SIGEMT" => Signal::SIGEMT,
40305 -- #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
40306 -+ #[cfg(not(any(target_os = "android", target_os = "emscripten",
40307 -+ target_os = "fuchsia", target_os = "linux",
40308 -+ target_os = "redox")))]
40309 - "SIGINFO" => Signal::SIGINFO,
40310 - _ => return Err(Error::invalid_argument()),
40311 - })
40312 - }
40313 - }
40314 -
40315 --impl AsRef<str> for Signal {
40316 -- fn as_ref(&self) -> &str {
40317 -- match *self {
40318 -+impl Signal {
40319 -+ /// Returns name of signal.
40320 -+ ///
40321 -+ /// This function is equivalent to `<Signal as AsRef<str>>::as_ref()`,
40322 -+ /// with difference that returned string is `'static`
40323 -+ /// and not bound to `self`'s lifetime.
40324 -+ pub fn as_str(self) -> &'static str {
40325 -+ match self {
40326 - Signal::SIGHUP => "SIGHUP",
40327 - Signal::SIGINT => "SIGINT",
40328 - Signal::SIGQUIT => "SIGQUIT",
40329 -@@ -129,7 +149,8 @@ impl AsRef<str> for Signal {
40330 - Signal::SIGPIPE => "SIGPIPE",
40331 - Signal::SIGALRM => "SIGALRM",
40332 - Signal::SIGTERM => "SIGTERM",
40333 -- #[cfg(all(any(target_os = "android", target_os = "emscripten", target_os = "linux"),
40334 -+ #[cfg(all(any(target_os = "android", target_os = "emscripten",
40335 -+ target_os = "fuchsia", target_os = "linux"),
40336 - not(any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64"))))]
40337 - Signal::SIGSTKFLT => "SIGSTKFLT",
40338 - Signal::SIGCHLD => "SIGCHLD",
40339 -@@ -145,17 +166,28 @@ impl AsRef<str> for Signal {
40340 - Signal::SIGPROF => "SIGPROF",
40341 - Signal::SIGWINCH => "SIGWINCH",
40342 - Signal::SIGIO => "SIGIO",
40343 -- #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux"))]
40344 -+ #[cfg(any(target_os = "android", target_os = "emscripten",
40345 -+ target_os = "fuchsia", target_os = "linux"))]
40346 - Signal::SIGPWR => "SIGPWR",
40347 - Signal::SIGSYS => "SIGSYS",
40348 -- #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
40349 -+ #[cfg(not(any(target_os = "android", target_os = "emscripten",
40350 -+ target_os = "fuchsia", target_os = "linux",
40351 -+ target_os = "redox")))]
40352 - Signal::SIGEMT => "SIGEMT",
40353 -- #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
40354 -+ #[cfg(not(any(target_os = "android", target_os = "emscripten",
40355 -+ target_os = "fuchsia", target_os = "linux",
40356 -+ target_os = "redox")))]
40357 - Signal::SIGINFO => "SIGINFO",
40358 - }
40359 - }
40360 - }
40361 -
40362 -+impl AsRef<str> for Signal {
40363 -+ fn as_ref(&self) -> &str {
40364 -+ self.as_str()
40365 -+ }
40366 -+}
40367 -+
40368 - impl fmt::Display for Signal {
40369 - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
40370 - f.write_str(self.as_ref())
40371 -@@ -164,7 +196,41 @@ impl fmt::Display for Signal {
40372 -
40373 - pub use self::Signal::*;
40374 -
40375 --#[cfg(all(any(target_os = "linux", target_os = "android", target_os = "emscripten"), not(any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64"))))]
40376 -+#[cfg(target_os = "redox")]
40377 -+const SIGNALS: [Signal; 29] = [
40378 -+ SIGHUP,
40379 -+ SIGINT,
40380 -+ SIGQUIT,
40381 -+ SIGILL,
40382 -+ SIGTRAP,
40383 -+ SIGABRT,
40384 -+ SIGBUS,
40385 -+ SIGFPE,
40386 -+ SIGKILL,
40387 -+ SIGUSR1,
40388 -+ SIGSEGV,
40389 -+ SIGUSR2,
40390 -+ SIGPIPE,
40391 -+ SIGALRM,
40392 -+ SIGTERM,
40393 -+ SIGCHLD,
40394 -+ SIGCONT,
40395 -+ SIGSTOP,
40396 -+ SIGTSTP,
40397 -+ SIGTTIN,
40398 -+ SIGTTOU,
40399 -+ SIGURG,
40400 -+ SIGXCPU,
40401 -+ SIGXFSZ,
40402 -+ SIGVTALRM,
40403 -+ SIGPROF,
40404 -+ SIGWINCH,
40405 -+ SIGIO,
40406 -+ SIGSYS];
40407 -+#[cfg(all(any(target_os = "linux", target_os = "android",
40408 -+ target_os = "emscripten", target_os = "fuchsia"),
40409 -+ not(any(target_arch = "mips", target_arch = "mips64",
40410 -+ target_arch = "sparc64"))))]
40411 - const SIGNALS: [Signal; 31] = [
40412 - SIGHUP,
40413 - SIGINT,
40414 -@@ -197,7 +263,10 @@ const SIGNALS: [Signal; 31] = [
40415 - SIGIO,
40416 - SIGPWR,
40417 - SIGSYS];
40418 --#[cfg(all(any(target_os = "linux", target_os = "android", target_os = "emscripten"), any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64")))]
40419 -+#[cfg(all(any(target_os = "linux", target_os = "android",
40420 -+ target_os = "emscripten", target_os = "fuchsia"),
40421 -+ any(target_arch = "mips", target_arch = "mips64",
40422 -+ target_arch = "sparc64")))]
40423 - const SIGNALS: [Signal; 30] = [
40424 - SIGHUP,
40425 - SIGINT,
40426 -@@ -229,7 +298,9 @@ const SIGNALS: [Signal; 30] = [
40427 - SIGIO,
40428 - SIGPWR,
40429 - SIGSYS];
40430 --#[cfg(not(any(target_os = "linux", target_os = "android", target_os = "emscripten")))]
40431 -+#[cfg(not(any(target_os = "linux", target_os = "android",
40432 -+ target_os = "fuchsia", target_os = "emscripten",
40433 -+ target_os = "redox")))]
40434 - const SIGNALS: [Signal; 31] = [
40435 - SIGHUP,
40436 - SIGINT,
40437 -@@ -288,12 +359,12 @@ impl Signal {
40438 - pub fn iterator() -> SignalIterator {
40439 - SignalIterator{next: 0}
40440 - }
40441 -+}
40442 -+
40443 -+impl TryFrom<libc::c_int> for Signal {
40444 -+ type Error = Error;
40445 -
40446 -- // We do not implement the From trait, because it is supposed to be infallible.
40447 -- // With Rust RFC 1542 comes the appropriate trait TryFrom. Once it is
40448 -- // implemented, we'll replace this function.
40449 -- #[inline]
40450 -- pub fn from_c_int(signum: libc::c_int) -> Result<Signal> {
40451 -+ fn try_from(signum: libc::c_int) -> Result<Signal> {
40452 - if 0 < signum && signum < NSIG {
40453 - Ok(unsafe { mem::transmute(signum) })
40454 - } else {
40455 -@@ -306,8 +377,13 @@ pub const SIGIOT : Signal = SIGABRT;
40456 - pub const SIGPOLL : Signal = SIGIO;
40457 - pub const SIGUNUSED : Signal = SIGSYS;
40458 -
40459 -+#[cfg(not(target_os = "redox"))]
40460 -+type SaFlags_t = libc::c_int;
40461 -+#[cfg(target_os = "redox")]
40462 -+type SaFlags_t = libc::c_ulong;
40463 -+
40464 - libc_bitflags!{
40465 -- pub struct SaFlags: libc::c_int {
40466 -+ pub struct SaFlags: SaFlags_t {
40467 - SA_NOCLDSTOP;
40468 - SA_NOCLDWAIT;
40469 - SA_NODEFER;
40470 -@@ -335,17 +411,17 @@ pub struct SigSet {
40471 -
40472 - impl SigSet {
40473 - pub fn all() -> SigSet {
40474 -- let mut sigset: libc::sigset_t = unsafe { mem::uninitialized() };
40475 -- let _ = unsafe { libc::sigfillset(&mut sigset as *mut libc::sigset_t) };
40476 -+ let mut sigset = mem::MaybeUninit::uninit();
40477 -+ let _ = unsafe { libc::sigfillset(sigset.as_mut_ptr()) };
40478 -
40479 -- SigSet { sigset: sigset }
40480 -+ unsafe{ SigSet { sigset: sigset.assume_init() } }
40481 - }
40482 -
40483 - pub fn empty() -> SigSet {
40484 -- let mut sigset: libc::sigset_t = unsafe { mem::uninitialized() };
40485 -- let _ = unsafe { libc::sigemptyset(&mut sigset as *mut libc::sigset_t) };
40486 -+ let mut sigset = mem::MaybeUninit::uninit();
40487 -+ let _ = unsafe { libc::sigemptyset(sigset.as_mut_ptr()) };
40488 -
40489 -- SigSet { sigset: sigset }
40490 -+ unsafe{ SigSet { sigset: sigset.assume_init() } }
40491 - }
40492 -
40493 - pub fn add(&mut self, signal: Signal) {
40494 -@@ -380,9 +456,9 @@ impl SigSet {
40495 -
40496 - /// Gets the currently blocked (masked) set of signals for the calling thread.
40497 - pub fn thread_get_mask() -> Result<SigSet> {
40498 -- let mut oldmask: SigSet = unsafe { mem::uninitialized() };
40499 -- pthread_sigmask(SigmaskHow::SIG_SETMASK, None, Some(&mut oldmask))?;
40500 -- Ok(oldmask)
40501 -+ let mut oldmask = mem::MaybeUninit::uninit();
40502 -+ do_pthread_sigmask(SigmaskHow::SIG_SETMASK, None, Some(oldmask.as_mut_ptr()))?;
40503 -+ Ok(unsafe{ SigSet{sigset: oldmask.assume_init()}})
40504 - }
40505 -
40506 - /// Sets the set of signals as the signal mask for the calling thread.
40507 -@@ -402,18 +478,21 @@ impl SigSet {
40508 -
40509 - /// Sets the set of signals as the signal mask, and returns the old mask.
40510 - pub fn thread_swap_mask(&self, how: SigmaskHow) -> Result<SigSet> {
40511 -- let mut oldmask: SigSet = unsafe { mem::uninitialized() };
40512 -- pthread_sigmask(how, Some(self), Some(&mut oldmask))?;
40513 -- Ok(oldmask)
40514 -+ let mut oldmask = mem::MaybeUninit::uninit();
40515 -+ do_pthread_sigmask(how, Some(self), Some(oldmask.as_mut_ptr()))?;
40516 -+ Ok(unsafe{ SigSet{sigset: oldmask.assume_init()}})
40517 - }
40518 -
40519 - /// Suspends execution of the calling thread until one of the signals in the
40520 - /// signal mask becomes pending, and returns the accepted signal.
40521 -+ #[cfg(not(target_os = "redox"))] // RedoxFS does not yet support sigwait
40522 - pub fn wait(&self) -> Result<Signal> {
40523 -- let mut signum: libc::c_int = unsafe { mem::uninitialized() };
40524 -- let res = unsafe { libc::sigwait(&self.sigset as *const libc::sigset_t, &mut signum) };
40525 -+ let mut signum = mem::MaybeUninit::uninit();
40526 -+ let res = unsafe { libc::sigwait(&self.sigset as *const libc::sigset_t, signum.as_mut_ptr()) };
40527 -
40528 -- Errno::result(res).map(|_| Signal::from_c_int(signum).unwrap())
40529 -+ Errno::result(res).map(|_| unsafe {
40530 -+ Signal::try_from(signum.assume_init()).unwrap()
40531 -+ })
40532 - }
40533 - }
40534 -
40535 -@@ -435,6 +514,7 @@ pub enum SigHandler {
40536 - Handler(extern fn(libc::c_int)),
40537 - /// Use the given signal-catching function, which takes in the signal, information about how
40538 - /// the signal was generated, and a pointer to the threads `ucontext_t`.
40539 -+ #[cfg(not(target_os = "redox"))]
40540 - SigAction(extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void))
40541 - }
40542 -
40543 -@@ -451,20 +531,38 @@ impl SigAction {
40544 - /// is the `SigAction` variant). `mask` specifies other signals to block during execution of
40545 - /// the signal-catching function.
40546 - pub fn new(handler: SigHandler, flags: SaFlags, mask: SigSet) -> SigAction {
40547 -- let mut s = unsafe { mem::uninitialized::<libc::sigaction>() };
40548 -- s.sa_sigaction = match handler {
40549 -- SigHandler::SigDfl => libc::SIG_DFL,
40550 -- SigHandler::SigIgn => libc::SIG_IGN,
40551 -- SigHandler::Handler(f) => f as *const extern fn(libc::c_int) as usize,
40552 -- SigHandler::SigAction(f) => f as *const extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void) as usize,
40553 -- };
40554 -- s.sa_flags = match handler {
40555 -- SigHandler::SigAction(_) => (flags | SaFlags::SA_SIGINFO).bits(),
40556 -- _ => (flags - SaFlags::SA_SIGINFO).bits(),
40557 -- };
40558 -- s.sa_mask = mask.sigset;
40559 --
40560 -- SigAction { sigaction: s }
40561 -+ #[cfg(target_os = "redox")]
40562 -+ unsafe fn install_sig(p: *mut libc::sigaction, handler: SigHandler) {
40563 -+ (*p).sa_handler = match handler {
40564 -+ SigHandler::SigDfl => libc::SIG_DFL,
40565 -+ SigHandler::SigIgn => libc::SIG_IGN,
40566 -+ SigHandler::Handler(f) => f as *const extern fn(libc::c_int) as usize,
40567 -+ };
40568 -+ }
40569 -+
40570 -+ #[cfg(not(target_os = "redox"))]
40571 -+ unsafe fn install_sig(p: *mut libc::sigaction, handler: SigHandler) {
40572 -+ (*p).sa_sigaction = match handler {
40573 -+ SigHandler::SigDfl => libc::SIG_DFL,
40574 -+ SigHandler::SigIgn => libc::SIG_IGN,
40575 -+ SigHandler::Handler(f) => f as *const extern fn(libc::c_int) as usize,
40576 -+ SigHandler::SigAction(f) => f as *const extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void) as usize,
40577 -+ };
40578 -+ }
40579 -+
40580 -+ let mut s = mem::MaybeUninit::<libc::sigaction>::uninit();
40581 -+ unsafe {
40582 -+ let p = s.as_mut_ptr();
40583 -+ install_sig(p, handler);
40584 -+ (*p).sa_flags = match handler {
40585 -+ #[cfg(not(target_os = "redox"))]
40586 -+ SigHandler::SigAction(_) => (flags | SaFlags::SA_SIGINFO).bits(),
40587 -+ _ => (flags - SaFlags::SA_SIGINFO).bits(),
40588 -+ };
40589 -+ (*p).sa_mask = mask.sigset;
40590 -+
40591 -+ SigAction { sigaction: s.assume_init() }
40592 -+ }
40593 - }
40594 -
40595 - /// Returns the flags set on the action.
40596 -@@ -479,6 +577,7 @@ impl SigAction {
40597 - }
40598 -
40599 - /// Returns the action's handler.
40600 -+ #[cfg(not(target_os = "redox"))]
40601 - pub fn handler(&self) -> SigHandler {
40602 - match self.sigaction.sa_sigaction {
40603 - libc::SIG_DFL => SigHandler::SigDfl,
40604 -@@ -488,6 +587,16 @@ impl SigAction {
40605 - f => SigHandler::Handler( unsafe { mem::transmute(f) } ),
40606 - }
40607 - }
40608 -+
40609 -+ /// Returns the action's handler.
40610 -+ #[cfg(target_os = "redox")]
40611 -+ pub fn handler(&self) -> SigHandler {
40612 -+ match self.sigaction.sa_handler {
40613 -+ libc::SIG_DFL => SigHandler::SigDfl,
40614 -+ libc::SIG_IGN => SigHandler::SigIgn,
40615 -+ f => SigHandler::Handler( unsafe { mem::transmute(f) } ),
40616 -+ }
40617 -+ }
40618 - }
40619 -
40620 - /// Changes the action taken by a process on receipt of a specific signal.
40621 -@@ -501,12 +610,13 @@ impl SigAction {
40622 - /// the body of the signal-catching function. Be certain to only make syscalls that are explicitly
40623 - /// marked safe for signal handlers and only share global data using atomics.
40624 - pub unsafe fn sigaction(signal: Signal, sigaction: &SigAction) -> Result<SigAction> {
40625 -- let mut oldact = mem::uninitialized::<libc::sigaction>();
40626 -+ let mut oldact = mem::MaybeUninit::<libc::sigaction>::uninit();
40627 -
40628 -- let res =
40629 -- libc::sigaction(signal as libc::c_int, &sigaction.sigaction as *const libc::sigaction, &mut oldact as *mut libc::sigaction);
40630 -+ let res = libc::sigaction(signal as libc::c_int,
40631 -+ &sigaction.sigaction as *const libc::sigaction,
40632 -+ oldact.as_mut_ptr());
40633 -
40634 -- Errno::result(res).map(|_| SigAction { sigaction: oldact })
40635 -+ Errno::result(res).map(|_| SigAction { sigaction: oldact.assume_init() })
40636 - }
40637 -
40638 - /// Signal management (see [signal(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html))
40639 -@@ -534,8 +644,7 @@ pub unsafe fn sigaction(signal: Signal, sigaction: &SigAction) -> Result<SigActi
40640 - ///
40641 - /// ```no_run
40642 - /// # #[macro_use] extern crate lazy_static;
40643 --/// # extern crate libc;
40644 --/// # extern crate nix;
40645 -+/// # use std::convert::TryFrom;
40646 - /// # use std::sync::atomic::{AtomicBool, Ordering};
40647 - /// # use nix::sys::signal::{self, Signal, SigHandler};
40648 - /// lazy_static! {
40649 -@@ -543,7 +652,7 @@ pub unsafe fn sigaction(signal: Signal, sigaction: &SigAction) -> Result<SigActi
40650 - /// }
40651 - ///
40652 - /// extern fn handle_sigint(signal: libc::c_int) {
40653 --/// let signal = Signal::from_c_int(signal).unwrap();
40654 -+/// let signal = Signal::try_from(signal).unwrap();
40655 - /// SIGNALED.store(signal == Signal::SIGINT, Ordering::Relaxed);
40656 - /// }
40657 - ///
40658 -@@ -571,6 +680,7 @@ pub unsafe fn signal(signal: Signal, handler: SigHandler) -> Result<SigHandler>
40659 - SigHandler::SigDfl => libc::signal(signal, libc::SIG_DFL),
40660 - SigHandler::SigIgn => libc::signal(signal, libc::SIG_IGN),
40661 - SigHandler::Handler(handler) => libc::signal(signal, handler as libc::sighandler_t),
40662 -+ #[cfg(not(target_os = "redox"))]
40663 - SigHandler::SigAction(_) => return Err(Error::UnsupportedOperation),
40664 - };
40665 - Errno::result(res).map(|oldhandler| {
40666 -@@ -582,6 +692,25 @@ pub unsafe fn signal(signal: Signal, handler: SigHandler) -> Result<SigHandler>
40667 - })
40668 - }
40669 -
40670 -+fn do_pthread_sigmask(how: SigmaskHow,
40671 -+ set: Option<&SigSet>,
40672 -+ oldset: Option<*mut libc::sigset_t>) -> Result<()> {
40673 -+ if set.is_none() && oldset.is_none() {
40674 -+ return Ok(())
40675 -+ }
40676 -+
40677 -+ let res = unsafe {
40678 -+ // if set or oldset is None, pass in null pointers instead
40679 -+ libc::pthread_sigmask(how as libc::c_int,
40680 -+ set.map_or_else(ptr::null::<libc::sigset_t>,
40681 -+ |s| &s.sigset as *const libc::sigset_t),
40682 -+ oldset.unwrap_or(ptr::null_mut())
40683 -+ )
40684 -+ };
40685 -+
40686 -+ Errno::result(res).map(drop)
40687 -+}
40688 -+
40689 - /// Manages the signal mask (set of blocked signals) for the calling thread.
40690 - ///
40691 - /// If the `set` parameter is `Some(..)`, then the signal mask will be updated with the signal set.
40692 -@@ -599,21 +728,9 @@ pub unsafe fn signal(signal: Signal, handler: SigHandler) -> Result<SigHandler>
40693 - /// or [`sigprocmask`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html) man pages.
40694 - pub fn pthread_sigmask(how: SigmaskHow,
40695 - set: Option<&SigSet>,
40696 -- oldset: Option<&mut SigSet>) -> Result<()> {
40697 -- if set.is_none() && oldset.is_none() {
40698 -- return Ok(())
40699 -- }
40700 --
40701 -- let res = unsafe {
40702 -- // if set or oldset is None, pass in null pointers instead
40703 -- libc::pthread_sigmask(how as libc::c_int,
40704 -- set.map_or_else(ptr::null::<libc::sigset_t>,
40705 -- |s| &s.sigset as *const libc::sigset_t),
40706 -- oldset.map_or_else(ptr::null_mut::<libc::sigset_t>,
40707 -- |os| &mut os.sigset as *mut libc::sigset_t))
40708 -- };
40709 --
40710 -- Errno::result(res).map(drop)
40711 -+ oldset: Option<&mut SigSet>) -> Result<()>
40712 -+{
40713 -+ do_pthread_sigmask(how, set, oldset.map(|os| &mut os.sigset as *mut _ ))
40714 - }
40715 -
40716 - /// Examine and change blocked signals.
40717 -@@ -637,7 +754,7 @@ pub fn sigprocmask(how: SigmaskHow, set: Option<&SigSet>, oldset: Option<&mut Si
40718 - Errno::result(res).map(drop)
40719 - }
40720 -
40721 --pub fn kill<T: Into<Option<Signal>>>(pid: ::unistd::Pid, signal: T) -> Result<()> {
40722 -+pub fn kill<T: Into<Option<Signal>>>(pid: Pid, signal: T) -> Result<()> {
40723 - let res = unsafe { libc::kill(pid.into(),
40724 - match signal.into() {
40725 - Some(s) => s as libc::c_int,
40726 -@@ -653,7 +770,8 @@ pub fn kill<T: Into<Option<Signal>>>(pid: ::unistd::Pid, signal: T) -> Result<()
40727 - /// If `pgrp` less then or equal 1, the behavior is platform-specific.
40728 - /// If `signal` is `None`, `killpg` will only preform error checking and won't
40729 - /// send any signal.
40730 --pub fn killpg<T: Into<Option<Signal>>>(pgrp: ::unistd::Pid, signal: T) -> Result<()> {
40731 -+#[cfg(not(target_os = "fuchsia"))]
40732 -+pub fn killpg<T: Into<Option<Signal>>>(pgrp: Pid, signal: T) -> Result<()> {
40733 - let res = unsafe { libc::killpg(pgrp.into(),
40734 - match signal.into() {
40735 - Some(s) => s as libc::c_int,
40736 -@@ -702,9 +820,8 @@ pub enum SigevNotify {
40737 - si_value: libc::intptr_t },
40738 - }
40739 -
40740 --#[cfg(not(target_os = "openbsd"))]
40741 -+#[cfg(not(any(target_os = "openbsd", target_os = "redox")))]
40742 - mod sigevent {
40743 -- use libc;
40744 - use std::mem;
40745 - use std::ptr;
40746 - use super::SigevNotify;
40747 -@@ -734,7 +851,10 @@ mod sigevent {
40748 - /// `SIGEV_SIGNAL`. That field is part of a union that shares space with the
40749 - /// more genuinely useful `sigev_notify_thread_id`
40750 - pub fn new(sigev_notify: SigevNotify) -> SigEvent {
40751 -- let mut sev = unsafe { mem::zeroed::<libc::sigevent>()};
40752 -+ // NB: This uses MaybeUninit rather than mem::zeroed because libc::sigevent contains a
40753 -+ // function pointer on Fuchsia as of https://github.com/rust-lang/libc/commit/2f59370,
40754 -+ // and function pointers must not be null.
40755 -+ let mut sev = unsafe { mem::MaybeUninit::<libc::sigevent>::zeroed().assume_init() };
40756 - sev.sigev_notify = match sigev_notify {
40757 - SigevNotify::SigevNone => libc::SIGEV_NONE,
40758 - SigevNotify::SigevSignal{..} => libc::SIGEV_SIGNAL,
40759 -@@ -793,6 +913,7 @@ mod sigevent {
40760 -
40761 - #[cfg(test)]
40762 - mod tests {
40763 -+ #[cfg(not(target_os = "redox"))]
40764 - use std::thread;
40765 - use super::*;
40766 -
40767 -@@ -848,6 +969,7 @@ mod tests {
40768 - }
40769 -
40770 - #[test]
40771 -+ #[cfg(not(target_os = "redox"))]
40772 - fn test_thread_signal_set_mask() {
40773 - thread::spawn(|| {
40774 - let prev_mask = SigSet::thread_get_mask()
40775 -@@ -868,6 +990,7 @@ mod tests {
40776 - }
40777 -
40778 - #[test]
40779 -+ #[cfg(not(target_os = "redox"))]
40780 - fn test_thread_signal_block() {
40781 - thread::spawn(|| {
40782 - let mut mask = SigSet::empty();
40783 -@@ -880,6 +1003,7 @@ mod tests {
40784 - }
40785 -
40786 - #[test]
40787 -+ #[cfg(not(target_os = "redox"))]
40788 - fn test_thread_signal_unblock() {
40789 - thread::spawn(|| {
40790 - let mut mask = SigSet::empty();
40791 -@@ -892,6 +1016,7 @@ mod tests {
40792 - }
40793 -
40794 - #[test]
40795 -+ #[cfg(not(target_os = "redox"))]
40796 - fn test_thread_signal_swap() {
40797 - thread::spawn(|| {
40798 - let mut mask = SigSet::empty();
40799 -@@ -914,8 +1039,8 @@ mod tests {
40800 - }
40801 -
40802 - #[test]
40803 -+ #[cfg(not(target_os = "redox"))]
40804 - fn test_sigaction() {
40805 -- use libc;
40806 - thread::spawn(|| {
40807 - extern fn test_sigaction_handler(_: libc::c_int) {}
40808 - extern fn test_sigaction_action(_: libc::c_int,
40809 -@@ -952,6 +1077,7 @@ mod tests {
40810 - }
40811 -
40812 - #[test]
40813 -+ #[cfg(not(target_os = "redox"))]
40814 - fn test_sigwait() {
40815 - thread::spawn(|| {
40816 - let mut mask = SigSet::empty();
40817 -diff --git a/third_party/rust/nix/src/sys/signalfd.rs b/third_party/rust/nix/src/sys/signalfd.rs
40818 -index 5425a27be9e52..c43b45046f719 100644
40819 ---- a/third_party/rust/nix/src/sys/signalfd.rs
40820 -+++ b/third_party/rust/nix/src/sys/signalfd.rs
40821 -@@ -16,10 +16,10 @@
40822 - //! Please note that signal discarding is not specific to `signalfd`, but also happens with regular
40823 - //! signal handlers.
40824 - use libc;
40825 --use unistd;
40826 --use {Error, Result};
40827 --use errno::Errno;
40828 --pub use sys::signal::{self, SigSet};
40829 -+use crate::unistd;
40830 -+use crate::{Error, Result};
40831 -+use crate::errno::Errno;
40832 -+pub use crate::sys::signal::{self, SigSet};
40833 - pub use libc::signalfd_siginfo as siginfo;
40834 -
40835 - use std::os::unix::io::{RawFd, AsRawFd};
40836 -@@ -79,7 +79,7 @@ pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result<RawFd> {
40837 - /// Err(err) => (), // some error happend
40838 - /// }
40839 - /// ```
40840 --#[derive(Clone, Debug, Eq, Hash, PartialEq)]
40841 -+#[derive(Debug, Eq, Hash, PartialEq)]
40842 - pub struct SignalFd(RawFd);
40843 -
40844 - impl SignalFd {
40845 -@@ -98,10 +98,15 @@ impl SignalFd {
40846 - }
40847 -
40848 - pub fn read_signal(&mut self) -> Result<Option<siginfo>> {
40849 -- let mut buffer: [u8; SIGNALFD_SIGINFO_SIZE] = unsafe { mem::uninitialized() };
40850 --
40851 -- match unistd::read(self.0, &mut buffer) {
40852 -- Ok(SIGNALFD_SIGINFO_SIZE) => Ok(Some(unsafe { mem::transmute(buffer) })),
40853 -+ let mut buffer = mem::MaybeUninit::<[u8; SIGNALFD_SIGINFO_SIZE]>::uninit();
40854 -+
40855 -+ let res = Errno::result(unsafe {
40856 -+ libc::read(self.0,
40857 -+ buffer.as_mut_ptr() as *mut libc::c_void,
40858 -+ SIGNALFD_SIGINFO_SIZE as libc::size_t)
40859 -+ }).map(|r| r as usize);
40860 -+ match res {
40861 -+ Ok(SIGNALFD_SIGINFO_SIZE) => Ok(Some(unsafe { mem::transmute(buffer.assume_init()) })),
40862 - Ok(_) => unreachable!("partial read on signalfd"),
40863 - Err(Error::Sys(Errno::EAGAIN)) => Ok(None),
40864 - Err(error) => Err(error)
40865 -@@ -111,7 +116,10 @@ impl SignalFd {
40866 -
40867 - impl Drop for SignalFd {
40868 - fn drop(&mut self) {
40869 -- let _ = unistd::close(self.0);
40870 -+ let e = unistd::close(self.0);
40871 -+ if !std::thread::panicking() && e == Err(Error::Sys(Errno::EBADF)) {
40872 -+ panic!("Closing an invalid file descriptor!");
40873 -+ };
40874 - }
40875 - }
40876 -
40877 -diff --git a/third_party/rust/nix/src/sys/socket/addr.rs b/third_party/rust/nix/src/sys/socket/addr.rs
40878 -index ed41441155361..5a2739bd10194 100644
40879 ---- a/third_party/rust/nix/src/sys/socket/addr.rs
40880 -+++ b/third_party/rust/nix/src/sys/socket/addr.rs
40881 -@@ -1,20 +1,20 @@
40882 - use super::sa_family_t;
40883 --use {Error, Result, NixPath};
40884 --use errno::Errno;
40885 --use libc;
40886 -+use crate::{Error, Result, NixPath};
40887 -+use crate::errno::Errno;
40888 -+use memoffset::offset_of;
40889 - use std::{fmt, mem, net, ptr, slice};
40890 - use std::ffi::OsStr;
40891 - use std::hash::{Hash, Hasher};
40892 - use std::path::Path;
40893 - use std::os::unix::ffi::OsStrExt;
40894 - #[cfg(any(target_os = "android", target_os = "linux"))]
40895 --use ::sys::socket::addr::netlink::NetlinkAddr;
40896 -+use crate::sys::socket::addr::netlink::NetlinkAddr;
40897 - #[cfg(any(target_os = "android", target_os = "linux"))]
40898 --use ::sys::socket::addr::alg::AlgAddr;
40899 -+use crate::sys::socket::addr::alg::AlgAddr;
40900 - #[cfg(any(target_os = "ios", target_os = "macos"))]
40901 - use std::os::unix::io::RawFd;
40902 - #[cfg(any(target_os = "ios", target_os = "macos"))]
40903 --use ::sys::socket::addr::sys_control::SysControlAddr;
40904 -+use crate::sys::socket::addr::sys_control::SysControlAddr;
40905 - #[cfg(any(target_os = "android",
40906 - target_os = "dragonfly",
40907 - target_os = "freebsd",
40908 -@@ -22,9 +22,10 @@ use ::sys::socket::addr::sys_control::SysControlAddr;
40909 - target_os = "linux",
40910 - target_os = "macos",
40911 - target_os = "netbsd",
40912 -- target_os = "openbsd"))]
40913 -+ target_os = "openbsd",
40914 -+ target_os = "fuchsia"))]
40915 - pub use self::datalink::LinkAddr;
40916 --#[cfg(target_os = "linux")]
40917 -+#[cfg(any(target_os = "android", target_os = "linux"))]
40918 - pub use self::vsock::VsockAddr;
40919 -
40920 - /// These constants specify the protocol family to be used
40921 -@@ -42,7 +43,7 @@ pub enum AddressFamily {
40922 - #[cfg(any(target_os = "android", target_os = "linux"))]
40923 - Netlink = libc::AF_NETLINK,
40924 - /// Low level packet interface (see [`packet(7)`](http://man7.org/linux/man-pages/man7/packet.7.html))
40925 -- #[cfg(any(target_os = "android", target_os = "linux"))]
40926 -+ #[cfg(any(target_os = "android", target_os = "linux", target_os = "fuchsia"))]
40927 - Packet = libc::AF_PACKET,
40928 - /// KEXT Controls and Notifications
40929 - #[cfg(any(target_os = "ios", target_os = "macos"))]
40930 -@@ -116,7 +117,7 @@ pub enum AddressFamily {
40931 - Alg = libc::AF_ALG,
40932 - #[cfg(target_os = "linux")]
40933 - Nfc = libc::AF_NFC,
40934 -- #[cfg(target_os = "linux")]
40935 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
40936 - Vsock = libc::AF_VSOCK,
40937 - #[cfg(any(target_os = "dragonfly",
40938 - target_os = "freebsd",
40939 -@@ -243,7 +244,7 @@ impl AddressFamily {
40940 - target_os = "netbsd",
40941 - target_os = "openbsd"))]
40942 - libc::AF_LINK => Some(AddressFamily::Link),
40943 -- #[cfg(target_os = "linux")]
40944 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
40945 - libc::AF_VSOCK => Some(AddressFamily::Vsock),
40946 - _ => None
40947 - }
40948 -@@ -367,6 +368,8 @@ impl IpAddr {
40949 - /// Create a new IpAddr that contains an IPv6 address.
40950 - ///
40951 - /// The result will represent the IP address a:b:c:d:e:f
40952 -+ #[allow(clippy::many_single_char_names)]
40953 -+ #[allow(clippy::too_many_arguments)]
40954 - pub fn new_v6(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> IpAddr {
40955 - IpAddr::V6(Ipv6Addr::new(a, b, c, d, e, f, g, h))
40956 - }
40957 -@@ -405,15 +408,18 @@ impl fmt::Display for IpAddr {
40958 - pub struct Ipv4Addr(pub libc::in_addr);
40959 -
40960 - impl Ipv4Addr {
40961 -+ #[allow(clippy::identity_op)] // More readable this way
40962 - pub fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
40963 -- let ip = (((a as u32) << 24) |
40964 -- ((b as u32) << 16) |
40965 -- ((c as u32) << 8) |
40966 -- ((d as u32) << 0)).to_be();
40967 -+ let ip = ((u32::from(a) << 24) |
40968 -+ (u32::from(b) << 16) |
40969 -+ (u32::from(c) << 8) |
40970 -+ (u32::from(d) << 0)).to_be();
40971 -
40972 - Ipv4Addr(libc::in_addr { s_addr: ip })
40973 - }
40974 -
40975 -+ // Use pass by reference for symmetry with Ipv6Addr::from_std
40976 -+ #[allow(clippy::trivially_copy_pass_by_ref)]
40977 - pub fn from_std(std: &net::Ipv4Addr) -> Ipv4Addr {
40978 - let bits = std.octets();
40979 - Ipv4Addr::new(bits[0], bits[1], bits[2], bits[3])
40980 -@@ -423,12 +429,12 @@ impl Ipv4Addr {
40981 - Ipv4Addr(libc::in_addr { s_addr: libc::INADDR_ANY })
40982 - }
40983 -
40984 -- pub fn octets(&self) -> [u8; 4] {
40985 -+ pub fn octets(self) -> [u8; 4] {
40986 - let bits = u32::from_be(self.0.s_addr);
40987 - [(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8]
40988 - }
40989 -
40990 -- pub fn to_std(&self) -> net::Ipv4Addr {
40991 -+ pub fn to_std(self) -> net::Ipv4Addr {
40992 - let bits = self.octets();
40993 - net::Ipv4Addr::new(bits[0], bits[1], bits[2], bits[3])
40994 - }
40995 -@@ -467,10 +473,10 @@ macro_rules! to_u16_array {
40996 - }
40997 -
40998 - impl Ipv6Addr {
40999 -+ #[allow(clippy::many_single_char_names)]
41000 -+ #[allow(clippy::too_many_arguments)]
41001 - pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr {
41002 -- let mut in6_addr_var: libc::in6_addr = unsafe{mem::uninitialized()};
41003 -- in6_addr_var.s6_addr = to_u8_array!(a,b,c,d,e,f,g,h);
41004 -- Ipv6Addr(in6_addr_var)
41005 -+ Ipv6Addr(libc::in6_addr{s6_addr: to_u8_array!(a,b,c,d,e,f,g,h)})
41006 - }
41007 -
41008 - pub fn from_std(std: &net::Ipv6Addr) -> Ipv6Addr {
41009 -@@ -555,7 +561,7 @@ impl UnixAddr {
41010 - ret.sun_path.as_mut_ptr().offset(1) as *mut u8,
41011 - path.len());
41012 -
41013 -- Ok(UnixAddr(ret, ret.sun_path.len()))
41014 -+ Ok(UnixAddr(ret, path.len() + 1))
41015 - }
41016 - }
41017 -
41018 -@@ -643,7 +649,7 @@ pub enum SockAddr {
41019 - target_os = "netbsd",
41020 - target_os = "openbsd"))]
41021 - Link(LinkAddr),
41022 -- #[cfg(target_os = "linux")]
41023 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41024 - Vsock(VsockAddr),
41025 - }
41026 -
41027 -@@ -671,7 +677,7 @@ impl SockAddr {
41028 - SysControlAddr::from_name(sockfd, name, unit).map(|a| SockAddr::SysControl(a))
41029 - }
41030 -
41031 -- #[cfg(target_os = "linux")]
41032 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41033 - pub fn new_vsock(cid: u32, port: u32) -> SockAddr {
41034 - SockAddr::Vsock(VsockAddr::new(cid, port))
41035 - }
41036 -@@ -696,7 +702,7 @@ impl SockAddr {
41037 - target_os = "netbsd",
41038 - target_os = "openbsd"))]
41039 - SockAddr::Link(..) => AddressFamily::Link,
41040 -- #[cfg(target_os = "linux")]
41041 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41042 - SockAddr::Vsock(..) => AddressFamily::Vsock,
41043 - }
41044 - }
41045 -@@ -709,11 +715,17 @@ impl SockAddr {
41046 - ///
41047 - /// Supports only the following address families: Unix, Inet (v4 & v6), Netlink and System.
41048 - /// Returns None for unsupported families.
41049 -- pub unsafe fn from_libc_sockaddr(addr: *const libc::sockaddr) -> Option<SockAddr> {
41050 -+ ///
41051 -+ /// # Safety
41052 -+ ///
41053 -+ /// unsafe because it takes a raw pointer as argument. The caller must
41054 -+ /// ensure that the pointer is valid.
41055 -+ #[cfg(not(target_os = "fuchsia"))]
41056 -+ pub(crate) unsafe fn from_libc_sockaddr(addr: *const libc::sockaddr) -> Option<SockAddr> {
41057 - if addr.is_null() {
41058 - None
41059 - } else {
41060 -- match AddressFamily::from_i32((*addr).sa_family as i32) {
41061 -+ match AddressFamily::from_i32(i32::from((*addr).sa_family)) {
41062 - Some(AddressFamily::Unix) => None,
41063 - Some(AddressFamily::Inet) => Some(SockAddr::Inet(
41064 - InetAddr::V4(*(addr as *const libc::sockaddr_in)))),
41065 -@@ -742,7 +754,7 @@ impl SockAddr {
41066 - Some(SockAddr::Link(ether_addr))
41067 - }
41068 - },
41069 -- #[cfg(target_os = "linux")]
41070 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41071 - Some(AddressFamily::Vsock) => Some(SockAddr::Vsock(
41072 - VsockAddr(*(addr as *const libc::sockaddr_vm)))),
41073 - // Other address families are currently not supported and simply yield a None
41074 -@@ -759,28 +771,83 @@ impl SockAddr {
41075 - /// with the size of the actual data type. sockaddr is commonly used as a proxy for
41076 - /// a superclass as C doesn't support inheritance, so many functions that take
41077 - /// a sockaddr * need to take the size of the underlying type as well and then internally cast it back.
41078 -- pub unsafe fn as_ffi_pair(&self) -> (&libc::sockaddr, libc::socklen_t) {
41079 -+ pub fn as_ffi_pair(&self) -> (&libc::sockaddr, libc::socklen_t) {
41080 - match *self {
41081 -- SockAddr::Inet(InetAddr::V4(ref addr)) => (mem::transmute(addr), mem::size_of::<libc::sockaddr_in>() as libc::socklen_t),
41082 -- SockAddr::Inet(InetAddr::V6(ref addr)) => (mem::transmute(addr), mem::size_of::<libc::sockaddr_in6>() as libc::socklen_t),
41083 -- SockAddr::Unix(UnixAddr(ref addr, len)) => (mem::transmute(addr), (len + offset_of!(libc::sockaddr_un, sun_path)) as libc::socklen_t),
41084 -+ SockAddr::Inet(InetAddr::V4(ref addr)) => (
41085 -+ // This cast is always allowed in C
41086 -+ unsafe {
41087 -+ &*(addr as *const libc::sockaddr_in as *const libc::sockaddr)
41088 -+ },
41089 -+ mem::size_of_val(addr) as libc::socklen_t
41090 -+ ),
41091 -+ SockAddr::Inet(InetAddr::V6(ref addr)) => (
41092 -+ // This cast is always allowed in C
41093 -+ unsafe {
41094 -+ &*(addr as *const libc::sockaddr_in6 as *const libc::sockaddr)
41095 -+ },
41096 -+ mem::size_of_val(addr) as libc::socklen_t
41097 -+ ),
41098 -+ SockAddr::Unix(UnixAddr(ref addr, len)) => (
41099 -+ // This cast is always allowed in C
41100 -+ unsafe {
41101 -+ &*(addr as *const libc::sockaddr_un as *const libc::sockaddr)
41102 -+ },
41103 -+ (len + offset_of!(libc::sockaddr_un, sun_path)) as libc::socklen_t
41104 -+ ),
41105 - #[cfg(any(target_os = "android", target_os = "linux"))]
41106 -- SockAddr::Netlink(NetlinkAddr(ref sa)) => (mem::transmute(sa), mem::size_of::<libc::sockaddr_nl>() as libc::socklen_t),
41107 -+ SockAddr::Netlink(NetlinkAddr(ref sa)) => (
41108 -+ // This cast is always allowed in C
41109 -+ unsafe {
41110 -+ &*(sa as *const libc::sockaddr_nl as *const libc::sockaddr)
41111 -+ },
41112 -+ mem::size_of_val(sa) as libc::socklen_t
41113 -+ ),
41114 - #[cfg(any(target_os = "android", target_os = "linux"))]
41115 -- SockAddr::Alg(AlgAddr(ref sa)) => (mem::transmute(sa), mem::size_of::<libc::sockaddr_alg>() as libc::socklen_t),
41116 -+ SockAddr::Alg(AlgAddr(ref sa)) => (
41117 -+ // This cast is always allowed in C
41118 -+ unsafe {
41119 -+ &*(sa as *const libc::sockaddr_alg as *const libc::sockaddr)
41120 -+ },
41121 -+ mem::size_of_val(sa) as libc::socklen_t
41122 -+ ),
41123 - #[cfg(any(target_os = "ios", target_os = "macos"))]
41124 -- SockAddr::SysControl(SysControlAddr(ref sa)) => (mem::transmute(sa), mem::size_of::<libc::sockaddr_ctl>() as libc::socklen_t),
41125 -+ SockAddr::SysControl(SysControlAddr(ref sa)) => (
41126 -+ // This cast is always allowed in C
41127 -+ unsafe {
41128 -+ &*(sa as *const libc::sockaddr_ctl as *const libc::sockaddr)
41129 -+ },
41130 -+ mem::size_of_val(sa) as libc::socklen_t
41131 -+
41132 -+ ),
41133 - #[cfg(any(target_os = "android", target_os = "linux"))]
41134 -- SockAddr::Link(LinkAddr(ref ether_addr)) => (mem::transmute(ether_addr), mem::size_of::<libc::sockaddr_ll>() as libc::socklen_t),
41135 -+ SockAddr::Link(LinkAddr(ref addr)) => (
41136 -+ // This cast is always allowed in C
41137 -+ unsafe {
41138 -+ &*(addr as *const libc::sockaddr_ll as *const libc::sockaddr)
41139 -+ },
41140 -+ mem::size_of_val(addr) as libc::socklen_t
41141 -+ ),
41142 - #[cfg(any(target_os = "dragonfly",
41143 - target_os = "freebsd",
41144 - target_os = "ios",
41145 - target_os = "macos",
41146 - target_os = "netbsd",
41147 - target_os = "openbsd"))]
41148 -- SockAddr::Link(LinkAddr(ref ether_addr)) => (mem::transmute(ether_addr), mem::size_of::<libc::sockaddr_dl>() as libc::socklen_t),
41149 -- #[cfg(target_os = "linux")]
41150 -- SockAddr::Vsock(VsockAddr(ref sa)) => (mem::transmute(sa), mem::size_of::<libc::sockaddr_vm>() as libc::socklen_t),
41151 -+ SockAddr::Link(LinkAddr(ref addr)) => (
41152 -+ // This cast is always allowed in C
41153 -+ unsafe {
41154 -+ &*(addr as *const libc::sockaddr_dl as *const libc::sockaddr)
41155 -+ },
41156 -+ mem::size_of_val(addr) as libc::socklen_t
41157 -+ ),
41158 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41159 -+ SockAddr::Vsock(VsockAddr(ref sa)) => (
41160 -+ // This cast is always allowed in C
41161 -+ unsafe {
41162 -+ &*(sa as *const libc::sockaddr_vm as *const libc::sockaddr)
41163 -+ },
41164 -+ mem::size_of_val(sa) as libc::socklen_t
41165 -+ ),
41166 - }
41167 - }
41168 - }
41169 -@@ -805,7 +872,7 @@ impl fmt::Display for SockAddr {
41170 - target_os = "netbsd",
41171 - target_os = "openbsd"))]
41172 - SockAddr::Link(ref ether_addr) => ether_addr.fmt(f),
41173 -- #[cfg(target_os = "linux")]
41174 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41175 - SockAddr::Vsock(ref svm) => svm.fmt(f),
41176 - }
41177 - }
41178 -@@ -813,7 +880,7 @@ impl fmt::Display for SockAddr {
41179 -
41180 - #[cfg(any(target_os = "android", target_os = "linux"))]
41181 - pub mod netlink {
41182 -- use ::sys::socket::addr::AddressFamily;
41183 -+ use crate::sys::socket::addr::AddressFamily;
41184 - use libc::{sa_family_t, sockaddr_nl};
41185 - use std::{fmt, mem};
41186 -
41187 -@@ -911,11 +978,11 @@ pub mod alg {
41188 -
41189 - #[cfg(any(target_os = "ios", target_os = "macos"))]
41190 - pub mod sys_control {
41191 -- use ::sys::socket::addr::AddressFamily;
41192 -+ use crate::sys::socket::addr::AddressFamily;
41193 - use libc::{self, c_uchar};
41194 - use std::{fmt, mem};
41195 - use std::os::unix::io::RawFd;
41196 -- use {Errno, Error, Result};
41197 -+ use crate::{Errno, Error, Result};
41198 -
41199 - // FIXME: Move type into `libc`
41200 - #[repr(C)]
41201 -@@ -957,7 +1024,7 @@ pub mod sys_control {
41202 -
41203 - let mut ctl_name = [0; MAX_KCTL_NAME];
41204 - ctl_name[..name.len()].clone_from_slice(name.as_bytes());
41205 -- let mut info = ctl_ioc_info { ctl_id: 0, ctl_name: ctl_name };
41206 -+ let mut info = ctl_ioc_info { ctl_id: 0, ctl_name };
41207 -
41208 - unsafe { ctl_info(sockfd, &mut info)?; }
41209 -
41210 -@@ -981,9 +1048,9 @@ pub mod sys_control {
41211 - }
41212 -
41213 -
41214 --#[cfg(any(target_os = "android", target_os = "linux"))]
41215 -+#[cfg(any(target_os = "android", target_os = "linux", target_os = "fuchsia"))]
41216 - mod datalink {
41217 -- use super::{libc, fmt, AddressFamily};
41218 -+ use super::{fmt, AddressFamily};
41219 -
41220 - /// Hardware Address
41221 - #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
41222 -@@ -1023,14 +1090,14 @@ mod datalink {
41223 -
41224 - /// Physical-layer address (MAC)
41225 - pub fn addr(&self) -> [u8; 6] {
41226 -- let a = self.0.sll_addr[0] as u8;
41227 -- let b = self.0.sll_addr[1] as u8;
41228 -- let c = self.0.sll_addr[2] as u8;
41229 -- let d = self.0.sll_addr[3] as u8;
41230 -- let e = self.0.sll_addr[4] as u8;
41231 -- let f = self.0.sll_addr[5] as u8;
41232 --
41233 -- [a, b, c, d, e, f]
41234 -+ [
41235 -+ self.0.sll_addr[0] as u8,
41236 -+ self.0.sll_addr[1] as u8,
41237 -+ self.0.sll_addr[2] as u8,
41238 -+ self.0.sll_addr[3] as u8,
41239 -+ self.0.sll_addr[4] as u8,
41240 -+ self.0.sll_addr[5] as u8,
41241 -+ ]
41242 - }
41243 - }
41244 -
41245 -@@ -1055,7 +1122,7 @@ mod datalink {
41246 - target_os = "netbsd",
41247 - target_os = "openbsd"))]
41248 - mod datalink {
41249 -- use super::{libc, fmt, AddressFamily};
41250 -+ use super::{fmt, AddressFamily};
41251 -
41252 - /// Hardware Address
41253 - #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
41254 -@@ -1069,7 +1136,7 @@ mod datalink {
41255 -
41256 - /// always == AF_LINK
41257 - pub fn family(&self) -> AddressFamily {
41258 -- assert_eq!(self.0.sdl_family as i32, libc::AF_LINK);
41259 -+ assert_eq!(i32::from(self.0.sdl_family), libc::AF_LINK);
41260 - AddressFamily::Link
41261 - }
41262 -
41263 -@@ -1105,11 +1172,7 @@ mod datalink {
41264 - let alen = self.alen();
41265 - let data_len = self.0.sdl_data.len();
41266 -
41267 -- if alen > 0 && nlen + alen < data_len {
41268 -- false
41269 -- } else {
41270 -- true
41271 -- }
41272 -+ alen == 0 || nlen + alen >= data_len
41273 - }
41274 -
41275 - /// Physical-layer address (MAC)
41276 -@@ -1119,14 +1182,14 @@ mod datalink {
41277 -
41278 - assert!(!self.is_empty());
41279 -
41280 -- let a = data[nlen] as u8;
41281 -- let b = data[nlen + 1] as u8;
41282 -- let c = data[nlen + 2] as u8;
41283 -- let d = data[nlen + 3] as u8;
41284 -- let e = data[nlen + 4] as u8;
41285 -- let f = data[nlen + 5] as u8;
41286 --
41287 -- [a, b, c, d, e, f]
41288 -+ [
41289 -+ data[nlen] as u8,
41290 -+ data[nlen + 1] as u8,
41291 -+ data[nlen + 2] as u8,
41292 -+ data[nlen + 3] as u8,
41293 -+ data[nlen + 4] as u8,
41294 -+ data[nlen + 5] as u8,
41295 -+ ]
41296 - }
41297 - }
41298 -
41299 -@@ -1144,9 +1207,9 @@ mod datalink {
41300 - }
41301 - }
41302 -
41303 --#[cfg(target_os = "linux")]
41304 -+#[cfg(any(target_os = "android", target_os = "linux"))]
41305 - pub mod vsock {
41306 -- use ::sys::socket::addr::AddressFamily;
41307 -+ use crate::sys::socket::addr::AddressFamily;
41308 - use libc::{sa_family_t, sockaddr_vm};
41309 - use std::{fmt, mem};
41310 - use std::hash::{Hash, Hasher};
41311 -@@ -1269,7 +1332,7 @@ mod tests {
41312 - let addr = UnixAddr::new_abstract(name.as_bytes()).unwrap();
41313 -
41314 - let sun_path1 = addr.sun_path();
41315 -- let sun_path2 = [0u8, 110, 105, 120, 0, 97, 98, 115, 116, 114, 97, 99, 116, 0, 116, 101, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
41316 -+ let sun_path2 = [0u8, 110, 105, 120, 0, 97, 98, 115, 116, 114, 97, 99, 116, 0, 116, 101, 115, 116];
41317 - assert_eq!(sun_path1.len(), sun_path2.len());
41318 - for i in 0..sun_path1.len() {
41319 - assert_eq!(sun_path1[i], sun_path2[i]);
41320 -diff --git a/third_party/rust/nix/src/sys/socket/mod.rs b/third_party/rust/nix/src/sys/socket/mod.rs
41321 -index 1c12c5f851734..631d281ed16af 100644
41322 ---- a/third_party/rust/nix/src/sys/socket/mod.rs
41323 -+++ b/third_party/rust/nix/src/sys/socket/mod.rs
41324 -@@ -1,14 +1,15 @@
41325 - //! Socket interface functions
41326 - //!
41327 - //! [Further reading](http://man7.org/linux/man-pages/man7/socket.7.html)
41328 --use {Error, Result};
41329 --use errno::Errno;
41330 -+use cfg_if::cfg_if;
41331 -+use crate::{Error, Result, errno::Errno};
41332 - use libc::{self, c_void, c_int, iovec, socklen_t, size_t,
41333 - CMSG_FIRSTHDR, CMSG_NXTHDR, CMSG_DATA, CMSG_LEN};
41334 -+use memoffset::offset_of;
41335 - use std::{mem, ptr, slice};
41336 - use std::os::unix::io::RawFd;
41337 --use sys::time::TimeVal;
41338 --use sys::uio::IoVec;
41339 -+use crate::sys::time::TimeVal;
41340 -+use crate::sys::uio::IoVec;
41341 -
41342 - mod addr;
41343 - pub mod sockopt;
41344 -@@ -30,11 +31,11 @@ pub use self::addr::{
41345 - LinkAddr,
41346 - };
41347 - #[cfg(any(target_os = "android", target_os = "linux"))]
41348 --pub use ::sys::socket::addr::netlink::NetlinkAddr;
41349 -+pub use crate::sys::socket::addr::netlink::NetlinkAddr;
41350 - #[cfg(any(target_os = "android", target_os = "linux"))]
41351 --pub use sys::socket::addr::alg::AlgAddr;
41352 --#[cfg(target_os = "linux")]
41353 --pub use sys::socket::addr::vsock::VsockAddr;
41354 -+pub use crate::sys::socket::addr::alg::AlgAddr;
41355 -+#[cfg(any(target_os = "android", target_os = "linux"))]
41356 -+pub use crate::sys::socket::addr::vsock::VsockAddr;
41357 -
41358 - pub use libc::{
41359 - cmsghdr,
41360 -@@ -92,6 +93,64 @@ pub enum SockProtocol {
41361 - /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
41362 - #[cfg(any(target_os = "ios", target_os = "macos"))]
41363 - KextControl = libc::SYSPROTO_CONTROL,
41364 -+ /// Receives routing and link updates and may be used to modify the routing tables (both IPv4 and IPv6), IP addresses, link
41365 -+ // parameters, neighbor setups, queueing disciplines, traffic classes and packet classifiers
41366 -+ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
41367 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41368 -+ NetlinkRoute = libc::NETLINK_ROUTE,
41369 -+ /// Reserved for user-mode socket protocols
41370 -+ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
41371 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41372 -+ NetlinkUserSock = libc::NETLINK_USERSOCK,
41373 -+ /// Query information about sockets of various protocol families from the kernel
41374 -+ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
41375 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41376 -+ NetlinkSockDiag = libc::NETLINK_SOCK_DIAG,
41377 -+ /// SELinux event notifications.
41378 -+ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
41379 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41380 -+ NetlinkSELinux = libc::NETLINK_SELINUX,
41381 -+ /// Open-iSCSI
41382 -+ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
41383 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41384 -+ NetlinkISCSI = libc::NETLINK_ISCSI,
41385 -+ /// Auditing
41386 -+ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
41387 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41388 -+ NetlinkAudit = libc::NETLINK_AUDIT,
41389 -+ /// Access to FIB lookup from user space
41390 -+ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
41391 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41392 -+ NetlinkFIBLookup = libc::NETLINK_FIB_LOOKUP,
41393 -+ /// Netfilter subsystem
41394 -+ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
41395 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41396 -+ NetlinkNetFilter = libc::NETLINK_NETFILTER,
41397 -+ /// SCSI Transports
41398 -+ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
41399 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41400 -+ NetlinkSCSITransport = libc::NETLINK_SCSITRANSPORT,
41401 -+ /// Infiniband RDMA
41402 -+ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
41403 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41404 -+ NetlinkRDMA = libc::NETLINK_RDMA,
41405 -+ /// Transport IPv6 packets from netfilter to user space. Used by ip6_queue kernel module.
41406 -+ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
41407 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41408 -+ NetlinkIPv6Firewall = libc::NETLINK_IP6_FW,
41409 -+ /// DECnet routing messages
41410 -+ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
41411 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41412 -+ NetlinkDECNetRoutingMessage = libc::NETLINK_DNRTMSG,
41413 -+ /// Kernel messages to user space
41414 -+ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
41415 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41416 -+ NetlinkKObjectUEvent = libc::NETLINK_KOBJECT_UEVENT,
41417 -+ /// Netlink interface to request information about ciphers registered with the kernel crypto API as well as allow
41418 -+ /// configuration of the kernel crypto API.
41419 -+ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
41420 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
41421 -+ NetlinkCrypto = libc::NETLINK_CRYPTO,
41422 - }
41423 -
41424 - libc_bitflags!{
41425 -@@ -189,12 +248,22 @@ cfg_if! {
41426 - if #[cfg(any(target_os = "android", target_os = "linux"))] {
41427 - /// Unix credentials of the sending process.
41428 - ///
41429 -- /// This struct is used with the `SO_PEERCRED` ancillary message for UNIX sockets.
41430 -- #[repr(C)]
41431 -+ /// This struct is used with the `SO_PEERCRED` ancillary message
41432 -+ /// and the `SCM_CREDENTIALS` control message for UNIX sockets.
41433 -+ #[repr(transparent)]
41434 - #[derive(Clone, Copy, Debug, Eq, PartialEq)]
41435 - pub struct UnixCredentials(libc::ucred);
41436 -
41437 - impl UnixCredentials {
41438 -+ /// Creates a new instance with the credentials of the current process
41439 -+ pub fn new() -> Self {
41440 -+ UnixCredentials(libc::ucred {
41441 -+ pid: crate::unistd::getpid().as_raw(),
41442 -+ uid: crate::unistd::getuid().as_raw(),
41443 -+ gid: crate::unistd::getgid().as_raw(),
41444 -+ })
41445 -+ }
41446 -+
41447 - /// Returns the process identifier
41448 - pub fn pid(&self) -> libc::pid_t {
41449 - self.0.pid
41450 -@@ -211,6 +280,12 @@ cfg_if! {
41451 - }
41452 - }
41453 -
41454 -+ impl Default for UnixCredentials {
41455 -+ fn default() -> Self {
41456 -+ Self::new()
41457 -+ }
41458 -+ }
41459 -+
41460 - impl From<libc::ucred> for UnixCredentials {
41461 - fn from(cred: libc::ucred) -> Self {
41462 - UnixCredentials(cred)
41463 -@@ -222,13 +297,53 @@ cfg_if! {
41464 - self.0
41465 - }
41466 - }
41467 -+ } else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] {
41468 -+ /// Unix credentials of the sending process.
41469 -+ ///
41470 -+ /// This struct is used with the `SCM_CREDS` ancillary message for UNIX sockets.
41471 -+ #[repr(transparent)]
41472 -+ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
41473 -+ pub struct UnixCredentials(libc::cmsgcred);
41474 -+
41475 -+ impl UnixCredentials {
41476 -+ /// Returns the process identifier
41477 -+ pub fn pid(&self) -> libc::pid_t {
41478 -+ self.0.cmcred_pid
41479 -+ }
41480 -+
41481 -+ /// Returns the real user identifier
41482 -+ pub fn uid(&self) -> libc::uid_t {
41483 -+ self.0.cmcred_uid
41484 -+ }
41485 -+
41486 -+ /// Returns the effective user identifier
41487 -+ pub fn euid(&self) -> libc::uid_t {
41488 -+ self.0.cmcred_euid
41489 -+ }
41490 -+
41491 -+ /// Returns the real group identifier
41492 -+ pub fn gid(&self) -> libc::gid_t {
41493 -+ self.0.cmcred_gid
41494 -+ }
41495 -+
41496 -+ /// Returns a list group identifiers (the first one being the effective GID)
41497 -+ pub fn groups(&self) -> &[libc::gid_t] {
41498 -+ unsafe { slice::from_raw_parts(self.0.cmcred_groups.as_ptr() as *const libc::gid_t, self.0.cmcred_ngroups as _) }
41499 -+ }
41500 -+ }
41501 -+
41502 -+ impl From<libc::cmsgcred> for UnixCredentials {
41503 -+ fn from(cred: libc::cmsgcred) -> Self {
41504 -+ UnixCredentials(cred)
41505 -+ }
41506 -+ }
41507 - }
41508 - }
41509 -
41510 - /// Request for multicast socket operations
41511 - ///
41512 - /// This is a wrapper type around `ip_mreq`.
41513 --#[repr(C)]
41514 -+#[repr(transparent)]
41515 - #[derive(Clone, Copy, Debug, Eq, PartialEq)]
41516 - pub struct IpMembershipRequest(libc::ip_mreq);
41517 -
41518 -@@ -247,7 +362,7 @@ impl IpMembershipRequest {
41519 - /// Request for ipv6 multicast socket operations
41520 - ///
41521 - /// This is a wrapper type around `ipv6_mreq`.
41522 --#[repr(C)]
41523 -+#[repr(transparent)]
41524 - #[derive(Clone, Copy, Debug, Eq, PartialEq)]
41525 - pub struct Ipv6MembershipRequest(libc::ipv6_mreq);
41526 -
41527 -@@ -261,21 +376,6 @@ impl Ipv6MembershipRequest {
41528 - }
41529 - }
41530 -
41531 --cfg_if! {
41532 -- // Darwin and DragonFly BSD always align struct cmsghdr to 32-bit only.
41533 -- if #[cfg(any(target_os = "dragonfly", target_os = "ios", target_os = "macos"))] {
41534 -- type align_of_cmsg_data = u32;
41535 -- } else {
41536 -- type align_of_cmsg_data = size_t;
41537 -- }
41538 --}
41539 --
41540 --/// A type that can be used to store ancillary data received by
41541 --/// [`recvmsg`](fn.recvmsg.html)
41542 --pub trait CmsgBuffer {
41543 -- fn as_bytes_mut(&mut self) -> &mut [u8];
41544 --}
41545 --
41546 - /// Create a buffer large enough for storing some control messages as returned
41547 - /// by [`recvmsg`](fn.recvmsg.html).
41548 - ///
41549 -@@ -311,61 +411,11 @@ macro_rules! cmsg_space {
41550 - CMSG_SPACE(mem::size_of::<$x>() as c_uint)
41551 - } as usize;
41552 - )*
41553 -- let mut v = Vec::<u8>::with_capacity(space);
41554 -- // safe because any bit pattern is a valid u8
41555 -- unsafe {v.set_len(space)};
41556 -- v
41557 -+ Vec::<u8>::with_capacity(space)
41558 - }
41559 - }
41560 - }
41561 -
41562 --/// A structure used to make room in a cmsghdr passed to recvmsg. The
41563 --/// size and alignment match that of a cmsghdr followed by a T, but the
41564 --/// fields are not accessible, as the actual types will change on a call
41565 --/// to recvmsg.
41566 --///
41567 --/// To make room for multiple messages, nest the type parameter with
41568 --/// tuples:
41569 --///
41570 --/// ```
41571 --/// use std::os::unix::io::RawFd;
41572 --/// use nix::sys::socket::CmsgSpace;
41573 --/// let cmsg: CmsgSpace<([RawFd; 3], CmsgSpace<[RawFd; 2]>)> = CmsgSpace::new();
41574 --/// ```
41575 --#[repr(C)]
41576 --#[derive(Clone, Copy, Debug, Eq, PartialEq)]
41577 --pub struct CmsgSpace<T> {
41578 -- _hdr: cmsghdr,
41579 -- _pad: [align_of_cmsg_data; 0],
41580 -- _data: T,
41581 --}
41582 --
41583 --impl<T> CmsgSpace<T> {
41584 -- /// Create a CmsgSpace<T>. The structure is used only for space, so
41585 -- /// the fields are uninitialized.
41586 -- #[deprecated( since="0.14.0", note="Use the cmsg_space! macro instead")]
41587 -- pub fn new() -> Self {
41588 -- // Safe because the fields themselves aren't accessible.
41589 -- unsafe { mem::uninitialized() }
41590 -- }
41591 --}
41592 --
41593 --impl<T> CmsgBuffer for CmsgSpace<T> {
41594 -- fn as_bytes_mut(&mut self) -> &mut [u8] {
41595 -- // Safe because nothing ever attempts to access CmsgSpace's fields
41596 -- unsafe {
41597 -- slice::from_raw_parts_mut(self as *mut CmsgSpace<T> as *mut u8,
41598 -- mem::size_of::<Self>())
41599 -- }
41600 -- }
41601 --}
41602 --
41603 --impl CmsgBuffer for Vec<u8> {
41604 -- fn as_bytes_mut(&mut self) -> &mut [u8] {
41605 -- &mut self[..]
41606 -- }
41607 --}
41608 --
41609 - #[derive(Clone, Copy, Debug, Eq, PartialEq)]
41610 - pub struct RecvMsg<'a> {
41611 - pub bytes: usize,
41612 -@@ -433,7 +483,11 @@ pub enum ControlMessageOwned {
41613 - /// Received version of
41614 - /// [`ControlMessage::ScmCredentials`][#enum.ControlMessage.html#variant.ScmCredentials]
41615 - #[cfg(any(target_os = "android", target_os = "linux"))]
41616 -- ScmCredentials(libc::ucred),
41617 -+ ScmCredentials(UnixCredentials),
41618 -+ /// Received version of
41619 -+ /// [`ControlMessage::ScmCreds`][#enum.ControlMessage.html#variant.ScmCreds]
41620 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
41621 -+ ScmCreds(UnixCredentials),
41622 - /// A message of type `SCM_TIMESTAMP`, containing the time the
41623 - /// packet was received by the kernel.
41624 - ///
41625 -@@ -442,10 +496,6 @@ pub enum ControlMessageOwned {
41626 - ///
41627 - /// # Examples
41628 - ///
41629 -- // Disable this test on FreeBSD i386
41630 -- // https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=222039
41631 -- #[cfg_attr(not(all(target_os = "freebsd", target_arch = "x86")), doc = " ```")]
41632 -- #[cfg_attr(all(target_os = "freebsd", target_arch = "x86"), doc = " ```no_run")]
41633 - /// # #[macro_use] extern crate nix;
41634 - /// # use nix::sys::socket::*;
41635 - /// # use nix::sys::uio::IoVec;
41636 -@@ -528,6 +578,18 @@ pub enum ControlMessageOwned {
41637 - target_os = "openbsd",
41638 - ))]
41639 - Ipv4RecvDstAddr(libc::in_addr),
41640 -+
41641 -+ /// UDP Generic Receive Offload (GRO) allows receiving multiple UDP
41642 -+ /// packets from a single sender.
41643 -+ /// Fixed-size payloads are following one by one in a receive buffer.
41644 -+ /// This Control Message indicates the size of all smaller packets,
41645 -+ /// except, maybe, the last one.
41646 -+ ///
41647 -+ /// `UdpGroSegment` socket option should be enabled on a socket
41648 -+ /// to allow receiving GRO packets.
41649 -+ #[cfg(target_os = "linux")]
41650 -+ UdpGroSegments(u16),
41651 -+
41652 - /// Catch-all variant for unimplemented cmsg types.
41653 - #[doc(hidden)]
41654 - Unknown(UnknownCmsg),
41655 -@@ -540,9 +602,9 @@ impl ControlMessageOwned {
41656 - /// specified in the header. Normally, the kernel ensures that this is the
41657 - /// case. "Correct" in this case includes correct length, alignment and
41658 - /// actual content.
41659 -- ///
41660 -- /// Returns `None` if the data may be unaligned. In that case use
41661 -- /// `ControlMessageOwned::decode_from`.
41662 -+ // Clippy complains about the pointer alignment of `p`, not understanding
41663 -+ // that it's being fed to a function that can handle that.
41664 -+ #[allow(clippy::cast_ptr_alignment)]
41665 - unsafe fn decode_from(header: &cmsghdr) -> ControlMessageOwned
41666 - {
41667 - let p = CMSG_DATA(header);
41668 -@@ -553,16 +615,20 @@ impl ControlMessageOwned {
41669 - let n = len / mem::size_of::<RawFd>();
41670 - let mut fds = Vec::with_capacity(n);
41671 - for i in 0..n {
41672 -- let fdp = (p as *const RawFd).offset(i as isize);
41673 -+ let fdp = (p as *const RawFd).add(i);
41674 - fds.push(ptr::read_unaligned(fdp));
41675 - }
41676 -- let cmo = ControlMessageOwned::ScmRights(fds);
41677 -- cmo
41678 -+ ControlMessageOwned::ScmRights(fds)
41679 - },
41680 - #[cfg(any(target_os = "android", target_os = "linux"))]
41681 - (libc::SOL_SOCKET, libc::SCM_CREDENTIALS) => {
41682 - let cred: libc::ucred = ptr::read_unaligned(p as *const _);
41683 -- ControlMessageOwned::ScmCredentials(cred)
41684 -+ ControlMessageOwned::ScmCredentials(cred.into())
41685 -+ }
41686 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
41687 -+ (libc::SOL_SOCKET, libc::SCM_CREDS) => {
41688 -+ let cred: libc::cmsgcred = ptr::read_unaligned(p as *const _);
41689 -+ ControlMessageOwned::ScmCreds(cred.into())
41690 - }
41691 - (libc::SOL_SOCKET, libc::SCM_TIMESTAMP) => {
41692 - let tv: libc::timeval = ptr::read_unaligned(p as *const _);
41693 -@@ -612,6 +678,11 @@ impl ControlMessageOwned {
41694 - let dl = ptr::read_unaligned(p as *const libc::in_addr);
41695 - ControlMessageOwned::Ipv4RecvDstAddr(dl)
41696 - },
41697 -+ #[cfg(target_os = "linux")]
41698 -+ (libc::SOL_UDP, libc::UDP_GRO) => {
41699 -+ let gso_size: u16 = ptr::read_unaligned(p as *const _);
41700 -+ ControlMessageOwned::UdpGroSegments(gso_size)
41701 -+ },
41702 - (_, _) => {
41703 - let sl = slice::from_raw_parts(p, len);
41704 - let ucmsg = UnknownCmsg(*header, Vec::<u8>::from(&sl[..]));
41705 -@@ -650,10 +721,22 @@ pub enum ControlMessage<'a> {
41706 - ///
41707 - /// For further information, please refer to the
41708 - /// [`unix(7)`](http://man7.org/linux/man-pages/man7/unix.7.html) man page.
41709 -- // FIXME: When `#[repr(transparent)]` is stable, use it on `UnixCredentials`
41710 -- // and put that in here instead of a raw ucred.
41711 - #[cfg(any(target_os = "android", target_os = "linux"))]
41712 -- ScmCredentials(&'a libc::ucred),
41713 -+ ScmCredentials(&'a UnixCredentials),
41714 -+ /// A message of type `SCM_CREDS`, containing the pid, uid, euid, gid and groups of
41715 -+ /// a process connected to the socket.
41716 -+ ///
41717 -+ /// This is similar to the socket options `LOCAL_CREDS` and `LOCAL_PEERCRED`, but
41718 -+ /// requires a process to explicitly send its credentials.
41719 -+ ///
41720 -+ /// Credentials are always overwritten by the kernel, so this variant does have
41721 -+ /// any data, unlike the receive-side
41722 -+ /// [`ControlMessageOwned::ScmCreds`][#enum.ControlMessageOwned.html#variant.ScmCreds].
41723 -+ ///
41724 -+ /// For further information, please refer to the
41725 -+ /// [`unix(4)`](https://www.freebsd.org/cgi/man.cgi?query=unix) man page.
41726 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
41727 -+ ScmCreds,
41728 -
41729 - /// Set IV for `AF_ALG` crypto API.
41730 - ///
41731 -@@ -685,6 +768,39 @@ pub enum ControlMessage<'a> {
41732 - ))]
41733 - AlgSetAeadAssoclen(&'a u32),
41734 -
41735 -+ /// UDP GSO makes it possible for applications to generate network packets
41736 -+ /// for a virtual MTU much greater than the real one.
41737 -+ /// The length of the send data no longer matches the expected length on
41738 -+ /// the wire.
41739 -+ /// The size of the datagram payload as it should appear on the wire may be
41740 -+ /// passed through this control message.
41741 -+ /// Send buffer should consist of multiple fixed-size wire payloads
41742 -+ /// following one by one, and the last, possibly smaller one.
41743 -+ #[cfg(target_os = "linux")]
41744 -+ UdpGsoSegments(&'a u16),
41745 -+
41746 -+ /// Configure the sending addressing and interface for v4
41747 -+ ///
41748 -+ /// For further information, please refer to the
41749 -+ /// [`ip(7)`](http://man7.org/linux/man-pages/man7/ip.7.html) man page.
41750 -+ #[cfg(any(target_os = "linux",
41751 -+ target_os = "macos",
41752 -+ target_os = "netbsd",
41753 -+ target_os = "android",
41754 -+ target_os = "ios",))]
41755 -+ Ipv4PacketInfo(&'a libc::in_pktinfo),
41756 -+
41757 -+ /// Configure the sending addressing and interface for v6
41758 -+ ///
41759 -+ /// For further information, please refer to the
41760 -+ /// [`ipv6(7)`](http://man7.org/linux/man-pages/man7/ipv6.7.html) man page.
41761 -+ #[cfg(any(target_os = "linux",
41762 -+ target_os = "macos",
41763 -+ target_os = "netbsd",
41764 -+ target_os = "freebsd",
41765 -+ target_os = "android",
41766 -+ target_os = "ios",))]
41767 -+ Ipv6PacketInfo(&'a libc::in6_pktinfo),
41768 - }
41769 -
41770 - // An opaque structure used to prevent cmsghdr from being a public type
41771 -@@ -715,35 +831,66 @@ impl<'a> ControlMessage<'a> {
41772 -
41773 - /// Return a reference to the payload data as a byte pointer
41774 - fn copy_to_cmsg_data(&self, cmsg_data: *mut u8) {
41775 -- let data_ptr = match self {
41776 -- &ControlMessage::ScmRights(fds) => {
41777 -+ let data_ptr = match *self {
41778 -+ ControlMessage::ScmRights(fds) => {
41779 - fds as *const _ as *const u8
41780 - },
41781 - #[cfg(any(target_os = "android", target_os = "linux"))]
41782 -- &ControlMessage::ScmCredentials(creds) => {
41783 -- creds as *const libc::ucred as *const u8
41784 -+ ControlMessage::ScmCredentials(creds) => {
41785 -+ &creds.0 as *const libc::ucred as *const u8
41786 -+ }
41787 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
41788 -+ ControlMessage::ScmCreds => {
41789 -+ // The kernel overwrites the data, we just zero it
41790 -+ // to make sure it's not uninitialized memory
41791 -+ unsafe { ptr::write_bytes(cmsg_data, 0, self.len()) };
41792 -+ return
41793 - }
41794 - #[cfg(any(target_os = "android", target_os = "linux"))]
41795 -- &ControlMessage::AlgSetIv(iv) => {
41796 -+ ControlMessage::AlgSetIv(iv) => {
41797 -+ #[allow(deprecated)] // https://github.com/rust-lang/libc/issues/1501
41798 -+ let af_alg_iv = libc::af_alg_iv {
41799 -+ ivlen: iv.len() as u32,
41800 -+ iv: [0u8; 0],
41801 -+ };
41802 -+
41803 -+ let size = mem::size_of_val(&af_alg_iv);
41804 -+
41805 - unsafe {
41806 -- let alg_iv = cmsg_data as *mut libc::af_alg_iv;
41807 -- (*alg_iv).ivlen = iv.len() as u32;
41808 -+ ptr::copy_nonoverlapping(
41809 -+ &af_alg_iv as *const _ as *const u8,
41810 -+ cmsg_data,
41811 -+ size,
41812 -+ );
41813 - ptr::copy_nonoverlapping(
41814 - iv.as_ptr(),
41815 -- (*alg_iv).iv.as_mut_ptr(),
41816 -+ cmsg_data.add(size),
41817 - iv.len()
41818 - );
41819 - };
41820 -+
41821 - return
41822 - },
41823 - #[cfg(any(target_os = "android", target_os = "linux"))]
41824 -- &ControlMessage::AlgSetOp(op) => {
41825 -+ ControlMessage::AlgSetOp(op) => {
41826 - op as *const _ as *const u8
41827 - },
41828 - #[cfg(any(target_os = "android", target_os = "linux"))]
41829 -- &ControlMessage::AlgSetAeadAssoclen(len) => {
41830 -+ ControlMessage::AlgSetAeadAssoclen(len) => {
41831 - len as *const _ as *const u8
41832 - },
41833 -+ #[cfg(target_os = "linux")]
41834 -+ ControlMessage::UdpGsoSegments(gso_size) => {
41835 -+ gso_size as *const _ as *const u8
41836 -+ },
41837 -+ #[cfg(any(target_os = "linux", target_os = "macos",
41838 -+ target_os = "netbsd", target_os = "android",
41839 -+ target_os = "ios",))]
41840 -+ ControlMessage::Ipv4PacketInfo(info) => info as *const _ as *const u8,
41841 -+ #[cfg(any(target_os = "linux", target_os = "macos",
41842 -+ target_os = "netbsd", target_os = "freebsd",
41843 -+ target_os = "android", target_os = "ios",))]
41844 -+ ControlMessage::Ipv6PacketInfo(info) => info as *const _ as *const u8,
41845 - };
41846 - unsafe {
41847 - ptr::copy_nonoverlapping(
41848 -@@ -756,60 +903,101 @@ impl<'a> ControlMessage<'a> {
41849 -
41850 - /// The size of the payload, excluding its cmsghdr
41851 - fn len(&self) -> usize {
41852 -- match self {
41853 -- &ControlMessage::ScmRights(fds) => {
41854 -+ match *self {
41855 -+ ControlMessage::ScmRights(fds) => {
41856 - mem::size_of_val(fds)
41857 - },
41858 - #[cfg(any(target_os = "android", target_os = "linux"))]
41859 -- &ControlMessage::ScmCredentials(creds) => {
41860 -+ ControlMessage::ScmCredentials(creds) => {
41861 - mem::size_of_val(creds)
41862 - }
41863 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
41864 -+ ControlMessage::ScmCreds => {
41865 -+ mem::size_of::<libc::cmsgcred>()
41866 -+ }
41867 - #[cfg(any(target_os = "android", target_os = "linux"))]
41868 -- &ControlMessage::AlgSetIv(iv) => {
41869 -- mem::size_of::<libc::af_alg_iv>() + iv.len()
41870 -+ ControlMessage::AlgSetIv(iv) => {
41871 -+ mem::size_of_val(&iv) + iv.len()
41872 - },
41873 - #[cfg(any(target_os = "android", target_os = "linux"))]
41874 -- &ControlMessage::AlgSetOp(op) => {
41875 -+ ControlMessage::AlgSetOp(op) => {
41876 - mem::size_of_val(op)
41877 - },
41878 - #[cfg(any(target_os = "android", target_os = "linux"))]
41879 -- &ControlMessage::AlgSetAeadAssoclen(len) => {
41880 -+ ControlMessage::AlgSetAeadAssoclen(len) => {
41881 - mem::size_of_val(len)
41882 - },
41883 -+ #[cfg(target_os = "linux")]
41884 -+ ControlMessage::UdpGsoSegments(gso_size) => {
41885 -+ mem::size_of_val(gso_size)
41886 -+ },
41887 -+ #[cfg(any(target_os = "linux", target_os = "macos",
41888 -+ target_os = "netbsd", target_os = "android",
41889 -+ target_os = "ios",))]
41890 -+ ControlMessage::Ipv4PacketInfo(info) => mem::size_of_val(info),
41891 -+ #[cfg(any(target_os = "linux", target_os = "macos",
41892 -+ target_os = "netbsd", target_os = "freebsd",
41893 -+ target_os = "android", target_os = "ios",))]
41894 -+ ControlMessage::Ipv6PacketInfo(info) => mem::size_of_val(info),
41895 - }
41896 - }
41897 -
41898 - /// Returns the value to put into the `cmsg_level` field of the header.
41899 - fn cmsg_level(&self) -> libc::c_int {
41900 -- match self {
41901 -- &ControlMessage::ScmRights(_) => libc::SOL_SOCKET,
41902 -+ match *self {
41903 -+ ControlMessage::ScmRights(_) => libc::SOL_SOCKET,
41904 - #[cfg(any(target_os = "android", target_os = "linux"))]
41905 -- &ControlMessage::ScmCredentials(_) => libc::SOL_SOCKET,
41906 -+ ControlMessage::ScmCredentials(_) => libc::SOL_SOCKET,
41907 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
41908 -+ ControlMessage::ScmCreds => libc::SOL_SOCKET,
41909 - #[cfg(any(target_os = "android", target_os = "linux"))]
41910 -- &ControlMessage::AlgSetIv(_) | &ControlMessage::AlgSetOp(_) | &ControlMessage::AlgSetAeadAssoclen(_) => {
41911 -- libc::SOL_ALG
41912 -- },
41913 -+ ControlMessage::AlgSetIv(_) | ControlMessage::AlgSetOp(_) |
41914 -+ ControlMessage::AlgSetAeadAssoclen(_) => libc::SOL_ALG,
41915 -+ #[cfg(target_os = "linux")]
41916 -+ ControlMessage::UdpGsoSegments(_) => libc::SOL_UDP,
41917 -+ #[cfg(any(target_os = "linux", target_os = "macos",
41918 -+ target_os = "netbsd", target_os = "android",
41919 -+ target_os = "ios",))]
41920 -+ ControlMessage::Ipv4PacketInfo(_) => libc::IPPROTO_IP,
41921 -+ #[cfg(any(target_os = "linux", target_os = "macos",
41922 -+ target_os = "netbsd", target_os = "freebsd",
41923 -+ target_os = "android", target_os = "ios",))]
41924 -+ ControlMessage::Ipv6PacketInfo(_) => libc::IPPROTO_IPV6,
41925 - }
41926 - }
41927 -
41928 - /// Returns the value to put into the `cmsg_type` field of the header.
41929 - fn cmsg_type(&self) -> libc::c_int {
41930 -- match self {
41931 -- &ControlMessage::ScmRights(_) => libc::SCM_RIGHTS,
41932 -+ match *self {
41933 -+ ControlMessage::ScmRights(_) => libc::SCM_RIGHTS,
41934 - #[cfg(any(target_os = "android", target_os = "linux"))]
41935 -- &ControlMessage::ScmCredentials(_) => libc::SCM_CREDENTIALS,
41936 -+ ControlMessage::ScmCredentials(_) => libc::SCM_CREDENTIALS,
41937 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
41938 -+ ControlMessage::ScmCreds => libc::SCM_CREDS,
41939 - #[cfg(any(target_os = "android", target_os = "linux"))]
41940 -- &ControlMessage::AlgSetIv(_) => {
41941 -+ ControlMessage::AlgSetIv(_) => {
41942 - libc::ALG_SET_IV
41943 - },
41944 - #[cfg(any(target_os = "android", target_os = "linux"))]
41945 -- &ControlMessage::AlgSetOp(_) => {
41946 -+ ControlMessage::AlgSetOp(_) => {
41947 - libc::ALG_SET_OP
41948 - },
41949 - #[cfg(any(target_os = "android", target_os = "linux"))]
41950 -- &ControlMessage::AlgSetAeadAssoclen(_) => {
41951 -+ ControlMessage::AlgSetAeadAssoclen(_) => {
41952 - libc::ALG_SET_AEAD_ASSOCLEN
41953 - },
41954 -+ #[cfg(target_os = "linux")]
41955 -+ ControlMessage::UdpGsoSegments(_) => {
41956 -+ libc::UDP_SEGMENT
41957 -+ },
41958 -+ #[cfg(any(target_os = "linux", target_os = "macos",
41959 -+ target_os = "netbsd", target_os = "android",
41960 -+ target_os = "ios",))]
41961 -+ ControlMessage::Ipv4PacketInfo(_) => libc::IP_PKTINFO,
41962 -+ #[cfg(any(target_os = "linux", target_os = "macos",
41963 -+ target_os = "netbsd", target_os = "freebsd",
41964 -+ target_os = "android", target_os = "ios",))]
41965 -+ ControlMessage::Ipv6PacketInfo(_) => libc::IPV6_PKTINFO,
41966 - }
41967 - }
41968 -
41969 -@@ -836,12 +1024,303 @@ pub fn sendmsg(fd: RawFd, iov: &[IoVec<&[u8]>], cmsgs: &[ControlMessage],
41970 -
41971 - // First size the buffer needed to hold the cmsgs. It must be zeroed,
41972 - // because subsequent code will not clear the padding bytes.
41973 -- let cmsg_buffer = vec![0u8; capacity];
41974 -+ let mut cmsg_buffer = vec![0u8; capacity];
41975 -+
41976 -+ let mhdr = pack_mhdr_to_send(&mut cmsg_buffer[..], &iov, &cmsgs, addr);
41977 -+
41978 -+ let ret = unsafe { libc::sendmsg(fd, &mhdr, flags.bits()) };
41979 -+
41980 -+ Errno::result(ret).map(|r| r as usize)
41981 -+}
41982 -+
41983 -+#[cfg(any(
41984 -+ target_os = "linux",
41985 -+ target_os = "android",
41986 -+ target_os = "freebsd",
41987 -+ target_os = "netbsd",
41988 -+))]
41989 -+#[derive(Debug)]
41990 -+pub struct SendMmsgData<'a, I, C>
41991 -+ where
41992 -+ I: AsRef<[IoVec<&'a [u8]>]>,
41993 -+ C: AsRef<[ControlMessage<'a>]>
41994 -+{
41995 -+ pub iov: I,
41996 -+ pub cmsgs: C,
41997 -+ pub addr: Option<SockAddr>,
41998 -+ pub _lt: std::marker::PhantomData<&'a I>,
41999 -+}
42000 -+
42001 -+/// An extension of `sendmsg` that allows the caller to transmit multiple
42002 -+/// messages on a socket using a single system call. This has performance
42003 -+/// benefits for some applications.
42004 -+///
42005 -+/// Allocations are performed for cmsgs and to build `msghdr` buffer
42006 -+///
42007 -+/// # Arguments
42008 -+///
42009 -+/// * `fd`: Socket file descriptor
42010 -+/// * `data`: Struct that implements `IntoIterator` with `SendMmsgData` items
42011 -+/// * `flags`: Optional flags passed directly to the operating system.
42012 -+///
42013 -+/// # Returns
42014 -+/// `Vec` with numbers of sent bytes on each sent message.
42015 -+///
42016 -+/// # References
42017 -+/// [`sendmsg`](fn.sendmsg.html)
42018 -+#[cfg(any(
42019 -+ target_os = "linux",
42020 -+ target_os = "android",
42021 -+ target_os = "freebsd",
42022 -+ target_os = "netbsd",
42023 -+))]
42024 -+pub fn sendmmsg<'a, I, C>(
42025 -+ fd: RawFd,
42026 -+ data: impl std::iter::IntoIterator<Item=&'a SendMmsgData<'a, I, C>>,
42027 -+ flags: MsgFlags
42028 -+) -> Result<Vec<usize>>
42029 -+ where
42030 -+ I: AsRef<[IoVec<&'a [u8]>]> + 'a,
42031 -+ C: AsRef<[ControlMessage<'a>]> + 'a,
42032 -+{
42033 -+ let iter = data.into_iter();
42034 -+
42035 -+ let size_hint = iter.size_hint();
42036 -+ let reserve_items = size_hint.1.unwrap_or(size_hint.0);
42037 -+
42038 -+ let mut output = Vec::<libc::mmsghdr>::with_capacity(reserve_items);
42039 -+
42040 -+ let mut cmsgs_buffer = vec![0u8; 0];
42041 -+
42042 -+ for d in iter {
42043 -+ let cmsgs_start = cmsgs_buffer.len();
42044 -+ let cmsgs_required_capacity: usize = d.cmsgs.as_ref().iter().map(|c| c.space()).sum();
42045 -+ let cmsgs_buffer_need_capacity = cmsgs_start + cmsgs_required_capacity;
42046 -+ cmsgs_buffer.resize(cmsgs_buffer_need_capacity, 0);
42047 -+
42048 -+ output.push(libc::mmsghdr {
42049 -+ msg_hdr: pack_mhdr_to_send(
42050 -+ &mut cmsgs_buffer[cmsgs_start..],
42051 -+ &d.iov,
42052 -+ &d.cmsgs,
42053 -+ d.addr.as_ref()
42054 -+ ),
42055 -+ msg_len: 0,
42056 -+ });
42057 -+ };
42058 -+
42059 -+ let ret = unsafe { libc::sendmmsg(fd, output.as_mut_ptr(), output.len() as _, flags.bits() as _) };
42060 -+
42061 -+ let sent_messages = Errno::result(ret)? as usize;
42062 -+ let mut sent_bytes = Vec::with_capacity(sent_messages);
42063 -+
42064 -+ for item in &output {
42065 -+ sent_bytes.push(item.msg_len as usize);
42066 -+ }
42067 -+
42068 -+ Ok(sent_bytes)
42069 -+}
42070 -+
42071 -+
42072 -+#[cfg(any(
42073 -+ target_os = "linux",
42074 -+ target_os = "android",
42075 -+ target_os = "freebsd",
42076 -+ target_os = "netbsd",
42077 -+))]
42078 -+#[derive(Debug)]
42079 -+pub struct RecvMmsgData<'a, I>
42080 -+ where
42081 -+ I: AsRef<[IoVec<&'a mut [u8]>]> + 'a,
42082 -+{
42083 -+ pub iov: I,
42084 -+ pub cmsg_buffer: Option<&'a mut Vec<u8>>,
42085 -+}
42086 -+
42087 -+/// An extension of `recvmsg` that allows the caller to receive multiple
42088 -+/// messages from a socket using a single system call. This has
42089 -+/// performance benefits for some applications.
42090 -+///
42091 -+/// `iov` and `cmsg_buffer` should be constructed similarly to `recvmsg`
42092 -+///
42093 -+/// Multiple allocations are performed
42094 -+///
42095 -+/// # Arguments
42096 -+///
42097 -+/// * `fd`: Socket file descriptor
42098 -+/// * `data`: Struct that implements `IntoIterator` with `RecvMmsgData` items
42099 -+/// * `flags`: Optional flags passed directly to the operating system.
42100 -+///
42101 -+/// # RecvMmsgData
42102 -+///
42103 -+/// * `iov`: Scatter-gather list of buffers to receive the message
42104 -+/// * `cmsg_buffer`: Space to receive ancillary data. Should be created by
42105 -+/// [`cmsg_space!`](macro.cmsg_space.html)
42106 -+///
42107 -+/// # Returns
42108 -+/// A `Vec` with multiple `RecvMsg`, one per received message
42109 -+///
42110 -+/// # References
42111 -+/// - [`recvmsg`](fn.recvmsg.html)
42112 -+/// - [`RecvMsg`](struct.RecvMsg.html)
42113 -+#[cfg(any(
42114 -+ target_os = "linux",
42115 -+ target_os = "android",
42116 -+ target_os = "freebsd",
42117 -+ target_os = "netbsd",
42118 -+))]
42119 -+pub fn recvmmsg<'a, I>(
42120 -+ fd: RawFd,
42121 -+ data: impl std::iter::IntoIterator<Item=&'a mut RecvMmsgData<'a, I>,
42122 -+ IntoIter=impl ExactSizeIterator + Iterator<Item=&'a mut RecvMmsgData<'a, I>>>,
42123 -+ flags: MsgFlags,
42124 -+ timeout: Option<crate::sys::time::TimeSpec>
42125 -+) -> Result<Vec<RecvMsg<'a>>>
42126 -+ where
42127 -+ I: AsRef<[IoVec<&'a mut [u8]>]> + 'a,
42128 -+{
42129 -+ let iter = data.into_iter();
42130 -+
42131 -+ let num_messages = iter.len();
42132 -+
42133 -+ let mut output: Vec<libc::mmsghdr> = Vec::with_capacity(num_messages);
42134 -+
42135 -+ // Addresses should be pre-allocated. pack_mhdr_to_receive will store them
42136 -+ // as raw pointers, so we may not move them. Turn the vec into a boxed
42137 -+ // slice so we won't inadvertently reallocate the vec.
42138 -+ let mut addresses = vec![mem::MaybeUninit::uninit(); num_messages]
42139 -+ .into_boxed_slice();
42140 -+
42141 -+ let results: Vec<_> = iter.enumerate().map(|(i, d)| {
42142 -+ let (msg_controllen, mhdr) = unsafe {
42143 -+ pack_mhdr_to_receive(
42144 -+ d.iov.as_ref(),
42145 -+ &mut d.cmsg_buffer,
42146 -+ addresses[i].as_mut_ptr(),
42147 -+ )
42148 -+ };
42149 -+
42150 -+ output.push(
42151 -+ libc::mmsghdr {
42152 -+ msg_hdr: mhdr,
42153 -+ msg_len: 0,
42154 -+ }
42155 -+ );
42156 -+
42157 -+ (msg_controllen as usize, &mut d.cmsg_buffer)
42158 -+ }).collect();
42159 -+
42160 -+ let timeout = if let Some(mut t) = timeout {
42161 -+ t.as_mut() as *mut libc::timespec
42162 -+ } else {
42163 -+ ptr::null_mut()
42164 -+ };
42165 -+
42166 -+ let ret = unsafe { libc::recvmmsg(fd, output.as_mut_ptr(), output.len() as _, flags.bits() as _, timeout) };
42167 -+
42168 -+ let _ = Errno::result(ret)?;
42169 -+
42170 -+ Ok(output
42171 -+ .into_iter()
42172 -+ .take(ret as usize)
42173 -+ .zip(addresses.iter().map(|addr| unsafe{addr.assume_init()}))
42174 -+ .zip(results.into_iter())
42175 -+ .map(|((mmsghdr, address), (msg_controllen, cmsg_buffer))| {
42176 -+ unsafe {
42177 -+ read_mhdr(
42178 -+ mmsghdr.msg_hdr,
42179 -+ mmsghdr.msg_len as isize,
42180 -+ msg_controllen,
42181 -+ address,
42182 -+ cmsg_buffer
42183 -+ )
42184 -+ }
42185 -+ })
42186 -+ .collect())
42187 -+}
42188 -+
42189 -+unsafe fn read_mhdr<'a, 'b>(
42190 -+ mhdr: msghdr,
42191 -+ r: isize,
42192 -+ msg_controllen: usize,
42193 -+ address: sockaddr_storage,
42194 -+ cmsg_buffer: &'a mut Option<&'b mut Vec<u8>>
42195 -+) -> RecvMsg<'b> {
42196 -+ let cmsghdr = {
42197 -+ if mhdr.msg_controllen > 0 {
42198 -+ // got control message(s)
42199 -+ cmsg_buffer
42200 -+ .as_mut()
42201 -+ .unwrap()
42202 -+ .set_len(mhdr.msg_controllen as usize);
42203 -+ debug_assert!(!mhdr.msg_control.is_null());
42204 -+ debug_assert!(msg_controllen >= mhdr.msg_controllen as usize);
42205 -+ CMSG_FIRSTHDR(&mhdr as *const msghdr)
42206 -+ } else {
42207 -+ ptr::null()
42208 -+ }.as_ref()
42209 -+ };
42210 -+
42211 -+ let address = sockaddr_storage_to_addr(
42212 -+ &address ,
42213 -+ mhdr.msg_namelen as usize
42214 -+ ).ok();
42215 -+
42216 -+ RecvMsg {
42217 -+ bytes: r as usize,
42218 -+ cmsghdr,
42219 -+ address,
42220 -+ flags: MsgFlags::from_bits_truncate(mhdr.msg_flags),
42221 -+ mhdr,
42222 -+ }
42223 -+}
42224 -+
42225 -+unsafe fn pack_mhdr_to_receive<'a, I>(
42226 -+ iov: I,
42227 -+ cmsg_buffer: &mut Option<&mut Vec<u8>>,
42228 -+ address: *mut sockaddr_storage,
42229 -+) -> (usize, msghdr)
42230 -+ where
42231 -+ I: AsRef<[IoVec<&'a mut [u8]>]> + 'a,
42232 -+{
42233 -+ let (msg_control, msg_controllen) = cmsg_buffer.as_mut()
42234 -+ .map(|v| (v.as_mut_ptr(), v.capacity()))
42235 -+ .unwrap_or((ptr::null_mut(), 0));
42236 -+
42237 -+ let mhdr = {
42238 -+ // Musl's msghdr has private fields, so this is the only way to
42239 -+ // initialize it.
42240 -+ let mut mhdr = mem::MaybeUninit::<msghdr>::zeroed();
42241 -+ let p = mhdr.as_mut_ptr();
42242 -+ (*p).msg_name = address as *mut c_void;
42243 -+ (*p).msg_namelen = mem::size_of::<sockaddr_storage>() as socklen_t;
42244 -+ (*p).msg_iov = iov.as_ref().as_ptr() as *mut iovec;
42245 -+ (*p).msg_iovlen = iov.as_ref().len() as _;
42246 -+ (*p).msg_control = msg_control as *mut c_void;
42247 -+ (*p).msg_controllen = msg_controllen as _;
42248 -+ (*p).msg_flags = 0;
42249 -+ mhdr.assume_init()
42250 -+ };
42251 -+
42252 -+ (msg_controllen, mhdr)
42253 -+}
42254 -+
42255 -+fn pack_mhdr_to_send<'a, I, C>(
42256 -+ cmsg_buffer: &mut [u8],
42257 -+ iov: I,
42258 -+ cmsgs: C,
42259 -+ addr: Option<&SockAddr>
42260 -+) -> msghdr
42261 -+ where
42262 -+ I: AsRef<[IoVec<&'a [u8]>]>,
42263 -+ C: AsRef<[ControlMessage<'a>]>
42264 -+{
42265 -+ let capacity = cmsg_buffer.len();
42266 -
42267 - // Next encode the sending address, if provided
42268 - let (name, namelen) = match addr {
42269 - Some(addr) => {
42270 -- let (x, y) = unsafe { addr.as_ffi_pair() };
42271 -+ let (x, y) = addr.as_ffi_pair();
42272 - (x as *const _, y)
42273 - },
42274 - None => (ptr::null(), 0),
42275 -@@ -854,97 +1333,68 @@ pub fn sendmsg(fd: RawFd, iov: &[IoVec<&[u8]>], cmsgs: &[ControlMessage],
42276 - ptr::null_mut()
42277 - };
42278 -
42279 -- let mhdr = {
42280 -+ let mhdr = unsafe {
42281 - // Musl's msghdr has private fields, so this is the only way to
42282 - // initialize it.
42283 -- let mut mhdr: msghdr = unsafe{mem::uninitialized()};
42284 -- mhdr.msg_name = name as *mut _;
42285 -- mhdr.msg_namelen = namelen;
42286 -+ let mut mhdr = mem::MaybeUninit::<msghdr>::zeroed();
42287 -+ let p = mhdr.as_mut_ptr();
42288 -+ (*p).msg_name = name as *mut _;
42289 -+ (*p).msg_namelen = namelen;
42290 - // transmute iov into a mutable pointer. sendmsg doesn't really mutate
42291 - // the buffer, but the standard says that it takes a mutable pointer
42292 -- mhdr.msg_iov = iov.as_ptr() as *mut _;
42293 -- mhdr.msg_iovlen = iov.len() as _;
42294 -- mhdr.msg_control = cmsg_ptr;
42295 -- mhdr.msg_controllen = capacity as _;
42296 -- mhdr.msg_flags = 0;
42297 -- mhdr
42298 -+ (*p).msg_iov = iov.as_ref().as_ptr() as *mut _;
42299 -+ (*p).msg_iovlen = iov.as_ref().len() as _;
42300 -+ (*p).msg_control = cmsg_ptr;
42301 -+ (*p).msg_controllen = capacity as _;
42302 -+ (*p).msg_flags = 0;
42303 -+ mhdr.assume_init()
42304 - };
42305 -
42306 - // Encode each cmsg. This must happen after initializing the header because
42307 - // CMSG_NEXT_HDR and friends read the msg_control and msg_controllen fields.
42308 - // CMSG_FIRSTHDR is always safe
42309 -- let mut pmhdr: *mut cmsghdr = unsafe{CMSG_FIRSTHDR(&mhdr as *const msghdr)};
42310 -- for cmsg in cmsgs {
42311 -+ let mut pmhdr: *mut cmsghdr = unsafe { CMSG_FIRSTHDR(&mhdr as *const msghdr) };
42312 -+ for cmsg in cmsgs.as_ref() {
42313 - assert_ne!(pmhdr, ptr::null_mut());
42314 - // Safe because we know that pmhdr is valid, and we initialized it with
42315 - // sufficient space
42316 - unsafe { cmsg.encode_into(pmhdr) };
42317 - // Safe because mhdr is valid
42318 -- pmhdr = unsafe{CMSG_NXTHDR(&mhdr as *const msghdr, pmhdr)};
42319 -+ pmhdr = unsafe { CMSG_NXTHDR(&mhdr as *const msghdr, pmhdr) };
42320 - }
42321 -
42322 -- let ret = unsafe { libc::sendmsg(fd, &mhdr, flags.bits()) };
42323 --
42324 -- Errno::result(ret).map(|r| r as usize)
42325 -+ mhdr
42326 - }
42327 -
42328 - /// Receive message in scatter-gather vectors from a socket, and
42329 - /// optionally receive ancillary data into the provided buffer.
42330 - /// If no ancillary data is desired, use () as the type parameter.
42331 - ///
42332 -+/// # Arguments
42333 -+///
42334 -+/// * `fd`: Socket file descriptor
42335 -+/// * `iov`: Scatter-gather list of buffers to receive the message
42336 -+/// * `cmsg_buffer`: Space to receive ancillary data. Should be created by
42337 -+/// [`cmsg_space!`](macro.cmsg_space.html)
42338 -+/// * `flags`: Optional flags passed directly to the operating system.
42339 -+///
42340 - /// # References
42341 - /// [recvmsg(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html)
42342 - pub fn recvmsg<'a>(fd: RawFd, iov: &[IoVec<&mut [u8]>],
42343 -- cmsg_buffer: Option<&'a mut dyn CmsgBuffer>,
42344 -+ mut cmsg_buffer: Option<&'a mut Vec<u8>>,
42345 - flags: MsgFlags) -> Result<RecvMsg<'a>>
42346 - {
42347 -- let mut address: sockaddr_storage = unsafe { mem::uninitialized() };
42348 -- let (msg_control, msg_controllen) = match cmsg_buffer {
42349 -- Some(cmsgspace) => {
42350 -- let msg_buf = cmsgspace.as_bytes_mut();
42351 -- (msg_buf.as_mut_ptr(), msg_buf.len())
42352 -- },
42353 -- None => (ptr::null_mut(), 0),
42354 -- };
42355 -- let mut mhdr = {
42356 -- // Musl's msghdr has private fields, so this is the only way to
42357 -- // initialize it.
42358 -- let mut mhdr: msghdr = unsafe{mem::uninitialized()};
42359 -- mhdr.msg_name = &mut address as *mut sockaddr_storage as *mut c_void;
42360 -- mhdr.msg_namelen = mem::size_of::<sockaddr_storage>() as socklen_t;
42361 -- mhdr.msg_iov = iov.as_ptr() as *mut iovec;
42362 -- mhdr.msg_iovlen = iov.len() as _;
42363 -- mhdr.msg_control = msg_control as *mut c_void;
42364 -- mhdr.msg_controllen = msg_controllen as _;
42365 -- mhdr.msg_flags = 0;
42366 -- mhdr
42367 -+ let mut address = mem::MaybeUninit::uninit();
42368 -+
42369 -+ let (msg_controllen, mut mhdr) = unsafe {
42370 -+ pack_mhdr_to_receive(&iov, &mut cmsg_buffer, address.as_mut_ptr())
42371 - };
42372 -
42373 - let ret = unsafe { libc::recvmsg(fd, &mut mhdr, flags.bits()) };
42374 -
42375 -- Errno::result(ret).map(|r| {
42376 -- let cmsghdr = unsafe {
42377 -- if mhdr.msg_controllen > 0 {
42378 -- // got control message(s)
42379 -- debug_assert!(!mhdr.msg_control.is_null());
42380 -- debug_assert!(msg_controllen >= mhdr.msg_controllen as usize);
42381 -- CMSG_FIRSTHDR(&mhdr as *const msghdr)
42382 -- } else {
42383 -- ptr::null()
42384 -- }.as_ref()
42385 -- };
42386 -+ let r = Errno::result(ret)?;
42387 -
42388 -- let address = unsafe {
42389 -- sockaddr_storage_to_addr(&address, mhdr.msg_namelen as usize).ok()
42390 -- };
42391 -- RecvMsg {
42392 -- bytes: r as usize,
42393 -- cmsghdr,
42394 -- address,
42395 -- flags: MsgFlags::from_bits_truncate(mhdr.msg_flags),
42396 -- mhdr,
42397 -- }
42398 -- })
42399 -+ Ok(unsafe { read_mhdr(mhdr, r, msg_controllen, address.assume_init(), &mut cmsg_buffer) })
42400 - }
42401 -
42402 -
42403 -@@ -1071,12 +1521,15 @@ pub fn recv(sockfd: RawFd, buf: &mut [u8], flags: MsgFlags) -> Result<usize> {
42404 - }
42405 -
42406 - /// Receive data from a connectionless or connection-oriented socket. Returns
42407 --/// the number of bytes read and the socket address of the sender.
42408 -+/// the number of bytes read and, for connectionless sockets, the socket
42409 -+/// address of the sender.
42410 - ///
42411 - /// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html)
42412 --pub fn recvfrom(sockfd: RawFd, buf: &mut [u8]) -> Result<(usize, SockAddr)> {
42413 -+pub fn recvfrom(sockfd: RawFd, buf: &mut [u8])
42414 -+ -> Result<(usize, Option<SockAddr>)>
42415 -+{
42416 - unsafe {
42417 -- let addr: sockaddr_storage = mem::zeroed();
42418 -+ let mut addr: sockaddr_storage = mem::zeroed();
42419 - let mut len = mem::size_of::<sockaddr_storage>() as socklen_t;
42420 -
42421 - let ret = Errno::result(libc::recvfrom(
42422 -@@ -1084,11 +1537,14 @@ pub fn recvfrom(sockfd: RawFd, buf: &mut [u8]) -> Result<(usize, SockAddr)> {
42423 - buf.as_ptr() as *mut c_void,
42424 - buf.len() as size_t,
42425 - 0,
42426 -- mem::transmute(&addr),
42427 -- &mut len as *mut socklen_t))?;
42428 -+ &mut addr as *mut libc::sockaddr_storage as *mut libc::sockaddr,
42429 -+ &mut len as *mut socklen_t))? as usize;
42430 -
42431 -- sockaddr_storage_to_addr(&addr, len as usize)
42432 -- .map(|addr| (ret as usize, addr))
42433 -+ match sockaddr_storage_to_addr(&addr, len as usize) {
42434 -+ Err(Error::Sys(Errno::ENOTCONN)) => Ok((ret, None)),
42435 -+ Ok(addr) => Ok((ret, Some(addr))),
42436 -+ Err(e) => Err(e)
42437 -+ }
42438 - }
42439 - }
42440 -
42441 -@@ -1121,24 +1577,6 @@ pub fn send(fd: RawFd, buf: &[u8], flags: MsgFlags) -> Result<usize> {
42442 - *
42443 - */
42444 -
42445 --/// The protocol level at which to get / set socket options. Used as an
42446 --/// argument to `getsockopt` and `setsockopt`.
42447 --///
42448 --/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html)
42449 --#[repr(i32)]
42450 --#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
42451 --pub enum SockLevel {
42452 -- Socket = libc::SOL_SOCKET,
42453 -- Tcp = libc::IPPROTO_TCP,
42454 -- Ip = libc::IPPROTO_IP,
42455 -- Ipv6 = libc::IPPROTO_IPV6,
42456 -- Udp = libc::IPPROTO_UDP,
42457 -- #[cfg(any(target_os = "android", target_os = "linux"))]
42458 -- Netlink = libc::SOL_NETLINK,
42459 -- #[cfg(any(target_os = "android", target_os = "linux"))]
42460 -- Alg = libc::SOL_ALG,
42461 --}
42462 --
42463 - /// Represents a socket option that can be accessed or set. Used as an argument
42464 - /// to `getsockopt`
42465 - pub trait GetSockOpt : Copy {
42466 -@@ -1190,14 +1628,18 @@ pub fn setsockopt<O: SetSockOpt>(fd: RawFd, opt: O, val: &O::Val) -> Result<()>
42467 - /// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html)
42468 - pub fn getpeername(fd: RawFd) -> Result<SockAddr> {
42469 - unsafe {
42470 -- let addr: sockaddr_storage = mem::uninitialized();
42471 -+ let mut addr = mem::MaybeUninit::uninit();
42472 - let mut len = mem::size_of::<sockaddr_storage>() as socklen_t;
42473 -
42474 -- let ret = libc::getpeername(fd, mem::transmute(&addr), &mut len);
42475 -+ let ret = libc::getpeername(
42476 -+ fd,
42477 -+ addr.as_mut_ptr() as *mut libc::sockaddr,
42478 -+ &mut len
42479 -+ );
42480 -
42481 - Errno::result(ret)?;
42482 -
42483 -- sockaddr_storage_to_addr(&addr, len as usize)
42484 -+ sockaddr_storage_to_addr(&addr.assume_init(), len as usize)
42485 - }
42486 - }
42487 -
42488 -@@ -1206,60 +1648,92 @@ pub fn getpeername(fd: RawFd) -> Result<SockAddr> {
42489 - /// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html)
42490 - pub fn getsockname(fd: RawFd) -> Result<SockAddr> {
42491 - unsafe {
42492 -- let addr: sockaddr_storage = mem::uninitialized();
42493 -+ let mut addr = mem::MaybeUninit::uninit();
42494 - let mut len = mem::size_of::<sockaddr_storage>() as socklen_t;
42495 -
42496 -- let ret = libc::getsockname(fd, mem::transmute(&addr), &mut len);
42497 -+ let ret = libc::getsockname(
42498 -+ fd,
42499 -+ addr.as_mut_ptr() as *mut libc::sockaddr,
42500 -+ &mut len
42501 -+ );
42502 -
42503 - Errno::result(ret)?;
42504 -
42505 -- sockaddr_storage_to_addr(&addr, len as usize)
42506 -+ sockaddr_storage_to_addr(&addr.assume_init(), len as usize)
42507 - }
42508 - }
42509 -
42510 --/// Return the appropriate `SockAddr` type from a `sockaddr_storage` of a certain
42511 --/// size. In C this would usually be done by casting. The `len` argument
42512 -+/// Return the appropriate `SockAddr` type from a `sockaddr_storage` of a
42513 -+/// certain size.
42514 -+///
42515 -+/// In C this would usually be done by casting. The `len` argument
42516 - /// should be the number of bytes in the `sockaddr_storage` that are actually
42517 - /// allocated and valid. It must be at least as large as all the useful parts
42518 - /// of the structure. Note that in the case of a `sockaddr_un`, `len` need not
42519 - /// include the terminating null.
42520 --pub unsafe fn sockaddr_storage_to_addr(
42521 -+pub fn sockaddr_storage_to_addr(
42522 - addr: &sockaddr_storage,
42523 - len: usize) -> Result<SockAddr> {
42524 -
42525 -+ assert!(len <= mem::size_of::<sockaddr_un>());
42526 - if len < mem::size_of_val(&addr.ss_family) {
42527 - return Err(Error::Sys(Errno::ENOTCONN));
42528 - }
42529 -
42530 -- match addr.ss_family as c_int {
42531 -+ match c_int::from(addr.ss_family) {
42532 - libc::AF_INET => {
42533 -- assert!(len as usize == mem::size_of::<sockaddr_in>());
42534 -- let ret = *(addr as *const _ as *const sockaddr_in);
42535 -- Ok(SockAddr::Inet(InetAddr::V4(ret)))
42536 -+ assert_eq!(len as usize, mem::size_of::<sockaddr_in>());
42537 -+ let sin = unsafe {
42538 -+ *(addr as *const sockaddr_storage as *const sockaddr_in)
42539 -+ };
42540 -+ Ok(SockAddr::Inet(InetAddr::V4(sin)))
42541 - }
42542 - libc::AF_INET6 => {
42543 -- assert!(len as usize == mem::size_of::<sockaddr_in6>());
42544 -- Ok(SockAddr::Inet(InetAddr::V6(*(addr as *const _ as *const sockaddr_in6))))
42545 -+ assert_eq!(len as usize, mem::size_of::<sockaddr_in6>());
42546 -+ let sin6 = unsafe {
42547 -+ *(addr as *const _ as *const sockaddr_in6)
42548 -+ };
42549 -+ Ok(SockAddr::Inet(InetAddr::V6(sin6)))
42550 - }
42551 - libc::AF_UNIX => {
42552 -- let sun = *(addr as *const _ as *const sockaddr_un);
42553 - let pathlen = len - offset_of!(sockaddr_un, sun_path);
42554 -+ let sun = unsafe {
42555 -+ *(addr as *const _ as *const sockaddr_un)
42556 -+ };
42557 - Ok(SockAddr::Unix(UnixAddr(sun, pathlen)))
42558 - }
42559 - #[cfg(any(target_os = "android", target_os = "linux"))]
42560 -+ libc::AF_PACKET => {
42561 -+ use libc::sockaddr_ll;
42562 -+ assert_eq!(len as usize, mem::size_of::<sockaddr_ll>());
42563 -+ let sll = unsafe {
42564 -+ *(addr as *const _ as *const sockaddr_ll)
42565 -+ };
42566 -+ Ok(SockAddr::Link(LinkAddr(sll)))
42567 -+ }
42568 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
42569 - libc::AF_NETLINK => {
42570 - use libc::sockaddr_nl;
42571 -- Ok(SockAddr::Netlink(NetlinkAddr(*(addr as *const _ as *const sockaddr_nl))))
42572 -+ let snl = unsafe {
42573 -+ *(addr as *const _ as *const sockaddr_nl)
42574 -+ };
42575 -+ Ok(SockAddr::Netlink(NetlinkAddr(snl)))
42576 - }
42577 - #[cfg(any(target_os = "android", target_os = "linux"))]
42578 - libc::AF_ALG => {
42579 - use libc::sockaddr_alg;
42580 -- Ok(SockAddr::Alg(AlgAddr(*(addr as *const _ as *const sockaddr_alg))))
42581 -+ let salg = unsafe {
42582 -+ *(addr as *const _ as *const sockaddr_alg)
42583 -+ };
42584 -+ Ok(SockAddr::Alg(AlgAddr(salg)))
42585 - }
42586 -- #[cfg(target_os = "linux")]
42587 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
42588 - libc::AF_VSOCK => {
42589 - use libc::sockaddr_vm;
42590 -- Ok(SockAddr::Vsock(VsockAddr(*(addr as *const _ as *const sockaddr_vm))))
42591 -+ let svm = unsafe {
42592 -+ *(addr as *const _ as *const sockaddr_vm)
42593 -+ };
42594 -+ Ok(SockAddr::Vsock(VsockAddr(svm)))
42595 - }
42596 - af => panic!("unexpected address family {}", af),
42597 - }
42598 -diff --git a/third_party/rust/nix/src/sys/socket/sockopt.rs b/third_party/rust/nix/src/sys/socket/sockopt.rs
42599 -index a996010018d5b..5b7b4feafb49a 100644
42600 ---- a/third_party/rust/nix/src/sys/socket/sockopt.rs
42601 -+++ b/third_party/rust/nix/src/sys/socket/sockopt.rs
42602 -@@ -1,9 +1,13 @@
42603 -+use cfg_if::cfg_if;
42604 - use super::{GetSockOpt, SetSockOpt};
42605 --use Result;
42606 --use errno::Errno;
42607 --use sys::time::TimeVal;
42608 -+use crate::Result;
42609 -+use crate::errno::Errno;
42610 -+use crate::sys::time::TimeVal;
42611 - use libc::{self, c_int, c_void, socklen_t};
42612 --use std::mem;
42613 -+use std::mem::{
42614 -+ self,
42615 -+ MaybeUninit
42616 -+};
42617 - use std::os::unix::io::RawFd;
42618 - use std::ffi::{OsStr, OsString};
42619 - #[cfg(target_family = "unix")]
42620 -@@ -84,14 +88,14 @@ macro_rules! getsockopt_impl {
42621 -
42622 - fn get(&self, fd: RawFd) -> Result<$ty> {
42623 - unsafe {
42624 -- let mut getter: $getter = Get::blank();
42625 -+ let mut getter: $getter = Get::uninit();
42626 -
42627 - let res = libc::getsockopt(fd, $level, $flag,
42628 - getter.ffi_ptr(),
42629 - getter.ffi_len());
42630 - Errno::result(res)?;
42631 -
42632 -- Ok(getter.unwrap())
42633 -+ Ok(getter.assume_init())
42634 - }
42635 - }
42636 - }
42637 -@@ -248,6 +252,10 @@ sockopt_impl!(Both, TcpKeepAlive, libc::IPPROTO_TCP, libc::TCP_KEEPALIVE, u32);
42638 - target_os = "linux",
42639 - target_os = "nacl"))]
42640 - sockopt_impl!(Both, TcpKeepIdle, libc::IPPROTO_TCP, libc::TCP_KEEPIDLE, u32);
42641 -+#[cfg(not(target_os = "openbsd"))]
42642 -+sockopt_impl!(Both, TcpKeepCount, libc::IPPROTO_TCP, libc::TCP_KEEPCNT, u32);
42643 -+#[cfg(not(target_os = "openbsd"))]
42644 -+sockopt_impl!(Both, TcpKeepInterval, libc::IPPROTO_TCP, libc::TCP_KEEPINTVL, u32);
42645 - sockopt_impl!(Both, RcvBuf, libc::SOL_SOCKET, libc::SO_RCVBUF, usize);
42646 - sockopt_impl!(Both, SndBuf, libc::SOL_SOCKET, libc::SO_SNDBUF, usize);
42647 - #[cfg(any(target_os = "android", target_os = "linux"))]
42648 -@@ -257,6 +265,8 @@ sockopt_impl!(SetOnly, SndBufForce, libc::SOL_SOCKET, libc::SO_SNDBUFFORCE, usiz
42649 - sockopt_impl!(GetOnly, SockType, libc::SOL_SOCKET, libc::SO_TYPE, super::SockType);
42650 - sockopt_impl!(GetOnly, AcceptConn, libc::SOL_SOCKET, libc::SO_ACCEPTCONN, bool);
42651 - #[cfg(any(target_os = "android", target_os = "linux"))]
42652 -+sockopt_impl!(Both, BindToDevice, libc::SOL_SOCKET, libc::SO_BINDTODEVICE, OsString<[u8; libc::IFNAMSIZ]>);
42653 -+#[cfg(any(target_os = "android", target_os = "linux"))]
42654 - sockopt_impl!(GetOnly, OriginalDst, libc::SOL_IP, libc::SO_ORIGINAL_DST, libc::sockaddr_in);
42655 - sockopt_impl!(Both, ReceiveTimestamp, libc::SOL_SOCKET, libc::SO_TIMESTAMP, bool);
42656 - #[cfg(any(target_os = "android", target_os = "linux"))]
42657 -@@ -305,7 +315,10 @@ sockopt_impl!(Both, Ipv4RecvIf, libc::IPPROTO_IP, libc::IP_RECVIF, bool);
42658 - target_os = "openbsd",
42659 - ))]
42660 - sockopt_impl!(Both, Ipv4RecvDstAddr, libc::IPPROTO_IP, libc::IP_RECVDSTADDR, bool);
42661 --
42662 -+#[cfg(target_os = "linux")]
42663 -+sockopt_impl!(Both, UdpGsoSegment, libc::SOL_UDP, libc::UDP_SEGMENT, libc::c_int);
42664 -+#[cfg(target_os = "linux")]
42665 -+sockopt_impl!(Both, UdpGroSegment, libc::IPPROTO_UDP, libc::UDP_GRO, bool);
42666 -
42667 - #[cfg(any(target_os = "android", target_os = "linux"))]
42668 - #[derive(Copy, Clone, Debug)]
42669 -@@ -364,16 +377,16 @@ impl<T> SetSockOpt for AlgSetKey<T> where T: AsRef<[u8]> + Clone {
42670 -
42671 - /// Helper trait that describes what is expected from a `GetSockOpt` getter.
42672 - unsafe trait Get<T> {
42673 -- /// Returns an empty value.
42674 -- unsafe fn blank() -> Self;
42675 -+ /// Returns an uninitialized value.
42676 -+ unsafe fn uninit() -> Self;
42677 - /// Returns a pointer to the stored value. This pointer will be passed to the system's
42678 - /// `getsockopt` call (`man 3p getsockopt`, argument `option_value`).
42679 - fn ffi_ptr(&mut self) -> *mut c_void;
42680 - /// Returns length of the stored value. This pointer will be passed to the system's
42681 - /// `getsockopt` call (`man 3p getsockopt`, argument `option_len`).
42682 - fn ffi_len(&mut self) -> *mut socklen_t;
42683 -- /// Returns the stored value.
42684 -- unsafe fn unwrap(self) -> T;
42685 -+ /// Returns the hopefully initialized inner value.
42686 -+ unsafe fn assume_init(self) -> T;
42687 - }
42688 -
42689 - /// Helper trait that describes what is expected from a `SetSockOpt` setter.
42690 -@@ -391,28 +404,28 @@ unsafe trait Set<'a, T> {
42691 - /// Getter for an arbitrary `struct`.
42692 - struct GetStruct<T> {
42693 - len: socklen_t,
42694 -- val: T,
42695 -+ val: MaybeUninit<T>,
42696 - }
42697 -
42698 - unsafe impl<T> Get<T> for GetStruct<T> {
42699 -- unsafe fn blank() -> Self {
42700 -+ unsafe fn uninit() -> Self {
42701 - GetStruct {
42702 - len: mem::size_of::<T>() as socklen_t,
42703 -- val: mem::zeroed(),
42704 -+ val: MaybeUninit::uninit(),
42705 - }
42706 - }
42707 -
42708 - fn ffi_ptr(&mut self) -> *mut c_void {
42709 -- &mut self.val as *mut T as *mut c_void
42710 -+ self.val.as_mut_ptr() as *mut c_void
42711 - }
42712 -
42713 - fn ffi_len(&mut self) -> *mut socklen_t {
42714 - &mut self.len
42715 - }
42716 -
42717 -- unsafe fn unwrap(self) -> T {
42718 -- assert!(self.len as usize == mem::size_of::<T>(), "invalid getsockopt implementation");
42719 -- self.val
42720 -+ unsafe fn assume_init(self) -> T {
42721 -+ assert_eq!(self.len as usize, mem::size_of::<T>(), "invalid getsockopt implementation");
42722 -+ self.val.assume_init()
42723 - }
42724 - }
42725 -
42726 -@@ -423,7 +436,7 @@ struct SetStruct<'a, T: 'static> {
42727 -
42728 - unsafe impl<'a, T> Set<'a, T> for SetStruct<'a, T> {
42729 - fn new(ptr: &'a T) -> SetStruct<'a, T> {
42730 -- SetStruct { ptr: ptr }
42731 -+ SetStruct { ptr }
42732 - }
42733 -
42734 - fn ffi_ptr(&self) -> *const c_void {
42735 -@@ -438,28 +451,28 @@ unsafe impl<'a, T> Set<'a, T> for SetStruct<'a, T> {
42736 - /// Getter for a boolean value.
42737 - struct GetBool {
42738 - len: socklen_t,
42739 -- val: c_int,
42740 -+ val: MaybeUninit<c_int>,
42741 - }
42742 -
42743 - unsafe impl Get<bool> for GetBool {
42744 -- unsafe fn blank() -> Self {
42745 -+ unsafe fn uninit() -> Self {
42746 - GetBool {
42747 - len: mem::size_of::<c_int>() as socklen_t,
42748 -- val: mem::zeroed(),
42749 -+ val: MaybeUninit::uninit(),
42750 - }
42751 - }
42752 -
42753 - fn ffi_ptr(&mut self) -> *mut c_void {
42754 -- &mut self.val as *mut c_int as *mut c_void
42755 -+ self.val.as_mut_ptr() as *mut c_void
42756 - }
42757 -
42758 - fn ffi_len(&mut self) -> *mut socklen_t {
42759 - &mut self.len
42760 - }
42761 -
42762 -- unsafe fn unwrap(self) -> bool {
42763 -- assert!(self.len as usize == mem::size_of::<c_int>(), "invalid getsockopt implementation");
42764 -- self.val != 0
42765 -+ unsafe fn assume_init(self) -> bool {
42766 -+ assert_eq!(self.len as usize, mem::size_of::<c_int>(), "invalid getsockopt implementation");
42767 -+ self.val.assume_init() != 0
42768 - }
42769 - }
42770 -
42771 -@@ -485,28 +498,28 @@ unsafe impl<'a> Set<'a, bool> for SetBool {
42772 - /// Getter for an `u8` value.
42773 - struct GetU8 {
42774 - len: socklen_t,
42775 -- val: u8,
42776 -+ val: MaybeUninit<u8>,
42777 - }
42778 -
42779 - unsafe impl Get<u8> for GetU8 {
42780 -- unsafe fn blank() -> Self {
42781 -+ unsafe fn uninit() -> Self {
42782 - GetU8 {
42783 - len: mem::size_of::<u8>() as socklen_t,
42784 -- val: mem::zeroed(),
42785 -+ val: MaybeUninit::uninit(),
42786 - }
42787 - }
42788 -
42789 - fn ffi_ptr(&mut self) -> *mut c_void {
42790 -- &mut self.val as *mut u8 as *mut c_void
42791 -+ self.val.as_mut_ptr() as *mut c_void
42792 - }
42793 -
42794 - fn ffi_len(&mut self) -> *mut socklen_t {
42795 - &mut self.len
42796 - }
42797 -
42798 -- unsafe fn unwrap(self) -> u8 {
42799 -- assert!(self.len as usize == mem::size_of::<u8>(), "invalid getsockopt implementation");
42800 -- self.val as u8
42801 -+ unsafe fn assume_init(self) -> u8 {
42802 -+ assert_eq!(self.len as usize, mem::size_of::<u8>(), "invalid getsockopt implementation");
42803 -+ self.val.assume_init()
42804 - }
42805 - }
42806 -
42807 -@@ -532,28 +545,28 @@ unsafe impl<'a> Set<'a, u8> for SetU8 {
42808 - /// Getter for an `usize` value.
42809 - struct GetUsize {
42810 - len: socklen_t,
42811 -- val: c_int,
42812 -+ val: MaybeUninit<c_int>,
42813 - }
42814 -
42815 - unsafe impl Get<usize> for GetUsize {
42816 -- unsafe fn blank() -> Self {
42817 -+ unsafe fn uninit() -> Self {
42818 - GetUsize {
42819 - len: mem::size_of::<c_int>() as socklen_t,
42820 -- val: mem::zeroed(),
42821 -+ val: MaybeUninit::uninit(),
42822 - }
42823 - }
42824 -
42825 - fn ffi_ptr(&mut self) -> *mut c_void {
42826 -- &mut self.val as *mut c_int as *mut c_void
42827 -+ self.val.as_mut_ptr() as *mut c_void
42828 - }
42829 -
42830 - fn ffi_len(&mut self) -> *mut socklen_t {
42831 - &mut self.len
42832 - }
42833 -
42834 -- unsafe fn unwrap(self) -> usize {
42835 -- assert!(self.len as usize == mem::size_of::<c_int>(), "invalid getsockopt implementation");
42836 -- self.val as usize
42837 -+ unsafe fn assume_init(self) -> usize {
42838 -+ assert_eq!(self.len as usize, mem::size_of::<c_int>(), "invalid getsockopt implementation");
42839 -+ self.val.assume_init() as usize
42840 - }
42841 - }
42842 -
42843 -@@ -579,27 +592,29 @@ unsafe impl<'a> Set<'a, usize> for SetUsize {
42844 - /// Getter for a `OsString` value.
42845 - struct GetOsString<T: AsMut<[u8]>> {
42846 - len: socklen_t,
42847 -- val: T,
42848 -+ val: MaybeUninit<T>,
42849 - }
42850 -
42851 - unsafe impl<T: AsMut<[u8]>> Get<OsString> for GetOsString<T> {
42852 -- unsafe fn blank() -> Self {
42853 -+ unsafe fn uninit() -> Self {
42854 - GetOsString {
42855 - len: mem::size_of::<T>() as socklen_t,
42856 -- val: mem::zeroed(),
42857 -+ val: MaybeUninit::uninit(),
42858 - }
42859 - }
42860 -
42861 - fn ffi_ptr(&mut self) -> *mut c_void {
42862 -- &mut self.val as *mut T as *mut c_void
42863 -+ self.val.as_mut_ptr() as *mut c_void
42864 - }
42865 -
42866 - fn ffi_len(&mut self) -> *mut socklen_t {
42867 - &mut self.len
42868 - }
42869 -
42870 -- unsafe fn unwrap(mut self) -> OsString {
42871 -- OsStr::from_bytes(self.val.as_mut()).to_owned()
42872 -+ unsafe fn assume_init(self) -> OsString {
42873 -+ let len = self.len as usize;
42874 -+ let mut v = self.val.assume_init();
42875 -+ OsStr::from_bytes(&v.as_mut()[0..len]).to_owned()
42876 - }
42877 - }
42878 -
42879 -@@ -640,11 +655,11 @@ mod test {
42880 - #[test]
42881 - fn is_socket_type_unix() {
42882 - use super::super::*;
42883 -- use ::unistd::close;
42884 -+ use crate::unistd::close;
42885 -
42886 - let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap();
42887 - let a_type = getsockopt(a, super::SockType).unwrap();
42888 -- assert!(a_type == SockType::Stream);
42889 -+ assert_eq!(a_type, SockType::Stream);
42890 - close(a).unwrap();
42891 - close(b).unwrap();
42892 - }
42893 -@@ -652,11 +667,11 @@ mod test {
42894 - #[test]
42895 - fn is_socket_type_dgram() {
42896 - use super::super::*;
42897 -- use ::unistd::close;
42898 -+ use crate::unistd::close;
42899 -
42900 - let s = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), None).unwrap();
42901 - let s_type = getsockopt(s, super::SockType).unwrap();
42902 -- assert!(s_type == SockType::Datagram);
42903 -+ assert_eq!(s_type, SockType::Datagram);
42904 - close(s).unwrap();
42905 - }
42906 -
42907 -@@ -666,7 +681,7 @@ mod test {
42908 - #[test]
42909 - fn can_get_listen_on_tcp_socket() {
42910 - use super::super::*;
42911 -- use ::unistd::close;
42912 -+ use crate::unistd::close;
42913 -
42914 - let s = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), None).unwrap();
42915 - let s_listening = getsockopt(s, super::AcceptConn).unwrap();
42916 -diff --git a/third_party/rust/nix/src/sys/stat.rs b/third_party/rust/nix/src/sys/stat.rs
42917 -index 66c8c9dd1b720..df81a2cb329d6 100644
42918 ---- a/third_party/rust/nix/src/sys/stat.rs
42919 -+++ b/third_party/rust/nix/src/sys/stat.rs
42920 -@@ -1,13 +1,12 @@
42921 - pub use libc::{dev_t, mode_t};
42922 - pub use libc::stat as FileStat;
42923 -
42924 --use {Result, NixPath};
42925 --use errno::Errno;
42926 --use fcntl::{AtFlags, at_rawfd};
42927 --use libc;
42928 -+use crate::{Result, NixPath, errno::Errno};
42929 -+#[cfg(not(target_os = "redox"))]
42930 -+use crate::fcntl::{AtFlags, at_rawfd};
42931 - use std::mem;
42932 - use std::os::unix::io::RawFd;
42933 --use sys::time::{TimeSpec, TimeVal};
42934 -+use crate::sys::time::{TimeSpec, TimeVal};
42935 -
42936 - libc_bitflags!(
42937 - pub struct SFlag: mode_t {
42938 -@@ -78,49 +77,50 @@ pub fn umask(mode: Mode) -> Mode {
42939 - }
42940 -
42941 - pub fn stat<P: ?Sized + NixPath>(path: &P) -> Result<FileStat> {
42942 -- let mut dst = unsafe { mem::uninitialized() };
42943 -+ let mut dst = mem::MaybeUninit::uninit();
42944 - let res = path.with_nix_path(|cstr| {
42945 - unsafe {
42946 -- libc::stat(cstr.as_ptr(), &mut dst as *mut FileStat)
42947 -+ libc::stat(cstr.as_ptr(), dst.as_mut_ptr())
42948 - }
42949 - })?;
42950 -
42951 - Errno::result(res)?;
42952 -
42953 -- Ok(dst)
42954 -+ Ok(unsafe{dst.assume_init()})
42955 - }
42956 -
42957 - pub fn lstat<P: ?Sized + NixPath>(path: &P) -> Result<FileStat> {
42958 -- let mut dst = unsafe { mem::uninitialized() };
42959 -+ let mut dst = mem::MaybeUninit::uninit();
42960 - let res = path.with_nix_path(|cstr| {
42961 - unsafe {
42962 -- libc::lstat(cstr.as_ptr(), &mut dst as *mut FileStat)
42963 -+ libc::lstat(cstr.as_ptr(), dst.as_mut_ptr())
42964 - }
42965 - })?;
42966 -
42967 - Errno::result(res)?;
42968 -
42969 -- Ok(dst)
42970 -+ Ok(unsafe{dst.assume_init()})
42971 - }
42972 -
42973 - pub fn fstat(fd: RawFd) -> Result<FileStat> {
42974 -- let mut dst = unsafe { mem::uninitialized() };
42975 -- let res = unsafe { libc::fstat(fd, &mut dst as *mut FileStat) };
42976 -+ let mut dst = mem::MaybeUninit::uninit();
42977 -+ let res = unsafe { libc::fstat(fd, dst.as_mut_ptr()) };
42978 -
42979 - Errno::result(res)?;
42980 -
42981 -- Ok(dst)
42982 -+ Ok(unsafe{dst.assume_init()})
42983 - }
42984 -
42985 -+#[cfg(not(target_os = "redox"))]
42986 - pub fn fstatat<P: ?Sized + NixPath>(dirfd: RawFd, pathname: &P, f: AtFlags) -> Result<FileStat> {
42987 -- let mut dst = unsafe { mem::uninitialized() };
42988 -+ let mut dst = mem::MaybeUninit::uninit();
42989 - let res = pathname.with_nix_path(|cstr| {
42990 -- unsafe { libc::fstatat(dirfd, cstr.as_ptr(), &mut dst as *mut FileStat, f.bits() as libc::c_int) }
42991 -+ unsafe { libc::fstatat(dirfd, cstr.as_ptr(), dst.as_mut_ptr(), f.bits() as libc::c_int) }
42992 - })?;
42993 -
42994 - Errno::result(res)?;
42995 -
42996 -- Ok(dst)
42997 -+ Ok(unsafe{dst.assume_init()})
42998 - }
42999 -
43000 - /// Change the file permission bits of the file specified by a file descriptor.
43001 -@@ -150,13 +150,14 @@ pub enum FchmodatFlags {
43002 - /// If `flag` is `FchmodatFlags::NoFollowSymlink` and `path` names a symbolic link,
43003 - /// then the mode of the symbolic link is changed.
43004 - ///
43005 --/// `fchmod(None, path, mode, FchmodatFlags::FollowSymlink)` is identical to
43006 -+/// `fchmodat(None, path, mode, FchmodatFlags::FollowSymlink)` is identical to
43007 - /// a call `libc::chmod(path, mode)`. That's why `chmod` is unimplemented
43008 - /// in the `nix` crate.
43009 - ///
43010 - /// # References
43011 - ///
43012 - /// [fchmodat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmodat.html).
43013 -+#[cfg(not(target_os = "redox"))]
43014 - pub fn fchmodat<P: ?Sized + NixPath>(
43015 - dirfd: Option<RawFd>,
43016 - path: &P,
43017 -@@ -260,6 +261,7 @@ pub enum UtimensatFlags {
43018 - /// # References
43019 - ///
43020 - /// [utimensat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/utimens.html).
43021 -+#[cfg(not(target_os = "redox"))]
43022 - pub fn utimensat<P: ?Sized + NixPath>(
43023 - dirfd: Option<RawFd>,
43024 - path: &P,
43025 -@@ -285,6 +287,7 @@ pub fn utimensat<P: ?Sized + NixPath>(
43026 - Errno::result(res).map(drop)
43027 - }
43028 -
43029 -+#[cfg(not(target_os = "redox"))]
43030 - pub fn mkdirat<P: ?Sized + NixPath>(fd: RawFd, path: &P, mode: Mode) -> Result<()> {
43031 - let res = path.with_nix_path(|cstr| {
43032 - unsafe { libc::mkdirat(fd, cstr.as_ptr(), mode.bits() as mode_t) }
43033 -diff --git a/third_party/rust/nix/src/sys/statfs.rs b/third_party/rust/nix/src/sys/statfs.rs
43034 -index d4596bf336958..27b72592b9a30 100644
43035 ---- a/third_party/rust/nix/src/sys/statfs.rs
43036 -+++ b/third_party/rust/nix/src/sys/statfs.rs
43037 -@@ -4,10 +4,7 @@ use std::os::unix::io::AsRawFd;
43038 - #[cfg(not(any(target_os = "linux", target_os = "android")))]
43039 - use std::ffi::CStr;
43040 -
43041 --use libc;
43042 --
43043 --use {NixPath, Result};
43044 --use errno::Errno;
43045 -+use crate::{NixPath, Result, errno::Errno};
43046 -
43047 - #[cfg(target_os = "android")]
43048 - pub type fsid_t = libc::__fsid_t;
43049 -@@ -15,81 +12,95 @@ pub type fsid_t = libc::__fsid_t;
43050 - pub type fsid_t = libc::fsid_t;
43051 -
43052 - #[derive(Clone, Copy)]
43053 -+#[repr(transparent)]
43054 - pub struct Statfs(libc::statfs);
43055 -
43056 - #[cfg(target_os = "freebsd")]
43057 --#[derive(Eq, Copy, Clone, PartialEq, Debug)]
43058 --pub struct FsType(u32);
43059 -+type fs_type_t = u32;
43060 - #[cfg(target_os = "android")]
43061 --#[derive(Eq, Copy, Clone, PartialEq, Debug)]
43062 --pub struct FsType(libc::c_ulong);
43063 -+type fs_type_t = libc::c_ulong;
43064 - #[cfg(all(target_os = "linux", target_arch = "s390x"))]
43065 --#[derive(Eq, Copy, Clone, PartialEq, Debug)]
43066 --pub struct FsType(u32);
43067 -+type fs_type_t = libc::c_uint;
43068 - #[cfg(all(target_os = "linux", target_env = "musl"))]
43069 --#[derive(Eq, Copy, Clone, PartialEq, Debug)]
43070 --pub struct FsType(libc::c_ulong);
43071 -+type fs_type_t = libc::c_ulong;
43072 - #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
43073 -+type fs_type_t = libc::__fsword_t;
43074 -+
43075 -+#[cfg(any(
43076 -+ target_os = "freebsd",
43077 -+ target_os = "android",
43078 -+ all(target_os = "linux", target_arch = "s390x"),
43079 -+ all(target_os = "linux", target_env = "musl"),
43080 -+ all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))),
43081 -+))]
43082 - #[derive(Eq, Copy, Clone, PartialEq, Debug)]
43083 --pub struct FsType(libc::c_long);
43084 --
43085 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43086 --pub const ADFS_SUPER_MAGIC: FsType = FsType(libc::ADFS_SUPER_MAGIC);
43087 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43088 --pub const AFFS_SUPER_MAGIC: FsType = FsType(libc::AFFS_SUPER_MAGIC);
43089 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43090 --pub const CODA_SUPER_MAGIC: FsType = FsType(libc::CODA_SUPER_MAGIC);
43091 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43092 --pub const CRAMFS_MAGIC: FsType = FsType(libc::CRAMFS_MAGIC);
43093 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43094 --pub const EFS_SUPER_MAGIC: FsType = FsType(libc::EFS_SUPER_MAGIC);
43095 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43096 --pub const EXT2_SUPER_MAGIC: FsType = FsType(libc::EXT2_SUPER_MAGIC);
43097 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43098 --pub const EXT3_SUPER_MAGIC: FsType = FsType(libc::EXT3_SUPER_MAGIC);
43099 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43100 --pub const EXT4_SUPER_MAGIC: FsType = FsType(libc::EXT4_SUPER_MAGIC);
43101 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43102 --pub const HPFS_SUPER_MAGIC: FsType = FsType(libc::HPFS_SUPER_MAGIC);
43103 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43104 --pub const HUGETLBFS_MAGIC: FsType = FsType(libc::HUGETLBFS_MAGIC);
43105 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43106 --pub const ISOFS_SUPER_MAGIC: FsType = FsType(libc::ISOFS_SUPER_MAGIC);
43107 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43108 --pub const JFFS2_SUPER_MAGIC: FsType = FsType(libc::JFFS2_SUPER_MAGIC);
43109 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43110 --pub const MINIX_SUPER_MAGIC: FsType = FsType(libc::MINIX_SUPER_MAGIC);
43111 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43112 --pub const MINIX_SUPER_MAGIC2: FsType = FsType(libc::MINIX_SUPER_MAGIC2);
43113 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43114 --pub const MINIX2_SUPER_MAGIC: FsType = FsType(libc::MINIX2_SUPER_MAGIC);
43115 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43116 --pub const MINIX2_SUPER_MAGIC2: FsType = FsType(libc::MINIX2_SUPER_MAGIC2);
43117 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43118 --pub const MSDOS_SUPER_MAGIC: FsType = FsType(libc::MSDOS_SUPER_MAGIC);
43119 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43120 --pub const NCP_SUPER_MAGIC: FsType = FsType(libc::NCP_SUPER_MAGIC);
43121 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43122 --pub const NFS_SUPER_MAGIC: FsType = FsType(libc::NFS_SUPER_MAGIC);
43123 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43124 --pub const OPENPROM_SUPER_MAGIC: FsType = FsType(libc::OPENPROM_SUPER_MAGIC);
43125 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43126 --pub const PROC_SUPER_MAGIC: FsType = FsType(libc::PROC_SUPER_MAGIC);
43127 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43128 --pub const QNX4_SUPER_MAGIC: FsType = FsType(libc::QNX4_SUPER_MAGIC);
43129 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43130 --pub const REISERFS_SUPER_MAGIC: FsType = FsType(libc::REISERFS_SUPER_MAGIC);
43131 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43132 --pub const SMB_SUPER_MAGIC: FsType = FsType(libc::SMB_SUPER_MAGIC);
43133 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43134 --pub const TMPFS_MAGIC: FsType = FsType(libc::TMPFS_MAGIC);
43135 --#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))]
43136 --pub const USBDEVICE_SUPER_MAGIC: FsType = FsType(libc::USBDEVICE_SUPER_MAGIC);
43137 -+pub struct FsType(pub fs_type_t);
43138 -+
43139 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43140 -+pub const ADFS_SUPER_MAGIC: FsType = FsType(libc::ADFS_SUPER_MAGIC as fs_type_t);
43141 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43142 -+pub const AFFS_SUPER_MAGIC: FsType = FsType(libc::AFFS_SUPER_MAGIC as fs_type_t);
43143 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43144 -+pub const CODA_SUPER_MAGIC: FsType = FsType(libc::CODA_SUPER_MAGIC as fs_type_t);
43145 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43146 -+pub const CRAMFS_MAGIC: FsType = FsType(libc::CRAMFS_MAGIC as fs_type_t);
43147 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43148 -+pub const EFS_SUPER_MAGIC: FsType = FsType(libc::EFS_SUPER_MAGIC as fs_type_t);
43149 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43150 -+pub const EXT2_SUPER_MAGIC: FsType = FsType(libc::EXT2_SUPER_MAGIC as fs_type_t);
43151 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43152 -+pub const EXT3_SUPER_MAGIC: FsType = FsType(libc::EXT3_SUPER_MAGIC as fs_type_t);
43153 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43154 -+pub const EXT4_SUPER_MAGIC: FsType = FsType(libc::EXT4_SUPER_MAGIC as fs_type_t);
43155 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43156 -+pub const HPFS_SUPER_MAGIC: FsType = FsType(libc::HPFS_SUPER_MAGIC as fs_type_t);
43157 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43158 -+pub const HUGETLBFS_MAGIC: FsType = FsType(libc::HUGETLBFS_MAGIC as fs_type_t);
43159 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43160 -+pub const ISOFS_SUPER_MAGIC: FsType = FsType(libc::ISOFS_SUPER_MAGIC as fs_type_t);
43161 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43162 -+pub const JFFS2_SUPER_MAGIC: FsType = FsType(libc::JFFS2_SUPER_MAGIC as fs_type_t);
43163 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43164 -+pub const MINIX_SUPER_MAGIC: FsType = FsType(libc::MINIX_SUPER_MAGIC as fs_type_t);
43165 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43166 -+pub const MINIX_SUPER_MAGIC2: FsType = FsType(libc::MINIX_SUPER_MAGIC2 as fs_type_t);
43167 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43168 -+pub const MINIX2_SUPER_MAGIC: FsType = FsType(libc::MINIX2_SUPER_MAGIC as fs_type_t);
43169 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43170 -+pub const MINIX2_SUPER_MAGIC2: FsType = FsType(libc::MINIX2_SUPER_MAGIC2 as fs_type_t);
43171 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43172 -+pub const MSDOS_SUPER_MAGIC: FsType = FsType(libc::MSDOS_SUPER_MAGIC as fs_type_t);
43173 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43174 -+pub const NCP_SUPER_MAGIC: FsType = FsType(libc::NCP_SUPER_MAGIC as fs_type_t);
43175 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43176 -+pub const NFS_SUPER_MAGIC: FsType = FsType(libc::NFS_SUPER_MAGIC as fs_type_t);
43177 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43178 -+pub const OPENPROM_SUPER_MAGIC: FsType = FsType(libc::OPENPROM_SUPER_MAGIC as fs_type_t);
43179 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43180 -+pub const OVERLAYFS_SUPER_MAGIC: FsType = FsType(libc::OVERLAYFS_SUPER_MAGIC as fs_type_t);
43181 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43182 -+pub const PROC_SUPER_MAGIC: FsType = FsType(libc::PROC_SUPER_MAGIC as fs_type_t);
43183 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43184 -+pub const QNX4_SUPER_MAGIC: FsType = FsType(libc::QNX4_SUPER_MAGIC as fs_type_t);
43185 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43186 -+pub const REISERFS_SUPER_MAGIC: FsType = FsType(libc::REISERFS_SUPER_MAGIC as fs_type_t);
43187 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43188 -+pub const SMB_SUPER_MAGIC: FsType = FsType(libc::SMB_SUPER_MAGIC as fs_type_t);
43189 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43190 -+pub const TMPFS_MAGIC: FsType = FsType(libc::TMPFS_MAGIC as fs_type_t);
43191 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43192 -+pub const USBDEVICE_SUPER_MAGIC: FsType = FsType(libc::USBDEVICE_SUPER_MAGIC as fs_type_t);
43193 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43194 -+pub const CGROUP_SUPER_MAGIC: FsType = FsType(libc::CGROUP_SUPER_MAGIC as fs_type_t);
43195 -+#[cfg(all(target_os = "linux", not(target_env = "musl")))]
43196 -+pub const CGROUP2_SUPER_MAGIC: FsType = FsType(libc::CGROUP2_SUPER_MAGIC as fs_type_t);
43197 -+
43198 -
43199 - impl Statfs {
43200 - /// Magic code defining system type
43201 - #[cfg(not(any(
43202 - target_os = "openbsd",
43203 -+ target_os = "dragonfly",
43204 - target_os = "ios",
43205 - target_os = "macos"
43206 - )))]
43207 -@@ -105,32 +116,35 @@ impl Statfs {
43208 - }
43209 -
43210 - /// Optimal transfer block size
43211 -- #[cfg(any(target_os = "ios", target_os = "macos", target_os = "openbsd"))]
43212 -+ #[cfg(any(target_os = "ios", target_os = "macos"))]
43213 - pub fn optimal_transfer_size(&self) -> i32 {
43214 - self.0.f_iosize
43215 - }
43216 -
43217 - /// Optimal transfer block size
43218 -- #[cfg(all(target_os = "linux", target_arch = "s390x"))]
43219 -+ #[cfg(target_os = "openbsd")]
43220 - pub fn optimal_transfer_size(&self) -> u32 {
43221 -- self.0.f_bsize
43222 -+ self.0.f_iosize
43223 - }
43224 -
43225 - /// Optimal transfer block size
43226 -- #[cfg(all(target_os = "linux", target_env = "musl"))]
43227 -- pub fn optimal_transfer_size(&self) -> libc::c_ulong {
43228 -+ #[cfg(all(target_os = "linux", target_arch = "s390x"))]
43229 -+ pub fn optimal_transfer_size(&self) -> u32 {
43230 - self.0.f_bsize
43231 - }
43232 -
43233 - /// Optimal transfer block size
43234 -- #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
43235 -- pub fn optimal_transfer_size(&self) -> libc::c_long {
43236 -+ #[cfg(any(
43237 -+ target_os = "android",
43238 -+ all(target_os = "linux", target_env = "musl")
43239 -+ ))]
43240 -+ pub fn optimal_transfer_size(&self) -> libc::c_ulong {
43241 - self.0.f_bsize
43242 - }
43243 -
43244 - /// Optimal transfer block size
43245 -- #[cfg(target_os = "android")]
43246 -- pub fn optimal_transfer_size(&self) -> libc::c_ulong {
43247 -+ #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
43248 -+ pub fn optimal_transfer_size(&self) -> libc::__fsword_t {
43249 - self.0.f_bsize
43250 - }
43251 -
43252 -@@ -169,7 +183,7 @@ impl Statfs {
43253 - /// Size of a block
43254 - // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
43255 - #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
43256 -- pub fn block_size(&self) -> libc::c_long {
43257 -+ pub fn block_size(&self) -> libc::__fsword_t {
43258 - self.0.f_bsize
43259 - }
43260 -
43261 -@@ -211,7 +225,7 @@ impl Statfs {
43262 -
43263 - /// Maximum length of filenames
43264 - #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
43265 -- pub fn maximum_name_length(&self) -> libc::c_long {
43266 -+ pub fn maximum_name_length(&self) -> libc::__fsword_t {
43267 - self.0.f_namelen
43268 - }
43269 -
43270 -@@ -240,7 +254,7 @@ impl Statfs {
43271 - }
43272 -
43273 - /// Total data blocks in filesystem
43274 -- #[cfg(all(target_os = "linux", target_env = "musl"))]
43275 -+ #[cfg(all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32"))))]
43276 - pub fn blocks(&self) -> u64 {
43277 - self.0.f_blocks
43278 - }
43279 -@@ -253,7 +267,7 @@ impl Statfs {
43280 - target_os = "freebsd",
43281 - target_os = "openbsd",
43282 - target_os = "dragonfly",
43283 -- all(target_os = "linux", target_env = "musl")
43284 -+ all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32")))
43285 - )))]
43286 - pub fn blocks(&self) -> libc::c_ulong {
43287 - self.0.f_blocks
43288 -@@ -278,7 +292,7 @@ impl Statfs {
43289 - }
43290 -
43291 - /// Free blocks in filesystem
43292 -- #[cfg(all(target_os = "linux", target_env = "musl"))]
43293 -+ #[cfg(all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32"))))]
43294 - pub fn blocks_free(&self) -> u64 {
43295 - self.0.f_bfree
43296 - }
43297 -@@ -291,7 +305,7 @@ impl Statfs {
43298 - target_os = "freebsd",
43299 - target_os = "openbsd",
43300 - target_os = "dragonfly",
43301 -- all(target_os = "linux", target_env = "musl")
43302 -+ all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32")))
43303 - )))]
43304 - pub fn blocks_free(&self) -> libc::c_ulong {
43305 - self.0.f_bfree
43306 -@@ -316,7 +330,7 @@ impl Statfs {
43307 - }
43308 -
43309 - /// Free blocks available to unprivileged user
43310 -- #[cfg(all(target_os = "linux", target_env = "musl"))]
43311 -+ #[cfg(all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32"))))]
43312 - pub fn blocks_available(&self) -> u64 {
43313 - self.0.f_bavail
43314 - }
43315 -@@ -329,7 +343,7 @@ impl Statfs {
43316 - target_os = "freebsd",
43317 - target_os = "openbsd",
43318 - target_os = "dragonfly",
43319 -- all(target_os = "linux", target_env = "musl")
43320 -+ all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32")))
43321 - )))]
43322 - pub fn blocks_available(&self) -> libc::c_ulong {
43323 - self.0.f_bavail
43324 -@@ -354,8 +368,8 @@ impl Statfs {
43325 - }
43326 -
43327 - /// Total file nodes in filesystem
43328 -- #[cfg(all(target_os = "linux", target_env = "musl"))]
43329 -- pub fn files(&self) -> u64 {
43330 -+ #[cfg(all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32"))))]
43331 -+ pub fn files(&self) -> libc::fsfilcnt_t {
43332 - self.0.f_files
43333 - }
43334 -
43335 -@@ -367,14 +381,19 @@ impl Statfs {
43336 - target_os = "freebsd",
43337 - target_os = "openbsd",
43338 - target_os = "dragonfly",
43339 -- all(target_os = "linux", target_env = "musl")
43340 -+ all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32")))
43341 - )))]
43342 - pub fn files(&self) -> libc::c_ulong {
43343 - self.0.f_files
43344 - }
43345 -
43346 - /// Free file nodes in filesystem
43347 -- #[cfg(any(target_os = "ios", target_os = "macos", target_os = "android"))]
43348 -+ #[cfg(any(
43349 -+ target_os = "android",
43350 -+ target_os = "ios",
43351 -+ target_os = "macos",
43352 -+ target_os = "openbsd"
43353 -+ ))]
43354 - pub fn files_free(&self) -> u64 {
43355 - self.0.f_ffree
43356 - }
43357 -@@ -386,14 +405,14 @@ impl Statfs {
43358 - }
43359 -
43360 - /// Free file nodes in filesystem
43361 -- #[cfg(any(target_os = "freebsd", target_os = "openbsd"))]
43362 -+ #[cfg(target_os = "freebsd")]
43363 - pub fn files_free(&self) -> i64 {
43364 - self.0.f_ffree
43365 - }
43366 -
43367 - /// Free file nodes in filesystem
43368 -- #[cfg(all(target_os = "linux", target_env = "musl"))]
43369 -- pub fn files_free(&self) -> u64 {
43370 -+ #[cfg(all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32"))))]
43371 -+ pub fn files_free(&self) -> libc::fsfilcnt_t {
43372 - self.0.f_ffree
43373 - }
43374 -
43375 -@@ -405,7 +424,7 @@ impl Statfs {
43376 - target_os = "freebsd",
43377 - target_os = "openbsd",
43378 - target_os = "dragonfly",
43379 -- all(target_os = "linux", target_env = "musl")
43380 -+ all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32")))
43381 - )))]
43382 - pub fn files_free(&self) -> libc::c_ulong {
43383 - self.0.f_ffree
43384 -@@ -434,16 +453,17 @@ impl Debug for Statfs {
43385 -
43386 - pub fn statfs<P: ?Sized + NixPath>(path: &P) -> Result<Statfs> {
43387 - unsafe {
43388 -- let mut stat: Statfs = mem::uninitialized();
43389 -- let res = path.with_nix_path(|path| libc::statfs(path.as_ptr(), &mut stat.0))?;
43390 -- Errno::result(res).map(|_| stat)
43391 -+ let mut stat = mem::MaybeUninit::<libc::statfs>::uninit();
43392 -+ let res = path.with_nix_path(|path| libc::statfs(path.as_ptr(), stat.as_mut_ptr()))?;
43393 -+ Errno::result(res).map(|_| Statfs(stat.assume_init()))
43394 - }
43395 - }
43396 -
43397 - pub fn fstatfs<T: AsRawFd>(fd: &T) -> Result<Statfs> {
43398 - unsafe {
43399 -- let mut stat: Statfs = mem::uninitialized();
43400 -- Errno::result(libc::fstatfs(fd.as_raw_fd(), &mut stat.0)).map(|_| stat)
43401 -+ let mut stat = mem::MaybeUninit::<libc::statfs>::uninit();
43402 -+ Errno::result(libc::fstatfs(fd.as_raw_fd(), stat.as_mut_ptr()))
43403 -+ .map(|_| Statfs(stat.assume_init()))
43404 - }
43405 - }
43406 -
43407 -@@ -451,8 +471,8 @@ pub fn fstatfs<T: AsRawFd>(fd: &T) -> Result<Statfs> {
43408 - mod test {
43409 - use std::fs::File;
43410 -
43411 -- use sys::statfs::*;
43412 -- use sys::statvfs::*;
43413 -+ use crate::sys::statfs::*;
43414 -+ use crate::sys::statvfs::*;
43415 - use std::path::Path;
43416 -
43417 - #[test]
43418 -diff --git a/third_party/rust/nix/src/sys/statvfs.rs b/third_party/rust/nix/src/sys/statvfs.rs
43419 -index e5980369d5119..9bea9734925f0 100644
43420 ---- a/third_party/rust/nix/src/sys/statvfs.rs
43421 -+++ b/third_party/rust/nix/src/sys/statvfs.rs
43422 -@@ -7,9 +7,9 @@ use std::os::unix::io::AsRawFd;
43423 -
43424 - use libc::{self, c_ulong};
43425 -
43426 --use {Result, NixPath};
43427 --use errno::Errno;
43428 -+use crate::{Result, NixPath, errno::Errno};
43429 -
43430 -+#[cfg(not(target_os = "redox"))]
43431 - libc_bitflags!(
43432 - /// File system mount Flags
43433 - #[repr(C)]
43434 -@@ -55,8 +55,7 @@ libc_bitflags!(
43435 - /// Wrapper around the POSIX `statvfs` struct
43436 - ///
43437 - /// For more information see the [`statvfs(3)` man pages](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_statvfs.h.html).
43438 --// FIXME: Replace with repr(transparent)
43439 --#[repr(C)]
43440 -+#[repr(transparent)]
43441 - #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
43442 - pub struct Statvfs(libc::statvfs);
43443 -
43444 -@@ -109,6 +108,7 @@ impl Statvfs {
43445 - }
43446 -
43447 - /// Get the mount flags
43448 -+ #[cfg(not(target_os = "redox"))]
43449 - pub fn flags(&self) -> FsFlags {
43450 - FsFlags::from_bits_truncate(self.0.f_flag)
43451 - }
43452 -@@ -124,12 +124,12 @@ impl Statvfs {
43453 - pub fn statvfs<P: ?Sized + NixPath>(path: &P) -> Result<Statvfs> {
43454 - unsafe {
43455 - Errno::clear();
43456 -- let mut stat: Statvfs = mem::uninitialized();
43457 -+ let mut stat = mem::MaybeUninit::<libc::statvfs>::uninit();
43458 - let res = path.with_nix_path(|path|
43459 -- libc::statvfs(path.as_ptr(), &mut stat.0)
43460 -+ libc::statvfs(path.as_ptr(), stat.as_mut_ptr())
43461 - )?;
43462 -
43463 -- Errno::result(res).map(|_| stat)
43464 -+ Errno::result(res).map(|_| Statvfs(stat.assume_init()))
43465 - }
43466 - }
43467 -
43468 -@@ -137,15 +137,16 @@ pub fn statvfs<P: ?Sized + NixPath>(path: &P) -> Result<Statvfs> {
43469 - pub fn fstatvfs<T: AsRawFd>(fd: &T) -> Result<Statvfs> {
43470 - unsafe {
43471 - Errno::clear();
43472 -- let mut stat: Statvfs = mem::uninitialized();
43473 -- Errno::result(libc::fstatvfs(fd.as_raw_fd(), &mut stat.0)).map(|_| stat)
43474 -+ let mut stat = mem::MaybeUninit::<libc::statvfs>::uninit();
43475 -+ Errno::result(libc::fstatvfs(fd.as_raw_fd(), stat.as_mut_ptr()))
43476 -+ .map(|_| Statvfs(stat.assume_init()))
43477 - }
43478 - }
43479 -
43480 - #[cfg(test)]
43481 - mod test {
43482 - use std::fs::File;
43483 -- use sys::statvfs::*;
43484 -+ use crate::sys::statvfs::*;
43485 -
43486 - #[test]
43487 - fn statvfs_call() {
43488 -diff --git a/third_party/rust/nix/src/sys/sysinfo.rs b/third_party/rust/nix/src/sys/sysinfo.rs
43489 -index 4c8e38988886d..222a2fc0480c3 100644
43490 ---- a/third_party/rust/nix/src/sys/sysinfo.rs
43491 -+++ b/third_party/rust/nix/src/sys/sysinfo.rs
43492 -@@ -2,13 +2,20 @@ use libc::{self, SI_LOAD_SHIFT};
43493 - use std::{cmp, mem};
43494 - use std::time::Duration;
43495 -
43496 --use Result;
43497 --use errno::Errno;
43498 -+use crate::Result;
43499 -+use crate::errno::Errno;
43500 -
43501 - /// System info structure returned by `sysinfo`.
43502 - #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
43503 -+#[repr(transparent)]
43504 - pub struct SysInfo(libc::sysinfo);
43505 -
43506 -+// The fields are c_ulong on 32-bit linux, u64 on 64-bit linux; x32's ulong is u32
43507 -+#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
43508 -+type mem_blocks_t = u64;
43509 -+#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
43510 -+type mem_blocks_t = libc::c_ulong;
43511 -+
43512 - impl SysInfo {
43513 - /// Returns the load average tuple.
43514 - ///
43515 -@@ -57,7 +64,7 @@ impl SysInfo {
43516 - self.scale_mem(self.0.freeram)
43517 - }
43518 -
43519 -- fn scale_mem(&self, units: libc::c_ulong) -> u64 {
43520 -+ fn scale_mem(&self, units: mem_blocks_t) -> u64 {
43521 - units as u64 * self.0.mem_unit as u64
43522 - }
43523 - }
43524 -@@ -66,7 +73,7 @@ impl SysInfo {
43525 - ///
43526 - /// [See `sysinfo(2)`](http://man7.org/linux/man-pages/man2/sysinfo.2.html).
43527 - pub fn sysinfo() -> Result<SysInfo> {
43528 -- let mut info: libc::sysinfo = unsafe { mem::uninitialized() };
43529 -- let res = unsafe { libc::sysinfo(&mut info) };
43530 -- Errno::result(res).map(|_| SysInfo(info))
43531 -+ let mut info = mem::MaybeUninit::uninit();
43532 -+ let res = unsafe { libc::sysinfo(info.as_mut_ptr()) };
43533 -+ Errno::result(res).map(|_| unsafe{ SysInfo(info.assume_init()) })
43534 - }
43535 -diff --git a/third_party/rust/nix/src/sys/termios.rs b/third_party/rust/nix/src/sys/termios.rs
43536 -index c7cdf10b461c1..95148360495f1 100644
43537 ---- a/third_party/rust/nix/src/sys/termios.rs
43538 -+++ b/third_party/rust/nix/src/sys/termios.rs
43539 -@@ -25,7 +25,7 @@
43540 - //! ```
43541 - //! # use self::nix::sys::termios::SpecialCharacterIndices::VEOF;
43542 - //! # use self::nix::sys::termios::{_POSIX_VDISABLE, Termios};
43543 --//! # let mut termios = unsafe { Termios::default_uninit() };
43544 -+//! # let mut termios: Termios = unsafe { std::mem::zeroed() };
43545 - //! termios.control_chars[VEOF as usize] = _POSIX_VDISABLE;
43546 - //! ```
43547 - //!
43548 -@@ -38,7 +38,7 @@
43549 - //!
43550 - //! ```
43551 - //! # use self::nix::sys::termios::{ControlFlags, Termios};
43552 --//! # let mut termios = unsafe { Termios::default_uninit() };
43553 -+//! # let mut termios: Termios = unsafe { std::mem::zeroed() };
43554 - //! termios.control_flags & ControlFlags::CSIZE == ControlFlags::CS5;
43555 - //! termios.control_flags |= ControlFlags::CS5;
43556 - //! ```
43557 -@@ -61,10 +61,9 @@
43558 - //! platforms:
43559 - //!
43560 - //! ```rust
43561 --//! # #[macro_use] extern crate nix;
43562 - //! # use nix::sys::termios::{BaudRate, cfsetispeed, cfsetospeed, cfsetspeed, Termios};
43563 - //! # fn main() {
43564 --//! # let mut t = unsafe { Termios::default_uninit() };
43565 -+//! # let mut t: Termios = unsafe { std::mem::zeroed() };
43566 - //! cfsetispeed(&mut t, BaudRate::B9600);
43567 - //! cfsetospeed(&mut t, BaudRate::B9600);
43568 - //! cfsetspeed(&mut t, BaudRate::B9600);
43569 -@@ -74,102 +73,94 @@
43570 - //! Additionally round-tripping baud rates is consistent across platforms:
43571 - //!
43572 - //! ```rust
43573 --//! # extern crate nix;
43574 - //! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetispeed, cfsetspeed, Termios};
43575 - //! # fn main() {
43576 --//! # let mut t = unsafe { Termios::default_uninit() };
43577 -+//! # let mut t: Termios = unsafe { std::mem::zeroed() };
43578 - //! # cfsetspeed(&mut t, BaudRate::B9600);
43579 - //! let speed = cfgetispeed(&t);
43580 --//! assert!(speed == cfgetospeed(&t));
43581 -+//! assert_eq!(speed, cfgetospeed(&t));
43582 - //! cfsetispeed(&mut t, speed);
43583 - //! # }
43584 - //! ```
43585 - //!
43586 - //! On non-BSDs, `cfgetispeed()` and `cfgetospeed()` both return a `BaudRate`:
43587 - //!
43588 --// FIXME: Replace `ignore` with `compile_fail` once 1.22 is the minimum support Rust version
43589 - #![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
43590 - target_os = "macos", target_os = "netbsd", target_os = "openbsd"),
43591 - doc = " ```rust,ignore")]
43592 - #![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
43593 - target_os = "macos", target_os = "netbsd", target_os = "openbsd")),
43594 - doc = " ```rust")]
43595 --//! # extern crate nix;
43596 - //! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetspeed, Termios};
43597 - //! # fn main() {
43598 --//! # let mut t = unsafe { Termios::default_uninit() };
43599 -+//! # let mut t: Termios = unsafe { std::mem::zeroed() };
43600 - //! # cfsetspeed(&mut t, BaudRate::B9600);
43601 --//! assert!(cfgetispeed(&t) == BaudRate::B9600);
43602 --//! assert!(cfgetospeed(&t) == BaudRate::B9600);
43603 -+//! assert_eq!(cfgetispeed(&t), BaudRate::B9600);
43604 -+//! assert_eq!(cfgetospeed(&t), BaudRate::B9600);
43605 - //! # }
43606 - //! ```
43607 - //!
43608 - //! But on the BSDs, `cfgetispeed()` and `cfgetospeed()` both return `u32`s:
43609 - //!
43610 --// FIXME: Replace `ignore` with `compile_fail` once 1.22 is the minimum support Rust version
43611 - #![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
43612 - target_os = "macos", target_os = "netbsd", target_os = "openbsd"),
43613 - doc = " ```rust")]
43614 - #![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
43615 - target_os = "macos", target_os = "netbsd", target_os = "openbsd")),
43616 - doc = " ```rust,ignore")]
43617 --//! # extern crate nix;
43618 - //! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetspeed, Termios};
43619 - //! # fn main() {
43620 --//! # let mut t = unsafe { Termios::default_uninit() };
43621 -+//! # let mut t: Termios = unsafe { std::mem::zeroed() };
43622 - //! # cfsetspeed(&mut t, 9600u32);
43623 --//! assert!(cfgetispeed(&t) == 9600u32);
43624 --//! assert!(cfgetospeed(&t) == 9600u32);
43625 -+//! assert_eq!(cfgetispeed(&t), 9600u32);
43626 -+//! assert_eq!(cfgetospeed(&t), 9600u32);
43627 - //! # }
43628 - //! ```
43629 - //!
43630 - //! It's trivial to convert from a `BaudRate` to a `u32` on BSDs:
43631 - //!
43632 --// FIXME: Replace `ignore` with `compile_fail` once 1.22 is the minimum support Rust version
43633 - #![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
43634 - target_os = "macos", target_os = "netbsd", target_os = "openbsd"),
43635 - doc = " ```rust")]
43636 - #![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
43637 - target_os = "macos", target_os = "netbsd", target_os = "openbsd")),
43638 - doc = " ```rust,ignore")]
43639 --//! # extern crate nix;
43640 - //! # use nix::sys::termios::{BaudRate, cfgetispeed, cfsetspeed, Termios};
43641 - //! # fn main() {
43642 --//! # let mut t = unsafe { Termios::default_uninit() };
43643 -+//! # let mut t: Termios = unsafe { std::mem::zeroed() };
43644 - //! # cfsetspeed(&mut t, 9600u32);
43645 --//! assert!(cfgetispeed(&t) == BaudRate::B9600.into());
43646 --//! assert!(u32::from(BaudRate::B9600) == 9600u32);
43647 -+//! assert_eq!(cfgetispeed(&t), BaudRate::B9600.into());
43648 -+//! assert_eq!(u32::from(BaudRate::B9600), 9600u32);
43649 - //! # }
43650 - //! ```
43651 - //!
43652 - //! And on BSDs you can specify arbitrary baud rates (**note** this depends on hardware support)
43653 - //! by specifying baud rates directly using `u32`s:
43654 - //!
43655 --// FIXME: Replace `ignore` with `compile_fail` once 1.22 is the minimum support Rust version
43656 - #![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
43657 - target_os = "macos", target_os = "netbsd", target_os = "openbsd"),
43658 - doc = " ```rust")]
43659 - #![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
43660 - target_os = "macos", target_os = "netbsd", target_os = "openbsd")),
43661 - doc = " ```rust,ignore")]
43662 --//! # extern crate nix;
43663 - //! # use nix::sys::termios::{cfsetispeed, cfsetospeed, cfsetspeed, Termios};
43664 - //! # fn main() {
43665 --//! # let mut t = unsafe { Termios::default_uninit() };
43666 -+//! # let mut t: Termios = unsafe { std::mem::zeroed() };
43667 - //! cfsetispeed(&mut t, 9600u32);
43668 - //! cfsetospeed(&mut t, 9600u32);
43669 - //! cfsetspeed(&mut t, 9600u32);
43670 - //! # }
43671 - //! ```
43672 --use Result;
43673 --use errno::Errno;
43674 -+use cfg_if::cfg_if;
43675 -+use crate::{Error, Result};
43676 -+use crate::errno::Errno;
43677 - use libc::{self, c_int, tcflag_t};
43678 - use std::cell::{Ref, RefCell};
43679 --use std::convert::From;
43680 -+use std::convert::{From, TryFrom};
43681 - use std::mem;
43682 - use std::os::unix::io::RawFd;
43683 -
43684 --use ::unistd::Pid;
43685 -+use crate::unistd::Pid;
43686 -
43687 - /// Stores settings for the termios API
43688 - ///
43689 -@@ -194,24 +185,9 @@ pub struct Termios {
43690 - impl Termios {
43691 - /// Exposes an immutable reference to the underlying `libc::termios` data structure.
43692 - ///
43693 -- /// This can be used for interfacing with other FFI functions like:
43694 -- ///
43695 -- /// ```rust
43696 -- /// # extern crate libc;
43697 -- /// # extern crate nix;
43698 -- /// # fn main() {
43699 -- /// # use nix::sys::termios::Termios;
43700 -- /// # let mut termios = unsafe { Termios::default_uninit() };
43701 -- /// let inner_termios = termios.get_libc_termios();
43702 -- /// unsafe { libc::cfgetispeed(&*inner_termios) };
43703 -- /// # }
43704 -- /// ```
43705 -- ///
43706 -- /// There is no public API exposed for functions that modify the underlying `libc::termios`
43707 -- /// data because it requires additional work to maintain type safety.
43708 -- // FIXME: Switch this over to use pub(crate)
43709 -- #[doc(hidden)]
43710 -- pub fn get_libc_termios(&self) -> Ref<libc::termios> {
43711 -+ /// This is not part of `nix`'s public API because it requires additional work to maintain type
43712 -+ /// safety.
43713 -+ pub(crate) fn get_libc_termios(&self) -> Ref<libc::termios> {
43714 - {
43715 - let mut termios = self.inner.borrow_mut();
43716 - termios.c_iflag = self.input_flags.bits();
43717 -@@ -225,12 +201,11 @@ impl Termios {
43718 -
43719 - /// Exposes the inner `libc::termios` datastore within `Termios`.
43720 - ///
43721 -- /// This is unsafe because if this is used to modify the inner libc::termios struct, it will not
43722 -- /// automatically update the safe wrapper type around it. Therefore we disable docs to
43723 -- /// effectively limit its use to nix internals. In this case it should also be paired with a
43724 -- /// call to `update_wrapper()` so that the wrapper-type and internal representation stay
43725 -- /// consistent.
43726 -- unsafe fn get_libc_termios_mut(&mut self) -> *mut libc::termios {
43727 -+ /// This is unsafe because if this is used to modify the inner `libc::termios` struct, it will
43728 -+ /// not automatically update the safe wrapper type around it. In this case it should also be
43729 -+ /// paired with a call to `update_wrapper()` so that the wrapper-type and internal
43730 -+ /// representation stay consistent.
43731 -+ pub(crate) unsafe fn get_libc_termios_mut(&mut self) -> *mut libc::termios {
43732 - {
43733 - let mut termios = self.inner.borrow_mut();
43734 - termios.c_iflag = self.input_flags.bits();
43735 -@@ -242,26 +217,8 @@ impl Termios {
43736 - self.inner.as_ptr()
43737 - }
43738 -
43739 -- /// Allows for easily creating new `Termios` structs that will be overwritten with real data.
43740 -- ///
43741 -- /// This should only be used when the inner libc::termios struct will be overwritten before it's
43742 -- /// read.
43743 -- // FIXME: Switch this over to use pub(crate)
43744 -- #[doc(hidden)]
43745 -- pub unsafe fn default_uninit() -> Self {
43746 -- Termios {
43747 -- inner: RefCell::new(mem::uninitialized()),
43748 -- input_flags: InputFlags::empty(),
43749 -- output_flags: OutputFlags::empty(),
43750 -- control_flags: ControlFlags::empty(),
43751 -- local_flags: LocalFlags::empty(),
43752 -- control_chars: [0 as libc::cc_t; NCCS],
43753 -- }
43754 -- }
43755 --
43756 - /// Updates the wrapper values from the internal `libc::termios` data structure.
43757 -- #[doc(hidden)]
43758 -- pub fn update_wrapper(&mut self) {
43759 -+ pub(crate) fn update_wrapper(&mut self) {
43760 - let termios = *self.inner.borrow_mut();
43761 - self.input_flags = InputFlags::from_bits_truncate(termios.c_iflag);
43762 - self.output_flags = OutputFlags::from_bits_truncate(termios.c_oflag);
43763 -@@ -376,9 +333,10 @@ libc_enum!{
43764 - }
43765 - }
43766 -
43767 --impl From<libc::speed_t> for BaudRate {
43768 -- fn from(s: libc::speed_t) -> BaudRate {
43769 -+impl TryFrom<libc::speed_t> for BaudRate {
43770 -+ type Error = Error;
43771 -
43772 -+ fn try_from(s: libc::speed_t) -> Result<BaudRate> {
43773 - use libc::{B0, B50, B75, B110, B134, B150, B200, B300, B600, B1200, B1800, B2400, B4800,
43774 - B9600, B19200, B38400, B57600, B115200, B230400};
43775 - #[cfg(any(target_os = "android", target_os = "linux"))]
43776 -@@ -398,85 +356,84 @@ impl From<libc::speed_t> for BaudRate {
43777 - use libc::{B460800, B921600};
43778 -
43779 - match s {
43780 -- B0 => BaudRate::B0,
43781 -- B50 => BaudRate::B50,
43782 -- B75 => BaudRate::B75,
43783 -- B110 => BaudRate::B110,
43784 -- B134 => BaudRate::B134,
43785 -- B150 => BaudRate::B150,
43786 -- B200 => BaudRate::B200,
43787 -- B300 => BaudRate::B300,
43788 -- B600 => BaudRate::B600,
43789 -- B1200 => BaudRate::B1200,
43790 -- B1800 => BaudRate::B1800,
43791 -- B2400 => BaudRate::B2400,
43792 -- B4800 => BaudRate::B4800,
43793 -+ B0 => Ok(BaudRate::B0),
43794 -+ B50 => Ok(BaudRate::B50),
43795 -+ B75 => Ok(BaudRate::B75),
43796 -+ B110 => Ok(BaudRate::B110),
43797 -+ B134 => Ok(BaudRate::B134),
43798 -+ B150 => Ok(BaudRate::B150),
43799 -+ B200 => Ok(BaudRate::B200),
43800 -+ B300 => Ok(BaudRate::B300),
43801 -+ B600 => Ok(BaudRate::B600),
43802 -+ B1200 => Ok(BaudRate::B1200),
43803 -+ B1800 => Ok(BaudRate::B1800),
43804 -+ B2400 => Ok(BaudRate::B2400),
43805 -+ B4800 => Ok(BaudRate::B4800),
43806 - #[cfg(any(target_os = "dragonfly",
43807 - target_os = "freebsd",
43808 - target_os = "macos",
43809 - target_os = "netbsd",
43810 - target_os = "openbsd"))]
43811 -- B7200 => BaudRate::B7200,
43812 -- B9600 => BaudRate::B9600,
43813 -+ B7200 => Ok(BaudRate::B7200),
43814 -+ B9600 => Ok(BaudRate::B9600),
43815 - #[cfg(any(target_os = "dragonfly",
43816 - target_os = "freebsd",
43817 - target_os = "macos",
43818 - target_os = "netbsd",
43819 - target_os = "openbsd"))]
43820 -- B14400 => BaudRate::B14400,
43821 -- B19200 => BaudRate::B19200,
43822 -+ B14400 => Ok(BaudRate::B14400),
43823 -+ B19200 => Ok(BaudRate::B19200),
43824 - #[cfg(any(target_os = "dragonfly",
43825 - target_os = "freebsd",
43826 - target_os = "macos",
43827 - target_os = "netbsd",
43828 - target_os = "openbsd"))]
43829 -- B28800 => BaudRate::B28800,
43830 -- B38400 => BaudRate::B38400,
43831 -- B57600 => BaudRate::B57600,
43832 -+ B28800 => Ok(BaudRate::B28800),
43833 -+ B38400 => Ok(BaudRate::B38400),
43834 -+ B57600 => Ok(BaudRate::B57600),
43835 - #[cfg(any(target_os = "dragonfly",
43836 - target_os = "freebsd",
43837 - target_os = "macos",
43838 - target_os = "netbsd",
43839 - target_os = "openbsd"))]
43840 -- B76800 => BaudRate::B76800,
43841 -- B115200 => BaudRate::B115200,
43842 -- B230400 => BaudRate::B230400,
43843 -+ B76800 => Ok(BaudRate::B76800),
43844 -+ B115200 => Ok(BaudRate::B115200),
43845 -+ B230400 => Ok(BaudRate::B230400),
43846 - #[cfg(any(target_os = "android",
43847 - target_os = "freebsd",
43848 - target_os = "linux",
43849 - target_os = "netbsd"))]
43850 -- B460800 => BaudRate::B460800,
43851 -+ B460800 => Ok(BaudRate::B460800),
43852 - #[cfg(any(target_os = "android", target_os = "linux"))]
43853 -- B500000 => BaudRate::B500000,
43854 -+ B500000 => Ok(BaudRate::B500000),
43855 - #[cfg(any(target_os = "android", target_os = "linux"))]
43856 -- B576000 => BaudRate::B576000,
43857 -+ B576000 => Ok(BaudRate::B576000),
43858 - #[cfg(any(target_os = "android",
43859 - target_os = "freebsd",
43860 - target_os = "linux",
43861 - target_os = "netbsd"))]
43862 -- B921600 => BaudRate::B921600,
43863 -+ B921600 => Ok(BaudRate::B921600),
43864 - #[cfg(any(target_os = "android", target_os = "linux"))]
43865 -- B1000000 => BaudRate::B1000000,
43866 -+ B1000000 => Ok(BaudRate::B1000000),
43867 - #[cfg(any(target_os = "android", target_os = "linux"))]
43868 -- B1152000 => BaudRate::B1152000,
43869 -+ B1152000 => Ok(BaudRate::B1152000),
43870 - #[cfg(any(target_os = "android", target_os = "linux"))]
43871 -- B1500000 => BaudRate::B1500000,
43872 -+ B1500000 => Ok(BaudRate::B1500000),
43873 - #[cfg(any(target_os = "android", target_os = "linux"))]
43874 -- B2000000 => BaudRate::B2000000,
43875 -+ B2000000 => Ok(BaudRate::B2000000),
43876 - #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
43877 -- B2500000 => BaudRate::B2500000,
43878 -+ B2500000 => Ok(BaudRate::B2500000),
43879 - #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
43880 -- B3000000 => BaudRate::B3000000,
43881 -+ B3000000 => Ok(BaudRate::B3000000),
43882 - #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
43883 -- B3500000 => BaudRate::B3500000,
43884 -+ B3500000 => Ok(BaudRate::B3500000),
43885 - #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
43886 -- B4000000 => BaudRate::B4000000,
43887 -- b => unreachable!("Invalid baud constant: {}", b),
43888 -+ B4000000 => Ok(BaudRate::B4000000),
43889 -+ _ => Err(Error::invalid_argument())
43890 - }
43891 - }
43892 - }
43893 -
43894 --// TODO: Include `TryFrom<u32> for BaudRate` once that API stabilizes
43895 - #[cfg(any(target_os = "freebsd",
43896 - target_os = "dragonfly",
43897 - target_os = "ios",
43898 -@@ -583,6 +540,12 @@ libc_enum! {
43899 - }
43900 - }
43901 -
43902 -+#[cfg(all(target_os = "linux", target_arch = "sparc64"))]
43903 -+impl SpecialCharacterIndices {
43904 -+ pub const VMIN: SpecialCharacterIndices = SpecialCharacterIndices::VEOF;
43905 -+ pub const VTIME: SpecialCharacterIndices = SpecialCharacterIndices::VEOL;
43906 -+}
43907 -+
43908 - pub use libc::NCCS;
43909 - #[cfg(any(target_os = "dragonfly",
43910 - target_os = "freebsd",
43911 -@@ -606,7 +569,9 @@ libc_bitflags! {
43912 - ICRNL;
43913 - IXON;
43914 - IXOFF;
43915 -+ #[cfg(not(target_os = "redox"))]
43916 - IXANY;
43917 -+ #[cfg(not(target_os = "redox"))]
43918 - IMAXBEL;
43919 - #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
43920 - IUTF8;
43921 -@@ -816,6 +781,7 @@ libc_bitflags! {
43922 - PARODD;
43923 - HUPCL;
43924 - CLOCAL;
43925 -+ #[cfg(not(target_os = "redox"))]
43926 - CRTSCTS;
43927 - #[cfg(any(target_os = "android", target_os = "linux"))]
43928 - CBAUD;
43929 -@@ -866,12 +832,15 @@ libc_bitflags! {
43930 - libc_bitflags! {
43931 - /// Flags for setting any local modes
43932 - pub struct LocalFlags: tcflag_t {
43933 -+ #[cfg(not(target_os = "redox"))]
43934 - ECHOKE;
43935 - ECHOE;
43936 - ECHOK;
43937 - ECHO;
43938 - ECHONL;
43939 -+ #[cfg(not(target_os = "redox"))]
43940 - ECHOPRT;
43941 -+ #[cfg(not(target_os = "redox"))]
43942 - ECHOCTL;
43943 - ISIG;
43944 - ICANON;
43945 -@@ -883,8 +852,10 @@ libc_bitflags! {
43946 - target_os = "openbsd"))]
43947 - ALTWERASE;
43948 - IEXTEN;
43949 -+ #[cfg(not(target_os = "redox"))]
43950 - EXTPROC;
43951 - TOSTOP;
43952 -+ #[cfg(not(target_os = "redox"))]
43953 - FLUSHO;
43954 - #[cfg(any(target_os = "freebsd",
43955 - target_os = "dragonfly",
43956 -@@ -893,6 +864,7 @@ libc_bitflags! {
43957 - target_os = "netbsd",
43958 - target_os = "openbsd"))]
43959 - NOKERNINFO;
43960 -+ #[cfg(not(target_os = "redox"))]
43961 - PENDIN;
43962 - NOFLSH;
43963 - }
43964 -@@ -957,13 +929,15 @@ cfg_if!{
43965 - Errno::result(res).map(drop)
43966 - }
43967 - } else {
43968 -+ use std::convert::TryInto;
43969 -+
43970 - /// Get input baud rate (see
43971 - /// [cfgetispeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetispeed.html)).
43972 - ///
43973 - /// `cfgetispeed()` extracts the input baud rate from the given `Termios` structure.
43974 - pub fn cfgetispeed(termios: &Termios) -> BaudRate {
43975 - let inner_termios = termios.get_libc_termios();
43976 -- unsafe { libc::cfgetispeed(&*inner_termios) }.into()
43977 -+ unsafe { libc::cfgetispeed(&*inner_termios) }.try_into().unwrap()
43978 - }
43979 -
43980 - /// Get output baud rate (see
43981 -@@ -972,7 +946,7 @@ cfg_if!{
43982 - /// `cfgetospeed()` extracts the output baud rate from the given `Termios` structure.
43983 - pub fn cfgetospeed(termios: &Termios) -> BaudRate {
43984 - let inner_termios = termios.get_libc_termios();
43985 -- unsafe { libc::cfgetospeed(&*inner_termios) }.into()
43986 -+ unsafe { libc::cfgetospeed(&*inner_termios) }.try_into().unwrap()
43987 - }
43988 -
43989 - /// Set input baud rate (see
43990 -@@ -1045,13 +1019,13 @@ pub fn cfmakesane(termios: &mut Termios) {
43991 - /// this structure *will not* reconfigure the port, instead the modifications should be done to
43992 - /// the `Termios` structure and then the port should be reconfigured using `tcsetattr()`.
43993 - pub fn tcgetattr(fd: RawFd) -> Result<Termios> {
43994 -- let mut termios: libc::termios = unsafe { mem::uninitialized() };
43995 -+ let mut termios = mem::MaybeUninit::uninit();
43996 -
43997 -- let res = unsafe { libc::tcgetattr(fd, &mut termios) };
43998 -+ let res = unsafe { libc::tcgetattr(fd, termios.as_mut_ptr()) };
43999 -
44000 - Errno::result(res)?;
44001 -
44002 -- Ok(termios.into())
44003 -+ unsafe { Ok(termios.assume_init().into()) }
44004 - }
44005 -
44006 - /// Set the configuration for a terminal (see
44007 -@@ -1105,3 +1079,14 @@ pub fn tcgetsid(fd: RawFd) -> Result<Pid> {
44008 -
44009 - Errno::result(res).map(Pid::from_raw)
44010 - }
44011 -+
44012 -+#[cfg(test)]
44013 -+mod test {
44014 -+ use super::*;
44015 -+
44016 -+ #[test]
44017 -+ fn try_from() {
44018 -+ assert_eq!(Ok(BaudRate::B0), BaudRate::try_from(libc::B0));
44019 -+ assert!(BaudRate::try_from(999999999).is_err());
44020 -+ }
44021 -+}
44022 -diff --git a/third_party/rust/nix/src/sys/time.rs b/third_party/rust/nix/src/sys/time.rs
44023 -index 3ad57543b18a7..7546d1b367c5e 100644
44024 ---- a/third_party/rust/nix/src/sys/time.rs
44025 -+++ b/third_party/rust/nix/src/sys/time.rs
44026 -@@ -1,6 +1,8 @@
44027 - use std::{cmp, fmt, ops};
44028 -+use std::time::Duration;
44029 - use std::convert::From;
44030 --use libc::{c_long, timespec, timeval};
44031 -+use libc::{timespec, timeval};
44032 -+#[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
44033 - pub use libc::{time_t, suseconds_t};
44034 -
44035 - pub trait TimeValLike: Sized {
44036 -@@ -60,6 +62,34 @@ const TS_MAX_SECONDS: i64 = ::std::isize::MAX as i64;
44037 -
44038 - const TS_MIN_SECONDS: i64 = -TS_MAX_SECONDS;
44039 -
44040 -+// x32 compatibility
44041 -+// See https://sourceware.org/bugzilla/show_bug.cgi?id=16437
44042 -+#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
44043 -+type timespec_tv_nsec_t = i64;
44044 -+#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
44045 -+type timespec_tv_nsec_t = libc::c_long;
44046 -+
44047 -+impl From<timespec> for TimeSpec {
44048 -+ fn from(ts: timespec) -> Self {
44049 -+ Self(ts)
44050 -+ }
44051 -+}
44052 -+
44053 -+impl From<Duration> for TimeSpec {
44054 -+ fn from(duration: Duration) -> Self {
44055 -+ #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
44056 -+ TimeSpec(timespec {
44057 -+ tv_sec: duration.as_secs() as time_t,
44058 -+ tv_nsec: duration.subsec_nanos() as timespec_tv_nsec_t
44059 -+ })
44060 -+ }
44061 -+}
44062 -+
44063 -+impl From<TimeSpec> for Duration {
44064 -+ fn from(timespec: TimeSpec) -> Self {
44065 -+ Duration::new(timespec.0.tv_sec as u64, timespec.0.tv_nsec as u32)
44066 -+ }
44067 -+}
44068 -
44069 - impl AsRef<timespec> for TimeSpec {
44070 - fn as_ref(&self) -> &timespec {
44071 -@@ -67,6 +97,12 @@ impl AsRef<timespec> for TimeSpec {
44072 - }
44073 - }
44074 -
44075 -+impl AsMut<timespec> for TimeSpec {
44076 -+ fn as_mut(&mut self) -> &mut timespec {
44077 -+ &mut self.0
44078 -+ }
44079 -+}
44080 -+
44081 - impl Ord for TimeSpec {
44082 - // The implementation of cmp is simplified by assuming that the struct is
44083 - // normalized. That is, tv_nsec must always be within [0, 1_000_000_000)
44084 -@@ -90,6 +126,7 @@ impl TimeValLike for TimeSpec {
44085 - fn seconds(seconds: i64) -> TimeSpec {
44086 - assert!(seconds >= TS_MIN_SECONDS && seconds <= TS_MAX_SECONDS,
44087 - "TimeSpec out of bounds; seconds={}", seconds);
44088 -+ #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
44089 - TimeSpec(timespec {tv_sec: seconds as time_t, tv_nsec: 0 })
44090 - }
44091 -
44092 -@@ -116,8 +153,9 @@ impl TimeValLike for TimeSpec {
44093 - let (secs, nanos) = div_mod_floor_64(nanoseconds, NANOS_PER_SEC);
44094 - assert!(secs >= TS_MIN_SECONDS && secs <= TS_MAX_SECONDS,
44095 - "TimeSpec out of bounds");
44096 -+ #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
44097 - TimeSpec(timespec {tv_sec: secs as time_t,
44098 -- tv_nsec: nanos as c_long })
44099 -+ tv_nsec: nanos as timespec_tv_nsec_t })
44100 - }
44101 -
44102 - fn num_seconds(&self) -> i64 {
44103 -@@ -144,19 +182,20 @@ impl TimeValLike for TimeSpec {
44104 - }
44105 -
44106 - impl TimeSpec {
44107 -- fn nanos_mod_sec(&self) -> c_long {
44108 -+ fn nanos_mod_sec(&self) -> timespec_tv_nsec_t {
44109 - if self.tv_sec() < 0 && self.tv_nsec() > 0 {
44110 -- self.tv_nsec() - NANOS_PER_SEC as c_long
44111 -+ self.tv_nsec() - NANOS_PER_SEC as timespec_tv_nsec_t
44112 - } else {
44113 - self.tv_nsec()
44114 - }
44115 - }
44116 -
44117 -+ #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
44118 - pub fn tv_sec(&self) -> time_t {
44119 - self.0.tv_sec
44120 - }
44121 -
44122 -- pub fn tv_nsec(&self) -> c_long {
44123 -+ pub fn tv_nsec(&self) -> timespec_tv_nsec_t {
44124 - self.0.tv_nsec
44125 - }
44126 - }
44127 -@@ -191,7 +230,7 @@ impl ops::Mul<i32> for TimeSpec {
44128 - type Output = TimeSpec;
44129 -
44130 - fn mul(self, rhs: i32) -> TimeSpec {
44131 -- let usec = self.num_nanoseconds().checked_mul(rhs as i64)
44132 -+ let usec = self.num_nanoseconds().checked_mul(i64::from(rhs))
44133 - .expect("TimeSpec multiply out of bounds");
44134 -
44135 - TimeSpec::nanoseconds(usec)
44136 -@@ -202,7 +241,7 @@ impl ops::Div<i32> for TimeSpec {
44137 - type Output = TimeSpec;
44138 -
44139 - fn div(self, rhs: i32) -> TimeSpec {
44140 -- let usec = self.num_nanoseconds() / rhs as i64;
44141 -+ let usec = self.num_nanoseconds() / i64::from(rhs);
44142 - TimeSpec::nanoseconds(usec)
44143 - }
44144 - }
44145 -@@ -239,7 +278,7 @@ impl fmt::Display for TimeSpec {
44146 -
44147 -
44148 -
44149 --#[repr(C)]
44150 -+#[repr(transparent)]
44151 - #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
44152 - pub struct TimeVal(timeval);
44153 -
44154 -@@ -259,6 +298,12 @@ impl AsRef<timeval> for TimeVal {
44155 - }
44156 - }
44157 -
44158 -+impl AsMut<timeval> for TimeVal {
44159 -+ fn as_mut(&mut self) -> &mut timeval {
44160 -+ &mut self.0
44161 -+ }
44162 -+}
44163 -+
44164 - impl Ord for TimeVal {
44165 - // The implementation of cmp is simplified by assuming that the struct is
44166 - // normalized. That is, tv_usec must always be within [0, 1_000_000)
44167 -@@ -282,6 +327,7 @@ impl TimeValLike for TimeVal {
44168 - fn seconds(seconds: i64) -> TimeVal {
44169 - assert!(seconds >= TV_MIN_SECONDS && seconds <= TV_MAX_SECONDS,
44170 - "TimeVal out of bounds; seconds={}", seconds);
44171 -+ #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
44172 - TimeVal(timeval {tv_sec: seconds as time_t, tv_usec: 0 })
44173 - }
44174 -
44175 -@@ -299,6 +345,7 @@ impl TimeValLike for TimeVal {
44176 - let (secs, micros) = div_mod_floor_64(microseconds, MICROS_PER_SEC);
44177 - assert!(secs >= TV_MIN_SECONDS && secs <= TV_MAX_SECONDS,
44178 - "TimeVal out of bounds");
44179 -+ #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
44180 - TimeVal(timeval {tv_sec: secs as time_t,
44181 - tv_usec: micros as suseconds_t })
44182 - }
44183 -@@ -311,6 +358,7 @@ impl TimeValLike for TimeVal {
44184 - let (secs, micros) = div_mod_floor_64(microseconds, MICROS_PER_SEC);
44185 - assert!(secs >= TV_MIN_SECONDS && secs <= TV_MAX_SECONDS,
44186 - "TimeVal out of bounds");
44187 -+ #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
44188 - TimeVal(timeval {tv_sec: secs as time_t,
44189 - tv_usec: micros as suseconds_t })
44190 - }
44191 -@@ -347,6 +395,7 @@ impl TimeVal {
44192 - }
44193 - }
44194 -
44195 -+ #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
44196 - pub fn tv_sec(&self) -> time_t {
44197 - self.0.tv_sec
44198 - }
44199 -@@ -386,7 +435,7 @@ impl ops::Mul<i32> for TimeVal {
44200 - type Output = TimeVal;
44201 -
44202 - fn mul(self, rhs: i32) -> TimeVal {
44203 -- let usec = self.num_microseconds().checked_mul(rhs as i64)
44204 -+ let usec = self.num_microseconds().checked_mul(i64::from(rhs))
44205 - .expect("TimeVal multiply out of bounds");
44206 -
44207 - TimeVal::microseconds(usec)
44208 -@@ -397,7 +446,7 @@ impl ops::Div<i32> for TimeVal {
44209 - type Output = TimeVal;
44210 -
44211 - fn div(self, rhs: i32) -> TimeVal {
44212 -- let usec = self.num_microseconds() / rhs as i64;
44213 -+ let usec = self.num_microseconds() / i64::from(rhs);
44214 - TimeVal::microseconds(usec)
44215 - }
44216 - }
44217 -@@ -467,6 +516,7 @@ fn div_rem_64(this: i64, other: i64) -> (i64, i64) {
44218 - #[cfg(test)]
44219 - mod test {
44220 - use super::{TimeSpec, TimeVal, TimeValLike};
44221 -+ use std::time::Duration;
44222 -
44223 - #[test]
44224 - pub fn test_timespec() {
44225 -@@ -477,6 +527,15 @@ mod test {
44226 - TimeSpec::seconds(182));
44227 - }
44228 -
44229 -+ #[test]
44230 -+ pub fn test_timespec_from() {
44231 -+ let duration = Duration::new(123, 123_456_789);
44232 -+ let timespec = TimeSpec::nanoseconds(123_123_456_789);
44233 -+
44234 -+ assert_eq!(TimeSpec::from(duration), timespec);
44235 -+ assert_eq!(Duration::from(timespec), duration);
44236 -+ }
44237 -+
44238 - #[test]
44239 - pub fn test_timespec_neg() {
44240 - let a = TimeSpec::seconds(1) + TimeSpec::nanoseconds(123);
44241 -diff --git a/third_party/rust/nix/src/sys/timerfd.rs b/third_party/rust/nix/src/sys/timerfd.rs
44242 -new file mode 100644
44243 -index 0000000000000..4a24719498602
44244 ---- /dev/null
44245 -+++ b/third_party/rust/nix/src/sys/timerfd.rs
44246 -@@ -0,0 +1,285 @@
44247 -+//! Timer API via file descriptors.
44248 -+//!
44249 -+//! Timer FD is a Linux-only API to create timers and get expiration
44250 -+//! notifications through file descriptors.
44251 -+//!
44252 -+//! For more documentation, please read [timerfd_create(2)](http://man7.org/linux/man-pages/man2/timerfd_create.2.html).
44253 -+//!
44254 -+//! # Examples
44255 -+//!
44256 -+//! Create a new one-shot timer that expires after 1 second.
44257 -+//! ```
44258 -+//! # use std::os::unix::io::AsRawFd;
44259 -+//! # use nix::sys::timerfd::{TimerFd, ClockId, TimerFlags, TimerSetTimeFlags,
44260 -+//! # Expiration};
44261 -+//! # use nix::sys::time::{TimeSpec, TimeValLike};
44262 -+//! # use nix::unistd::read;
44263 -+//! #
44264 -+//! // We create a new monotonic timer.
44265 -+//! let timer = TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty())
44266 -+//! .unwrap();
44267 -+//!
44268 -+//! // We set a new one-shot timer in 1 seconds.
44269 -+//! timer.set(
44270 -+//! Expiration::OneShot(TimeSpec::seconds(1)),
44271 -+//! TimerSetTimeFlags::empty()
44272 -+//! ).unwrap();
44273 -+//!
44274 -+//! // We wait for the timer to expire.
44275 -+//! timer.wait().unwrap();
44276 -+//! ```
44277 -+use crate::sys::time::TimeSpec;
44278 -+use crate::unistd::read;
44279 -+use crate::{errno::Errno, Error, Result};
44280 -+use bitflags::bitflags;
44281 -+use libc::c_int;
44282 -+use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
44283 -+
44284 -+/// A timerfd instance. This is also a file descriptor, you can feed it to
44285 -+/// other interfaces consuming file descriptors, epoll for example.
44286 -+#[derive(Debug)]
44287 -+pub struct TimerFd {
44288 -+ fd: RawFd,
44289 -+}
44290 -+
44291 -+impl AsRawFd for TimerFd {
44292 -+ fn as_raw_fd(&self) -> RawFd {
44293 -+ self.fd
44294 -+ }
44295 -+}
44296 -+
44297 -+impl FromRawFd for TimerFd {
44298 -+ unsafe fn from_raw_fd(fd: RawFd) -> Self {
44299 -+ TimerFd { fd }
44300 -+ }
44301 -+}
44302 -+
44303 -+libc_enum! {
44304 -+ /// The type of the clock used to mark the progress of the timer. For more
44305 -+ /// details on each kind of clock, please refer to [timerfd_create(2)](http://man7.org/linux/man-pages/man2/timerfd_create.2.html).
44306 -+ #[repr(i32)]
44307 -+ pub enum ClockId {
44308 -+ CLOCK_REALTIME,
44309 -+ CLOCK_MONOTONIC,
44310 -+ CLOCK_BOOTTIME,
44311 -+ CLOCK_REALTIME_ALARM,
44312 -+ CLOCK_BOOTTIME_ALARM,
44313 -+ }
44314 -+}
44315 -+
44316 -+libc_bitflags! {
44317 -+ /// Additional flags to change the behaviour of the file descriptor at the
44318 -+ /// time of creation.
44319 -+ pub struct TimerFlags: c_int {
44320 -+ TFD_NONBLOCK;
44321 -+ TFD_CLOEXEC;
44322 -+ }
44323 -+}
44324 -+
44325 -+bitflags! {
44326 -+ /// Flags that are used for arming the timer.
44327 -+ pub struct TimerSetTimeFlags: libc::c_int {
44328 -+ const TFD_TIMER_ABSTIME = libc::TFD_TIMER_ABSTIME;
44329 -+ }
44330 -+}
44331 -+
44332 -+#[derive(Debug, Clone, Copy)]
44333 -+struct TimerSpec(libc::itimerspec);
44334 -+
44335 -+impl TimerSpec {
44336 -+ pub fn none() -> Self {
44337 -+ Self(libc::itimerspec {
44338 -+ it_interval: libc::timespec {
44339 -+ tv_sec: 0,
44340 -+ tv_nsec: 0,
44341 -+ },
44342 -+ it_value: libc::timespec {
44343 -+ tv_sec: 0,
44344 -+ tv_nsec: 0,
44345 -+ },
44346 -+ })
44347 -+ }
44348 -+}
44349 -+
44350 -+impl AsRef<libc::itimerspec> for TimerSpec {
44351 -+ fn as_ref(&self) -> &libc::itimerspec {
44352 -+ &self.0
44353 -+ }
44354 -+}
44355 -+
44356 -+impl From<Expiration> for TimerSpec {
44357 -+ fn from(expiration: Expiration) -> TimerSpec {
44358 -+ match expiration {
44359 -+ Expiration::OneShot(t) => TimerSpec(libc::itimerspec {
44360 -+ it_interval: libc::timespec {
44361 -+ tv_sec: 0,
44362 -+ tv_nsec: 0,
44363 -+ },
44364 -+ it_value: *t.as_ref(),
44365 -+ }),
44366 -+ Expiration::IntervalDelayed(start, interval) => TimerSpec(libc::itimerspec {
44367 -+ it_interval: *interval.as_ref(),
44368 -+ it_value: *start.as_ref(),
44369 -+ }),
44370 -+ Expiration::Interval(t) => TimerSpec(libc::itimerspec {
44371 -+ it_interval: *t.as_ref(),
44372 -+ it_value: *t.as_ref(),
44373 -+ }),
44374 -+ }
44375 -+ }
44376 -+}
44377 -+
44378 -+impl From<TimerSpec> for Expiration {
44379 -+ fn from(timerspec: TimerSpec) -> Expiration {
44380 -+ match timerspec {
44381 -+ TimerSpec(libc::itimerspec {
44382 -+ it_interval:
44383 -+ libc::timespec {
44384 -+ tv_sec: 0,
44385 -+ tv_nsec: 0,
44386 -+ },
44387 -+ it_value: ts,
44388 -+ }) => Expiration::OneShot(ts.into()),
44389 -+ TimerSpec(libc::itimerspec {
44390 -+ it_interval: int_ts,
44391 -+ it_value: val_ts,
44392 -+ }) => {
44393 -+ if (int_ts.tv_sec == val_ts.tv_sec) && (int_ts.tv_nsec == val_ts.tv_nsec) {
44394 -+ Expiration::Interval(int_ts.into())
44395 -+ } else {
44396 -+ Expiration::IntervalDelayed(val_ts.into(), int_ts.into())
44397 -+ }
44398 -+ }
44399 -+ }
44400 -+ }
44401 -+}
44402 -+
44403 -+/// An enumeration allowing the definition of the expiration time of an alarm,
44404 -+/// recurring or not.
44405 -+#[derive(Debug, Clone, Copy, PartialEq)]
44406 -+pub enum Expiration {
44407 -+ OneShot(TimeSpec),
44408 -+ IntervalDelayed(TimeSpec, TimeSpec),
44409 -+ Interval(TimeSpec),
44410 -+}
44411 -+
44412 -+impl TimerFd {
44413 -+ /// Creates a new timer based on the clock defined by `clockid`. The
44414 -+ /// underlying fd can be assigned specific flags with `flags` (CLOEXEC,
44415 -+ /// NONBLOCK). The underlying fd will be closed on drop.
44416 -+ pub fn new(clockid: ClockId, flags: TimerFlags) -> Result<Self> {
44417 -+ Errno::result(unsafe { libc::timerfd_create(clockid as i32, flags.bits()) })
44418 -+ .map(|fd| Self { fd })
44419 -+ }
44420 -+
44421 -+ /// Sets a new alarm on the timer.
44422 -+ ///
44423 -+ /// # Types of alarm
44424 -+ ///
44425 -+ /// There are 3 types of alarms you can set:
44426 -+ ///
44427 -+ /// - one shot: the alarm will trigger once after the specified amount of
44428 -+ /// time.
44429 -+ /// Example: I want an alarm to go off in 60s and then disables itself.
44430 -+ ///
44431 -+ /// - interval: the alarm will trigger every specified interval of time.
44432 -+ /// Example: I want an alarm to go off every 60s. The alarm will first
44433 -+ /// go off 60s after I set it and every 60s after that. The alarm will
44434 -+ /// not disable itself.
44435 -+ ///
44436 -+ /// - interval delayed: the alarm will trigger after a certain amount of
44437 -+ /// time and then trigger at a specified interval.
44438 -+ /// Example: I want an alarm to go off every 60s but only start in 1h.
44439 -+ /// The alarm will first trigger 1h after I set it and then every 60s
44440 -+ /// after that. The alarm will not disable itself.
44441 -+ ///
44442 -+ /// # Relative vs absolute alarm
44443 -+ ///
44444 -+ /// If you do not set any `TimerSetTimeFlags`, then the `TimeSpec` you pass
44445 -+ /// to the `Expiration` you want is relative. If however you want an alarm
44446 -+ /// to go off at a certain point in time, you can set `TFD_TIMER_ABSTIME`.
44447 -+ /// Then the one shot TimeSpec and the delay TimeSpec of the delayed
44448 -+ /// interval are going to be interpreted as absolute.
44449 -+ ///
44450 -+ /// # Disabling alarms
44451 -+ ///
44452 -+ /// Note: Only one alarm can be set for any given timer. Setting a new alarm
44453 -+ /// actually removes the previous one.
44454 -+ ///
44455 -+ /// Note: Setting a one shot alarm with a 0s TimeSpec disables the alarm
44456 -+ /// altogether.
44457 -+ pub fn set(&self, expiration: Expiration, flags: TimerSetTimeFlags) -> Result<()> {
44458 -+ let timerspec: TimerSpec = expiration.into();
44459 -+ Errno::result(unsafe {
44460 -+ libc::timerfd_settime(
44461 -+ self.fd,
44462 -+ flags.bits(),
44463 -+ timerspec.as_ref(),
44464 -+ std::ptr::null_mut(),
44465 -+ )
44466 -+ })
44467 -+ .map(drop)
44468 -+ }
44469 -+
44470 -+ /// Get the parameters for the alarm currently set, if any.
44471 -+ pub fn get(&self) -> Result<Option<Expiration>> {
44472 -+ let mut timerspec = TimerSpec::none();
44473 -+ let timerspec_ptr: *mut libc::itimerspec = &mut timerspec.0;
44474 -+
44475 -+ Errno::result(unsafe { libc::timerfd_gettime(self.fd, timerspec_ptr) }).map(|_| {
44476 -+ if timerspec.0.it_interval.tv_sec == 0
44477 -+ && timerspec.0.it_interval.tv_nsec == 0
44478 -+ && timerspec.0.it_value.tv_sec == 0
44479 -+ && timerspec.0.it_value.tv_nsec == 0
44480 -+ {
44481 -+ None
44482 -+ } else {
44483 -+ Some(timerspec.into())
44484 -+ }
44485 -+ })
44486 -+ }
44487 -+
44488 -+ /// Remove the alarm if any is set.
44489 -+ pub fn unset(&self) -> Result<()> {
44490 -+ Errno::result(unsafe {
44491 -+ libc::timerfd_settime(
44492 -+ self.fd,
44493 -+ TimerSetTimeFlags::empty().bits(),
44494 -+ TimerSpec::none().as_ref(),
44495 -+ std::ptr::null_mut(),
44496 -+ )
44497 -+ })
44498 -+ .map(drop)
44499 -+ }
44500 -+
44501 -+ /// Wait for the configured alarm to expire.
44502 -+ ///
44503 -+ /// Note: If the alarm is unset, then you will wait forever.
44504 -+ pub fn wait(&self) -> Result<()> {
44505 -+ loop {
44506 -+ if let Err(e) = read(self.fd, &mut [0u8; 8]) {
44507 -+ match e {
44508 -+ Error::Sys(Errno::EINTR) => continue,
44509 -+ _ => return Err(e),
44510 -+ }
44511 -+ } else {
44512 -+ break;
44513 -+ }
44514 -+ }
44515 -+
44516 -+ Ok(())
44517 -+ }
44518 -+}
44519 -+
44520 -+impl Drop for TimerFd {
44521 -+ fn drop(&mut self) {
44522 -+ if !std::thread::panicking() {
44523 -+ let result = Errno::result(unsafe {
44524 -+ libc::close(self.fd)
44525 -+ });
44526 -+ if let Err(Error::Sys(Errno::EBADF)) = result {
44527 -+ panic!("close of TimerFd encountered EBADF");
44528 -+ }
44529 -+ }
44530 -+ }
44531 -+}
44532 -diff --git a/third_party/rust/nix/src/sys/uio.rs b/third_party/rust/nix/src/sys/uio.rs
44533 -index d089084eed711..65334227b4d1d 100644
44534 ---- a/third_party/rust/nix/src/sys/uio.rs
44535 -+++ b/third_party/rust/nix/src/sys/uio.rs
44536 -@@ -1,8 +1,8 @@
44537 - // Silence invalid warnings due to rust-lang/rust#16719
44538 - #![allow(improper_ctypes)]
44539 -
44540 --use Result;
44541 --use errno::Errno;
44542 -+use crate::Result;
44543 -+use crate::errno::Errno;
44544 - use libc::{self, c_int, c_void, size_t, off_t};
44545 - use std::marker::PhantomData;
44546 - use std::os::unix::io::RawFd;
44547 -@@ -117,7 +117,11 @@ pub struct RemoteIoVec {
44548 - /// [`IoVec`]: struct.IoVec.html
44549 - /// [`RemoteIoVec`]: struct.RemoteIoVec.html
44550 - #[cfg(target_os = "linux")]
44551 --pub fn process_vm_writev(pid: ::unistd::Pid, local_iov: &[IoVec<&[u8]>], remote_iov: &[RemoteIoVec]) -> Result<usize> {
44552 -+pub fn process_vm_writev(
44553 -+ pid: crate::unistd::Pid,
44554 -+ local_iov: &[IoVec<&[u8]>],
44555 -+ remote_iov: &[RemoteIoVec]) -> Result<usize>
44556 -+{
44557 - let res = unsafe {
44558 - libc::process_vm_writev(pid.into(),
44559 - local_iov.as_ptr() as *const libc::iovec, local_iov.len() as libc::c_ulong,
44560 -@@ -148,7 +152,11 @@ pub fn process_vm_writev(pid: ::unistd::Pid, local_iov: &[IoVec<&[u8]>], remote_
44561 - /// [`IoVec`]: struct.IoVec.html
44562 - /// [`RemoteIoVec`]: struct.RemoteIoVec.html
44563 - #[cfg(any(target_os = "linux"))]
44564 --pub fn process_vm_readv(pid: ::unistd::Pid, local_iov: &[IoVec<&mut [u8]>], remote_iov: &[RemoteIoVec]) -> Result<usize> {
44565 -+pub fn process_vm_readv(
44566 -+ pid: crate::unistd::Pid,
44567 -+ local_iov: &[IoVec<&mut [u8]>],
44568 -+ remote_iov: &[RemoteIoVec]) -> Result<usize>
44569 -+{
44570 - let res = unsafe {
44571 - libc::process_vm_readv(pid.into(),
44572 - local_iov.as_ptr() as *const libc::iovec, local_iov.len() as libc::c_ulong,
44573 -@@ -158,7 +166,7 @@ pub fn process_vm_readv(pid: ::unistd::Pid, local_iov: &[IoVec<&mut [u8]>], remo
44574 - Errno::result(res).map(|r| r as usize)
44575 - }
44576 -
44577 --#[repr(C)]
44578 -+#[repr(transparent)]
44579 - #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
44580 - pub struct IoVec<T>(libc::iovec, PhantomData<T>);
44581 -
44582 -diff --git a/third_party/rust/nix/src/sys/utsname.rs b/third_party/rust/nix/src/sys/utsname.rs
44583 -index ab09c7d23232a..bf1a814d6d863 100644
44584 ---- a/third_party/rust/nix/src/sys/utsname.rs
44585 -+++ b/third_party/rust/nix/src/sys/utsname.rs
44586 -@@ -3,8 +3,8 @@ use libc::{self, c_char};
44587 - use std::ffi::CStr;
44588 - use std::str::from_utf8_unchecked;
44589 -
44590 --#[repr(C)]
44591 - #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
44592 -+#[repr(transparent)]
44593 - pub struct UtsName(libc::utsname);
44594 -
44595 - impl UtsName {
44596 -@@ -31,9 +31,9 @@ impl UtsName {
44597 -
44598 - pub fn uname() -> UtsName {
44599 - unsafe {
44600 -- let mut ret: UtsName = mem::uninitialized();
44601 -- libc::uname(&mut ret.0);
44602 -- ret
44603 -+ let mut ret = mem::MaybeUninit::uninit();
44604 -+ libc::uname(ret.as_mut_ptr());
44605 -+ UtsName(ret.assume_init())
44606 - }
44607 - }
44608 -
44609 -diff --git a/third_party/rust/nix/src/sys/wait.rs b/third_party/rust/nix/src/sys/wait.rs
44610 -index c54f7ec579667..faf8543cb1589 100644
44611 ---- a/third_party/rust/nix/src/sys/wait.rs
44612 -+++ b/third_party/rust/nix/src/sys/wait.rs
44613 -@@ -1,9 +1,10 @@
44614 -+use crate::errno::Errno;
44615 -+use crate::sys::signal::Signal;
44616 -+use crate::unistd::Pid;
44617 -+use crate::Result;
44618 -+use cfg_if::cfg_if;
44619 - use libc::{self, c_int};
44620 --use Result;
44621 --use errno::Errno;
44622 --use unistd::Pid;
44623 --
44624 --use sys::signal::Signal;
44625 -+use std::convert::TryFrom;
44626 -
44627 - libc_bitflags!(
44628 - pub struct WaitPidFlag: c_int {
44629 -@@ -14,6 +15,7 @@ libc_bitflags!(
44630 - target_os = "haiku",
44631 - target_os = "ios",
44632 - target_os = "linux",
44633 -+ target_os = "redox",
44634 - target_os = "macos",
44635 - target_os = "netbsd"))]
44636 - WEXITED;
44637 -@@ -23,6 +25,7 @@ libc_bitflags!(
44638 - target_os = "haiku",
44639 - target_os = "ios",
44640 - target_os = "linux",
44641 -+ target_os = "redox",
44642 - target_os = "macos",
44643 - target_os = "netbsd"))]
44644 - WSTOPPED;
44645 -@@ -32,16 +35,17 @@ libc_bitflags!(
44646 - target_os = "haiku",
44647 - target_os = "ios",
44648 - target_os = "linux",
44649 -+ target_os = "redox",
44650 - target_os = "macos",
44651 - target_os = "netbsd"))]
44652 - WNOWAIT;
44653 - /// Don't wait on children of other threads in this group
44654 -- #[cfg(any(target_os = "android", target_os = "linux"))]
44655 -+ #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
44656 - __WNOTHREAD;
44657 - /// Wait on all children, regardless of type
44658 -- #[cfg(any(target_os = "android", target_os = "linux"))]
44659 -+ #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
44660 - __WALL;
44661 -- #[cfg(any(target_os = "android", target_os = "linux"))]
44662 -+ #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
44663 - __WCLONE;
44664 - }
44665 - );
44666 -@@ -104,8 +108,7 @@ impl WaitStatus {
44667 - pub fn pid(&self) -> Option<Pid> {
44668 - use self::WaitStatus::*;
44669 - match *self {
44670 -- Exited(p, _) | Signaled(p, _, _) |
44671 -- Stopped(p, _) | Continued(p) => Some(p),
44672 -+ Exited(p, _) | Signaled(p, _, _) | Stopped(p, _) | Continued(p) => Some(p),
44673 - StillAlive => None,
44674 - #[cfg(any(target_os = "android", target_os = "linux"))]
44675 - PtraceEvent(p, _, _) | PtraceSyscall(p) => Some(p),
44676 -@@ -114,31 +117,31 @@ impl WaitStatus {
44677 - }
44678 -
44679 - fn exited(status: i32) -> bool {
44680 -- unsafe { libc::WIFEXITED(status) }
44681 -+ libc::WIFEXITED(status)
44682 - }
44683 -
44684 - fn exit_status(status: i32) -> i32 {
44685 -- unsafe { libc::WEXITSTATUS(status) }
44686 -+ libc::WEXITSTATUS(status)
44687 - }
44688 -
44689 - fn signaled(status: i32) -> bool {
44690 -- unsafe { libc::WIFSIGNALED(status) }
44691 -+ libc::WIFSIGNALED(status)
44692 - }
44693 -
44694 - fn term_signal(status: i32) -> Result<Signal> {
44695 -- Signal::from_c_int(unsafe { libc::WTERMSIG(status) })
44696 -+ Signal::try_from(libc::WTERMSIG(status))
44697 - }
44698 -
44699 - fn dumped_core(status: i32) -> bool {
44700 -- unsafe { libc::WCOREDUMP(status) }
44701 -+ libc::WCOREDUMP(status)
44702 - }
44703 -
44704 - fn stopped(status: i32) -> bool {
44705 -- unsafe { libc::WIFSTOPPED(status) }
44706 -+ libc::WIFSTOPPED(status)
44707 - }
44708 -
44709 - fn stop_signal(status: i32) -> Result<Signal> {
44710 -- Signal::from_c_int(unsafe { libc::WSTOPSIG(status) })
44711 -+ Signal::try_from(libc::WSTOPSIG(status))
44712 - }
44713 -
44714 - #[cfg(any(target_os = "android", target_os = "linux"))]
44715 -@@ -147,7 +150,7 @@ fn syscall_stop(status: i32) -> bool {
44716 - // of delivering SIGTRAP | 0x80 as the signal number for syscall
44717 - // stops. This allows easily distinguishing syscall stops from
44718 - // genuine SIGTRAP signals.
44719 -- unsafe { libc::WSTOPSIG(status) == libc::SIGTRAP | 0x80 }
44720 -+ libc::WSTOPSIG(status) == libc::SIGTRAP | 0x80
44721 - }
44722 -
44723 - #[cfg(any(target_os = "android", target_os = "linux"))]
44724 -@@ -156,7 +159,7 @@ fn stop_additional(status: i32) -> c_int {
44725 - }
44726 -
44727 - fn continued(status: i32) -> bool {
44728 -- unsafe { libc::WIFCONTINUED(status) }
44729 -+ libc::WIFCONTINUED(status)
44730 - }
44731 -
44732 - impl WaitStatus {
44733 -@@ -222,7 +225,7 @@ pub fn waitpid<P: Into<Option<Pid>>>(pid: P, options: Option<WaitPidFlag>) -> Re
44734 -
44735 - let res = unsafe {
44736 - libc::waitpid(
44737 -- pid.into().unwrap_or(Pid::from_raw(-1)).into(),
44738 -+ pid.into().unwrap_or_else(|| Pid::from_raw(-1)).into(),
44739 - &mut status as *mut c_int,
44740 - option_bits,
44741 - )
44742 -diff --git a/third_party/rust/nix/src/time.rs b/third_party/rust/nix/src/time.rs
44743 -new file mode 100644
44744 -index 0000000000000..e6c3f8ded5a52
44745 ---- /dev/null
44746 -+++ b/third_party/rust/nix/src/time.rs
44747 -@@ -0,0 +1,260 @@
44748 -+use crate::sys::time::TimeSpec;
44749 -+#[cfg(any(
44750 -+ target_os = "freebsd",
44751 -+ target_os = "dragonfly",
44752 -+ target_os = "linux",
44753 -+ target_os = "android",
44754 -+ target_os = "emscripten",
44755 -+))]
44756 -+use crate::{unistd::Pid, Error};
44757 -+use crate::{Errno, Result};
44758 -+use libc::{self, clockid_t};
44759 -+use std::mem::MaybeUninit;
44760 -+
44761 -+/// Clock identifier
44762 -+///
44763 -+/// Newtype pattern around `clockid_t` (which is just alias). It pervents bugs caused by
44764 -+/// accidentally passing wrong value.
44765 -+#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
44766 -+pub struct ClockId(clockid_t);
44767 -+
44768 -+impl ClockId {
44769 -+ /// Creates `ClockId` from raw `clockid_t`
44770 -+ pub fn from_raw(clk_id: clockid_t) -> Self {
44771 -+ ClockId(clk_id)
44772 -+ }
44773 -+
44774 -+ /// Returns `ClockId` of a `pid` CPU-time clock
44775 -+ #[cfg(any(
44776 -+ target_os = "freebsd",
44777 -+ target_os = "dragonfly",
44778 -+ target_os = "linux",
44779 -+ target_os = "android",
44780 -+ target_os = "emscripten",
44781 -+ ))]
44782 -+ pub fn pid_cpu_clock_id(pid: Pid) -> Result<Self> {
44783 -+ clock_getcpuclockid(pid)
44784 -+ }
44785 -+
44786 -+ /// Returns resolution of the clock id
44787 -+ #[cfg(not(target_os = "redox"))]
44788 -+ pub fn res(self) -> Result<TimeSpec> {
44789 -+ clock_getres(self)
44790 -+ }
44791 -+
44792 -+ /// Returns the current time on the clock id
44793 -+ pub fn now(self) -> Result<TimeSpec> {
44794 -+ clock_gettime(self)
44795 -+ }
44796 -+
44797 -+ /// Sets time to `timespec` on the clock id
44798 -+ #[cfg(not(any(
44799 -+ target_os = "macos",
44800 -+ target_os = "ios",
44801 -+ all(
44802 -+ not(any(target_env = "uclibc", target_env = "newlibc")),
44803 -+ any(target_os = "redox", target_os = "hermit",),
44804 -+ ),
44805 -+ )))]
44806 -+ pub fn set_time(self, timespec: TimeSpec) -> Result<()> {
44807 -+ clock_settime(self, timespec)
44808 -+ }
44809 -+
44810 -+ /// Gets the raw `clockid_t` wrapped by `self`
44811 -+ pub fn as_raw(self) -> clockid_t {
44812 -+ self.0
44813 -+ }
44814 -+
44815 -+ #[cfg(any(
44816 -+ target_os = "fuchsia",
44817 -+ all(
44818 -+ not(any(target_env = "uclibc", target_env = "newlib")),
44819 -+ any(target_os = "linux", target_os = "android", target_os = "emscripten"),
44820 -+ )
44821 -+ ))]
44822 -+ pub const CLOCK_BOOTTIME: ClockId = ClockId(libc::CLOCK_BOOTTIME);
44823 -+ #[cfg(any(
44824 -+ target_os = "fuchsia",
44825 -+ all(
44826 -+ not(any(target_env = "uclibc", target_env = "newlib")),
44827 -+ any(target_os = "linux", target_os = "android", target_os = "emscripten")
44828 -+ )
44829 -+ ))]
44830 -+ pub const CLOCK_BOOTTIME_ALARM: ClockId = ClockId(libc::CLOCK_BOOTTIME_ALARM);
44831 -+ pub const CLOCK_MONOTONIC: ClockId = ClockId(libc::CLOCK_MONOTONIC);
44832 -+ #[cfg(any(
44833 -+ target_os = "fuchsia",
44834 -+ all(
44835 -+ not(any(target_env = "uclibc", target_env = "newlib")),
44836 -+ any(target_os = "linux", target_os = "android", target_os = "emscripten")
44837 -+ )
44838 -+ ))]
44839 -+ pub const CLOCK_MONOTONIC_COARSE: ClockId = ClockId(libc::CLOCK_MONOTONIC_COARSE);
44840 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
44841 -+ pub const CLOCK_MONOTONIC_FAST: ClockId = ClockId(libc::CLOCK_MONOTONIC_FAST);
44842 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
44843 -+ pub const CLOCK_MONOTONIC_PRECISE: ClockId = ClockId(libc::CLOCK_MONOTONIC_PRECISE);
44844 -+ #[cfg(any(
44845 -+ target_os = "fuchsia",
44846 -+ all(
44847 -+ not(any(target_env = "uclibc", target_env = "newlib")),
44848 -+ any(target_os = "linux", target_os = "android", target_os = "emscripten")
44849 -+ )
44850 -+ ))]
44851 -+ pub const CLOCK_MONOTONIC_RAW: ClockId = ClockId(libc::CLOCK_MONOTONIC_RAW);
44852 -+ #[cfg(any(
44853 -+ target_os = "fuchsia",
44854 -+ target_env = "uclibc",
44855 -+ target_os = "macos",
44856 -+ target_os = "ios",
44857 -+ target_os = "freebsd",
44858 -+ target_os = "dragonfly",
44859 -+ all(
44860 -+ not(target_env = "newlib"),
44861 -+ any(target_os = "linux", target_os = "android", target_os = "emscripten")
44862 -+ )
44863 -+ ))]
44864 -+ pub const CLOCK_PROCESS_CPUTIME_ID: ClockId = ClockId(libc::CLOCK_PROCESS_CPUTIME_ID);
44865 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
44866 -+ pub const CLOCK_PROF: ClockId = ClockId(libc::CLOCK_PROF);
44867 -+ pub const CLOCK_REALTIME: ClockId = ClockId(libc::CLOCK_REALTIME);
44868 -+ #[cfg(any(
44869 -+ target_os = "fuchsia",
44870 -+ all(
44871 -+ not(any(target_env = "uclibc", target_env = "newlib")),
44872 -+ any(target_os = "linux", target_os = "android", target_os = "emscripten")
44873 -+ )
44874 -+ ))]
44875 -+ pub const CLOCK_REALTIME_ALARM: ClockId = ClockId(libc::CLOCK_REALTIME_ALARM);
44876 -+ #[cfg(any(
44877 -+ target_os = "fuchsia",
44878 -+ all(
44879 -+ not(any(target_env = "uclibc", target_env = "newlib")),
44880 -+ any(target_os = "linux", target_os = "android", target_os = "emscripten")
44881 -+ )
44882 -+ ))]
44883 -+ pub const CLOCK_REALTIME_COARSE: ClockId = ClockId(libc::CLOCK_REALTIME_COARSE);
44884 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
44885 -+ pub const CLOCK_REALTIME_FAST: ClockId = ClockId(libc::CLOCK_REALTIME_FAST);
44886 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
44887 -+ pub const CLOCK_REALTIME_PRECISE: ClockId = ClockId(libc::CLOCK_REALTIME_PRECISE);
44888 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
44889 -+ pub const CLOCK_SECOND: ClockId = ClockId(libc::CLOCK_SECOND);
44890 -+ #[cfg(any(
44891 -+ target_os = "fuchsia",
44892 -+ all(
44893 -+ not(any(target_env = "uclibc", target_env = "newlib")),
44894 -+ any(
44895 -+ target_os = "emscripten",
44896 -+ all(target_os = "linux", target_env = "musl")
44897 -+ )
44898 -+ )
44899 -+ ))]
44900 -+ pub const CLOCK_SGI_CYCLE: ClockId = ClockId(libc::CLOCK_SGI_CYCLE);
44901 -+ #[cfg(any(
44902 -+ target_os = "fuchsia",
44903 -+ all(
44904 -+ not(any(target_env = "uclibc", target_env = "newlib")),
44905 -+ any(
44906 -+ target_os = "emscripten",
44907 -+ all(target_os = "linux", target_env = "musl")
44908 -+ )
44909 -+ )
44910 -+ ))]
44911 -+ pub const CLOCK_TAI: ClockId = ClockId(libc::CLOCK_TAI);
44912 -+ #[cfg(any(
44913 -+ target_env = "uclibc",
44914 -+ target_os = "fuchsia",
44915 -+ target_os = "ios",
44916 -+ target_os = "macos",
44917 -+ target_os = "freebsd",
44918 -+ target_os = "dragonfly",
44919 -+ all(
44920 -+ not(target_env = "newlib"),
44921 -+ any(target_os = "linux", target_os = "android", target_os = "emscripten",),
44922 -+ ),
44923 -+ ))]
44924 -+ pub const CLOCK_THREAD_CPUTIME_ID: ClockId = ClockId(libc::CLOCK_THREAD_CPUTIME_ID);
44925 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
44926 -+ pub const CLOCK_UPTIME: ClockId = ClockId(libc::CLOCK_UPTIME);
44927 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
44928 -+ pub const CLOCK_UPTIME_FAST: ClockId = ClockId(libc::CLOCK_UPTIME_FAST);
44929 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
44930 -+ pub const CLOCK_UPTIME_PRECISE: ClockId = ClockId(libc::CLOCK_UPTIME_PRECISE);
44931 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
44932 -+ pub const CLOCK_VIRTUAL: ClockId = ClockId(libc::CLOCK_VIRTUAL);
44933 -+}
44934 -+
44935 -+impl Into<clockid_t> for ClockId {
44936 -+ fn into(self) -> clockid_t {
44937 -+ self.as_raw()
44938 -+ }
44939 -+}
44940 -+
44941 -+impl From<clockid_t> for ClockId {
44942 -+ fn from(clk_id: clockid_t) -> Self {
44943 -+ ClockId::from_raw(clk_id)
44944 -+ }
44945 -+}
44946 -+
44947 -+impl std::fmt::Display for ClockId {
44948 -+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
44949 -+ std::fmt::Display::fmt(&self.0, f)
44950 -+ }
44951 -+}
44952 -+
44953 -+/// Get the resolution of the specified clock, (see
44954 -+/// [clock_getres(2)](https://pubs.opengroup.org/onlinepubs/7908799/xsh/clock_getres.html)).
44955 -+#[cfg(not(target_os = "redox"))]
44956 -+pub fn clock_getres(clock_id: ClockId) -> Result<TimeSpec> {
44957 -+ let mut c_time: MaybeUninit<libc::timespec> = MaybeUninit::uninit();
44958 -+ let ret = unsafe { libc::clock_getres(clock_id.as_raw(), c_time.as_mut_ptr()) };
44959 -+ Errno::result(ret)?;
44960 -+ let res = unsafe { c_time.assume_init() };
44961 -+ Ok(TimeSpec::from(res))
44962 -+}
44963 -+
44964 -+/// Get the time of the specified clock, (see
44965 -+/// [clock_gettime(2)](https://pubs.opengroup.org/onlinepubs/7908799/xsh/clock_gettime.html)).
44966 -+pub fn clock_gettime(clock_id: ClockId) -> Result<TimeSpec> {
44967 -+ let mut c_time: MaybeUninit<libc::timespec> = MaybeUninit::uninit();
44968 -+ let ret = unsafe { libc::clock_gettime(clock_id.as_raw(), c_time.as_mut_ptr()) };
44969 -+ Errno::result(ret)?;
44970 -+ let res = unsafe { c_time.assume_init() };
44971 -+ Ok(TimeSpec::from(res))
44972 -+}
44973 -+
44974 -+/// Set the time of the specified clock, (see
44975 -+/// [clock_settime(2)](https://pubs.opengroup.org/onlinepubs/7908799/xsh/clock_settime.html)).
44976 -+#[cfg(not(any(
44977 -+ target_os = "macos",
44978 -+ target_os = "ios",
44979 -+ all(
44980 -+ not(any(target_env = "uclibc", target_env = "newlibc")),
44981 -+ any(target_os = "redox", target_os = "hermit",),
44982 -+ ),
44983 -+)))]
44984 -+pub fn clock_settime(clock_id: ClockId, timespec: TimeSpec) -> Result<()> {
44985 -+ let ret = unsafe { libc::clock_settime(clock_id.as_raw(), timespec.as_ref()) };
44986 -+ Errno::result(ret).map(drop)
44987 -+}
44988 -+
44989 -+/// Get the clock id of the specified process id, (see
44990 -+/// [clock_getcpuclockid(3)](https://pubs.opengroup.org/onlinepubs/009695399/functions/clock_getcpuclockid.html)).
44991 -+#[cfg(any(
44992 -+ target_os = "freebsd",
44993 -+ target_os = "dragonfly",
44994 -+ target_os = "linux",
44995 -+ target_os = "android",
44996 -+ target_os = "emscripten",
44997 -+))]
44998 -+pub fn clock_getcpuclockid(pid: Pid) -> Result<ClockId> {
44999 -+ let mut clk_id: MaybeUninit<libc::clockid_t> = MaybeUninit::uninit();
45000 -+ let ret = unsafe { libc::clock_getcpuclockid(pid.into(), clk_id.as_mut_ptr()) };
45001 -+ if ret == 0 {
45002 -+ let res = unsafe { clk_id.assume_init() };
45003 -+ Ok(ClockId::from(res))
45004 -+ } else {
45005 -+ Err(Error::Sys(Errno::from_i32(ret)))
45006 -+ }
45007 -+}
45008 -diff --git a/third_party/rust/nix/src/ucontext.rs b/third_party/rust/nix/src/ucontext.rs
45009 -index 5e10e7d1f8934..a5b8cc75cb330 100644
45010 ---- a/third_party/rust/nix/src/ucontext.rs
45011 -+++ b/third_party/rust/nix/src/ucontext.rs
45012 -@@ -1,10 +1,11 @@
45013 - use libc;
45014 - #[cfg(not(target_env = "musl"))]
45015 --use Result;
45016 -+use crate::Result;
45017 -+#[cfg(not(target_env = "musl"))]
45018 -+use crate::errno::Errno;
45019 - #[cfg(not(target_env = "musl"))]
45020 --use errno::Errno;
45021 - use std::mem;
45022 --use sys::signal::SigSet;
45023 -+use crate::sys::signal::SigSet;
45024 -
45025 - #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
45026 - pub struct UContext {
45027 -@@ -14,11 +15,11 @@ pub struct UContext {
45028 - impl UContext {
45029 - #[cfg(not(target_env = "musl"))]
45030 - pub fn get() -> Result<UContext> {
45031 -- let mut context: libc::ucontext_t = unsafe { mem::uninitialized() };
45032 -- let res = unsafe {
45033 -- libc::getcontext(&mut context as *mut libc::ucontext_t)
45034 -- };
45035 -- Errno::result(res).map(|_| UContext { context: context })
45036 -+ let mut context = mem::MaybeUninit::<libc::ucontext_t>::uninit();
45037 -+ let res = unsafe { libc::getcontext(context.as_mut_ptr()) };
45038 -+ Errno::result(res).map(|_| unsafe {
45039 -+ UContext { context: context.assume_init()}
45040 -+ })
45041 - }
45042 -
45043 - #[cfg(not(target_env = "musl"))]
45044 -@@ -30,10 +31,14 @@ impl UContext {
45045 - }
45046 -
45047 - pub fn sigmask_mut(&mut self) -> &mut SigSet {
45048 -- unsafe { mem::transmute(&mut self.context.uc_sigmask) }
45049 -+ unsafe {
45050 -+ &mut *(&mut self.context.uc_sigmask as *mut libc::sigset_t as *mut SigSet)
45051 -+ }
45052 - }
45053 -
45054 - pub fn sigmask(&self) -> &SigSet {
45055 -- unsafe { mem::transmute(&self.context.uc_sigmask) }
45056 -+ unsafe {
45057 -+ &*(&self.context.uc_sigmask as *const libc::sigset_t as *const SigSet)
45058 -+ }
45059 - }
45060 - }
45061 -diff --git a/third_party/rust/nix/src/unistd.rs b/third_party/rust/nix/src/unistd.rs
45062 -index f422f09198655..59cb1ed8b5901 100644
45063 ---- a/third_party/rust/nix/src/unistd.rs
45064 -+++ b/third_party/rust/nix/src/unistd.rs
45065 -@@ -1,18 +1,26 @@
45066 - //! Safe wrappers around functions found in libc "unistd.h" header
45067 -
45068 --use errno::{self, Errno};
45069 --use {Error, Result, NixPath};
45070 --use fcntl::{AtFlags, at_rawfd, fcntl, FdFlag, OFlag};
45071 --use fcntl::FcntlArg::F_SETFD;
45072 -+#[cfg(not(target_os = "redox"))]
45073 -+use cfg_if::cfg_if;
45074 -+use crate::errno::{self, Errno};
45075 -+use crate::{Error, Result, NixPath};
45076 -+#[cfg(not(target_os = "redox"))]
45077 -+use crate::fcntl::{AtFlags, at_rawfd};
45078 -+use crate::fcntl::{FdFlag, OFlag, fcntl};
45079 -+use crate::fcntl::FcntlArg::F_SETFD;
45080 - use libc::{self, c_char, c_void, c_int, c_long, c_uint, size_t, pid_t, off_t,
45081 -- uid_t, gid_t, mode_t};
45082 -+ uid_t, gid_t, mode_t, PATH_MAX};
45083 - use std::{fmt, mem, ptr};
45084 --use std::ffi::{CString, CStr, OsString, OsStr};
45085 --use std::os::unix::ffi::{OsStringExt, OsStrExt};
45086 -+use std::convert::Infallible;
45087 -+use std::ffi::{CStr, OsString};
45088 -+#[cfg(not(target_os = "redox"))]
45089 -+use std::ffi::{CString, OsStr};
45090 -+use std::os::unix::ffi::OsStringExt;
45091 -+#[cfg(not(target_os = "redox"))]
45092 -+use std::os::unix::ffi::OsStrExt;
45093 - use std::os::unix::io::RawFd;
45094 - use std::path::PathBuf;
45095 --use void::Void;
45096 --use sys::stat::Mode;
45097 -+use crate::sys::stat::Mode;
45098 -
45099 - #[cfg(any(target_os = "android", target_os = "linux"))]
45100 - pub use self::pivot_root::*;
45101 -@@ -45,12 +53,12 @@ impl Uid {
45102 - }
45103 -
45104 - /// Returns true if the `Uid` represents privileged user - root. (If it equals zero.)
45105 -- pub fn is_root(&self) -> bool {
45106 -- *self == ROOT
45107 -+ pub fn is_root(self) -> bool {
45108 -+ self == ROOT
45109 - }
45110 -
45111 - /// Get the raw `uid_t` wrapped by `self`.
45112 -- pub fn as_raw(&self) -> uid_t {
45113 -+ pub fn as_raw(self) -> uid_t {
45114 - self.0
45115 - }
45116 - }
45117 -@@ -88,13 +96,13 @@ impl Gid {
45118 - getgid()
45119 - }
45120 -
45121 -- /// Returns effective Gid of calling process. This is practically a more Rusty alias for `getgid`.
45122 -+ /// Returns effective Gid of calling process. This is practically a more Rusty alias for `getegid`.
45123 - pub fn effective() -> Self {
45124 - getegid()
45125 - }
45126 -
45127 - /// Get the raw `gid_t` wrapped by `self`.
45128 -- pub fn as_raw(&self) -> gid_t {
45129 -+ pub fn as_raw(self) -> gid_t {
45130 - self.0
45131 - }
45132 - }
45133 -@@ -115,7 +123,7 @@ impl fmt::Display for Gid {
45134 - ///
45135 - /// Newtype pattern around `pid_t` (which is just alias). It prevents bugs caused by accidentally
45136 - /// passing wrong value.
45137 --#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
45138 -+#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
45139 - pub struct Pid(pid_t);
45140 -
45141 - impl Pid {
45142 -@@ -135,7 +143,7 @@ impl Pid {
45143 - }
45144 -
45145 - /// Get the raw `pid_t` wrapped by `self`.
45146 -- pub fn as_raw(&self) -> pid_t {
45147 -+ pub fn as_raw(self) -> pid_t {
45148 - self.0
45149 - }
45150 - }
45151 -@@ -168,8 +176,8 @@ impl ForkResult {
45152 -
45153 - /// Return `true` if this is the child process of the `fork()`
45154 - #[inline]
45155 -- pub fn is_child(&self) -> bool {
45156 -- match *self {
45157 -+ pub fn is_child(self) -> bool {
45158 -+ match self {
45159 - ForkResult::Child => true,
45160 - _ => false
45161 - }
45162 -@@ -177,7 +185,7 @@ impl ForkResult {
45163 -
45164 - /// Returns `true` if this is the parent process of the `fork()`
45165 - #[inline]
45166 -- pub fn is_parent(&self) -> bool {
45167 -+ pub fn is_parent(self) -> bool {
45168 - !self.is_child()
45169 - }
45170 - }
45171 -@@ -192,7 +200,7 @@ impl ForkResult {
45172 - /// ```no_run
45173 - /// use nix::unistd::{fork, ForkResult};
45174 - ///
45175 --/// match fork() {
45176 -+/// match unsafe{fork()} {
45177 - /// Ok(ForkResult::Parent { child, .. }) => {
45178 - /// println!("Continuing execution in parent process, new child has pid: {}", child);
45179 - /// }
45180 -@@ -222,9 +230,9 @@ impl ForkResult {
45181 - ///
45182 - /// [async-signal-safe]: http://man7.org/linux/man-pages/man7/signal-safety.7.html
45183 - #[inline]
45184 --pub fn fork() -> Result<ForkResult> {
45185 -+pub unsafe fn fork() -> Result<ForkResult> {
45186 - use self::ForkResult::*;
45187 -- let res = unsafe { libc::fork() };
45188 -+ let res = libc::fork();
45189 -
45190 - Errno::result(res).map(|res| match res {
45191 - 0 => Child,
45192 -@@ -285,6 +293,7 @@ pub fn setsid() -> Result<Pid> {
45193 - /// Obtain the process group ID of the process that is the session leader of the process specified
45194 - /// by pid. If pid is zero, it specifies the calling process.
45195 - #[inline]
45196 -+#[cfg(not(target_os = "redox"))]
45197 - pub fn getsid(pid: Option<Pid>) -> Result<Pid> {
45198 - let res = unsafe { libc::getsid(pid.unwrap_or(Pid(0)).into()) };
45199 - Errno::result(res).map(Pid)
45200 -@@ -417,6 +426,7 @@ pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> {
45201 - /// This function may fail in a number of different scenarios. See the man
45202 - /// pages for additional details on possible failure cases.
45203 - #[inline]
45204 -+#[cfg(not(target_os = "fuchsia"))]
45205 - pub fn fchdir(dirfd: RawFd) -> Result<()> {
45206 - let res = unsafe { libc::fchdir(dirfd) };
45207 -
45208 -@@ -436,9 +446,6 @@ pub fn fchdir(dirfd: RawFd) -> Result<()> {
45209 - /// # Example
45210 - ///
45211 - /// ```rust
45212 --/// extern crate tempfile;
45213 --/// extern crate nix;
45214 --///
45215 - /// use nix::unistd;
45216 - /// use nix::sys::stat;
45217 - /// use tempfile::tempdir;
45218 -@@ -479,9 +486,6 @@ pub fn mkdir<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
45219 - /// # Example
45220 - ///
45221 - /// ```rust
45222 --/// extern crate tempfile;
45223 --/// extern crate nix;
45224 --///
45225 - /// use nix::unistd;
45226 - /// use nix::sys::stat;
45227 - /// use tempfile::tempdir;
45228 -@@ -498,6 +502,7 @@ pub fn mkdir<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
45229 - /// }
45230 - /// ```
45231 - #[inline]
45232 -+#[cfg(not(target_os = "redox"))] // RedoxFS does not support fifo yet
45233 - pub fn mkfifo<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
45234 - let res = path.with_nix_path(|cstr| {
45235 - unsafe { libc::mkfifo(cstr.as_ptr(), mode.bits() as mode_t) }
45236 -@@ -506,6 +511,28 @@ pub fn mkfifo<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
45237 - Errno::result(res).map(drop)
45238 - }
45239 -
45240 -+/// Creates new fifo special file (named pipe) with path `path` and access rights `mode`.
45241 -+///
45242 -+/// If `dirfd` has a value, then `path` is relative to directory associated with the file descriptor.
45243 -+///
45244 -+/// If `dirfd` is `None`, then `path` is relative to the current working directory.
45245 -+///
45246 -+/// # References
45247 -+///
45248 -+/// [mkfifoat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifoat.html).
45249 -+// mkfifoat is not implemented in OSX or android
45250 -+#[inline]
45251 -+#[cfg(not(any(
45252 -+ target_os = "macos", target_os = "ios",
45253 -+ target_os = "android", target_os = "redox")))]
45254 -+pub fn mkfifoat<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P, mode: Mode) -> Result<()> {
45255 -+ let res = path.with_nix_path(|cstr| unsafe {
45256 -+ libc::mkfifoat(at_rawfd(dirfd), cstr.as_ptr(), mode.bits() as mode_t)
45257 -+ })?;
45258 -+
45259 -+ Errno::result(res).map(drop)
45260 -+}
45261 -+
45262 - /// Creates a symbolic link at `path2` which points to `path1`.
45263 - ///
45264 - /// If `dirfd` has a value, then `path2` is relative to directory associated
45265 -@@ -515,6 +542,7 @@ pub fn mkfifo<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
45266 - /// directory. This is identical to `libc::symlink(path1, path2)`.
45267 - ///
45268 - /// See also [symlinkat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/symlinkat.html).
45269 -+#[cfg(not(target_os = "redox"))]
45270 - pub fn symlinkat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
45271 - path1: &P1,
45272 - dirfd: Option<RawFd>,
45273 -@@ -534,6 +562,21 @@ pub fn symlinkat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
45274 - Errno::result(res).map(drop)
45275 - }
45276 -
45277 -+// Double the buffer capacity up to limit. In case it already has
45278 -+// reached the limit, return Errno::ERANGE.
45279 -+fn reserve_double_buffer_size<T>(buf: &mut Vec<T>, limit: usize) -> Result<()> {
45280 -+ use std::cmp::min;
45281 -+
45282 -+ if buf.capacity() >= limit {
45283 -+ return Err(Error::Sys(Errno::ERANGE))
45284 -+ }
45285 -+
45286 -+ let capacity = min(buf.capacity() * 2, limit);
45287 -+ buf.reserve(capacity);
45288 -+
45289 -+ Ok(())
45290 -+}
45291 -+
45292 - /// Returns the current directory as a `PathBuf`
45293 - ///
45294 - /// Err is returned if the current user doesn't have the permission to read or search a component
45295 -@@ -542,8 +585,6 @@ pub fn symlinkat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
45296 - /// # Example
45297 - ///
45298 - /// ```rust
45299 --/// extern crate nix;
45300 --///
45301 - /// use nix::unistd;
45302 - ///
45303 - /// fn main() {
45304 -@@ -576,11 +617,8 @@ pub fn getcwd() -> Result<PathBuf> {
45305 - }
45306 - }
45307 -
45308 -- // Trigger the internal buffer resizing logic of `Vec` by requiring
45309 -- // more space than the current capacity.
45310 -- let cap = buf.capacity();
45311 -- buf.set_len(cap);
45312 -- buf.reserve(1);
45313 -+ // Trigger the internal buffer resizing logic.
45314 -+ reserve_double_buffer_size(&mut buf, PATH_MAX as usize)?;
45315 - }
45316 - }
45317 - }
45318 -@@ -590,8 +628,10 @@ fn chown_raw_ids(owner: Option<Uid>, group: Option<Gid>) -> (libc::uid_t, libc::
45319 - // According to the POSIX specification, -1 is used to indicate that owner and group
45320 - // are not to be changed. Since uid_t and gid_t are unsigned types, we have to wrap
45321 - // around to get -1.
45322 -- let uid = owner.map(Into::into).unwrap_or((0 as uid_t).wrapping_sub(1));
45323 -- let gid = group.map(Into::into).unwrap_or((0 as gid_t).wrapping_sub(1));
45324 -+ let uid = owner.map(Into::into)
45325 -+ .unwrap_or_else(|| (0 as uid_t).wrapping_sub(1));
45326 -+ let gid = group.map(Into::into)
45327 -+ .unwrap_or_else(|| (0 as gid_t).wrapping_sub(1));
45328 - (uid, gid)
45329 - }
45330 -
45331 -@@ -612,6 +652,20 @@ pub fn chown<P: ?Sized + NixPath>(path: &P, owner: Option<Uid>, group: Option<Gi
45332 - Errno::result(res).map(drop)
45333 - }
45334 -
45335 -+/// Change the ownership of the file referred to by the open file descriptor `fd` to be owned by
45336 -+/// the specified `owner` (user) and `group` (see
45337 -+/// [fchown(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchown.html)).
45338 -+///
45339 -+/// The owner/group for the provided file will not be modified if `None` is
45340 -+/// provided for that argument. Ownership change will be attempted for the path
45341 -+/// only if `Some` owner/group is provided.
45342 -+#[inline]
45343 -+pub fn fchown(fd: RawFd, owner: Option<Uid>, group: Option<Gid>) -> Result<()> {
45344 -+ let (uid, gid) = chown_raw_ids(owner, group);
45345 -+ let res = unsafe { libc::fchown(fd, uid, gid) };
45346 -+ Errno::result(res).map(drop)
45347 -+}
45348 -+
45349 - /// Flags for `fchownat` function.
45350 - #[derive(Clone, Copy, Debug)]
45351 - pub enum FchownatFlags {
45352 -@@ -640,6 +694,7 @@ pub enum FchownatFlags {
45353 - /// # References
45354 - ///
45355 - /// [fchownat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchownat.html).
45356 -+#[cfg(not(target_os = "redox"))]
45357 - pub fn fchownat<P: ?Sized + NixPath>(
45358 - dirfd: Option<RawFd>,
45359 - path: &P,
45360 -@@ -661,10 +716,9 @@ pub fn fchownat<P: ?Sized + NixPath>(
45361 - Errno::result(res).map(drop)
45362 - }
45363 -
45364 --fn to_exec_array(args: &[CString]) -> Vec<*const c_char> {
45365 -- let mut args_p: Vec<*const c_char> = args.iter().map(|s| s.as_ptr()).collect();
45366 -- args_p.push(ptr::null());
45367 -- args_p
45368 -+fn to_exec_array<S: AsRef<CStr>>(args: &[S]) -> Vec<*const c_char> {
45369 -+ use std::iter::once;
45370 -+ args.iter().map(|s| s.as_ref().as_ptr()).chain(once(ptr::null())).collect()
45371 - }
45372 -
45373 - /// Replace the current process image with a new one (see
45374 -@@ -674,7 +728,7 @@ fn to_exec_array(args: &[CString]) -> Vec<*const c_char> {
45375 - /// performs the same action but does not allow for customization of the
45376 - /// environment for the new process.
45377 - #[inline]
45378 --pub fn execv(path: &CString, argv: &[CString]) -> Result<Void> {
45379 -+pub fn execv<S: AsRef<CStr>>(path: &CStr, argv: &[S]) -> Result<Infallible> {
45380 - let args_p = to_exec_array(argv);
45381 -
45382 - unsafe {
45383 -@@ -698,7 +752,7 @@ pub fn execv(path: &CString, argv: &[CString]) -> Result<Void> {
45384 - /// in the `args` list is an argument to the new process. Each element in the
45385 - /// `env` list should be a string in the form "key=value".
45386 - #[inline]
45387 --pub fn execve(path: &CString, args: &[CString], env: &[CString]) -> Result<Void> {
45388 -+pub fn execve<SA: AsRef<CStr>, SE: AsRef<CStr>>(path: &CStr, args: &[SA], env: &[SE]) -> Result<Infallible> {
45389 - let args_p = to_exec_array(args);
45390 - let env_p = to_exec_array(env);
45391 -
45392 -@@ -719,7 +773,7 @@ pub fn execve(path: &CString, args: &[CString], env: &[CString]) -> Result<Void>
45393 - /// would not work if "bash" was specified for the path argument, but `execvp`
45394 - /// would assuming that a bash executable was on the system `PATH`.
45395 - #[inline]
45396 --pub fn execvp(filename: &CString, args: &[CString]) -> Result<Void> {
45397 -+pub fn execvp<S: AsRef<CStr>>(filename: &CStr, args: &[S]) -> Result<Infallible> {
45398 - let args_p = to_exec_array(args);
45399 -
45400 - unsafe {
45401 -@@ -739,7 +793,7 @@ pub fn execvp(filename: &CString, args: &[CString]) -> Result<Void> {
45402 - #[cfg(any(target_os = "haiku",
45403 - target_os = "linux",
45404 - target_os = "openbsd"))]
45405 --pub fn execvpe(filename: &CString, args: &[CString], env: &[CString]) -> Result<Void> {
45406 -+pub fn execvpe<SA: AsRef<CStr>, SE: AsRef<CStr>>(filename: &CStr, args: &[SA], env: &[SE]) -> Result<Infallible> {
45407 - let args_p = to_exec_array(args);
45408 - let env_p = to_exec_array(env);
45409 -
45410 -@@ -767,7 +821,7 @@ pub fn execvpe(filename: &CString, args: &[CString], env: &[CString]) -> Result<
45411 - target_os = "linux",
45412 - target_os = "freebsd"))]
45413 - #[inline]
45414 --pub fn fexecve(fd: RawFd, args: &[CString], env: &[CString]) -> Result<Void> {
45415 -+pub fn fexecve<SA: AsRef<CStr> ,SE: AsRef<CStr>>(fd: RawFd, args: &[SA], env: &[SE]) -> Result<Infallible> {
45416 - let args_p = to_exec_array(args);
45417 - let env_p = to_exec_array(env);
45418 -
45419 -@@ -790,8 +844,8 @@ pub fn fexecve(fd: RawFd, args: &[CString], env: &[CString]) -> Result<Void> {
45420 - /// is referenced as a file descriptor to the base directory plus a path.
45421 - #[cfg(any(target_os = "android", target_os = "linux"))]
45422 - #[inline]
45423 --pub fn execveat(dirfd: RawFd, pathname: &CString, args: &[CString],
45424 -- env: &[CString], flags: super::fcntl::AtFlags) -> Result<Void> {
45425 -+pub fn execveat<SA: AsRef<CStr>,SE: AsRef<CStr>>(dirfd: RawFd, pathname: &CStr, args: &[SA],
45426 -+ env: &[SE], flags: super::fcntl::AtFlags) -> Result<Infallible> {
45427 - let args_p = to_exec_array(args);
45428 - let env_p = to_exec_array(env);
45429 -
45430 -@@ -828,11 +882,12 @@ pub fn execveat(dirfd: RawFd, pathname: &CString, args: &[CString],
45431 - /// descriptors will remain identical after daemonizing.
45432 - /// * `noclose = false`: The process' stdin, stdout, and stderr will point to
45433 - /// `/dev/null` after daemonizing.
45434 --#[cfg_attr(any(target_os = "macos", target_os = "ios"), deprecated(
45435 -- since="0.14.0",
45436 -- note="Deprecated in MacOSX 10.5"
45437 --))]
45438 --#[cfg_attr(any(target_os = "macos", target_os = "ios"), allow(deprecated))]
45439 -+#[cfg(any(target_os = "android",
45440 -+ target_os = "dragonfly",
45441 -+ target_os = "freebsd",
45442 -+ target_os = "linux",
45443 -+ target_os = "netbsd",
45444 -+ target_os = "openbsd"))]
45445 - pub fn daemon(nochdir: bool, noclose: bool) -> Result<()> {
45446 - let res = unsafe { libc::daemon(nochdir as c_int, noclose as c_int) };
45447 - Errno::result(res).map(drop)
45448 -@@ -845,6 +900,7 @@ pub fn daemon(nochdir: bool, noclose: bool) -> Result<()> {
45449 - /// On some systems, the host name is limited to as few as 64 bytes. An error
45450 - /// will be return if the name is not valid or the current process does not have
45451 - /// permissions to update the host name.
45452 -+#[cfg(not(target_os = "redox"))]
45453 - pub fn sethostname<S: AsRef<OsStr>>(name: S) -> Result<()> {
45454 - // Handle some differences in type of the len arg across platforms.
45455 - cfg_if! {
45456 -@@ -906,9 +962,6 @@ pub fn gethostname(buffer: &mut [u8]) -> Result<&CStr> {
45457 - /// # Examples
45458 - ///
45459 - /// ```no_run
45460 --/// extern crate tempfile;
45461 --/// extern crate nix;
45462 --///
45463 - /// use std::os::unix::io::AsRawFd;
45464 - /// use nix::unistd::close;
45465 - ///
45466 -@@ -919,9 +972,6 @@ pub fn gethostname(buffer: &mut [u8]) -> Result<&CStr> {
45467 - /// ```
45468 - ///
45469 - /// ```rust
45470 --/// extern crate tempfile;
45471 --/// extern crate nix;
45472 --///
45473 - /// use std::os::unix::io::IntoRawFd;
45474 - /// use nix::unistd::close;
45475 - ///
45476 -@@ -969,20 +1019,14 @@ pub enum Whence {
45477 - /// Specify an offset relative to the next location in the file greater than or
45478 - /// equal to offset that contains some data. If offset points to
45479 - /// some data, then the file offset is set to offset.
45480 -- #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
45481 -- all(target_os = "linux", not(any(target_env = "musl",
45482 -- target_arch = "mips",
45483 -- target_arch = "mips64")))))]
45484 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
45485 - SeekData = libc::SEEK_DATA,
45486 - /// Specify an offset relative to the next hole in the file greater than
45487 - /// or equal to offset. If offset points into the middle of a hole, then
45488 - /// the file offset should be set to offset. If there is no hole past offset,
45489 - /// then the file offset should be adjusted to the end of the file (i.e., there
45490 - /// is an implicit hole at the end of any file).
45491 -- #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
45492 -- all(target_os = "linux", not(any(target_env = "musl",
45493 -- target_arch = "mips",
45494 -- target_arch = "mips64")))))]
45495 -+ #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
45496 - SeekHole = libc::SEEK_HOLE
45497 - }
45498 -
45499 -@@ -1007,13 +1051,13 @@ pub fn lseek64(fd: RawFd, offset: libc::off64_t, whence: Whence) -> Result<libc:
45500 - /// See also [pipe(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pipe.html)
45501 - pub fn pipe() -> Result<(RawFd, RawFd)> {
45502 - unsafe {
45503 -- let mut fds: [c_int; 2] = mem::uninitialized();
45504 -+ let mut fds = mem::MaybeUninit::<[c_int; 2]>::uninit();
45505 -
45506 -- let res = libc::pipe(fds.as_mut_ptr());
45507 -+ let res = libc::pipe(fds.as_mut_ptr() as *mut c_int);
45508 -
45509 - Errno::result(res)?;
45510 -
45511 -- Ok((fds[0], fds[1]))
45512 -+ Ok((fds.assume_init()[0], fds.assume_init()[1]))
45513 - }
45514 - }
45515 -
45516 -@@ -1022,7 +1066,9 @@ pub fn pipe() -> Result<(RawFd, RawFd)> {
45517 - /// The following flags are supported, and will be set atomically as the pipe is
45518 - /// created:
45519 - ///
45520 --/// `O_CLOEXEC`: Set the close-on-exec flag for the new file descriptors.
45521 -+/// `O_CLOEXEC`: Set the close-on-exec flag for the new file descriptors.
45522 -+#[cfg_attr(target_os = "linux", doc = "`O_DIRECT`: Create a pipe that performs I/O in \"packet\" mode. ")]
45523 -+#[cfg_attr(target_os = "netbsd", doc = "`O_NOSIGPIPE`: Return `EPIPE` instead of raising `SIGPIPE`. ")]
45524 - /// `O_NONBLOCK`: Set the non-blocking flag for the ends of the pipe.
45525 - ///
45526 - /// See also [pipe(2)](http://man7.org/linux/man-pages/man2/pipe.2.html)
45527 -@@ -1031,74 +1077,26 @@ pub fn pipe() -> Result<(RawFd, RawFd)> {
45528 - target_os = "emscripten",
45529 - target_os = "freebsd",
45530 - target_os = "linux",
45531 -+ target_os = "redox",
45532 - target_os = "netbsd",
45533 - target_os = "openbsd"))]
45534 - pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
45535 -- let mut fds: [c_int; 2] = unsafe { mem::uninitialized() };
45536 --
45537 -- let res = unsafe { libc::pipe2(fds.as_mut_ptr(), flags.bits()) };
45538 --
45539 -- Errno::result(res)?;
45540 --
45541 -- Ok((fds[0], fds[1]))
45542 --}
45543 -+ let mut fds = mem::MaybeUninit::<[c_int; 2]>::uninit();
45544 -
45545 --/// Like `pipe`, but allows setting certain file descriptor flags.
45546 --///
45547 --/// The following flags are supported, and will be set after the pipe is
45548 --/// created:
45549 --///
45550 --/// `O_CLOEXEC`: Set the close-on-exec flag for the new file descriptors.
45551 --/// `O_NONBLOCK`: Set the non-blocking flag for the ends of the pipe.
45552 --#[cfg(any(target_os = "ios", target_os = "macos"))]
45553 --#[deprecated(
45554 -- since="0.10.0",
45555 -- note="pipe2(2) is not actually atomic on these platforms. Use pipe(2) and fcntl(2) instead"
45556 --)]
45557 --pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
45558 -- let mut fds: [c_int; 2] = unsafe { mem::uninitialized() };
45559 --
45560 -- let res = unsafe { libc::pipe(fds.as_mut_ptr()) };
45561 -+ let res = unsafe {
45562 -+ libc::pipe2(fds.as_mut_ptr() as *mut c_int, flags.bits())
45563 -+ };
45564 -
45565 - Errno::result(res)?;
45566 -
45567 -- pipe2_setflags(fds[0], fds[1], flags)?;
45568 --
45569 -- Ok((fds[0], fds[1]))
45570 --}
45571 --
45572 --#[cfg(any(target_os = "ios", target_os = "macos"))]
45573 --fn pipe2_setflags(fd1: RawFd, fd2: RawFd, flags: OFlag) -> Result<()> {
45574 -- use fcntl::FcntlArg::F_SETFL;
45575 --
45576 -- let mut res = Ok(0);
45577 --
45578 -- if flags.contains(OFlag::O_CLOEXEC) {
45579 -- res = res
45580 -- .and_then(|_| fcntl(fd1, F_SETFD(FdFlag::FD_CLOEXEC)))
45581 -- .and_then(|_| fcntl(fd2, F_SETFD(FdFlag::FD_CLOEXEC)));
45582 -- }
45583 --
45584 -- if flags.contains(OFlag::O_NONBLOCK) {
45585 -- res = res
45586 -- .and_then(|_| fcntl(fd1, F_SETFL(OFlag::O_NONBLOCK)))
45587 -- .and_then(|_| fcntl(fd2, F_SETFL(OFlag::O_NONBLOCK)));
45588 -- }
45589 --
45590 -- match res {
45591 -- Ok(_) => Ok(()),
45592 -- Err(e) => {
45593 -- let _ = close(fd1);
45594 -- let _ = close(fd2);
45595 -- Err(e)
45596 -- }
45597 -- }
45598 -+ unsafe { Ok((fds.assume_init()[0], fds.assume_init()[1])) }
45599 - }
45600 -
45601 - /// Truncate a file to a specified length
45602 - ///
45603 - /// See also
45604 - /// [truncate(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html)
45605 -+#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
45606 - pub fn truncate<P: ?Sized + NixPath>(path: &P, len: off_t) -> Result<()> {
45607 - let res = path.with_nix_path(|cstr| {
45608 - unsafe {
45609 -@@ -1132,6 +1130,59 @@ pub fn isatty(fd: RawFd) -> Result<bool> {
45610 - }
45611 - }
45612 -
45613 -+/// Flags for `linkat` function.
45614 -+#[derive(Clone, Copy, Debug)]
45615 -+pub enum LinkatFlags {
45616 -+ SymlinkFollow,
45617 -+ NoSymlinkFollow,
45618 -+}
45619 -+
45620 -+/// Link one file to another file
45621 -+///
45622 -+/// Creates a new link (directory entry) at `newpath` for the existing file at `oldpath`. In the
45623 -+/// case of a relative `oldpath`, the path is interpreted relative to the directory associated
45624 -+/// with file descriptor `olddirfd` instead of the current working directory and similiarly for
45625 -+/// `newpath` and file descriptor `newdirfd`. In case `flag` is LinkatFlags::SymlinkFollow and
45626 -+/// `oldpath` names a symoblic link, a new link for the target of the symbolic link is created.
45627 -+/// If either `olddirfd` or `newdirfd` is `None`, `AT_FDCWD` is used respectively where `oldpath`
45628 -+/// and/or `newpath` is then interpreted relative to the current working directory of the calling
45629 -+/// process. If either `oldpath` or `newpath` is absolute, then `dirfd` is ignored.
45630 -+///
45631 -+/// # References
45632 -+/// See also [linkat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/linkat.html)
45633 -+#[cfg(not(target_os = "redox"))] // RedoxFS does not support symlinks yet
45634 -+pub fn linkat<P: ?Sized + NixPath>(
45635 -+ olddirfd: Option<RawFd>,
45636 -+ oldpath: &P,
45637 -+ newdirfd: Option<RawFd>,
45638 -+ newpath: &P,
45639 -+ flag: LinkatFlags,
45640 -+) -> Result<()> {
45641 -+
45642 -+ let atflag =
45643 -+ match flag {
45644 -+ LinkatFlags::SymlinkFollow => AtFlags::AT_SYMLINK_FOLLOW,
45645 -+ LinkatFlags::NoSymlinkFollow => AtFlags::empty(),
45646 -+ };
45647 -+
45648 -+ let res =
45649 -+ oldpath.with_nix_path(|oldcstr| {
45650 -+ newpath.with_nix_path(|newcstr| {
45651 -+ unsafe {
45652 -+ libc::linkat(
45653 -+ at_rawfd(olddirfd),
45654 -+ oldcstr.as_ptr(),
45655 -+ at_rawfd(newdirfd),
45656 -+ newcstr.as_ptr(),
45657 -+ atflag.bits() as libc::c_int
45658 -+ )
45659 -+ }
45660 -+ })
45661 -+ })??;
45662 -+ Errno::result(res).map(drop)
45663 -+}
45664 -+
45665 -+
45666 - /// Remove a directory entry
45667 - ///
45668 - /// See also [unlink(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html)
45669 -@@ -1161,6 +1212,7 @@ pub enum UnlinkatFlags {
45670 - ///
45671 - /// # References
45672 - /// See also [unlinkat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlinkat.html)
45673 -+#[cfg(not(target_os = "redox"))]
45674 - pub fn unlinkat<P: ?Sized + NixPath>(
45675 - dirfd: Option<RawFd>,
45676 - path: &P,
45677 -@@ -1181,6 +1233,7 @@ pub fn unlinkat<P: ?Sized + NixPath>(
45678 -
45679 -
45680 - #[inline]
45681 -+#[cfg(not(target_os = "fuchsia"))]
45682 - pub fn chroot<P: ?Sized + NixPath>(path: &P) -> Result<()> {
45683 - let res = path.with_nix_path(|cstr| {
45684 - unsafe { libc::chroot(cstr.as_ptr()) }
45685 -@@ -1199,7 +1252,7 @@ pub fn chroot<P: ?Sized + NixPath>(path: &P) -> Result<()> {
45686 - target_os = "netbsd",
45687 - target_os = "openbsd"
45688 - ))]
45689 --pub fn sync() -> () {
45690 -+pub fn sync() {
45691 - unsafe { libc::sync() };
45692 - }
45693 -
45694 -@@ -1309,6 +1362,28 @@ pub fn setgid(gid: Gid) -> Result<()> {
45695 - Errno::result(res).map(drop)
45696 - }
45697 -
45698 -+/// Set the user identity used for filesystem checks per-thread.
45699 -+/// On both success and failure, this call returns the previous filesystem user
45700 -+/// ID of the caller.
45701 -+///
45702 -+/// See also [setfsuid(2)](http://man7.org/linux/man-pages/man2/setfsuid.2.html)
45703 -+#[cfg(any(target_os = "linux", target_os = "android"))]
45704 -+pub fn setfsuid(uid: Uid) -> Uid {
45705 -+ let prev_fsuid = unsafe { libc::setfsuid(uid.into()) };
45706 -+ Uid::from_raw(prev_fsuid as uid_t)
45707 -+}
45708 -+
45709 -+/// Set the group identity used for filesystem checks per-thread.
45710 -+/// On both success and failure, this call returns the previous filesystem group
45711 -+/// ID of the caller.
45712 -+///
45713 -+/// See also [setfsgid(2)](http://man7.org/linux/man-pages/man2/setfsgid.2.html)
45714 -+#[cfg(any(target_os = "linux", target_os = "android"))]
45715 -+pub fn setfsgid(gid: Gid) -> Gid {
45716 -+ let prev_fsgid = unsafe { libc::setfsgid(gid.into()) };
45717 -+ Gid::from_raw(prev_fsgid as gid_t)
45718 -+}
45719 -+
45720 - /// Get the list of supplementary group IDs of the calling process.
45721 - ///
45722 - /// [Further reading](http://pubs.opengroup.org/onlinepubs/009695399/functions/getgroups.html)
45723 -@@ -1318,33 +1393,39 @@ pub fn setgid(gid: Gid) -> Result<()> {
45724 - /// with the `opendirectoryd` service.
45725 - #[cfg(not(any(target_os = "ios", target_os = "macos")))]
45726 - pub fn getgroups() -> Result<Vec<Gid>> {
45727 -- // First get the number of groups so we can size our Vec
45728 -- let ret = unsafe { libc::getgroups(0, ptr::null_mut()) };
45729 -+ // First get the maximum number of groups. The value returned
45730 -+ // shall always be greater than or equal to one and less than or
45731 -+ // equal to the value of {NGROUPS_MAX} + 1.
45732 -+ let ngroups_max = match sysconf(SysconfVar::NGROUPS_MAX) {
45733 -+ Ok(Some(n)) => (n + 1) as usize,
45734 -+ Ok(None) | Err(_) => <usize>::max_value(),
45735 -+ };
45736 -+
45737 -+ // Next, get the number of groups so we can size our Vec
45738 -+ let ngroups = unsafe { libc::getgroups(0, ptr::null_mut()) };
45739 -
45740 - // Now actually get the groups. We try multiple times in case the number of
45741 - // groups has changed since the first call to getgroups() and the buffer is
45742 - // now too small.
45743 -- let mut groups = Vec::<Gid>::with_capacity(Errno::result(ret)? as usize);
45744 -+ let mut groups = Vec::<Gid>::with_capacity(Errno::result(ngroups)? as usize);
45745 - loop {
45746 - // FIXME: On the platforms we currently support, the `Gid` struct has
45747 - // the same representation in memory as a bare `gid_t`. This is not
45748 - // necessarily the case on all Rust platforms, though. See RFC 1785.
45749 -- let ret = unsafe {
45750 -+ let ngroups = unsafe {
45751 - libc::getgroups(groups.capacity() as c_int, groups.as_mut_ptr() as *mut gid_t)
45752 - };
45753 -
45754 -- match Errno::result(ret) {
45755 -+ match Errno::result(ngroups) {
45756 - Ok(s) => {
45757 - unsafe { groups.set_len(s as usize) };
45758 - return Ok(groups);
45759 - },
45760 - Err(Error::Sys(Errno::EINVAL)) => {
45761 -- // EINVAL indicates that the buffer size was too small. Trigger
45762 -- // the internal buffer resizing logic of `Vec` by requiring
45763 -- // more space than the current capacity.
45764 -- let cap = groups.capacity();
45765 -- unsafe { groups.set_len(cap) };
45766 -- groups.reserve(1);
45767 -+ // EINVAL indicates that the buffer size was too
45768 -+ // small, resize it up to ngroups_max as limit.
45769 -+ reserve_double_buffer_size(&mut groups, ngroups_max)
45770 -+ .or(Err(Error::Sys(Errno::EINVAL)))?;
45771 - },
45772 - Err(e) => return Err(e)
45773 - }
45774 -@@ -1380,11 +1461,9 @@ pub fn getgroups() -> Result<Vec<Gid>> {
45775 - /// # Ok(())
45776 - /// # }
45777 - /// #
45778 --/// # fn main() {
45779 --/// # try_main().unwrap();
45780 --/// # }
45781 -+/// # try_main().unwrap();
45782 - /// ```
45783 --#[cfg(not(any(target_os = "ios", target_os = "macos")))]
45784 -+#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))]
45785 - pub fn setgroups(groups: &[Gid]) -> Result<()> {
45786 - cfg_if! {
45787 - if #[cfg(any(target_os = "dragonfly",
45788 -@@ -1428,15 +1507,14 @@ pub fn setgroups(groups: &[Gid]) -> Result<()> {
45789 - /// and `setgroups()`. Additionally, while some implementations will return a
45790 - /// partial list of groups when `NGROUPS_MAX` is exceeded, this implementation
45791 - /// will only ever return the complete list or else an error.
45792 --#[cfg(not(any(target_os = "ios", target_os = "macos")))]
45793 -+#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))]
45794 - pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
45795 - let ngroups_max = match sysconf(SysconfVar::NGROUPS_MAX) {
45796 - Ok(Some(n)) => n as c_int,
45797 - Ok(None) | Err(_) => <c_int>::max_value(),
45798 - };
45799 - use std::cmp::min;
45800 -- let mut ngroups = min(ngroups_max, 8);
45801 -- let mut groups = Vec::<Gid>::with_capacity(ngroups as usize);
45802 -+ let mut groups = Vec::<Gid>::with_capacity(min(ngroups_max, 8) as usize);
45803 - cfg_if! {
45804 - if #[cfg(any(target_os = "ios", target_os = "macos"))] {
45805 - type getgrouplist_group_t = c_int;
45806 -@@ -1446,6 +1524,7 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
45807 - }
45808 - let gid: gid_t = group.into();
45809 - loop {
45810 -+ let mut ngroups = groups.capacity() as i32;
45811 - let ret = unsafe {
45812 - libc::getgrouplist(user.as_ptr(),
45813 - gid as getgrouplist_group_t,
45814 -@@ -1462,19 +1541,8 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
45815 - // BSD systems will still fill the groups buffer with as many
45816 - // groups as possible, but Linux manpages do not mention this
45817 - // behavior.
45818 --
45819 -- let cap = groups.capacity();
45820 -- if cap >= ngroups_max as usize {
45821 -- // We already have the largest capacity we can, give up
45822 -- return Err(Error::invalid_argument());
45823 -- }
45824 --
45825 -- // Reserve space for at least ngroups
45826 -- groups.reserve(ngroups as usize);
45827 --
45828 -- // Even if the buffer gets resized to bigger than ngroups_max,
45829 -- // don't ever ask for more than ngroups_max groups
45830 -- ngroups = min(ngroups_max, groups.capacity() as c_int);
45831 -+ reserve_double_buffer_size(&mut groups, ngroups_max as usize)
45832 -+ .or_else(|_| Err(Error::invalid_argument()))?;
45833 - }
45834 - }
45835 - }
45836 -@@ -1515,11 +1583,9 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
45837 - /// # Ok(())
45838 - /// # }
45839 - /// #
45840 --/// # fn main() {
45841 --/// # try_main().unwrap();
45842 --/// # }
45843 -+/// # try_main().unwrap();
45844 - /// ```
45845 --#[cfg(not(any(target_os = "ios", target_os = "macos")))]
45846 -+#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))]
45847 - pub fn initgroups(user: &CStr, group: Gid) -> Result<()> {
45848 - cfg_if! {
45849 - if #[cfg(any(target_os = "ios", target_os = "macos"))] {
45850 -@@ -1538,6 +1604,7 @@ pub fn initgroups(user: &CStr, group: Gid) -> Result<()> {
45851 - ///
45852 - /// See also [pause(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pause.html).
45853 - #[inline]
45854 -+#[cfg(not(target_os = "redox"))]
45855 - pub fn pause() {
45856 - unsafe { libc::pause() };
45857 - }
45858 -@@ -1568,7 +1635,8 @@ pub mod alarm {
45859 - //!
45860 - //! Scheduling an alarm and waiting for the signal:
45861 - //!
45862 -- //! ```
45863 -+#![cfg_attr(target_os = "redox", doc = " ```rust,ignore")]
45864 -+#![cfg_attr(not(target_os = "redox"), doc = " ```rust")]
45865 - //! use std::time::{Duration, Instant};
45866 - //!
45867 - //! use nix::unistd::{alarm, pause};
45868 -@@ -1577,14 +1645,23 @@ pub mod alarm {
45869 - //! // We need to setup an empty signal handler to catch the alarm signal,
45870 - //! // otherwise the program will be terminated once the signal is delivered.
45871 - //! extern fn signal_handler(_: nix::libc::c_int) { }
45872 -- //! unsafe { sigaction(Signal::SIGALRM, &SigAction::new(SigHandler::Handler(signal_handler), SaFlags::empty(), SigSet::empty())); }
45873 -+ //! let sa = SigAction::new(
45874 -+ //! SigHandler::Handler(signal_handler),
45875 -+ //! SaFlags::empty(),
45876 -+ //! SigSet::empty()
45877 -+ //! );
45878 -+ //! unsafe {
45879 -+ //! sigaction(Signal::SIGALRM, &sa);
45880 -+ //! }
45881 - //!
45882 - //! // Set an alarm for 1 second from now.
45883 - //! alarm::set(1);
45884 - //!
45885 - //! let start = Instant::now();
45886 - //! // Pause the process until the alarm signal is received.
45887 -- //! pause();
45888 -+ //! let mut sigset = SigSet::empty();
45889 -+ //! sigset.add(Signal::SIGALRM);
45890 -+ //! sigset.wait();
45891 - //!
45892 - //! assert!(start.elapsed() >= Duration::from_secs(1));
45893 - //! ```
45894 -@@ -1593,8 +1670,6 @@ pub mod alarm {
45895 - //!
45896 - //! See also [alarm(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/alarm.html).
45897 -
45898 -- use libc;
45899 --
45900 - /// Schedule an alarm signal.
45901 - ///
45902 - /// This will cause the system to generate a `SIGALRM` signal for the
45903 -@@ -1630,10 +1705,10 @@ pub fn sleep(seconds: c_uint) -> c_uint {
45904 - unsafe { libc::sleep(seconds) }
45905 - }
45906 -
45907 -+#[cfg(not(target_os = "redox"))]
45908 - pub mod acct {
45909 -- use libc;
45910 -- use {Result, NixPath};
45911 -- use errno::Errno;
45912 -+ use crate::{Result, NixPath};
45913 -+ use crate::errno::Errno;
45914 - use std::ptr;
45915 -
45916 - /// Enable process accounting
45917 -@@ -1711,7 +1786,7 @@ pub fn mkstemp<P: ?Sized + NixPath>(template: &P) -> Result<(RawFd, PathBuf)> {
45918 - #[repr(i32)]
45919 - pub enum PathconfVar {
45920 - #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "linux",
45921 -- target_os = "netbsd", target_os = "openbsd"))]
45922 -+ target_os = "netbsd", target_os = "openbsd", target_os = "redox"))]
45923 - /// Minimum number of bits needed to represent, as a signed integer value,
45924 - /// the maximum size of a regular file allowed in the specified directory.
45925 - FILESIZEBITS = libc::_PC_FILESIZEBITS,
45926 -@@ -1735,11 +1810,11 @@ pub enum PathconfVar {
45927 - /// a pipe.
45928 - PIPE_BUF = libc::_PC_PIPE_BUF,
45929 - #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "linux",
45930 -- target_os = "netbsd", target_os = "openbsd"))]
45931 -+ target_os = "netbsd", target_os = "openbsd", target_os = "redox"))]
45932 - /// Symbolic links can be created.
45933 - POSIX2_SYMLINKS = libc::_PC_2_SYMLINKS,
45934 - #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
45935 -- target_os = "linux", target_os = "openbsd"))]
45936 -+ target_os = "linux", target_os = "openbsd", target_os = "redox"))]
45937 - /// Minimum number of bytes of storage actually allocated for any portion of
45938 - /// a file.
45939 - POSIX_ALLOC_SIZE_MIN = libc::_PC_ALLOC_SIZE_MIN,
45940 -@@ -1749,19 +1824,20 @@ pub enum PathconfVar {
45941 - /// `POSIX_REC_MIN_XFER_SIZE` and `POSIX_REC_MAX_XFER_SIZE` values.
45942 - POSIX_REC_INCR_XFER_SIZE = libc::_PC_REC_INCR_XFER_SIZE,
45943 - #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
45944 -- target_os = "linux", target_os = "openbsd"))]
45945 -+ target_os = "linux", target_os = "openbsd", target_os = "redox"))]
45946 - /// Maximum recommended file transfer size.
45947 - POSIX_REC_MAX_XFER_SIZE = libc::_PC_REC_MAX_XFER_SIZE,
45948 - #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
45949 -- target_os = "linux", target_os = "openbsd"))]
45950 -+ target_os = "linux", target_os = "openbsd", target_os = "redox"))]
45951 - /// Minimum recommended file transfer size.
45952 - POSIX_REC_MIN_XFER_SIZE = libc::_PC_REC_MIN_XFER_SIZE,
45953 - #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
45954 -- target_os = "linux", target_os = "openbsd"))]
45955 -+ target_os = "linux", target_os = "openbsd", target_os = "redox"))]
45956 - /// Recommended file transfer buffer alignment.
45957 - POSIX_REC_XFER_ALIGN = libc::_PC_REC_XFER_ALIGN,
45958 - #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
45959 -- target_os = "linux", target_os = "netbsd", target_os = "openbsd"))]
45960 -+ target_os = "linux", target_os = "netbsd", target_os = "openbsd",
45961 -+ target_os = "redox"))]
45962 - /// Maximum number of bytes in a symbolic link.
45963 - SYMLINK_MAX = libc::_PC_SYMLINK_MAX,
45964 - /// The use of `chown` and `fchown` is restricted to a process with
45965 -@@ -1775,17 +1851,18 @@ pub enum PathconfVar {
45966 - /// disable terminal special character handling.
45967 - _POSIX_VDISABLE = libc::_PC_VDISABLE,
45968 - #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
45969 -- target_os = "linux", target_os = "openbsd"))]
45970 -+ target_os = "linux", target_os = "openbsd", target_os = "redox"))]
45971 - /// Asynchronous input or output operations may be performed for the
45972 - /// associated file.
45973 - _POSIX_ASYNC_IO = libc::_PC_ASYNC_IO,
45974 - #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
45975 -- target_os = "linux", target_os = "openbsd"))]
45976 -+ target_os = "linux", target_os = "openbsd", target_os = "redox"))]
45977 - /// Prioritized input or output operations may be performed for the
45978 - /// associated file.
45979 - _POSIX_PRIO_IO = libc::_PC_PRIO_IO,
45980 - #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
45981 -- target_os = "linux", target_os = "netbsd", target_os = "openbsd"))]
45982 -+ target_os = "linux", target_os = "netbsd", target_os = "openbsd",
45983 -+ target_os = "redox"))]
45984 - /// Synchronized input or output operations may be performed for the
45985 - /// associated file.
45986 - _POSIX_SYNC_IO = libc::_PC_SYNC_IO,
45987 -@@ -1886,9 +1963,11 @@ pub fn pathconf<P: ?Sized + NixPath>(path: &P, var: PathconfVar) -> Result<Optio
45988 - pub enum SysconfVar {
45989 - /// Maximum number of I/O operations in a single list I/O call supported by
45990 - /// the implementation.
45991 -+ #[cfg(not(target_os = "redox"))]
45992 - AIO_LISTIO_MAX = libc::_SC_AIO_LISTIO_MAX,
45993 - /// Maximum number of outstanding asynchronous I/O operations supported by
45994 - /// the implementation.
45995 -+ #[cfg(not(target_os = "redox"))]
45996 - AIO_MAX = libc::_SC_AIO_MAX,
45997 - #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
45998 - target_os = "ios", target_os="linux", target_os = "macos",
45999 -@@ -1899,25 +1978,34 @@ pub enum SysconfVar {
46000 - /// Maximum length of argument to the exec functions including environment data.
46001 - ARG_MAX = libc::_SC_ARG_MAX,
46002 - /// Maximum number of functions that may be registered with `atexit`.
46003 -+ #[cfg(not(target_os = "redox"))]
46004 - ATEXIT_MAX = libc::_SC_ATEXIT_MAX,
46005 - /// Maximum obase values allowed by the bc utility.
46006 -+ #[cfg(not(target_os = "redox"))]
46007 - BC_BASE_MAX = libc::_SC_BC_BASE_MAX,
46008 - /// Maximum number of elements permitted in an array by the bc utility.
46009 -+ #[cfg(not(target_os = "redox"))]
46010 - BC_DIM_MAX = libc::_SC_BC_DIM_MAX,
46011 - /// Maximum scale value allowed by the bc utility.
46012 -+ #[cfg(not(target_os = "redox"))]
46013 - BC_SCALE_MAX = libc::_SC_BC_SCALE_MAX,
46014 - /// Maximum length of a string constant accepted by the bc utility.
46015 -+ #[cfg(not(target_os = "redox"))]
46016 - BC_STRING_MAX = libc::_SC_BC_STRING_MAX,
46017 - /// Maximum number of simultaneous processes per real user ID.
46018 - CHILD_MAX = libc::_SC_CHILD_MAX,
46019 -- // _SC_CLK_TCK is obsolete
46020 -+ // The number of clock ticks per second.
46021 -+ CLK_TCK = libc::_SC_CLK_TCK,
46022 - /// Maximum number of weights that can be assigned to an entry of the
46023 - /// LC_COLLATE order keyword in the locale definition file
46024 -+ #[cfg(not(target_os = "redox"))]
46025 - COLL_WEIGHTS_MAX = libc::_SC_COLL_WEIGHTS_MAX,
46026 - /// Maximum number of timer expiration overruns.
46027 -+ #[cfg(not(target_os = "redox"))]
46028 - DELAYTIMER_MAX = libc::_SC_DELAYTIMER_MAX,
46029 - /// Maximum number of expressions that can be nested within parentheses by
46030 - /// the expr utility.
46031 -+ #[cfg(not(target_os = "redox"))]
46032 - EXPR_NEST_MAX = libc::_SC_EXPR_NEST_MAX,
46033 - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
46034 - target_os="linux", target_os = "macos", target_os="netbsd",
46035 -@@ -1927,23 +2015,29 @@ pub enum SysconfVar {
46036 - HOST_NAME_MAX = libc::_SC_HOST_NAME_MAX,
46037 - /// Maximum number of iovec structures that one process has available for
46038 - /// use with `readv` or `writev`.
46039 -+ #[cfg(not(target_os = "redox"))]
46040 - IOV_MAX = libc::_SC_IOV_MAX,
46041 - /// Unless otherwise noted, the maximum length, in bytes, of a utility's
46042 - /// input line (either standard input or another file), when the utility is
46043 - /// described as processing text files. The length includes room for the
46044 - /// trailing <newline>.
46045 -+ #[cfg(not(target_os = "redox"))]
46046 - LINE_MAX = libc::_SC_LINE_MAX,
46047 - /// Maximum length of a login name.
46048 - LOGIN_NAME_MAX = libc::_SC_LOGIN_NAME_MAX,
46049 - /// Maximum number of simultaneous supplementary group IDs per process.
46050 - NGROUPS_MAX = libc::_SC_NGROUPS_MAX,
46051 - /// Initial size of `getgrgid_r` and `getgrnam_r` data buffers
46052 -+ #[cfg(not(target_os = "redox"))]
46053 - GETGR_R_SIZE_MAX = libc::_SC_GETGR_R_SIZE_MAX,
46054 - /// Initial size of `getpwuid_r` and `getpwnam_r` data buffers
46055 -+ #[cfg(not(target_os = "redox"))]
46056 - GETPW_R_SIZE_MAX = libc::_SC_GETPW_R_SIZE_MAX,
46057 - /// The maximum number of open message queue descriptors a process may hold.
46058 -+ #[cfg(not(target_os = "redox"))]
46059 - MQ_OPEN_MAX = libc::_SC_MQ_OPEN_MAX,
46060 - /// The maximum number of message priorities supported by the implementation.
46061 -+ #[cfg(not(target_os = "redox"))]
46062 - MQ_PRIO_MAX = libc::_SC_MQ_PRIO_MAX,
46063 - /// A value one greater than the maximum value that the system may assign to
46064 - /// a newly-created file descriptor.
46065 -@@ -1958,6 +2052,7 @@ pub enum SysconfVar {
46066 - /// The implementation supports barriers.
46067 - _POSIX_BARRIERS = libc::_SC_BARRIERS,
46068 - /// The implementation supports asynchronous input and output.
46069 -+ #[cfg(not(target_os = "redox"))]
46070 - _POSIX_ASYNCHRONOUS_IO = libc::_SC_ASYNCHRONOUS_IO,
46071 - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
46072 - target_os="linux", target_os = "macos", target_os="netbsd",
46073 -@@ -1970,24 +2065,32 @@ pub enum SysconfVar {
46074 - /// The implementation supports the Process CPU-Time Clocks option.
46075 - _POSIX_CPUTIME = libc::_SC_CPUTIME,
46076 - /// The implementation supports the File Synchronization option.
46077 -+ #[cfg(not(target_os = "redox"))]
46078 - _POSIX_FSYNC = libc::_SC_FSYNC,
46079 - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
46080 - target_os="linux", target_os = "macos", target_os="openbsd"))]
46081 - /// The implementation supports the IPv6 option.
46082 - _POSIX_IPV6 = libc::_SC_IPV6,
46083 - /// The implementation supports job control.
46084 -+ #[cfg(not(target_os = "redox"))]
46085 - _POSIX_JOB_CONTROL = libc::_SC_JOB_CONTROL,
46086 - /// The implementation supports memory mapped Files.
46087 -+ #[cfg(not(target_os = "redox"))]
46088 - _POSIX_MAPPED_FILES = libc::_SC_MAPPED_FILES,
46089 - /// The implementation supports the Process Memory Locking option.
46090 -+ #[cfg(not(target_os = "redox"))]
46091 - _POSIX_MEMLOCK = libc::_SC_MEMLOCK,
46092 - /// The implementation supports the Range Memory Locking option.
46093 -+ #[cfg(not(target_os = "redox"))]
46094 - _POSIX_MEMLOCK_RANGE = libc::_SC_MEMLOCK_RANGE,
46095 - /// The implementation supports memory protection.
46096 -+ #[cfg(not(target_os = "redox"))]
46097 - _POSIX_MEMORY_PROTECTION = libc::_SC_MEMORY_PROTECTION,
46098 - /// The implementation supports the Message Passing option.
46099 -+ #[cfg(not(target_os = "redox"))]
46100 - _POSIX_MESSAGE_PASSING = libc::_SC_MESSAGE_PASSING,
46101 - /// The implementation supports the Monotonic Clock option.
46102 -+ #[cfg(not(target_os = "redox"))]
46103 - _POSIX_MONOTONIC_CLOCK = libc::_SC_MONOTONIC_CLOCK,
46104 - #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
46105 - target_os = "ios", target_os="linux", target_os = "macos",
46106 -@@ -1995,6 +2098,7 @@ pub enum SysconfVar {
46107 - /// The implementation supports the Prioritized Input and Output option.
46108 - _POSIX_PRIORITIZED_IO = libc::_SC_PRIORITIZED_IO,
46109 - /// The implementation supports the Process Scheduling option.
46110 -+ #[cfg(not(target_os = "redox"))]
46111 - _POSIX_PRIORITY_SCHEDULING = libc::_SC_PRIORITY_SCHEDULING,
46112 - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
46113 - target_os="linux", target_os = "macos", target_os="openbsd"))]
46114 -@@ -2016,10 +2120,13 @@ pub enum SysconfVar {
46115 - /// The implementation supports the Regular Expression Handling option.
46116 - _POSIX_REGEXP = libc::_SC_REGEXP,
46117 - /// Each process has a saved set-user-ID and a saved set-group-ID.
46118 -+ #[cfg(not(target_os = "redox"))]
46119 - _POSIX_SAVED_IDS = libc::_SC_SAVED_IDS,
46120 - /// The implementation supports semaphores.
46121 -+ #[cfg(not(target_os = "redox"))]
46122 - _POSIX_SEMAPHORES = libc::_SC_SEMAPHORES,
46123 - /// The implementation supports the Shared Memory Objects option.
46124 -+ #[cfg(not(target_os = "redox"))]
46125 - _POSIX_SHARED_MEMORY_OBJECTS = libc::_SC_SHARED_MEMORY_OBJECTS,
46126 - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
46127 - target_os="linux", target_os = "macos", target_os="netbsd",
46128 -@@ -2044,10 +2151,13 @@ pub enum SysconfVar {
46129 - target_os="openbsd"))]
46130 - _POSIX_SS_REPL_MAX = libc::_SC_SS_REPL_MAX,
46131 - /// The implementation supports the Synchronized Input and Output option.
46132 -+ #[cfg(not(target_os = "redox"))]
46133 - _POSIX_SYNCHRONIZED_IO = libc::_SC_SYNCHRONIZED_IO,
46134 - /// The implementation supports the Thread Stack Address Attribute option.
46135 -+ #[cfg(not(target_os = "redox"))]
46136 - _POSIX_THREAD_ATTR_STACKADDR = libc::_SC_THREAD_ATTR_STACKADDR,
46137 - /// The implementation supports the Thread Stack Size Attribute option.
46138 -+ #[cfg(not(target_os = "redox"))]
46139 - _POSIX_THREAD_ATTR_STACKSIZE = libc::_SC_THREAD_ATTR_STACKSIZE,
46140 - #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
46141 - target_os="netbsd", target_os="openbsd"))]
46142 -@@ -2055,10 +2165,13 @@ pub enum SysconfVar {
46143 - _POSIX_THREAD_CPUTIME = libc::_SC_THREAD_CPUTIME,
46144 - /// The implementation supports the Non-Robust Mutex Priority Inheritance
46145 - /// option.
46146 -+ #[cfg(not(target_os = "redox"))]
46147 - _POSIX_THREAD_PRIO_INHERIT = libc::_SC_THREAD_PRIO_INHERIT,
46148 - /// The implementation supports the Non-Robust Mutex Priority Protection option.
46149 -+ #[cfg(not(target_os = "redox"))]
46150 - _POSIX_THREAD_PRIO_PROTECT = libc::_SC_THREAD_PRIO_PROTECT,
46151 - /// The implementation supports the Thread Execution Scheduling option.
46152 -+ #[cfg(not(target_os = "redox"))]
46153 - _POSIX_THREAD_PRIORITY_SCHEDULING = libc::_SC_THREAD_PRIORITY_SCHEDULING,
46154 - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
46155 - target_os="linux", target_os = "macos", target_os="netbsd",
46156 -@@ -2073,18 +2186,21 @@ pub enum SysconfVar {
46157 - /// The implementation supports the Robust Mutex Priority Protection option.
46158 - _POSIX_THREAD_ROBUST_PRIO_PROTECT = libc::_SC_THREAD_ROBUST_PRIO_PROTECT,
46159 - /// The implementation supports thread-safe functions.
46160 -+ #[cfg(not(target_os = "redox"))]
46161 - _POSIX_THREAD_SAFE_FUNCTIONS = libc::_SC_THREAD_SAFE_FUNCTIONS,
46162 - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
46163 - target_os="linux", target_os = "macos", target_os="openbsd"))]
46164 - /// The implementation supports the Thread Sporadic Server option.
46165 - _POSIX_THREAD_SPORADIC_SERVER = libc::_SC_THREAD_SPORADIC_SERVER,
46166 - /// The implementation supports threads.
46167 -+ #[cfg(not(target_os = "redox"))]
46168 - _POSIX_THREADS = libc::_SC_THREADS,
46169 - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
46170 - target_os="linux", target_os = "macos", target_os="openbsd"))]
46171 - /// The implementation supports timeouts.
46172 - _POSIX_TIMEOUTS = libc::_SC_TIMEOUTS,
46173 - /// The implementation supports timers.
46174 -+ #[cfg(not(target_os = "redox"))]
46175 - _POSIX_TIMERS = libc::_SC_TIMERS,
46176 - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
46177 - target_os="linux", target_os = "macos", target_os="openbsd"))]
46178 -@@ -2149,17 +2265,23 @@ pub enum SysconfVar {
46179 - /// using at least 64 bits.
46180 - _POSIX_V6_LPBIG_OFFBIG = libc::_SC_V6_LPBIG_OFFBIG,
46181 - /// The implementation supports the C-Language Binding option.
46182 -+ #[cfg(not(target_os = "redox"))]
46183 - _POSIX2_C_BIND = libc::_SC_2_C_BIND,
46184 - /// The implementation supports the C-Language Development Utilities option.
46185 -+ #[cfg(not(target_os = "redox"))]
46186 - _POSIX2_C_DEV = libc::_SC_2_C_DEV,
46187 - /// The implementation supports the Terminal Characteristics option.
46188 -+ #[cfg(not(target_os = "redox"))]
46189 - _POSIX2_CHAR_TERM = libc::_SC_2_CHAR_TERM,
46190 - /// The implementation supports the FORTRAN Development Utilities option.
46191 -+ #[cfg(not(target_os = "redox"))]
46192 - _POSIX2_FORT_DEV = libc::_SC_2_FORT_DEV,
46193 - /// The implementation supports the FORTRAN Runtime Utilities option.
46194 -+ #[cfg(not(target_os = "redox"))]
46195 - _POSIX2_FORT_RUN = libc::_SC_2_FORT_RUN,
46196 - /// The implementation supports the creation of locales by the localedef
46197 - /// utility.
46198 -+ #[cfg(not(target_os = "redox"))]
46199 - _POSIX2_LOCALEDEF = libc::_SC_2_LOCALEDEF,
46200 - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
46201 - target_os="linux", target_os = "macos", target_os="netbsd",
46202 -@@ -2193,26 +2315,34 @@ pub enum SysconfVar {
46203 - /// The implementation supports the Track Batch Job Request option.
46204 - _POSIX2_PBS_TRACK = libc::_SC_2_PBS_TRACK,
46205 - /// The implementation supports the Software Development Utilities option.
46206 -+ #[cfg(not(target_os = "redox"))]
46207 - _POSIX2_SW_DEV = libc::_SC_2_SW_DEV,
46208 - /// The implementation supports the User Portability Utilities option.
46209 -+ #[cfg(not(target_os = "redox"))]
46210 - _POSIX2_UPE = libc::_SC_2_UPE,
46211 - /// Integer value indicating version of the Shell and Utilities volume of
46212 - /// POSIX.1 to which the implementation conforms.
46213 -+ #[cfg(not(target_os = "redox"))]
46214 - _POSIX2_VERSION = libc::_SC_2_VERSION,
46215 - /// The size of a system page in bytes.
46216 - ///
46217 - /// POSIX also defines an alias named `PAGESIZE`, but Rust does not allow two
46218 - /// enum constants to have the same value, so nix omits `PAGESIZE`.
46219 - PAGE_SIZE = libc::_SC_PAGE_SIZE,
46220 -+ #[cfg(not(target_os = "redox"))]
46221 - PTHREAD_DESTRUCTOR_ITERATIONS = libc::_SC_THREAD_DESTRUCTOR_ITERATIONS,
46222 -+ #[cfg(not(target_os = "redox"))]
46223 - PTHREAD_KEYS_MAX = libc::_SC_THREAD_KEYS_MAX,
46224 -+ #[cfg(not(target_os = "redox"))]
46225 - PTHREAD_STACK_MIN = libc::_SC_THREAD_STACK_MIN,
46226 -+ #[cfg(not(target_os = "redox"))]
46227 - PTHREAD_THREADS_MAX = libc::_SC_THREAD_THREADS_MAX,
46228 - RE_DUP_MAX = libc::_SC_RE_DUP_MAX,
46229 - #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
46230 - target_os = "ios", target_os="linux", target_os = "macos",
46231 - target_os="openbsd"))]
46232 - RTSIG_MAX = libc::_SC_RTSIG_MAX,
46233 -+ #[cfg(not(target_os = "redox"))]
46234 - SEM_NSEMS_MAX = libc::_SC_SEM_NSEMS_MAX,
46235 - #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
46236 - target_os = "ios", target_os="linux", target_os = "macos",
46237 -@@ -2227,6 +2357,7 @@ pub enum SysconfVar {
46238 - target_os="linux", target_os = "macos", target_os="netbsd",
46239 - target_os="openbsd"))]
46240 - SYMLOOP_MAX = libc::_SC_SYMLOOP_MAX,
46241 -+ #[cfg(not(target_os = "redox"))]
46242 - TIMER_MAX = libc::_SC_TIMER_MAX,
46243 - TTY_NAME_MAX = libc::_SC_TTY_NAME_MAX,
46244 - TZNAME_MAX = libc::_SC_TZNAME_MAX,
46245 -@@ -2257,6 +2388,7 @@ pub enum SysconfVar {
46246 - _XOPEN_REALTIME_THREADS = libc::_SC_XOPEN_REALTIME_THREADS,
46247 - /// The implementation supports the Issue 4, Version 2 Shared Memory Option
46248 - /// Group.
46249 -+ #[cfg(not(target_os = "redox"))]
46250 - _XOPEN_SHM = libc::_SC_XOPEN_SHM,
46251 - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
46252 - target_os="linux", target_os = "macos", target_os="openbsd"))]
46253 -@@ -2309,9 +2441,8 @@ pub fn sysconf(var: SysconfVar) -> Result<Option<c_long>> {
46254 -
46255 - #[cfg(any(target_os = "android", target_os = "linux"))]
46256 - mod pivot_root {
46257 -- use libc;
46258 -- use {Result, NixPath};
46259 -- use errno::Errno;
46260 -+ use crate::{Result, NixPath};
46261 -+ use crate::errno::Errno;
46262 -
46263 - pub fn pivot_root<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
46264 - new_root: &P1, put_old: &P2) -> Result<()> {
46265 -@@ -2330,9 +2461,8 @@ mod pivot_root {
46266 - #[cfg(any(target_os = "android", target_os = "freebsd",
46267 - target_os = "linux", target_os = "openbsd"))]
46268 - mod setres {
46269 -- use libc;
46270 -- use Result;
46271 -- use errno::Errno;
46272 -+ use crate::Result;
46273 -+ use crate::errno::Errno;
46274 - use super::{Uid, Gid};
46275 -
46276 - /// Sets the real, effective, and saved uid.
46277 -@@ -2392,3 +2522,308 @@ pub fn access<P: ?Sized + NixPath>(path: &P, amode: AccessFlags) -> Result<()> {
46278 - })?;
46279 - Errno::result(res).map(drop)
46280 - }
46281 -+
46282 -+/// Representation of a User, based on `libc::passwd`
46283 -+///
46284 -+/// The reason some fields in this struct are `String` and others are `CString` is because some
46285 -+/// fields are based on the user's locale, which could be non-UTF8, while other fields are
46286 -+/// guaranteed to conform to [`NAME_REGEX`](https://serverfault.com/a/73101/407341), which only
46287 -+/// contains ASCII.
46288 -+#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
46289 -+#[derive(Debug, Clone, PartialEq)]
46290 -+pub struct User {
46291 -+ /// Username
46292 -+ pub name: String,
46293 -+ /// User password (probably encrypted)
46294 -+ pub passwd: CString,
46295 -+ /// User ID
46296 -+ pub uid: Uid,
46297 -+ /// Group ID
46298 -+ pub gid: Gid,
46299 -+ /// User information
46300 -+ #[cfg(not(target_os = "android"))]
46301 -+ pub gecos: CString,
46302 -+ /// Home directory
46303 -+ pub dir: PathBuf,
46304 -+ /// Path to shell
46305 -+ pub shell: PathBuf,
46306 -+ /// Login class
46307 -+ #[cfg(not(any(target_os = "android", target_os = "fuchsia",
46308 -+ target_os = "linux")))]
46309 -+ pub class: CString,
46310 -+ /// Last password change
46311 -+ #[cfg(not(any(target_os = "android", target_os = "fuchsia",
46312 -+ target_os = "linux")))]
46313 -+ pub change: libc::time_t,
46314 -+ /// Expiration time of account
46315 -+ #[cfg(not(any(target_os = "android", target_os = "fuchsia",
46316 -+ target_os = "linux")))]
46317 -+ pub expire: libc::time_t
46318 -+}
46319 -+
46320 -+#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
46321 -+impl From<&libc::passwd> for User {
46322 -+ fn from(pw: &libc::passwd) -> User {
46323 -+ unsafe {
46324 -+ User {
46325 -+ name: CStr::from_ptr((*pw).pw_name).to_string_lossy().into_owned(),
46326 -+ passwd: CString::new(CStr::from_ptr((*pw).pw_passwd).to_bytes()).unwrap(),
46327 -+ #[cfg(not(target_os = "android"))]
46328 -+ gecos: CString::new(CStr::from_ptr((*pw).pw_gecos).to_bytes()).unwrap(),
46329 -+ dir: PathBuf::from(OsStr::from_bytes(CStr::from_ptr((*pw).pw_dir).to_bytes())),
46330 -+ shell: PathBuf::from(OsStr::from_bytes(CStr::from_ptr((*pw).pw_shell).to_bytes())),
46331 -+ uid: Uid::from_raw((*pw).pw_uid),
46332 -+ gid: Gid::from_raw((*pw).pw_gid),
46333 -+ #[cfg(not(any(target_os = "android", target_os = "fuchsia",
46334 -+ target_os = "linux")))]
46335 -+ class: CString::new(CStr::from_ptr((*pw).pw_class).to_bytes()).unwrap(),
46336 -+ #[cfg(not(any(target_os = "android", target_os = "fuchsia",
46337 -+ target_os = "linux")))]
46338 -+ change: (*pw).pw_change,
46339 -+ #[cfg(not(any(target_os = "android", target_os = "fuchsia",
46340 -+ target_os = "linux")))]
46341 -+ expire: (*pw).pw_expire
46342 -+ }
46343 -+ }
46344 -+ }
46345 -+}
46346 -+
46347 -+#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
46348 -+impl User {
46349 -+ fn from_anything<F>(f: F) -> Result<Option<Self>>
46350 -+ where
46351 -+ F: Fn(*mut libc::passwd,
46352 -+ *mut libc::c_char,
46353 -+ libc::size_t,
46354 -+ *mut *mut libc::passwd) -> libc::c_int
46355 -+ {
46356 -+ let buflimit = 16384;
46357 -+ let bufsize = match sysconf(SysconfVar::GETPW_R_SIZE_MAX) {
46358 -+ Ok(Some(n)) => n as usize,
46359 -+ Ok(None) | Err(_) => buflimit as usize,
46360 -+ };
46361 -+
46362 -+ let mut cbuf = Vec::with_capacity(bufsize);
46363 -+ let mut pwd = mem::MaybeUninit::<libc::passwd>::uninit();
46364 -+ let mut res = ptr::null_mut();
46365 -+
46366 -+ loop {
46367 -+ let error = f(pwd.as_mut_ptr(), cbuf.as_mut_ptr(), cbuf.capacity(), &mut res);
46368 -+ if error == 0 {
46369 -+ if res.is_null() {
46370 -+ return Ok(None);
46371 -+ } else {
46372 -+ let pwd = unsafe { pwd.assume_init() };
46373 -+ return Ok(Some(User::from(&pwd)));
46374 -+ }
46375 -+ } else if Errno::last() == Errno::ERANGE {
46376 -+ // Trigger the internal buffer resizing logic.
46377 -+ reserve_double_buffer_size(&mut cbuf, buflimit)?;
46378 -+ } else {
46379 -+ return Err(Error::Sys(Errno::last()));
46380 -+ }
46381 -+ }
46382 -+ }
46383 -+
46384 -+ /// Get a user by UID.
46385 -+ ///
46386 -+ /// Internally, this function calls
46387 -+ /// [getpwuid_r(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html)
46388 -+ ///
46389 -+ /// # Examples
46390 -+ ///
46391 -+ /// ```
46392 -+ /// use nix::unistd::{Uid, User};
46393 -+ /// // Returns an Result<Option<User>>, thus the double unwrap.
46394 -+ /// let res = User::from_uid(Uid::from_raw(0)).unwrap().unwrap();
46395 -+ /// assert!(res.name == "root");
46396 -+ /// ```
46397 -+ pub fn from_uid(uid: Uid) -> Result<Option<Self>> {
46398 -+ User::from_anything(|pwd, cbuf, cap, res| {
46399 -+ unsafe { libc::getpwuid_r(uid.0, pwd, cbuf, cap, res) }
46400 -+ })
46401 -+ }
46402 -+
46403 -+ /// Get a user by name.
46404 -+ ///
46405 -+ /// Internally, this function calls
46406 -+ /// [getpwnam_r(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html)
46407 -+ ///
46408 -+ /// # Examples
46409 -+ ///
46410 -+ /// ```
46411 -+ /// use nix::unistd::User;
46412 -+ /// // Returns an Result<Option<User>>, thus the double unwrap.
46413 -+ /// let res = User::from_name("root").unwrap().unwrap();
46414 -+ /// assert!(res.name == "root");
46415 -+ /// ```
46416 -+ pub fn from_name(name: &str) -> Result<Option<Self>> {
46417 -+ let name = CString::new(name).unwrap();
46418 -+ User::from_anything(|pwd, cbuf, cap, res| {
46419 -+ unsafe { libc::getpwnam_r(name.as_ptr(), pwd, cbuf, cap, res) }
46420 -+ })
46421 -+ }
46422 -+}
46423 -+
46424 -+/// Representation of a Group, based on `libc::group`
46425 -+#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
46426 -+#[derive(Debug, Clone, PartialEq)]
46427 -+pub struct Group {
46428 -+ /// Group name
46429 -+ pub name: String,
46430 -+ /// Group password
46431 -+ pub passwd: CString,
46432 -+ /// Group ID
46433 -+ pub gid: Gid,
46434 -+ /// List of Group members
46435 -+ pub mem: Vec<String>
46436 -+}
46437 -+
46438 -+#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
46439 -+impl From<&libc::group> for Group {
46440 -+ fn from(gr: &libc::group) -> Group {
46441 -+ unsafe {
46442 -+ Group {
46443 -+ name: CStr::from_ptr((*gr).gr_name).to_string_lossy().into_owned(),
46444 -+ passwd: CString::new(CStr::from_ptr((*gr).gr_passwd).to_bytes()).unwrap(),
46445 -+ gid: Gid::from_raw((*gr).gr_gid),
46446 -+ mem: Group::members((*gr).gr_mem)
46447 -+ }
46448 -+ }
46449 -+ }
46450 -+}
46451 -+
46452 -+#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
46453 -+impl Group {
46454 -+ unsafe fn members(mem: *mut *mut c_char) -> Vec<String> {
46455 -+ let mut ret = Vec::new();
46456 -+
46457 -+ for i in 0.. {
46458 -+ let u = mem.offset(i);
46459 -+ if (*u).is_null() {
46460 -+ break;
46461 -+ } else {
46462 -+ let s = CStr::from_ptr(*u).to_string_lossy().into_owned();
46463 -+ ret.push(s);
46464 -+ }
46465 -+ }
46466 -+
46467 -+ ret
46468 -+ }
46469 -+
46470 -+ fn from_anything<F>(f: F) -> Result<Option<Self>>
46471 -+ where
46472 -+ F: Fn(*mut libc::group,
46473 -+ *mut libc::c_char,
46474 -+ libc::size_t,
46475 -+ *mut *mut libc::group) -> libc::c_int
46476 -+ {
46477 -+ let buflimit = 16384;
46478 -+ let bufsize = match sysconf(SysconfVar::GETGR_R_SIZE_MAX) {
46479 -+ Ok(Some(n)) => n as usize,
46480 -+ Ok(None) | Err(_) => buflimit as usize,
46481 -+ };
46482 -+
46483 -+ let mut cbuf = Vec::with_capacity(bufsize);
46484 -+ let mut grp = mem::MaybeUninit::<libc::group>::uninit();
46485 -+ let mut res = ptr::null_mut();
46486 -+
46487 -+ loop {
46488 -+ let error = f(grp.as_mut_ptr(), cbuf.as_mut_ptr(), cbuf.capacity(), &mut res);
46489 -+ if error == 0 {
46490 -+ if res.is_null() {
46491 -+ return Ok(None);
46492 -+ } else {
46493 -+ let grp = unsafe { grp.assume_init() };
46494 -+ return Ok(Some(Group::from(&grp)));
46495 -+ }
46496 -+ } else if Errno::last() == Errno::ERANGE {
46497 -+ // Trigger the internal buffer resizing logic.
46498 -+ reserve_double_buffer_size(&mut cbuf, buflimit)?;
46499 -+ } else {
46500 -+ return Err(Error::Sys(Errno::last()));
46501 -+ }
46502 -+ }
46503 -+ }
46504 -+
46505 -+ /// Get a group by GID.
46506 -+ ///
46507 -+ /// Internally, this function calls
46508 -+ /// [getgrgid_r(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html)
46509 -+ ///
46510 -+ /// # Examples
46511 -+ ///
46512 -+ // Disable this test on all OS except Linux as root group may not exist.
46513 -+ #[cfg_attr(not(target_os = "linux"), doc = " ```no_run")]
46514 -+ #[cfg_attr(target_os = "linux", doc = " ```")]
46515 -+ /// use nix::unistd::{Gid, Group};
46516 -+ /// // Returns an Result<Option<Group>>, thus the double unwrap.
46517 -+ /// let res = Group::from_gid(Gid::from_raw(0)).unwrap().unwrap();
46518 -+ /// assert!(res.name == "root");
46519 -+ /// ```
46520 -+ pub fn from_gid(gid: Gid) -> Result<Option<Self>> {
46521 -+ Group::from_anything(|grp, cbuf, cap, res| {
46522 -+ unsafe { libc::getgrgid_r(gid.0, grp, cbuf, cap, res) }
46523 -+ })
46524 -+ }
46525 -+
46526 -+ /// Get a group by name.
46527 -+ ///
46528 -+ /// Internally, this function calls
46529 -+ /// [getgrnam_r(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html)
46530 -+ ///
46531 -+ /// # Examples
46532 -+ ///
46533 -+ // Disable this test on all OS except Linux as root group may not exist.
46534 -+ #[cfg_attr(not(target_os = "linux"), doc = " ```no_run")]
46535 -+ #[cfg_attr(target_os = "linux", doc = " ```")]
46536 -+ /// use nix::unistd::Group;
46537 -+ /// // Returns an Result<Option<Group>>, thus the double unwrap.
46538 -+ /// let res = Group::from_name("root").unwrap().unwrap();
46539 -+ /// assert!(res.name == "root");
46540 -+ /// ```
46541 -+ pub fn from_name(name: &str) -> Result<Option<Self>> {
46542 -+ let name = CString::new(name).unwrap();
46543 -+ Group::from_anything(|grp, cbuf, cap, res| {
46544 -+ unsafe { libc::getgrnam_r(name.as_ptr(), grp, cbuf, cap, res) }
46545 -+ })
46546 -+ }
46547 -+}
46548 -+
46549 -+/// Get the name of the terminal device that is open on file descriptor fd
46550 -+/// (see [`ttyname(3)`](http://man7.org/linux/man-pages/man3/ttyname.3.html)).
46551 -+#[cfg(not(target_os = "fuchsia"))]
46552 -+pub fn ttyname(fd: RawFd) -> Result<PathBuf> {
46553 -+ const PATH_MAX: usize = libc::PATH_MAX as usize;
46554 -+ let mut buf = vec![0_u8; PATH_MAX];
46555 -+ let c_buf = buf.as_mut_ptr() as *mut libc::c_char;
46556 -+
46557 -+ let ret = unsafe { libc::ttyname_r(fd, c_buf, buf.len()) };
46558 -+ if ret != 0 {
46559 -+ return Err(Error::Sys(Errno::from_i32(ret)));
46560 -+ }
46561 -+
46562 -+ let nul = buf.iter().position(|c| *c == b'\0').unwrap();
46563 -+ buf.truncate(nul);
46564 -+ Ok(OsString::from_vec(buf).into())
46565 -+}
46566 -+
46567 -+/// Get the effective user ID and group ID associated with a Unix domain socket.
46568 -+///
46569 -+/// See also [getpeereid(3)](https://www.freebsd.org/cgi/man.cgi?query=getpeereid)
46570 -+#[cfg(any(
46571 -+ target_os = "macos",
46572 -+ target_os = "ios",
46573 -+ target_os = "freebsd",
46574 -+ target_os = "openbsd",
46575 -+ target_os = "netbsd",
46576 -+ target_os = "dragonfly",
46577 -+))]
46578 -+pub fn getpeereid(fd: RawFd) -> Result<(Uid, Gid)> {
46579 -+ let mut uid = 1;
46580 -+ let mut gid = 1;
46581 -+
46582 -+ let ret = unsafe { libc::getpeereid(fd, &mut uid, &mut gid) };
46583 -+
46584 -+ Errno::result(ret).map(|_| (Uid(uid), Gid(gid)))
46585 -+}
46586 -diff --git a/third_party/rust/nix/test/common/mod.rs b/third_party/rust/nix/test/common/mod.rs
46587 -new file mode 100644
46588 -index 0000000000000..a871b47041d3e
46589 ---- /dev/null
46590 -+++ b/third_party/rust/nix/test/common/mod.rs
46591 -@@ -0,0 +1,127 @@
46592 -+use cfg_if::cfg_if;
46593 -+
46594 -+#[macro_export] macro_rules! skip {
46595 -+ ($($reason: expr),+) => {
46596 -+ use ::std::io::{self, Write};
46597 -+
46598 -+ let stderr = io::stderr();
46599 -+ let mut handle = stderr.lock();
46600 -+ writeln!(handle, $($reason),+).unwrap();
46601 -+ return;
46602 -+ }
46603 -+}
46604 -+
46605 -+cfg_if! {
46606 -+ if #[cfg(any(target_os = "android", target_os = "linux"))] {
46607 -+ #[macro_export] macro_rules! require_capability {
46608 -+ ($capname:ident) => {
46609 -+ use ::caps::{Capability, CapSet, has_cap};
46610 -+
46611 -+ if !has_cap(None, CapSet::Effective, Capability::$capname)
46612 -+ .unwrap()
46613 -+ {
46614 -+ skip!("Insufficient capabilities. Skipping test.");
46615 -+ }
46616 -+ }
46617 -+ }
46618 -+ } else if #[cfg(not(target_os = "redox"))] {
46619 -+ #[macro_export] macro_rules! require_capability {
46620 -+ ($capname:ident) => {}
46621 -+ }
46622 -+ }
46623 -+}
46624 -+
46625 -+#[cfg(any(target_os = "linux", target_os= "android"))]
46626 -+#[macro_export] macro_rules! skip_if_cirrus {
46627 -+ ($reason:expr) => {
46628 -+ if std::env::var_os("CIRRUS_CI").is_some() {
46629 -+ skip!("{}", $reason);
46630 -+ }
46631 -+ }
46632 -+}
46633 -+
46634 -+#[cfg(target_os = "freebsd")]
46635 -+#[macro_export] macro_rules! skip_if_jailed {
46636 -+ ($name:expr) => {
46637 -+ use ::sysctl::CtlValue;
46638 -+
46639 -+ if let CtlValue::Int(1) = ::sysctl::value("security.jail.jailed")
46640 -+ .unwrap()
46641 -+ {
46642 -+ skip!("{} cannot run in a jail. Skipping test.", $name);
46643 -+ }
46644 -+ }
46645 -+}
46646 -+
46647 -+#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
46648 -+#[macro_export] macro_rules! skip_if_not_root {
46649 -+ ($name:expr) => {
46650 -+ use nix::unistd::Uid;
46651 -+
46652 -+ if !Uid::current().is_root() {
46653 -+ skip!("{} requires root privileges. Skipping test.", $name);
46654 -+ }
46655 -+ };
46656 -+}
46657 -+
46658 -+cfg_if! {
46659 -+ if #[cfg(any(target_os = "android", target_os = "linux"))] {
46660 -+ #[macro_export] macro_rules! skip_if_seccomp {
46661 -+ ($name:expr) => {
46662 -+ if let Ok(s) = std::fs::read_to_string("/proc/self/status") {
46663 -+ for l in s.lines() {
46664 -+ let mut fields = l.split_whitespace();
46665 -+ if fields.next() == Some("Seccomp:") &&
46666 -+ fields.next() != Some("0")
46667 -+ {
46668 -+ skip!("{} cannot be run in Seccomp mode. Skipping test.",
46669 -+ stringify!($name));
46670 -+ }
46671 -+ }
46672 -+ }
46673 -+ }
46674 -+ }
46675 -+ } else if #[cfg(not(target_os = "redox"))] {
46676 -+ #[macro_export] macro_rules! skip_if_seccomp {
46677 -+ ($name:expr) => {}
46678 -+ }
46679 -+ }
46680 -+}
46681 -+
46682 -+cfg_if! {
46683 -+ if #[cfg(target_os = "linux")] {
46684 -+ #[macro_export] macro_rules! require_kernel_version {
46685 -+ ($name:expr, $version_requirement:expr) => {
46686 -+ use semver::{Version, VersionReq};
46687 -+
46688 -+ let version_requirement = VersionReq::parse($version_requirement)
46689 -+ .expect("Bad match_version provided");
46690 -+
46691 -+ let uname = nix::sys::utsname::uname();
46692 -+ println!("{}", uname.sysname());
46693 -+ println!("{}", uname.nodename());
46694 -+ println!("{}", uname.release());
46695 -+ println!("{}", uname.version());
46696 -+ println!("{}", uname.machine());
46697 -+
46698 -+ // Fix stuff that the semver parser can't handle
46699 -+ let fixed_release = &uname.release().to_string()
46700 -+ // Fedora 33 reports version as 4.18.el8_2.x86_64 or
46701 -+ // 5.18.200-fc33.x86_64. Remove the underscore.
46702 -+ .replace("_", "-")
46703 -+ // Cirrus-CI reports version as 4.19.112+ . Remove the +
46704 -+ .replace("+", "");
46705 -+ let mut version = Version::parse(fixed_release).unwrap();
46706 -+
46707 -+ //Keep only numeric parts
46708 -+ version.pre.clear();
46709 -+ version.build.clear();
46710 -+
46711 -+ if !version_requirement.matches(&version) {
46712 -+ skip!("Skip {} because kernel version `{}` doesn't match the requirement `{}`",
46713 -+ stringify!($name), version, version_requirement);
46714 -+ }
46715 -+ }
46716 -+ }
46717 -+ }
46718 -+}
46719 -diff --git a/third_party/rust/nix/test/sys/mod.rs b/third_party/rust/nix/test/sys/mod.rs
46720 -index 60a58dd106f19..14b03784a0a57 100644
46721 ---- a/third_party/rust/nix/test/sys/mod.rs
46722 -+++ b/third_party/rust/nix/test/sys/mod.rs
46723 -@@ -13,12 +13,17 @@ mod test_signal;
46724 - mod test_aio;
46725 - #[cfg(target_os = "linux")]
46726 - mod test_signalfd;
46727 -+#[cfg(not(target_os = "redox"))]
46728 - mod test_socket;
46729 -+#[cfg(not(target_os = "redox"))]
46730 - mod test_sockopt;
46731 -+#[cfg(not(target_os = "redox"))]
46732 - mod test_select;
46733 - #[cfg(any(target_os = "android", target_os = "linux"))]
46734 - mod test_sysinfo;
46735 -+#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
46736 - mod test_termios;
46737 -+#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
46738 - mod test_ioctl;
46739 - mod test_wait;
46740 - mod test_uio;
46741 -@@ -36,3 +41,5 @@ mod test_pthread;
46742 - target_os = "netbsd",
46743 - target_os = "openbsd"))]
46744 - mod test_ptrace;
46745 -+#[cfg(any(target_os = "android", target_os = "linux"))]
46746 -+mod test_timerfd;
46747 -diff --git a/third_party/rust/nix/test/sys/test_aio.rs b/third_party/rust/nix/test/sys/test_aio.rs
46748 -index d4b09b0b81905..3878da94a6ef6 100644
46749 ---- a/third_party/rust/nix/test/sys/test_aio.rs
46750 -+++ b/third_party/rust/nix/test/sys/test_aio.rs
46751 -@@ -47,7 +47,7 @@ fn test_accessors() {
46752 - // our bindings. So it's sufficient to check that AioCb.cancel returned any
46753 - // AioCancelStat value.
46754 - #[test]
46755 --#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
46756 -+#[cfg_attr(target_env = "musl", ignore)]
46757 - fn test_cancel() {
46758 - let wbuf: &[u8] = b"CDEF";
46759 -
46760 -@@ -72,7 +72,7 @@ fn test_cancel() {
46761 -
46762 - // Tests using aio_cancel_all for all outstanding IOs.
46763 - #[test]
46764 --#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
46765 -+#[cfg_attr(target_env = "musl", ignore)]
46766 - fn test_aio_cancel_all() {
46767 - let wbuf: &[u8] = b"CDEF";
46768 -
46769 -@@ -133,6 +133,13 @@ fn test_fsync_error() {
46770 -
46771 - #[test]
46772 - #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
46773 -+// On Travis, aio_suspend hits an assertion within glibc. This is either a bug
46774 -+// in Travis's version of glibc or Linux. Either way, we must skip the test.
46775 -+// https://github.com/nix-rust/nix/issues/1099
46776 -+#[cfg_attr(target_os = "linux", ignore)]
46777 -+// On Cirrus, aio_suspend is failing with EINVAL
46778 -+// https://github.com/nix-rust/nix/issues/1361
46779 -+#[cfg_attr(target_os = "macos", ignore)]
46780 - fn test_aio_suspend() {
46781 - const INITIAL: &[u8] = b"abcdef123456";
46782 - const WBUF: &[u8] = b"CDEFG";
46783 -@@ -160,7 +167,12 @@ fn test_aio_suspend() {
46784 - loop {
46785 - {
46786 - let cbbuf = [&wcb, &rcb];
46787 -- assert!(aio_suspend(&cbbuf[..], Some(timeout)).is_ok());
46788 -+ let r = aio_suspend(&cbbuf[..], Some(timeout));
46789 -+ match r {
46790 -+ Err(Error::Sys(Errno::EINTR)) => continue,
46791 -+ Err(e) => panic!("aio_suspend returned {:?}", e),
46792 -+ Ok(_) => ()
46793 -+ };
46794 - }
46795 - if rcb.error() != Err(Error::from(Errno::EINPROGRESS)) &&
46796 - wcb.error() != Err(Error::from(Errno::EINPROGRESS)) {
46797 -@@ -168,8 +180,8 @@ fn test_aio_suspend() {
46798 - }
46799 - }
46800 -
46801 -- assert!(wcb.aio_return().unwrap() as usize == WBUF.len());
46802 -- assert!(rcb.aio_return().unwrap() as usize == rlen);
46803 -+ assert_eq!(wcb.aio_return().unwrap() as usize, WBUF.len());
46804 -+ assert_eq!(rcb.aio_return().unwrap() as usize, rlen);
46805 - }
46806 -
46807 - // Test a simple aio operation with no completion notification. We must poll
46808 -@@ -192,11 +204,11 @@ fn test_read() {
46809 - aiocb.read().unwrap();
46810 -
46811 - let err = poll_aio(&mut aiocb);
46812 -- assert!(err == Ok(()));
46813 -- assert!(aiocb.aio_return().unwrap() as usize == EXPECT.len());
46814 -+ assert_eq!(err, Ok(()));
46815 -+ assert_eq!(aiocb.aio_return().unwrap() as usize, EXPECT.len());
46816 - }
46817 -
46818 -- assert!(EXPECT == rbuf.deref().deref());
46819 -+ assert_eq!(EXPECT, rbuf.deref().deref());
46820 - }
46821 -
46822 - /// `AioCb::read` should not modify the `AioCb` object if `libc::aio_read`
46823 -@@ -238,11 +250,11 @@ fn test_read_into_mut_slice() {
46824 - aiocb.read().unwrap();
46825 -
46826 - let err = poll_aio(&mut aiocb);
46827 -- assert!(err == Ok(()));
46828 -- assert!(aiocb.aio_return().unwrap() as usize == EXPECT.len());
46829 -+ assert_eq!(err, Ok(()));
46830 -+ assert_eq!(aiocb.aio_return().unwrap() as usize, EXPECT.len());
46831 - }
46832 -
46833 -- assert!(rbuf == EXPECT);
46834 -+ assert_eq!(rbuf, EXPECT);
46835 - }
46836 -
46837 - // Tests from_ptr
46838 -@@ -268,11 +280,11 @@ fn test_read_into_pointer() {
46839 - aiocb.read().unwrap();
46840 -
46841 - let err = poll_aio(&mut aiocb);
46842 -- assert!(err == Ok(()));
46843 -- assert!(aiocb.aio_return().unwrap() as usize == EXPECT.len());
46844 -+ assert_eq!(err, Ok(()));
46845 -+ assert_eq!(aiocb.aio_return().unwrap() as usize, EXPECT.len());
46846 - }
46847 -
46848 -- assert!(rbuf == EXPECT);
46849 -+ assert_eq!(rbuf, EXPECT);
46850 - }
46851 -
46852 - // Test reading into an immutable buffer. It should fail
46853 -@@ -314,13 +326,13 @@ fn test_write() {
46854 - aiocb.write().unwrap();
46855 -
46856 - let err = poll_aio(&mut aiocb);
46857 -- assert!(err == Ok(()));
46858 -- assert!(aiocb.aio_return().unwrap() as usize == wbuf.len());
46859 -+ assert_eq!(err, Ok(()));
46860 -+ assert_eq!(aiocb.aio_return().unwrap() as usize, wbuf.len());
46861 -
46862 - f.seek(SeekFrom::Start(0)).unwrap();
46863 - let len = f.read_to_end(&mut rbuf).unwrap();
46864 -- assert!(len == EXPECT.len());
46865 -- assert!(rbuf == EXPECT);
46866 -+ assert_eq!(len, EXPECT.len());
46867 -+ assert_eq!(rbuf, EXPECT);
46868 - }
46869 -
46870 - // Tests `AioCb::from_boxed_slice` with `Bytes`
46871 -@@ -344,13 +356,13 @@ fn test_write_bytes() {
46872 - aiocb.write().unwrap();
46873 -
46874 - let err = poll_aio(&mut aiocb);
46875 -- assert!(err == Ok(()));
46876 -- assert!(aiocb.aio_return().unwrap() as usize == expected_len);
46877 -+ assert_eq!(err, Ok(()));
46878 -+ assert_eq!(aiocb.aio_return().unwrap() as usize, expected_len);
46879 -
46880 - f.seek(SeekFrom::Start(0)).unwrap();
46881 - let len = f.read_to_end(&mut rbuf).unwrap();
46882 -- assert!(len == EXPECT.len());
46883 -- assert!(rbuf == EXPECT);
46884 -+ assert_eq!(len, EXPECT.len());
46885 -+ assert_eq!(rbuf, EXPECT);
46886 - }
46887 -
46888 - // Tests `AioCb::from_boxed_mut_slice` with `BytesMut`
46889 -@@ -402,13 +414,13 @@ fn test_write_from_pointer() {
46890 - aiocb.write().unwrap();
46891 -
46892 - let err = poll_aio(&mut aiocb);
46893 -- assert!(err == Ok(()));
46894 -- assert!(aiocb.aio_return().unwrap() as usize == wbuf.len());
46895 -+ assert_eq!(err, Ok(()));
46896 -+ assert_eq!(aiocb.aio_return().unwrap() as usize, wbuf.len());
46897 -
46898 - f.seek(SeekFrom::Start(0)).unwrap();
46899 - let len = f.read_to_end(&mut rbuf).unwrap();
46900 -- assert!(len == EXPECT.len());
46901 -- assert!(rbuf == EXPECT);
46902 -+ assert_eq!(len, EXPECT.len());
46903 -+ assert_eq!(rbuf, EXPECT);
46904 - }
46905 -
46906 - /// `AioCb::write` should not modify the `AioCb` object if `libc::aio_write`
46907 -@@ -441,7 +453,7 @@ extern fn sigfunc(_: c_int) {
46908 - #[test]
46909 - #[cfg_attr(any(all(target_env = "musl", target_arch = "x86_64"), target_arch = "mips", target_arch = "mips64"), ignore)]
46910 - fn test_write_sigev_signal() {
46911 -- let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
46912 -+ let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
46913 - let sa = SigAction::new(SigHandler::Handler(sigfunc),
46914 - SaFlags::SA_RESETHAND,
46915 - SigSet::empty());
46916 -@@ -469,11 +481,11 @@ fn test_write_sigev_signal() {
46917 - thread::sleep(time::Duration::from_millis(10));
46918 - }
46919 -
46920 -- assert!(aiocb.aio_return().unwrap() as usize == WBUF.len());
46921 -+ assert_eq!(aiocb.aio_return().unwrap() as usize, WBUF.len());
46922 - f.seek(SeekFrom::Start(0)).unwrap();
46923 - let len = f.read_to_end(&mut rbuf).unwrap();
46924 -- assert!(len == EXPECT.len());
46925 -- assert!(rbuf == EXPECT);
46926 -+ assert_eq!(len, EXPECT.len());
46927 -+ assert_eq!(rbuf, EXPECT);
46928 - }
46929 -
46930 - // Test LioCb::listio with LIO_WAIT, so all AIO ops should be complete by the
46931 -@@ -512,15 +524,15 @@ fn test_liocb_listio_wait() {
46932 - let err = liocb.listio(LioMode::LIO_WAIT, SigevNotify::SigevNone);
46933 - err.expect("lio_listio");
46934 -
46935 -- assert!(liocb.aio_return(0).unwrap() as usize == WBUF.len());
46936 -- assert!(liocb.aio_return(1).unwrap() as usize == rlen);
46937 -+ assert_eq!(liocb.aio_return(0).unwrap() as usize, WBUF.len());
46938 -+ assert_eq!(liocb.aio_return(1).unwrap() as usize, rlen);
46939 - }
46940 -- assert!(rbuf.deref().deref() == b"3456");
46941 -+ assert_eq!(rbuf.deref().deref(), b"3456");
46942 -
46943 - f.seek(SeekFrom::Start(0)).unwrap();
46944 - let len = f.read_to_end(&mut rbuf2).unwrap();
46945 -- assert!(len == EXPECT.len());
46946 -- assert!(rbuf2 == EXPECT);
46947 -+ assert_eq!(len, EXPECT.len());
46948 -+ assert_eq!(rbuf2, EXPECT);
46949 - }
46950 -
46951 - // Test LioCb::listio with LIO_NOWAIT and no SigEvent, so we must use some other
46952 -@@ -561,15 +573,15 @@ fn test_liocb_listio_nowait() {
46953 -
46954 - poll_aio(&mut liocb.aiocbs[0]).unwrap();
46955 - poll_aio(&mut liocb.aiocbs[1]).unwrap();
46956 -- assert!(liocb.aiocbs[0].aio_return().unwrap() as usize == WBUF.len());
46957 -- assert!(liocb.aiocbs[1].aio_return().unwrap() as usize == rlen);
46958 -+ assert_eq!(liocb.aiocbs[0].aio_return().unwrap() as usize, WBUF.len());
46959 -+ assert_eq!(liocb.aiocbs[1].aio_return().unwrap() as usize, rlen);
46960 - }
46961 -- assert!(rbuf.deref().deref() == b"3456");
46962 -+ assert_eq!(rbuf.deref().deref(), b"3456");
46963 -
46964 - f.seek(SeekFrom::Start(0)).unwrap();
46965 - let len = f.read_to_end(&mut rbuf2).unwrap();
46966 -- assert!(len == EXPECT.len());
46967 -- assert!(rbuf2 == EXPECT);
46968 -+ assert_eq!(len, EXPECT.len());
46969 -+ assert_eq!(rbuf2, EXPECT);
46970 - }
46971 -
46972 - // Test LioCb::listio with LIO_NOWAIT and a SigEvent to indicate when all
46973 -@@ -579,7 +591,7 @@ fn test_liocb_listio_nowait() {
46974 - #[cfg(not(any(target_os = "ios", target_os = "macos")))]
46975 - #[cfg_attr(any(target_arch = "mips", target_arch = "mips64", target_env = "musl"), ignore)]
46976 - fn test_liocb_listio_signal() {
46977 -- let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
46978 -+ let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
46979 - const INITIAL: &[u8] = b"abcdef123456";
46980 - const WBUF: &[u8] = b"CDEF";
46981 - let mut rbuf = vec![0; 4];
46982 -@@ -620,15 +632,15 @@ fn test_liocb_listio_signal() {
46983 - thread::sleep(time::Duration::from_millis(10));
46984 - }
46985 -
46986 -- assert!(liocb.aiocbs[0].aio_return().unwrap() as usize == WBUF.len());
46987 -- assert!(liocb.aiocbs[1].aio_return().unwrap() as usize == rlen);
46988 -+ assert_eq!(liocb.aiocbs[0].aio_return().unwrap() as usize, WBUF.len());
46989 -+ assert_eq!(liocb.aiocbs[1].aio_return().unwrap() as usize, rlen);
46990 - }
46991 -- assert!(rbuf.deref().deref() == b"3456");
46992 -+ assert_eq!(rbuf.deref().deref(), b"3456");
46993 -
46994 - f.seek(SeekFrom::Start(0)).unwrap();
46995 - let len = f.read_to_end(&mut rbuf2).unwrap();
46996 -- assert!(len == EXPECT.len());
46997 -- assert!(rbuf2 == EXPECT);
46998 -+ assert_eq!(len, EXPECT.len());
46999 -+ assert_eq!(rbuf2, EXPECT);
47000 - }
47001 -
47002 - // Try to use LioCb::listio to read into an immutable buffer. It should fail
47003 -diff --git a/third_party/rust/nix/test/sys/test_aio_drop.rs b/third_party/rust/nix/test/sys/test_aio_drop.rs
47004 -index 492da401ef726..784ee3ef6c75e 100644
47005 ---- a/third_party/rust/nix/test/sys/test_aio_drop.rs
47006 -+++ b/third_party/rust/nix/test/sys/test_aio_drop.rs
47007 -@@ -1,6 +1,3 @@
47008 --extern crate nix;
47009 --extern crate tempfile;
47010 --
47011 - // Test dropping an AioCb that hasn't yet finished.
47012 - // This must happen in its own process, because on OSX this test seems to hose
47013 - // the AIO subsystem and causes subsequent tests to fail
47014 -@@ -12,6 +9,7 @@ extern crate tempfile;
47015 - target_os = "macos",
47016 - target_os = "freebsd",
47017 - target_os = "netbsd")))]
47018 -+#[cfg_attr(target_env = "gnu", ignore = "Occasionally fails in Travis; glibc bug suspected")]
47019 - fn test_drop() {
47020 - use nix::sys::aio::*;
47021 - use nix::sys::signal::*;
47022 -diff --git a/third_party/rust/nix/test/sys/test_ioctl.rs b/third_party/rust/nix/test/sys/test_ioctl.rs
47023 -index 0a439b3346f53..fa4510a69c089 100644
47024 ---- a/third_party/rust/nix/test/sys/test_ioctl.rs
47025 -+++ b/third_party/rust/nix/test/sys/test_ioctl.rs
47026 -@@ -33,22 +33,22 @@ mod linux {
47027 - #[test]
47028 - fn test_op_none() {
47029 - if cfg!(any(target_arch = "mips", target_arch = "mips64", target_arch="powerpc", target_arch="powerpc64")){
47030 -- assert_eq!(request_code_none!(b'q', 10), 0x2000_710A);
47031 -- assert_eq!(request_code_none!(b'a', 255), 0x2000_61FF);
47032 -+ assert_eq!(request_code_none!(b'q', 10) as u32, 0x2000_710A);
47033 -+ assert_eq!(request_code_none!(b'a', 255) as u32, 0x2000_61FF);
47034 - } else {
47035 -- assert_eq!(request_code_none!(b'q', 10), 0x0000_710A);
47036 -- assert_eq!(request_code_none!(b'a', 255), 0x0000_61FF);
47037 -+ assert_eq!(request_code_none!(b'q', 10) as u32, 0x0000_710A);
47038 -+ assert_eq!(request_code_none!(b'a', 255) as u32, 0x0000_61FF);
47039 - }
47040 - }
47041 -
47042 - #[test]
47043 - fn test_op_write() {
47044 - if cfg!(any(target_arch = "mips", target_arch = "mips64", target_arch="powerpc", target_arch="powerpc64")){
47045 -- assert_eq!(request_code_write!(b'z', 10, 1), 0x8001_7A0A);
47046 -- assert_eq!(request_code_write!(b'z', 10, 512), 0x8200_7A0A);
47047 -+ assert_eq!(request_code_write!(b'z', 10, 1) as u32, 0x8001_7A0A);
47048 -+ assert_eq!(request_code_write!(b'z', 10, 512) as u32, 0x8200_7A0A);
47049 - } else {
47050 -- assert_eq!(request_code_write!(b'z', 10, 1), 0x4001_7A0A);
47051 -- assert_eq!(request_code_write!(b'z', 10, 512), 0x4200_7A0A);
47052 -+ assert_eq!(request_code_write!(b'z', 10, 1) as u32, 0x4001_7A0A);
47053 -+ assert_eq!(request_code_write!(b'z', 10, 512) as u32, 0x4200_7A0A);
47054 - }
47055 - }
47056 -
47057 -@@ -56,9 +56,11 @@ mod linux {
47058 - #[test]
47059 - fn test_op_write_64() {
47060 - if cfg!(any(target_arch = "mips64", target_arch="powerpc64")){
47061 -- assert_eq!(request_code_write!(b'z', 10, (1 as u64) << 32), 0x8000_7A0A);
47062 -+ assert_eq!(request_code_write!(b'z', 10, (1 as u64) << 32) as u32,
47063 -+ 0x8000_7A0A);
47064 - } else {
47065 -- assert_eq!(request_code_write!(b'z', 10, (1 as u64) << 32), 0x4000_7A0A);
47066 -+ assert_eq!(request_code_write!(b'z', 10, (1 as u64) << 32) as u32,
47067 -+ 0x4000_7A0A);
47068 - }
47069 -
47070 - }
47071 -@@ -66,11 +68,11 @@ mod linux {
47072 - #[test]
47073 - fn test_op_read() {
47074 - if cfg!(any(target_arch = "mips", target_arch = "mips64", target_arch="powerpc", target_arch="powerpc64")){
47075 -- assert_eq!(request_code_read!(b'z', 10, 1), 0x4001_7A0A);
47076 -- assert_eq!(request_code_read!(b'z', 10, 512), 0x4200_7A0A);
47077 -+ assert_eq!(request_code_read!(b'z', 10, 1) as u32, 0x4001_7A0A);
47078 -+ assert_eq!(request_code_read!(b'z', 10, 512) as u32, 0x4200_7A0A);
47079 - } else {
47080 -- assert_eq!(request_code_read!(b'z', 10, 1), 0x8001_7A0A);
47081 -- assert_eq!(request_code_read!(b'z', 10, 512), 0x8200_7A0A);
47082 -+ assert_eq!(request_code_read!(b'z', 10, 1) as u32, 0x8001_7A0A);
47083 -+ assert_eq!(request_code_read!(b'z', 10, 512) as u32, 0x8200_7A0A);
47084 - }
47085 - }
47086 -
47087 -@@ -78,22 +80,25 @@ mod linux {
47088 - #[test]
47089 - fn test_op_read_64() {
47090 - if cfg!(any(target_arch = "mips64", target_arch="powerpc64")){
47091 -- assert_eq!(request_code_read!(b'z', 10, (1 as u64) << 32), 0x4000_7A0A);
47092 -+ assert_eq!(request_code_read!(b'z', 10, (1 as u64) << 32) as u32,
47093 -+ 0x4000_7A0A);
47094 - } else {
47095 -- assert_eq!(request_code_read!(b'z', 10, (1 as u64) << 32), 0x8000_7A0A);
47096 -+ assert_eq!(request_code_read!(b'z', 10, (1 as u64) << 32) as u32,
47097 -+ 0x8000_7A0A);
47098 - }
47099 - }
47100 -
47101 - #[test]
47102 - fn test_op_read_write() {
47103 -- assert_eq!(request_code_readwrite!(b'z', 10, 1), 0xC001_7A0A);
47104 -- assert_eq!(request_code_readwrite!(b'z', 10, 512), 0xC200_7A0A);
47105 -+ assert_eq!(request_code_readwrite!(b'z', 10, 1) as u32, 0xC001_7A0A);
47106 -+ assert_eq!(request_code_readwrite!(b'z', 10, 512) as u32, 0xC200_7A0A);
47107 - }
47108 -
47109 - #[cfg(target_pointer_width = "64")]
47110 - #[test]
47111 - fn test_op_read_write_64() {
47112 -- assert_eq!(request_code_readwrite!(b'z', 10, (1 as u64) << 32), 0xC000_7A0A);
47113 -+ assert_eq!(request_code_readwrite!(b'z', 10, (1 as u64) << 32) as u32,
47114 -+ 0xC000_7A0A);
47115 - }
47116 - }
47117 -
47118 -@@ -177,7 +182,7 @@ mod linux_ioctls {
47119 - #[test]
47120 - fn test_ioctl_read_bad() {
47121 - let file = tempfile().unwrap();
47122 -- let mut termios = unsafe { mem::uninitialized() };
47123 -+ let mut termios = unsafe { mem::zeroed() };
47124 - let res = unsafe { tcgets(file.as_raw_fd(), &mut termios) };
47125 - assert_eq!(res, Err(Sys(ENOTTY)));
47126 - }
47127 -@@ -194,7 +199,7 @@ mod linux_ioctls {
47128 - #[test]
47129 - fn test_ioctl_write_ptr_bad() {
47130 - let file = tempfile().unwrap();
47131 -- let termios: termios = unsafe { mem::uninitialized() };
47132 -+ let termios: termios = unsafe { mem::zeroed() };
47133 - let res = unsafe { tcsets(file.as_raw_fd(), &termios) };
47134 - assert_eq!(res, Err(Sys(ENOTTY)));
47135 - }
47136 -@@ -245,7 +250,7 @@ mod linux_ioctls {
47137 - #[test]
47138 - fn test_ioctl_read() {
47139 - let file = tempfile().unwrap();
47140 -- let mut data: v4l2_audio = unsafe { mem::uninitialized() };
47141 -+ let mut data: v4l2_audio = unsafe { mem::zeroed() };
47142 - let res = unsafe { g_audio(file.as_raw_fd(), &mut data) };
47143 - assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
47144 - }
47145 -@@ -255,7 +260,7 @@ mod linux_ioctls {
47146 - #[test]
47147 - fn test_ioctl_readwrite() {
47148 - let file = tempfile().unwrap();
47149 -- let mut data: v4l2_audio = unsafe { mem::uninitialized() };
47150 -+ let mut data: v4l2_audio = unsafe { mem::zeroed() };
47151 - let res = unsafe { enum_audio(file.as_raw_fd(), &mut data) };
47152 - assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS)));
47153 - }
47154 -@@ -318,7 +323,7 @@ mod freebsd_ioctls {
47155 - #[test]
47156 - fn test_ioctl_read() {
47157 - let file = tempfile().unwrap();
47158 -- let mut termios = unsafe { mem::uninitialized() };
47159 -+ let mut termios = unsafe { mem::zeroed() };
47160 - let res = unsafe { tiocgeta(file.as_raw_fd(), &mut termios) };
47161 - assert_eq!(res, Err(Sys(ENOTTY)));
47162 - }
47163 -@@ -327,7 +332,7 @@ mod freebsd_ioctls {
47164 - #[test]
47165 - fn test_ioctl_write_ptr() {
47166 - let file = tempfile().unwrap();
47167 -- let termios: termios = unsafe { mem::uninitialized() };
47168 -+ let termios: termios = unsafe { mem::zeroed() };
47169 - let res = unsafe { tiocseta(file.as_raw_fd(), &termios) };
47170 - assert_eq!(res, Err(Sys(ENOTTY)));
47171 - }
47172 -diff --git a/third_party/rust/nix/test/sys/test_lio_listio_resubmit.rs b/third_party/rust/nix/test/sys/test_lio_listio_resubmit.rs
47173 -index 19ee3facf87d7..0795370b8c448 100644
47174 ---- a/third_party/rust/nix/test/sys/test_lio_listio_resubmit.rs
47175 -+++ b/third_party/rust/nix/test/sys/test_lio_listio_resubmit.rs
47176 -@@ -4,10 +4,6 @@
47177 - // we must disable the test here rather than in Cargo.toml
47178 - #![cfg(target_os = "freebsd")]
47179 -
47180 --extern crate nix;
47181 --extern crate sysctl;
47182 --extern crate tempfile;
47183 --
47184 - use nix::Error;
47185 - use nix::errno::*;
47186 - use nix::libc::off_t;
47187 -diff --git a/third_party/rust/nix/test/sys/test_mman.rs b/third_party/rust/nix/test/sys/test_mman.rs
47188 -new file mode 100644
47189 -index 0000000000000..152fff69c24de
47190 ---- /dev/null
47191 -+++ b/third_party/rust/nix/test/sys/test_mman.rs
47192 -@@ -0,0 +1,80 @@
47193 -+use nix::Error;
47194 -+use nix::libc::{c_void, size_t};
47195 -+use nix::sys::mman::{mmap, MapFlags, ProtFlags};
47196 -+
47197 -+#[cfg(target_os = "linux")]
47198 -+use nix::sys::mman::{mremap, MRemapFlags};
47199 -+
47200 -+#[test]
47201 -+fn test_mmap_anonymous() {
47202 -+ let ref mut byte = unsafe {
47203 -+ let ptr = mmap(std::ptr::null_mut(), 1,
47204 -+ ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
47205 -+ MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS, -1, 0)
47206 -+ .unwrap();
47207 -+ *(ptr as * mut u8)
47208 -+ };
47209 -+ assert_eq !(*byte, 0x00u8);
47210 -+ *byte = 0xffu8;
47211 -+ assert_eq !(*byte, 0xffu8);
47212 -+}
47213 -+
47214 -+#[test]
47215 -+#[cfg(target_os = "linux")]
47216 -+fn test_mremap_grow() {
47217 -+ const ONE_K : size_t = 1024;
47218 -+ let slice : &mut[u8] = unsafe {
47219 -+ let mem = mmap(std::ptr::null_mut(), ONE_K,
47220 -+ ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
47221 -+ MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE, -1, 0)
47222 -+ .unwrap();
47223 -+ std::slice::from_raw_parts_mut(mem as * mut u8, ONE_K)
47224 -+ };
47225 -+ assert_eq !(slice[ONE_K - 1], 0x00);
47226 -+ slice[ONE_K - 1] = 0xFF;
47227 -+ assert_eq !(slice[ONE_K - 1], 0xFF);
47228 -+
47229 -+ let slice : &mut[u8] = unsafe {
47230 -+ let mem = mremap(slice.as_mut_ptr() as * mut c_void, ONE_K, 10 * ONE_K,
47231 -+ MRemapFlags::MREMAP_MAYMOVE, None)
47232 -+ .unwrap();
47233 -+ std::slice::from_raw_parts_mut(mem as * mut u8, 10 * ONE_K)
47234 -+ };
47235 -+
47236 -+ // The first KB should still have the old data in it.
47237 -+ assert_eq !(slice[ONE_K - 1], 0xFF);
47238 -+
47239 -+ // The additional range should be zero-init'd and accessible.
47240 -+ assert_eq !(slice[10 * ONE_K - 1], 0x00);
47241 -+ slice[10 * ONE_K - 1] = 0xFF;
47242 -+ assert_eq !(slice[10 * ONE_K - 1], 0xFF);
47243 -+}
47244 -+
47245 -+#[test]
47246 -+#[cfg(target_os = "linux")]
47247 -+fn test_mremap_shrink() {
47248 -+ const ONE_K : size_t = 1024;
47249 -+ let slice : &mut[u8] = unsafe {
47250 -+ let mem = mmap(std::ptr::null_mut(), 10 * ONE_K,
47251 -+ ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
47252 -+ MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE, -1, 0)
47253 -+ .unwrap();
47254 -+ std::slice::from_raw_parts_mut(mem as * mut u8, ONE_K)
47255 -+ };
47256 -+ assert_eq !(slice[ONE_K - 1], 0x00);
47257 -+ slice[ONE_K - 1] = 0xFF;
47258 -+ assert_eq !(slice[ONE_K - 1], 0xFF);
47259 -+
47260 -+ let slice : &mut[u8] = unsafe {
47261 -+ let mem = mremap(slice.as_mut_ptr() as * mut c_void, 10 * ONE_K, ONE_K,
47262 -+ MRemapFlags::empty(), None)
47263 -+ .unwrap();
47264 -+ // Since we didn't supply MREMAP_MAYMOVE, the address should be the
47265 -+ // same.
47266 -+ assert_eq !(mem, slice.as_mut_ptr() as * mut c_void);
47267 -+ std::slice::from_raw_parts_mut(mem as * mut u8, ONE_K)
47268 -+ };
47269 -+
47270 -+ // The first KB should still be accessible and have the old data in it.
47271 -+ assert_eq !(slice[ONE_K - 1], 0xFF);
47272 -+}
47273 -diff --git a/third_party/rust/nix/test/sys/test_pthread.rs b/third_party/rust/nix/test/sys/test_pthread.rs
47274 -index 8928010087a13..1fc3dd900f382 100644
47275 ---- a/third_party/rust/nix/test/sys/test_pthread.rs
47276 -+++ b/third_party/rust/nix/test/sys/test_pthread.rs
47277 -@@ -1,13 +1,13 @@
47278 - use nix::sys::pthread::*;
47279 -
47280 --#[cfg(target_env = "musl")]
47281 -+#[cfg(any(target_env = "musl", target_os = "redox"))]
47282 - #[test]
47283 - fn test_pthread_self() {
47284 - let tid = pthread_self();
47285 - assert!(tid != ::std::ptr::null_mut());
47286 - }
47287 -
47288 --#[cfg(not(target_env = "musl"))]
47289 -+#[cfg(not(any(target_env = "musl", target_os = "redox")))]
47290 - #[test]
47291 - fn test_pthread_self() {
47292 - let tid = pthread_self();
47293 -diff --git a/third_party/rust/nix/test/sys/test_ptrace.rs b/third_party/rust/nix/test/sys/test_ptrace.rs
47294 -index 24d9b522ee4e5..b9793b39c54ae 100644
47295 ---- a/third_party/rust/nix/test/sys/test_ptrace.rs
47296 -+++ b/third_party/rust/nix/test/sys/test_ptrace.rs
47297 -@@ -8,10 +8,13 @@ use nix::sys::ptrace::Options;
47298 - #[cfg(any(target_os = "android", target_os = "linux"))]
47299 - use std::mem;
47300 -
47301 -+use crate::*;
47302 -+
47303 - #[test]
47304 - fn test_ptrace() {
47305 - // Just make sure ptrace can be called at all, for now.
47306 - // FIXME: qemu-user doesn't implement ptrace on all arches, so permit ENOSYS
47307 -+ require_capability!(CAP_SYS_PTRACE);
47308 - let err = ptrace::attach(getpid()).unwrap_err();
47309 - assert!(err == Error::Sys(Errno::EPERM) || err == Error::Sys(Errno::EINVAL) ||
47310 - err == Error::Sys(Errno::ENOSYS));
47311 -@@ -21,6 +24,7 @@ fn test_ptrace() {
47312 - #[test]
47313 - #[cfg(any(target_os = "android", target_os = "linux"))]
47314 - fn test_ptrace_setoptions() {
47315 -+ require_capability!(CAP_SYS_PTRACE);
47316 - let err = ptrace::setoptions(getpid(), Options::PTRACE_O_TRACESYSGOOD).unwrap_err();
47317 - assert!(err != Error::UnsupportedOperation);
47318 - }
47319 -@@ -29,6 +33,7 @@ fn test_ptrace_setoptions() {
47320 - #[test]
47321 - #[cfg(any(target_os = "android", target_os = "linux"))]
47322 - fn test_ptrace_getevent() {
47323 -+ require_capability!(CAP_SYS_PTRACE);
47324 - let err = ptrace::getevent(getpid()).unwrap_err();
47325 - assert!(err != Error::UnsupportedOperation);
47326 - }
47327 -@@ -37,6 +42,7 @@ fn test_ptrace_getevent() {
47328 - #[test]
47329 - #[cfg(any(target_os = "android", target_os = "linux"))]
47330 - fn test_ptrace_getsiginfo() {
47331 -+ require_capability!(CAP_SYS_PTRACE);
47332 - if let Err(Error::UnsupportedOperation) = ptrace::getsiginfo(getpid()) {
47333 - panic!("ptrace_getsiginfo returns Error::UnsupportedOperation!");
47334 - }
47335 -@@ -46,7 +52,8 @@ fn test_ptrace_getsiginfo() {
47336 - #[test]
47337 - #[cfg(any(target_os = "android", target_os = "linux"))]
47338 - fn test_ptrace_setsiginfo() {
47339 -- let siginfo = unsafe { mem::uninitialized() };
47340 -+ require_capability!(CAP_SYS_PTRACE);
47341 -+ let siginfo = unsafe { mem::zeroed() };
47342 - if let Err(Error::UnsupportedOperation) = ptrace::setsiginfo(getpid(), &siginfo) {
47343 - panic!("ptrace_setsiginfo returns Error::UnsupportedOperation!");
47344 - }
47345 -@@ -61,7 +68,9 @@ fn test_ptrace_cont() {
47346 - use nix::unistd::fork;
47347 - use nix::unistd::ForkResult::*;
47348 -
47349 -- let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
47350 -+ require_capability!(CAP_SYS_PTRACE);
47351 -+
47352 -+ let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test");
47353 -
47354 - // FIXME: qemu-user doesn't implement ptrace on all architectures
47355 - // and retunrs ENOSYS in this case.
47356 -@@ -74,7 +83,7 @@ fn test_ptrace_cont() {
47357 - return;
47358 - }
47359 -
47360 -- match fork().expect("Error: Fork Failed") {
47361 -+ match unsafe{fork()}.expect("Error: Fork Failed") {
47362 - Child => {
47363 - ptrace::traceme().unwrap();
47364 - // As recommended by ptrace(2), raise SIGTRAP to pause the child
47365 -@@ -91,7 +100,7 @@ fn test_ptrace_cont() {
47366 - ptrace::cont(child, Some(Signal::SIGKILL)).unwrap();
47367 - match waitpid(child, None) {
47368 - Ok(WaitStatus::Signaled(pid, Signal::SIGKILL, _)) if pid == child => {
47369 -- // FIXME It's been observed on some systems (apple) the
47370 -+ // FIXME It's been observed on some systems (apple) the
47371 - // tracee may not be killed but remain as a zombie process
47372 - // affecting other wait based tests. Add an extra kill just
47373 - // to make sure there are no zombies.
47374 -@@ -105,3 +114,65 @@ fn test_ptrace_cont() {
47375 - },
47376 - }
47377 - }
47378 -+
47379 -+// ptrace::{setoptions, getregs} are only available in these platforms
47380 -+#[cfg(all(target_os = "linux",
47381 -+ any(target_arch = "x86_64",
47382 -+ target_arch = "x86"),
47383 -+ target_env = "gnu"))]
47384 -+#[test]
47385 -+fn test_ptrace_syscall() {
47386 -+ use nix::sys::signal::kill;
47387 -+ use nix::sys::ptrace;
47388 -+ use nix::sys::signal::Signal;
47389 -+ use nix::sys::wait::{waitpid, WaitStatus};
47390 -+ use nix::unistd::fork;
47391 -+ use nix::unistd::getpid;
47392 -+ use nix::unistd::ForkResult::*;
47393 -+
47394 -+ require_capability!(CAP_SYS_PTRACE);
47395 -+
47396 -+ let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test");
47397 -+
47398 -+ match unsafe{fork()}.expect("Error: Fork Failed") {
47399 -+ Child => {
47400 -+ ptrace::traceme().unwrap();
47401 -+ // first sigstop until parent is ready to continue
47402 -+ let pid = getpid();
47403 -+ kill(pid, Signal::SIGSTOP).unwrap();
47404 -+ kill(pid, Signal::SIGTERM).unwrap();
47405 -+ unsafe { ::libc::_exit(0); }
47406 -+ },
47407 -+
47408 -+ Parent { child } => {
47409 -+ assert_eq!(waitpid(child, None), Ok(WaitStatus::Stopped(child, Signal::SIGSTOP)));
47410 -+
47411 -+ // set this option to recognize syscall-stops
47412 -+ ptrace::setoptions(child, ptrace::Options::PTRACE_O_TRACESYSGOOD).unwrap();
47413 -+
47414 -+ #[cfg(target_arch = "x86_64")]
47415 -+ let get_syscall_id = || ptrace::getregs(child).unwrap().orig_rax as libc::c_long;
47416 -+
47417 -+ #[cfg(target_arch = "x86")]
47418 -+ let get_syscall_id = || ptrace::getregs(child).unwrap().orig_eax as libc::c_long;
47419 -+
47420 -+ // kill entry
47421 -+ ptrace::syscall(child, None).unwrap();
47422 -+ assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceSyscall(child)));
47423 -+ assert_eq!(get_syscall_id(), ::libc::SYS_kill);
47424 -+
47425 -+ // kill exit
47426 -+ ptrace::syscall(child, None).unwrap();
47427 -+ assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceSyscall(child)));
47428 -+ assert_eq!(get_syscall_id(), ::libc::SYS_kill);
47429 -+
47430 -+ // receive signal
47431 -+ ptrace::syscall(child, None).unwrap();
47432 -+ assert_eq!(waitpid(child, None), Ok(WaitStatus::Stopped(child, Signal::SIGTERM)));
47433 -+
47434 -+ // inject signal
47435 -+ ptrace::syscall(child, Signal::SIGTERM).unwrap();
47436 -+ assert_eq!(waitpid(child, None), Ok(WaitStatus::Signaled(child, Signal::SIGTERM, false)));
47437 -+ },
47438 -+ }
47439 -+}
47440 -diff --git a/third_party/rust/nix/test/sys/test_select.rs b/third_party/rust/nix/test/sys/test_select.rs
47441 -index cf68700c5e16f..37951086c2d8d 100644
47442 ---- a/third_party/rust/nix/test/sys/test_select.rs
47443 -+++ b/third_party/rust/nix/test/sys/test_select.rs
47444 -@@ -5,7 +5,7 @@ use nix::sys::time::{TimeSpec, TimeValLike};
47445 -
47446 - #[test]
47447 - pub fn test_pselect() {
47448 -- let _mtx = ::SIGNAL_MTX
47449 -+ let _mtx = crate::SIGNAL_MTX
47450 - .lock()
47451 - .expect("Mutex got poisoned by another test");
47452 -
47453 -diff --git a/third_party/rust/nix/test/sys/test_signal.rs b/third_party/rust/nix/test/sys/test_signal.rs
47454 -index 8780763f773ef..ae22527fde278 100644
47455 ---- a/third_party/rust/nix/test/sys/test_signal.rs
47456 -+++ b/third_party/rust/nix/test/sys/test_signal.rs
47457 -@@ -1,7 +1,9 @@
47458 - use libc;
47459 -+#[cfg(not(target_os = "redox"))]
47460 - use nix::Error;
47461 - use nix::sys::signal::*;
47462 - use nix::unistd::*;
47463 -+use std::convert::TryFrom;
47464 - use std::sync::atomic::{AtomicBool, Ordering};
47465 -
47466 - #[test]
47467 -@@ -10,6 +12,7 @@ fn test_kill_none() {
47468 - }
47469 -
47470 - #[test]
47471 -+#[cfg(not(target_os = "fuchsia"))]
47472 - fn test_killpg_none() {
47473 - killpg(getpgrp(), None)
47474 - .expect("Should be able to send signal to my process group.");
47475 -@@ -17,6 +20,8 @@ fn test_killpg_none() {
47476 -
47477 - #[test]
47478 - fn test_old_sigaction_flags() {
47479 -+ let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
47480 -+
47481 - extern "C" fn handler(_: ::libc::c_int) {}
47482 - let act = SigAction::new(
47483 - SigHandler::Handler(handler),
47484 -@@ -37,7 +42,7 @@ fn test_sigprocmask_noop() {
47485 -
47486 - #[test]
47487 - fn test_sigprocmask() {
47488 -- let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
47489 -+ let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
47490 -
47491 - // This needs to be a signal that rust doesn't use in the test harness.
47492 - const SIGNAL: Signal = Signal::SIGCHLD;
47493 -@@ -75,16 +80,25 @@ lazy_static! {
47494 - }
47495 -
47496 - extern fn test_sigaction_handler(signal: libc::c_int) {
47497 -- let signal = Signal::from_c_int(signal).unwrap();
47498 -+ let signal = Signal::try_from(signal).unwrap();
47499 - SIGNALED.store(signal == Signal::SIGINT, Ordering::Relaxed);
47500 - }
47501 -
47502 --extern fn test_sigaction_action(_: libc::c_int, _: *mut libc::siginfo_t, _: *mut libc::c_void) {
47503 -+#[cfg(not(target_os = "redox"))]
47504 -+extern fn test_sigaction_action(_: libc::c_int, _: *mut libc::siginfo_t, _: *mut libc::c_void) {}
47505 -+
47506 -+#[test]
47507 -+#[cfg(not(target_os = "redox"))]
47508 -+fn test_signal_sigaction() {
47509 -+ let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
47510 -+
47511 -+ let action_handler = SigHandler::SigAction(test_sigaction_action);
47512 -+ assert_eq!(unsafe { signal(Signal::SIGINT, action_handler) }.unwrap_err(), Error::UnsupportedOperation);
47513 - }
47514 -
47515 - #[test]
47516 - fn test_signal() {
47517 -- let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
47518 -+ let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
47519 -
47520 - unsafe { signal(Signal::SIGINT, SigHandler::SigIgn) }.unwrap();
47521 - raise(Signal::SIGINT).unwrap();
47522 -@@ -96,9 +110,6 @@ fn test_signal() {
47523 - assert!(SIGNALED.load(Ordering::Relaxed));
47524 - assert_eq!(unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(), handler);
47525 -
47526 -- let action_handler = SigHandler::SigAction(test_sigaction_action);
47527 -- assert_eq!(unsafe { signal(Signal::SIGINT, action_handler) }.unwrap_err(), Error::UnsupportedOperation);
47528 --
47529 - // Restore default signal handler
47530 - unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap();
47531 - }
47532 -diff --git a/third_party/rust/nix/test/sys/test_signalfd.rs b/third_party/rust/nix/test/sys/test_signalfd.rs
47533 -index a3b6098841f1c..af04c222852d8 100644
47534 ---- a/third_party/rust/nix/test/sys/test_signalfd.rs
47535 -+++ b/third_party/rust/nix/test/sys/test_signalfd.rs
47536 -@@ -1,10 +1,12 @@
47537 -+use std::convert::TryFrom;
47538 -+
47539 - #[test]
47540 - fn test_signalfd() {
47541 - use nix::sys::signalfd::SignalFd;
47542 - use nix::sys::signal::{self, raise, Signal, SigSet};
47543 -
47544 - // Grab the mutex for altering signals so we don't interfere with other tests.
47545 -- let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
47546 -+ let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
47547 -
47548 - // Block the SIGUSR1 signal from automatic processing for this thread
47549 - let mut mask = SigSet::empty();
47550 -@@ -20,6 +22,6 @@ fn test_signalfd() {
47551 -
47552 - // And now catch that same signal.
47553 - let res = fd.read_signal().unwrap().unwrap();
47554 -- let signo = Signal::from_c_int(res.ssi_signo as i32).unwrap();
47555 -+ let signo = Signal::try_from(res.ssi_signo as i32).unwrap();
47556 - assert_eq!(signo, signal::SIGUSR1);
47557 - }
47558 -diff --git a/third_party/rust/nix/test/sys/test_socket.rs b/third_party/rust/nix/test/sys/test_socket.rs
47559 -index 7e64d2b77f071..2b89a45336f3e 100644
47560 ---- a/third_party/rust/nix/test/sys/test_socket.rs
47561 -+++ b/third_party/rust/nix/test/sys/test_socket.rs
47562 -@@ -1,4 +1,3 @@
47563 --use nix::ifaddrs::InterfaceAddress;
47564 - use nix::sys::socket::{AddressFamily, InetAddr, UnixAddr, getsockname};
47565 - use std::collections::hash_map::DefaultHasher;
47566 - use std::hash::{Hash, Hasher};
47567 -@@ -9,6 +8,8 @@ use std::slice;
47568 - use std::str::FromStr;
47569 - use libc::c_char;
47570 - use tempfile;
47571 -+#[cfg(any(target_os = "linux", target_os= "android"))]
47572 -+use crate::*;
47573 -
47574 - #[test]
47575 - pub fn test_inetv4_addr_to_sock_addr() {
47576 -@@ -106,7 +107,7 @@ pub fn test_addr_equality_abstract() {
47577 - assert_eq!(addr1, addr2);
47578 - assert_eq!(calculate_hash(&addr1), calculate_hash(&addr2));
47579 -
47580 -- addr2.0.sun_path[18] = 127;
47581 -+ addr2.0.sun_path[17] = 127;
47582 - assert_ne!(addr1, addr2);
47583 - assert_ne!(calculate_hash(&addr1), calculate_hash(&addr2));
47584 - }
47585 -@@ -117,16 +118,13 @@ pub fn test_addr_equality_abstract() {
47586 - pub fn test_abstract_uds_addr() {
47587 - let empty = String::new();
47588 - let addr = UnixAddr::new_abstract(empty.as_bytes()).unwrap();
47589 -- let sun_path = [0u8; 107];
47590 -+ let sun_path: [u8; 0] = [];
47591 - assert_eq!(addr.as_abstract(), Some(&sun_path[..]));
47592 -
47593 - let name = String::from("nix\0abstract\0test");
47594 - let addr = UnixAddr::new_abstract(name.as_bytes()).unwrap();
47595 - let sun_path = [
47596 -- 110u8, 105, 120, 0, 97, 98, 115, 116, 114, 97, 99, 116, 0, 116, 101, 115, 116, 0, 0, 0, 0,
47597 -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47598 -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47599 -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47600 -+ 110u8, 105, 120, 0, 97, 98, 115, 116, 114, 97, 99, 116, 0, 116, 101, 115, 116
47601 - ];
47602 - assert_eq!(addr.as_abstract(), Some(&sun_path[..]));
47603 - assert_eq!(addr.path(), None);
47604 -@@ -164,6 +162,360 @@ pub fn test_socketpair() {
47605 - assert_eq!(&buf[..], b"hello");
47606 - }
47607 -
47608 -+mod recvfrom {
47609 -+ use nix::Result;
47610 -+ use nix::sys::socket::*;
47611 -+ use std::thread;
47612 -+ use super::*;
47613 -+
47614 -+ const MSG: &'static [u8] = b"Hello, World!";
47615 -+
47616 -+ fn sendrecv<Fs, Fr>(rsock: RawFd, ssock: RawFd, f_send: Fs, mut f_recv: Fr) -> Option<SockAddr>
47617 -+ where
47618 -+ Fs: Fn(RawFd, &[u8], MsgFlags) -> Result<usize> + Send + 'static,
47619 -+ Fr: FnMut(usize, Option<SockAddr>),
47620 -+ {
47621 -+ let mut buf: [u8; 13] = [0u8; 13];
47622 -+ let mut l = 0;
47623 -+ let mut from = None;
47624 -+
47625 -+ let send_thread = thread::spawn(move || {
47626 -+ let mut l = 0;
47627 -+ while l < std::mem::size_of_val(MSG) {
47628 -+ l += f_send(ssock, &MSG[l..], MsgFlags::empty()).unwrap();
47629 -+ }
47630 -+ });
47631 -+
47632 -+ while l < std::mem::size_of_val(MSG) {
47633 -+ let (len, from_) = recvfrom(rsock, &mut buf[l..]).unwrap();
47634 -+ f_recv(len, from_);
47635 -+ from = from_;
47636 -+ l += len;
47637 -+ }
47638 -+ assert_eq!(&buf, MSG);
47639 -+ send_thread.join().unwrap();
47640 -+ from
47641 -+ }
47642 -+
47643 -+ #[test]
47644 -+ pub fn stream() {
47645 -+ let (fd2, fd1) = socketpair(AddressFamily::Unix, SockType::Stream,
47646 -+ None, SockFlag::empty()).unwrap();
47647 -+ // Ignore from for stream sockets
47648 -+ let _ = sendrecv(fd1, fd2, |s, m, flags| {
47649 -+ send(s, m, flags)
47650 -+ }, |_, _| {});
47651 -+ }
47652 -+
47653 -+ #[test]
47654 -+ pub fn udp() {
47655 -+ let std_sa = SocketAddr::from_str("127.0.0.1:6789").unwrap();
47656 -+ let inet_addr = InetAddr::from_std(&std_sa);
47657 -+ let sock_addr = SockAddr::new_inet(inet_addr);
47658 -+ let rsock = socket(AddressFamily::Inet,
47659 -+ SockType::Datagram,
47660 -+ SockFlag::empty(),
47661 -+ None
47662 -+ ).unwrap();
47663 -+ bind(rsock, &sock_addr).unwrap();
47664 -+ let ssock = socket(
47665 -+ AddressFamily::Inet,
47666 -+ SockType::Datagram,
47667 -+ SockFlag::empty(),
47668 -+ None,
47669 -+ ).expect("send socket failed");
47670 -+ let from = sendrecv(rsock, ssock, move |s, m, flags| {
47671 -+ sendto(s, m, &sock_addr, flags)
47672 -+ },|_, _| {});
47673 -+ // UDP sockets should set the from address
47674 -+ assert_eq!(AddressFamily::Inet, from.unwrap().family());
47675 -+ }
47676 -+
47677 -+ #[cfg(target_os = "linux")]
47678 -+ mod udp_offload {
47679 -+ use super::*;
47680 -+ use nix::sys::uio::IoVec;
47681 -+ use nix::sys::socket::sockopt::{UdpGroSegment, UdpGsoSegment};
47682 -+
47683 -+ #[test]
47684 -+ // Disable the test on emulated platforms because it fails in Cirrus-CI. Lack of QEMU
47685 -+ // support is suspected.
47686 -+ #[cfg_attr(not(any(target_arch = "x86_64", target_arch="i686")), ignore)]
47687 -+ pub fn gso() {
47688 -+ require_kernel_version!(udp_offload::gso, ">= 4.18");
47689 -+
47690 -+ // In this test, we send the data and provide a GSO segment size.
47691 -+ // Since we are sending the buffer of size 13, six UDP packets
47692 -+ // with size 2 and two UDP packet with size 1 will be sent.
47693 -+ let segment_size: u16 = 2;
47694 -+
47695 -+ let std_sa = SocketAddr::from_str("127.0.0.1:6791").unwrap();
47696 -+ let inet_addr = InetAddr::from_std(&std_sa);
47697 -+ let sock_addr = SockAddr::new_inet(inet_addr);
47698 -+ let rsock = socket(AddressFamily::Inet,
47699 -+ SockType::Datagram,
47700 -+ SockFlag::empty(),
47701 -+ None
47702 -+ ).unwrap();
47703 -+
47704 -+ setsockopt(rsock, UdpGsoSegment, &(segment_size as _))
47705 -+ .expect("setsockopt UDP_SEGMENT failed");
47706 -+
47707 -+ bind(rsock, &sock_addr).unwrap();
47708 -+ let ssock = socket(
47709 -+ AddressFamily::Inet,
47710 -+ SockType::Datagram,
47711 -+ SockFlag::empty(),
47712 -+ None,
47713 -+ ).expect("send socket failed");
47714 -+
47715 -+ let mut num_packets_received: i32 = 0;
47716 -+
47717 -+ sendrecv(rsock, ssock, move |s, m, flags| {
47718 -+ let iov = [IoVec::from_slice(m)];
47719 -+ let cmsg = ControlMessage::UdpGsoSegments(&segment_size);
47720 -+ sendmsg(s, &iov, &[cmsg], flags, Some(&sock_addr))
47721 -+ }, {
47722 -+ let num_packets_received_ref = &mut num_packets_received;
47723 -+
47724 -+ move |len, _| {
47725 -+ // check that we receive UDP packets with payload size
47726 -+ // less or equal to segment size
47727 -+ assert!(len <= segment_size as usize);
47728 -+ *num_packets_received_ref += 1;
47729 -+ }
47730 -+ });
47731 -+
47732 -+ // Buffer size is 13, we will receive six packets of size 2,
47733 -+ // and one packet of size 1.
47734 -+ assert_eq!(7, num_packets_received);
47735 -+ }
47736 -+
47737 -+ #[test]
47738 -+ // Disable the test on emulated platforms because it fails in Cirrus-CI. Lack of QEMU
47739 -+ // support is suspected.
47740 -+ #[cfg_attr(not(any(target_arch = "x86_64", target_arch="i686")), ignore)]
47741 -+ pub fn gro() {
47742 -+ require_kernel_version!(udp_offload::gro, ">= 5.3");
47743 -+
47744 -+ // It's hard to guarantee receiving GRO packets. Just checking
47745 -+ // that `setsockopt` doesn't fail with error
47746 -+
47747 -+ let rsock = socket(AddressFamily::Inet,
47748 -+ SockType::Datagram,
47749 -+ SockFlag::empty(),
47750 -+ None
47751 -+ ).unwrap();
47752 -+
47753 -+ setsockopt(rsock, UdpGroSegment, &true)
47754 -+ .expect("setsockopt UDP_GRO failed");
47755 -+ }
47756 -+ }
47757 -+
47758 -+ #[cfg(any(
47759 -+ target_os = "linux",
47760 -+ target_os = "android",
47761 -+ target_os = "freebsd",
47762 -+ target_os = "netbsd",
47763 -+ ))]
47764 -+ #[test]
47765 -+ pub fn udp_sendmmsg() {
47766 -+ use nix::sys::uio::IoVec;
47767 -+
47768 -+ let std_sa = SocketAddr::from_str("127.0.0.1:6793").unwrap();
47769 -+ let std_sa2 = SocketAddr::from_str("127.0.0.1:6794").unwrap();
47770 -+ let inet_addr = InetAddr::from_std(&std_sa);
47771 -+ let inet_addr2 = InetAddr::from_std(&std_sa2);
47772 -+ let sock_addr = SockAddr::new_inet(inet_addr);
47773 -+ let sock_addr2 = SockAddr::new_inet(inet_addr2);
47774 -+
47775 -+ let rsock = socket(AddressFamily::Inet,
47776 -+ SockType::Datagram,
47777 -+ SockFlag::empty(),
47778 -+ None
47779 -+ ).unwrap();
47780 -+ bind(rsock, &sock_addr).unwrap();
47781 -+ let ssock = socket(
47782 -+ AddressFamily::Inet,
47783 -+ SockType::Datagram,
47784 -+ SockFlag::empty(),
47785 -+ None,
47786 -+ ).expect("send socket failed");
47787 -+
47788 -+ let from = sendrecv(rsock, ssock, move |s, m, flags| {
47789 -+ let iov = [IoVec::from_slice(m)];
47790 -+ let mut msgs = Vec::new();
47791 -+ msgs.push(
47792 -+ SendMmsgData {
47793 -+ iov: &iov,
47794 -+ cmsgs: &[],
47795 -+ addr: Some(sock_addr),
47796 -+ _lt: Default::default(),
47797 -+ });
47798 -+
47799 -+ let batch_size = 15;
47800 -+
47801 -+ for _ in 0..batch_size {
47802 -+ msgs.push(
47803 -+ SendMmsgData {
47804 -+ iov: &iov,
47805 -+ cmsgs: &[],
47806 -+ addr: Some(sock_addr2),
47807 -+ _lt: Default::default(),
47808 -+ }
47809 -+ );
47810 -+ }
47811 -+ sendmmsg(s, msgs.iter(), flags)
47812 -+ .map(move |sent_bytes| {
47813 -+ assert!(sent_bytes.len() >= 1);
47814 -+ for sent in &sent_bytes {
47815 -+ assert_eq!(*sent, m.len());
47816 -+ }
47817 -+ sent_bytes.len()
47818 -+ })
47819 -+ }, |_, _ | {});
47820 -+ // UDP sockets should set the from address
47821 -+ assert_eq!(AddressFamily::Inet, from.unwrap().family());
47822 -+ }
47823 -+
47824 -+ #[cfg(any(
47825 -+ target_os = "linux",
47826 -+ target_os = "android",
47827 -+ target_os = "freebsd",
47828 -+ target_os = "netbsd",
47829 -+ ))]
47830 -+ #[test]
47831 -+ pub fn udp_recvmmsg() {
47832 -+ use nix::sys::uio::IoVec;
47833 -+ use nix::sys::socket::{MsgFlags, recvmmsg};
47834 -+
47835 -+ const NUM_MESSAGES_SENT: usize = 2;
47836 -+ const DATA: [u8; 2] = [1,2];
47837 -+
47838 -+ let std_sa = SocketAddr::from_str("127.0.0.1:6798").unwrap();
47839 -+ let inet_addr = InetAddr::from_std(&std_sa);
47840 -+ let sock_addr = SockAddr::new_inet(inet_addr);
47841 -+
47842 -+ let rsock = socket(AddressFamily::Inet,
47843 -+ SockType::Datagram,
47844 -+ SockFlag::empty(),
47845 -+ None
47846 -+ ).unwrap();
47847 -+ bind(rsock, &sock_addr).unwrap();
47848 -+ let ssock = socket(
47849 -+ AddressFamily::Inet,
47850 -+ SockType::Datagram,
47851 -+ SockFlag::empty(),
47852 -+ None,
47853 -+ ).expect("send socket failed");
47854 -+
47855 -+ let send_thread = thread::spawn(move || {
47856 -+ for _ in 0..NUM_MESSAGES_SENT {
47857 -+ sendto(ssock, &DATA[..], &sock_addr, MsgFlags::empty()).unwrap();
47858 -+ }
47859 -+ });
47860 -+
47861 -+ let mut msgs = std::collections::LinkedList::new();
47862 -+
47863 -+ // Buffers to receive exactly `NUM_MESSAGES_SENT` messages
47864 -+ let mut receive_buffers = [[0u8; 32]; NUM_MESSAGES_SENT];
47865 -+ let iovs: Vec<_> = receive_buffers.iter_mut().map(|buf| {
47866 -+ [IoVec::from_mut_slice(&mut buf[..])]
47867 -+ }).collect();
47868 -+
47869 -+ for iov in &iovs {
47870 -+ msgs.push_back(RecvMmsgData {
47871 -+ iov: iov,
47872 -+ cmsg_buffer: None,
47873 -+ })
47874 -+ };
47875 -+
47876 -+ let res = recvmmsg(rsock, &mut msgs, MsgFlags::empty(), None).expect("recvmmsg");
47877 -+ assert_eq!(res.len(), DATA.len());
47878 -+
47879 -+ for RecvMsg { address, bytes, .. } in res.into_iter() {
47880 -+ assert_eq!(AddressFamily::Inet, address.unwrap().family());
47881 -+ assert_eq!(DATA.len(), bytes);
47882 -+ }
47883 -+
47884 -+ for buf in &receive_buffers {
47885 -+ assert_eq!(&buf[..DATA.len()], DATA);
47886 -+ }
47887 -+
47888 -+ send_thread.join().unwrap();
47889 -+ }
47890 -+
47891 -+ #[cfg(any(
47892 -+ target_os = "linux",
47893 -+ target_os = "android",
47894 -+ target_os = "freebsd",
47895 -+ target_os = "netbsd",
47896 -+ ))]
47897 -+ #[test]
47898 -+ pub fn udp_recvmmsg_dontwait_short_read() {
47899 -+ use nix::sys::uio::IoVec;
47900 -+ use nix::sys::socket::{MsgFlags, recvmmsg};
47901 -+
47902 -+ const NUM_MESSAGES_SENT: usize = 2;
47903 -+ const DATA: [u8; 4] = [1,2,3,4];
47904 -+
47905 -+ let std_sa = SocketAddr::from_str("127.0.0.1:6799").unwrap();
47906 -+ let inet_addr = InetAddr::from_std(&std_sa);
47907 -+ let sock_addr = SockAddr::new_inet(inet_addr);
47908 -+
47909 -+ let rsock = socket(AddressFamily::Inet,
47910 -+ SockType::Datagram,
47911 -+ SockFlag::empty(),
47912 -+ None
47913 -+ ).unwrap();
47914 -+ bind(rsock, &sock_addr).unwrap();
47915 -+ let ssock = socket(
47916 -+ AddressFamily::Inet,
47917 -+ SockType::Datagram,
47918 -+ SockFlag::empty(),
47919 -+ None,
47920 -+ ).expect("send socket failed");
47921 -+
47922 -+ let send_thread = thread::spawn(move || {
47923 -+ for _ in 0..NUM_MESSAGES_SENT {
47924 -+ sendto(ssock, &DATA[..], &sock_addr, MsgFlags::empty()).unwrap();
47925 -+ }
47926 -+ });
47927 -+ // Ensure we've sent all the messages before continuing so `recvmmsg`
47928 -+ // will return right away
47929 -+ send_thread.join().unwrap();
47930 -+
47931 -+ let mut msgs = std::collections::LinkedList::new();
47932 -+
47933 -+ // Buffers to receive >`NUM_MESSAGES_SENT` messages to ensure `recvmmsg`
47934 -+ // will return when there are fewer than requested messages in the
47935 -+ // kernel buffers when using `MSG_DONTWAIT`.
47936 -+ let mut receive_buffers = [[0u8; 32]; NUM_MESSAGES_SENT + 2];
47937 -+ let iovs: Vec<_> = receive_buffers.iter_mut().map(|buf| {
47938 -+ [IoVec::from_mut_slice(&mut buf[..])]
47939 -+ }).collect();
47940 -+
47941 -+ for iov in &iovs {
47942 -+ msgs.push_back(RecvMmsgData {
47943 -+ iov: iov,
47944 -+ cmsg_buffer: None,
47945 -+ })
47946 -+ };
47947 -+
47948 -+ let res = recvmmsg(rsock, &mut msgs, MsgFlags::MSG_DONTWAIT, None).expect("recvmmsg");
47949 -+ assert_eq!(res.len(), NUM_MESSAGES_SENT);
47950 -+
47951 -+ for RecvMsg { address, bytes, .. } in res.into_iter() {
47952 -+ assert_eq!(AddressFamily::Inet, address.unwrap().family());
47953 -+ assert_eq!(DATA.len(), bytes);
47954 -+ }
47955 -+
47956 -+ for buf in &receive_buffers[..NUM_MESSAGES_SENT] {
47957 -+ assert_eq!(&buf[..DATA.len()], DATA);
47958 -+ }
47959 -+ }
47960 -+}
47961 -+
47962 - // Test error handling of our recvmsg wrapper
47963 - #[test]
47964 - pub fn test_recvmsg_ebadf() {
47965 -@@ -247,8 +599,13 @@ pub fn test_af_alg_cipher() {
47966 - ControlMessage, MsgFlags};
47967 - use nix::sys::socket::sockopt::AlgSetKey;
47968 -
47969 -+ skip_if_cirrus!("Fails for an unknown reason Cirrus CI. Bug #1352");
47970 -+ // Travis's seccomp profile blocks AF_ALG
47971 -+ // https://docs.docker.com/engine/security/seccomp/
47972 -+ skip_if_seccomp!(test_af_alg_cipher);
47973 -+
47974 - let alg_type = "skcipher";
47975 -- let alg_name = "ctr(aes)";
47976 -+ let alg_name = "ctr-aes-aesni";
47977 - // 256-bits secret key
47978 - let key = vec![0u8; 32];
47979 - // 16-bytes IV
47980 -@@ -311,6 +668,11 @@ pub fn test_af_alg_aead() {
47981 - ControlMessage, MsgFlags};
47982 - use nix::sys::socket::sockopt::{AlgSetKey, AlgSetAeadAuthSize};
47983 -
47984 -+ skip_if_cirrus!("Fails for an unknown reason Cirrus CI. Bug #1352");
47985 -+ // Travis's seccomp profile blocks AF_ALG
47986 -+ // https://docs.docker.com/engine/security/seccomp/
47987 -+ skip_if_seccomp!(test_af_alg_aead);
47988 -+
47989 - let auth_size = 4usize;
47990 - let assoc_size = 16u32;
47991 -
47992 -@@ -383,6 +745,111 @@ pub fn test_af_alg_aead() {
47993 - assert_eq!(decrypted[(assoc_size as usize)..(payload_len + (assoc_size as usize))], payload[(assoc_size as usize)..payload_len + (assoc_size as usize)]);
47994 - }
47995 -
47996 -+// Verify `ControlMessage::Ipv4PacketInfo` for `sendmsg`.
47997 -+// This creates a (udp) socket bound to localhost, then sends a message to
47998 -+// itself but uses Ipv4PacketInfo to force the source address to be localhost.
47999 -+//
48000 -+// This would be a more interesting test if we could assume that the test host
48001 -+// has more than one IP address (since we could select a different address to
48002 -+// test from).
48003 -+#[cfg(any(target_os = "linux",
48004 -+ target_os = "macos",
48005 -+ target_os = "netbsd"))]
48006 -+#[test]
48007 -+pub fn test_sendmsg_ipv4packetinfo() {
48008 -+ use nix::sys::uio::IoVec;
48009 -+ use nix::sys::socket::{socket, sendmsg, bind,
48010 -+ AddressFamily, SockType, SockFlag, SockAddr,
48011 -+ ControlMessage, MsgFlags};
48012 -+
48013 -+ let sock = socket(AddressFamily::Inet,
48014 -+ SockType::Datagram,
48015 -+ SockFlag::empty(),
48016 -+ None)
48017 -+ .expect("socket failed");
48018 -+
48019 -+ let std_sa = SocketAddr::from_str("127.0.0.1:4000").unwrap();
48020 -+ let inet_addr = InetAddr::from_std(&std_sa);
48021 -+ let sock_addr = SockAddr::new_inet(inet_addr);
48022 -+
48023 -+ bind(sock, &sock_addr).expect("bind failed");
48024 -+
48025 -+ let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
48026 -+ let iov = [IoVec::from_slice(&slice)];
48027 -+
48028 -+ if let InetAddr::V4(sin) = inet_addr {
48029 -+ let pi = libc::in_pktinfo {
48030 -+ ipi_ifindex: 0, /* Unspecified interface */
48031 -+ ipi_addr: libc::in_addr { s_addr: 0 },
48032 -+ ipi_spec_dst: sin.sin_addr,
48033 -+ };
48034 -+
48035 -+ let cmsg = [ControlMessage::Ipv4PacketInfo(&pi)];
48036 -+
48037 -+ sendmsg(sock, &iov, &cmsg, MsgFlags::empty(), Some(&sock_addr))
48038 -+ .expect("sendmsg");
48039 -+ } else {
48040 -+ panic!("No IPv4 addresses available for testing?");
48041 -+ }
48042 -+}
48043 -+
48044 -+// Verify `ControlMessage::Ipv6PacketInfo` for `sendmsg`.
48045 -+// This creates a (udp) socket bound to ip6-localhost, then sends a message to
48046 -+// itself but uses Ipv6PacketInfo to force the source address to be
48047 -+// ip6-localhost.
48048 -+//
48049 -+// This would be a more interesting test if we could assume that the test host
48050 -+// has more than one IP address (since we could select a different address to
48051 -+// test from).
48052 -+#[cfg(any(target_os = "linux",
48053 -+ target_os = "macos",
48054 -+ target_os = "netbsd",
48055 -+ target_os = "freebsd"))]
48056 -+#[test]
48057 -+pub fn test_sendmsg_ipv6packetinfo() {
48058 -+ use nix::Error;
48059 -+ use nix::errno::Errno;
48060 -+ use nix::sys::uio::IoVec;
48061 -+ use nix::sys::socket::{socket, sendmsg, bind,
48062 -+ AddressFamily, SockType, SockFlag, SockAddr,
48063 -+ ControlMessage, MsgFlags};
48064 -+
48065 -+ let sock = socket(AddressFamily::Inet6,
48066 -+ SockType::Datagram,
48067 -+ SockFlag::empty(),
48068 -+ None)
48069 -+ .expect("socket failed");
48070 -+
48071 -+ let std_sa = SocketAddr::from_str("[::1]:6000").unwrap();
48072 -+ let inet_addr = InetAddr::from_std(&std_sa);
48073 -+ let sock_addr = SockAddr::new_inet(inet_addr);
48074 -+
48075 -+ match bind(sock, &sock_addr) {
48076 -+ Err(Error::Sys(Errno::EADDRNOTAVAIL)) => {
48077 -+ println!("IPv6 not available, skipping test.");
48078 -+ return;
48079 -+ },
48080 -+ _ => (),
48081 -+ }
48082 -+
48083 -+ let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
48084 -+ let iov = [IoVec::from_slice(&slice)];
48085 -+
48086 -+ if let InetAddr::V6(sin) = inet_addr {
48087 -+ let pi = libc::in6_pktinfo {
48088 -+ ipi6_ifindex: 0, /* Unspecified interface */
48089 -+ ipi6_addr: sin.sin6_addr,
48090 -+ };
48091 -+
48092 -+ let cmsg = [ControlMessage::Ipv6PacketInfo(&pi)];
48093 -+
48094 -+ sendmsg(sock, &iov, &cmsg, MsgFlags::empty(), Some(&sock_addr))
48095 -+ .expect("sendmsg");
48096 -+ } else {
48097 -+ println!("No IPv6 addresses available for testing: skipping testing Ipv6PacketInfo");
48098 -+ }
48099 -+}
48100 -+
48101 - /// Tests that passing multiple fds using a single `ControlMessage` works.
48102 - // Disable the test on emulated platforms due to a bug in QEMU versions <
48103 - // 2.12.0. https://bugs.launchpad.net/qemu/+bug/1701808
48104 -@@ -468,29 +935,36 @@ pub fn test_sendmsg_empty_cmsgs() {
48105 - }
48106 - }
48107 -
48108 --#[cfg(any(target_os = "android", target_os = "linux"))]
48109 -+#[cfg(any(
48110 -+ target_os = "android",
48111 -+ target_os = "linux",
48112 -+ target_os = "freebsd",
48113 -+ target_os = "dragonfly",
48114 -+))]
48115 - #[test]
48116 - fn test_scm_credentials() {
48117 -- use libc;
48118 - use nix::sys::uio::IoVec;
48119 - use nix::unistd::{close, getpid, getuid, getgid};
48120 -- use nix::sys::socket::{socketpair, sendmsg, recvmsg, setsockopt,
48121 -+ use nix::sys::socket::{socketpair, sendmsg, recvmsg,
48122 - AddressFamily, SockType, SockFlag,
48123 -- ControlMessage, ControlMessageOwned, MsgFlags};
48124 -- use nix::sys::socket::sockopt::PassCred;
48125 -+ ControlMessage, ControlMessageOwned, MsgFlags,
48126 -+ UnixCredentials};
48127 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
48128 -+ use nix::sys::socket::{setsockopt, sockopt::PassCred};
48129 -
48130 - let (send, recv) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
48131 - .unwrap();
48132 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
48133 - setsockopt(recv, PassCred, &true).unwrap();
48134 -
48135 - {
48136 - let iov = [IoVec::from_slice(b"hello")];
48137 -- let cred = libc::ucred {
48138 -- pid: getpid().as_raw(),
48139 -- uid: getuid().as_raw(),
48140 -- gid: getgid().as_raw(),
48141 -- };
48142 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
48143 -+ let cred = UnixCredentials::new();
48144 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
48145 - let cmsg = ControlMessage::ScmCredentials(&cred);
48146 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
48147 -+ let cmsg = ControlMessage::ScmCreds;
48148 - assert_eq!(sendmsg(send, &iov, &[cmsg], MsgFlags::empty(), None).unwrap(), 5);
48149 - close(send).unwrap();
48150 - }
48151 -@@ -498,20 +972,23 @@ fn test_scm_credentials() {
48152 - {
48153 - let mut buf = [0u8; 5];
48154 - let iov = [IoVec::from_mut_slice(&mut buf[..])];
48155 -- let mut cmsgspace = cmsg_space!(libc::ucred);
48156 -+ let mut cmsgspace = cmsg_space!(UnixCredentials);
48157 - let msg = recvmsg(recv, &iov, Some(&mut cmsgspace), MsgFlags::empty()).unwrap();
48158 - let mut received_cred = None;
48159 -
48160 - for cmsg in msg.cmsgs() {
48161 -- if let ControlMessageOwned::ScmCredentials(cred) = cmsg {
48162 -- assert!(received_cred.is_none());
48163 -- assert_eq!(cred.pid, getpid().as_raw());
48164 -- assert_eq!(cred.uid, getuid().as_raw());
48165 -- assert_eq!(cred.gid, getgid().as_raw());
48166 -- received_cred = Some(cred);
48167 -- } else {
48168 -- panic!("unexpected cmsg");
48169 -- }
48170 -+ let cred = match cmsg {
48171 -+ #[cfg(any(target_os = "android", target_os = "linux"))]
48172 -+ ControlMessageOwned::ScmCredentials(cred) => cred,
48173 -+ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
48174 -+ ControlMessageOwned::ScmCreds(cred) => cred,
48175 -+ other => panic!("unexpected cmsg {:?}", other),
48176 -+ };
48177 -+ assert!(received_cred.is_none());
48178 -+ assert_eq!(cred.pid(), getpid().as_raw());
48179 -+ assert_eq!(cred.uid(), getuid().as_raw());
48180 -+ assert_eq!(cred.gid(), getgid().as_raw());
48181 -+ received_cred = Some(cred);
48182 - }
48183 - received_cred.expect("no creds received");
48184 - assert_eq!(msg.bytes, 5);
48185 -@@ -550,7 +1027,7 @@ fn test_too_large_cmsgspace() {
48186 - fn test_impl_scm_credentials_and_rights(mut space: Vec<u8>) {
48187 - use libc::ucred;
48188 - use nix::sys::uio::IoVec;
48189 -- use nix::unistd::{pipe, read, write, close, getpid, getuid, getgid};
48190 -+ use nix::unistd::{pipe, write, close, getpid, getuid, getgid};
48191 - use nix::sys::socket::{socketpair, sendmsg, recvmsg, setsockopt,
48192 - SockType, SockFlag,
48193 - ControlMessage, ControlMessageOwned, MsgFlags};
48194 -@@ -569,7 +1046,7 @@ fn test_impl_scm_credentials_and_rights(mut space: Vec<u8>) {
48195 - pid: getpid().as_raw(),
48196 - uid: getuid().as_raw(),
48197 - gid: getgid().as_raw(),
48198 -- };
48199 -+ }.into();
48200 - let fds = [r];
48201 - let cmsgs = [
48202 - ControlMessage::ScmCredentials(&cred),
48203 -@@ -597,9 +1074,9 @@ fn test_impl_scm_credentials_and_rights(mut space: Vec<u8>) {
48204 - }
48205 - ControlMessageOwned::ScmCredentials(cred) => {
48206 - assert!(received_cred.is_none());
48207 -- assert_eq!(cred.pid, getpid().as_raw());
48208 -- assert_eq!(cred.uid, getuid().as_raw());
48209 -- assert_eq!(cred.gid, getgid().as_raw());
48210 -+ assert_eq!(cred.pid(), getpid().as_raw());
48211 -+ assert_eq!(cred.uid(), getuid().as_raw());
48212 -+ assert_eq!(cred.gid(), getgid().as_raw());
48213 - received_cred = Some(cred);
48214 - }
48215 - _ => panic!("unexpected cmsg"),
48216 -@@ -683,7 +1160,7 @@ pub fn test_syscontrol() {
48217 - target_os = "netbsd",
48218 - target_os = "openbsd",
48219 - ))]
48220 --fn loopback_address(family: AddressFamily) -> Option<InterfaceAddress> {
48221 -+fn loopback_address(family: AddressFamily) -> Option<nix::ifaddrs::InterfaceAddress> {
48222 - use std::io;
48223 - use std::io::Write;
48224 - use nix::ifaddrs::getifaddrs;
48225 -@@ -1013,7 +1490,7 @@ pub fn test_recv_ipv6pktinfo() {
48226 - }
48227 - }
48228 -
48229 --#[cfg(target_os = "linux")]
48230 -+#[cfg(any(target_os = "android", target_os = "linux"))]
48231 - #[test]
48232 - pub fn test_vsock() {
48233 - use libc;
48234 -@@ -1030,17 +1507,11 @@ pub fn test_vsock() {
48235 - SockFlag::empty(), None)
48236 - .expect("socket failed");
48237 -
48238 -- // VMADDR_CID_HYPERVISOR and VMADDR_CID_RESERVED are reserved, so we expect
48239 -- // an EADDRNOTAVAIL error.
48240 -+ // VMADDR_CID_HYPERVISOR is reserved, so we expect an EADDRNOTAVAIL error.
48241 - let sockaddr = SockAddr::new_vsock(libc::VMADDR_CID_HYPERVISOR, port);
48242 - assert_eq!(bind(s1, &sockaddr).err(),
48243 - Some(Error::Sys(Errno::EADDRNOTAVAIL)));
48244 -
48245 -- let sockaddr = SockAddr::new_vsock(libc::VMADDR_CID_RESERVED, port);
48246 -- assert_eq!(bind(s1, &sockaddr).err(),
48247 -- Some(Error::Sys(Errno::EADDRNOTAVAIL)));
48248 --
48249 --
48250 - let sockaddr = SockAddr::new_vsock(libc::VMADDR_CID_ANY, port);
48251 - assert_eq!(bind(s1, &sockaddr), Ok(()));
48252 - listen(s1, 10).expect("listen failed");
48253 -diff --git a/third_party/rust/nix/test/sys/test_sockopt.rs b/third_party/rust/nix/test/sys/test_sockopt.rs
48254 -index c4860c0d61d3d..56065931322ec 100644
48255 ---- a/third_party/rust/nix/test/sys/test_sockopt.rs
48256 -+++ b/third_party/rust/nix/test/sys/test_sockopt.rs
48257 -@@ -1,5 +1,7 @@
48258 - use rand::{thread_rng, Rng};
48259 - use nix::sys::socket::{socket, sockopt, getsockopt, setsockopt, AddressFamily, SockType, SockFlag, SockProtocol};
48260 -+#[cfg(any(target_os = "android", target_os = "linux"))]
48261 -+use crate::*;
48262 -
48263 - #[cfg(target_os = "linux")]
48264 - #[test]
48265 -@@ -51,3 +53,44 @@ fn test_tcp_congestion() {
48266 - val
48267 - );
48268 - }
48269 -+
48270 -+#[test]
48271 -+#[cfg(any(target_os = "android", target_os = "linux"))]
48272 -+fn test_bindtodevice() {
48273 -+ skip_if_not_root!("test_bindtodevice");
48274 -+
48275 -+ let fd = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), None).unwrap();
48276 -+
48277 -+ let val = getsockopt(fd, sockopt::BindToDevice).unwrap();
48278 -+ setsockopt(fd, sockopt::BindToDevice, &val).unwrap();
48279 -+
48280 -+ assert_eq!(
48281 -+ getsockopt(fd, sockopt::BindToDevice).unwrap(),
48282 -+ val
48283 -+ );
48284 -+}
48285 -+
48286 -+#[test]
48287 -+fn test_so_tcp_keepalive() {
48288 -+ let fd = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), SockProtocol::Tcp).unwrap();
48289 -+ setsockopt(fd, sockopt::KeepAlive, &true).unwrap();
48290 -+ assert_eq!(getsockopt(fd, sockopt::KeepAlive).unwrap(), true);
48291 -+
48292 -+ #[cfg(any(target_os = "android",
48293 -+ target_os = "dragonfly",
48294 -+ target_os = "freebsd",
48295 -+ target_os = "linux",
48296 -+ target_os = "nacl"))] {
48297 -+ let x = getsockopt(fd, sockopt::TcpKeepIdle).unwrap();
48298 -+ setsockopt(fd, sockopt::TcpKeepIdle, &(x + 1)).unwrap();
48299 -+ assert_eq!(getsockopt(fd, sockopt::TcpKeepIdle).unwrap(), x + 1);
48300 -+
48301 -+ let x = getsockopt(fd, sockopt::TcpKeepCount).unwrap();
48302 -+ setsockopt(fd, sockopt::TcpKeepCount, &(x + 1)).unwrap();
48303 -+ assert_eq!(getsockopt(fd, sockopt::TcpKeepCount).unwrap(), x + 1);
48304 -+
48305 -+ let x = getsockopt(fd, sockopt::TcpKeepInterval).unwrap();
48306 -+ setsockopt(fd, sockopt::TcpKeepInterval, &(x + 1)).unwrap();
48307 -+ assert_eq!(getsockopt(fd, sockopt::TcpKeepInterval).unwrap(), x + 1);
48308 -+ }
48309 -+}
48310 -diff --git a/third_party/rust/nix/test/sys/test_termios.rs b/third_party/rust/nix/test/sys/test_termios.rs
48311 -index a14b8ce1a23cb..00aeb2fc57f15 100644
48312 ---- a/third_party/rust/nix/test/sys/test_termios.rs
48313 -+++ b/third_party/rust/nix/test/sys/test_termios.rs
48314 -@@ -4,7 +4,7 @@ use tempfile::tempfile;
48315 - use nix::{Error, fcntl};
48316 - use nix::errno::Errno;
48317 - use nix::pty::openpty;
48318 --use nix::sys::termios::{self, LocalFlags, OutputFlags, Termios, tcgetattr};
48319 -+use nix::sys::termios::{self, LocalFlags, OutputFlags, tcgetattr};
48320 - use nix::unistd::{read, write, close};
48321 -
48322 - /// Helper function analogous to `std::io::Write::write_all`, but for `RawFd`s
48323 -@@ -19,10 +19,10 @@ fn write_all(f: RawFd, buf: &[u8]) {
48324 - #[test]
48325 - fn test_tcgetattr_pty() {
48326 - // openpty uses ptname(3) internally
48327 -- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
48328 -+ let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
48329 -
48330 - let pty = openpty(None, None).expect("openpty failed");
48331 -- assert!(termios::tcgetattr(pty.master).is_ok());
48332 -+ assert!(termios::tcgetattr(pty.slave).is_ok());
48333 - close(pty.master).expect("closing the master failed");
48334 - close(pty.slave).expect("closing the slave failed");
48335 - }
48336 -@@ -46,14 +46,14 @@ fn test_tcgetattr_ebadf() {
48337 - #[test]
48338 - fn test_output_flags() {
48339 - // openpty uses ptname(3) internally
48340 -- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
48341 -+ let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
48342 -
48343 - // Open one pty to get attributes for the second one
48344 - let mut termios = {
48345 - let pty = openpty(None, None).expect("openpty failed");
48346 - assert!(pty.master > 0);
48347 - assert!(pty.slave > 0);
48348 -- let termios = tcgetattr(pty.master).expect("tcgetattr failed");
48349 -+ let termios = tcgetattr(pty.slave).expect("tcgetattr failed");
48350 - close(pty.master).unwrap();
48351 - close(pty.slave).unwrap();
48352 - termios
48353 -@@ -77,7 +77,7 @@ fn test_output_flags() {
48354 -
48355 - // Read from the slave verifying that the output has been properly transformed
48356 - let mut buf = [0u8; 10];
48357 -- ::read_exact(pty.slave, &mut buf);
48358 -+ crate::read_exact(pty.slave, &mut buf);
48359 - let transformed_string = "foofoofoo\n";
48360 - close(pty.master).unwrap();
48361 - close(pty.slave).unwrap();
48362 -@@ -88,14 +88,14 @@ fn test_output_flags() {
48363 - #[test]
48364 - fn test_local_flags() {
48365 - // openpty uses ptname(3) internally
48366 -- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
48367 -+ let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
48368 -
48369 - // Open one pty to get attributes for the second one
48370 - let mut termios = {
48371 - let pty = openpty(None, None).unwrap();
48372 - assert!(pty.master > 0);
48373 - assert!(pty.slave > 0);
48374 -- let termios = tcgetattr(pty.master).unwrap();
48375 -+ let termios = tcgetattr(pty.slave).unwrap();
48376 - close(pty.master).unwrap();
48377 - close(pty.slave).unwrap();
48378 - termios
48379 -@@ -128,9 +128,3 @@ fn test_local_flags() {
48380 - close(pty.slave).unwrap();
48381 - assert_eq!(read, Error::Sys(Errno::EAGAIN));
48382 - }
48383 --
48384 --#[test]
48385 --fn test_cfmakeraw() {
48386 -- let mut termios = unsafe { Termios::default_uninit() };
48387 -- termios::cfmakeraw(&mut termios);
48388 --}
48389 -diff --git a/third_party/rust/nix/test/sys/test_timerfd.rs b/third_party/rust/nix/test/sys/test_timerfd.rs
48390 -new file mode 100644
48391 -index 0000000000000..24fb2ac002e1d
48392 ---- /dev/null
48393 -+++ b/third_party/rust/nix/test/sys/test_timerfd.rs
48394 -@@ -0,0 +1,61 @@
48395 -+use nix::sys::time::{TimeSpec, TimeValLike};
48396 -+use nix::sys::timerfd::{ClockId, Expiration, TimerFd, TimerFlags, TimerSetTimeFlags};
48397 -+use std::time::Instant;
48398 -+
48399 -+#[test]
48400 -+pub fn test_timerfd_oneshot() {
48401 -+ let timer = TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty()).unwrap();
48402 -+
48403 -+ let before = Instant::now();
48404 -+
48405 -+ timer
48406 -+ .set(
48407 -+ Expiration::OneShot(TimeSpec::seconds(1)),
48408 -+ TimerSetTimeFlags::empty(),
48409 -+ )
48410 -+ .unwrap();
48411 -+
48412 -+ timer.wait().unwrap();
48413 -+
48414 -+ let millis = before.elapsed().as_millis();
48415 -+ assert!(millis > 900);
48416 -+}
48417 -+
48418 -+#[test]
48419 -+pub fn test_timerfd_interval() {
48420 -+ let timer = TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty()).unwrap();
48421 -+
48422 -+ let before = Instant::now();
48423 -+ timer
48424 -+ .set(
48425 -+ Expiration::IntervalDelayed(TimeSpec::seconds(1), TimeSpec::seconds(2)),
48426 -+ TimerSetTimeFlags::empty(),
48427 -+ )
48428 -+ .unwrap();
48429 -+
48430 -+ timer.wait().unwrap();
48431 -+
48432 -+ let start_delay = before.elapsed().as_millis();
48433 -+ assert!(start_delay > 900);
48434 -+
48435 -+ timer.wait().unwrap();
48436 -+
48437 -+ let interval_delay = before.elapsed().as_millis();
48438 -+ assert!(interval_delay > 2900);
48439 -+}
48440 -+
48441 -+#[test]
48442 -+pub fn test_timerfd_unset() {
48443 -+ let timer = TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty()).unwrap();
48444 -+
48445 -+ timer
48446 -+ .set(
48447 -+ Expiration::OneShot(TimeSpec::seconds(1)),
48448 -+ TimerSetTimeFlags::empty(),
48449 -+ )
48450 -+ .unwrap();
48451 -+
48452 -+ timer.unset().unwrap();
48453 -+
48454 -+ assert!(timer.get().unwrap() == None);
48455 -+}
48456 -diff --git a/third_party/rust/nix/test/sys/test_uio.rs b/third_party/rust/nix/test/sys/test_uio.rs
48457 -index 3e4fc28ceb0e4..8d22bf1755a2c 100644
48458 ---- a/third_party/rust/nix/test/sys/test_uio.rs
48459 -+++ b/third_party/rust/nix/test/sys/test_uio.rs
48460 -@@ -6,7 +6,9 @@ use std::{cmp, iter};
48461 - use std::fs::{OpenOptions};
48462 - use std::os::unix::io::AsRawFd;
48463 -
48464 --use tempfile::{tempfile, tempdir};
48465 -+#[cfg(not(target_os = "redox"))]
48466 -+use tempfile::tempfile;
48467 -+use tempfile::tempdir;
48468 -
48469 - #[test]
48470 - fn test_writev() {
48471 -@@ -53,6 +55,7 @@ fn test_writev() {
48472 - }
48473 -
48474 - #[test]
48475 -+#[cfg(not(target_os = "redox"))]
48476 - fn test_readv() {
48477 - let s:String = thread_rng().sample_iter(&Alphanumeric).take(128).collect();
48478 - let to_write = s.as_bytes().to_vec();
48479 -@@ -97,6 +100,7 @@ fn test_readv() {
48480 - }
48481 -
48482 - #[test]
48483 -+#[cfg(not(target_os = "redox"))]
48484 - fn test_pwrite() {
48485 - use std::io::Read;
48486 -
48487 -@@ -199,15 +203,17 @@ fn test_process_vm_readv() {
48488 - use nix::unistd::ForkResult::*;
48489 - use nix::sys::signal::*;
48490 - use nix::sys::wait::*;
48491 -+ use crate::*;
48492 -
48493 -- let _ = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
48494 -+ require_capability!(CAP_SYS_PTRACE);
48495 -+ let _ = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test");
48496 -
48497 - // Pre-allocate memory in the child, since allocation isn't safe
48498 - // post-fork (~= async-signal-safe)
48499 - let mut vector = vec![1u8, 2, 3, 4, 5];
48500 -
48501 - let (r, w) = pipe().unwrap();
48502 -- match fork().expect("Error: Fork Failed") {
48503 -+ match unsafe{fork()}.expect("Error: Fork Failed") {
48504 - Parent { child } => {
48505 - close(w).unwrap();
48506 - // wait for child
48507 -diff --git a/third_party/rust/nix/test/sys/test_wait.rs b/third_party/rust/nix/test/sys/test_wait.rs
48508 -index d07d82f0d9075..5bb298eba4d29 100644
48509 ---- a/third_party/rust/nix/test/sys/test_wait.rs
48510 -+++ b/third_party/rust/nix/test/sys/test_wait.rs
48511 -@@ -6,11 +6,12 @@ use nix::sys::wait::*;
48512 - use libc::_exit;
48513 -
48514 - #[test]
48515 -+#[cfg(not(target_os = "redox"))]
48516 - fn test_wait_signal() {
48517 -- let _ = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
48518 -+ let _ = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test");
48519 -
48520 - // Safe: The child only calls `pause` and/or `_exit`, which are async-signal-safe.
48521 -- match fork().expect("Error: Fork Failed") {
48522 -+ match unsafe{fork()}.expect("Error: Fork Failed") {
48523 - Child => {
48524 - pause();
48525 - unsafe { _exit(123) }
48526 -@@ -24,10 +25,10 @@ fn test_wait_signal() {
48527 -
48528 - #[test]
48529 - fn test_wait_exit() {
48530 -- let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
48531 -+ let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test");
48532 -
48533 - // Safe: Child only calls `_exit`, which is async-signal-safe.
48534 -- match fork().expect("Error: Fork Failed") {
48535 -+ match unsafe{fork()}.expect("Error: Fork Failed") {
48536 - Child => unsafe { _exit(12); },
48537 - Parent { child } => {
48538 - assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 12)));
48539 -@@ -45,9 +46,9 @@ fn test_waitstatus_from_raw() {
48540 -
48541 - #[test]
48542 - fn test_waitstatus_pid() {
48543 -- let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
48544 -+ let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test");
48545 -
48546 -- match fork().unwrap() {
48547 -+ match unsafe{fork()}.unwrap() {
48548 - Child => unsafe { _exit(0) },
48549 - Parent { child } => {
48550 - let status = waitpid(child, None).unwrap();
48551 -@@ -66,6 +67,7 @@ mod ptrace {
48552 - use nix::unistd::*;
48553 - use nix::unistd::ForkResult::*;
48554 - use libc::_exit;
48555 -+ use crate::*;
48556 -
48557 - fn ptrace_child() -> ! {
48558 - ptrace::traceme().unwrap();
48559 -@@ -82,7 +84,7 @@ mod ptrace {
48560 - assert!(ptrace::setoptions(child, Options::PTRACE_O_TRACESYSGOOD | Options::PTRACE_O_TRACEEXIT).is_ok());
48561 -
48562 - // First, stop on the next system call, which will be exit()
48563 -- assert!(ptrace::syscall(child).is_ok());
48564 -+ assert!(ptrace::syscall(child, None).is_ok());
48565 - assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceSyscall(child)));
48566 - // Then get the ptrace event for the process exiting
48567 - assert!(ptrace::cont(child, None).is_ok());
48568 -@@ -94,9 +96,10 @@ mod ptrace {
48569 -
48570 - #[test]
48571 - fn test_wait_ptrace() {
48572 -- let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
48573 -+ require_capability!(CAP_SYS_PTRACE);
48574 -+ let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test");
48575 -
48576 -- match fork().expect("Error: Fork Failed") {
48577 -+ match unsafe{fork()}.expect("Error: Fork Failed") {
48578 - Child => ptrace_child(),
48579 - Parent { child } => ptrace_parent(child),
48580 - }
48581 -diff --git a/third_party/rust/nix/test/test.rs b/third_party/rust/nix/test/test.rs
48582 -index 6a71d261b5712..5a5330b7e4010 100644
48583 ---- a/third_party/rust/nix/test/test.rs
48584 -+++ b/third_party/rust/nix/test/test.rs
48585 -@@ -1,69 +1,13 @@
48586 --// XXX Allow deprecated items until release 0.16.0. See issue #1096.
48587 --#![allow(deprecated)]
48588 --extern crate bytes;
48589 --#[cfg(any(target_os = "android", target_os = "linux"))]
48590 --extern crate caps;
48591 - #[macro_use]
48592 - extern crate cfg_if;
48593 --#[macro_use]
48594 -+#[cfg_attr(not(target_os = "redox"), macro_use)]
48595 - extern crate nix;
48596 - #[macro_use]
48597 - extern crate lazy_static;
48598 --extern crate libc;
48599 --extern crate rand;
48600 --#[cfg(target_os = "freebsd")]
48601 --extern crate sysctl;
48602 --extern crate tempfile;
48603 --
48604 --#[cfg(any(target_os = "android", target_os = "linux"))]
48605 --macro_rules! require_capability {
48606 -- ($capname:ident) => {
48607 -- use ::caps::{Capability, CapSet, has_cap};
48608 -- use ::std::io::{self, Write};
48609 --
48610 -- if !has_cap(None, CapSet::Effective, Capability::$capname).unwrap() {
48611 -- let stderr = io::stderr();
48612 -- let mut handle = stderr.lock();
48613 -- writeln!(handle, "Insufficient capabilities. Skipping test.")
48614 -- .unwrap();
48615 -- return;
48616 -- }
48617 -- }
48618 --}
48619 --
48620 --#[cfg(target_os = "freebsd")]
48621 --macro_rules! skip_if_jailed {
48622 -- ($name:expr) => {
48623 -- use ::sysctl::CtlValue;
48624 --
48625 -- if let CtlValue::Int(1) = ::sysctl::value("security.jail.jailed")
48626 -- .unwrap()
48627 -- {
48628 -- use ::std::io::Write;
48629 -- let stderr = ::std::io::stderr();
48630 -- let mut handle = stderr.lock();
48631 -- writeln!(handle, "{} cannot run in a jail. Skipping test.", $name)
48632 -- .unwrap();
48633 -- return;
48634 -- }
48635 -- }
48636 --}
48637 --
48638 --macro_rules! skip_if_not_root {
48639 -- ($name:expr) => {
48640 -- use nix::unistd::Uid;
48641 --
48642 -- if !Uid::current().is_root() {
48643 -- use ::std::io::Write;
48644 -- let stderr = ::std::io::stderr();
48645 -- let mut handle = stderr.lock();
48646 -- writeln!(handle, "{} requires root privileges. Skipping test.", $name).unwrap();
48647 -- return;
48648 -- }
48649 -- };
48650 --}
48651 -
48652 -+mod common;
48653 - mod sys;
48654 -+#[cfg(not(target_os = "redox"))]
48655 - mod test_dir;
48656 - mod test_fcntl;
48657 - #[cfg(any(target_os = "android",
48658 -@@ -75,10 +19,15 @@ mod test_kmod;
48659 - target_os = "linux",
48660 - target_os = "netbsd"))]
48661 - mod test_mq;
48662 -+#[cfg(not(target_os = "redox"))]
48663 - mod test_net;
48664 - mod test_nix_path;
48665 - mod test_poll;
48666 -+#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
48667 - mod test_pty;
48668 -+#[cfg(any(target_os = "android",
48669 -+ target_os = "linux"))]
48670 -+mod test_sched;
48671 - #[cfg(any(target_os = "android",
48672 - target_os = "freebsd",
48673 - target_os = "ios",
48674 -@@ -86,6 +35,7 @@ mod test_pty;
48675 - target_os = "macos"))]
48676 - mod test_sendfile;
48677 - mod test_stat;
48678 -+mod test_time;
48679 - mod test_unistd;
48680 -
48681 - use std::os::unix::io::RawFd;
48682 -@@ -93,6 +43,7 @@ use std::path::PathBuf;
48683 - use std::sync::{Mutex, RwLock, RwLockWriteGuard};
48684 - use nix::unistd::{chdir, getcwd, read};
48685 -
48686 -+
48687 - /// Helper function analogous to `std::io::Read::read_exact`, but for `RawFD`s
48688 - fn read_exact(f: RawFd, buf: &mut [u8]) {
48689 - let mut len = 0;
48690 -@@ -130,7 +81,7 @@ struct DirRestore<'a> {
48691 -
48692 - impl<'a> DirRestore<'a> {
48693 - fn new() -> Self {
48694 -- let guard = ::CWD_LOCK.write()
48695 -+ let guard = crate::CWD_LOCK.write()
48696 - .expect("Lock got poisoned by another test");
48697 - DirRestore{
48698 - _g: guard,
48699 -diff --git a/third_party/rust/nix/test/test_clearenv.rs b/third_party/rust/nix/test/test_clearenv.rs
48700 -new file mode 100644
48701 -index 0000000000000..28a77680498ca
48702 ---- /dev/null
48703 -+++ b/third_party/rust/nix/test/test_clearenv.rs
48704 -@@ -0,0 +1,9 @@
48705 -+use std::env;
48706 -+
48707 -+#[test]
48708 -+fn clearenv() {
48709 -+ env::set_var("FOO", "BAR");
48710 -+ unsafe { nix::env::clearenv() }.unwrap();
48711 -+ assert_eq!(env::var("FOO").unwrap_err(), env::VarError::NotPresent);
48712 -+ assert_eq!(env::vars().count(), 0);
48713 -+}
48714 -diff --git a/third_party/rust/nix/test/test_dir.rs b/third_party/rust/nix/test/test_dir.rs
48715 -index c42fbcd18a29d..505277e7143b7 100644
48716 ---- a/third_party/rust/nix/test/test_dir.rs
48717 -+++ b/third_party/rust/nix/test/test_dir.rs
48718 -@@ -1,11 +1,8 @@
48719 --extern crate nix;
48720 --extern crate tempfile;
48721 --
48722 - use nix::dir::{Dir, Type};
48723 - use nix::fcntl::OFlag;
48724 - use nix::sys::stat::Mode;
48725 - use std::fs::File;
48726 --use self::tempfile::tempdir;
48727 -+use tempfile::tempdir;
48728 -
48729 - #[test]
48730 - fn read() {
48731 -@@ -37,7 +34,9 @@ fn rewind() {
48732 - Mode::empty()).unwrap();
48733 - let entries1: Vec<_> = dir.iter().map(|e| e.unwrap().file_name().to_owned()).collect();
48734 - let entries2: Vec<_> = dir.iter().map(|e| e.unwrap().file_name().to_owned()).collect();
48735 -+ let entries3: Vec<_> = dir.into_iter().map(|e| e.unwrap().file_name().to_owned()).collect();
48736 - assert_eq!(entries1, entries2);
48737 -+ assert_eq!(entries2, entries3);
48738 - }
48739 -
48740 - #[test]
48741 -diff --git a/third_party/rust/nix/test/test_fcntl.rs b/third_party/rust/nix/test/test_fcntl.rs
48742 -index 6b2bbd679fc31..5d1bafebe195f 100644
48743 ---- a/third_party/rust/nix/test/test_fcntl.rs
48744 -+++ b/third_party/rust/nix/test/test_fcntl.rs
48745 -@@ -1,14 +1,28 @@
48746 -+#[cfg(not(target_os = "redox"))]
48747 - use nix::Error;
48748 -+#[cfg(not(target_os = "redox"))]
48749 - use nix::errno::*;
48750 --use nix::fcntl::{openat, open, OFlag, readlink, readlinkat, renameat};
48751 -+#[cfg(not(target_os = "redox"))]
48752 -+use nix::fcntl::{open, OFlag, readlink};
48753 -+#[cfg(not(target_os = "redox"))]
48754 -+use nix::fcntl::{openat, readlinkat, renameat};
48755 -+#[cfg(not(target_os = "redox"))]
48756 - use nix::sys::stat::Mode;
48757 -+#[cfg(not(target_os = "redox"))]
48758 - use nix::unistd::{close, read};
48759 -+#[cfg(not(target_os = "redox"))]
48760 - use tempfile::{self, NamedTempFile};
48761 -+#[cfg(not(target_os = "redox"))]
48762 - use std::fs::File;
48763 -+#[cfg(not(target_os = "redox"))]
48764 - use std::io::prelude::*;
48765 -+#[cfg(not(target_os = "redox"))]
48766 - use std::os::unix::fs;
48767 -
48768 -+use crate::*;
48769 -+
48770 - #[test]
48771 -+#[cfg(not(target_os = "redox"))]
48772 - fn test_openat() {
48773 - const CONTENTS: &[u8] = b"abcd";
48774 - let mut tmp = NamedTempFile::new().unwrap();
48775 -@@ -31,6 +45,7 @@ fn test_openat() {
48776 - }
48777 -
48778 - #[test]
48779 -+#[cfg(not(target_os = "redox"))]
48780 - fn test_renameat() {
48781 - let old_dir = tempfile::tempdir().unwrap();
48782 - let old_dirfd = open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap();
48783 -@@ -47,6 +62,7 @@ fn test_renameat() {
48784 - }
48785 -
48786 - #[test]
48787 -+#[cfg(not(target_os = "redox"))]
48788 - fn test_readlink() {
48789 - let tempdir = tempfile::tempdir().unwrap();
48790 - let src = tempdir.path().join("a");
48791 -@@ -56,28 +72,31 @@ fn test_readlink() {
48792 - let dirfd = open(tempdir.path(),
48793 - OFlag::empty(),
48794 - Mode::empty()).unwrap();
48795 -+ let expected_dir = src.to_str().unwrap();
48796 -+
48797 -+ assert_eq!(readlink(&dst).unwrap().to_str().unwrap(), expected_dir);
48798 -+ assert_eq!(readlinkat(dirfd, "b").unwrap().to_str().unwrap(), expected_dir);
48799 -
48800 -- let mut buf = vec![0; src.to_str().unwrap().len() + 1];
48801 -- assert_eq!(readlink(&dst, &mut buf).unwrap().to_str().unwrap(),
48802 -- src.to_str().unwrap());
48803 -- assert_eq!(readlinkat(dirfd, "b", &mut buf).unwrap().to_str().unwrap(),
48804 -- src.to_str().unwrap());
48805 - }
48806 -
48807 - #[cfg(any(target_os = "linux", target_os = "android"))]
48808 - mod linux_android {
48809 -+ use std::fs::File;
48810 - use std::io::prelude::*;
48811 -- use std::io::SeekFrom;
48812 -+ use std::io::{BufRead, BufReader, SeekFrom};
48813 - use std::os::unix::prelude::*;
48814 -
48815 - use libc::loff_t;
48816 -
48817 - use nix::fcntl::*;
48818 -+ use nix::sys::stat::fstat;
48819 - use nix::sys::uio::IoVec;
48820 - use nix::unistd::{close, pipe, read, write};
48821 -
48822 - use tempfile::{tempfile, NamedTempFile};
48823 -
48824 -+ use crate::*;
48825 -+
48826 - /// This test creates a temporary file containing the contents
48827 - /// 'foobarbaz' and uses the `copy_file_range` call to transfer
48828 - /// 3 bytes at offset 3 (`bar`) to another empty file at offset 0. The
48829 -@@ -198,6 +217,113 @@ mod linux_android {
48830 - let mut buf = [0u8; 200];
48831 - assert_eq!(100, read(fd, &mut buf).unwrap());
48832 - }
48833 -+
48834 -+ // The tests below are disabled for the listed targets
48835 -+ // due to OFD locks not being available in the kernel/libc
48836 -+ // versions used in the CI environment, probably because
48837 -+ // they run under QEMU.
48838 -+
48839 -+ #[test]
48840 -+ #[cfg(not(any(target_arch = "aarch64",
48841 -+ target_arch = "arm",
48842 -+ target_arch = "armv7",
48843 -+ target_arch = "x86",
48844 -+ target_arch = "mips",
48845 -+ target_arch = "mips64",
48846 -+ target_arch = "mips64el",
48847 -+ target_arch = "powerpc64",
48848 -+ target_arch = "powerpc64le",
48849 -+ target_env = "musl")))]
48850 -+ fn test_ofd_write_lock() {
48851 -+ let tmp = NamedTempFile::new().unwrap();
48852 -+
48853 -+ let fd = tmp.as_raw_fd();
48854 -+ let statfs = nix::sys::statfs::fstatfs(&tmp).unwrap();
48855 -+ if statfs.filesystem_type() == nix::sys::statfs::OVERLAYFS_SUPER_MAGIC {
48856 -+ // OverlayFS is a union file system. It returns one inode value in
48857 -+ // stat(2), but a different one shows up in /proc/locks. So we must
48858 -+ // skip the test.
48859 -+ skip!("/proc/locks does not work on overlayfs");
48860 -+ }
48861 -+ let inode = fstat(fd).expect("fstat failed").st_ino as usize;
48862 -+
48863 -+ let mut flock = libc::flock {
48864 -+ l_type: libc::F_WRLCK as libc::c_short,
48865 -+ l_whence: libc::SEEK_SET as libc::c_short,
48866 -+ l_start: 0,
48867 -+ l_len: 0,
48868 -+ l_pid: 0,
48869 -+ };
48870 -+ fcntl(fd, FcntlArg::F_OFD_SETLKW(&flock)).expect("write lock failed");
48871 -+ assert_eq!(
48872 -+ Some(("OFDLCK".to_string(), "WRITE".to_string())),
48873 -+ lock_info(inode)
48874 -+ );
48875 -+
48876 -+ flock.l_type = libc::F_UNLCK as libc::c_short;
48877 -+ fcntl(fd, FcntlArg::F_OFD_SETLKW(&flock)).expect("write unlock failed");
48878 -+ assert_eq!(None, lock_info(inode));
48879 -+ }
48880 -+
48881 -+ #[test]
48882 -+ #[cfg(not(any(target_arch = "aarch64",
48883 -+ target_arch = "arm",
48884 -+ target_arch = "armv7",
48885 -+ target_arch = "x86",
48886 -+ target_arch = "mips",
48887 -+ target_arch = "mips64",
48888 -+ target_arch = "mips64el",
48889 -+ target_arch = "powerpc64",
48890 -+ target_arch = "powerpc64le",
48891 -+ target_env = "musl")))]
48892 -+ fn test_ofd_read_lock() {
48893 -+ let tmp = NamedTempFile::new().unwrap();
48894 -+
48895 -+ let fd = tmp.as_raw_fd();
48896 -+ let statfs = nix::sys::statfs::fstatfs(&tmp).unwrap();
48897 -+ if statfs.filesystem_type() == nix::sys::statfs::OVERLAYFS_SUPER_MAGIC {
48898 -+ // OverlayFS is a union file system. It returns one inode value in
48899 -+ // stat(2), but a different one shows up in /proc/locks. So we must
48900 -+ // skip the test.
48901 -+ skip!("/proc/locks does not work on overlayfs");
48902 -+ }
48903 -+ let inode = fstat(fd).expect("fstat failed").st_ino as usize;
48904 -+
48905 -+ let mut flock = libc::flock {
48906 -+ l_type: libc::F_RDLCK as libc::c_short,
48907 -+ l_whence: libc::SEEK_SET as libc::c_short,
48908 -+ l_start: 0,
48909 -+ l_len: 0,
48910 -+ l_pid: 0,
48911 -+ };
48912 -+ fcntl(fd, FcntlArg::F_OFD_SETLKW(&flock)).expect("read lock failed");
48913 -+ assert_eq!(
48914 -+ Some(("OFDLCK".to_string(), "READ".to_string())),
48915 -+ lock_info(inode)
48916 -+ );
48917 -+
48918 -+ flock.l_type = libc::F_UNLCK as libc::c_short;
48919 -+ fcntl(fd, FcntlArg::F_OFD_SETLKW(&flock)).expect("read unlock failed");
48920 -+ assert_eq!(None, lock_info(inode));
48921 -+ }
48922 -+
48923 -+ fn lock_info(inode: usize) -> Option<(String, String)> {
48924 -+ let file = File::open("/proc/locks").expect("open /proc/locks failed");
48925 -+ let buf = BufReader::new(file);
48926 -+
48927 -+ for line in buf.lines() {
48928 -+ let line = line.unwrap();
48929 -+ let parts: Vec<_> = line.split_whitespace().collect();
48930 -+ let lock_type = parts[1];
48931 -+ let lock_access = parts[3];
48932 -+ let ino_parts: Vec<_> = parts[5].split(':').collect();
48933 -+ let ino: usize = ino_parts[2].parse().unwrap();
48934 -+ if ino == inode {
48935 -+ return Some((lock_type.to_string(), lock_access.to_string()));
48936 -+ }
48937 -+ }
48938 -+ None
48939 -+ }
48940 - }
48941 -
48942 - #[cfg(any(target_os = "linux",
48943 -@@ -206,7 +332,7 @@ mod linux_android {
48944 - target_os = "fuchsia",
48945 - any(target_os = "wasi", target_env = "wasi"),
48946 - target_env = "uclibc",
48947 -- target_env = "freebsd"))]
48948 -+ target_os = "freebsd"))]
48949 - mod test_posix_fadvise {
48950 -
48951 - use tempfile::NamedTempFile;
48952 -@@ -232,3 +358,60 @@ mod test_posix_fadvise {
48953 - assert_eq!(errno, Errno::ESPIPE as i32);
48954 - }
48955 - }
48956 -+
48957 -+#[cfg(any(target_os = "linux",
48958 -+ target_os = "android",
48959 -+ target_os = "emscripten",
48960 -+ target_os = "fuchsia",
48961 -+ any(target_os = "wasi", target_env = "wasi"),
48962 -+ target_os = "freebsd"))]
48963 -+mod test_posix_fallocate {
48964 -+
48965 -+ use tempfile::NamedTempFile;
48966 -+ use std::{io::Read, os::unix::io::{RawFd, AsRawFd}};
48967 -+ use nix::errno::Errno;
48968 -+ use nix::fcntl::*;
48969 -+ use nix::unistd::pipe;
48970 -+
48971 -+ #[test]
48972 -+ fn success() {
48973 -+ const LEN: usize = 100;
48974 -+ let mut tmp = NamedTempFile::new().unwrap();
48975 -+ let fd = tmp.as_raw_fd();
48976 -+ let res = posix_fallocate(fd, 0, LEN as libc::off_t);
48977 -+ match res {
48978 -+ Ok(_) => {
48979 -+ let mut data = [1u8; LEN];
48980 -+ assert_eq!(tmp.read(&mut data).expect("read failure"), LEN);
48981 -+ assert_eq!(&data[..], &[0u8; LEN][..]);
48982 -+ }
48983 -+ Err(nix::Error::Sys(Errno::EINVAL)) => {
48984 -+ // POSIX requires posix_fallocate to return EINVAL both for
48985 -+ // invalid arguments (i.e. len < 0) and if the operation is not
48986 -+ // supported by the file system.
48987 -+ // There's no way to tell for sure whether the file system
48988 -+ // supports posix_fallocate, so we must pass the test if it
48989 -+ // returns EINVAL.
48990 -+ }
48991 -+ _ => res.unwrap(),
48992 -+ }
48993 -+ }
48994 -+
48995 -+ #[test]
48996 -+ fn errno() {
48997 -+ let (rd, _wr) = pipe().unwrap();
48998 -+ let err = posix_fallocate(rd as RawFd, 0, 100).unwrap_err();
48999 -+ use nix::Error::Sys;
49000 -+ match err {
49001 -+ Sys(Errno::EINVAL)
49002 -+ | Sys(Errno::ENODEV)
49003 -+ | Sys(Errno::ESPIPE)
49004 -+ | Sys(Errno::EBADF) => (),
49005 -+ errno =>
49006 -+ panic!(
49007 -+ "unexpected errno {}",
49008 -+ errno,
49009 -+ ),
49010 -+ }
49011 -+ }
49012 -+}
49013 -diff --git a/third_party/rust/nix/test/test_kmod/mod.rs b/third_party/rust/nix/test/test_kmod/mod.rs
49014 -index ad406357b06d2..fb7260ba9c9d9 100644
49015 ---- a/third_party/rust/nix/test/test_kmod/mod.rs
49016 -+++ b/third_party/rust/nix/test/test_kmod/mod.rs
49017 -@@ -2,9 +2,10 @@ use std::fs::copy;
49018 - use std::path::PathBuf;
49019 - use std::process::Command;
49020 - use tempfile::{tempdir, TempDir};
49021 -+use crate::*;
49022 -
49023 - fn compile_kernel_module() -> (PathBuf, String, TempDir) {
49024 -- let _m = ::FORK_MTX
49025 -+ let _m = crate::FORK_MTX
49026 - .lock()
49027 - .expect("Mutex got poisoned by another test");
49028 -
49029 -@@ -41,8 +42,8 @@ use std::io::Read;
49030 - #[test]
49031 - fn test_finit_and_delete_module() {
49032 - require_capability!(CAP_SYS_MODULE);
49033 -- let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
49034 -- let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test");
49035 -+ let _m0 = crate::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
49036 -+ let _m1 = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test");
49037 -
49038 - let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
49039 -
49040 -@@ -59,8 +60,8 @@ fn test_finit_and_delete_module() {
49041 - #[test]
49042 - fn test_finit_and_delete_modul_with_params() {
49043 - require_capability!(CAP_SYS_MODULE);
49044 -- let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
49045 -- let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test");
49046 -+ let _m0 = crate::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
49047 -+ let _m1 = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test");
49048 -
49049 - let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
49050 -
49051 -@@ -80,8 +81,8 @@ fn test_finit_and_delete_modul_with_params() {
49052 - #[test]
49053 - fn test_init_and_delete_module() {
49054 - require_capability!(CAP_SYS_MODULE);
49055 -- let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
49056 -- let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test");
49057 -+ let _m0 = crate::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
49058 -+ let _m1 = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test");
49059 -
49060 - let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
49061 -
49062 -@@ -100,8 +101,8 @@ fn test_init_and_delete_module() {
49063 - #[test]
49064 - fn test_init_and_delete_module_with_params() {
49065 - require_capability!(CAP_SYS_MODULE);
49066 -- let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
49067 -- let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test");
49068 -+ let _m0 = crate::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
49069 -+ let _m1 = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test");
49070 -
49071 - let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
49072 -
49073 -@@ -121,8 +122,8 @@ fn test_init_and_delete_module_with_params() {
49074 - #[test]
49075 - fn test_finit_module_invalid() {
49076 - require_capability!(CAP_SYS_MODULE);
49077 -- let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
49078 -- let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test");
49079 -+ let _m0 = crate::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
49080 -+ let _m1 = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test");
49081 -
49082 - let kmod_path = "/dev/zero";
49083 -
49084 -@@ -135,8 +136,8 @@ fn test_finit_module_invalid() {
49085 - #[test]
49086 - fn test_finit_module_twice_and_delete_module() {
49087 - require_capability!(CAP_SYS_MODULE);
49088 -- let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
49089 -- let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test");
49090 -+ let _m0 = crate::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
49091 -+ let _m1 = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test");
49092 -
49093 - let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
49094 -
49095 -@@ -157,8 +158,8 @@ fn test_finit_module_twice_and_delete_module() {
49096 - #[test]
49097 - fn test_delete_module_not_loaded() {
49098 - require_capability!(CAP_SYS_MODULE);
49099 -- let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
49100 -- let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test");
49101 -+ let _m0 = crate::KMOD_MTX.lock().expect("Mutex got poisoned by another test");
49102 -+ let _m1 = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test");
49103 -
49104 - let result = delete_module(&CString::new("hello").unwrap(), DeleteModuleFlags::empty());
49105 -
49106 -diff --git a/third_party/rust/nix/test/test_mount.rs b/third_party/rust/nix/test/test_mount.rs
49107 -index d2e08bc42855d..c1b6c8a3bf2d2 100644
49108 ---- a/third_party/rust/nix/test/test_mount.rs
49109 -+++ b/third_party/rust/nix/test/test_mount.rs
49110 -@@ -1,12 +1,10 @@
49111 -+mod common;
49112 -+
49113 - // Impelmentation note: to allow unprivileged users to run it, this test makes
49114 - // use of user and mount namespaces. On systems that allow unprivileged user
49115 - // namespaces (Linux >= 3.8 compiled with CONFIG_USER_NS), the test should run
49116 - // without root.
49117 -
49118 --extern crate libc;
49119 --extern crate nix;
49120 --extern crate tempfile;
49121 --
49122 - #[cfg(target_os = "linux")]
49123 - mod test_mount {
49124 - use std::fs::{self, File};
49125 -@@ -226,6 +224,7 @@ fn main() {
49126 - use test_mount::{setup_namespaces, test_mount_tmpfs_without_flags_allows_rwx,
49127 - test_mount_rdonly_disallows_write, test_mount_noexec_disallows_exec,
49128 - test_mount_bind};
49129 -+ skip_if_cirrus!("Fails for an unknown reason Cirrus CI. Bug #1351");
49130 - setup_namespaces();
49131 -
49132 - run_tests!(test_mount_tmpfs_without_flags_allows_rwx,
49133 -diff --git a/third_party/rust/nix/test/test_mq.rs b/third_party/rust/nix/test/test_mq.rs
49134 -index caac4fc261cd6..1667a35b1a04b 100644
49135 ---- a/third_party/rust/nix/test/test_mq.rs
49136 -+++ b/third_party/rust/nix/test/test_mq.rs
49137 -@@ -1,17 +1,15 @@
49138 --use libc::c_long;
49139 --
49140 - use std::ffi::CString;
49141 - use std::str;
49142 -
49143 - use nix::errno::Errno::*;
49144 - use nix::Error::Sys;
49145 --use nix::mqueue::{mq_open, mq_close, mq_send, mq_receive};
49146 -+use nix::mqueue::{mq_open, mq_close, mq_send, mq_receive, mq_attr_member_t};
49147 - use nix::mqueue::{MqAttr, MQ_OFlag};
49148 - use nix::sys::stat::Mode;
49149 -
49150 - #[test]
49151 - fn test_mq_send_and_receive() {
49152 -- const MSG_SIZE: c_long = 32;
49153 -+ const MSG_SIZE: mq_attr_member_t = 32;
49154 - let attr = MqAttr::new(0, 10, MSG_SIZE, 0);
49155 - let mq_name= &CString::new(b"/a_nix_test_queue".as_ref()).unwrap();
49156 -
49157 -@@ -31,7 +29,7 @@ fn test_mq_send_and_receive() {
49158 - let mut buf = [0u8; 32];
49159 - let mut prio = 0u32;
49160 - let len = mq_receive(mqd1, &mut buf, &mut prio).unwrap();
49161 -- assert!(prio == 1);
49162 -+ assert_eq!(prio, 1);
49163 -
49164 - mq_close(mqd1).unwrap();
49165 - mq_close(mqd0).unwrap();
49166 -@@ -43,7 +41,7 @@ fn test_mq_send_and_receive() {
49167 - #[cfg(not(any(target_os = "netbsd")))]
49168 - fn test_mq_getattr() {
49169 - use nix::mqueue::mq_getattr;
49170 -- const MSG_SIZE: c_long = 32;
49171 -+ const MSG_SIZE: mq_attr_member_t = 32;
49172 - let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0);
49173 - let mq_name = &CString::new(b"/attr_test_get_attr".as_ref()).unwrap();
49174 - let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
49175 -@@ -66,7 +64,7 @@ fn test_mq_getattr() {
49176 - #[cfg_attr(any(target_arch = "mips", target_arch = "mips64"), ignore)]
49177 - fn test_mq_setattr() {
49178 - use nix::mqueue::{mq_getattr, mq_setattr};
49179 -- const MSG_SIZE: c_long = 32;
49180 -+ const MSG_SIZE: mq_attr_member_t = 32;
49181 - let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0);
49182 - let mq_name = &CString::new(b"/attr_test_get_attr".as_ref()).unwrap();
49183 - let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
49184 -@@ -87,7 +85,7 @@ fn test_mq_setattr() {
49185 - // O_NONBLOCK can be set (see tests below)
49186 - assert_ne!(new_attr_get, new_attr);
49187 -
49188 -- let new_attr_non_blocking = MqAttr::new(MQ_OFlag::O_NONBLOCK.bits() as c_long, 10, MSG_SIZE, 0);
49189 -+ let new_attr_non_blocking = MqAttr::new(MQ_OFlag::O_NONBLOCK.bits() as mq_attr_member_t, 10, MSG_SIZE, 0);
49190 - mq_setattr(mqd, &new_attr_non_blocking).unwrap();
49191 - let new_attr_get = mq_getattr(mqd).unwrap();
49192 -
49193 -@@ -103,7 +101,7 @@ fn test_mq_setattr() {
49194 - #[cfg_attr(any(target_arch = "mips", target_arch = "mips64"), ignore)]
49195 - fn test_mq_set_nonblocking() {
49196 - use nix::mqueue::{mq_getattr, mq_set_nonblock, mq_remove_nonblock};
49197 -- const MSG_SIZE: c_long = 32;
49198 -+ const MSG_SIZE: mq_attr_member_t = 32;
49199 - let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0);
49200 - let mq_name = &CString::new(b"/attr_test_get_attr".as_ref()).unwrap();
49201 - let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
49202 -@@ -116,10 +114,10 @@ fn test_mq_set_nonblocking() {
49203 - let mqd = r.unwrap();
49204 - mq_set_nonblock(mqd).unwrap();
49205 - let new_attr = mq_getattr(mqd);
49206 -- assert!(new_attr.unwrap().flags() == MQ_OFlag::O_NONBLOCK.bits() as c_long);
49207 -+ assert_eq!(new_attr.unwrap().flags(), MQ_OFlag::O_NONBLOCK.bits() as mq_attr_member_t);
49208 - mq_remove_nonblock(mqd).unwrap();
49209 - let new_attr = mq_getattr(mqd);
49210 -- assert!(new_attr.unwrap().flags() == 0);
49211 -+ assert_eq!(new_attr.unwrap().flags(), 0);
49212 - mq_close(mqd).unwrap();
49213 - }
49214 -
49215 -@@ -127,7 +125,7 @@ fn test_mq_set_nonblocking() {
49216 - #[cfg(not(any(target_os = "netbsd")))]
49217 - fn test_mq_unlink() {
49218 - use nix::mqueue::mq_unlink;
49219 -- const MSG_SIZE: c_long = 32;
49220 -+ const MSG_SIZE: mq_attr_member_t = 32;
49221 - let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0);
49222 - let mq_name_opened = &CString::new(b"/mq_unlink_test".as_ref()).unwrap();
49223 - let mq_name_not_opened = &CString::new(b"/mq_unlink_test".as_ref()).unwrap();
49224 -@@ -141,12 +139,12 @@ fn test_mq_unlink() {
49225 - let mqd = r.unwrap();
49226 -
49227 - let res_unlink = mq_unlink(mq_name_opened);
49228 -- assert!(res_unlink == Ok(()) );
49229 -+ assert_eq!(res_unlink, Ok(()) );
49230 -
49231 - let res_unlink_not_opened = mq_unlink(mq_name_not_opened);
49232 -- assert!(res_unlink_not_opened == Err(Sys(ENOENT)) );
49233 -+ assert_eq!(res_unlink_not_opened, Err(Sys(ENOENT)) );
49234 -
49235 - mq_close(mqd).unwrap();
49236 - let res_unlink_after_close = mq_unlink(mq_name_opened);
49237 -- assert!(res_unlink_after_close == Err(Sys(ENOENT)) );
49238 -+ assert_eq!(res_unlink_after_close, Err(Sys(ENOENT)) );
49239 - }
49240 -diff --git a/third_party/rust/nix/test/test_poll.rs b/third_party/rust/nix/test/test_poll.rs
49241 -index aef40e4792b5a..acfaad8bea6c0 100644
49242 ---- a/third_party/rust/nix/test/test_poll.rs
49243 -+++ b/third_party/rust/nix/test/test_poll.rs
49244 -@@ -1,5 +1,21 @@
49245 --use nix::poll::{PollFlags, poll, PollFd};
49246 --use nix::unistd::{write, pipe};
49247 -+use nix::{
49248 -+ Error,
49249 -+ errno::Errno,
49250 -+ poll::{PollFlags, poll, PollFd},
49251 -+ unistd::{write, pipe}
49252 -+};
49253 -+
49254 -+macro_rules! loop_while_eintr {
49255 -+ ($poll_expr: expr) => {
49256 -+ loop {
49257 -+ match $poll_expr {
49258 -+ Ok(nfds) => break nfds,
49259 -+ Err(Error::Sys(Errno::EINTR)) => (),
49260 -+ Err(e) => panic!("{}", e)
49261 -+ }
49262 -+ }
49263 -+ }
49264 -+}
49265 -
49266 - #[test]
49267 - fn test_poll() {
49268 -@@ -7,7 +23,7 @@ fn test_poll() {
49269 - let mut fds = [PollFd::new(r, PollFlags::POLLIN)];
49270 -
49271 - // Poll an idle pipe. Should timeout
49272 -- let nfds = poll(&mut fds, 100).unwrap();
49273 -+ let nfds = loop_while_eintr!(poll(&mut fds, 100));
49274 - assert_eq!(nfds, 0);
49275 - assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN));
49276 -
49277 -@@ -37,14 +53,15 @@ fn test_ppoll() {
49278 - let mut fds = [PollFd::new(r, PollFlags::POLLIN)];
49279 -
49280 - // Poll an idle pipe. Should timeout
49281 -- let nfds = ppoll(&mut fds, timeout, SigSet::empty()).unwrap();
49282 -+ let sigset = SigSet::empty();
49283 -+ let nfds = loop_while_eintr!(ppoll(&mut fds, Some(timeout), sigset));
49284 - assert_eq!(nfds, 0);
49285 - assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN));
49286 -
49287 - write(w, b".").unwrap();
49288 -
49289 - // Poll a readable pipe. Should return an event.
49290 -- let nfds = ppoll(&mut fds, timeout, SigSet::empty()).unwrap();
49291 -+ let nfds = ppoll(&mut fds, Some(timeout), SigSet::empty()).unwrap();
49292 - assert_eq!(nfds, 1);
49293 - assert!(fds[0].revents().unwrap().contains(PollFlags::POLLIN));
49294 - }
49295 -diff --git a/third_party/rust/nix/test/test_pty.rs b/third_party/rust/nix/test/test_pty.rs
49296 -index 476b15c10128c..ab347bb040f5f 100644
49297 ---- a/third_party/rust/nix/test/test_pty.rs
49298 -+++ b/third_party/rust/nix/test/test_pty.rs
49299 -@@ -1,4 +1,5 @@
49300 --use std::io::Write;
49301 -+use std::fs::File;
49302 -+use std::io::{Read, Write};
49303 - use std::path::Path;
49304 - use std::os::unix::prelude::*;
49305 - use tempfile::tempfile;
49306 -@@ -28,7 +29,7 @@ fn test_explicit_close() {
49307 - #[test]
49308 - #[cfg(any(target_os = "android", target_os = "linux"))]
49309 - fn test_ptsname_equivalence() {
49310 -- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
49311 -+ let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
49312 -
49313 - // Open a new PTTY master
49314 - let master_fd = posix_openpt(OFlag::O_RDWR).unwrap();
49315 -@@ -45,7 +46,7 @@ fn test_ptsname_equivalence() {
49316 - #[test]
49317 - #[cfg(any(target_os = "android", target_os = "linux"))]
49318 - fn test_ptsname_copy() {
49319 -- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
49320 -+ let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
49321 -
49322 - // Open a new PTTY master
49323 - let master_fd = posix_openpt(OFlag::O_RDWR).unwrap();
49324 -@@ -54,7 +55,7 @@ fn test_ptsname_copy() {
49325 - // Get the name of the slave
49326 - let slave_name1 = unsafe { ptsname(&master_fd) }.unwrap();
49327 - let slave_name2 = unsafe { ptsname(&master_fd) }.unwrap();
49328 -- assert!(slave_name1 == slave_name2);
49329 -+ assert_eq!(slave_name1, slave_name2);
49330 - // Also make sure that the string was actually copied and they point to different parts of
49331 - // memory.
49332 - assert!(slave_name1.as_ptr() != slave_name2.as_ptr());
49333 -@@ -71,7 +72,7 @@ fn test_ptsname_r_copy() {
49334 - // Get the name of the slave
49335 - let slave_name1 = ptsname_r(&master_fd).unwrap();
49336 - let slave_name2 = ptsname_r(&master_fd).unwrap();
49337 -- assert!(slave_name1 == slave_name2);
49338 -+ assert_eq!(slave_name1, slave_name2);
49339 - assert!(slave_name1.as_ptr() != slave_name2.as_ptr());
49340 - }
49341 -
49342 -@@ -79,7 +80,7 @@ fn test_ptsname_r_copy() {
49343 - #[test]
49344 - #[cfg(any(target_os = "android", target_os = "linux"))]
49345 - fn test_ptsname_unique() {
49346 -- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
49347 -+ let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
49348 -
49349 - // Open a new PTTY master
49350 - let master1_fd = posix_openpt(OFlag::O_RDWR).unwrap();
49351 -@@ -95,35 +96,74 @@ fn test_ptsname_unique() {
49352 - assert!(slave_name1 != slave_name2);
49353 - }
49354 -
49355 --/// Test opening a master/slave PTTY pair
49356 --///
49357 --/// This is a single larger test because much of these functions aren't useful by themselves. So for
49358 --/// this test we perform the basic act of getting a file handle for a connect master/slave PTTY
49359 --/// pair.
49360 --#[test]
49361 --fn test_open_ptty_pair() {
49362 -- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
49363 -+/// Common setup for testing PTTY pairs
49364 -+fn open_ptty_pair() -> (PtyMaster, File) {
49365 -+ let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
49366 -
49367 - // Open a new PTTY master
49368 -- let master_fd = posix_openpt(OFlag::O_RDWR).expect("posix_openpt failed");
49369 -- assert!(master_fd.as_raw_fd() > 0);
49370 -+ let master = posix_openpt(OFlag::O_RDWR).expect("posix_openpt failed");
49371 -
49372 - // Allow a slave to be generated for it
49373 -- grantpt(&master_fd).expect("grantpt failed");
49374 -- unlockpt(&master_fd).expect("unlockpt failed");
49375 -+ grantpt(&master).expect("grantpt failed");
49376 -+ unlockpt(&master).expect("unlockpt failed");
49377 -
49378 - // Get the name of the slave
49379 -- let slave_name = unsafe { ptsname(&master_fd) }.expect("ptsname failed");
49380 -+ let slave_name = unsafe { ptsname(&master) }.expect("ptsname failed");
49381 -
49382 - // Open the slave device
49383 - let slave_fd = open(Path::new(&slave_name), OFlag::O_RDWR, stat::Mode::empty()).unwrap();
49384 -- assert!(slave_fd > 0);
49385 -+ let slave = unsafe { File::from_raw_fd(slave_fd) };
49386 -+
49387 -+ (master, slave)
49388 -+}
49389 -+
49390 -+/// Test opening a master/slave PTTY pair
49391 -+///
49392 -+/// This uses a common `open_ptty_pair` because much of these functions aren't useful by
49393 -+/// themselves. So for this test we perform the basic act of getting a file handle for a
49394 -+/// master/slave PTTY pair, then just sanity-check the raw values.
49395 -+#[test]
49396 -+fn test_open_ptty_pair() {
49397 -+ let (master, slave) = open_ptty_pair();
49398 -+ assert!(master.as_raw_fd() > 0);
49399 -+ assert!(slave.as_raw_fd() > 0);
49400 -+}
49401 -+
49402 -+/// Put the terminal in raw mode.
49403 -+fn make_raw(fd: RawFd) {
49404 -+ let mut termios = tcgetattr(fd).unwrap();
49405 -+ cfmakeraw(&mut termios);
49406 -+ tcsetattr(fd, SetArg::TCSANOW, &termios).unwrap();
49407 -+}
49408 -+
49409 -+/// Test `io::Read` on the PTTY master
49410 -+#[test]
49411 -+fn test_read_ptty_pair() {
49412 -+ let (mut master, mut slave) = open_ptty_pair();
49413 -+ make_raw(slave.as_raw_fd());
49414 -+
49415 -+ let mut buf = [0u8; 5];
49416 -+ slave.write_all(b"hello").unwrap();
49417 -+ master.read_exact(&mut buf).unwrap();
49418 -+ assert_eq!(&buf, b"hello");
49419 -+}
49420 -+
49421 -+/// Test `io::Write` on the PTTY master
49422 -+#[test]
49423 -+fn test_write_ptty_pair() {
49424 -+ let (mut master, mut slave) = open_ptty_pair();
49425 -+ make_raw(slave.as_raw_fd());
49426 -+
49427 -+ let mut buf = [0u8; 5];
49428 -+ master.write_all(b"adios").unwrap();
49429 -+ slave.read_exact(&mut buf).unwrap();
49430 -+ assert_eq!(&buf, b"adios");
49431 - }
49432 -
49433 - #[test]
49434 - fn test_openpty() {
49435 - // openpty uses ptname(3) internally
49436 -- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
49437 -+ let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
49438 -
49439 - let pty = openpty(None, None).unwrap();
49440 - assert!(pty.master > 0);
49441 -@@ -133,21 +173,21 @@ fn test_openpty() {
49442 - let string = "foofoofoo\n";
49443 - let mut buf = [0u8; 10];
49444 - write(pty.master, string.as_bytes()).unwrap();
49445 -- ::read_exact(pty.slave, &mut buf);
49446 -+ crate::read_exact(pty.slave, &mut buf);
49447 -
49448 - assert_eq!(&buf, string.as_bytes());
49449 -
49450 - // Read the echo as well
49451 - let echoed_string = "foofoofoo\r\n";
49452 - let mut buf = [0u8; 11];
49453 -- ::read_exact(pty.master, &mut buf);
49454 -+ crate::read_exact(pty.master, &mut buf);
49455 - assert_eq!(&buf, echoed_string.as_bytes());
49456 -
49457 - let string2 = "barbarbarbar\n";
49458 - let echoed_string2 = "barbarbarbar\r\n";
49459 - let mut buf = [0u8; 14];
49460 - write(pty.slave, string2.as_bytes()).unwrap();
49461 -- ::read_exact(pty.master, &mut buf);
49462 -+ crate::read_exact(pty.master, &mut buf);
49463 -
49464 - assert_eq!(&buf, echoed_string2.as_bytes());
49465 -
49466 -@@ -158,14 +198,14 @@ fn test_openpty() {
49467 - #[test]
49468 - fn test_openpty_with_termios() {
49469 - // openpty uses ptname(3) internally
49470 -- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
49471 -+ let _m = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
49472 -
49473 - // Open one pty to get attributes for the second one
49474 - let mut termios = {
49475 - let pty = openpty(None, None).unwrap();
49476 - assert!(pty.master > 0);
49477 - assert!(pty.slave > 0);
49478 -- let termios = tcgetattr(pty.master).unwrap();
49479 -+ let termios = tcgetattr(pty.slave).unwrap();
49480 - close(pty.master).unwrap();
49481 - close(pty.slave).unwrap();
49482 - termios
49483 -@@ -182,20 +222,20 @@ fn test_openpty_with_termios() {
49484 - let string = "foofoofoo\n";
49485 - let mut buf = [0u8; 10];
49486 - write(pty.master, string.as_bytes()).unwrap();
49487 -- ::read_exact(pty.slave, &mut buf);
49488 -+ crate::read_exact(pty.slave, &mut buf);
49489 -
49490 - assert_eq!(&buf, string.as_bytes());
49491 -
49492 - // read the echo as well
49493 - let echoed_string = "foofoofoo\n";
49494 -- ::read_exact(pty.master, &mut buf);
49495 -+ crate::read_exact(pty.master, &mut buf);
49496 - assert_eq!(&buf, echoed_string.as_bytes());
49497 -
49498 - let string2 = "barbarbarbar\n";
49499 - let echoed_string2 = "barbarbarbar\n";
49500 - let mut buf = [0u8; 13];
49501 - write(pty.slave, string2.as_bytes()).unwrap();
49502 -- ::read_exact(pty.master, &mut buf);
49503 -+ crate::read_exact(pty.master, &mut buf);
49504 -
49505 - assert_eq!(&buf, echoed_string2.as_bytes());
49506 -
49507 -@@ -209,9 +249,9 @@ fn test_forkpty() {
49508 - use nix::sys::signal::*;
49509 - use nix::sys::wait::wait;
49510 - // forkpty calls openpty which uses ptname(3) internally.
49511 -- let _m0 = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
49512 -+ let _m0 = crate::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
49513 - // forkpty spawns a child process
49514 -- let _m1 = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
49515 -+ let _m1 = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test");
49516 -
49517 - let string = "naninani\n";
49518 - let echoed_string = "naninani\r\n";
49519 -@@ -225,7 +265,7 @@ fn test_forkpty() {
49520 - Parent { child } => {
49521 - let mut buf = [0u8; 10];
49522 - assert!(child.as_raw() > 0);
49523 -- ::read_exact(pty.master, &mut buf);
49524 -+ crate::read_exact(pty.master, &mut buf);
49525 - kill(child, SIGTERM).unwrap();
49526 - wait().unwrap(); // keep other tests using generic wait from getting our child
49527 - assert_eq!(&buf, echoed_string.as_bytes());
49528 -diff --git a/third_party/rust/nix/test/test_ptymaster_drop.rs b/third_party/rust/nix/test/test_ptymaster_drop.rs
49529 -index 9b59d66435ed0..ff939b9c63e76 100644
49530 ---- a/third_party/rust/nix/test/test_ptymaster_drop.rs
49531 -+++ b/third_party/rust/nix/test/test_ptymaster_drop.rs
49532 -@@ -1,21 +1,24 @@
49533 --extern crate nix;
49534 -+#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
49535 -+mod t {
49536 -+ use nix::fcntl::OFlag;
49537 -+ use nix::pty::*;
49538 -+ use nix::unistd::close;
49539 -+ use std::os::unix::io::AsRawFd;
49540 -
49541 --use nix::fcntl::OFlag;
49542 --use nix::pty::*;
49543 --use nix::unistd::close;
49544 --use std::os::unix::io::AsRawFd;
49545 --
49546 --/// Regression test for Issue #659
49547 --/// `PtyMaster` should panic rather than double close the file descriptor
49548 --/// This must run in its own test process because it deliberately creates a race
49549 --/// condition.
49550 --#[test]
49551 --#[should_panic(expected = "Closing an invalid file descriptor!")]
49552 --// In Travis on i686-unknown-linux-musl, this test gets SIGABRT. I don't know
49553 --// why. It doesn't happen on any other target, and it doesn't happen on my PC.
49554 --#[cfg_attr(all(target_env = "musl", target_arch = "x86"), ignore)]
49555 --fn test_double_close() {
49556 -- let m = posix_openpt(OFlag::O_RDWR).unwrap();
49557 -- close(m.as_raw_fd()).unwrap();
49558 -- drop(m); // should panic here
49559 -+ /// Regression test for Issue #659
49560 -+ ///
49561 -+ /// `PtyMaster` should panic rather than double close the file descriptor
49562 -+ /// This must run in its own test process because it deliberately creates a
49563 -+ /// race condition.
49564 -+ #[test]
49565 -+ #[should_panic(expected = "Closing an invalid file descriptor!")]
49566 -+ // In Travis on i686-unknown-linux-musl, this test gets SIGABRT. I don't
49567 -+ // know why. It doesn't happen on any other target, and it doesn't happen
49568 -+ // on my PC.
49569 -+ #[cfg_attr(all(target_env = "musl", target_arch = "x86"), ignore)]
49570 -+ fn test_double_close() {
49571 -+ let m = posix_openpt(OFlag::O_RDWR).unwrap();
49572 -+ close(m.as_raw_fd()).unwrap();
49573 -+ drop(m); // should panic here
49574 -+ }
49575 - }
49576 -diff --git a/third_party/rust/nix/test/test_sched.rs b/third_party/rust/nix/test/test_sched.rs
49577 -new file mode 100644
49578 -index 0000000000000..922196a3dba73
49579 ---- /dev/null
49580 -+++ b/third_party/rust/nix/test/test_sched.rs
49581 -@@ -0,0 +1,32 @@
49582 -+use nix::sched::{sched_getaffinity, sched_setaffinity, CpuSet};
49583 -+use nix::unistd::Pid;
49584 -+
49585 -+#[test]
49586 -+fn test_sched_affinity() {
49587 -+ // If pid is zero, then the mask of the calling process is returned.
49588 -+ let initial_affinity = sched_getaffinity(Pid::from_raw(0)).unwrap();
49589 -+ let mut at_least_one_cpu = false;
49590 -+ let mut last_valid_cpu = 0;
49591 -+ for field in 0..CpuSet::count() {
49592 -+ if initial_affinity.is_set(field).unwrap() {
49593 -+ at_least_one_cpu = true;
49594 -+ last_valid_cpu = field;
49595 -+ }
49596 -+ }
49597 -+ assert!(at_least_one_cpu);
49598 -+
49599 -+ // Now restrict the running CPU
49600 -+ let mut new_affinity = CpuSet::new();
49601 -+ new_affinity.set(last_valid_cpu).unwrap();
49602 -+ sched_setaffinity(Pid::from_raw(0), &new_affinity).unwrap();
49603 -+
49604 -+ // And now re-check the affinity which should be only the one we set.
49605 -+ let updated_affinity = sched_getaffinity(Pid::from_raw(0)).unwrap();
49606 -+ for field in 0..CpuSet::count() {
49607 -+ // Should be set only for the CPU we set previously
49608 -+ assert_eq!(updated_affinity.is_set(field).unwrap(), field==last_valid_cpu)
49609 -+ }
49610 -+
49611 -+ // Finally, reset the initial CPU set
49612 -+ sched_setaffinity(Pid::from_raw(0), &initial_affinity).unwrap();
49613 -+}
49614 -diff --git a/third_party/rust/nix/test/test_stat.rs b/third_party/rust/nix/test/test_stat.rs
49615 -index 1173455fae8db..0b9466685607b 100644
49616 ---- a/third_party/rust/nix/test/test_stat.rs
49617 -+++ b/third_party/rust/nix/test/test_stat.rs
49618 -@@ -1,15 +1,26 @@
49619 --use std::fs::{self, File};
49620 -+#[cfg(not(target_os = "redox"))]
49621 -+use std::fs;
49622 -+use std::fs::File;
49623 -+#[cfg(not(target_os = "redox"))]
49624 - use std::os::unix::fs::{symlink, PermissionsExt};
49625 - use std::os::unix::prelude::AsRawFd;
49626 -+#[cfg(not(target_os = "redox"))]
49627 - use std::time::{Duration, UNIX_EPOCH};
49628 -+#[cfg(not(target_os = "redox"))]
49629 - use std::path::Path;
49630 -
49631 --#[cfg(not(any(target_os = "netbsd")))]
49632 -+#[cfg(not(any(target_os = "netbsd", target_os = "redox")))]
49633 - use libc::{S_IFMT, S_IFLNK, mode_t};
49634 -
49635 -+#[cfg(not(target_os = "redox"))]
49636 - use nix::{fcntl, Error};
49637 --use nix::errno::{Errno};
49638 --use nix::sys::stat::{self, fchmod, fchmodat, futimens, stat, utimes, utimensat, mkdirat};
49639 -+#[cfg(not(target_os = "redox"))]
49640 -+use nix::errno::Errno;
49641 -+#[cfg(not(target_os = "redox"))]
49642 -+use nix::sys::stat::{self, futimens, utimes};
49643 -+use nix::sys::stat::{fchmod, stat};
49644 -+#[cfg(not(target_os = "redox"))]
49645 -+use nix::sys::stat::{fchmodat, utimensat, mkdirat};
49646 - #[cfg(any(target_os = "linux",
49647 - target_os = "haiku",
49648 - target_os = "ios",
49649 -@@ -17,15 +28,19 @@ use nix::sys::stat::{self, fchmod, fchmodat, futimens, stat, utimes, utimensat,
49650 - target_os = "freebsd",
49651 - target_os = "netbsd"))]
49652 - use nix::sys::stat::lutimes;
49653 --use nix::sys::stat::{Mode, FchmodatFlags, UtimensatFlags};
49654 -+#[cfg(not(target_os = "redox"))]
49655 -+use nix::sys::stat::{FchmodatFlags, UtimensatFlags};
49656 -+use nix::sys::stat::Mode;
49657 -
49658 --#[cfg(not(any(target_os = "netbsd")))]
49659 -+#[cfg(not(any(target_os = "netbsd", target_os = "redox")))]
49660 - use nix::sys::stat::FileStat;
49661 -
49662 -+#[cfg(not(target_os = "redox"))]
49663 - use nix::sys::time::{TimeSpec, TimeVal, TimeValLike};
49664 -+#[cfg(not(target_os = "redox"))]
49665 - use nix::unistd::chdir;
49666 -
49667 --#[cfg(not(any(target_os = "netbsd")))]
49668 -+#[cfg(not(any(target_os = "netbsd", target_os = "redox")))]
49669 - use nix::Result;
49670 - use tempfile;
49671 -
49672 -@@ -33,27 +48,27 @@ use tempfile;
49673 - // uid and gid are signed on Windows, but not on other platforms. This function
49674 - // allows warning free compiles on all platforms, and can be removed when
49675 - // expression-level #[allow] is available.
49676 --#[cfg(not(any(target_os = "netbsd")))]
49677 -+#[cfg(not(any(target_os = "netbsd", target_os = "redox")))]
49678 - fn valid_uid_gid(stat: FileStat) -> bool {
49679 - // uid could be 0 for the `root` user. This quite possible when
49680 - // the tests are being run on a rooted Android device.
49681 - stat.st_uid >= 0 && stat.st_gid >= 0
49682 - }
49683 -
49684 --#[cfg(not(any(target_os = "netbsd")))]
49685 -+#[cfg(not(any(target_os = "netbsd", target_os = "redox")))]
49686 - fn assert_stat_results(stat_result: Result<FileStat>) {
49687 - let stats = stat_result.expect("stat call failed");
49688 - assert!(stats.st_dev > 0); // must be positive integer, exact number machine dependent
49689 - assert!(stats.st_ino > 0); // inode is positive integer, exact number machine dependent
49690 - assert!(stats.st_mode > 0); // must be positive integer
49691 -- assert!(stats.st_nlink == 1); // there links created, must be 1
49692 -+ assert_eq!(stats.st_nlink, 1); // there links created, must be 1
49693 - assert!(valid_uid_gid(stats)); // must be positive integers
49694 -- assert!(stats.st_size == 0); // size is 0 because we did not write anything to the file
49695 -+ assert_eq!(stats.st_size, 0); // size is 0 because we did not write anything to the file
49696 - assert!(stats.st_blksize > 0); // must be positive integer, exact number machine dependent
49697 - assert!(stats.st_blocks <= 16); // Up to 16 blocks can be allocated for a blank file
49698 - }
49699 -
49700 --#[cfg(not(any(target_os = "netbsd")))]
49701 -+#[cfg(not(any(target_os = "netbsd", target_os = "redox")))]
49702 - fn assert_lstat_results(stat_result: Result<FileStat>) {
49703 - let stats = stat_result.expect("stat call failed");
49704 - assert!(stats.st_dev > 0); // must be positive integer, exact number machine dependent
49705 -@@ -63,8 +78,8 @@ fn assert_lstat_results(stat_result: Result<FileStat>) {
49706 - // st_mode is c_uint (u32 on Android) while S_IFMT is mode_t
49707 - // (u16 on Android), and that will be a compile error.
49708 - // On other platforms they are the same (either both are u16 or u32).
49709 -- assert!((stats.st_mode as usize) & (S_IFMT as usize) == S_IFLNK as usize); // should be a link
49710 -- assert!(stats.st_nlink == 1); // there links created, must be 1
49711 -+ assert_eq!((stats.st_mode as usize) & (S_IFMT as usize), S_IFLNK as usize); // should be a link
49712 -+ assert_eq!(stats.st_nlink, 1); // there links created, must be 1
49713 - assert!(valid_uid_gid(stats)); // must be positive integers
49714 - assert!(stats.st_size > 0); // size is > 0 because it points to another file
49715 - assert!(stats.st_blksize > 0); // must be positive integer, exact number machine dependent
49716 -@@ -76,7 +91,7 @@ fn assert_lstat_results(stat_result: Result<FileStat>) {
49717 - }
49718 -
49719 - #[test]
49720 --#[cfg(not(any(target_os = "netbsd")))]
49721 -+#[cfg(not(any(target_os = "netbsd", target_os = "redox")))]
49722 - fn test_stat_and_fstat() {
49723 - use nix::sys::stat::fstat;
49724 -
49725 -@@ -92,7 +107,7 @@ fn test_stat_and_fstat() {
49726 - }
49727 -
49728 - #[test]
49729 --#[cfg(not(any(target_os = "netbsd")))]
49730 -+#[cfg(not(any(target_os = "netbsd", target_os = "redox")))]
49731 - fn test_fstatat() {
49732 - let tempdir = tempfile::tempdir().unwrap();
49733 - let filename = tempdir.path().join("foo.txt");
49734 -@@ -108,7 +123,7 @@ fn test_fstatat() {
49735 - }
49736 -
49737 - #[test]
49738 --#[cfg(not(any(target_os = "netbsd")))]
49739 -+#[cfg(not(any(target_os = "netbsd", target_os = "redox")))]
49740 - fn test_stat_fstat_lstat() {
49741 - use nix::sys::stat::{fstat, lstat};
49742 -
49743 -@@ -155,8 +170,9 @@ fn test_fchmod() {
49744 - }
49745 -
49746 - #[test]
49747 -+#[cfg(not(target_os = "redox"))]
49748 - fn test_fchmodat() {
49749 -- let _dr = ::DirRestore::new();
49750 -+ let _dr = crate::DirRestore::new();
49751 - let tempdir = tempfile::tempdir().unwrap();
49752 - let filename = "foo.txt";
49753 - let fullpath = tempdir.path().join(filename);
49754 -@@ -186,6 +202,7 @@ fn test_fchmodat() {
49755 - ///
49756 - /// The atime and mtime are expressed with a resolution of seconds because some file systems
49757 - /// (like macOS's HFS+) do not have higher granularity.
49758 -+#[cfg(not(target_os = "redox"))]
49759 - fn assert_times_eq(exp_atime_sec: u64, exp_mtime_sec: u64, attr: &fs::Metadata) {
49760 - assert_eq!(
49761 - Duration::new(exp_atime_sec, 0),
49762 -@@ -196,6 +213,7 @@ fn assert_times_eq(exp_atime_sec: u64, exp_mtime_sec: u64, attr: &fs::Metadata)
49763 - }
49764 -
49765 - #[test]
49766 -+#[cfg(not(target_os = "redox"))]
49767 - fn test_utimes() {
49768 - let tempdir = tempfile::tempdir().unwrap();
49769 - let fullpath = tempdir.path().join("file");
49770 -@@ -231,6 +249,7 @@ fn test_lutimes() {
49771 - }
49772 -
49773 - #[test]
49774 -+#[cfg(not(target_os = "redox"))]
49775 - fn test_futimens() {
49776 - let tempdir = tempfile::tempdir().unwrap();
49777 - let fullpath = tempdir.path().join("file");
49778 -@@ -243,8 +262,9 @@ fn test_futimens() {
49779 - }
49780 -
49781 - #[test]
49782 -+#[cfg(not(target_os = "redox"))]
49783 - fn test_utimensat() {
49784 -- let _dr = ::DirRestore::new();
49785 -+ let _dr = crate::DirRestore::new();
49786 - let tempdir = tempfile::tempdir().unwrap();
49787 - let filename = "foo.txt";
49788 - let fullpath = tempdir.path().join(filename);
49789 -@@ -264,6 +284,7 @@ fn test_utimensat() {
49790 - }
49791 -
49792 - #[test]
49793 -+#[cfg(not(target_os = "redox"))]
49794 - fn test_mkdirat_success_path() {
49795 - let tempdir = tempfile::tempdir().unwrap();
49796 - let filename = "example_subdir";
49797 -@@ -273,6 +294,7 @@ fn test_mkdirat_success_path() {
49798 - }
49799 -
49800 - #[test]
49801 -+#[cfg(not(target_os = "redox"))]
49802 - fn test_mkdirat_success_mode() {
49803 - let expected_bits = stat::SFlag::S_IFDIR.bits() | stat::Mode::S_IRWXU.bits();
49804 - let tempdir = tempfile::tempdir().unwrap();
49805 -@@ -285,6 +307,7 @@ fn test_mkdirat_success_mode() {
49806 - }
49807 -
49808 - #[test]
49809 -+#[cfg(not(target_os = "redox"))]
49810 - fn test_mkdirat_fail() {
49811 - let tempdir = tempfile::tempdir().unwrap();
49812 - let not_dir_filename= "example_not_dir";
49813 -diff --git a/third_party/rust/nix/test/test_time.rs b/third_party/rust/nix/test/test_time.rs
49814 -new file mode 100644
49815 -index 0000000000000..c321352d79c16
49816 ---- /dev/null
49817 -+++ b/third_party/rust/nix/test/test_time.rs
49818 -@@ -0,0 +1,56 @@
49819 -+#[cfg(any(
49820 -+ target_os = "freebsd",
49821 -+ target_os = "dragonfly",
49822 -+ target_os = "linux",
49823 -+ target_os = "android",
49824 -+ target_os = "emscripten",
49825 -+))]
49826 -+use nix::time::clock_getcpuclockid;
49827 -+use nix::time::{clock_getres, clock_gettime, ClockId};
49828 -+
49829 -+#[test]
49830 -+pub fn test_clock_getres() {
49831 -+ assert!(clock_getres(ClockId::CLOCK_REALTIME).is_ok());
49832 -+}
49833 -+
49834 -+#[test]
49835 -+pub fn test_clock_gettime() {
49836 -+ assert!(clock_gettime(ClockId::CLOCK_REALTIME).is_ok());
49837 -+}
49838 -+
49839 -+#[cfg(any(
49840 -+ target_os = "freebsd",
49841 -+ target_os = "dragonfly",
49842 -+ target_os = "linux",
49843 -+ target_os = "android",
49844 -+ target_os = "emscripten",
49845 -+))]
49846 -+#[test]
49847 -+pub fn test_clock_getcpuclockid() {
49848 -+ let clock_id = clock_getcpuclockid(nix::unistd::Pid::this()).unwrap();
49849 -+ assert!(clock_gettime(clock_id).is_ok());
49850 -+}
49851 -+
49852 -+#[test]
49853 -+pub fn test_clock_id_res() {
49854 -+ assert!(ClockId::CLOCK_REALTIME.res().is_ok());
49855 -+}
49856 -+
49857 -+#[test]
49858 -+pub fn test_clock_id_now() {
49859 -+ assert!(ClockId::CLOCK_REALTIME.now().is_ok());
49860 -+}
49861 -+
49862 -+#[cfg(any(
49863 -+ target_os = "freebsd",
49864 -+ target_os = "dragonfly",
49865 -+ target_os = "linux",
49866 -+ target_os = "android",
49867 -+ target_os = "emscripten",
49868 -+))]
49869 -+#[test]
49870 -+pub fn test_clock_id_pid_cpu_clock_id() {
49871 -+ assert!(ClockId::pid_cpu_clock_id(nix::unistd::Pid::this())
49872 -+ .map(ClockId::now)
49873 -+ .is_ok());
49874 -+}
49875 -diff --git a/third_party/rust/nix/test/test_unistd.rs b/third_party/rust/nix/test/test_unistd.rs
49876 -index 46196dec7ccce..16a8a05dd6d08 100644
49877 ---- a/third_party/rust/nix/test/test_unistd.rs
49878 -+++ b/third_party/rust/nix/test/test_unistd.rs
49879 -@@ -1,26 +1,39 @@
49880 --use nix::fcntl::{self, fcntl, FcntlArg, FdFlag, open, OFlag, readlink};
49881 -+#[cfg(not(target_os = "redox"))]
49882 -+use nix::fcntl::{self, open, readlink};
49883 -+use nix::fcntl::{fcntl, FcntlArg, FdFlag, OFlag};
49884 - use nix::unistd::*;
49885 - use nix::unistd::ForkResult::*;
49886 -+#[cfg(not(target_os = "redox"))]
49887 - use nix::sys::signal::{SaFlags, SigAction, SigHandler, SigSet, Signal, sigaction};
49888 - use nix::sys::wait::*;
49889 - use nix::sys::stat::{self, Mode, SFlag};
49890 -+#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
49891 -+use nix::pty::{posix_openpt, grantpt, unlockpt, ptsname};
49892 - use nix::errno::Errno;
49893 -+#[cfg(not(target_os = "redox"))]
49894 - use nix::Error;
49895 - use std::{env, iter};
49896 -+#[cfg(not(target_os = "redox"))]
49897 - use std::ffi::CString;
49898 --use std::fs::{self, DirBuilder, File};
49899 -+#[cfg(not(target_os = "redox"))]
49900 -+use std::fs::DirBuilder;
49901 -+use std::fs::{self, File};
49902 - use std::io::Write;
49903 - use std::os::unix::prelude::*;
49904 --use tempfile::{self, tempfile};
49905 --use libc::{self, _exit, off_t};
49906 -+#[cfg(not(target_os = "redox"))]
49907 -+use std::path::Path;
49908 -+use tempfile::{tempdir, tempfile};
49909 -+use libc::{_exit, off_t};
49910 -+
49911 -+use crate::*;
49912 -
49913 - #[test]
49914 - #[cfg(not(any(target_os = "netbsd")))]
49915 - fn test_fork_and_waitpid() {
49916 -- let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
49917 -+ let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test");
49918 -
49919 - // Safe: Child only calls `_exit`, which is signal-safe
49920 -- match fork().expect("Error: Fork Failed") {
49921 -+ match unsafe{fork()}.expect("Error: Fork Failed") {
49922 - Child => unsafe { _exit(0) },
49923 - Parent { child } => {
49924 - // assert that child was created and pid > 0
49925 -@@ -29,7 +42,7 @@ fn test_fork_and_waitpid() {
49926 - let wait_status = waitpid(child, None);
49927 - match wait_status {
49928 - // assert that waitpid returned correct status and the pid is the one of the child
49929 -- Ok(WaitStatus::Exited(pid_t, _)) => assert!(pid_t == child),
49930 -+ Ok(WaitStatus::Exited(pid_t, _)) => assert_eq!(pid_t, child),
49931 -
49932 - // panic, must never happen
49933 - s @ Ok(_) => panic!("Child exited {:?}, should never happen", s),
49934 -@@ -45,10 +58,10 @@ fn test_fork_and_waitpid() {
49935 - #[test]
49936 - fn test_wait() {
49937 - // Grab FORK_MTX so wait doesn't reap a different test's child process
49938 -- let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
49939 -+ let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test");
49940 -
49941 - // Safe: Child only calls `_exit`, which is signal-safe
49942 -- match fork().expect("Error: Fork Failed") {
49943 -+ match unsafe{fork()}.expect("Error: Fork Failed") {
49944 - Child => unsafe { _exit(0) },
49945 - Parent { child } => {
49946 - let wait_status = wait();
49947 -@@ -81,8 +94,9 @@ fn test_mkstemp_directory() {
49948 - }
49949 -
49950 - #[test]
49951 -+#[cfg(not(target_os = "redox"))]
49952 - fn test_mkfifo() {
49953 -- let tempdir = tempfile::tempdir().unwrap();
49954 -+ let tempdir = tempdir().unwrap();
49955 - let mkfifo_fifo = tempdir.path().join("mkfifo_fifo");
49956 -
49957 - mkfifo(&mkfifo_fifo, Mode::S_IRUSR).unwrap();
49958 -@@ -93,11 +107,70 @@ fn test_mkfifo() {
49959 - }
49960 -
49961 - #[test]
49962 -+#[cfg(not(target_os = "redox"))]
49963 - fn test_mkfifo_directory() {
49964 - // mkfifo should fail if a directory is given
49965 - assert!(mkfifo(&env::temp_dir(), Mode::S_IRUSR).is_err());
49966 - }
49967 -
49968 -+#[test]
49969 -+#[cfg(not(any(
49970 -+ target_os = "macos", target_os = "ios",
49971 -+ target_os = "android", target_os = "redox")))]
49972 -+fn test_mkfifoat_none() {
49973 -+ let _m = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test");
49974 -+
49975 -+ let tempdir = tempdir().unwrap();
49976 -+ let mkfifoat_fifo = tempdir.path().join("mkfifoat_fifo");
49977 -+
49978 -+ mkfifoat(None, &mkfifoat_fifo, Mode::S_IRUSR).unwrap();
49979 -+
49980 -+ let stats = stat::stat(&mkfifoat_fifo).unwrap();
49981 -+ let typ = stat::SFlag::from_bits_truncate(stats.st_mode);
49982 -+ assert_eq!(typ, SFlag::S_IFIFO);
49983 -+}
49984 -+
49985 -+#[test]
49986 -+#[cfg(not(any(
49987 -+ target_os = "macos", target_os = "ios",
49988 -+ target_os = "android", target_os = "redox")))]
49989 -+fn test_mkfifoat() {
49990 -+ let tempdir = tempdir().unwrap();
49991 -+ let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap();
49992 -+ let mkfifoat_name = "mkfifoat_name";
49993 -+
49994 -+ mkfifoat(Some(dirfd), mkfifoat_name, Mode::S_IRUSR).unwrap();
49995 -+
49996 -+ let stats = stat::fstatat(dirfd, mkfifoat_name, fcntl::AtFlags::empty()).unwrap();
49997 -+ let typ = stat::SFlag::from_bits_truncate(stats.st_mode);
49998 -+ assert_eq!(typ, SFlag::S_IFIFO);
49999 -+}
50000 -+
50001 -+#[test]
50002 -+#[cfg(not(any(
50003 -+ target_os = "macos", target_os = "ios",
50004 -+ target_os = "android", target_os = "redox")))]
50005 -+fn test_mkfifoat_directory_none() {
50006 -+ let _m = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test");
50007 -+
50008 -+ // mkfifoat should fail if a directory is given
50009 -+ assert!(!mkfifoat(None, &env::temp_dir(), Mode::S_IRUSR).is_ok());
50010 -+}
50011 -+
50012 -+#[test]
50013 -+#[cfg(not(any(
50014 -+ target_os = "macos", target_os = "ios",
50015 -+ target_os = "android", target_os = "redox")))]
50016 -+fn test_mkfifoat_directory() {
50017 -+ // mkfifoat should fail if a directory is given
50018 -+ let tempdir = tempdir().unwrap();
50019 -+ let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap();
50020 -+ let mkfifoat_dir = "mkfifoat_dir";
50021 -+ stat::mkdirat(dirfd, mkfifoat_dir, Mode::S_IRUSR).unwrap();
50022 -+
50023 -+ assert!(!mkfifoat(Some(dirfd), mkfifoat_dir, Mode::S_IRUSR).is_ok());
50024 -+}
50025 -+
50026 - #[test]
50027 - fn test_getpid() {
50028 - let pid: ::libc::pid_t = getpid().into();
50029 -@@ -107,11 +180,12 @@ fn test_getpid() {
50030 - }
50031 -
50032 - #[test]
50033 -+#[cfg(not(target_os = "redox"))]
50034 - fn test_getsid() {
50035 - let none_sid: ::libc::pid_t = getsid(None).unwrap().into();
50036 - let pid_sid: ::libc::pid_t = getsid(Some(getpid())).unwrap().into();
50037 - assert!(none_sid > 0);
50038 -- assert!(none_sid == pid_sid);
50039 -+ assert_eq!(none_sid, pid_sid);
50040 - }
50041 -
50042 - #[cfg(any(target_os = "linux", target_os = "android"))]
50043 -@@ -127,12 +201,12 @@ mod linux_android {
50044 -
50045 - #[test]
50046 - // `getgroups()` and `setgroups()` do not behave as expected on Apple platforms
50047 --#[cfg(not(any(target_os = "ios", target_os = "macos")))]
50048 -+#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox", target_os = "fuchsia")))]
50049 - fn test_setgroups() {
50050 - // Skip this test when not run as root as `setgroups()` requires root.
50051 - skip_if_not_root!("test_setgroups");
50052 -
50053 -- let _m = ::GROUPS_MTX.lock().expect("Mutex got poisoned by another test");
50054 -+ let _m = crate::GROUPS_MTX.lock().expect("Mutex got poisoned by another test");
50055 -
50056 - // Save the existing groups
50057 - let old_groups = getgroups().unwrap();
50058 -@@ -150,13 +224,13 @@ fn test_setgroups() {
50059 -
50060 - #[test]
50061 - // `getgroups()` and `setgroups()` do not behave as expected on Apple platforms
50062 --#[cfg(not(any(target_os = "ios", target_os = "macos")))]
50063 -+#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox", target_os = "fuchsia")))]
50064 - fn test_initgroups() {
50065 - // Skip this test when not run as root as `initgroups()` and `setgroups()`
50066 - // require root.
50067 - skip_if_not_root!("test_initgroups");
50068 -
50069 -- let _m = ::GROUPS_MTX.lock().expect("Mutex got poisoned by another test");
50070 -+ let _m = crate::GROUPS_MTX.lock().expect("Mutex got poisoned by another test");
50071 -
50072 - // Save the existing groups
50073 - let old_groups = getgroups().unwrap();
50074 -@@ -180,11 +254,53 @@ fn test_initgroups() {
50075 - setgroups(&old_groups).unwrap();
50076 - }
50077 -
50078 -+#[cfg(not(target_os = "redox"))]
50079 - macro_rules! execve_test_factory(
50080 - ($test_name:ident, $syscall:ident, $exe: expr $(, $pathname:expr, $flags:expr)*) => (
50081 -- #[test]
50082 -- fn $test_name() {
50083 -- let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
50084 -+
50085 -+ #[cfg(test)]
50086 -+ mod $test_name {
50087 -+ use std::ffi::CStr;
50088 -+ use super::*;
50089 -+
50090 -+ const EMPTY: &'static [u8] = b"\0";
50091 -+ const DASH_C: &'static [u8] = b"-c\0";
50092 -+ const BIGARG: &'static [u8] = b"echo nix!!! && echo foo=$foo && echo baz=$baz\0";
50093 -+ const FOO: &'static [u8] = b"foo=bar\0";
50094 -+ const BAZ: &'static [u8] = b"baz=quux\0";
50095 -+
50096 -+ fn syscall_cstr_ref() -> Result<std::convert::Infallible, nix::Error> {
50097 -+ $syscall(
50098 -+ $exe,
50099 -+ $(CString::new($pathname).unwrap().as_c_str(), )*
50100 -+ &[CStr::from_bytes_with_nul(EMPTY).unwrap(),
50101 -+ CStr::from_bytes_with_nul(DASH_C).unwrap(),
50102 -+ CStr::from_bytes_with_nul(BIGARG).unwrap()],
50103 -+ &[CStr::from_bytes_with_nul(FOO).unwrap(),
50104 -+ CStr::from_bytes_with_nul(BAZ).unwrap()]
50105 -+ $(, $flags)*)
50106 -+ }
50107 -+
50108 -+ fn syscall_cstring() -> Result<std::convert::Infallible, nix::Error> {
50109 -+ $syscall(
50110 -+ $exe,
50111 -+ $(CString::new($pathname).unwrap().as_c_str(), )*
50112 -+ &[CString::from(CStr::from_bytes_with_nul(EMPTY).unwrap()),
50113 -+ CString::from(CStr::from_bytes_with_nul(DASH_C).unwrap()),
50114 -+ CString::from(CStr::from_bytes_with_nul(BIGARG).unwrap())],
50115 -+ &[CString::from(CStr::from_bytes_with_nul(FOO).unwrap()),
50116 -+ CString::from(CStr::from_bytes_with_nul(BAZ).unwrap())]
50117 -+ $(, $flags)*)
50118 -+ }
50119 -+
50120 -+ fn common_test(syscall: fn() -> Result<std::convert::Infallible, nix::Error>) {
50121 -+ if "execveat" == stringify!($syscall) {
50122 -+ // Though undocumented, Docker's default seccomp profile seems to
50123 -+ // block this syscall. https://github.com/nix-rust/nix/issues/1122
50124 -+ skip_if_seccomp!($test_name);
50125 -+ }
50126 -+
50127 -+ let m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test");
50128 - // The `exec`d process will write to `writer`, and we'll read that
50129 - // data from `reader`.
50130 - let (reader, writer) = pipe().unwrap();
50131 -@@ -192,27 +308,21 @@ macro_rules! execve_test_factory(
50132 - // Safe: Child calls `exit`, `dup`, `close` and the provided `exec*` family function.
50133 - // NOTE: Technically, this makes the macro unsafe to use because you could pass anything.
50134 - // The tests make sure not to do that, though.
50135 -- match fork().unwrap() {
50136 -+ match unsafe{fork()}.unwrap() {
50137 - Child => {
50138 -- // Close stdout.
50139 -- close(1).unwrap();
50140 - // Make `writer` be the stdout of the new process.
50141 -- dup(writer).unwrap();
50142 -- // exec!
50143 -- $syscall(
50144 -- $exe,
50145 -- $(&CString::new($pathname).unwrap(), )*
50146 -- &[CString::new(b"".as_ref()).unwrap(),
50147 -- CString::new(b"-c".as_ref()).unwrap(),
50148 -- CString::new(b"echo nix!!! && echo foo=$foo && echo baz=$baz"
50149 -- .as_ref()).unwrap()],
50150 -- &[CString::new(b"foo=bar".as_ref()).unwrap(),
50151 -- CString::new(b"baz=quux".as_ref()).unwrap()]
50152 -- $(, $flags)*).unwrap();
50153 -+ dup2(writer, 1).unwrap();
50154 -+ let r = syscall();
50155 -+ let _ = std::io::stderr()
50156 -+ .write_all(format!("{:?}", r).as_bytes());
50157 -+ // Should only get here in event of error
50158 -+ unsafe{ _exit(1) };
50159 - },
50160 - Parent { child } => {
50161 - // Wait for the child to exit.
50162 -- waitpid(child, None).unwrap();
50163 -+ let ws = waitpid(child, None);
50164 -+ drop(m);
50165 -+ assert_eq!(ws, Ok(WaitStatus::Exited(child, 0)));
50166 - // Read 1024 bytes.
50167 - let mut buf = [0u8; 1024];
50168 - read(reader, &mut buf).unwrap();
50169 -@@ -224,23 +334,43 @@ macro_rules! execve_test_factory(
50170 - }
50171 - }
50172 - }
50173 -+
50174 -+ // These tests frequently fail on musl, probably due to
50175 -+ // https://github.com/nix-rust/nix/issues/555
50176 -+ #[cfg_attr(target_env = "musl", ignore)]
50177 -+ #[test]
50178 -+ fn test_cstr_ref() {
50179 -+ common_test(syscall_cstr_ref);
50180 -+ }
50181 -+
50182 -+ // These tests frequently fail on musl, probably due to
50183 -+ // https://github.com/nix-rust/nix/issues/555
50184 -+ #[cfg_attr(target_env = "musl", ignore)]
50185 -+ #[test]
50186 -+ fn test_cstring() {
50187 -+ common_test(syscall_cstring);
50188 -+ }
50189 -+ }
50190 -+
50191 - )
50192 - );
50193 -
50194 - cfg_if!{
50195 - if #[cfg(target_os = "android")] {
50196 -- execve_test_factory!(test_execve, execve, &CString::new("/system/bin/sh").unwrap());
50197 -+ execve_test_factory!(test_execve, execve, CString::new("/system/bin/sh").unwrap().as_c_str());
50198 - execve_test_factory!(test_fexecve, fexecve, File::open("/system/bin/sh").unwrap().into_raw_fd());
50199 - } else if #[cfg(any(target_os = "freebsd",
50200 - target_os = "linux"))] {
50201 -- execve_test_factory!(test_execve, execve, &CString::new("/bin/sh").unwrap());
50202 -+ // These tests frequently fail on musl, probably due to
50203 -+ // https://github.com/nix-rust/nix/issues/555
50204 -+ execve_test_factory!(test_execve, execve, CString::new("/bin/sh").unwrap().as_c_str());
50205 - execve_test_factory!(test_fexecve, fexecve, File::open("/bin/sh").unwrap().into_raw_fd());
50206 - } else if #[cfg(any(target_os = "dragonfly",
50207 - target_os = "ios",
50208 - target_os = "macos",
50209 - target_os = "netbsd",
50210 - target_os = "openbsd"))] {
50211 -- execve_test_factory!(test_execve, execve, &CString::new("/bin/sh").unwrap());
50212 -+ execve_test_factory!(test_execve, execve, CString::new("/bin/sh").unwrap().as_c_str());
50213 - // No fexecve() on DragonFly, ios, macos, NetBSD, OpenBSD.
50214 - //
50215 - // Note for NetBSD and OpenBSD: although rust-lang/libc includes it
50216 -@@ -255,13 +385,16 @@ execve_test_factory!(test_execvpe, execvpe, &CString::new("sh").unwrap());
50217 - cfg_if!{
50218 - if #[cfg(target_os = "android")] {
50219 - use nix::fcntl::AtFlags;
50220 -- execve_test_factory!(test_execveat_empty, execveat, File::open("/system/bin/sh").unwrap().into_raw_fd(),
50221 -+ execve_test_factory!(test_execveat_empty, execveat,
50222 -+ File::open("/system/bin/sh").unwrap().into_raw_fd(),
50223 - "", AtFlags::AT_EMPTY_PATH);
50224 -- execve_test_factory!(test_execveat_relative, execveat, File::open("/system/bin/").unwrap().into_raw_fd(),
50225 -+ execve_test_factory!(test_execveat_relative, execveat,
50226 -+ File::open("/system/bin/").unwrap().into_raw_fd(),
50227 - "./sh", AtFlags::empty());
50228 -- execve_test_factory!(test_execveat_absolute, execveat, File::open("/").unwrap().into_raw_fd(),
50229 -+ execve_test_factory!(test_execveat_absolute, execveat,
50230 -+ File::open("/").unwrap().into_raw_fd(),
50231 - "/system/bin/sh", AtFlags::empty());
50232 -- } else if #[cfg(all(target_os = "linux"), any(target_arch ="x86_64", target_arch ="x86"))] {
50233 -+ } else if #[cfg(all(target_os = "linux", any(target_arch ="x86_64", target_arch ="x86")))] {
50234 - use nix::fcntl::AtFlags;
50235 - execve_test_factory!(test_execveat_empty, execveat, File::open("/bin/sh").unwrap().into_raw_fd(),
50236 - "", AtFlags::AT_EMPTY_PATH);
50237 -@@ -273,11 +406,12 @@ cfg_if!{
50238 - }
50239 -
50240 - #[test]
50241 -+#[cfg(not(target_os = "fuchsia"))]
50242 - fn test_fchdir() {
50243 - // fchdir changes the process's cwd
50244 -- let _dr = ::DirRestore::new();
50245 -+ let _dr = crate::DirRestore::new();
50246 -
50247 -- let tmpdir = tempfile::tempdir().unwrap();
50248 -+ let tmpdir = tempdir().unwrap();
50249 - let tmpdir_path = tmpdir.path().canonicalize().unwrap();
50250 - let tmpdir_fd = File::open(&tmpdir_path).unwrap().into_raw_fd();
50251 -
50252 -@@ -290,9 +424,9 @@ fn test_fchdir() {
50253 - #[test]
50254 - fn test_getcwd() {
50255 - // chdir changes the process's cwd
50256 -- let _dr = ::DirRestore::new();
50257 -+ let _dr = crate::DirRestore::new();
50258 -
50259 -- let tmpdir = tempfile::tempdir().unwrap();
50260 -+ let tmpdir = tempdir().unwrap();
50261 - let tmpdir_path = tmpdir.path().canonicalize().unwrap();
50262 - assert!(chdir(&tmpdir_path).is_ok());
50263 - assert_eq!(getcwd().unwrap(), tmpdir_path);
50264 -@@ -317,7 +451,7 @@ fn test_chown() {
50265 - let uid = Some(getuid());
50266 - let gid = Some(getgid());
50267 -
50268 -- let tempdir = tempfile::tempdir().unwrap();
50269 -+ let tempdir = tempdir().unwrap();
50270 - let path = tempdir.path().join("file");
50271 - {
50272 - File::create(&path).unwrap();
50273 -@@ -332,13 +466,29 @@ fn test_chown() {
50274 - }
50275 -
50276 - #[test]
50277 -+fn test_fchown() {
50278 -+ // Testing for anything other than our own UID/GID is hard.
50279 -+ let uid = Some(getuid());
50280 -+ let gid = Some(getgid());
50281 -+
50282 -+ let path = tempfile().unwrap();
50283 -+ let fd = path.as_raw_fd();
50284 -+
50285 -+ fchown(fd, uid, gid).unwrap();
50286 -+ fchown(fd, uid, None).unwrap();
50287 -+ fchown(fd, None, gid).unwrap();
50288 -+ fchown(999999999, uid, gid).unwrap_err();
50289 -+}
50290 -+
50291 -+#[test]
50292 -+#[cfg(not(target_os = "redox"))]
50293 - fn test_fchownat() {
50294 -- let _dr = ::DirRestore::new();
50295 -+ let _dr = crate::DirRestore::new();
50296 - // Testing for anything other than our own UID/GID is hard.
50297 - let uid = Some(getuid());
50298 - let gid = Some(getgid());
50299 -
50300 -- let tempdir = tempfile::tempdir().unwrap();
50301 -+ let tempdir = tempdir().unwrap();
50302 - let path = tempdir.path().join("file");
50303 - {
50304 - File::create(&path).unwrap();
50305 -@@ -366,7 +516,7 @@ fn test_lseek() {
50306 - lseek(tmpfd, offset, Whence::SeekSet).unwrap();
50307 -
50308 - let mut buf = [0u8; 7];
50309 -- ::read_exact(tmpfd, &mut buf);
50310 -+ crate::read_exact(tmpfd, &mut buf);
50311 - assert_eq!(b"f123456", &buf);
50312 -
50313 - close(tmpfd).unwrap();
50314 -@@ -383,7 +533,7 @@ fn test_lseek64() {
50315 - lseek64(tmpfd, 5, Whence::SeekSet).unwrap();
50316 -
50317 - let mut buf = [0u8; 7];
50318 -- ::read_exact(tmpfd, &mut buf);
50319 -+ crate::read_exact(tmpfd, &mut buf);
50320 - assert_eq!(b"f123456", &buf);
50321 -
50322 - close(tmpfd).unwrap();
50323 -@@ -403,7 +553,7 @@ cfg_if!{
50324 - skip_if_jailed!("test_acct");
50325 - }
50326 - }
50327 -- } else {
50328 -+ } else if #[cfg(not(any(target_os = "redox", target_os = "fuchsia")))] {
50329 - macro_rules! require_acct{
50330 - () => {
50331 - skip_if_not_root!("test_acct");
50332 -@@ -413,12 +563,13 @@ cfg_if!{
50333 - }
50334 -
50335 - #[test]
50336 -+#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
50337 - fn test_acct() {
50338 - use tempfile::NamedTempFile;
50339 - use std::process::Command;
50340 - use std::{thread, time};
50341 -
50342 -- let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
50343 -+ let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test");
50344 - require_acct!();
50345 -
50346 - let file = NamedTempFile::new().unwrap();
50347 -@@ -481,6 +632,14 @@ fn test_pipe() {
50348 -
50349 - // pipe2(2) is the same as pipe(2), except it allows setting some flags. Check
50350 - // that we can set a flag.
50351 -+#[cfg(any(target_os = "android",
50352 -+ target_os = "dragonfly",
50353 -+ target_os = "emscripten",
50354 -+ target_os = "freebsd",
50355 -+ target_os = "linux",
50356 -+ target_os = "netbsd",
50357 -+ target_os = "openbsd",
50358 -+ target_os = "redox"))]
50359 - #[test]
50360 - fn test_pipe2() {
50361 - let (fd0, fd1) = pipe2(OFlag::O_CLOEXEC).unwrap();
50362 -@@ -491,8 +650,9 @@ fn test_pipe2() {
50363 - }
50364 -
50365 - #[test]
50366 -+#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
50367 - fn test_truncate() {
50368 -- let tempdir = tempfile::tempdir().unwrap();
50369 -+ let tempdir = tempdir().unwrap();
50370 - let path = tempdir.path().join("file");
50371 -
50372 - {
50373 -@@ -509,7 +669,7 @@ fn test_truncate() {
50374 -
50375 - #[test]
50376 - fn test_ftruncate() {
50377 -- let tempdir = tempfile::tempdir().unwrap();
50378 -+ let tempdir = tempdir().unwrap();
50379 - let path = tempdir.path().join("file");
50380 -
50381 - let tmpfd = {
50382 -@@ -527,17 +687,26 @@ fn test_ftruncate() {
50383 - }
50384 -
50385 - // Used in `test_alarm`.
50386 -+#[cfg(not(target_os = "redox"))]
50387 - static mut ALARM_CALLED: bool = false;
50388 -
50389 - // Used in `test_alarm`.
50390 -+#[cfg(not(target_os = "redox"))]
50391 - pub extern fn alarm_signal_handler(raw_signal: libc::c_int) {
50392 - assert_eq!(raw_signal, libc::SIGALRM, "unexpected signal: {}", raw_signal);
50393 - unsafe { ALARM_CALLED = true };
50394 - }
50395 -
50396 - #[test]
50397 -+#[cfg(not(target_os = "redox"))]
50398 - fn test_alarm() {
50399 -- let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
50400 -+ use std::{
50401 -+ time::{Duration, Instant,},
50402 -+ thread
50403 -+ };
50404 -+
50405 -+ // Maybe other tests that fork interfere with this one?
50406 -+ let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
50407 -
50408 - let handler = SigHandler::Handler(alarm_signal_handler);
50409 - let signal_action = SigAction::new(handler, SaFlags::SA_RESTART, SigSet::empty());
50410 -@@ -554,8 +723,16 @@ fn test_alarm() {
50411 -
50412 - // We should be woken up after 1 second by the alarm, so we'll sleep for 2
50413 - // seconds to be sure.
50414 -- sleep(2);
50415 -- assert_eq!(unsafe { ALARM_CALLED }, true, "expected our alarm signal handler to be called");
50416 -+ let starttime = Instant::now();
50417 -+ loop {
50418 -+ thread::sleep(Duration::from_millis(100));
50419 -+ if unsafe { ALARM_CALLED} {
50420 -+ break;
50421 -+ }
50422 -+ if starttime.elapsed() > Duration::from_secs(3) {
50423 -+ panic!("Timeout waiting for SIGALRM");
50424 -+ }
50425 -+ }
50426 -
50427 - // Reset the signal.
50428 - unsafe {
50429 -@@ -565,8 +742,9 @@ fn test_alarm() {
50430 - }
50431 -
50432 - #[test]
50433 -+#[cfg(not(target_os = "redox"))]
50434 - fn test_canceling_alarm() {
50435 -- let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
50436 -+ let _m = crate::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test");
50437 -
50438 - assert_eq!(alarm::cancel(), None);
50439 -
50440 -@@ -575,15 +753,17 @@ fn test_canceling_alarm() {
50441 - }
50442 -
50443 - #[test]
50444 -+#[cfg(not(target_os = "redox"))]
50445 - fn test_symlinkat() {
50446 -- let mut buf = [0; 1024];
50447 -- let tempdir = tempfile::tempdir().unwrap();
50448 -+ let _m = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test");
50449 -+
50450 -+ let tempdir = tempdir().unwrap();
50451 -
50452 - let target = tempdir.path().join("a");
50453 - let linkpath = tempdir.path().join("b");
50454 - symlinkat(&target, None, &linkpath).unwrap();
50455 - assert_eq!(
50456 -- readlink(&linkpath, &mut buf).unwrap().to_str().unwrap(),
50457 -+ readlink(&linkpath).unwrap().to_str().unwrap(),
50458 - target.to_str().unwrap()
50459 - );
50460 -
50461 -@@ -592,7 +772,7 @@ fn test_symlinkat() {
50462 - let linkpath = "d";
50463 - symlinkat(target, Some(dirfd), linkpath).unwrap();
50464 - assert_eq!(
50465 -- readlink(&tempdir.path().join(linkpath), &mut buf)
50466 -+ readlink(&tempdir.path().join(linkpath))
50467 - .unwrap()
50468 - .to_str()
50469 - .unwrap(),
50470 -@@ -600,10 +780,154 @@ fn test_symlinkat() {
50471 - );
50472 - }
50473 -
50474 -+#[test]
50475 -+#[cfg(not(target_os = "redox"))]
50476 -+fn test_linkat_file() {
50477 -+ let tempdir = tempdir().unwrap();
50478 -+ let oldfilename = "foo.txt";
50479 -+ let oldfilepath = tempdir.path().join(oldfilename);
50480 -+
50481 -+ let newfilename = "bar.txt";
50482 -+ let newfilepath = tempdir.path().join(newfilename);
50483 -+
50484 -+ // Create file
50485 -+ File::create(&oldfilepath).unwrap();
50486 -+
50487 -+ // Get file descriptor for base directory
50488 -+ let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap();
50489 -+
50490 -+ // Attempt hard link file at relative path
50491 -+ linkat(Some(dirfd), oldfilename, Some(dirfd), newfilename, LinkatFlags::SymlinkFollow).unwrap();
50492 -+ assert!(newfilepath.exists());
50493 -+}
50494 -+
50495 -+#[test]
50496 -+#[cfg(not(target_os = "redox"))]
50497 -+fn test_linkat_olddirfd_none() {
50498 -+ let _dr = crate::DirRestore::new();
50499 -+
50500 -+ let tempdir_oldfile = tempdir().unwrap();
50501 -+ let oldfilename = "foo.txt";
50502 -+ let oldfilepath = tempdir_oldfile.path().join(oldfilename);
50503 -+
50504 -+ let tempdir_newfile = tempdir().unwrap();
50505 -+ let newfilename = "bar.txt";
50506 -+ let newfilepath = tempdir_newfile.path().join(newfilename);
50507 -+
50508 -+ // Create file
50509 -+ File::create(&oldfilepath).unwrap();
50510 -+
50511 -+ // Get file descriptor for base directory of new file
50512 -+ let dirfd = fcntl::open(tempdir_newfile.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap();
50513 -+
50514 -+ // Attempt hard link file using curent working directory as relative path for old file path
50515 -+ chdir(tempdir_oldfile.path()).unwrap();
50516 -+ linkat(None, oldfilename, Some(dirfd), newfilename, LinkatFlags::SymlinkFollow).unwrap();
50517 -+ assert!(newfilepath.exists());
50518 -+}
50519 -+
50520 -+#[test]
50521 -+#[cfg(not(target_os = "redox"))]
50522 -+fn test_linkat_newdirfd_none() {
50523 -+ let _dr = crate::DirRestore::new();
50524 -+
50525 -+ let tempdir_oldfile = tempdir().unwrap();
50526 -+ let oldfilename = "foo.txt";
50527 -+ let oldfilepath = tempdir_oldfile.path().join(oldfilename);
50528 -+
50529 -+ let tempdir_newfile = tempdir().unwrap();
50530 -+ let newfilename = "bar.txt";
50531 -+ let newfilepath = tempdir_newfile.path().join(newfilename);
50532 -+
50533 -+ // Create file
50534 -+ File::create(&oldfilepath).unwrap();
50535 -+
50536 -+ // Get file descriptor for base directory of old file
50537 -+ let dirfd = fcntl::open(tempdir_oldfile.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap();
50538 -+
50539 -+ // Attempt hard link file using current working directory as relative path for new file path
50540 -+ chdir(tempdir_newfile.path()).unwrap();
50541 -+ linkat(Some(dirfd), oldfilename, None, newfilename, LinkatFlags::SymlinkFollow).unwrap();
50542 -+ assert!(newfilepath.exists());
50543 -+}
50544 -+
50545 -+#[test]
50546 -+#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))]
50547 -+fn test_linkat_no_follow_symlink() {
50548 -+ let _m = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test");
50549 -+
50550 -+ let tempdir = tempdir().unwrap();
50551 -+ let oldfilename = "foo.txt";
50552 -+ let oldfilepath = tempdir.path().join(oldfilename);
50553 -+
50554 -+ let symoldfilename = "symfoo.txt";
50555 -+ let symoldfilepath = tempdir.path().join(symoldfilename);
50556 -+
50557 -+ let newfilename = "nofollowsymbar.txt";
50558 -+ let newfilepath = tempdir.path().join(newfilename);
50559 -+
50560 -+ // Create file
50561 -+ File::create(&oldfilepath).unwrap();
50562 -+
50563 -+ // Create symlink to file
50564 -+ symlinkat(&oldfilepath, None, &symoldfilepath).unwrap();
50565 -+
50566 -+ // Get file descriptor for base directory
50567 -+ let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap();
50568 -+
50569 -+ // Attempt link symlink of file at relative path
50570 -+ linkat(Some(dirfd), symoldfilename, Some(dirfd), newfilename, LinkatFlags::NoSymlinkFollow).unwrap();
50571 -+
50572 -+ // Assert newfile is actually a symlink to oldfile.
50573 -+ assert_eq!(
50574 -+ readlink(&newfilepath)
50575 -+ .unwrap()
50576 -+ .to_str()
50577 -+ .unwrap(),
50578 -+ oldfilepath.to_str().unwrap()
50579 -+ );
50580 -+}
50581 -+
50582 -+#[test]
50583 -+#[cfg(not(target_os = "redox"))]
50584 -+fn test_linkat_follow_symlink() {
50585 -+ let _m = crate::CWD_LOCK.read().expect("Mutex got poisoned by another test");
50586 -+
50587 -+ let tempdir = tempdir().unwrap();
50588 -+ let oldfilename = "foo.txt";
50589 -+ let oldfilepath = tempdir.path().join(oldfilename);
50590 -+
50591 -+ let symoldfilename = "symfoo.txt";
50592 -+ let symoldfilepath = tempdir.path().join(symoldfilename);
50593 -+
50594 -+ let newfilename = "nofollowsymbar.txt";
50595 -+ let newfilepath = tempdir.path().join(newfilename);
50596 -+
50597 -+ // Create file
50598 -+ File::create(&oldfilepath).unwrap();
50599 -+
50600 -+ // Create symlink to file
50601 -+ symlinkat(&oldfilepath, None, &symoldfilepath).unwrap();
50602 -+
50603 -+ // Get file descriptor for base directory
50604 -+ let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap();
50605 -+
50606 -+ // Attempt link target of symlink of file at relative path
50607 -+ linkat(Some(dirfd), symoldfilename, Some(dirfd), newfilename, LinkatFlags::SymlinkFollow).unwrap();
50608 -+
50609 -+ let newfilestat = stat::stat(&newfilepath).unwrap();
50610 -+
50611 -+ // Check the file type of the new link
50612 -+ assert!((stat::SFlag::from_bits_truncate(newfilestat.st_mode) & SFlag::S_IFMT) == SFlag::S_IFREG);
50613 -+
50614 -+ // Check the number of hard links to the original file
50615 -+ assert_eq!(newfilestat.st_nlink, 2);
50616 -+}
50617 -
50618 - #[test]
50619 -+#[cfg(not(target_os = "redox"))]
50620 - fn test_unlinkat_dir_noremovedir() {
50621 -- let tempdir = tempfile::tempdir().unwrap();
50622 -+ let tempdir = tempdir().unwrap();
50623 - let dirname = "foo_dir";
50624 - let dirpath = tempdir.path().join(dirname);
50625 -
50626 -@@ -619,8 +943,9 @@ fn test_unlinkat_dir_noremovedir() {
50627 - }
50628 -
50629 - #[test]
50630 -+#[cfg(not(target_os = "redox"))]
50631 - fn test_unlinkat_dir_removedir() {
50632 -- let tempdir = tempfile::tempdir().unwrap();
50633 -+ let tempdir = tempdir().unwrap();
50634 - let dirname = "foo_dir";
50635 - let dirpath = tempdir.path().join(dirname);
50636 -
50637 -@@ -636,8 +961,9 @@ fn test_unlinkat_dir_removedir() {
50638 - }
50639 -
50640 - #[test]
50641 -+#[cfg(not(target_os = "redox"))]
50642 - fn test_unlinkat_file() {
50643 -- let tempdir = tempfile::tempdir().unwrap();
50644 -+ let tempdir = tempdir().unwrap();
50645 - let filename = "foo.txt";
50646 - let filepath = tempdir.path().join(filename);
50647 -
50648 -@@ -654,7 +980,7 @@ fn test_unlinkat_file() {
50649 -
50650 - #[test]
50651 - fn test_access_not_existing() {
50652 -- let tempdir = tempfile::tempdir().unwrap();
50653 -+ let tempdir = tempdir().unwrap();
50654 - let dir = tempdir.path().join("does_not_exist.txt");
50655 - assert_eq!(access(&dir, AccessFlags::F_OK).err().unwrap().as_errno().unwrap(),
50656 - Errno::ENOENT);
50657 -@@ -662,8 +988,123 @@ fn test_access_not_existing() {
50658 -
50659 - #[test]
50660 - fn test_access_file_exists() {
50661 -- let tempdir = tempfile::tempdir().unwrap();
50662 -+ let tempdir = tempdir().unwrap();
50663 - let path = tempdir.path().join("does_exist.txt");
50664 - let _file = File::create(path.clone()).unwrap();
50665 - assert!(access(&path, AccessFlags::R_OK | AccessFlags::W_OK).is_ok());
50666 - }
50667 -+
50668 -+/// Tests setting the filesystem UID with `setfsuid`.
50669 -+#[cfg(any(target_os = "linux", target_os = "android"))]
50670 -+#[test]
50671 -+fn test_setfsuid() {
50672 -+ use std::os::unix::fs::PermissionsExt;
50673 -+ use std::{fs, io, thread};
50674 -+ require_capability!(CAP_SETUID);
50675 -+
50676 -+ // get the UID of the "nobody" user
50677 -+ let nobody = User::from_name("nobody").unwrap().unwrap();
50678 -+
50679 -+ // create a temporary file with permissions '-rw-r-----'
50680 -+ let file = tempfile::NamedTempFile::new_in("/var/tmp").unwrap();
50681 -+ let temp_path = file.into_temp_path();
50682 -+ dbg!(&temp_path);
50683 -+ let temp_path_2 = (&temp_path).to_path_buf();
50684 -+ let mut permissions = fs::metadata(&temp_path).unwrap().permissions();
50685 -+ permissions.set_mode(640);
50686 -+
50687 -+ // spawn a new thread where to test setfsuid
50688 -+ thread::spawn(move || {
50689 -+ // set filesystem UID
50690 -+ let fuid = setfsuid(nobody.uid);
50691 -+ // trying to open the temporary file should fail with EACCES
50692 -+ let res = fs::File::open(&temp_path);
50693 -+ assert!(res.is_err());
50694 -+ assert_eq!(res.err().unwrap().kind(), io::ErrorKind::PermissionDenied);
50695 -+
50696 -+ // assert fuid actually changes
50697 -+ let prev_fuid = setfsuid(Uid::from_raw(-1i32 as u32));
50698 -+ assert_ne!(prev_fuid, fuid);
50699 -+ })
50700 -+ .join()
50701 -+ .unwrap();
50702 -+
50703 -+ // open the temporary file with the current thread filesystem UID
50704 -+ fs::File::open(temp_path_2).unwrap();
50705 -+}
50706 -+
50707 -+#[test]
50708 -+#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
50709 -+fn test_ttyname() {
50710 -+ let fd = posix_openpt(OFlag::O_RDWR).expect("posix_openpt failed");
50711 -+ assert!(fd.as_raw_fd() > 0);
50712 -+
50713 -+ // on linux, we can just call ttyname on the pty master directly, but
50714 -+ // apparently osx requires that ttyname is called on a slave pty (can't
50715 -+ // find this documented anywhere, but it seems to empirically be the case)
50716 -+ grantpt(&fd).expect("grantpt failed");
50717 -+ unlockpt(&fd).expect("unlockpt failed");
50718 -+ let sname = unsafe { ptsname(&fd) }.expect("ptsname failed");
50719 -+ let fds = open(
50720 -+ Path::new(&sname),
50721 -+ OFlag::O_RDWR,
50722 -+ stat::Mode::empty(),
50723 -+ ).expect("open failed");
50724 -+ assert!(fds > 0);
50725 -+
50726 -+ let name = ttyname(fds).expect("ttyname failed");
50727 -+ assert!(name.starts_with("/dev"));
50728 -+}
50729 -+
50730 -+#[test]
50731 -+#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
50732 -+fn test_ttyname_not_pty() {
50733 -+ let fd = File::open("/dev/zero").unwrap();
50734 -+ assert!(fd.as_raw_fd() > 0);
50735 -+ assert_eq!(ttyname(fd.as_raw_fd()), Err(Error::Sys(Errno::ENOTTY)));
50736 -+}
50737 -+
50738 -+#[test]
50739 -+#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
50740 -+fn test_ttyname_invalid_fd() {
50741 -+ assert_eq!(ttyname(-1), Err(Error::Sys(Errno::EBADF)));
50742 -+}
50743 -+
50744 -+#[test]
50745 -+#[cfg(any(
50746 -+ target_os = "macos",
50747 -+ target_os = "ios",
50748 -+ target_os = "freebsd",
50749 -+ target_os = "openbsd",
50750 -+ target_os = "netbsd",
50751 -+ target_os = "dragonfly",
50752 -+))]
50753 -+fn test_getpeereid() {
50754 -+ use std::os::unix::net::UnixStream;
50755 -+ let (sock_a, sock_b) = UnixStream::pair().unwrap();
50756 -+
50757 -+ let (uid_a, gid_a) = getpeereid(sock_a.as_raw_fd()).unwrap();
50758 -+ let (uid_b, gid_b) = getpeereid(sock_b.as_raw_fd()).unwrap();
50759 -+
50760 -+ let uid = geteuid();
50761 -+ let gid = getegid();
50762 -+
50763 -+ assert_eq!(uid, uid_a);
50764 -+ assert_eq!(gid, gid_a);
50765 -+ assert_eq!(uid_a, uid_b);
50766 -+ assert_eq!(gid_a, gid_b);
50767 -+}
50768 -+
50769 -+#[test]
50770 -+#[cfg(any(
50771 -+ target_os = "macos",
50772 -+ target_os = "ios",
50773 -+ target_os = "freebsd",
50774 -+ target_os = "openbsd",
50775 -+ target_os = "netbsd",
50776 -+ target_os = "dragonfly",
50777 -+))]
50778 -+fn test_getpeereid_invalid_fd() {
50779 -+ // getpeereid is not POSIX, so error codes are inconsistent between different Unices.
50780 -+ assert!(getpeereid(-1).is_err());
50781 -+}
50782
50783 diff --git a/www-client/firefox/firefox-103.0.1.ebuild b/www-client/firefox/firefox-103.0.1.ebuild
50784 new file mode 100644
50785 index 0000000..d0494bb
50786 --- /dev/null
50787 +++ b/www-client/firefox/firefox-103.0.1.ebuild
50788 @@ -0,0 +1,1301 @@
50789 +# Copyright 1999-2022 Gentoo Authors
50790 +# Distributed under the terms of the GNU General Public License v2
50791 +
50792 +EAPI="8"
50793 +
50794 +FIREFOX_PATCHSET="firefox-103-patches-03j.tar.xz"
50795 +
50796 +LLVM_MAX_SLOT=14
50797 +
50798 +PYTHON_COMPAT=( python3_{8..11} )
50799 +PYTHON_REQ_USE="ncurses,sqlite,ssl"
50800 +
50801 +WANT_AUTOCONF="2.1"
50802 +
50803 +VIRTUALX_REQUIRED="pgo"
50804 +
50805 +MOZ_ESR=
50806 +
50807 +MOZ_PV=${PV}
50808 +MOZ_PV_SUFFIX=
50809 +if [[ ${PV} =~ (_(alpha|beta|rc).*)$ ]] ; then
50810 + MOZ_PV_SUFFIX=${BASH_REMATCH[1]}
50811 +
50812 + # Convert the ebuild version to the upstream Mozilla version
50813 + MOZ_PV="${MOZ_PV/_alpha/a}" # Handle alpha for SRC_URI
50814 + MOZ_PV="${MOZ_PV/_beta/b}" # Handle beta for SRC_URI
50815 + MOZ_PV="${MOZ_PV%%_rc*}" # Handle rc for SRC_URI
50816 +fi
50817 +
50818 +if [[ -n ${MOZ_ESR} ]] ; then
50819 + # ESR releases have slightly different version numbers
50820 + MOZ_PV="${MOZ_PV}esr"
50821 +fi
50822 +
50823 +MOZ_PN="${PN%-bin}"
50824 +MOZ_P="${MOZ_PN}-${MOZ_PV}"
50825 +MOZ_PV_DISTFILES="${MOZ_PV}${MOZ_PV_SUFFIX}"
50826 +MOZ_P_DISTFILES="${MOZ_PN}-${MOZ_PV_DISTFILES}"
50827 +
50828 +inherit autotools check-reqs desktop flag-o-matic gnome2-utils linux-info \
50829 + llvm multiprocessing pax-utils python-any-r1 toolchain-funcs \
50830 + virtualx xdg
50831 +
50832 +MOZ_SRC_BASE_URI="https://archive.mozilla.org/pub/${MOZ_PN}/releases/${MOZ_PV}"
50833 +
50834 +if [[ ${PV} == *_rc* ]] ; then
50835 + MOZ_SRC_BASE_URI="https://archive.mozilla.org/pub/${MOZ_PN}/candidates/${MOZ_PV}-candidates/build${PV##*_rc}"
50836 +fi
50837 +
50838 +PATCH_URIS=(
50839 + https://dev.gentoo.org/~{juippis,whissi,slashbeast}/mozilla/patchsets/${FIREFOX_PATCHSET}
50840 +)
50841 +
50842 +SRC_URI="${MOZ_SRC_BASE_URI}/source/${MOZ_P}.source.tar.xz -> ${MOZ_P_DISTFILES}.source.tar.xz
50843 + ${PATCH_URIS[@]}"
50844 +
50845 +DESCRIPTION="Firefox Web Browser"
50846 +HOMEPAGE="https://www.mozilla.com/firefox"
50847 +
50848 +KEYWORDS="~amd64 ~arm64 ~ppc64 ~riscv ~x86"
50849 +
50850 +SLOT="rapid"
50851 +LICENSE="MPL-2.0 GPL-2 LGPL-2.1"
50852 +
50853 +# make clang non-default for now, as lld's relocation relax support is comming in llvm 15 release
50854 +# https://reviews.llvm.org/D127611
50855 +IUSE="clang cpu_flags_arm_neon dbus debug eme-free hardened hwaccel"
50856 +IUSE+=" jack libproxy lto +openh264 pgo pulseaudio sndio selinux"
50857 +IUSE+=" +system-av1 +system-harfbuzz +system-icu +system-jpeg +system-libevent +system-libvpx system-png system-python-libs +system-webp"
50858 +IUSE+=" wayland wifi"
50859 +
50860 +# Firefox-only IUSE
50861 +IUSE+=" geckodriver +gmp-autoupdate screencast +X"
50862 +
50863 +REQUIRED_USE="debug? ( !system-av1 )
50864 + pgo? ( lto )
50865 + wifi? ( dbus )"
50866 +
50867 +# Firefox-only REQUIRED_USE flags
50868 +REQUIRED_USE+=" || ( X wayland )"
50869 +REQUIRED_USE+=" pgo? ( X )"
50870 +REQUIRED_USE+=" screencast? ( wayland )"
50871 +
50872 +BDEPEND="${PYTHON_DEPS}
50873 + app-arch/unzip
50874 + app-arch/zip
50875 + >=dev-util/cbindgen-0.24.3
50876 + net-libs/nodejs
50877 + virtual/pkgconfig
50878 + virtual/rust
50879 + || (
50880 + (
50881 + sys-devel/clang:14
50882 + sys-devel/llvm:14
50883 + clang? (
50884 + =sys-devel/lld-14*
50885 + pgo? ( =sys-libs/compiler-rt-sanitizers-14*[profile] )
50886 + )
50887 + )
50888 + (
50889 + sys-devel/clang:13
50890 + sys-devel/llvm:13
50891 + clang? (
50892 + =sys-devel/lld-13*
50893 + pgo? ( =sys-libs/compiler-rt-sanitizers-13*[profile] )
50894 + )
50895 + )
50896 + )
50897 + amd64? ( >=dev-lang/nasm-2.14 )
50898 + x86? ( >=dev-lang/nasm-2.14 )"
50899 +
50900 +COMMON_DEPEND="
50901 + dev-libs/atk
50902 + dev-libs/expat
50903 + dev-libs/glib:2
50904 + dev-libs/libffi:=
50905 + >=dev-libs/nss-3.80
50906 + >=dev-libs/nspr-4.34
50907 + media-libs/alsa-lib
50908 + media-libs/fontconfig
50909 + media-libs/freetype
50910 + media-libs/mesa
50911 + media-video/ffmpeg
50912 + sys-libs/zlib
50913 + virtual/freedesktop-icon-theme
50914 + x11-libs/cairo
50915 + x11-libs/gdk-pixbuf
50916 + x11-libs/pango
50917 + x11-libs/pixman
50918 + dbus? (
50919 + dev-libs/dbus-glib
50920 + sys-apps/dbus
50921 + )
50922 + jack? ( virtual/jack )
50923 + libproxy? ( net-libs/libproxy )
50924 + selinux? ( sec-policy/selinux-mozilla )
50925 + sndio? ( >=media-sound/sndio-1.8.0-r1 )
50926 + screencast? ( media-video/pipewire:= )
50927 + system-av1? (
50928 + >=media-libs/dav1d-0.9.3:=
50929 + >=media-libs/libaom-1.0.0:=
50930 + )
50931 + system-harfbuzz? (
50932 + >=media-gfx/graphite2-1.3.13
50933 + >=media-libs/harfbuzz-2.8.1:0=
50934 + )
50935 + system-icu? ( >=dev-libs/icu-71.1:= )
50936 + system-jpeg? ( >=media-libs/libjpeg-turbo-1.2.1 )
50937 + system-libevent? ( >=dev-libs/libevent-2.0:0=[threads] )
50938 + system-libvpx? ( >=media-libs/libvpx-1.8.2:0=[postproc] )
50939 + system-png? ( >=media-libs/libpng-1.6.35:0=[apng] )
50940 + system-webp? ( >=media-libs/libwebp-1.1.0:0= )
50941 + wayland? (
50942 + >=media-libs/libepoxy-1.5.10-r1
50943 + x11-libs/gtk+:3[wayland]
50944 + x11-libs/libdrm
50945 + x11-libs/libxkbcommon[wayland]
50946 + )
50947 + wifi? (
50948 + kernel_linux? (
50949 + dev-libs/dbus-glib
50950 + net-misc/networkmanager
50951 + sys-apps/dbus
50952 + )
50953 + )
50954 + X? (
50955 + virtual/opengl
50956 + x11-libs/cairo[X]
50957 + x11-libs/gtk+:3[X]
50958 + x11-libs/libX11
50959 + x11-libs/libXcomposite
50960 + x11-libs/libXdamage
50961 + x11-libs/libXext
50962 + x11-libs/libXfixes
50963 + x11-libs/libxkbcommon[X]
50964 + x11-libs/libXrandr
50965 + x11-libs/libXtst
50966 + x11-libs/libxcb:=
50967 + )"
50968 +
50969 +RDEPEND="${COMMON_DEPEND}
50970 + !www-client/firefox:0
50971 + !www-client/firefox:esr
50972 + jack? ( virtual/jack )
50973 + openh264? ( media-libs/openh264:*[plugin] )
50974 + pulseaudio? (
50975 + || (
50976 + media-sound/pulseaudio
50977 + >=media-sound/apulse-0.1.12-r4
50978 + )
50979 + )
50980 + selinux? ( sec-policy/selinux-mozilla )"
50981 +
50982 +DEPEND="${COMMON_DEPEND}
50983 + pulseaudio? (
50984 + || (
50985 + media-sound/pulseaudio
50986 + >=media-sound/apulse-0.1.12-r4[sdk]
50987 + )
50988 + )
50989 + X? (
50990 + x11-libs/libICE
50991 + x11-libs/libSM
50992 + )"
50993 +
50994 +S="${WORKDIR}/${PN}-${PV%_*}"
50995 +RESTRICT=network-sandbox
50996 +
50997 +# Allow MOZ_GMP_PLUGIN_LIST to be set in an eclass or
50998 +# overridden in the enviromnent (advanced hackers only)
50999 +if [[ -z "${MOZ_GMP_PLUGIN_LIST+set}" ]] ; then
51000 + MOZ_GMP_PLUGIN_LIST=( gmp-gmpopenh264 gmp-widevinecdm )
51001 +fi
51002 +
51003 +llvm_check_deps() {
51004 + if ! has_version -b "sys-devel/clang:${LLVM_SLOT}" ; then
51005 + einfo "sys-devel/clang:${LLVM_SLOT} is missing! Cannot use LLVM slot ${LLVM_SLOT} ..." >&2
51006 + return 1
51007 + fi
51008 +
51009 + if use clang ; then
51010 + if ! has_version -b "=sys-devel/lld-${LLVM_SLOT}*" ; then
51011 + einfo "=sys-devel/lld-${LLVM_SLOT}* is missing! Cannot use LLVM slot ${LLVM_SLOT} ..." >&2
51012 + return 1
51013 + fi
51014 +
51015 + if use pgo ; then
51016 + if ! has_version -b "=sys-libs/compiler-rt-sanitizers-${LLVM_SLOT}*" ; then
51017 + einfo "=sys-libs/compiler-rt-sanitizers-${LLVM_SLOT}* is missing! Cannot use LLVM slot ${LLVM_SLOT} ..." >&2
51018 + return 1
51019 + fi
51020 + fi
51021 + fi
51022 +
51023 + einfo "Using LLVM slot ${LLVM_SLOT} to build" >&2
51024 +}
51025 +
51026 +MOZ_LANGS=(
51027 + af ar ast be bg br ca cak cs cy da de dsb
51028 + el en-CA en-GB en-US es-AR es-ES et eu
51029 + fi fr fy-NL ga-IE gd gl he hr hsb hu
51030 + id is it ja ka kab kk ko lt lv ms nb-NO nl nn-NO
51031 + pa-IN pl pt-BR pt-PT rm ro ru
51032 + sk sl sq sr sv-SE th tr uk uz vi zh-CN zh-TW
51033 +)
51034 +
51035 +# Firefox-only LANGS
51036 +MOZ_LANGS+=( ach )
51037 +MOZ_LANGS+=( an )
51038 +MOZ_LANGS+=( az )
51039 +MOZ_LANGS+=( bn )
51040 +MOZ_LANGS+=( bs )
51041 +MOZ_LANGS+=( ca-valencia )
51042 +MOZ_LANGS+=( eo )
51043 +MOZ_LANGS+=( es-CL )
51044 +MOZ_LANGS+=( es-MX )
51045 +MOZ_LANGS+=( fa )
51046 +MOZ_LANGS+=( ff )
51047 +MOZ_LANGS+=( gn )
51048 +MOZ_LANGS+=( gu-IN )
51049 +MOZ_LANGS+=( hi-IN )
51050 +MOZ_LANGS+=( hy-AM )
51051 +MOZ_LANGS+=( ia )
51052 +MOZ_LANGS+=( km )
51053 +MOZ_LANGS+=( kn )
51054 +MOZ_LANGS+=( lij )
51055 +MOZ_LANGS+=( mk )
51056 +MOZ_LANGS+=( mr )
51057 +MOZ_LANGS+=( my )
51058 +MOZ_LANGS+=( ne-NP )
51059 +MOZ_LANGS+=( oc )
51060 +MOZ_LANGS+=( sco )
51061 +MOZ_LANGS+=( si )
51062 +MOZ_LANGS+=( son )
51063 +MOZ_LANGS+=( szl )
51064 +MOZ_LANGS+=( ta )
51065 +MOZ_LANGS+=( te )
51066 +MOZ_LANGS+=( tl )
51067 +MOZ_LANGS+=( trs )
51068 +MOZ_LANGS+=( ur )
51069 +MOZ_LANGS+=( xh )
51070 +
51071 +mozilla_set_globals() {
51072 + # https://bugs.gentoo.org/587334
51073 + local MOZ_TOO_REGIONALIZED_FOR_L10N=(
51074 + fy-NL ga-IE gu-IN hi-IN hy-AM nb-NO ne-NP nn-NO pa-IN sv-SE
51075 + )
51076 +
51077 + local lang xflag
51078 + for lang in "${MOZ_LANGS[@]}" ; do
51079 + # en and en_US are handled internally
51080 + if [[ ${lang} == en ]] || [[ ${lang} == en-US ]] ; then
51081 + continue
51082 + fi
51083 +
51084 + # strip region subtag if $lang is in the list
51085 + if has ${lang} "${MOZ_TOO_REGIONALIZED_FOR_L10N[@]}" ; then
51086 + xflag=${lang%%-*}
51087 + else
51088 + xflag=${lang}
51089 + fi
51090 +
51091 + SRC_URI+=" l10n_${xflag/[_@]/-}? ("
51092 + SRC_URI+=" ${MOZ_SRC_BASE_URI}/linux-x86_64/xpi/${lang}.xpi -> ${MOZ_P_DISTFILES}-${lang}.xpi"
51093 + SRC_URI+=" )"
51094 + IUSE+=" l10n_${xflag/[_@]/-}"
51095 + done
51096 +}
51097 +mozilla_set_globals
51098 +
51099 +moz_clear_vendor_checksums() {
51100 + debug-print-function ${FUNCNAME} "$@"
51101 +
51102 + if [[ ${#} -ne 1 ]] ; then
51103 + die "${FUNCNAME} requires exact one argument"
51104 + fi
51105 +
51106 + einfo "Clearing cargo checksums for ${1} ..."
51107 +
51108 + sed -i \
51109 + -e 's/\("files":{\)[^}]*/\1/' \
51110 + "${S}"/third_party/rust/${1}/.cargo-checksum.json \
51111 + || die
51112 +}
51113 +
51114 +moz_install_xpi() {
51115 + debug-print-function ${FUNCNAME} "$@"
51116 +
51117 + if [[ ${#} -lt 2 ]] ; then
51118 + die "${FUNCNAME} requires at least two arguments"
51119 + fi
51120 +
51121 + local DESTDIR=${1}
51122 + shift
51123 +
51124 + insinto "${DESTDIR}"
51125 +
51126 + local emid xpi_file xpi_tmp_dir
51127 + for xpi_file in "${@}" ; do
51128 + emid=
51129 + xpi_tmp_dir=$(mktemp -d --tmpdir="${T}")
51130 +
51131 + # Unpack XPI
51132 + unzip -qq "${xpi_file}" -d "${xpi_tmp_dir}" || die
51133 +
51134 + # Determine extension ID
51135 + if [[ -f "${xpi_tmp_dir}/install.rdf" ]] ; then
51136 + emid=$(sed -n -e '/install-manifest/,$ { /em:id/!d; s/.*[\">]\([^\"<>]*\)[\"<].*/\1/; p; q }' "${xpi_tmp_dir}/install.rdf")
51137 + [[ -z "${emid}" ]] && die "failed to determine extension id from install.rdf"
51138 + elif [[ -f "${xpi_tmp_dir}/manifest.json" ]] ; then
51139 + emid=$(sed -n -e 's/.*"id": "\([^"]*\)".*/\1/p' "${xpi_tmp_dir}/manifest.json")
51140 + [[ -z "${emid}" ]] && die "failed to determine extension id from manifest.json"
51141 + else
51142 + die "failed to determine extension id"
51143 + fi
51144 +
51145 + einfo "Installing ${emid}.xpi into ${ED}${DESTDIR} ..."
51146 + newins "${xpi_file}" "${emid}.xpi"
51147 + done
51148 +}
51149 +
51150 +mozconfig_add_options_ac() {
51151 + debug-print-function ${FUNCNAME} "$@"
51152 +
51153 + if [[ ${#} -lt 2 ]] ; then
51154 + die "${FUNCNAME} requires at least two arguments"
51155 + fi
51156 +
51157 + local reason=${1}
51158 + shift
51159 +
51160 + local option
51161 + for option in ${@} ; do
51162 + echo "ac_add_options ${option} # ${reason}" >>${MOZCONFIG}
51163 + done
51164 +}
51165 +
51166 +mozconfig_add_options_mk() {
51167 + debug-print-function ${FUNCNAME} "$@"
51168 +
51169 + if [[ ${#} -lt 2 ]] ; then
51170 + die "${FUNCNAME} requires at least two arguments"
51171 + fi
51172 +
51173 + local reason=${1}
51174 + shift
51175 +
51176 + local option
51177 + for option in ${@} ; do
51178 + echo "mk_add_options ${option} # ${reason}" >>${MOZCONFIG}
51179 + done
51180 +}
51181 +
51182 +mozconfig_use_enable() {
51183 + debug-print-function ${FUNCNAME} "$@"
51184 +
51185 + if [[ ${#} -lt 1 ]] ; then
51186 + die "${FUNCNAME} requires at least one arguments"
51187 + fi
51188 +
51189 + local flag=$(use_enable "${@}")
51190 + mozconfig_add_options_ac "$(use ${1} && echo +${1} || echo -${1})" "${flag}"
51191 +}
51192 +
51193 +mozconfig_use_with() {
51194 + debug-print-function ${FUNCNAME} "$@"
51195 +
51196 + if [[ ${#} -lt 1 ]] ; then
51197 + die "${FUNCNAME} requires at least one arguments"
51198 + fi
51199 +
51200 + local flag=$(use_with "${@}")
51201 + mozconfig_add_options_ac "$(use ${1} && echo +${1} || echo -${1})" "${flag}"
51202 +}
51203 +
51204 +pkg_pretend() {
51205 + if [[ ${MERGE_TYPE} != binary ]] ; then
51206 + if use pgo ; then
51207 + if ! has usersandbox $FEATURES ; then
51208 + die "You must enable usersandbox as X server can not run as root!"
51209 + fi
51210 + fi
51211 +
51212 + # Ensure we have enough disk space to compile
51213 + if use pgo || use lto || use debug ; then
51214 + CHECKREQS_DISK_BUILD="13500M"
51215 + else
51216 + CHECKREQS_DISK_BUILD="6600M"
51217 + fi
51218 +
51219 + check-reqs_pkg_pretend
51220 + fi
51221 +}
51222 +
51223 +pkg_setup() {
51224 + if [[ ${MERGE_TYPE} != binary ]] ; then
51225 + if use pgo ; then
51226 + if ! has userpriv ${FEATURES} ; then
51227 + eerror "Building ${PN} with USE=pgo and FEATURES=-userpriv is not supported!"
51228 + fi
51229 + fi
51230 +
51231 + # Ensure we have enough disk space to compile
51232 + if use pgo || use lto || use debug ; then
51233 + CHECKREQS_DISK_BUILD="13500M"
51234 + else
51235 + CHECKREQS_DISK_BUILD="6400M"
51236 + fi
51237 +
51238 + check-reqs_pkg_setup
51239 +
51240 + llvm_pkg_setup
51241 +
51242 + if use clang && use lto ; then
51243 + local version_lld=$(ld.lld --version 2>/dev/null | awk '{ print $2 }')
51244 + [[ -n ${version_lld} ]] && version_lld=$(ver_cut 1 "${version_lld}")
51245 + [[ -z ${version_lld} ]] && die "Failed to read ld.lld version!"
51246 +
51247 + local version_llvm_rust=$(rustc -Vv 2>/dev/null | grep -F -- 'LLVM version:' | awk '{ print $3 }')
51248 + [[ -n ${version_llvm_rust} ]] && version_llvm_rust=$(ver_cut 1 "${version_llvm_rust}")
51249 + [[ -z ${version_llvm_rust} ]] && die "Failed to read used LLVM version from rustc!"
51250 +
51251 + if ver_test "${version_lld}" -ne "${version_llvm_rust}" ; then
51252 + eerror "Rust is using LLVM version ${version_llvm_rust} but ld.lld version belongs to LLVM version ${version_lld}."
51253 + eerror "You will be unable to link ${CATEGORY}/${PN}. To proceed you have the following options:"
51254 + eerror " - Manually switch rust version using 'eselect rust' to match used LLVM version"
51255 + eerror " - Switch to dev-lang/rust[system-llvm] which will guarantee matching version"
51256 + eerror " - Build ${CATEGORY}/${PN} without USE=lto"
51257 + eerror " - Rebuild lld with llvm that was used to build rust (may need to rebuild the whole "
51258 + eerror " llvm/clang/lld/rust chain depending on your @world updates)"
51259 + die "LLVM version used by Rust (${version_llvm_rust}) does not match with ld.lld version (${version_lld})!"
51260 + fi
51261 + fi
51262 +
51263 + if ! use clang && [[ $(gcc-major-version) -eq 11 ]] \
51264 + && ! has_version -b ">sys-devel/gcc-11.1.0:11" ; then
51265 + # bug 792705
51266 + eerror "Using GCC 11 to compile firefox is currently known to be broken (see bug #792705)."
51267 + die "Set USE=clang or select <gcc-11 to build ${CATEGORY}/${P}."
51268 + fi
51269 +
51270 + python-any-r1_pkg_setup
51271 +
51272 + # Avoid PGO profiling problems due to enviroment leakage
51273 + # These should *always* be cleaned up anyway
51274 + unset \
51275 + DBUS_SESSION_BUS_ADDRESS \
51276 + DISPLAY \
51277 + ORBIT_SOCKETDIR \
51278 + SESSION_MANAGER \
51279 + XAUTHORITY \
51280 + XDG_CACHE_HOME \
51281 + XDG_SESSION_COOKIE
51282 +
51283 + # Build system is using /proc/self/oom_score_adj, bug #604394
51284 + addpredict /proc/self/oom_score_adj
51285 +
51286 + if use pgo ; then
51287 + # Allow access to GPU during PGO run
51288 + local ati_cards mesa_cards nvidia_cards render_cards
51289 + shopt -s nullglob
51290 +
51291 + ati_cards=$(echo -n /dev/ati/card* | sed 's/ /:/g')
51292 + if [[ -n "${ati_cards}" ]] ; then
51293 + addpredict "${ati_cards}"
51294 + fi
51295 +
51296 + mesa_cards=$(echo -n /dev/dri/card* | sed 's/ /:/g')
51297 + if [[ -n "${mesa_cards}" ]] ; then
51298 + addpredict "${mesa_cards}"
51299 + fi
51300 +
51301 + nvidia_cards=$(echo -n /dev/nvidia* | sed 's/ /:/g')
51302 + if [[ -n "${nvidia_cards}" ]] ; then
51303 + addpredict "${nvidia_cards}"
51304 + fi
51305 +
51306 + render_cards=$(echo -n /dev/dri/renderD128* | sed 's/ /:/g')
51307 + if [[ -n "${render_cards}" ]] ; then
51308 + addpredict "${render_cards}"
51309 + fi
51310 +
51311 + shopt -u nullglob
51312 + fi
51313 +
51314 + if ! mountpoint -q /dev/shm ; then
51315 + # If /dev/shm is not available, configure is known to fail with
51316 + # a traceback report referencing /usr/lib/pythonN.N/multiprocessing/synchronize.py
51317 + ewarn "/dev/shm is not mounted -- expect build failures!"
51318 + fi
51319 +
51320 + # Google API keys (see http://www.chromium.org/developers/how-tos/api-keys)
51321 + # Note: These are for Gentoo Linux use ONLY. For your own distribution, please
51322 + # get your own set of keys.
51323 + if [[ -z "${MOZ_API_KEY_GOOGLE+set}" ]] ; then
51324 + MOZ_API_KEY_GOOGLE="AIzaSyDEAOvatFogGaPi0eTgsV_ZlEzx0ObmepsMzfAc"
51325 + fi
51326 +
51327 + if [[ -z "${MOZ_API_KEY_LOCATION+set}" ]] ; then
51328 + MOZ_API_KEY_LOCATION="AIzaSyB2h2OuRgGaPicUgy5N-5hsZqiPW6sH3n_rptiQ"
51329 + fi
51330 +
51331 + # Mozilla API keys (see https://location.services.mozilla.com/api)
51332 + # Note: These are for Gentoo Linux use ONLY. For your own distribution, please
51333 + # get your own set of keys.
51334 + if [[ -z "${MOZ_API_KEY_MOZILLA+set}" ]] ; then
51335 + MOZ_API_KEY_MOZILLA="edb3d487-3a84-46m0ap1e3-9dfd-92b5efaaa005"
51336 + fi
51337 +
51338 + # Ensure we use C locale when building, bug #746215
51339 + export LC_ALL=C
51340 + fi
51341 +
51342 + CONFIG_CHECK="~SECCOMP"
51343 + WARNING_SECCOMP="CONFIG_SECCOMP not set! This system will be unable to play DRM-protected content."
51344 + linux-info_pkg_setup
51345 +}
51346 +
51347 +src_unpack() {
51348 + local _lp_dir="${WORKDIR}/language_packs"
51349 + local _src_file
51350 +
51351 + if [[ ! -d "${_lp_dir}" ]] ; then
51352 + mkdir "${_lp_dir}" || die
51353 + fi
51354 +
51355 + for _src_file in ${A} ; do
51356 + if [[ ${_src_file} == *.xpi ]]; then
51357 + cp "${DISTDIR}/${_src_file}" "${_lp_dir}" || die "Failed to copy '${_src_file}' to '${_lp_dir}'!"
51358 + else
51359 + unpack ${_src_file}
51360 + fi
51361 + done
51362 +}
51363 +
51364 +src_prepare() {
51365 + use lto && rm -v "${WORKDIR}"/firefox-patches/*-LTO-Only-enable-LTO-*.patch
51366 + eapply "${WORKDIR}/firefox-patches"
51367 + # riscv support from https://github.com/makotokato/gecko-dev
51368 + eapply "${FILESDIR}/firefox-riscv64-support.patch"
51369 + # disable cargo-vet check in order to do ./mach vendor rust
51370 + # https://bugzilla.mozilla.org/show_bug.cgi?id=1787601
51371 + # skip check_macroassembler_style.py
51372 + eapply "${FILESDIR}/firefox-riscv64-hack.patch"
51373 +
51374 + # Allow user to apply any additional patches without modifing ebuild
51375 + eapply_user
51376 +
51377 + # Make cargo respect MAKEOPTS
51378 + export CARGO_BUILD_JOBS="$(makeopts_jobs)"
51379 +
51380 + # Make LTO respect MAKEOPTS
51381 + sed -i \
51382 + -e "s/multiprocessing.cpu_count()/$(makeopts_jobs)/" \
51383 + "${S}"/build/moz.configure/lto-pgo.configure \
51384 + || die "sed failed to set num_cores"
51385 +
51386 + # Make ICU respect MAKEOPTS
51387 + sed -i \
51388 + -e "s/multiprocessing.cpu_count()/$(makeopts_jobs)/" \
51389 + "${S}"/intl/icu_sources_data.py \
51390 + || die "sed failed to set num_cores"
51391 +
51392 + # sed-in toolchain prefix
51393 + sed -i \
51394 + -e "s/objdump/${CHOST}-objdump/" \
51395 + "${S}"/python/mozbuild/mozbuild/configure/check_debug_ranges.py \
51396 + || die "sed failed to set toolchain prefix"
51397 +
51398 + sed -i \
51399 + -e 's/ccache_stats = None/return None/' \
51400 + "${S}"/python/mozbuild/mozbuild/controller/building.py \
51401 + || die "sed failed to disable ccache stats call"
51402 +
51403 + einfo "Removing pre-built binaries ..."
51404 + find "${S}"/third_party -type f \( -name '*.so' -o -name '*.o' \) -print -delete || die
51405 +
51406 + # Clearing checksums where we have applied patches
51407 + moz_clear_vendor_checksums audioipc
51408 + moz_clear_vendor_checksums audioipc-client
51409 + moz_clear_vendor_checksums audioipc-server
51410 +
51411 + # Create build dir
51412 + BUILD_DIR="${WORKDIR}/${PN}_build"
51413 + mkdir -p "${BUILD_DIR}" || die
51414 +
51415 + # Write API keys to disk
51416 + echo -n "${MOZ_API_KEY_GOOGLE//gGaPi/}" > "${S}"/api-google.key || die
51417 + echo -n "${MOZ_API_KEY_LOCATION//gGaPi/}" > "${S}"/api-location.key || die
51418 + echo -n "${MOZ_API_KEY_MOZILLA//m0ap1/}" > "${S}"/api-mozilla.key || die
51419 +
51420 + xdg_environment_reset
51421 +}
51422 +
51423 +src_configure() {
51424 + # Show flags set at the beginning
51425 + einfo "Current BINDGEN_CFLAGS:\t${BINDGEN_CFLAGS:-no value set}"
51426 + einfo "Current CFLAGS:\t\t${CFLAGS:-no value set}"
51427 + einfo "Current CXXFLAGS:\t\t${CXXFLAGS:-no value set}"
51428 + einfo "Current LDFLAGS:\t\t${LDFLAGS:-no value set}"
51429 + einfo "Current RUSTFLAGS:\t\t${RUSTFLAGS:-no value set}"
51430 +
51431 + local have_switched_compiler=
51432 + if use clang && ! tc-is-clang ; then
51433 + # Force clang
51434 + einfo "Enforcing the use of clang due to USE=clang ..."
51435 + have_switched_compiler=yes
51436 + AR=llvm-ar
51437 + AS=llvm-as
51438 + CC=${CHOST}-clang
51439 + CXX=${CHOST}-clang++
51440 + NM=llvm-nm
51441 + RANLIB=llvm-ranlib
51442 + elif ! use clang && ! tc-is-gcc ; then
51443 + # Force gcc
51444 + have_switched_compiler=yes
51445 + einfo "Enforcing the use of gcc due to USE=-clang ..."
51446 + AR=gcc-ar
51447 + CC=${CHOST}-gcc
51448 + CXX=${CHOST}-g++
51449 + NM=gcc-nm
51450 + RANLIB=gcc-ranlib
51451 + fi
51452 +
51453 + if [[ -n "${have_switched_compiler}" ]] ; then
51454 + # Because we switched active compiler we have to ensure
51455 + # that no unsupported flags are set
51456 + strip-unsupported-flags
51457 + fi
51458 +
51459 + # Ensure we use correct toolchain
51460 + export HOST_CC="$(tc-getBUILD_CC)"
51461 + export HOST_CXX="$(tc-getBUILD_CXX)"
51462 + tc-export CC CXX LD AR NM OBJDUMP RANLIB PKG_CONFIG
51463 +
51464 + # Pass the correct toolchain paths through cbindgen
51465 + if tc-is-cross-compiler ; then
51466 + export BINDGEN_CFLAGS="${SYSROOT:+--sysroot=${ESYSROOT}} --target=${CHOST} ${BINDGEN_CFLAGS-}"
51467 + fi
51468 +
51469 + # Set MOZILLA_FIVE_HOME
51470 + export MOZILLA_FIVE_HOME="/usr/$(get_libdir)/${PN}"
51471 +
51472 + # python/mach/mach/mixin/process.py fails to detect SHELL
51473 + export SHELL="${EPREFIX}/bin/bash"
51474 +
51475 + # Set state path
51476 + export MOZBUILD_STATE_PATH="${BUILD_DIR}"
51477 +
51478 + # Set MOZCONFIG
51479 + export MOZCONFIG="${S}/.mozconfig"
51480 +
51481 + # Initialize MOZCONFIG
51482 + mozconfig_add_options_ac '' --enable-application=browser
51483 +
51484 + # Set Gentoo defaults
51485 + export MOZILLA_OFFICIAL=1
51486 +
51487 + mozconfig_add_options_ac 'Gentoo default' \
51488 + --allow-addon-sideload \
51489 + --disable-cargo-incremental \
51490 + --disable-crashreporter \
51491 + --disable-gpsd \
51492 + --disable-install-strip \
51493 + --disable-parental-controls \
51494 + --disable-strip \
51495 + --disable-updater \
51496 + --enable-negotiateauth \
51497 + --enable-new-pass-manager \
51498 + --enable-official-branding \
51499 + --enable-release \
51500 + --enable-system-ffi \
51501 + --enable-system-pixman \
51502 + --host="${CBUILD:-${CHOST}}" \
51503 + --libdir="${EPREFIX}/usr/$(get_libdir)" \
51504 + --prefix="${EPREFIX}/usr" \
51505 + --target="${CHOST}" \
51506 + --without-ccache \
51507 + --without-wasm-sandboxed-libraries \
51508 + --with-intl-api \
51509 + --with-libclang-path="$(llvm-config --libdir)" \
51510 + --with-system-nspr \
51511 + --with-system-nss \
51512 + --with-system-zlib \
51513 + --with-toolchain-prefix="${CHOST}-" \
51514 + --with-unsigned-addon-scopes=app,system \
51515 + --x-includes="${ESYSROOT}/usr/include" \
51516 + --x-libraries="${ESYSROOT}/usr/$(get_libdir)"
51517 +
51518 + # Set update channel
51519 + local update_channel=release
51520 + [[ -n ${MOZ_ESR} ]] && update_channel=esr
51521 + mozconfig_add_options_ac '' --update-channel=${update_channel}
51522 +
51523 + if ! use x86 && [[ ${CHOST} != armv*h* ]] ; then
51524 + mozconfig_add_options_ac '' --enable-rust-simd
51525 + fi
51526 +
51527 + # For future keywording: This is currently (97.0) only supported on:
51528 + # amd64, arm, arm64 & x86.
51529 + # Might want to flip the logic around if Firefox is to support more arches.
51530 + if use ppc64 || use riscv; then
51531 + mozconfig_add_options_ac '' --disable-sandbox
51532 + else
51533 + mozconfig_add_options_ac '' --enable-sandbox
51534 + fi
51535 + if use riscv; then
51536 + mozconfig_add_options_ac '' --disable-jit
51537 + fi
51538 +
51539 + if [[ -s "${S}/api-google.key" ]] ; then
51540 + local key_origin="Gentoo default"
51541 + if [[ $(cat "${S}/api-google.key" | md5sum | awk '{ print $1 }') != 709560c02f94b41f9ad2c49207be6c54 ]] ; then
51542 + key_origin="User value"
51543 + fi
51544 +
51545 + mozconfig_add_options_ac "${key_origin}" \
51546 + --with-google-safebrowsing-api-keyfile="${S}/api-google.key"
51547 + else
51548 + einfo "Building without Google API key ..."
51549 + fi
51550 +
51551 + if [[ -s "${S}/api-location.key" ]] ; then
51552 + local key_origin="Gentoo default"
51553 + if [[ $(cat "${S}/api-location.key" | md5sum | awk '{ print $1 }') != ffb7895e35dedf832eb1c5d420ac7420 ]] ; then
51554 + key_origin="User value"
51555 + fi
51556 +
51557 + mozconfig_add_options_ac "${key_origin}" \
51558 + --with-google-location-service-api-keyfile="${S}/api-location.key"
51559 + else
51560 + einfo "Building without Location API key ..."
51561 + fi
51562 +
51563 + if [[ -s "${S}/api-mozilla.key" ]] ; then
51564 + local key_origin="Gentoo default"
51565 + if [[ $(cat "${S}/api-mozilla.key" | md5sum | awk '{ print $1 }') != 3927726e9442a8e8fa0e46ccc39caa27 ]] ; then
51566 + key_origin="User value"
51567 + fi
51568 +
51569 + mozconfig_add_options_ac "${key_origin}" \
51570 + --with-mozilla-api-keyfile="${S}/api-mozilla.key"
51571 + else
51572 + einfo "Building without Mozilla API key ..."
51573 + fi
51574 +
51575 + mozconfig_use_with system-av1
51576 + mozconfig_use_with system-harfbuzz
51577 + mozconfig_use_with system-harfbuzz system-graphite2
51578 + mozconfig_use_with system-icu
51579 + mozconfig_use_with system-jpeg
51580 + mozconfig_use_with system-libevent
51581 + mozconfig_use_with system-libvpx
51582 + mozconfig_use_with system-png
51583 + mozconfig_use_with system-webp
51584 +
51585 + mozconfig_use_enable dbus
51586 + mozconfig_use_enable libproxy
51587 +
51588 + use eme-free && mozconfig_add_options_ac '+eme-free' --disable-eme
51589 +
51590 + mozconfig_use_enable geckodriver
51591 +
51592 + if use hardened ; then
51593 + mozconfig_add_options_ac "+hardened" --enable-hardening
51594 + append-ldflags "-Wl,-z,relro -Wl,-z,now"
51595 + fi
51596 +
51597 + local myaudiobackends=""
51598 + use jack && myaudiobackends+="jack,"
51599 + use sndio && myaudiobackends+="sndio,"
51600 + use pulseaudio && myaudiobackends+="pulseaudio,"
51601 + ! use pulseaudio && myaudiobackends+="alsa,"
51602 +
51603 + mozconfig_add_options_ac '--enable-audio-backends' --enable-audio-backends="${myaudiobackends::-1}"
51604 +
51605 + mozconfig_use_enable wifi necko-wifi
51606 +
51607 + if use X && use wayland ; then
51608 + mozconfig_add_options_ac '+x11+wayland' --enable-default-toolkit=cairo-gtk3-x11-wayland
51609 + elif ! use X && use wayland ; then
51610 + mozconfig_add_options_ac '+wayland' --enable-default-toolkit=cairo-gtk3-wayland-only
51611 + else
51612 + mozconfig_add_options_ac '+x11' --enable-default-toolkit=cairo-gtk3
51613 + fi
51614 +
51615 + if use lto ; then
51616 + if use clang ; then
51617 + # Upstream only supports lld when using clang
51618 + mozconfig_add_options_ac "forcing ld=lld due to USE=clang and USE=lto" --enable-linker=lld
51619 +
51620 + mozconfig_add_options_ac '+lto' --enable-lto=cross
51621 +
51622 + else
51623 + # ThinLTO is currently broken, see bmo#1644409
51624 + mozconfig_add_options_ac '+lto' --enable-lto=full
51625 + mozconfig_add_options_ac "linker is set to bfd" --enable-linker=bfd
51626 + fi
51627 +
51628 + if use pgo ; then
51629 + mozconfig_add_options_ac '+pgo' MOZ_PGO=1
51630 +
51631 + if use clang ; then
51632 + # Used in build/pgo/profileserver.py
51633 + export LLVM_PROFDATA="llvm-profdata"
51634 + fi
51635 + fi
51636 + else
51637 + # Avoid auto-magic on linker
51638 + if use clang ; then
51639 + # This is upstream's default
51640 + mozconfig_add_options_ac "forcing ld=lld due to USE=clang" --enable-linker=lld
51641 + else
51642 + mozconfig_add_options_ac "linker is set to bfd" --enable-linker=bfd
51643 + fi
51644 + fi
51645 +
51646 + # LTO flag was handled via configure
51647 + filter-flags '-flto*'
51648 +
51649 + mozconfig_use_enable debug
51650 + if use debug ; then
51651 + mozconfig_add_options_ac '+debug' --disable-optimize
51652 + else
51653 + if is-flag '-g*' ; then
51654 + if use clang ; then
51655 + mozconfig_add_options_ac 'from CFLAGS' --enable-debug-symbols=$(get-flag '-g*')
51656 + else
51657 + mozconfig_add_options_ac 'from CFLAGS' --enable-debug-symbols
51658 + fi
51659 + else
51660 + mozconfig_add_options_ac 'Gentoo default' --disable-debug-symbols
51661 + fi
51662 +
51663 + if is-flag '-O0' ; then
51664 + mozconfig_add_options_ac "from CFLAGS" --enable-optimize=-O0
51665 + elif is-flag '-O4' ; then
51666 + mozconfig_add_options_ac "from CFLAGS" --enable-optimize=-O4
51667 + elif is-flag '-O3' ; then
51668 + mozconfig_add_options_ac "from CFLAGS" --enable-optimize=-O3
51669 + elif is-flag '-O1' ; then
51670 + mozconfig_add_options_ac "from CFLAGS" --enable-optimize=-O1
51671 + elif is-flag '-Os' ; then
51672 + mozconfig_add_options_ac "from CFLAGS" --enable-optimize=-Os
51673 + else
51674 + mozconfig_add_options_ac "Gentoo default" --enable-optimize=-O2
51675 + fi
51676 + fi
51677 +
51678 + # Debug flag was handled via configure
51679 + filter-flags '-g*'
51680 +
51681 + # Optimization flag was handled via configure
51682 + filter-flags '-O*'
51683 +
51684 + # Modifications to better support ARM, bug #553364
51685 + if use cpu_flags_arm_neon ; then
51686 + mozconfig_add_options_ac '+cpu_flags_arm_neon' --with-fpu=neon
51687 +
51688 + if ! tc-is-clang ; then
51689 + # thumb options aren't supported when using clang, bug 666966
51690 + mozconfig_add_options_ac '+cpu_flags_arm_neon' \
51691 + --with-thumb=yes \
51692 + --with-thumb-interwork=no
51693 + fi
51694 + fi
51695 +
51696 + if [[ ${CHOST} == armv*h* ]] ; then
51697 + mozconfig_add_options_ac 'CHOST=armv*h*' --with-float-abi=hard
51698 +
51699 + if ! use system-libvpx ; then
51700 + sed -i \
51701 + -e "s|softfp|hard|" \
51702 + "${S}"/media/libvpx/moz.build \
51703 + || die
51704 + fi
51705 + fi
51706 +
51707 + if use clang ; then
51708 + # https://bugzilla.mozilla.org/show_bug.cgi?id=1482204
51709 + # https://bugzilla.mozilla.org/show_bug.cgi?id=1483822
51710 + # toolkit/moz.configure Elfhack section: target.cpu in ('arm', 'x86', 'x86_64')
51711 + local disable_elf_hack=
51712 + if use amd64 ; then
51713 + disable_elf_hack=yes
51714 + elif use x86 ; then
51715 + disable_elf_hack=yes
51716 + elif use arm ; then
51717 + disable_elf_hack=yes
51718 + fi
51719 +
51720 + if [[ -n ${disable_elf_hack} ]] ; then
51721 + mozconfig_add_options_ac 'elf-hack is broken when using Clang' --disable-elf-hack
51722 + fi
51723 + elif tc-is-gcc ; then
51724 + if ver_test $(gcc-fullversion) -ge 10 ; then
51725 + einfo "Forcing -fno-tree-loop-vectorize to workaround GCC bug, see bug 758446 ..."
51726 + append-cxxflags -fno-tree-loop-vectorize
51727 + fi
51728 + fi
51729 +
51730 + # Additional ARCH support
51731 + case "${ARCH}" in
51732 + arm)
51733 + # Reduce the memory requirements for linking
51734 + if use clang ; then
51735 + # Nothing to do
51736 + :;
51737 + elif use lto ; then
51738 + append-ldflags -Wl,--no-keep-memory
51739 + else
51740 + append-ldflags -Wl,--no-keep-memory -Wl,--reduce-memory-overheads
51741 + fi
51742 + ;;
51743 + esac
51744 +
51745 + if ! use elibc_glibc ; then
51746 + mozconfig_add_options_ac '!elibc_glibc' --disable-jemalloc
51747 + fi
51748 +
51749 + # Allow elfhack to work in combination with unstripped binaries
51750 + # when they would normally be larger than 2GiB.
51751 + append-ldflags "-Wl,--compress-debug-sections=zlib"
51752 +
51753 + # Make revdep-rebuild.sh happy; Also required for musl
51754 + append-ldflags -Wl,-rpath="${MOZILLA_FIVE_HOME}",--enable-new-dtags
51755 +
51756 + # Pass $MAKEOPTS to build system
51757 + export MOZ_MAKE_FLAGS="${MAKEOPTS}"
51758 +
51759 + # Use system's Python environment
51760 + PIP_NETWORK_INSTALL_RESTRICTED_VIRTUALENVS=mach
51761 +
51762 + if use system-python-libs; then
51763 + export MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE="system"
51764 + else
51765 + export MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE="none"
51766 + fi
51767 +
51768 + # Disable notification when build system has finished
51769 + export MOZ_NOSPAM=1
51770 +
51771 + # Portage sets XARGS environment variable to "xargs -r" by default which
51772 + # breaks build system's check_prog() function which doesn't support arguments
51773 + mozconfig_add_options_ac 'Gentoo default' "XARGS=${EPREFIX}/usr/bin/xargs"
51774 +
51775 + # Set build dir
51776 + mozconfig_add_options_mk 'Gentoo default' "MOZ_OBJDIR=${BUILD_DIR}"
51777 +
51778 + # Show flags we will use
51779 + einfo "Build BINDGEN_CFLAGS:\t${BINDGEN_CFLAGS:-no value set}"
51780 + einfo "Build CFLAGS:\t\t${CFLAGS:-no value set}"
51781 + einfo "Build CXXFLAGS:\t\t${CXXFLAGS:-no value set}"
51782 + einfo "Build LDFLAGS:\t\t${LDFLAGS:-no value set}"
51783 + einfo "Build RUSTFLAGS:\t\t${RUSTFLAGS:-no value set}"
51784 +
51785 + # Handle EXTRA_CONF and show summary
51786 + local ac opt hash reason
51787 +
51788 + # Apply EXTRA_ECONF entries to $MOZCONFIG
51789 + if [[ -n ${EXTRA_ECONF} ]] ; then
51790 + IFS=\! read -a ac <<<${EXTRA_ECONF// --/\!}
51791 + for opt in "${ac[@]}"; do
51792 + mozconfig_add_options_ac "EXTRA_ECONF" --${opt#--}
51793 + done
51794 + fi
51795 +
51796 + echo
51797 + echo "=========================================================="
51798 + echo "Building ${PF} with the following configuration"
51799 + grep ^ac_add_options "${MOZCONFIG}" | while read ac opt hash reason; do
51800 + [[ -z ${hash} || ${hash} == \# ]] \
51801 + || die "error reading mozconfig: ${ac} ${opt} ${hash} ${reason}"
51802 + printf " %-30s %s\n" "${opt}" "${reason:-mozilla.org default}"
51803 + done
51804 + echo "=========================================================="
51805 + echo
51806 +
51807 + # To avoid huge patches of rust library (~200MB), we have to download on the fly
51808 + einfo "riscv overlay: Performing ./mach vendor rust to update third party libs"
51809 + ./mach vendor rust --ignore-modified || die
51810 + ./mach configure || die
51811 +}
51812 +
51813 +src_compile() {
51814 + local virtx_cmd=
51815 +
51816 + if use pgo ; then
51817 + virtx_cmd=virtx
51818 +
51819 + # Reset and cleanup environment variables used by GNOME/XDG
51820 + gnome2_environment_reset
51821 +
51822 + addpredict /root
51823 + fi
51824 +
51825 + if ! use X && use wayland; then
51826 + local -x GDK_BACKEND=wayland
51827 + else
51828 + local -x GDK_BACKEND=x11
51829 + fi
51830 +
51831 + ${virtx_cmd} ./mach build --verbose \
51832 + || die
51833 +}
51834 +
51835 +src_install() {
51836 + # xpcshell is getting called during install
51837 + pax-mark m \
51838 + "${BUILD_DIR}"/dist/bin/xpcshell \
51839 + "${BUILD_DIR}"/dist/bin/${PN} \
51840 + "${BUILD_DIR}"/dist/bin/plugin-container
51841 +
51842 + DESTDIR="${D}" ./mach install || die
51843 +
51844 + # Upstream cannot ship symlink but we can (bmo#658850)
51845 + rm "${ED}${MOZILLA_FIVE_HOME}/${PN}-bin" || die
51846 + dosym ${PN} ${MOZILLA_FIVE_HOME}/${PN}-bin
51847 +
51848 + # Don't install llvm-symbolizer from sys-devel/llvm package
51849 + if [[ -f "${ED}${MOZILLA_FIVE_HOME}/llvm-symbolizer" ]] ; then
51850 + rm -v "${ED}${MOZILLA_FIVE_HOME}/llvm-symbolizer" || die
51851 + fi
51852 +
51853 + # Install policy (currently only used to disable application updates)
51854 + insinto "${MOZILLA_FIVE_HOME}/distribution"
51855 + newins "${FILESDIR}"/distribution.ini distribution.ini
51856 + newins "${FILESDIR}"/disable-auto-update.policy.json policies.json
51857 +
51858 + # Install system-wide preferences
51859 + local PREFS_DIR="${MOZILLA_FIVE_HOME}/browser/defaults/preferences"
51860 + insinto "${PREFS_DIR}"
51861 + newins "${FILESDIR}"/gentoo-default-prefs.js gentoo-prefs.js
51862 +
51863 + local GENTOO_PREFS="${ED}${PREFS_DIR}/gentoo-prefs.js"
51864 +
51865 + # Set dictionary path to use system hunspell
51866 + cat >>"${GENTOO_PREFS}" <<-EOF || die "failed to set spellchecker.dictionary_path pref"
51867 + pref("spellchecker.dictionary_path", "${EPREFIX}/usr/share/myspell");
51868 + EOF
51869 +
51870 + # Force hwaccel prefs if USE=hwaccel is enabled
51871 + if use hwaccel ; then
51872 + cat "${FILESDIR}"/gentoo-hwaccel-prefs.js-r2 \
51873 + >>"${GENTOO_PREFS}" \
51874 + || die "failed to add prefs to force hardware-accelerated rendering to all-gentoo.js"
51875 +
51876 + if use wayland; then
51877 + cat >>"${GENTOO_PREFS}" <<-EOF || die "failed to set hwaccel wayland prefs"
51878 + pref("gfx.x11-egl.force-enabled", false);
51879 + EOF
51880 + else
51881 + cat >>"${GENTOO_PREFS}" <<-EOF || die "failed to set hwaccel x11 prefs"
51882 + pref("gfx.x11-egl.force-enabled", true);
51883 + EOF
51884 + fi
51885 + fi
51886 +
51887 + if ! use gmp-autoupdate ; then
51888 + local plugin
51889 + for plugin in "${MOZ_GMP_PLUGIN_LIST[@]}" ; do
51890 + einfo "Disabling auto-update for ${plugin} plugin ..."
51891 + cat >>"${GENTOO_PREFS}" <<-EOF || die "failed to disable autoupdate for ${plugin} media plugin"
51892 + pref("media.${plugin}.autoupdate", false);
51893 + EOF
51894 + done
51895 + fi
51896 +
51897 + # Force the graphite pref if USE=system-harfbuzz is enabled, since the pref cannot disable it
51898 + if use system-harfbuzz ; then
51899 + cat >>"${GENTOO_PREFS}" <<-EOF || die "failed to set gfx.font_rendering.graphite.enabled pref"
51900 + sticky_pref("gfx.font_rendering.graphite.enabled", true);
51901 + EOF
51902 + fi
51903 +
51904 + # Install language packs
51905 + local langpacks=( $(find "${WORKDIR}/language_packs" -type f -name '*.xpi') )
51906 + if [[ -n "${langpacks}" ]] ; then
51907 + moz_install_xpi "${MOZILLA_FIVE_HOME}/distribution/extensions" "${langpacks[@]}"
51908 + fi
51909 +
51910 + # Install geckodriver
51911 + if use geckodriver ; then
51912 + einfo "Installing geckodriver into ${ED}${MOZILLA_FIVE_HOME} ..."
51913 + pax-mark m "${BUILD_DIR}"/dist/bin/geckodriver
51914 + exeinto "${MOZILLA_FIVE_HOME}"
51915 + doexe "${BUILD_DIR}"/dist/bin/geckodriver
51916 +
51917 + dosym ${MOZILLA_FIVE_HOME}/geckodriver /usr/bin/geckodriver
51918 + fi
51919 +
51920 + # Install icons
51921 + local icon_srcdir="${S}/browser/branding/official"
51922 + local icon_symbolic_file="${FILESDIR}/icon/firefox-symbolic.svg"
51923 +
51924 + insinto /usr/share/icons/hicolor/symbolic/apps
51925 + newins "${icon_symbolic_file}" ${PN}-symbolic.svg
51926 +
51927 + local icon size
51928 + for icon in "${icon_srcdir}"/default*.png ; do
51929 + size=${icon%.png}
51930 + size=${size##*/default}
51931 +
51932 + if [[ ${size} -eq 48 ]] ; then
51933 + newicon "${icon}" ${PN}.png
51934 + fi
51935 +
51936 + newicon -s ${size} "${icon}" ${PN}.png
51937 + done
51938 +
51939 + # Install menu
51940 + local app_name="Mozilla ${MOZ_PN^}"
51941 + local desktop_file="${FILESDIR}/icon/${PN}-r3.desktop"
51942 + local desktop_filename="${PN}.desktop"
51943 + local exec_command="${PN}"
51944 + local icon="${PN}"
51945 + local use_wayland="false"
51946 +
51947 + if use wayland ; then
51948 + use_wayland="true"
51949 + fi
51950 +
51951 + cp "${desktop_file}" "${WORKDIR}/${PN}.desktop-template" || die
51952 +
51953 + sed -i \
51954 + -e "s:@NAME@:${app_name}:" \
51955 + -e "s:@EXEC@:${exec_command}:" \
51956 + -e "s:@ICON@:${icon}:" \
51957 + "${WORKDIR}/${PN}.desktop-template" \
51958 + || die
51959 +
51960 + newmenu "${WORKDIR}/${PN}.desktop-template" "${desktop_filename}"
51961 +
51962 + rm "${WORKDIR}/${PN}.desktop-template" || die
51963 +
51964 + # Install wrapper script
51965 + [[ -f "${ED}/usr/bin/${PN}" ]] && rm "${ED}/usr/bin/${PN}"
51966 + newbin "${FILESDIR}/${PN}-r1.sh" ${PN}
51967 +
51968 + # Update wrapper
51969 + sed -i \
51970 + -e "s:@PREFIX@:${EPREFIX}/usr:" \
51971 + -e "s:@MOZ_FIVE_HOME@:${MOZILLA_FIVE_HOME}:" \
51972 + -e "s:@APULSELIB_DIR@:${apulselib}:" \
51973 + -e "s:@DEFAULT_WAYLAND@:${use_wayland}:" \
51974 + "${ED}/usr/bin/${PN}" \
51975 + || die
51976 +}
51977 +
51978 +pkg_preinst() {
51979 + xdg_pkg_preinst
51980 +
51981 + # If the apulse libs are available in MOZILLA_FIVE_HOME then apulse
51982 + # does not need to be forced into the LD_LIBRARY_PATH
51983 + if use pulseaudio && has_version ">=media-sound/apulse-0.1.12-r4" ; then
51984 + einfo "APULSE found; Generating library symlinks for sound support ..."
51985 + local lib
51986 + pushd "${ED}${MOZILLA_FIVE_HOME}" &>/dev/null || die
51987 + for lib in ../apulse/libpulse{.so{,.0},-simple.so{,.0}} ; do
51988 + # A quickpkg rolled by hand will grab symlinks as part of the package,
51989 + # so we need to avoid creating them if they already exist.
51990 + if [[ ! -L ${lib##*/} ]] ; then
51991 + ln -s "${lib}" ${lib##*/} || die
51992 + fi
51993 + done
51994 + popd &>/dev/null || die
51995 + fi
51996 +}
51997 +
51998 +pkg_postinst() {
51999 + xdg_pkg_postinst
52000 +
52001 + if ! use gmp-autoupdate ; then
52002 + elog "USE='-gmp-autoupdate' has disabled the following plugins from updating or"
52003 + elog "installing into new profiles:"
52004 + local plugin
52005 + for plugin in "${MOZ_GMP_PLUGIN_LIST[@]}" ; do
52006 + elog "\t ${plugin}"
52007 + done
52008 + elog
52009 + fi
52010 +
52011 + if use pulseaudio && has_version ">=media-sound/apulse-0.1.12-r4" ; then
52012 + elog "Apulse was detected at merge time on this system and so it will always be"
52013 + elog "used for sound. If you wish to use pulseaudio instead please unmerge"
52014 + elog "media-sound/apulse."
52015 + elog
52016 + fi
52017 +
52018 + local show_doh_information
52019 + local show_normandy_information
52020 + local show_shortcut_information
52021 +
52022 + if [[ -z "${REPLACING_VERSIONS}" ]] ; then
52023 + # New install; Tell user that DoH is disabled by default
52024 + show_doh_information=yes
52025 + show_normandy_information=yes
52026 + show_shortcut_information=no
52027 + else
52028 + local replacing_version
52029 + for replacing_version in ${REPLACING_VERSIONS} ; do
52030 + if ver_test "${replacing_version}" -lt 91.0 ; then
52031 + # Tell user that we no longer install a shortcut
52032 + # per supported display protocol
52033 + show_shortcut_information=yes
52034 + fi
52035 + done
52036 + fi
52037 +
52038 + if [[ -n "${show_doh_information}" ]] ; then
52039 + elog
52040 + elog "Note regarding Trusted Recursive Resolver aka DNS-over-HTTPS (DoH):"
52041 + elog "Due to privacy concerns (encrypting DNS might be a good thing, sending all"
52042 + elog "DNS traffic to Cloudflare by default is not a good idea and applications"
52043 + elog "should respect OS configured settings), \"network.trr.mode\" was set to 5"
52044 + elog "(\"Off by choice\") by default."
52045 + elog "You can enable DNS-over-HTTPS in ${PN^}'s preferences."
52046 + fi
52047 +
52048 + # bug 713782
52049 + if [[ -n "${show_normandy_information}" ]] ; then
52050 + elog
52051 + elog "Upstream operates a service named Normandy which allows Mozilla to"
52052 + elog "push changes for default settings or even install new add-ons remotely."
52053 + elog "While this can be useful to address problems like 'Armagadd-on 2.0' or"
52054 + elog "revert previous decisions to disable TLS 1.0/1.1, privacy and security"
52055 + elog "concerns prevail, which is why we have switched off the use of this"
52056 + elog "service by default."
52057 + elog
52058 + elog "To re-enable this service set"
52059 + elog
52060 + elog " app.normandy.enabled=true"
52061 + elog
52062 + elog "in about:config."
52063 + fi
52064 +
52065 + if [[ -n "${show_shortcut_information}" ]] ; then
52066 + elog
52067 + elog "Since ${PN}-91.0 we no longer install multiple shortcuts for"
52068 + elog "each supported display protocol. Instead we will only install"
52069 + elog "one generic Mozilla ${PN^} shortcut."
52070 + elog "If you still want to be able to select between running Mozilla ${PN^}"
52071 + elog "on X11 or Wayland, you have to re-create these shortcuts on your own."
52072 + fi
52073 +
52074 + # bug 835078
52075 + if use hwaccel && has_version "x11-drivers/xf86-video-nouveau"; then
52076 + ewarn "You have nouveau drivers installed in your system and 'hwaccel' "
52077 + ewarn "enabled for Firefox. Nouveau / your GPU might not support the "
52078 + ewarn "required EGL, so either disable 'hwaccel' or try the workaround "
52079 + ewarn "explained in https://bugs.gentoo.org/835078#c5 if Firefox crashes."
52080 + fi
52081 +
52082 + elog
52083 + elog "Unfortunately Firefox-100.0 breaks compatibility with some sites using "
52084 + elog "useragent checks. To temporarily fix this, enter about:config and modify "
52085 + elog "network.http.useragent.forceVersion preference to \"99\"."
52086 + elog "Or install an addon to change your useragent."
52087 + elog "See: https://support.mozilla.org/en-US/kb/difficulties-opening-or-using-website-firefox-100"
52088 + elog
52089 +}