diff --git a/device-mapper-persistent-data.spec b/device-mapper-persistent-data.spec index f4fb197..f49fb9c 100644 --- a/device-mapper-persistent-data.spec +++ b/device-mapper-persistent-data.spec @@ -8,7 +8,7 @@ Summary: Device-mapper Persistent Data Tools Name: device-mapper-persistent-data Version: 0.9.0 -Release: 10%{?dist}%{?release_suffix} +Release: 10.0.riscv64%{?dist}%{?release_suffix} License: GPLv3+ URL: https://github.com/jthornber/thin-provisioning-tools #Source0: https://github.com/jthornber/thin-provisioning-tools/archive/thin-provisioning-tools-%%{version}.tar.gz @@ -30,6 +30,7 @@ Patch12: 0011-file_utils-Fix-resource-leak.patch Patch13: 0012-thin_delta-Clean-up-duplicated-code.patch Patch14: 0013-build-Remove-lboost_iostreams-linker-flag.patch Patch15: 0014-cargo-update.patch +Patch16: thin-provisioning-tools-0.9.0-vendor-riscv64.patch BuildRequires: autoconf, expat-devel, libaio-devel, libstdc++-devel, boost-devel, gcc-c++ Requires: expat @@ -80,6 +81,7 @@ END %patch12 -p1 -b .backup12 %patch13 -p1 -b .backup13 %patch14 -p1 -b .backup14 +%patch16 -p1 -b .riscv64 # NOTE: patch 15 is above at the rust setup echo %{version}-%{release} > VERSION @@ -153,6 +155,9 @@ make DESTDIR=%{buildroot} MANDIR=%{_mandir} install-rust-tools #% {_sbindir}/thin_show_duplicates %changelog +* Thu Apr 27 2023 David Abdurachmanov - 0.9.0-10.0.riscv64 +- Update vendor code for riscv64 + * Sun Feb 05 2023 Fabio Valentini - 0.9.0-10 - Rebuild for fixed frame pointer compiler flags in Rust RPM macros. diff --git a/thin-provisioning-tools-0.9.0-vendor-riscv64.patch b/thin-provisioning-tools-0.9.0-vendor-riscv64.patch new file mode 100644 index 0000000..c175552 --- /dev/null +++ b/thin-provisioning-tools-0.9.0-vendor-riscv64.patch @@ -0,0 +1,96969 @@ +diff --git a/Cargo.lock b/Cargo.lock +index 9dc0b8a..dd64019 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -1,5 +1,7 @@ + # This file is automatically @generated by Cargo. + # It is not intended for manual editing. ++version = 3 ++ + [[package]] + name = "adler" + version = "1.0.2" +@@ -65,18 +67,6 @@ version = "1.4.3" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +-[[package]] +-name = "cc" +-version = "1.0.68" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" +- +-[[package]] +-name = "cfg-if" +-version = "0.1.10" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +- + [[package]] + name = "cfg-if" + version = "1.0.0" +@@ -113,7 +103,7 @@ version = "1.2.1" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" + dependencies = [ +- "cfg-if 1.0.0", ++ "cfg-if", + ] + + [[package]] +@@ -138,7 +128,7 @@ version = "1.0.20" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0" + dependencies = [ +- "cfg-if 1.0.0", ++ "cfg-if", + "crc32fast", + "libc", + "miniz_oxide", +@@ -150,7 +140,7 @@ version = "0.1.16" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" + dependencies = [ +- "cfg-if 1.0.0", ++ "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + ] +@@ -161,7 +151,7 @@ version = "0.2.3" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" + dependencies = [ +- "cfg-if 1.0.0", ++ "cfg-if", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", + ] +@@ -183,16 +173,16 @@ checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" + dependencies = [ + "arrayvec", + "bitflags", +- "cfg-if 1.0.0", ++ "cfg-if", + "ryu", + "static_assertions", + ] + + [[package]] + name = "libc" +-version = "0.2.97" ++version = "0.2.142" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" ++checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" + + [[package]] + name = "log" +@@ -200,7 +190,7 @@ version = "0.4.14" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" + dependencies = [ +- "cfg-if 1.0.0", ++ "cfg-if", + ] + + [[package]] +@@ -209,6 +199,15 @@ version = "2.4.0" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" + ++[[package]] ++name = "memoffset" ++version = "0.7.1" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" ++dependencies = [ ++ "autocfg", ++] ++ + [[package]] + name = "miniz_oxide" + version = "0.4.4" +@@ -221,15 +220,16 @@ dependencies = [ + + [[package]] + name = "nix" +-version = "0.17.0" ++version = "0.26.2" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363" ++checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" + dependencies = [ + "bitflags", +- "cc", +- "cfg-if 0.1.10", ++ "cfg-if", + "libc", +- "void", ++ "memoffset", ++ "pin-utils", ++ "static_assertions", + ] + + [[package]] +@@ -273,6 +273,12 @@ dependencies = [ + "libc", + ] + ++[[package]] ++name = "pin-utils" ++version = "0.1.0" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" ++ + [[package]] + name = "ppv-lite86" + version = "0.2.10" +@@ -504,7 +510,7 @@ version = "3.2.0" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" + dependencies = [ +- "cfg-if 1.0.0", ++ "cfg-if", + "libc", + "rand 0.8.4", + "redox_syscall", +@@ -568,12 +574,6 @@ version = "0.9.3" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +-[[package]] +-name = "void" +-version = "1.0.2" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +- + [[package]] + name = "wasi" + version = "0.9.0+wasi-snapshot-preview1" +diff --git a/Cargo.toml b/Cargo.toml +index 69a5d94..431c2a7 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -12,9 +12,9 @@ clap = "2.33" + crc32c = "0.6" + flate2 = "1.0" + fixedbitset = "0.3" +-libc = "0.2.71" ++libc = "0.2" + quick-xml = "0.18" +-nix = "0.17" ++nix = "0.26" + nom = "5.1" + num_cpus = "1.13" + rand = "0.7" +diff --git a/vendor/cc/.cargo-checksum.json b/vendor/cc/.cargo-checksum.json +deleted file mode 100644 +index c502b41..0000000 +--- a/vendor/cc/.cargo-checksum.json ++++ /dev/null +@@ -1 +0,0 @@ +-{"files":{"Cargo.lock":"24720bf62cfad67ca24dfc9192a8f1c11a0f262655c087795605f188cee5c5f0","Cargo.toml":"84ef3b052c7b9ba469573df3ee45d89d426f2cd30d350f43198f115b9c5691fc","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"9916275542d23bfa0815b1f48d4546e514739fadc79775500de6a81cf17aac09","src/bin/gcc-shim.rs":"b77907875029494b6288841c3aed2e4939ed40708c7f597fca5c9e2570490ca6","src/com.rs":"bcdaf1c28b71e6ef889c6b08d1ce9d7c0761344a677f523bc4c3cd297957f804","src/lib.rs":"20d349f8528f191a4cf04a5a42daaaa8085c4e00885c78456ebada92dc39b7fb","src/registry.rs":"3cc1b5a50879fa751572878ae1d0afbfc960c11665258492754b2c8bccb0ff5d","src/setup_config.rs":"7014103587d3382eac599cb76f016e2609b8140970861b2237982d1db24af265","src/vs_instances.rs":"2d3f8278a803b0e7052f4eeb1979b29f963dd0143f4458e2cb5f33c4e5f0963b","src/winapi.rs":"ea8b7edbb9ff87957254f465c2334e714c5d6b3b19a8d757c48ea7ca0881c50c","src/windows_registry.rs":"090b5de68e19dab9e1884175dc2a6866f697bd043d6b3a0d4b3836c9d6812569","tests/cc_env.rs":"e02b3b0824ad039b47e4462c5ef6dbe6c824c28e7953af94a0f28f7b5158042e","tests/cflags.rs":"57f06eb5ce1557e5b4a032d0c4673e18fbe6f8d26c1deb153126e368b96b41b3","tests/cxxflags.rs":"c2c6c6d8a0d7146616fa1caed26876ee7bc9fcfffd525eb4743593cade5f3371","tests/support/mod.rs":"16274867f23871e9b07614eda4c7344da13d1751fed63d4f633857e40be86394","tests/test.rs":"65c073e0e2cf4aa0433066102788e9f57442719e6f32f5ad5248aa7132bb4597"},"package":"4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"} +\ No newline at end of file +diff --git a/vendor/cc/Cargo.lock b/vendor/cc/Cargo.lock +deleted file mode 100644 +index 9f1103f..0000000 +--- a/vendor/cc/Cargo.lock ++++ /dev/null +@@ -1,145 +0,0 @@ +-# This file is automatically @generated by Cargo. +-# It is not intended for manual editing. +-[[package]] +-name = "cc" +-version = "1.0.68" +-dependencies = [ +- "jobserver", +- "tempfile", +-] +- +-[[package]] +-name = "cfg-if" +-version = "0.1.10" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +- +-[[package]] +-name = "getrandom" +-version = "0.1.15" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" +-dependencies = [ +- "cfg-if", +- "libc", +- "wasi", +-] +- +-[[package]] +-name = "jobserver" +-version = "0.1.21" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2" +-dependencies = [ +- "libc", +-] +- +-[[package]] +-name = "libc" +-version = "0.2.80" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" +- +-[[package]] +-name = "ppv-lite86" +-version = "0.2.10" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +- +-[[package]] +-name = "rand" +-version = "0.7.3" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +-dependencies = [ +- "getrandom", +- "libc", +- "rand_chacha", +- "rand_core", +- "rand_hc", +-] +- +-[[package]] +-name = "rand_chacha" +-version = "0.2.2" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +-dependencies = [ +- "ppv-lite86", +- "rand_core", +-] +- +-[[package]] +-name = "rand_core" +-version = "0.5.1" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +-dependencies = [ +- "getrandom", +-] +- +-[[package]] +-name = "rand_hc" +-version = "0.2.0" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +-dependencies = [ +- "rand_core", +-] +- +-[[package]] +-name = "redox_syscall" +-version = "0.1.57" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +- +-[[package]] +-name = "remove_dir_all" +-version = "0.5.3" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +-dependencies = [ +- "winapi", +-] +- +-[[package]] +-name = "tempfile" +-version = "3.1.0" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" +-dependencies = [ +- "cfg-if", +- "libc", +- "rand", +- "redox_syscall", +- "remove_dir_all", +- "winapi", +-] +- +-[[package]] +-name = "wasi" +-version = "0.9.0+wasi-snapshot-preview1" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +- +-[[package]] +-name = "winapi" +-version = "0.3.9" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +-dependencies = [ +- "winapi-i686-pc-windows-gnu", +- "winapi-x86_64-pc-windows-gnu", +-] +- +-[[package]] +-name = "winapi-i686-pc-windows-gnu" +-version = "0.4.0" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +- +-[[package]] +-name = "winapi-x86_64-pc-windows-gnu" +-version = "0.4.0" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +diff --git a/vendor/cc/Cargo.toml b/vendor/cc/Cargo.toml +deleted file mode 100644 +index f246779..0000000 +--- a/vendor/cc/Cargo.toml ++++ /dev/null +@@ -1,34 +0,0 @@ +-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +-# +-# When uploading crates to the registry Cargo will automatically +-# "normalize" Cargo.toml files for maximal compatibility +-# with all versions of Cargo and also rewrite `path` dependencies +-# to registry (e.g., crates.io) dependencies +-# +-# If you believe there's an error in this file please file an +-# issue against the rust-lang/cargo repository. If you're +-# editing this file be aware that the upstream Cargo.toml +-# will likely look very different (and much more reasonable) +- +-[package] +-edition = "2018" +-name = "cc" +-version = "1.0.68" +-authors = ["Alex Crichton "] +-exclude = ["/.github", "/.travis.yml", "/appveyor.yml"] +-description = "A build-time dependency for Cargo build scripts to assist in invoking the native\nC compiler to compile native C code into a static archive to be linked into Rust\ncode.\n" +-homepage = "https://github.com/alexcrichton/cc-rs" +-documentation = "https://docs.rs/cc" +-readme = "README.md" +-keywords = ["build-dependencies"] +-categories = ["development-tools::build-utils"] +-license = "MIT/Apache-2.0" +-repository = "https://github.com/alexcrichton/cc-rs" +-[dependencies.jobserver] +-version = "0.1.16" +-optional = true +-[dev-dependencies.tempfile] +-version = "3" +- +-[features] +-parallel = ["jobserver"] +diff --git a/vendor/cc/LICENSE-APACHE b/vendor/cc/LICENSE-APACHE +deleted file mode 100644 +index 16fe87b..0000000 +--- a/vendor/cc/LICENSE-APACHE ++++ /dev/null +@@ -1,201 +0,0 @@ +- Apache License +- Version 2.0, January 2004 +- http://www.apache.org/licenses/ +- +-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +- +-1. Definitions. +- +- "License" shall mean the terms and conditions for use, reproduction, +- and distribution as defined by Sections 1 through 9 of this document. +- +- "Licensor" shall mean the copyright owner or entity authorized by +- the copyright owner that is granting the License. +- +- "Legal Entity" shall mean the union of the acting entity and all +- other entities that control, are controlled by, or are under common +- control with that entity. For the purposes of this definition, +- "control" means (i) the power, direct or indirect, to cause the +- direction or management of such entity, whether by contract or +- otherwise, or (ii) ownership of fifty percent (50%) or more of the +- outstanding shares, or (iii) beneficial ownership of such entity. +- +- "You" (or "Your") shall mean an individual or Legal Entity +- exercising permissions granted by this License. +- +- "Source" form shall mean the preferred form for making modifications, +- including but not limited to software source code, documentation +- source, and configuration files. +- +- "Object" form shall mean any form resulting from mechanical +- transformation or translation of a Source form, including but +- not limited to compiled object code, generated documentation, +- and conversions to other media types. +- +- "Work" shall mean the work of authorship, whether in Source or +- Object form, made available under the License, as indicated by a +- copyright notice that is included in or attached to the work +- (an example is provided in the Appendix below). +- +- "Derivative Works" shall mean any work, whether in Source or Object +- form, that is based on (or derived from) the Work and for which the +- editorial revisions, annotations, elaborations, or other modifications +- represent, as a whole, an original work of authorship. For the purposes +- of this License, Derivative Works shall not include works that remain +- separable from, or merely link (or bind by name) to the interfaces of, +- the Work and Derivative Works thereof. +- +- "Contribution" shall mean any work of authorship, including +- the original version of the Work and any modifications or additions +- to that Work or Derivative Works thereof, that is intentionally +- submitted to Licensor for inclusion in the Work by the copyright owner +- or by an individual or Legal Entity authorized to submit on behalf of +- the copyright owner. For the purposes of this definition, "submitted" +- means any form of electronic, verbal, or written communication sent +- to the Licensor or its representatives, including but not limited to +- communication on electronic mailing lists, source code control systems, +- and issue tracking systems that are managed by, or on behalf of, the +- Licensor for the purpose of discussing and improving the Work, but +- excluding communication that is conspicuously marked or otherwise +- designated in writing by the copyright owner as "Not a Contribution." +- +- "Contributor" shall mean Licensor and any individual or Legal Entity +- on behalf of whom a Contribution has been received by Licensor and +- subsequently incorporated within the Work. +- +-2. Grant of Copyright License. Subject to the terms and conditions of +- this License, each Contributor hereby grants to You a perpetual, +- worldwide, non-exclusive, no-charge, royalty-free, irrevocable +- copyright license to reproduce, prepare Derivative Works of, +- publicly display, publicly perform, sublicense, and distribute the +- Work and such Derivative Works in Source or Object form. +- +-3. Grant of Patent License. Subject to the terms and conditions of +- this License, each Contributor hereby grants to You a perpetual, +- worldwide, non-exclusive, no-charge, royalty-free, irrevocable +- (except as stated in this section) patent license to make, have made, +- use, offer to sell, sell, import, and otherwise transfer the Work, +- where such license applies only to those patent claims licensable +- by such Contributor that are necessarily infringed by their +- Contribution(s) alone or by combination of their Contribution(s) +- with the Work to which such Contribution(s) was submitted. If You +- institute patent litigation against any entity (including a +- cross-claim or counterclaim in a lawsuit) alleging that the Work +- or a Contribution incorporated within the Work constitutes direct +- or contributory patent infringement, then any patent licenses +- granted to You under this License for that Work shall terminate +- as of the date such litigation is filed. +- +-4. Redistribution. You may reproduce and distribute copies of the +- Work or Derivative Works thereof in any medium, with or without +- modifications, and in Source or Object form, provided that You +- meet the following conditions: +- +- (a) You must give any other recipients of the Work or +- Derivative Works a copy of this License; and +- +- (b) You must cause any modified files to carry prominent notices +- stating that You changed the files; and +- +- (c) You must retain, in the Source form of any Derivative Works +- that You distribute, all copyright, patent, trademark, and +- attribution notices from the Source form of the Work, +- excluding those notices that do not pertain to any part of +- the Derivative Works; and +- +- (d) If the Work includes a "NOTICE" text file as part of its +- distribution, then any Derivative Works that You distribute must +- include a readable copy of the attribution notices contained +- within such NOTICE file, excluding those notices that do not +- pertain to any part of the Derivative Works, in at least one +- of the following places: within a NOTICE text file distributed +- as part of the Derivative Works; within the Source form or +- documentation, if provided along with the Derivative Works; or, +- within a display generated by the Derivative Works, if and +- wherever such third-party notices normally appear. The contents +- of the NOTICE file are for informational purposes only and +- do not modify the License. You may add Your own attribution +- notices within Derivative Works that You distribute, alongside +- or as an addendum to the NOTICE text from the Work, provided +- that such additional attribution notices cannot be construed +- as modifying the License. +- +- You may add Your own copyright statement to Your modifications and +- may provide additional or different license terms and conditions +- for use, reproduction, or distribution of Your modifications, or +- for any such Derivative Works as a whole, provided Your use, +- reproduction, and distribution of the Work otherwise complies with +- the conditions stated in this License. +- +-5. Submission of Contributions. Unless You explicitly state otherwise, +- any Contribution intentionally submitted for inclusion in the Work +- by You to the Licensor shall be under the terms and conditions of +- this License, without any additional terms or conditions. +- Notwithstanding the above, nothing herein shall supersede or modify +- the terms of any separate license agreement you may have executed +- with Licensor regarding such Contributions. +- +-6. Trademarks. This License does not grant permission to use the trade +- names, trademarks, service marks, or product names of the Licensor, +- except as required for reasonable and customary use in describing the +- origin of the Work and reproducing the content of the NOTICE file. +- +-7. Disclaimer of Warranty. Unless required by applicable law or +- agreed to in writing, Licensor provides the Work (and each +- Contributor provides its Contributions) on an "AS IS" BASIS, +- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +- implied, including, without limitation, any warranties or conditions +- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +- PARTICULAR PURPOSE. You are solely responsible for determining the +- appropriateness of using or redistributing the Work and assume any +- risks associated with Your exercise of permissions under this License. +- +-8. Limitation of Liability. In no event and under no legal theory, +- whether in tort (including negligence), contract, or otherwise, +- unless required by applicable law (such as deliberate and grossly +- negligent acts) or agreed to in writing, shall any Contributor be +- liable to You for damages, including any direct, indirect, special, +- incidental, or consequential damages of any character arising as a +- result of this License or out of the use or inability to use the +- Work (including but not limited to damages for loss of goodwill, +- work stoppage, computer failure or malfunction, or any and all +- other commercial damages or losses), even if such Contributor +- has been advised of the possibility of such damages. +- +-9. Accepting Warranty or Additional Liability. While redistributing +- the Work or Derivative Works thereof, You may choose to offer, +- and charge a fee for, acceptance of support, warranty, indemnity, +- or other liability obligations and/or rights consistent with this +- License. However, in accepting such obligations, You may act only +- on Your own behalf and on Your sole responsibility, not on behalf +- of any other Contributor, and only if You agree to indemnify, +- defend, and hold each Contributor harmless for any liability +- incurred by, or claims asserted against, such Contributor by reason +- of your accepting any such warranty or additional liability. +- +-END OF TERMS AND CONDITIONS +- +-APPENDIX: How to apply the Apache License to your work. +- +- To apply the Apache License to your work, attach the following +- boilerplate notice, with the fields enclosed by brackets "[]" +- replaced with your own identifying information. (Don't include +- the brackets!) The text should be enclosed in the appropriate +- comment syntax for the file format. We also recommend that a +- file or class name and description of purpose be included on the +- same "printed page" as the copyright notice for easier +- identification within third-party archives. +- +-Copyright [yyyy] [name of copyright owner] +- +-Licensed under the Apache License, Version 2.0 (the "License"); +-you may not use this file except in compliance with the License. +-You may obtain a copy of the License at +- +- http://www.apache.org/licenses/LICENSE-2.0 +- +-Unless required by applicable law or agreed to in writing, software +-distributed under the License is distributed on an "AS IS" BASIS, +-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-See the License for the specific language governing permissions and +-limitations under the License. +diff --git a/vendor/cc/README.md b/vendor/cc/README.md +deleted file mode 100644 +index f88455e..0000000 +--- a/vendor/cc/README.md ++++ /dev/null +@@ -1,222 +0,0 @@ +-# cc-rs +- +-A library to compile C/C++/assembly into a Rust library/application. +- +-[Documentation](https://docs.rs/cc) +- +-A simple library meant to be used as a build dependency with Cargo packages in +-order to build a set of C/C++ files into a static archive. This crate calls out +-to the most relevant compiler for a platform, for example using `cl` on MSVC. +- +-## Using cc-rs +- +-First, you'll want to both add a build script for your crate (`build.rs`) and +-also add this crate to your `Cargo.toml` via: +- +-```toml +-[build-dependencies] +-cc = "1.0" +-``` +- +-Next up, you'll want to write a build script like so: +- +-```rust,no_run +-// build.rs +- +-fn main() { +- cc::Build::new() +- .file("foo.c") +- .file("bar.c") +- .compile("foo"); +-} +-``` +- +-And that's it! Running `cargo build` should take care of the rest and your Rust +-application will now have the C files `foo.c` and `bar.c` compiled into a file +-named `libfoo.a`. If the C files contain +- +-```c +-void foo_function(void) { ... } +-``` +- +-and +- +-```c +-int32_t bar_function(int32_t x) { ... } +-``` +- +-you can call them from Rust by declaring them in +-your Rust code like so: +- +-```rust,no_run +-extern { +- fn foo_function(); +- fn bar_function(x: i32) -> i32; +-} +- +-pub fn call() { +- unsafe { +- foo_function(); +- bar_function(42); +- } +-} +- +-fn main() { +- // ... +-} +-``` +- +-See [the Rustonomicon](https://doc.rust-lang.org/nomicon/ffi.html) for more details. +- +-## External configuration via environment variables +- +-To control the programs and flags used for building, the builder can set a +-number of different environment variables. +- +-* `CFLAGS` - a series of space separated flags passed to compilers. Note that +- individual flags cannot currently contain spaces, so doing +- something like: `-L=foo\ bar` is not possible. +-* `CC` - the actual C compiler used. Note that this is used as an exact +- executable name, so (for example) no extra flags can be passed inside +- this variable, and the builder must ensure that there aren't any +- trailing spaces. This compiler must understand the `-c` flag. For +- certain `TARGET`s, it also is assumed to know about other flags (most +- common is `-fPIC`). +-* `AR` - the `ar` (archiver) executable to use to build the static library. +-* `CRATE_CC_NO_DEFAULTS` - the default compiler flags may cause conflicts in some cross compiling scenarios. Setting this variable will disable the generation of default compiler flags. +-* `CXX...` - see [C++ Support](#c-support). +- +-Each of these variables can also be supplied with certain prefixes and suffixes, +-in the following prioritized order: +- +-1. `_` - for example, `CC_x86_64-unknown-linux-gnu` +-2. `_` - for example, `CC_x86_64_unknown_linux_gnu` +-3. `_` - for example, `HOST_CC` or `TARGET_CFLAGS` +-4. `` - a plain `CC`, `AR` as above. +- +-If none of these variables exist, cc-rs uses built-in defaults +- +-In addition to the above optional environment variables, `cc-rs` has some +-functions with hard requirements on some variables supplied by [cargo's +-build-script driver][cargo] that it has the `TARGET`, `OUT_DIR`, `OPT_LEVEL`, +-and `HOST` variables. +- +-[cargo]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#inputs-to-the-build-script +- +-## Optional features +- +-### Parallel +- +-Currently cc-rs supports parallel compilation (think `make -jN`) but this +-feature is turned off by default. To enable cc-rs to compile C/C++ in parallel, +-you can change your dependency to: +- +-```toml +-[build-dependencies] +-cc = { version = "1.0", features = ["parallel"] } +-``` +- +-By default cc-rs will limit parallelism to `$NUM_JOBS`, or if not present it +-will limit it to the number of cpus on the machine. If you are using cargo, +-use `-jN` option of `build`, `test` and `run` commands as `$NUM_JOBS` +-is supplied by cargo. +- +-## Compile-time Requirements +- +-To work properly this crate needs access to a C compiler when the build script +-is being run. This crate does not ship a C compiler with it. The compiler +-required varies per platform, but there are three broad categories: +- +-* Unix platforms require `cc` to be the C compiler. This can be found by +- installing cc/clang on Linux distributions and Xcode on macOS, for example. +-* Windows platforms targeting MSVC (e.g. your target triple ends in `-msvc`) +- require `cl.exe` to be available and in `PATH`. This is typically found in +- standard Visual Studio installations and the `PATH` can be set up by running +- the appropriate developer tools shell. +-* Windows platforms targeting MinGW (e.g. your target triple ends in `-gnu`) +- require `cc` to be available in `PATH`. We recommend the +- [MinGW-w64](http://mingw-w64.org) distribution, which is using the +- [Win-builds](http://win-builds.org) installation system. +- You may also acquire it via +- [MSYS2](https://www.msys2.org/), as explained [here][msys2-help]. Make sure +- to install the appropriate architecture corresponding to your installation of +- rustc. GCC from older [MinGW](http://www.mingw.org) project is compatible +- only with 32-bit rust compiler. +- +-[msys2-help]: https://github.com/rust-lang/rust#building-on-windows +- +-## C++ support +- +-`cc-rs` supports C++ libraries compilation by using the `cpp` method on +-`Build`: +- +-```rust,no_run +-fn main() { +- cc::Build::new() +- .cpp(true) // Switch to C++ library compilation. +- .file("foo.cpp") +- .compile("libfoo.a"); +-} +-``` +- +-For C++ libraries, the `CXX` and `CXXFLAGS` environment variables are used instead of `CC` and `CFLAGS`. +- +-The C++ standard library may be linked to the crate target. By default it's `libc++` for macOS, FreeBSD, and OpenBSD, `libc++_shared` for Android, nothing for MSVC, and `libstdc++` for anything else. It can be changed in one of two ways: +- +-1. by using the `cpp_link_stdlib` method on `Build`: +- ```rust,no-run +- fn main() { +- cc::Build::new() +- .cpp(true) +- .file("foo.cpp") +- .cpp_link_stdlib("stdc++") // use libstdc++ +- .compile("libfoo.a"); +- } +- ``` +-2. by setting the `CXXSTDLIB` environment variable. +- +-In particular, for Android you may want to [use `c++_static` if you have at most one shared library](https://developer.android.com/ndk/guides/cpp-support). +- +-Remember that C++ does name mangling so `extern "C"` might be required to enable Rust linker to find your functions. +- +-## CUDA C++ support +- +-`cc-rs` also supports compiling CUDA C++ libraries by using the `cuda` method +-on `Build` (currently for GNU/Clang toolchains only): +- +-```rust,no_run +-fn main() { +- cc::Build::new() +- // Switch to CUDA C++ library compilation using NVCC. +- .cuda(true) +- // Generate code for Maxwell (GTX 970, 980, 980 Ti, Titan X). +- .flag("-gencode").flag("arch=compute_52,code=sm_52") +- // Generate code for Maxwell (Jetson TX1). +- .flag("-gencode").flag("arch=compute_53,code=sm_53") +- // Generate code for Pascal (GTX 1070, 1080, 1080 Ti, Titan Xp). +- .flag("-gencode").flag("arch=compute_61,code=sm_61") +- // Generate code for Pascal (Tesla P100). +- .flag("-gencode").flag("arch=compute_60,code=sm_60") +- // Generate code for Pascal (Jetson TX2). +- .flag("-gencode").flag("arch=compute_62,code=sm_62") +- .file("bar.cu") +- .compile("libbar.a"); +-} +-``` +- +-## License +- +-This project is licensed under either of +- +- * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or +- https://www.apache.org/licenses/LICENSE-2.0) +- * MIT license ([LICENSE-MIT](LICENSE-MIT) or +- https://opensource.org/licenses/MIT) +- +-at your option. +- +-### Contribution +- +-Unless you explicitly state otherwise, any contribution intentionally submitted +-for inclusion in cc-rs by you, as defined in the Apache-2.0 license, shall be +-dual licensed as above, without any additional terms or conditions. +diff --git a/vendor/cc/src/bin/gcc-shim.rs b/vendor/cc/src/bin/gcc-shim.rs +deleted file mode 100644 +index 1731df8..0000000 +--- a/vendor/cc/src/bin/gcc-shim.rs ++++ /dev/null +@@ -1,48 +0,0 @@ +-#![cfg_attr(test, allow(dead_code))] +- +-use std::env; +-use std::fs::File; +-use std::io::prelude::*; +-use std::path::PathBuf; +- +-fn main() { +- let mut args = env::args(); +- let program = args.next().expect("Unexpected empty args"); +- +- let out_dir = PathBuf::from( +- env::var_os("GCCTEST_OUT_DIR").expect(&format!("{}: GCCTEST_OUT_DIR not found", program)), +- ); +- +- // Find the first nonexistent candidate file to which the program's args can be written. +- for i in 0.. { +- let candidate = &out_dir.join(format!("out{}", i)); +- +- // If the file exists, commands have already run. Try again. +- if candidate.exists() { +- continue; +- } +- +- // Create a file and record the args passed to the command. +- let mut f = File::create(candidate).expect(&format!( +- "{}: can't create candidate: {}", +- program, +- candidate.to_string_lossy() +- )); +- for arg in args { +- writeln!(f, "{}", arg).expect(&format!( +- "{}: can't write to candidate: {}", +- program, +- candidate.to_string_lossy() +- )); +- } +- break; +- } +- +- // Create a file used by some tests. +- let path = &out_dir.join("libfoo.a"); +- File::create(path).expect(&format!( +- "{}: can't create libfoo.a: {}", +- program, +- path.to_string_lossy() +- )); +-} +diff --git a/vendor/cc/src/com.rs b/vendor/cc/src/com.rs +deleted file mode 100644 +index a5f2afe..0000000 +--- a/vendor/cc/src/com.rs ++++ /dev/null +@@ -1,155 +0,0 @@ +-// Copyright © 2017 winapi-rs developers +-// Licensed under the Apache License, Version 2.0 +-// or the MIT license +-// , at your option. +-// All files in the project carrying such notice may not be copied, modified, or distributed +-// except according to those terms. +- +-#![allow(unused)] +- +-use crate::winapi::CoInitializeEx; +-use crate::winapi::IUnknown; +-use crate::winapi::Interface; +-use crate::winapi::BSTR; +-use crate::winapi::COINIT_MULTITHREADED; +-use crate::winapi::{SysFreeString, SysStringLen}; +-use crate::winapi::{HRESULT, S_FALSE, S_OK}; +-use std::ffi::{OsStr, OsString}; +-use std::mem::forget; +-use std::ops::Deref; +-use std::os::windows::ffi::{OsStrExt, OsStringExt}; +-use std::ptr::null_mut; +-use std::slice::from_raw_parts; +- +-pub fn initialize() -> Result<(), HRESULT> { +- let err = unsafe { CoInitializeEx(null_mut(), COINIT_MULTITHREADED) }; +- if err != S_OK && err != S_FALSE { +- // S_FALSE just means COM is already initialized +- return Err(err); +- } +- Ok(()) +-} +- +-pub struct ComPtr(*mut T) +-where +- T: Interface; +-impl ComPtr +-where +- T: Interface, +-{ +- /// Creates a `ComPtr` to wrap a raw pointer. +- /// It takes ownership over the pointer which means it does __not__ call `AddRef`. +- /// `T` __must__ be a COM interface that inherits from `IUnknown`. +- pub unsafe fn from_raw(ptr: *mut T) -> ComPtr { +- assert!(!ptr.is_null()); +- ComPtr(ptr) +- } +- /// Casts up the inheritance chain +- pub fn up(self) -> ComPtr +- where +- T: Deref, +- U: Interface, +- { +- ComPtr(self.into_raw() as *mut U) +- } +- /// Extracts the raw pointer. +- /// You are now responsible for releasing it yourself. +- pub fn into_raw(self) -> *mut T { +- let p = self.0; +- forget(self); +- p +- } +- /// For internal use only. +- fn as_unknown(&self) -> &IUnknown { +- unsafe { &*(self.0 as *mut IUnknown) } +- } +- /// Performs QueryInterface fun. +- pub fn cast(&self) -> Result, i32> +- where +- U: Interface, +- { +- let mut obj = null_mut(); +- let err = unsafe { self.as_unknown().QueryInterface(&U::uuidof(), &mut obj) }; +- if err < 0 { +- return Err(err); +- } +- Ok(unsafe { ComPtr::from_raw(obj as *mut U) }) +- } +-} +-impl Deref for ComPtr +-where +- T: Interface, +-{ +- type Target = T; +- fn deref(&self) -> &T { +- unsafe { &*self.0 } +- } +-} +-impl Clone for ComPtr +-where +- T: Interface, +-{ +- fn clone(&self) -> Self { +- unsafe { +- self.as_unknown().AddRef(); +- ComPtr::from_raw(self.0) +- } +- } +-} +-impl Drop for ComPtr +-where +- T: Interface, +-{ +- fn drop(&mut self) { +- unsafe { +- self.as_unknown().Release(); +- } +- } +-} +-pub struct BStr(BSTR); +-impl BStr { +- pub unsafe fn from_raw(s: BSTR) -> BStr { +- BStr(s) +- } +- pub fn to_osstring(&self) -> OsString { +- let len = unsafe { SysStringLen(self.0) }; +- let slice = unsafe { from_raw_parts(self.0, len as usize) }; +- OsStringExt::from_wide(slice) +- } +-} +-impl Drop for BStr { +- fn drop(&mut self) { +- unsafe { SysFreeString(self.0) }; +- } +-} +- +-pub trait ToWide { +- fn to_wide(&self) -> Vec; +- fn to_wide_null(&self) -> Vec; +-} +-impl ToWide for T +-where +- T: AsRef, +-{ +- fn to_wide(&self) -> Vec { +- self.as_ref().encode_wide().collect() +- } +- fn to_wide_null(&self) -> Vec { +- self.as_ref().encode_wide().chain(Some(0)).collect() +- } +-} +-pub trait FromWide +-where +- Self: Sized, +-{ +- fn from_wide(wide: &[u16]) -> Self; +- fn from_wide_null(wide: &[u16]) -> Self { +- let len = wide.iter().take_while(|&&c| c != 0).count(); +- Self::from_wide(&wide[..len]) +- } +-} +-impl FromWide for OsString { +- fn from_wide(wide: &[u16]) -> OsString { +- OsStringExt::from_wide(wide) +- } +-} +diff --git a/vendor/cc/src/lib.rs b/vendor/cc/src/lib.rs +deleted file mode 100644 +index 9d133a0..0000000 +--- a/vendor/cc/src/lib.rs ++++ /dev/null +@@ -1,3092 +0,0 @@ +-//! A library for build scripts to compile custom C code +-//! +-//! This library is intended to be used as a `build-dependencies` entry in +-//! `Cargo.toml`: +-//! +-//! ```toml +-//! [build-dependencies] +-//! cc = "1.0" +-//! ``` +-//! +-//! The purpose of this crate is to provide the utility functions necessary to +-//! compile C code into a static archive which is then linked into a Rust crate. +-//! Configuration is available through the `Build` struct. +-//! +-//! This crate will automatically detect situations such as cross compilation or +-//! other environment variables set by Cargo and will build code appropriately. +-//! +-//! The crate is not limited to C code, it can accept any source code that can +-//! be passed to a C or C++ compiler. As such, assembly files with extensions +-//! `.s` (gcc/clang) and `.asm` (MSVC) can also be compiled. +-//! +-//! [`Build`]: struct.Build.html +-//! +-//! # Parallelism +-//! +-//! To parallelize computation, enable the `parallel` feature for the crate. +-//! +-//! ```toml +-//! [build-dependencies] +-//! cc = { version = "1.0", features = ["parallel"] } +-//! ``` +-//! To specify the max number of concurrent compilation jobs, set the `NUM_JOBS` +-//! environment variable to the desired amount. +-//! +-//! Cargo will also set this environment variable when executed with the `-jN` flag. +-//! +-//! If `NUM_JOBS` is not set, the `RAYON_NUM_THREADS` environment variable can +-//! also specify the build parallelism. +-//! +-//! # Examples +-//! +-//! Use the `Build` struct to compile `src/foo.c`: +-//! +-//! ```no_run +-//! fn main() { +-//! cc::Build::new() +-//! .file("src/foo.c") +-//! .define("FOO", Some("bar")) +-//! .include("src") +-//! .compile("foo"); +-//! } +-//! ``` +- +-#![doc(html_root_url = "https://docs.rs/cc/1.0")] +-#![cfg_attr(test, deny(warnings))] +-#![allow(deprecated)] +-#![deny(missing_docs)] +- +-use std::collections::HashMap; +-use std::env; +-use std::ffi::{OsStr, OsString}; +-use std::fmt::{self, Display}; +-use std::fs; +-use std::io::{self, BufRead, BufReader, Read, Write}; +-use std::path::{Path, PathBuf}; +-use std::process::{Child, Command, Stdio}; +-use std::sync::{Arc, Mutex}; +-use std::thread::{self, JoinHandle}; +- +-// These modules are all glue to support reading the MSVC version from +-// the registry and from COM interfaces +-#[cfg(windows)] +-mod registry; +-#[cfg(windows)] +-#[macro_use] +-mod winapi; +-#[cfg(windows)] +-mod com; +-#[cfg(windows)] +-mod setup_config; +-#[cfg(windows)] +-mod vs_instances; +- +-pub mod windows_registry; +- +-/// A builder for compilation of a native library. +-/// +-/// A `Build` is the main type of the `cc` crate and is used to control all the +-/// various configuration options and such of a compile. You'll find more +-/// documentation on each method itself. +-#[derive(Clone, Debug)] +-pub struct Build { +- include_directories: Vec, +- definitions: Vec<(String, Option)>, +- objects: Vec, +- flags: Vec, +- flags_supported: Vec, +- known_flag_support_status: Arc>>, +- ar_flags: Vec, +- no_default_flags: bool, +- files: Vec, +- cpp: bool, +- cpp_link_stdlib: Option>, +- cpp_set_stdlib: Option, +- cuda: bool, +- target: Option, +- host: Option, +- out_dir: Option, +- opt_level: Option, +- debug: Option, +- force_frame_pointer: Option, +- env: Vec<(OsString, OsString)>, +- compiler: Option, +- archiver: Option, +- cargo_metadata: bool, +- pic: Option, +- use_plt: Option, +- static_crt: Option, +- shared_flag: Option, +- static_flag: Option, +- warnings_into_errors: bool, +- warnings: Option, +- extra_warnings: Option, +- env_cache: Arc>>>, +- apple_sdk_root_cache: Arc>>, +-} +- +-/// Represents the types of errors that may occur while using cc-rs. +-#[derive(Clone, Debug)] +-enum ErrorKind { +- /// Error occurred while performing I/O. +- IOError, +- /// Invalid architecture supplied. +- ArchitectureInvalid, +- /// Environment variable not found, with the var in question as extra info. +- EnvVarNotFound, +- /// Error occurred while using external tools (ie: invocation of compiler). +- ToolExecError, +- /// Error occurred due to missing external tools. +- ToolNotFound, +-} +- +-/// Represents an internal error that occurred, with an explanation. +-#[derive(Clone, Debug)] +-pub struct Error { +- /// Describes the kind of error that occurred. +- kind: ErrorKind, +- /// More explanation of error that occurred. +- message: String, +-} +- +-impl Error { +- fn new(kind: ErrorKind, message: &str) -> Error { +- Error { +- kind: kind, +- message: message.to_owned(), +- } +- } +-} +- +-impl From for Error { +- fn from(e: io::Error) -> Error { +- Error::new(ErrorKind::IOError, &format!("{}", e)) +- } +-} +- +-impl Display for Error { +- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +- write!(f, "{:?}: {}", self.kind, self.message) +- } +-} +- +-impl std::error::Error for Error {} +- +-/// Configuration used to represent an invocation of a C compiler. +-/// +-/// This can be used to figure out what compiler is in use, what the arguments +-/// to it are, and what the environment variables look like for the compiler. +-/// This can be used to further configure other build systems (e.g. forward +-/// along CC and/or CFLAGS) or the `to_command` method can be used to run the +-/// compiler itself. +-#[derive(Clone, Debug)] +-pub struct Tool { +- path: PathBuf, +- cc_wrapper_path: Option, +- cc_wrapper_args: Vec, +- args: Vec, +- env: Vec<(OsString, OsString)>, +- family: ToolFamily, +- cuda: bool, +- removed_args: Vec, +-} +- +-/// Represents the family of tools this tool belongs to. +-/// +-/// Each family of tools differs in how and what arguments they accept. +-/// +-/// Detection of a family is done on best-effort basis and may not accurately reflect the tool. +-#[derive(Copy, Clone, Debug, PartialEq)] +-enum ToolFamily { +- /// Tool is GNU Compiler Collection-like. +- Gnu, +- /// Tool is Clang-like. It differs from the GCC in a sense that it accepts superset of flags +- /// and its cross-compilation approach is different. +- Clang, +- /// Tool is the MSVC cl.exe. +- Msvc { clang_cl: bool }, +-} +- +-impl ToolFamily { +- /// What the flag to request debug info for this family of tools look like +- fn add_debug_flags(&self, cmd: &mut Tool) { +- match *self { +- ToolFamily::Msvc { .. } => { +- cmd.push_cc_arg("-Z7".into()); +- } +- ToolFamily::Gnu | ToolFamily::Clang => { +- cmd.push_cc_arg("-g".into()); +- } +- } +- } +- +- /// What the flag to force frame pointers. +- fn add_force_frame_pointer(&self, cmd: &mut Tool) { +- match *self { +- ToolFamily::Gnu | ToolFamily::Clang => { +- cmd.push_cc_arg("-fno-omit-frame-pointer".into()); +- } +- _ => (), +- } +- } +- +- /// What the flags to enable all warnings +- fn warnings_flags(&self) -> &'static str { +- match *self { +- ToolFamily::Msvc { .. } => "-W4", +- ToolFamily::Gnu | ToolFamily::Clang => "-Wall", +- } +- } +- +- /// What the flags to enable extra warnings +- fn extra_warnings_flags(&self) -> Option<&'static str> { +- match *self { +- ToolFamily::Msvc { .. } => None, +- ToolFamily::Gnu | ToolFamily::Clang => Some("-Wextra"), +- } +- } +- +- /// What the flag to turn warning into errors +- fn warnings_to_errors_flag(&self) -> &'static str { +- match *self { +- ToolFamily::Msvc { .. } => "-WX", +- ToolFamily::Gnu | ToolFamily::Clang => "-Werror", +- } +- } +- +- fn verbose_stderr(&self) -> bool { +- *self == ToolFamily::Clang +- } +-} +- +-/// Represents an object. +-/// +-/// This is a source file -> object file pair. +-#[derive(Clone, Debug)] +-struct Object { +- src: PathBuf, +- dst: PathBuf, +-} +- +-impl Object { +- /// Create a new source file -> object file pair. +- fn new(src: PathBuf, dst: PathBuf) -> Object { +- Object { src: src, dst: dst } +- } +-} +- +-impl Build { +- /// Construct a new instance of a blank set of configuration. +- /// +- /// This builder is finished with the [`compile`] function. +- /// +- /// [`compile`]: struct.Build.html#method.compile +- pub fn new() -> Build { +- Build { +- include_directories: Vec::new(), +- definitions: Vec::new(), +- objects: Vec::new(), +- flags: Vec::new(), +- flags_supported: Vec::new(), +- known_flag_support_status: Arc::new(Mutex::new(HashMap::new())), +- ar_flags: Vec::new(), +- no_default_flags: false, +- files: Vec::new(), +- shared_flag: None, +- static_flag: None, +- cpp: false, +- cpp_link_stdlib: None, +- cpp_set_stdlib: None, +- cuda: false, +- target: None, +- host: None, +- out_dir: None, +- opt_level: None, +- debug: None, +- force_frame_pointer: None, +- env: Vec::new(), +- compiler: None, +- archiver: None, +- cargo_metadata: true, +- pic: None, +- use_plt: None, +- static_crt: None, +- warnings: None, +- extra_warnings: None, +- warnings_into_errors: false, +- env_cache: Arc::new(Mutex::new(HashMap::new())), +- apple_sdk_root_cache: Arc::new(Mutex::new(HashMap::new())), +- } +- } +- +- /// Add a directory to the `-I` or include path for headers +- /// +- /// # Example +- /// +- /// ```no_run +- /// use std::path::Path; +- /// +- /// let library_path = Path::new("/path/to/library"); +- /// +- /// cc::Build::new() +- /// .file("src/foo.c") +- /// .include(library_path) +- /// .include("src") +- /// .compile("foo"); +- /// ``` +- pub fn include>(&mut self, dir: P) -> &mut Build { +- self.include_directories.push(dir.as_ref().to_path_buf()); +- self +- } +- +- /// Add multiple directories to the `-I` include path. +- /// +- /// # Example +- /// +- /// ```no_run +- /// # use std::path::Path; +- /// # let condition = true; +- /// # +- /// let mut extra_dir = None; +- /// if condition { +- /// extra_dir = Some(Path::new("/path/to")); +- /// } +- /// +- /// cc::Build::new() +- /// .file("src/foo.c") +- /// .includes(extra_dir) +- /// .compile("foo"); +- /// ``` +- pub fn includes

(&mut self, dirs: P) -> &mut Build +- where +- P: IntoIterator, +- P::Item: AsRef, +- { +- for dir in dirs { +- self.include(dir); +- } +- self +- } +- +- /// Specify a `-D` variable with an optional value. +- /// +- /// # Example +- /// +- /// ```no_run +- /// cc::Build::new() +- /// .file("src/foo.c") +- /// .define("FOO", "BAR") +- /// .define("BAZ", None) +- /// .compile("foo"); +- /// ``` +- pub fn define<'a, V: Into>>(&mut self, var: &str, val: V) -> &mut Build { +- self.definitions +- .push((var.to_string(), val.into().map(|s| s.to_string()))); +- self +- } +- +- /// Add an arbitrary object file to link in +- pub fn object>(&mut self, obj: P) -> &mut Build { +- self.objects.push(obj.as_ref().to_path_buf()); +- self +- } +- +- /// Add an arbitrary flag to the invocation of the compiler +- /// +- /// # Example +- /// +- /// ```no_run +- /// cc::Build::new() +- /// .file("src/foo.c") +- /// .flag("-ffunction-sections") +- /// .compile("foo"); +- /// ``` +- pub fn flag(&mut self, flag: &str) -> &mut Build { +- self.flags.push(flag.to_string()); +- self +- } +- +- /// Add an arbitrary flag to the invocation of the compiler +- /// +- /// # Example +- /// +- /// ```no_run +- /// cc::Build::new() +- /// .file("src/foo.c") +- /// .file("src/bar.c") +- /// .ar_flag("/NODEFAULTLIB:libc.dll") +- /// .compile("foo"); +- /// ``` +- +- pub fn ar_flag(&mut self, flag: &str) -> &mut Build { +- self.ar_flags.push(flag.to_string()); +- self +- } +- +- fn ensure_check_file(&self) -> Result { +- let out_dir = self.get_out_dir()?; +- let src = if self.cuda { +- assert!(self.cpp); +- out_dir.join("flag_check.cu") +- } else if self.cpp { +- out_dir.join("flag_check.cpp") +- } else { +- out_dir.join("flag_check.c") +- }; +- +- if !src.exists() { +- let mut f = fs::File::create(&src)?; +- write!(f, "int main(void) {{ return 0; }}")?; +- } +- +- Ok(src) +- } +- +- /// Run the compiler to test if it accepts the given flag. +- /// +- /// For a convenience method for setting flags conditionally, +- /// see `flag_if_supported()`. +- /// +- /// It may return error if it's unable to run the compiler with a test file +- /// (e.g. the compiler is missing or a write to the `out_dir` failed). +- /// +- /// Note: Once computed, the result of this call is stored in the +- /// `known_flag_support` field. If `is_flag_supported(flag)` +- /// is called again, the result will be read from the hash table. +- pub fn is_flag_supported(&self, flag: &str) -> Result { +- let mut known_status = self.known_flag_support_status.lock().unwrap(); +- if let Some(is_supported) = known_status.get(flag).cloned() { +- return Ok(is_supported); +- } +- +- let out_dir = self.get_out_dir()?; +- let src = self.ensure_check_file()?; +- let obj = out_dir.join("flag_check"); +- let target = self.get_target()?; +- let host = self.get_host()?; +- let mut cfg = Build::new(); +- cfg.flag(flag) +- .target(&target) +- .opt_level(0) +- .host(&host) +- .debug(false) +- .cpp(self.cpp) +- .cuda(self.cuda); +- let mut compiler = cfg.try_get_compiler()?; +- +- // Clang uses stderr for verbose output, which yields a false positive +- // result if the CFLAGS/CXXFLAGS include -v to aid in debugging. +- if compiler.family.verbose_stderr() { +- compiler.remove_arg("-v".into()); +- } +- +- let mut cmd = compiler.to_command(); +- let is_arm = target.contains("aarch64") || target.contains("arm"); +- let clang = compiler.family == ToolFamily::Clang; +- command_add_output_file( +- &mut cmd, +- &obj, +- self.cuda, +- target.contains("msvc"), +- clang, +- false, +- is_arm, +- ); +- +- // We need to explicitly tell msvc not to link and create an exe +- // in the root directory of the crate +- if target.contains("msvc") && !self.cuda { +- cmd.arg("-c"); +- } +- +- cmd.arg(&src); +- +- let output = cmd.output()?; +- let is_supported = output.stderr.is_empty(); +- +- known_status.insert(flag.to_owned(), is_supported); +- Ok(is_supported) +- } +- +- /// Add an arbitrary flag to the invocation of the compiler if it supports it +- /// +- /// # Example +- /// +- /// ```no_run +- /// cc::Build::new() +- /// .file("src/foo.c") +- /// .flag_if_supported("-Wlogical-op") // only supported by GCC +- /// .flag_if_supported("-Wunreachable-code") // only supported by clang +- /// .compile("foo"); +- /// ``` +- pub fn flag_if_supported(&mut self, flag: &str) -> &mut Build { +- self.flags_supported.push(flag.to_string()); +- self +- } +- +- /// Set the `-shared` flag. +- /// +- /// When enabled, the compiler will produce a shared object which can +- /// then be linked with other objects to form an executable. +- /// +- /// # Example +- /// +- /// ```no_run +- /// cc::Build::new() +- /// .file("src/foo.c") +- /// .shared_flag(true) +- /// .compile("libfoo.so"); +- /// ``` +- pub fn shared_flag(&mut self, shared_flag: bool) -> &mut Build { +- self.shared_flag = Some(shared_flag); +- self +- } +- +- /// Set the `-static` flag. +- /// +- /// When enabled on systems that support dynamic linking, this prevents +- /// linking with the shared libraries. +- /// +- /// # Example +- /// +- /// ```no_run +- /// cc::Build::new() +- /// .file("src/foo.c") +- /// .shared_flag(true) +- /// .static_flag(true) +- /// .compile("foo"); +- /// ``` +- pub fn static_flag(&mut self, static_flag: bool) -> &mut Build { +- self.static_flag = Some(static_flag); +- self +- } +- +- /// Disables the generation of default compiler flags. The default compiler +- /// flags may cause conflicts in some cross compiling scenarios. +- /// +- /// Setting the `CRATE_CC_NO_DEFAULTS` environment variable has the same +- /// effect as setting this to `true`. The presence of the environment +- /// variable and the value of `no_default_flags` will be OR'd together. +- pub fn no_default_flags(&mut self, no_default_flags: bool) -> &mut Build { +- self.no_default_flags = no_default_flags; +- self +- } +- +- /// Add a file which will be compiled +- pub fn file>(&mut self, p: P) -> &mut Build { +- self.files.push(p.as_ref().to_path_buf()); +- self +- } +- +- /// Add files which will be compiled +- pub fn files

(&mut self, p: P) -> &mut Build +- where +- P: IntoIterator, +- P::Item: AsRef, +- { +- for file in p.into_iter() { +- self.file(file); +- } +- self +- } +- +- /// Set C++ support. +- /// +- /// The other `cpp_*` options will only become active if this is set to +- /// `true`. +- pub fn cpp(&mut self, cpp: bool) -> &mut Build { +- self.cpp = cpp; +- self +- } +- +- /// Set CUDA C++ support. +- /// +- /// Enabling CUDA will pass the detected C/C++ toolchain as an argument to +- /// the CUDA compiler, NVCC. NVCC itself accepts some limited GNU-like args; +- /// any other arguments for the C/C++ toolchain will be redirected using +- /// "-Xcompiler" flags. +- /// +- /// If enabled, this also implicitly enables C++ support. +- pub fn cuda(&mut self, cuda: bool) -> &mut Build { +- self.cuda = cuda; +- if cuda { +- self.cpp = true; +- } +- self +- } +- +- /// Set warnings into errors flag. +- /// +- /// Disabled by default. +- /// +- /// Warning: turning warnings into errors only make sense +- /// if you are a developer of the crate using cc-rs. +- /// Some warnings only appear on some architecture or +- /// specific version of the compiler. Any user of this crate, +- /// or any other crate depending on it, could fail during +- /// compile time. +- /// +- /// # Example +- /// +- /// ```no_run +- /// cc::Build::new() +- /// .file("src/foo.c") +- /// .warnings_into_errors(true) +- /// .compile("libfoo.a"); +- /// ``` +- pub fn warnings_into_errors(&mut self, warnings_into_errors: bool) -> &mut Build { +- self.warnings_into_errors = warnings_into_errors; +- self +- } +- +- /// Set warnings flags. +- /// +- /// Adds some flags: +- /// - "-Wall" for MSVC. +- /// - "-Wall", "-Wextra" for GNU and Clang. +- /// +- /// Enabled by default. +- /// +- /// # Example +- /// +- /// ```no_run +- /// cc::Build::new() +- /// .file("src/foo.c") +- /// .warnings(false) +- /// .compile("libfoo.a"); +- /// ``` +- pub fn warnings(&mut self, warnings: bool) -> &mut Build { +- self.warnings = Some(warnings); +- self.extra_warnings = Some(warnings); +- self +- } +- +- /// Set extra warnings flags. +- /// +- /// Adds some flags: +- /// - nothing for MSVC. +- /// - "-Wextra" for GNU and Clang. +- /// +- /// Enabled by default. +- /// +- /// # Example +- /// +- /// ```no_run +- /// // Disables -Wextra, -Wall remains enabled: +- /// cc::Build::new() +- /// .file("src/foo.c") +- /// .extra_warnings(false) +- /// .compile("libfoo.a"); +- /// ``` +- pub fn extra_warnings(&mut self, warnings: bool) -> &mut Build { +- self.extra_warnings = Some(warnings); +- self +- } +- +- /// Set the standard library to link against when compiling with C++ +- /// support. +- /// +- /// See [`get_cpp_link_stdlib`](cc::Build::get_cpp_link_stdlib) documentation +- /// for the default value. +- /// If the `CXXSTDLIB` environment variable is set, its value will +- /// override the default value, but not the value explicitly set by calling +- /// this function. +- /// +- /// A value of `None` indicates that no automatic linking should happen, +- /// otherwise cargo will link against the specified library. +- /// +- /// The given library name must not contain the `lib` prefix. +- /// +- /// Common values: +- /// - `stdc++` for GNU +- /// - `c++` for Clang +- /// - `c++_shared` or `c++_static` for Android +- /// +- /// # Example +- /// +- /// ```no_run +- /// cc::Build::new() +- /// .file("src/foo.c") +- /// .shared_flag(true) +- /// .cpp_link_stdlib("stdc++") +- /// .compile("libfoo.so"); +- /// ``` +- pub fn cpp_link_stdlib<'a, V: Into>>( +- &mut self, +- cpp_link_stdlib: V, +- ) -> &mut Build { +- self.cpp_link_stdlib = Some(cpp_link_stdlib.into().map(|s| s.into())); +- self +- } +- +- /// Force the C++ compiler to use the specified standard library. +- /// +- /// Setting this option will automatically set `cpp_link_stdlib` to the same +- /// value. +- /// +- /// The default value of this option is always `None`. +- /// +- /// This option has no effect when compiling for a Visual Studio based +- /// target. +- /// +- /// This option sets the `-stdlib` flag, which is only supported by some +- /// compilers (clang, icc) but not by others (gcc). The library will not +- /// detect which compiler is used, as such it is the responsibility of the +- /// caller to ensure that this option is only used in conjuction with a +- /// compiler which supports the `-stdlib` flag. +- /// +- /// A value of `None` indicates that no specific C++ standard library should +- /// be used, otherwise `-stdlib` is added to the compile invocation. +- /// +- /// The given library name must not contain the `lib` prefix. +- /// +- /// Common values: +- /// - `stdc++` for GNU +- /// - `c++` for Clang +- /// +- /// # Example +- /// +- /// ```no_run +- /// cc::Build::new() +- /// .file("src/foo.c") +- /// .cpp_set_stdlib("c++") +- /// .compile("libfoo.a"); +- /// ``` +- pub fn cpp_set_stdlib<'a, V: Into>>( +- &mut self, +- cpp_set_stdlib: V, +- ) -> &mut Build { +- let cpp_set_stdlib = cpp_set_stdlib.into(); +- self.cpp_set_stdlib = cpp_set_stdlib.map(|s| s.into()); +- self.cpp_link_stdlib(cpp_set_stdlib); +- self +- } +- +- /// Configures the target this configuration will be compiling for. +- /// +- /// This option is automatically scraped from the `TARGET` environment +- /// variable by build scripts, so it's not required to call this function. +- /// +- /// # Example +- /// +- /// ```no_run +- /// cc::Build::new() +- /// .file("src/foo.c") +- /// .target("aarch64-linux-android") +- /// .compile("foo"); +- /// ``` +- pub fn target(&mut self, target: &str) -> &mut Build { +- self.target = Some(target.to_string()); +- self +- } +- +- /// Configures the host assumed by this configuration. +- /// +- /// This option is automatically scraped from the `HOST` environment +- /// variable by build scripts, so it's not required to call this function. +- /// +- /// # Example +- /// +- /// ```no_run +- /// cc::Build::new() +- /// .file("src/foo.c") +- /// .host("arm-linux-gnueabihf") +- /// .compile("foo"); +- /// ``` +- pub fn host(&mut self, host: &str) -> &mut Build { +- self.host = Some(host.to_string()); +- self +- } +- +- /// Configures the optimization level of the generated object files. +- /// +- /// This option is automatically scraped from the `OPT_LEVEL` environment +- /// variable by build scripts, so it's not required to call this function. +- pub fn opt_level(&mut self, opt_level: u32) -> &mut Build { +- self.opt_level = Some(opt_level.to_string()); +- self +- } +- +- /// Configures the optimization level of the generated object files. +- /// +- /// This option is automatically scraped from the `OPT_LEVEL` environment +- /// variable by build scripts, so it's not required to call this function. +- pub fn opt_level_str(&mut self, opt_level: &str) -> &mut Build { +- self.opt_level = Some(opt_level.to_string()); +- self +- } +- +- /// Configures whether the compiler will emit debug information when +- /// generating object files. +- /// +- /// This option is automatically scraped from the `DEBUG` environment +- /// variable by build scripts, so it's not required to call this function. +- pub fn debug(&mut self, debug: bool) -> &mut Build { +- self.debug = Some(debug); +- self +- } +- +- /// Configures whether the compiler will emit instructions to store +- /// frame pointers during codegen. +- /// +- /// This option is automatically enabled when debug information is emitted. +- /// Otherwise the target platform compiler's default will be used. +- /// You can use this option to force a specific setting. +- pub fn force_frame_pointer(&mut self, force: bool) -> &mut Build { +- self.force_frame_pointer = Some(force); +- self +- } +- +- /// Configures the output directory where all object files and static +- /// libraries will be located. +- /// +- /// This option is automatically scraped from the `OUT_DIR` environment +- /// variable by build scripts, so it's not required to call this function. +- pub fn out_dir>(&mut self, out_dir: P) -> &mut Build { +- self.out_dir = Some(out_dir.as_ref().to_owned()); +- self +- } +- +- /// Configures the compiler to be used to produce output. +- /// +- /// This option is automatically determined from the target platform or a +- /// number of environment variables, so it's not required to call this +- /// function. +- pub fn compiler>(&mut self, compiler: P) -> &mut Build { +- self.compiler = Some(compiler.as_ref().to_owned()); +- self +- } +- +- /// Configures the tool used to assemble archives. +- /// +- /// This option is automatically determined from the target platform or a +- /// number of environment variables, so it's not required to call this +- /// function. +- pub fn archiver>(&mut self, archiver: P) -> &mut Build { +- self.archiver = Some(archiver.as_ref().to_owned()); +- self +- } +- /// Define whether metadata should be emitted for cargo allowing it to +- /// automatically link the binary. Defaults to `true`. +- /// +- /// The emitted metadata is: +- /// +- /// - `rustc-link-lib=static=`*compiled lib* +- /// - `rustc-link-search=native=`*target folder* +- /// - When target is MSVC, the ATL-MFC libs are added via `rustc-link-search=native=` +- /// - When C++ is enabled, the C++ stdlib is added via `rustc-link-lib` +- /// +- pub fn cargo_metadata(&mut self, cargo_metadata: bool) -> &mut Build { +- self.cargo_metadata = cargo_metadata; +- self +- } +- +- /// Configures whether the compiler will emit position independent code. +- /// +- /// This option defaults to `false` for `windows-gnu` and bare metal targets and +- /// to `true` for all other targets. +- pub fn pic(&mut self, pic: bool) -> &mut Build { +- self.pic = Some(pic); +- self +- } +- +- /// Configures whether the Procedure Linkage Table is used for indirect +- /// calls into shared libraries. +- /// +- /// The PLT is used to provide features like lazy binding, but introduces +- /// a small performance loss due to extra pointer indirection. Setting +- /// `use_plt` to `false` can provide a small performance increase. +- /// +- /// Note that skipping the PLT requires a recent version of GCC/Clang. +- /// +- /// This only applies to ELF targets. It has no effect on other platforms. +- pub fn use_plt(&mut self, use_plt: bool) -> &mut Build { +- self.use_plt = Some(use_plt); +- self +- } +- +- /// Configures whether the /MT flag or the /MD flag will be passed to msvc build tools. +- /// +- /// This option defaults to `false`, and affect only msvc targets. +- pub fn static_crt(&mut self, static_crt: bool) -> &mut Build { +- self.static_crt = Some(static_crt); +- self +- } +- +- #[doc(hidden)] +- pub fn __set_env(&mut self, a: A, b: B) -> &mut Build +- where +- A: AsRef, +- B: AsRef, +- { +- self.env +- .push((a.as_ref().to_owned(), b.as_ref().to_owned())); +- self +- } +- +- /// Run the compiler, generating the file `output` +- /// +- /// This will return a result instead of panicing; see compile() for the complete description. +- pub fn try_compile(&self, output: &str) -> Result<(), Error> { +- let (lib_name, gnu_lib_name) = if output.starts_with("lib") && output.ends_with(".a") { +- (&output[3..output.len() - 2], output.to_owned()) +- } else { +- let mut gnu = String::with_capacity(5 + output.len()); +- gnu.push_str("lib"); +- gnu.push_str(&output); +- gnu.push_str(".a"); +- (output, gnu) +- }; +- let dst = self.get_out_dir()?; +- +- let mut objects = Vec::new(); +- for file in self.files.iter() { +- let obj = dst.join(file).with_extension("o"); +- let obj = if !obj.starts_with(&dst) { +- dst.join(obj.file_name().ok_or_else(|| { +- Error::new(ErrorKind::IOError, "Getting object file details failed.") +- })?) +- } else { +- obj +- }; +- +- match obj.parent() { +- Some(s) => fs::create_dir_all(s)?, +- None => { +- return Err(Error::new( +- ErrorKind::IOError, +- "Getting object file details failed.", +- )); +- } +- }; +- +- objects.push(Object::new(file.to_path_buf(), obj)); +- } +- self.compile_objects(&objects)?; +- self.assemble(lib_name, &dst.join(gnu_lib_name), &objects)?; +- +- if self.get_target()?.contains("msvc") { +- let compiler = self.get_base_compiler()?; +- let atlmfc_lib = compiler +- .env() +- .iter() +- .find(|&&(ref var, _)| var.as_os_str() == OsStr::new("LIB")) +- .and_then(|&(_, ref lib_paths)| { +- env::split_paths(lib_paths).find(|path| { +- let sub = Path::new("atlmfc/lib"); +- path.ends_with(sub) || path.parent().map_or(false, |p| p.ends_with(sub)) +- }) +- }); +- +- if let Some(atlmfc_lib) = atlmfc_lib { +- self.print(&format!( +- "cargo:rustc-link-search=native={}", +- atlmfc_lib.display() +- )); +- } +- } +- +- self.print(&format!("cargo:rustc-link-lib=static={}", lib_name)); +- self.print(&format!("cargo:rustc-link-search=native={}", dst.display())); +- +- // Add specific C++ libraries, if enabled. +- if self.cpp { +- if let Some(stdlib) = self.get_cpp_link_stdlib()? { +- self.print(&format!("cargo:rustc-link-lib={}", stdlib)); +- } +- } +- +- Ok(()) +- } +- +- /// Run the compiler, generating the file `output` +- /// +- /// The name `output` should be the name of the library. For backwards compatibility, +- /// the `output` may start with `lib` and end with `.a`. The Rust compiler will create +- /// the assembly with the lib prefix and .a extension. MSVC will create a file without prefix, +- /// ending with `.lib`. +- /// +- /// # Panics +- /// +- /// Panics if `output` is not formatted correctly or if one of the underlying +- /// compiler commands fails. It can also panic if it fails reading file names +- /// or creating directories. +- pub fn compile(&self, output: &str) { +- if let Err(e) = self.try_compile(output) { +- fail(&e.message); +- } +- } +- +- #[cfg(feature = "parallel")] +- fn compile_objects<'me>(&'me self, objs: &[Object]) -> Result<(), Error> { +- use std::sync::atomic::{AtomicBool, Ordering::SeqCst}; +- use std::sync::Once; +- +- // Limit our parallelism globally with a jobserver. Start off by +- // releasing our own token for this process so we can have a bit of an +- // easier to write loop below. If this fails, though, then we're likely +- // on Windows with the main implicit token, so we just have a bit extra +- // parallelism for a bit and don't reacquire later. +- let server = jobserver(); +- let reacquire = server.release_raw().is_ok(); +- +- // When compiling objects in parallel we do a few dirty tricks to speed +- // things up: +- // +- // * First is that we use the `jobserver` crate to limit the parallelism +- // of this build script. The `jobserver` crate will use a jobserver +- // configured by Cargo for build scripts to ensure that parallelism is +- // coordinated across C compilations and Rust compilations. Before we +- // compile anything we make sure to wait until we acquire a token. +- // +- // Note that this jobserver is cached globally so we only used one per +- // process and only worry about creating it once. +- // +- // * Next we use a raw `thread::spawn` per thread to actually compile +- // objects in parallel. We only actually spawn a thread after we've +- // acquired a token to perform some work +- // +- // * Finally though we want to keep the dependencies of this crate +- // pretty light, so we avoid using a safe abstraction like `rayon` and +- // instead rely on some bits of `unsafe` code. We know that this stack +- // frame persists while everything is compiling so we use all the +- // stack-allocated objects without cloning/reallocating. We use a +- // transmute to `State` with a `'static` lifetime to persist +- // everything we need across the boundary, and the join-on-drop +- // semantics of `JoinOnDrop` should ensure that our stack frame is +- // alive while threads are alive. +- // +- // With all that in mind we compile all objects in a loop here, after we +- // acquire the appropriate tokens, Once all objects have been compiled +- // we join on all the threads and propagate the results of compilation. +- // +- // Note that as a slight optimization we try to break out as soon as +- // possible as soon as any compilation fails to ensure that errors get +- // out to the user as fast as possible. +- let error = AtomicBool::new(false); +- let mut threads = Vec::new(); +- for obj in objs { +- if error.load(SeqCst) { +- break; +- } +- let token = server.acquire()?; +- let state = State { +- build: self, +- obj, +- error: &error, +- }; +- let state = unsafe { std::mem::transmute::>(state) }; +- let thread = thread::spawn(|| { +- let state: State<'me> = state; // erase the `'static` lifetime +- let result = state.build.compile_object(state.obj); +- if result.is_err() { +- state.error.store(true, SeqCst); +- } +- drop(token); // make sure our jobserver token is released after the compile +- return result; +- }); +- threads.push(JoinOnDrop(Some(thread))); +- } +- +- for mut thread in threads { +- if let Some(thread) = thread.0.take() { +- thread.join().expect("thread should not panic")?; +- } +- } +- +- // Reacquire our process's token before we proceed, which we released +- // before entering the loop above. +- if reacquire { +- server.acquire_raw()?; +- } +- +- return Ok(()); +- +- /// Shared state from the parent thread to the child thread. This +- /// package of pointers is temporarily transmuted to a `'static` +- /// lifetime to cross the thread boundary and then once the thread is +- /// running we erase the `'static` to go back to an anonymous lifetime. +- struct State<'a> { +- build: &'a Build, +- obj: &'a Object, +- error: &'a AtomicBool, +- } +- +- /// Returns a suitable `jobserver::Client` used to coordinate +- /// parallelism between build scripts. +- fn jobserver() -> &'static jobserver::Client { +- static INIT: Once = Once::new(); +- static mut JOBSERVER: Option = None; +- +- fn _assert_sync() {} +- _assert_sync::(); +- +- unsafe { +- INIT.call_once(|| { +- let server = default_jobserver(); +- JOBSERVER = Some(server); +- }); +- JOBSERVER.as_ref().unwrap() +- } +- } +- +- unsafe fn default_jobserver() -> jobserver::Client { +- // Try to use the environmental jobserver which Cargo typically +- // initializes for us... +- if let Some(client) = jobserver::Client::from_env() { +- return client; +- } +- +- // ... but if that fails for whatever reason select something +- // reasonable and crate a new jobserver. Use `NUM_JOBS` if set (it's +- // configured by Cargo) and otherwise just fall back to a +- // semi-reasonable number. Note that we could use `num_cpus` here +- // but it's an extra dependency that will almost never be used, so +- // it's generally not too worth it. +- let mut parallelism = 4; +- if let Ok(amt) = env::var("NUM_JOBS") { +- if let Ok(amt) = amt.parse() { +- parallelism = amt; +- } +- } +- +- // If we create our own jobserver then be sure to reserve one token +- // for ourselves. +- let client = jobserver::Client::new(parallelism).expect("failed to create jobserver"); +- client.acquire_raw().expect("failed to acquire initial"); +- return client; +- } +- +- struct JoinOnDrop(Option>>); +- +- impl Drop for JoinOnDrop { +- fn drop(&mut self) { +- if let Some(thread) = self.0.take() { +- drop(thread.join()); +- } +- } +- } +- } +- +- #[cfg(not(feature = "parallel"))] +- fn compile_objects(&self, objs: &[Object]) -> Result<(), Error> { +- for obj in objs { +- self.compile_object(obj)?; +- } +- Ok(()) +- } +- +- fn compile_object(&self, obj: &Object) -> Result<(), Error> { +- let is_asm = obj.src.extension().and_then(|s| s.to_str()) == Some("asm"); +- let target = self.get_target()?; +- let msvc = target.contains("msvc"); +- let compiler = self.try_get_compiler()?; +- let clang = compiler.family == ToolFamily::Clang; +- let (mut cmd, name) = if msvc && is_asm { +- self.msvc_macro_assembler()? +- } else { +- let mut cmd = compiler.to_command(); +- for &(ref a, ref b) in self.env.iter() { +- cmd.env(a, b); +- } +- ( +- cmd, +- compiler +- .path +- .file_name() +- .ok_or_else(|| Error::new(ErrorKind::IOError, "Failed to get compiler path."))? +- .to_string_lossy() +- .into_owned(), +- ) +- }; +- let is_arm = target.contains("aarch64") || target.contains("arm"); +- command_add_output_file(&mut cmd, &obj.dst, self.cuda, msvc, clang, is_asm, is_arm); +- // armasm and armasm64 don't requrie -c option +- if !msvc || !is_asm || !is_arm { +- cmd.arg("-c"); +- } +- cmd.arg(&obj.src); +- if cfg!(target_os = "macos") { +- self.fix_env_for_apple_os(&mut cmd)?; +- } +- +- run(&mut cmd, &name)?; +- Ok(()) +- } +- +- /// This will return a result instead of panicing; see expand() for the complete description. +- pub fn try_expand(&self) -> Result, Error> { +- let compiler = self.try_get_compiler()?; +- let mut cmd = compiler.to_command(); +- for &(ref a, ref b) in self.env.iter() { +- cmd.env(a, b); +- } +- cmd.arg("-E"); +- +- assert!( +- self.files.len() <= 1, +- "Expand may only be called for a single file" +- ); +- +- for file in self.files.iter() { +- cmd.arg(file); +- } +- +- let name = compiler +- .path +- .file_name() +- .ok_or_else(|| Error::new(ErrorKind::IOError, "Failed to get compiler path."))? +- .to_string_lossy() +- .into_owned(); +- +- Ok(run_output(&mut cmd, &name)?) +- } +- +- /// Run the compiler, returning the macro-expanded version of the input files. +- /// +- /// This is only relevant for C and C++ files. +- /// +- /// # Panics +- /// Panics if more than one file is present in the config, or if compiler +- /// path has an invalid file name. +- /// +- /// # Example +- /// ```no_run +- /// let out = cc::Build::new().file("src/foo.c").expand(); +- /// ``` +- pub fn expand(&self) -> Vec { +- match self.try_expand() { +- Err(e) => fail(&e.message), +- Ok(v) => v, +- } +- } +- +- /// Get the compiler that's in use for this configuration. +- /// +- /// This function will return a `Tool` which represents the culmination +- /// of this configuration at a snapshot in time. The returned compiler can +- /// be inspected (e.g. the path, arguments, environment) to forward along to +- /// other tools, or the `to_command` method can be used to invoke the +- /// compiler itself. +- /// +- /// This method will take into account all configuration such as debug +- /// information, optimization level, include directories, defines, etc. +- /// Additionally, the compiler binary in use follows the standard +- /// conventions for this path, e.g. looking at the explicitly set compiler, +- /// environment variables (a number of which are inspected here), and then +- /// falling back to the default configuration. +- /// +- /// # Panics +- /// +- /// Panics if an error occurred while determining the architecture. +- pub fn get_compiler(&self) -> Tool { +- match self.try_get_compiler() { +- Ok(tool) => tool, +- Err(e) => fail(&e.message), +- } +- } +- +- /// Get the compiler that's in use for this configuration. +- /// +- /// This will return a result instead of panicing; see get_compiler() for the complete description. +- pub fn try_get_compiler(&self) -> Result { +- let opt_level = self.get_opt_level()?; +- let target = self.get_target()?; +- +- let mut cmd = self.get_base_compiler()?; +- let envflags = self.envflags(if self.cpp { "CXXFLAGS" } else { "CFLAGS" }); +- +- // Disable default flag generation via `no_default_flags` or environment variable +- let no_defaults = self.no_default_flags || self.getenv("CRATE_CC_NO_DEFAULTS").is_some(); +- +- if !no_defaults { +- self.add_default_flags(&mut cmd, &target, &opt_level)?; +- } else { +- println!("Info: default compiler flags are disabled"); +- } +- +- for arg in envflags { +- cmd.push_cc_arg(arg.into()); +- } +- +- for directory in self.include_directories.iter() { +- cmd.args.push("-I".into()); +- cmd.args.push(directory.into()); +- } +- +- // If warnings and/or extra_warnings haven't been explicitly set, +- // then we set them only if the environment doesn't already have +- // CFLAGS/CXXFLAGS, since those variables presumably already contain +- // the desired set of warnings flags. +- +- if self +- .warnings +- .unwrap_or(if self.has_flags() { false } else { true }) +- { +- let wflags = cmd.family.warnings_flags().into(); +- cmd.push_cc_arg(wflags); +- } +- +- if self +- .extra_warnings +- .unwrap_or(if self.has_flags() { false } else { true }) +- { +- if let Some(wflags) = cmd.family.extra_warnings_flags() { +- cmd.push_cc_arg(wflags.into()); +- } +- } +- +- for flag in self.flags.iter() { +- cmd.args.push(flag.into()); +- } +- +- for flag in self.flags_supported.iter() { +- if self.is_flag_supported(flag).unwrap_or(false) { +- cmd.push_cc_arg(flag.into()); +- } +- } +- +- for &(ref key, ref value) in self.definitions.iter() { +- if let Some(ref value) = *value { +- cmd.args.push(format!("-D{}={}", key, value).into()); +- } else { +- cmd.args.push(format!("-D{}", key).into()); +- } +- } +- +- if self.warnings_into_errors { +- let warnings_to_errors_flag = cmd.family.warnings_to_errors_flag().into(); +- cmd.push_cc_arg(warnings_to_errors_flag); +- } +- +- Ok(cmd) +- } +- +- fn add_default_flags( +- &self, +- cmd: &mut Tool, +- target: &str, +- opt_level: &str, +- ) -> Result<(), Error> { +- // Non-target flags +- // If the flag is not conditioned on target variable, it belongs here :) +- match cmd.family { +- ToolFamily::Msvc { .. } => { +- cmd.push_cc_arg("-nologo".into()); +- +- let crt_flag = match self.static_crt { +- Some(true) => "-MT", +- Some(false) => "-MD", +- None => { +- let features = self +- .getenv("CARGO_CFG_TARGET_FEATURE") +- .unwrap_or(String::new()); +- if features.contains("crt-static") { +- "-MT" +- } else { +- "-MD" +- } +- } +- }; +- cmd.push_cc_arg(crt_flag.into()); +- +- match &opt_level[..] { +- // Msvc uses /O1 to enable all optimizations that minimize code size. +- "z" | "s" | "1" => cmd.push_opt_unless_duplicate("-O1".into()), +- // -O3 is a valid value for gcc and clang compilers, but not msvc. Cap to /O2. +- "2" | "3" => cmd.push_opt_unless_duplicate("-O2".into()), +- _ => {} +- } +- } +- ToolFamily::Gnu | ToolFamily::Clang => { +- // arm-linux-androideabi-gcc 4.8 shipped with Android NDK does +- // not support '-Oz' +- if opt_level == "z" && cmd.family != ToolFamily::Clang { +- cmd.push_opt_unless_duplicate("-Os".into()); +- } else { +- cmd.push_opt_unless_duplicate(format!("-O{}", opt_level).into()); +- } +- +- if cmd.family == ToolFamily::Clang && target.contains("android") { +- // For compatibility with code that doesn't use pre-defined `__ANDROID__` macro. +- // If compiler used via ndk-build or cmake (officially supported build methods) +- // this macros is defined. +- // See https://android.googlesource.com/platform/ndk/+/refs/heads/ndk-release-r21/build/cmake/android.toolchain.cmake#456 +- // https://android.googlesource.com/platform/ndk/+/refs/heads/ndk-release-r21/build/core/build-binary.mk#141 +- cmd.push_opt_unless_duplicate("-DANDROID".into()); +- } +- +- if !target.contains("apple-ios") { +- cmd.push_cc_arg("-ffunction-sections".into()); +- cmd.push_cc_arg("-fdata-sections".into()); +- } +- // Disable generation of PIC on bare-metal for now: rust-lld doesn't support this yet +- if self +- .pic +- .unwrap_or(!target.contains("windows") && !target.contains("-none-")) +- { +- cmd.push_cc_arg("-fPIC".into()); +- // PLT only applies if code is compiled with PIC support, +- // and only for ELF targets. +- if target.contains("linux") && !self.use_plt.unwrap_or(true) { +- cmd.push_cc_arg("-fno-plt".into()); +- } +- } +- } +- } +- +- if self.get_debug() { +- if self.cuda { +- // NVCC debug flag +- cmd.args.push("-G".into()); +- } +- let family = cmd.family; +- family.add_debug_flags(cmd); +- } +- +- if self.get_force_frame_pointer() { +- let family = cmd.family; +- family.add_force_frame_pointer(cmd); +- } +- +- // Target flags +- match cmd.family { +- ToolFamily::Clang => { +- if !(target.contains("android") +- && android_clang_compiler_uses_target_arg_internally(&cmd.path)) +- { +- if target.contains("darwin") { +- if let Some(arch) = +- map_darwin_target_from_rust_to_compiler_architecture(target) +- { +- cmd.args +- .push(format!("--target={}-apple-darwin", arch).into()); +- } +- } else if target.contains("macabi") { +- if let Some(arch) = +- map_darwin_target_from_rust_to_compiler_architecture(target) +- { +- let ios = if arch == "arm64" { "ios" } else { "ios13.0" }; +- cmd.args +- .push(format!("--target={}-apple-{}-macabi", arch, ios).into()); +- } +- } else if target.contains("ios-sim") { +- if let Some(arch) = +- map_darwin_target_from_rust_to_compiler_architecture(target) +- { +- let deployment_target = env::var("IPHONEOS_DEPLOYMENT_TARGET") +- .unwrap_or_else(|_| "7.0".into()); +- cmd.args.push( +- format!( +- "--target={}-apple-ios{}-simulator", +- arch, deployment_target +- ) +- .into(), +- ); +- } +- } else { +- cmd.args.push(format!("--target={}", target).into()); +- } +- } +- } +- ToolFamily::Msvc { clang_cl } => { +- // This is an undocumented flag from MSVC but helps with making +- // builds more reproducible by avoiding putting timestamps into +- // files. +- cmd.push_cc_arg("-Brepro".into()); +- +- if clang_cl { +- if target.contains("x86_64") { +- cmd.push_cc_arg("-m64".into()); +- } else if target.contains("86") { +- cmd.push_cc_arg("-m32".into()); +- cmd.push_cc_arg("-arch:IA32".into()); +- } else { +- cmd.push_cc_arg(format!("--target={}", target).into()); +- } +- } else { +- if target.contains("i586") { +- cmd.push_cc_arg("-arch:IA32".into()); +- } +- } +- +- // There is a check in corecrt.h that will generate a +- // compilation error if +- // _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE is +- // not defined to 1. The check was added in Windows +- // 8 days because only store apps were allowed on ARM. +- // This changed with the release of Windows 10 IoT Core. +- // The check will be going away in future versions of +- // the SDK, but for all released versions of the +- // Windows SDK it is required. +- if target.contains("arm") || target.contains("thumb") { +- cmd.args +- .push("-D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1".into()); +- } +- } +- ToolFamily::Gnu => { +- if target.contains("i686") || target.contains("i586") { +- cmd.args.push("-m32".into()); +- } else if target == "x86_64-unknown-linux-gnux32" { +- cmd.args.push("-mx32".into()); +- } else if target.contains("x86_64") || target.contains("powerpc64") { +- cmd.args.push("-m64".into()); +- } +- +- if target.contains("darwin") { +- if let Some(arch) = map_darwin_target_from_rust_to_compiler_architecture(target) +- { +- cmd.args.push("-arch".into()); +- cmd.args.push(arch.into()); +- } +- } +- +- if self.static_flag.is_none() { +- let features = self +- .getenv("CARGO_CFG_TARGET_FEATURE") +- .unwrap_or(String::new()); +- if features.contains("crt-static") { +- cmd.args.push("-static".into()); +- } +- } +- +- // armv7 targets get to use armv7 instructions +- if (target.starts_with("armv7") || target.starts_with("thumbv7")) +- && target.contains("-linux-") +- { +- cmd.args.push("-march=armv7-a".into()); +- } +- +- // (x86 Android doesn't say "eabi") +- if target.contains("-androideabi") && target.contains("v7") { +- // -march=armv7-a handled above +- cmd.args.push("-mthumb".into()); +- if !target.contains("neon") { +- // On android we can guarantee some extra float instructions +- // (specified in the android spec online) +- // NEON guarantees even more; see below. +- cmd.args.push("-mfpu=vfpv3-d16".into()); +- } +- cmd.args.push("-mfloat-abi=softfp".into()); +- } +- +- if target.contains("neon") { +- cmd.args.push("-mfpu=neon-vfpv4".into()); +- } +- +- if target.starts_with("armv4t-unknown-linux-") { +- cmd.args.push("-march=armv4t".into()); +- cmd.args.push("-marm".into()); +- cmd.args.push("-mfloat-abi=soft".into()); +- } +- +- if target.starts_with("armv5te-unknown-linux-") { +- cmd.args.push("-march=armv5te".into()); +- cmd.args.push("-marm".into()); +- cmd.args.push("-mfloat-abi=soft".into()); +- } +- +- // For us arm == armv6 by default +- if target.starts_with("arm-unknown-linux-") { +- cmd.args.push("-march=armv6".into()); +- cmd.args.push("-marm".into()); +- if target.ends_with("hf") { +- cmd.args.push("-mfpu=vfp".into()); +- } else { +- cmd.args.push("-mfloat-abi=soft".into()); +- } +- } +- +- // We can guarantee some settings for FRC +- if target.starts_with("arm-frc-") { +- cmd.args.push("-march=armv7-a".into()); +- cmd.args.push("-mcpu=cortex-a9".into()); +- cmd.args.push("-mfpu=vfpv3".into()); +- cmd.args.push("-mfloat-abi=softfp".into()); +- cmd.args.push("-marm".into()); +- } +- +- // Turn codegen down on i586 to avoid some instructions. +- if target.starts_with("i586-unknown-linux-") { +- cmd.args.push("-march=pentium".into()); +- } +- +- // Set codegen level for i686 correctly +- if target.starts_with("i686-unknown-linux-") { +- cmd.args.push("-march=i686".into()); +- } +- +- // Looks like `musl-gcc` makes it hard for `-m32` to make its way +- // all the way to the linker, so we need to actually instruct the +- // linker that we're generating 32-bit executables as well. This'll +- // typically only be used for build scripts which transitively use +- // these flags that try to compile executables. +- if target == "i686-unknown-linux-musl" || target == "i586-unknown-linux-musl" { +- cmd.args.push("-Wl,-melf_i386".into()); +- } +- +- if target.starts_with("thumb") { +- cmd.args.push("-mthumb".into()); +- +- if target.ends_with("eabihf") { +- cmd.args.push("-mfloat-abi=hard".into()) +- } +- } +- if target.starts_with("thumbv6m") { +- cmd.args.push("-march=armv6s-m".into()); +- } +- if target.starts_with("thumbv7em") { +- cmd.args.push("-march=armv7e-m".into()); +- +- if target.ends_with("eabihf") { +- cmd.args.push("-mfpu=fpv4-sp-d16".into()) +- } +- } +- if target.starts_with("thumbv7m") { +- cmd.args.push("-march=armv7-m".into()); +- } +- if target.starts_with("thumbv8m.base") { +- cmd.args.push("-march=armv8-m.base".into()); +- } +- if target.starts_with("thumbv8m.main") { +- cmd.args.push("-march=armv8-m.main".into()); +- +- if target.ends_with("eabihf") { +- cmd.args.push("-mfpu=fpv5-sp-d16".into()) +- } +- } +- if target.starts_with("armebv7r") | target.starts_with("armv7r") { +- if target.starts_with("armeb") { +- cmd.args.push("-mbig-endian".into()); +- } else { +- cmd.args.push("-mlittle-endian".into()); +- } +- +- // ARM mode +- cmd.args.push("-marm".into()); +- +- // R Profile +- cmd.args.push("-march=armv7-r".into()); +- +- if target.ends_with("eabihf") { +- // Calling convention +- cmd.args.push("-mfloat-abi=hard".into()); +- +- // lowest common denominator FPU +- // (see Cortex-R4 technical reference manual) +- cmd.args.push("-mfpu=vfpv3-d16".into()) +- } else { +- // Calling convention +- cmd.args.push("-mfloat-abi=soft".into()); +- } +- } +- if target.starts_with("armv7a") { +- cmd.args.push("-march=armv7-a".into()); +- +- if target.ends_with("eabihf") { +- // lowest common denominator FPU +- cmd.args.push("-mfpu=vfpv3-d16".into()); +- } +- } +- if target.starts_with("riscv32") || target.starts_with("riscv64") { +- // get the 32i/32imac/32imc/64gc/64imac/... part +- let mut parts = target.split('-'); +- if let Some(arch) = parts.next() { +- let arch = &arch[5..]; +- if target.contains("linux") && arch.starts_with("64") { +- cmd.args.push(("-march=rv64gc").into()); +- cmd.args.push("-mabi=lp64d".into()); +- } else if target.contains("linux") && arch.starts_with("32") { +- cmd.args.push(("-march=rv32gc").into()); +- cmd.args.push("-mabi=ilp32d".into()); +- } else if arch.starts_with("64") { +- cmd.args.push(("-march=rv".to_owned() + arch).into()); +- cmd.args.push("-mabi=lp64".into()); +- } else { +- cmd.args.push(("-march=rv".to_owned() + arch).into()); +- cmd.args.push("-mabi=ilp32".into()); +- } +- cmd.args.push("-mcmodel=medany".into()); +- } +- } +- } +- } +- +- if target.contains("apple-ios") { +- self.ios_flags(cmd)?; +- } +- +- if self.static_flag.unwrap_or(false) { +- cmd.args.push("-static".into()); +- } +- if self.shared_flag.unwrap_or(false) { +- cmd.args.push("-shared".into()); +- } +- +- if self.cpp { +- match (self.cpp_set_stdlib.as_ref(), cmd.family) { +- (None, _) => {} +- (Some(stdlib), ToolFamily::Gnu) | (Some(stdlib), ToolFamily::Clang) => { +- cmd.push_cc_arg(format!("-stdlib=lib{}", stdlib).into()); +- } +- _ => { +- println!( +- "cargo:warning=cpp_set_stdlib is specified, but the {:?} compiler \ +- does not support this option, ignored", +- cmd.family +- ); +- } +- } +- } +- +- Ok(()) +- } +- +- fn has_flags(&self) -> bool { +- let flags_env_var_name = if self.cpp { "CXXFLAGS" } else { "CFLAGS" }; +- let flags_env_var_value = self.get_var(flags_env_var_name); +- if let Ok(_) = flags_env_var_value { +- true +- } else { +- false +- } +- } +- +- fn msvc_macro_assembler(&self) -> Result<(Command, String), Error> { +- let target = self.get_target()?; +- let tool = if target.contains("x86_64") { +- "ml64.exe" +- } else if target.contains("arm") { +- "armasm.exe" +- } else if target.contains("aarch64") { +- "armasm64.exe" +- } else { +- "ml.exe" +- }; +- let mut cmd = windows_registry::find(&target, tool).unwrap_or_else(|| self.cmd(tool)); +- cmd.arg("-nologo"); // undocumented, yet working with armasm[64] +- for directory in self.include_directories.iter() { +- cmd.arg("-I").arg(directory); +- } +- if target.contains("aarch64") || target.contains("arm") { +- println!("cargo:warning=The MSVC ARM assemblers do not support -D flags"); +- } else { +- for &(ref key, ref value) in self.definitions.iter() { +- if let Some(ref value) = *value { +- cmd.arg(&format!("-D{}={}", key, value)); +- } else { +- cmd.arg(&format!("-D{}", key)); +- } +- } +- } +- +- if target.contains("i686") || target.contains("i586") { +- cmd.arg("-safeseh"); +- } +- for flag in self.flags.iter() { +- cmd.arg(flag); +- } +- +- Ok((cmd, tool.to_string())) +- } +- +- fn assemble(&self, lib_name: &str, dst: &Path, objs: &[Object]) -> Result<(), Error> { +- // Delete the destination if it exists as we want to +- // create on the first iteration instead of appending. +- let _ = fs::remove_file(&dst); +- +- // Add objects to the archive in limited-length batches. This helps keep +- // the length of the command line within a reasonable length to avoid +- // blowing system limits on limiting platforms like Windows. +- let objs: Vec<_> = objs +- .iter() +- .map(|o| o.dst.clone()) +- .chain(self.objects.clone()) +- .collect(); +- for chunk in objs.chunks(100) { +- self.assemble_progressive(dst, chunk)?; +- } +- +- let target = self.get_target()?; +- if target.contains("msvc") { +- // The Rust compiler will look for libfoo.a and foo.lib, but the +- // MSVC linker will also be passed foo.lib, so be sure that both +- // exist for now. +- +- let lib_dst = dst.with_file_name(format!("{}.lib", lib_name)); +- let _ = fs::remove_file(&lib_dst); +- match fs::hard_link(&dst, &lib_dst).or_else(|_| { +- // if hard-link fails, just copy (ignoring the number of bytes written) +- fs::copy(&dst, &lib_dst).map(|_| ()) +- }) { +- Ok(_) => (), +- Err(_) => { +- return Err(Error::new( +- ErrorKind::IOError, +- "Could not copy or create a hard-link to the generated lib file.", +- )); +- } +- }; +- } else { +- // Non-msvc targets (those using `ar`) need a separate step to add +- // the symbol table to archives since our construction command of +- // `cq` doesn't add it for us. +- let (mut ar, cmd) = self.get_ar()?; +- run(ar.arg("s").arg(dst), &cmd)?; +- } +- +- Ok(()) +- } +- +- fn assemble_progressive(&self, dst: &Path, objs: &[PathBuf]) -> Result<(), Error> { +- let target = self.get_target()?; +- +- if target.contains("msvc") { +- let (mut cmd, program) = self.get_ar()?; +- let mut out = OsString::from("-out:"); +- out.push(dst); +- cmd.arg(out).arg("-nologo"); +- for flag in self.ar_flags.iter() { +- cmd.arg(flag); +- } +- // If the library file already exists, add the libary name +- // as an argument to let lib.exe know we are appending the objs. +- if dst.exists() { +- cmd.arg(dst); +- } +- cmd.args(objs); +- run(&mut cmd, &program)?; +- } else { +- let (mut ar, cmd) = self.get_ar()?; +- +- // Set an environment variable to tell the OSX archiver to ensure +- // that all dates listed in the archive are zero, improving +- // determinism of builds. AFAIK there's not really official +- // documentation of this but there's a lot of references to it if +- // you search google. +- // +- // You can reproduce this locally on a mac with: +- // +- // $ touch foo.c +- // $ cc -c foo.c -o foo.o +- // +- // # Notice that these two checksums are different +- // $ ar crus libfoo1.a foo.o && sleep 2 && ar crus libfoo2.a foo.o +- // $ md5sum libfoo*.a +- // +- // # Notice that these two checksums are the same +- // $ export ZERO_AR_DATE=1 +- // $ ar crus libfoo1.a foo.o && sleep 2 && touch foo.o && ar crus libfoo2.a foo.o +- // $ md5sum libfoo*.a +- // +- // In any case if this doesn't end up getting read, it shouldn't +- // cause that many issues! +- ar.env("ZERO_AR_DATE", "1"); +- for flag in self.ar_flags.iter() { +- ar.arg(flag); +- } +- run(ar.arg("cq").arg(dst).args(objs), &cmd)?; +- } +- +- Ok(()) +- } +- +- fn ios_flags(&self, cmd: &mut Tool) -> Result<(), Error> { +- enum ArchSpec { +- Device(&'static str), +- Simulator(&'static str), +- Catalyst(&'static str), +- } +- +- let target = self.get_target()?; +- let arch = target.split('-').nth(0).ok_or_else(|| { +- Error::new( +- ErrorKind::ArchitectureInvalid, +- "Unknown architecture for iOS target.", +- ) +- })?; +- +- let is_catalyst = match target.split('-').nth(3) { +- Some(v) => v == "macabi", +- None => false, +- }; +- +- let arch = if is_catalyst { +- match arch { +- "arm64e" => ArchSpec::Catalyst("arm64e"), +- "arm64" | "aarch64" => ArchSpec::Catalyst("arm64"), +- "x86_64" => ArchSpec::Catalyst("-m64"), +- _ => { +- return Err(Error::new( +- ErrorKind::ArchitectureInvalid, +- "Unknown architecture for iOS target.", +- )); +- } +- } +- } else { +- match arch { +- "arm" | "armv7" | "thumbv7" => ArchSpec::Device("armv7"), +- "armv7s" | "thumbv7s" => ArchSpec::Device("armv7s"), +- "arm64e" => ArchSpec::Device("arm64e"), +- "arm64" | "aarch64" => ArchSpec::Device("arm64"), +- "i386" | "i686" => ArchSpec::Simulator("-m32"), +- "x86_64" => ArchSpec::Simulator("-m64"), +- _ => { +- return Err(Error::new( +- ErrorKind::ArchitectureInvalid, +- "Unknown architecture for iOS target.", +- )); +- } +- } +- }; +- +- let min_version = +- std::env::var("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "7.0".into()); +- +- let sdk = match arch { +- ArchSpec::Device(arch) => { +- cmd.args.push("-arch".into()); +- cmd.args.push(arch.into()); +- cmd.args +- .push(format!("-miphoneos-version-min={}", min_version).into()); +- "iphoneos" +- } +- ArchSpec::Simulator(arch) => { +- cmd.args.push(arch.into()); +- cmd.args +- .push(format!("-mios-simulator-version-min={}", min_version).into()); +- "iphonesimulator" +- } +- ArchSpec::Catalyst(_) => "macosx", +- }; +- +- self.print(&format!("Detecting iOS SDK path for {}", sdk)); +- let sdk_path = self.apple_sdk_root(sdk)?; +- cmd.args.push("-isysroot".into()); +- cmd.args.push(sdk_path); +- cmd.args.push("-fembed-bitcode".into()); +- /* +- * TODO we probably ultimately want the -fembed-bitcode-marker flag +- * but can't have it now because of an issue in LLVM: +- * https://github.com/alexcrichton/cc-rs/issues/301 +- * https://github.com/rust-lang/rust/pull/48896#comment-372192660 +- */ +- /* +- if self.get_opt_level()? == "0" { +- cmd.args.push("-fembed-bitcode-marker".into()); +- } +- */ +- +- Ok(()) +- } +- +- fn cmd>(&self, prog: P) -> Command { +- let mut cmd = Command::new(prog); +- for &(ref a, ref b) in self.env.iter() { +- cmd.env(a, b); +- } +- cmd +- } +- +- fn get_base_compiler(&self) -> Result { +- if let Some(ref c) = self.compiler { +- return Ok(Tool::new(c.clone())); +- } +- let host = self.get_host()?; +- let target = self.get_target()?; +- let (env, msvc, gnu, traditional, clang) = if self.cpp { +- ("CXX", "cl.exe", "g++", "c++", "clang++") +- } else { +- ("CC", "cl.exe", "gcc", "cc", "clang") +- }; +- +- // On historical Solaris systems, "cc" may have been Sun Studio, which +- // is not flag-compatible with "gcc". This history casts a long shadow, +- // and many modern illumos distributions today ship GCC as "gcc" without +- // also making it available as "cc". +- let default = if host.contains("solaris") || host.contains("illumos") { +- gnu +- } else { +- traditional +- }; +- +- let cl_exe = windows_registry::find_tool(&target, "cl.exe"); +- +- let tool_opt: Option = self +- .env_tool(env) +- .map(|(tool, wrapper, args)| { +- // find the driver mode, if any +- const DRIVER_MODE: &str = "--driver-mode="; +- let driver_mode = args +- .iter() +- .find(|a| a.starts_with(DRIVER_MODE)) +- .map(|a| &a[DRIVER_MODE.len()..]); +- // Chop off leading/trailing whitespace to work around +- // semi-buggy build scripts which are shared in +- // makefiles/configure scripts (where spaces are far more +- // lenient) +- let mut t = Tool::with_clang_driver(PathBuf::from(tool.trim()), driver_mode); +- if let Some(cc_wrapper) = wrapper { +- t.cc_wrapper_path = Some(PathBuf::from(cc_wrapper)); +- } +- for arg in args { +- t.cc_wrapper_args.push(arg.into()); +- } +- t +- }) +- .or_else(|| { +- if target.contains("emscripten") { +- let tool = if self.cpp { "em++" } else { "emcc" }; +- // Windows uses bat file so we have to be a bit more specific +- if cfg!(windows) { +- let mut t = Tool::new(PathBuf::from("cmd")); +- t.args.push("/c".into()); +- t.args.push(format!("{}.bat", tool).into()); +- Some(t) +- } else { +- Some(Tool::new(PathBuf::from(tool))) +- } +- } else { +- None +- } +- }) +- .or_else(|| cl_exe.clone()); +- +- let tool = match tool_opt { +- Some(t) => t, +- None => { +- let compiler = if host.contains("windows") && target.contains("windows") { +- if target.contains("msvc") { +- msvc.to_string() +- } else { +- format!("{}.exe", gnu) +- } +- } else if target.contains("apple-ios") { +- clang.to_string() +- } else if target.contains("android") { +- autodetect_android_compiler(&target, &host, gnu, clang) +- } else if target.contains("cloudabi") { +- format!("{}-{}", target, traditional) +- } else if target == "wasm32-wasi" +- || target == "wasm32-unknown-wasi" +- || target == "wasm32-unknown-unknown" +- { +- "clang".to_string() +- } else if target.contains("vxworks") { +- if self.cpp { +- "wr-c++".to_string() +- } else { +- "wr-cc".to_string() +- } +- } else if self.get_host()? != target { +- let prefix = self.prefix_for_target(&target); +- match prefix { +- Some(prefix) => format!("{}-{}", prefix, gnu), +- None => default.to_string(), +- } +- } else { +- default.to_string() +- }; +- +- let mut t = Tool::new(PathBuf::from(compiler)); +- if let Some(cc_wrapper) = Self::rustc_wrapper_fallback() { +- t.cc_wrapper_path = Some(PathBuf::from(cc_wrapper)); +- } +- t +- } +- }; +- +- let mut tool = if self.cuda { +- assert!( +- tool.args.is_empty(), +- "CUDA compilation currently assumes empty pre-existing args" +- ); +- let nvcc = match self.get_var("NVCC") { +- Err(_) => "nvcc".into(), +- Ok(nvcc) => nvcc, +- }; +- let mut nvcc_tool = Tool::with_features(PathBuf::from(nvcc), None, self.cuda); +- nvcc_tool +- .args +- .push(format!("-ccbin={}", tool.path.display()).into()); +- nvcc_tool.family = tool.family; +- nvcc_tool +- } else { +- tool +- }; +- +- // New "standalone" C/C++ cross-compiler executables from recent Android NDK +- // are just shell scripts that call main clang binary (from Android NDK) with +- // proper `--target` argument. +- // +- // For example, armv7a-linux-androideabi16-clang passes +- // `--target=armv7a-linux-androideabi16` to clang. +- // +- // As the shell script calls the main clang binary, the command line limit length +- // on Windows is restricted to around 8k characters instead of around 32k characters. +- // To remove this limit, we call the main clang binary directly and contruct the +- // `--target=` ourselves. +- if host.contains("windows") && android_clang_compiler_uses_target_arg_internally(&tool.path) +- { +- if let Some(path) = tool.path.file_name() { +- let file_name = path.to_str().unwrap().to_owned(); +- let (target, clang) = file_name.split_at(file_name.rfind("-").unwrap()); +- +- tool.path.set_file_name(clang.trim_start_matches("-")); +- tool.path.set_extension("exe"); +- tool.args.push(format!("--target={}", target).into()); +- +- // Additionally, shell scripts for target i686-linux-android versions 16 to 24 +- // pass the `mstackrealign` option so we do that here as well. +- if target.contains("i686-linux-android") { +- let (_, version) = target.split_at(target.rfind("d").unwrap() + 1); +- if let Ok(version) = version.parse::() { +- if version > 15 && version < 25 { +- tool.args.push("-mstackrealign".into()); +- } +- } +- } +- }; +- } +- +- // If we found `cl.exe` in our environment, the tool we're returning is +- // an MSVC-like tool, *and* no env vars were set then set env vars for +- // the tool that we're returning. +- // +- // Env vars are needed for things like `link.exe` being put into PATH as +- // well as header include paths sometimes. These paths are automatically +- // included by default but if the `CC` or `CXX` env vars are set these +- // won't be used. This'll ensure that when the env vars are used to +- // configure for invocations like `clang-cl` we still get a "works out +- // of the box" experience. +- if let Some(cl_exe) = cl_exe { +- if tool.family == (ToolFamily::Msvc { clang_cl: true }) +- && tool.env.len() == 0 +- && target.contains("msvc") +- { +- for &(ref k, ref v) in cl_exe.env.iter() { +- tool.env.push((k.to_owned(), v.to_owned())); +- } +- } +- } +- +- Ok(tool) +- } +- +- fn get_var(&self, var_base: &str) -> Result { +- let target = self.get_target()?; +- let host = self.get_host()?; +- let kind = if host == target { "HOST" } else { "TARGET" }; +- let target_u = target.replace("-", "_"); +- let res = self +- .getenv(&format!("{}_{}", var_base, target)) +- .or_else(|| self.getenv(&format!("{}_{}", var_base, target_u))) +- .or_else(|| self.getenv(&format!("{}_{}", kind, var_base))) +- .or_else(|| self.getenv(var_base)); +- +- match res { +- Some(res) => Ok(res), +- None => Err(Error::new( +- ErrorKind::EnvVarNotFound, +- &format!("Could not find environment variable {}.", var_base), +- )), +- } +- } +- +- fn envflags(&self, name: &str) -> Vec { +- self.get_var(name) +- .unwrap_or(String::new()) +- .split_ascii_whitespace() +- .map(|slice| slice.to_string()) +- .collect() +- } +- +- /// Returns a fallback `cc_compiler_wrapper` by introspecting `RUSTC_WRAPPER` +- fn rustc_wrapper_fallback() -> Option { +- // No explicit CC wrapper was detected, but check if RUSTC_WRAPPER +- // is defined and is a build accelerator that is compatible with +- // C/C++ compilers (e.g. sccache) +- let valid_wrappers = ["sccache"]; +- +- let rustc_wrapper = std::env::var_os("RUSTC_WRAPPER")?; +- let wrapper_path = Path::new(&rustc_wrapper); +- let wrapper_stem = wrapper_path.file_stem()?; +- +- if valid_wrappers.contains(&wrapper_stem.to_str()?) { +- Some(rustc_wrapper.to_str()?.to_owned()) +- } else { +- None +- } +- } +- +- /// Returns compiler path, optional modifier name from whitelist, and arguments vec +- fn env_tool(&self, name: &str) -> Option<(String, Option, Vec)> { +- let tool = match self.get_var(name) { +- Ok(tool) => tool, +- Err(_) => return None, +- }; +- +- // If this is an exact path on the filesystem we don't want to do any +- // interpretation at all, just pass it on through. This'll hopefully get +- // us to support spaces-in-paths. +- if Path::new(&tool).exists() { +- return Some((tool, None, Vec::new())); +- } +- +- // Ok now we want to handle a couple of scenarios. We'll assume from +- // here on out that spaces are splitting separate arguments. Two major +- // features we want to support are: +- // +- // CC='sccache cc' +- // +- // aka using `sccache` or any other wrapper/caching-like-thing for +- // compilations. We want to know what the actual compiler is still, +- // though, because our `Tool` API support introspection of it to see +- // what compiler is in use. +- // +- // additionally we want to support +- // +- // CC='cc -flag' +- // +- // where the CC env var is used to also pass default flags to the C +- // compiler. +- // +- // It's true that everything here is a bit of a pain, but apparently if +- // you're not literally make or bash then you get a lot of bug reports. +- let known_wrappers = ["ccache", "distcc", "sccache", "icecc"]; +- +- let mut parts = tool.split_whitespace(); +- let maybe_wrapper = match parts.next() { +- Some(s) => s, +- None => return None, +- }; +- +- let file_stem = Path::new(maybe_wrapper) +- .file_stem() +- .unwrap() +- .to_str() +- .unwrap(); +- if known_wrappers.contains(&file_stem) { +- if let Some(compiler) = parts.next() { +- return Some(( +- compiler.to_string(), +- Some(maybe_wrapper.to_string()), +- parts.map(|s| s.to_string()).collect(), +- )); +- } +- } +- +- Some(( +- maybe_wrapper.to_string(), +- Self::rustc_wrapper_fallback(), +- parts.map(|s| s.to_string()).collect(), +- )) +- } +- +- /// Returns the C++ standard library: +- /// 1. If [cpp_link_stdlib](cc::Build::cpp_link_stdlib) is set, uses its value. +- /// 2. Else if the `CXXSTDLIB` environment variable is set, uses its value. +- /// 3. Else the default is `libc++` for OS X and BSDs, `libc++_shared` for Android, +- /// `None` for MSVC and `libstdc++` for anything else. +- fn get_cpp_link_stdlib(&self) -> Result, Error> { +- match self.cpp_link_stdlib.clone() { +- Some(s) => Ok(s), +- None => { +- if let Ok(stdlib) = self.get_var("CXXSTDLIB") { +- if stdlib.is_empty() { +- Ok(None) +- } else { +- Ok(Some(stdlib)) +- } +- } else { +- let target = self.get_target()?; +- if target.contains("msvc") { +- Ok(None) +- } else if target.contains("apple") { +- Ok(Some("c++".to_string())) +- } else if target.contains("freebsd") { +- Ok(Some("c++".to_string())) +- } else if target.contains("openbsd") { +- Ok(Some("c++".to_string())) +- } else if target.contains("android") { +- Ok(Some("c++_shared".to_string())) +- } else { +- Ok(Some("stdc++".to_string())) +- } +- } +- } +- } +- } +- +- fn get_ar(&self) -> Result<(Command, String), Error> { +- if let Some(ref p) = self.archiver { +- let name = p.file_name().and_then(|s| s.to_str()).unwrap_or("ar"); +- return Ok((self.cmd(p), name.to_string())); +- } +- if let Ok(p) = self.get_var("AR") { +- return Ok((self.cmd(&p), p)); +- } +- let target = self.get_target()?; +- let default_ar = "ar".to_string(); +- let program = if target.contains("android") { +- format!("{}-ar", target.replace("armv7", "arm")) +- } else if target.contains("emscripten") { +- // Windows use bat files so we have to be a bit more specific +- if cfg!(windows) { +- let mut cmd = self.cmd("cmd"); +- cmd.arg("/c").arg("emar.bat"); +- return Ok((cmd, "emar.bat".to_string())); +- } +- +- "emar".to_string() +- } else if target.contains("msvc") { +- match windows_registry::find(&target, "lib.exe") { +- Some(t) => return Ok((t, "lib.exe".to_string())), +- None => "lib.exe".to_string(), +- } +- } else if target.contains("illumos") { +- // The default 'ar' on illumos uses a non-standard flags, +- // but the OS comes bundled with a GNU-compatible variant. +- // +- // Use the GNU-variant to match other Unix systems. +- "gar".to_string() +- } else if self.get_host()? != target { +- match self.prefix_for_target(&target) { +- Some(p) => { +- let target_ar = format!("{}-ar", p); +- if Command::new(&target_ar).output().is_ok() { +- target_ar +- } else { +- default_ar +- } +- } +- None => default_ar, +- } +- } else { +- default_ar +- }; +- Ok((self.cmd(&program), program)) +- } +- +- fn prefix_for_target(&self, target: &str) -> Option { +- // CROSS_COMPILE is of the form: "arm-linux-gnueabi-" +- let cc_env = self.getenv("CROSS_COMPILE"); +- let cross_compile = cc_env +- .as_ref() +- .map(|s| s.trim_right_matches('-').to_owned()); +- cross_compile.or(match &target[..] { +- "aarch64-unknown-linux-gnu" => Some("aarch64-linux-gnu"), +- "aarch64-unknown-linux-musl" => Some("aarch64-linux-musl"), +- "aarch64-unknown-netbsd" => Some("aarch64--netbsd"), +- "arm-unknown-linux-gnueabi" => Some("arm-linux-gnueabi"), +- "armv4t-unknown-linux-gnueabi" => Some("arm-linux-gnueabi"), +- "armv5te-unknown-linux-gnueabi" => Some("arm-linux-gnueabi"), +- "armv5te-unknown-linux-musleabi" => Some("arm-linux-gnueabi"), +- "arm-frc-linux-gnueabi" => Some("arm-frc-linux-gnueabi"), +- "arm-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"), +- "arm-unknown-linux-musleabi" => Some("arm-linux-musleabi"), +- "arm-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"), +- "arm-unknown-netbsd-eabi" => Some("arm--netbsdelf-eabi"), +- "armv6-unknown-netbsd-eabihf" => Some("armv6--netbsdelf-eabihf"), +- "armv7-unknown-linux-gnueabi" => Some("arm-linux-gnueabi"), +- "armv7-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"), +- "armv7-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"), +- "armv7neon-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"), +- "armv7neon-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"), +- "thumbv7-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"), +- "thumbv7-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"), +- "thumbv7neon-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"), +- "thumbv7neon-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"), +- "armv7-unknown-netbsd-eabihf" => Some("armv7--netbsdelf-eabihf"), +- "hexagon-unknown-linux-musl" => Some("hexagon-linux-musl"), +- "i586-unknown-linux-musl" => Some("musl"), +- "i686-pc-windows-gnu" => Some("i686-w64-mingw32"), +- "i686-uwp-windows-gnu" => Some("i686-w64-mingw32"), +- "i686-unknown-linux-musl" => Some("musl"), +- "i686-unknown-netbsd" => Some("i486--netbsdelf"), +- "mips-unknown-linux-gnu" => Some("mips-linux-gnu"), +- "mips-unknown-linux-musl" => Some("mips-linux-musl"), +- "mipsel-unknown-linux-gnu" => Some("mipsel-linux-gnu"), +- "mipsel-unknown-linux-musl" => Some("mipsel-linux-musl"), +- "mips64-unknown-linux-gnuabi64" => Some("mips64-linux-gnuabi64"), +- "mips64el-unknown-linux-gnuabi64" => Some("mips64el-linux-gnuabi64"), +- "mipsisa32r6-unknown-linux-gnu" => Some("mipsisa32r6-linux-gnu"), +- "mipsisa32r6el-unknown-linux-gnu" => Some("mipsisa32r6el-linux-gnu"), +- "mipsisa64r6-unknown-linux-gnuabi64" => Some("mipsisa64r6-linux-gnuabi64"), +- "mipsisa64r6el-unknown-linux-gnuabi64" => Some("mipsisa64r6el-linux-gnuabi64"), +- "powerpc-unknown-linux-gnu" => Some("powerpc-linux-gnu"), +- "powerpc-unknown-linux-gnuspe" => Some("powerpc-linux-gnuspe"), +- "powerpc-unknown-netbsd" => Some("powerpc--netbsd"), +- "powerpc64-unknown-linux-gnu" => Some("powerpc-linux-gnu"), +- "powerpc64le-unknown-linux-gnu" => Some("powerpc64le-linux-gnu"), +- "riscv32i-unknown-none-elf" => self.find_working_gnu_prefix(&[ +- "riscv32-unknown-elf", +- "riscv64-unknown-elf", +- "riscv-none-embed", +- ]), +- "riscv32imac-unknown-none-elf" => self.find_working_gnu_prefix(&[ +- "riscv32-unknown-elf", +- "riscv64-unknown-elf", +- "riscv-none-embed", +- ]), +- "riscv32imc-unknown-none-elf" => self.find_working_gnu_prefix(&[ +- "riscv32-unknown-elf", +- "riscv64-unknown-elf", +- "riscv-none-embed", +- ]), +- "riscv64gc-unknown-none-elf" => self.find_working_gnu_prefix(&[ +- "riscv64-unknown-elf", +- "riscv32-unknown-elf", +- "riscv-none-embed", +- ]), +- "riscv64imac-unknown-none-elf" => self.find_working_gnu_prefix(&[ +- "riscv64-unknown-elf", +- "riscv32-unknown-elf", +- "riscv-none-embed", +- ]), +- "riscv64gc-unknown-linux-gnu" => Some("riscv64-linux-gnu"), +- "riscv32gc-unknown-linux-gnu" => Some("riscv32-linux-gnu"), +- "riscv64gc-unknown-linux-musl" => Some("riscv64-linux-musl"), +- "riscv32gc-unknown-linux-musl" => Some("riscv32-linux-musl"), +- "s390x-unknown-linux-gnu" => Some("s390x-linux-gnu"), +- "sparc-unknown-linux-gnu" => Some("sparc-linux-gnu"), +- "sparc64-unknown-linux-gnu" => Some("sparc64-linux-gnu"), +- "sparc64-unknown-netbsd" => Some("sparc64--netbsd"), +- "sparcv9-sun-solaris" => Some("sparcv9-sun-solaris"), +- "armv7a-none-eabi" => Some("arm-none-eabi"), +- "armv7a-none-eabihf" => Some("arm-none-eabi"), +- "armebv7r-none-eabi" => Some("arm-none-eabi"), +- "armebv7r-none-eabihf" => Some("arm-none-eabi"), +- "armv7r-none-eabi" => Some("arm-none-eabi"), +- "armv7r-none-eabihf" => Some("arm-none-eabi"), +- "thumbv6m-none-eabi" => Some("arm-none-eabi"), +- "thumbv7em-none-eabi" => Some("arm-none-eabi"), +- "thumbv7em-none-eabihf" => Some("arm-none-eabi"), +- "thumbv7m-none-eabi" => Some("arm-none-eabi"), +- "thumbv8m.base-none-eabi" => Some("arm-none-eabi"), +- "thumbv8m.main-none-eabi" => Some("arm-none-eabi"), +- "thumbv8m.main-none-eabihf" => Some("arm-none-eabi"), +- "x86_64-pc-windows-gnu" => Some("x86_64-w64-mingw32"), +- "x86_64-uwp-windows-gnu" => Some("x86_64-w64-mingw32"), +- "x86_64-rumprun-netbsd" => Some("x86_64-rumprun-netbsd"), +- "x86_64-unknown-linux-musl" => Some("musl"), +- "x86_64-unknown-netbsd" => Some("x86_64--netbsd"), +- _ => None, +- } +- .map(|x| x.to_owned())) +- } +- +- /// Some platforms have multiple, compatible, canonical prefixes. Look through +- /// each possible prefix for a compiler that exists and return it. The prefixes +- /// should be ordered from most-likely to least-likely. +- fn find_working_gnu_prefix(&self, prefixes: &[&'static str]) -> Option<&'static str> { +- let suffix = if self.cpp { "-g++" } else { "-gcc" }; +- let extension = std::env::consts::EXE_SUFFIX; +- +- // Loop through PATH entries searching for each toolchain. This ensures that we +- // are more likely to discover the toolchain early on, because chances are good +- // that the desired toolchain is in one of the higher-priority paths. +- env::var_os("PATH") +- .as_ref() +- .and_then(|path_entries| { +- env::split_paths(path_entries).find_map(|path_entry| { +- for prefix in prefixes { +- let target_compiler = format!("{}{}{}", prefix, suffix, extension); +- if path_entry.join(&target_compiler).exists() { +- return Some(prefix); +- } +- } +- None +- }) +- }) +- .map(|prefix| *prefix) +- .or_else(|| +- // If no toolchain was found, provide the first toolchain that was passed in. +- // This toolchain has been shown not to exist, however it will appear in the +- // error that is shown to the user which should make it easier to search for +- // where it should be obtained. +- prefixes.first().map(|prefix| *prefix)) +- } +- +- fn get_target(&self) -> Result { +- match self.target.clone() { +- Some(t) => Ok(t), +- None => Ok(self.getenv_unwrap("TARGET")?), +- } +- } +- +- fn get_host(&self) -> Result { +- match self.host.clone() { +- Some(h) => Ok(h), +- None => Ok(self.getenv_unwrap("HOST")?), +- } +- } +- +- fn get_opt_level(&self) -> Result { +- match self.opt_level.as_ref().cloned() { +- Some(ol) => Ok(ol), +- None => Ok(self.getenv_unwrap("OPT_LEVEL")?), +- } +- } +- +- fn get_debug(&self) -> bool { +- self.debug.unwrap_or_else(|| match self.getenv("DEBUG") { +- Some(s) => s != "false", +- None => false, +- }) +- } +- +- fn get_force_frame_pointer(&self) -> bool { +- self.force_frame_pointer.unwrap_or_else(|| self.get_debug()) +- } +- +- fn get_out_dir(&self) -> Result { +- match self.out_dir.clone() { +- Some(p) => Ok(p), +- None => Ok(env::var_os("OUT_DIR").map(PathBuf::from).ok_or_else(|| { +- Error::new( +- ErrorKind::EnvVarNotFound, +- "Environment variable OUT_DIR not defined.", +- ) +- })?), +- } +- } +- +- fn getenv(&self, v: &str) -> Option { +- let mut cache = self.env_cache.lock().unwrap(); +- if let Some(val) = cache.get(v) { +- return val.clone(); +- } +- let r = env::var(v).ok(); +- self.print(&format!("{} = {:?}", v, r)); +- cache.insert(v.to_string(), r.clone()); +- r +- } +- +- fn getenv_unwrap(&self, v: &str) -> Result { +- match self.getenv(v) { +- Some(s) => Ok(s), +- None => Err(Error::new( +- ErrorKind::EnvVarNotFound, +- &format!("Environment variable {} not defined.", v.to_string()), +- )), +- } +- } +- +- fn print(&self, s: &str) { +- if self.cargo_metadata { +- println!("{}", s); +- } +- } +- +- fn fix_env_for_apple_os(&self, cmd: &mut Command) -> Result<(), Error> { +- let target = self.get_target()?; +- let host = self.get_host()?; +- if host.contains("apple-darwin") && target.contains("apple-darwin") { +- // If, for example, `cargo` runs during the build of an XCode project, then `SDKROOT` environment variable +- // would represent the current target, and this is the problem for us, if we want to compile something +- // for the host, when host != target. +- // We can not just remove `SDKROOT`, because, again, for example, XCode add to PATH +- // /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin +- // and `cc` from this path can not find system include files, like `pthread.h`, if `SDKROOT` +- // is not set +- if let Ok(sdkroot) = env::var("SDKROOT") { +- if !sdkroot.contains("MacOSX") { +- let macos_sdk = self.apple_sdk_root("macosx")?; +- cmd.env("SDKROOT", macos_sdk); +- } +- } +- // Additionally, `IPHONEOS_DEPLOYMENT_TARGET` must not be set when using the Xcode linker at +- // "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld", +- // although this is apparently ignored when using the linker at "/usr/bin/ld". +- cmd.env_remove("IPHONEOS_DEPLOYMENT_TARGET"); +- } +- Ok(()) +- } +- +- fn apple_sdk_root(&self, sdk: &str) -> Result { +- let mut cache = self +- .apple_sdk_root_cache +- .lock() +- .expect("apple_sdk_root_cache lock failed"); +- if let Some(ret) = cache.get(sdk) { +- return Ok(ret.clone()); +- } +- +- let sdk_path = run_output( +- self.cmd("xcrun") +- .arg("--show-sdk-path") +- .arg("--sdk") +- .arg(sdk), +- "xcrun", +- )?; +- +- let sdk_path = match String::from_utf8(sdk_path) { +- Ok(p) => p, +- Err(_) => { +- return Err(Error::new( +- ErrorKind::IOError, +- "Unable to determine iOS SDK path.", +- )); +- } +- }; +- let ret: OsString = sdk_path.trim().into(); +- cache.insert(sdk.into(), ret.clone()); +- Ok(ret) +- } +-} +- +-impl Default for Build { +- fn default() -> Build { +- Build::new() +- } +-} +- +-impl Tool { +- fn new(path: PathBuf) -> Self { +- Tool::with_features(path, None, false) +- } +- +- fn with_clang_driver(path: PathBuf, clang_driver: Option<&str>) -> Self { +- Self::with_features(path, clang_driver, false) +- } +- +- #[cfg(windows)] +- /// Explictly set the `ToolFamily`, skipping name-based detection. +- fn with_family(path: PathBuf, family: ToolFamily) -> Self { +- Self { +- path: path, +- cc_wrapper_path: None, +- cc_wrapper_args: Vec::new(), +- args: Vec::new(), +- env: Vec::new(), +- family: family, +- cuda: false, +- removed_args: Vec::new(), +- } +- } +- +- fn with_features(path: PathBuf, clang_driver: Option<&str>, cuda: bool) -> Self { +- // Try to detect family of the tool from its name, falling back to Gnu. +- let family = if let Some(fname) = path.file_name().and_then(|p| p.to_str()) { +- if fname.contains("clang-cl") { +- ToolFamily::Msvc { clang_cl: true } +- } else if fname.ends_with("cl") || fname == "cl.exe" { +- ToolFamily::Msvc { clang_cl: false } +- } else if fname.contains("clang") { +- match clang_driver { +- Some("cl") => ToolFamily::Msvc { clang_cl: true }, +- _ => ToolFamily::Clang, +- } +- } else { +- ToolFamily::Gnu +- } +- } else { +- ToolFamily::Gnu +- }; +- +- Tool { +- path: path, +- cc_wrapper_path: None, +- cc_wrapper_args: Vec::new(), +- args: Vec::new(), +- env: Vec::new(), +- family: family, +- cuda: cuda, +- removed_args: Vec::new(), +- } +- } +- +- /// Add an argument to be stripped from the final command arguments. +- fn remove_arg(&mut self, flag: OsString) { +- self.removed_args.push(flag); +- } +- +- /// Add a flag, and optionally prepend the NVCC wrapper flag "-Xcompiler". +- /// +- /// Currently this is only used for compiling CUDA sources, since NVCC only +- /// accepts a limited set of GNU-like flags, and the rest must be prefixed +- /// with a "-Xcompiler" flag to get passed to the underlying C++ compiler. +- fn push_cc_arg(&mut self, flag: OsString) { +- if self.cuda { +- self.args.push("-Xcompiler".into()); +- } +- self.args.push(flag); +- } +- +- fn is_duplicate_opt_arg(&self, flag: &OsString) -> bool { +- let flag = flag.to_str().unwrap(); +- let mut chars = flag.chars(); +- +- // Only duplicate check compiler flags +- if self.is_like_msvc() { +- if chars.next() != Some('/') { +- return false; +- } +- } else if self.is_like_gnu() || self.is_like_clang() { +- if chars.next() != Some('-') { +- return false; +- } +- } +- +- // Check for existing optimization flags (-O, /O) +- if chars.next() == Some('O') { +- return self +- .args() +- .iter() +- .any(|ref a| a.to_str().unwrap_or("").chars().nth(1) == Some('O')); +- } +- +- // TODO Check for existing -m..., -m...=..., /arch:... flags +- return false; +- } +- +- /// Don't push optimization arg if it conflicts with existing args +- fn push_opt_unless_duplicate(&mut self, flag: OsString) { +- if self.is_duplicate_opt_arg(&flag) { +- println!("Info: Ignoring duplicate arg {:?}", &flag); +- } else { +- self.push_cc_arg(flag); +- } +- } +- +- /// Converts this compiler into a `Command` that's ready to be run. +- /// +- /// This is useful for when the compiler needs to be executed and the +- /// command returned will already have the initial arguments and environment +- /// variables configured. +- pub fn to_command(&self) -> Command { +- let mut cmd = match self.cc_wrapper_path { +- Some(ref cc_wrapper_path) => { +- let mut cmd = Command::new(&cc_wrapper_path); +- cmd.arg(&self.path); +- cmd +- } +- None => Command::new(&self.path), +- }; +- cmd.args(&self.cc_wrapper_args); +- +- let value = self +- .args +- .iter() +- .filter(|a| !self.removed_args.contains(a)) +- .collect::>(); +- cmd.args(&value); +- +- for &(ref k, ref v) in self.env.iter() { +- cmd.env(k, v); +- } +- cmd +- } +- +- /// Returns the path for this compiler. +- /// +- /// Note that this may not be a path to a file on the filesystem, e.g. "cc", +- /// but rather something which will be resolved when a process is spawned. +- pub fn path(&self) -> &Path { +- &self.path +- } +- +- /// Returns the default set of arguments to the compiler needed to produce +- /// executables for the target this compiler generates. +- pub fn args(&self) -> &[OsString] { +- &self.args +- } +- +- /// Returns the set of environment variables needed for this compiler to +- /// operate. +- /// +- /// This is typically only used for MSVC compilers currently. +- pub fn env(&self) -> &[(OsString, OsString)] { +- &self.env +- } +- +- /// Returns the compiler command in format of CC environment variable. +- /// Or empty string if CC env was not present +- /// +- /// This is typically used by configure script +- pub fn cc_env(&self) -> OsString { +- match self.cc_wrapper_path { +- Some(ref cc_wrapper_path) => { +- let mut cc_env = cc_wrapper_path.as_os_str().to_owned(); +- cc_env.push(" "); +- cc_env.push(self.path.to_path_buf().into_os_string()); +- for arg in self.cc_wrapper_args.iter() { +- cc_env.push(" "); +- cc_env.push(arg); +- } +- cc_env +- } +- None => OsString::from(""), +- } +- } +- +- /// Returns the compiler flags in format of CFLAGS environment variable. +- /// Important here - this will not be CFLAGS from env, its internal gcc's flags to use as CFLAGS +- /// This is typically used by configure script +- pub fn cflags_env(&self) -> OsString { +- let mut flags = OsString::new(); +- for (i, arg) in self.args.iter().enumerate() { +- if i > 0 { +- flags.push(" "); +- } +- flags.push(arg); +- } +- flags +- } +- +- /// Whether the tool is GNU Compiler Collection-like. +- pub fn is_like_gnu(&self) -> bool { +- self.family == ToolFamily::Gnu +- } +- +- /// Whether the tool is Clang-like. +- pub fn is_like_clang(&self) -> bool { +- self.family == ToolFamily::Clang +- } +- +- /// Whether the tool is MSVC-like. +- pub fn is_like_msvc(&self) -> bool { +- match self.family { +- ToolFamily::Msvc { .. } => true, +- _ => false, +- } +- } +-} +- +-fn run(cmd: &mut Command, program: &str) -> Result<(), Error> { +- let (mut child, print) = spawn(cmd, program)?; +- let status = match child.wait() { +- Ok(s) => s, +- Err(_) => { +- return Err(Error::new( +- ErrorKind::ToolExecError, +- &format!( +- "Failed to wait on spawned child process, command {:?} with args {:?}.", +- cmd, program +- ), +- )); +- } +- }; +- print.join().unwrap(); +- println!("{}", status); +- +- if status.success() { +- Ok(()) +- } else { +- Err(Error::new( +- ErrorKind::ToolExecError, +- &format!( +- "Command {:?} with args {:?} did not execute successfully (status code {}).", +- cmd, program, status +- ), +- )) +- } +-} +- +-fn run_output(cmd: &mut Command, program: &str) -> Result, Error> { +- cmd.stdout(Stdio::piped()); +- let (mut child, print) = spawn(cmd, program)?; +- let mut stdout = vec![]; +- child +- .stdout +- .take() +- .unwrap() +- .read_to_end(&mut stdout) +- .unwrap(); +- let status = match child.wait() { +- Ok(s) => s, +- Err(_) => { +- return Err(Error::new( +- ErrorKind::ToolExecError, +- &format!( +- "Failed to wait on spawned child process, command {:?} with args {:?}.", +- cmd, program +- ), +- )); +- } +- }; +- print.join().unwrap(); +- println!("{}", status); +- +- if status.success() { +- Ok(stdout) +- } else { +- Err(Error::new( +- ErrorKind::ToolExecError, +- &format!( +- "Command {:?} with args {:?} did not execute successfully (status code {}).", +- cmd, program, status +- ), +- )) +- } +-} +- +-fn spawn(cmd: &mut Command, program: &str) -> Result<(Child, JoinHandle<()>), Error> { +- println!("running: {:?}", cmd); +- +- // Capture the standard error coming from these programs, and write it out +- // with cargo:warning= prefixes. Note that this is a bit wonky to avoid +- // requiring the output to be UTF-8, we instead just ship bytes from one +- // location to another. +- match cmd.stderr(Stdio::piped()).spawn() { +- Ok(mut child) => { +- let stderr = BufReader::new(child.stderr.take().unwrap()); +- let print = thread::spawn(move || { +- for line in stderr.split(b'\n').filter_map(|l| l.ok()) { +- print!("cargo:warning="); +- std::io::stdout().write_all(&line).unwrap(); +- println!(""); +- } +- }); +- Ok((child, print)) +- } +- Err(ref e) if e.kind() == io::ErrorKind::NotFound => { +- let extra = if cfg!(windows) { +- " (see https://github.com/alexcrichton/cc-rs#compile-time-requirements \ +- for help)" +- } else { +- "" +- }; +- Err(Error::new( +- ErrorKind::ToolNotFound, +- &format!("Failed to find tool. Is `{}` installed?{}", program, extra), +- )) +- } +- Err(_) => Err(Error::new( +- ErrorKind::ToolExecError, +- &format!("Command {:?} with args {:?} failed to start.", cmd, program), +- )), +- } +-} +- +-fn fail(s: &str) -> ! { +- eprintln!("\n\nerror occurred: {}\n\n", s); +- std::process::exit(1); +-} +- +-fn command_add_output_file( +- cmd: &mut Command, +- dst: &Path, +- cuda: bool, +- msvc: bool, +- clang: bool, +- is_asm: bool, +- is_arm: bool, +-) { +- if msvc && !clang && !cuda && !(is_asm && is_arm) { +- let mut s = OsString::from("-Fo"); +- s.push(&dst); +- cmd.arg(s); +- } else { +- cmd.arg("-o").arg(&dst); +- } +-} +- +-// Use by default minimum available API level +-// See note about naming here +-// https://android.googlesource.com/platform/ndk/+/refs/heads/ndk-release-r21/docs/BuildSystemMaintainers.md#Clang +-static NEW_STANDALONE_ANDROID_COMPILERS: [&str; 4] = [ +- "aarch64-linux-android21-clang", +- "armv7a-linux-androideabi16-clang", +- "i686-linux-android16-clang", +- "x86_64-linux-android21-clang", +-]; +- +-// New "standalone" C/C++ cross-compiler executables from recent Android NDK +-// are just shell scripts that call main clang binary (from Android NDK) with +-// proper `--target` argument. +-// +-// For example, armv7a-linux-androideabi16-clang passes +-// `--target=armv7a-linux-androideabi16` to clang. +-// So to construct proper command line check if +-// `--target` argument would be passed or not to clang +-fn android_clang_compiler_uses_target_arg_internally(clang_path: &Path) -> bool { +- if let Some(filename) = clang_path.file_name() { +- if let Some(filename_str) = filename.to_str() { +- filename_str.contains("android") +- } else { +- false +- } +- } else { +- false +- } +-} +- +-#[test] +-fn test_android_clang_compiler_uses_target_arg_internally() { +- for version in 16..21 { +- assert!(android_clang_compiler_uses_target_arg_internally( +- &PathBuf::from(format!("armv7a-linux-androideabi{}-clang", version)) +- )); +- assert!(android_clang_compiler_uses_target_arg_internally( +- &PathBuf::from(format!("armv7a-linux-androideabi{}-clang++", version)) +- )); +- } +- assert!(!android_clang_compiler_uses_target_arg_internally( +- &PathBuf::from("clang") +- )); +- assert!(!android_clang_compiler_uses_target_arg_internally( +- &PathBuf::from("clang++") +- )); +-} +- +-fn autodetect_android_compiler(target: &str, host: &str, gnu: &str, clang: &str) -> String { +- let new_clang_key = match target { +- "aarch64-linux-android" => Some("aarch64"), +- "armv7-linux-androideabi" => Some("armv7a"), +- "i686-linux-android" => Some("i686"), +- "x86_64-linux-android" => Some("x86_64"), +- _ => None, +- }; +- +- let new_clang = new_clang_key +- .map(|key| { +- NEW_STANDALONE_ANDROID_COMPILERS +- .iter() +- .find(|x| x.starts_with(key)) +- }) +- .unwrap_or(None); +- +- if let Some(new_clang) = new_clang { +- if Command::new(new_clang).output().is_ok() { +- return (*new_clang).into(); +- } +- } +- +- let target = target +- .replace("armv7neon", "arm") +- .replace("armv7", "arm") +- .replace("thumbv7neon", "arm") +- .replace("thumbv7", "arm"); +- let gnu_compiler = format!("{}-{}", target, gnu); +- let clang_compiler = format!("{}-{}", target, clang); +- +- // On Windows, the Android clang compiler is provided as a `.cmd` file instead +- // of a `.exe` file. `std::process::Command` won't run `.cmd` files unless the +- // `.cmd` is explicitly appended to the command name, so we do that here. +- let clang_compiler_cmd = format!("{}-{}.cmd", target, clang); +- +- // Check if gnu compiler is present +- // if not, use clang +- if Command::new(&gnu_compiler).output().is_ok() { +- gnu_compiler +- } else if host.contains("windows") && Command::new(&clang_compiler_cmd).output().is_ok() { +- clang_compiler_cmd +- } else { +- clang_compiler +- } +-} +- +-// Rust and clang/cc don't agree on how to name the target. +-fn map_darwin_target_from_rust_to_compiler_architecture(target: &str) -> Option<&'static str> { +- if target.contains("x86_64") { +- Some("x86_64") +- } else if target.contains("arm64e") { +- Some("arm64e") +- } else if target.contains("aarch64") { +- Some("arm64") +- } else { +- None +- } +-} +diff --git a/vendor/cc/src/registry.rs b/vendor/cc/src/registry.rs +deleted file mode 100644 +index 2ac2fa6..0000000 +--- a/vendor/cc/src/registry.rs ++++ /dev/null +@@ -1,204 +0,0 @@ +-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +-// file at the top-level directory of this distribution and at +-// http://rust-lang.org/COPYRIGHT. +-// +-// Licensed under the Apache License, Version 2.0 or the MIT license +-// , at your +-// option. This file may not be copied, modified, or distributed +-// except according to those terms. +- +-use std::ffi::{OsStr, OsString}; +-use std::io; +-use std::ops::RangeFrom; +-use std::os::raw; +-use std::os::windows::prelude::*; +- +-pub struct RegistryKey(Repr); +- +-type HKEY = *mut u8; +-type DWORD = u32; +-type LPDWORD = *mut DWORD; +-type LPCWSTR = *const u16; +-type LPWSTR = *mut u16; +-type LONG = raw::c_long; +-type PHKEY = *mut HKEY; +-type PFILETIME = *mut u8; +-type LPBYTE = *mut u8; +-type REGSAM = u32; +- +-const ERROR_SUCCESS: DWORD = 0; +-const ERROR_NO_MORE_ITEMS: DWORD = 259; +-const HKEY_LOCAL_MACHINE: HKEY = 0x80000002 as HKEY; +-const REG_SZ: DWORD = 1; +-const KEY_READ: DWORD = 0x20019; +-const KEY_WOW64_32KEY: DWORD = 0x200; +- +-#[link(name = "advapi32")] +-extern "system" { +- fn RegOpenKeyExW( +- key: HKEY, +- lpSubKey: LPCWSTR, +- ulOptions: DWORD, +- samDesired: REGSAM, +- phkResult: PHKEY, +- ) -> LONG; +- fn RegEnumKeyExW( +- key: HKEY, +- dwIndex: DWORD, +- lpName: LPWSTR, +- lpcName: LPDWORD, +- lpReserved: LPDWORD, +- lpClass: LPWSTR, +- lpcClass: LPDWORD, +- lpftLastWriteTime: PFILETIME, +- ) -> LONG; +- fn RegQueryValueExW( +- hKey: HKEY, +- lpValueName: LPCWSTR, +- lpReserved: LPDWORD, +- lpType: LPDWORD, +- lpData: LPBYTE, +- lpcbData: LPDWORD, +- ) -> LONG; +- fn RegCloseKey(hKey: HKEY) -> LONG; +-} +- +-struct OwnedKey(HKEY); +- +-enum Repr { +- Const(HKEY), +- Owned(OwnedKey), +-} +- +-pub struct Iter<'a> { +- idx: RangeFrom, +- key: &'a RegistryKey, +-} +- +-unsafe impl Sync for Repr {} +-unsafe impl Send for Repr {} +- +-pub static LOCAL_MACHINE: RegistryKey = RegistryKey(Repr::Const(HKEY_LOCAL_MACHINE)); +- +-impl RegistryKey { +- fn raw(&self) -> HKEY { +- match self.0 { +- Repr::Const(val) => val, +- Repr::Owned(ref val) => val.0, +- } +- } +- +- pub fn open(&self, key: &OsStr) -> io::Result { +- let key = key.encode_wide().chain(Some(0)).collect::>(); +- let mut ret = 0 as *mut _; +- let err = unsafe { +- RegOpenKeyExW( +- self.raw(), +- key.as_ptr(), +- 0, +- KEY_READ | KEY_WOW64_32KEY, +- &mut ret, +- ) +- }; +- if err == ERROR_SUCCESS as LONG { +- Ok(RegistryKey(Repr::Owned(OwnedKey(ret)))) +- } else { +- Err(io::Error::from_raw_os_error(err as i32)) +- } +- } +- +- pub fn iter(&self) -> Iter { +- Iter { +- idx: 0.., +- key: self, +- } +- } +- +- pub fn query_str(&self, name: &str) -> io::Result { +- let name: &OsStr = name.as_ref(); +- let name = name.encode_wide().chain(Some(0)).collect::>(); +- let mut len = 0; +- let mut kind = 0; +- unsafe { +- let err = RegQueryValueExW( +- self.raw(), +- name.as_ptr(), +- 0 as *mut _, +- &mut kind, +- 0 as *mut _, +- &mut len, +- ); +- if err != ERROR_SUCCESS as LONG { +- return Err(io::Error::from_raw_os_error(err as i32)); +- } +- if kind != REG_SZ { +- return Err(io::Error::new( +- io::ErrorKind::Other, +- "registry key wasn't a string", +- )); +- } +- +- // The length here is the length in bytes, but we're using wide +- // characters so we need to be sure to halve it for the capacity +- // passed in. +- let mut v = Vec::with_capacity(len as usize / 2); +- let err = RegQueryValueExW( +- self.raw(), +- name.as_ptr(), +- 0 as *mut _, +- 0 as *mut _, +- v.as_mut_ptr() as *mut _, +- &mut len, +- ); +- if err != ERROR_SUCCESS as LONG { +- return Err(io::Error::from_raw_os_error(err as i32)); +- } +- v.set_len(len as usize / 2); +- +- // Some registry keys may have a terminating nul character, but +- // we're not interested in that, so chop it off if it's there. +- if v[v.len() - 1] == 0 { +- v.pop(); +- } +- Ok(OsString::from_wide(&v)) +- } +- } +-} +- +-impl Drop for OwnedKey { +- fn drop(&mut self) { +- unsafe { +- RegCloseKey(self.0); +- } +- } +-} +- +-impl<'a> Iterator for Iter<'a> { +- type Item = io::Result; +- +- fn next(&mut self) -> Option> { +- self.idx.next().and_then(|i| unsafe { +- let mut v = Vec::with_capacity(256); +- let mut len = v.capacity() as DWORD; +- let ret = RegEnumKeyExW( +- self.key.raw(), +- i, +- v.as_mut_ptr(), +- &mut len, +- 0 as *mut _, +- 0 as *mut _, +- 0 as *mut _, +- 0 as *mut _, +- ); +- if ret == ERROR_NO_MORE_ITEMS as LONG { +- None +- } else if ret != ERROR_SUCCESS as LONG { +- Some(Err(io::Error::from_raw_os_error(ret as i32))) +- } else { +- v.set_len(len as usize); +- Some(Ok(OsString::from_wide(&v))) +- } +- }) +- } +-} +diff --git a/vendor/cc/src/setup_config.rs b/vendor/cc/src/setup_config.rs +deleted file mode 100644 +index bc2b1c2..0000000 +--- a/vendor/cc/src/setup_config.rs ++++ /dev/null +@@ -1,283 +0,0 @@ +-// Copyright © 2017 winapi-rs developers +-// Licensed under the Apache License, Version 2.0 +-// or the MIT license +-// , at your option. +-// All files in the project carrying such notice may not be copied, modified, or distributed +-// except according to those terms. +- +-#![allow(bad_style)] +-#![allow(unused)] +- +-use crate::winapi::Interface; +-use crate::winapi::BSTR; +-use crate::winapi::LPCOLESTR; +-use crate::winapi::LPSAFEARRAY; +-use crate::winapi::S_FALSE; +-use crate::winapi::{CoCreateInstance, CLSCTX_ALL}; +-use crate::winapi::{IUnknown, IUnknownVtbl}; +-use crate::winapi::{HRESULT, LCID, LPCWSTR, PULONGLONG}; +-use crate::winapi::{LPFILETIME, ULONG}; +-use std::ffi::OsString; +-use std::ptr::null_mut; +- +-use crate::com::{BStr, ComPtr}; +- +-// Bindings to the Setup.Configuration stuff +-pub type InstanceState = u32; +- +-pub const eNone: InstanceState = 0; +-pub const eLocal: InstanceState = 1; +-pub const eRegistered: InstanceState = 2; +-pub const eNoRebootRequired: InstanceState = 4; +-pub const eComplete: InstanceState = -1i32 as u32; +- +-RIDL! {#[uuid(0xb41463c3, 0x8866, 0x43b5, 0xbc, 0x33, 0x2b, 0x06, 0x76, 0xf7, 0xf4, 0x2e)] +-interface ISetupInstance(ISetupInstanceVtbl): IUnknown(IUnknownVtbl) { +- fn GetInstanceId( +- pbstrInstanceId: *mut BSTR, +- ) -> HRESULT, +- fn GetInstallDate( +- pInstallDate: LPFILETIME, +- ) -> HRESULT, +- fn GetInstallationName( +- pbstrInstallationName: *mut BSTR, +- ) -> HRESULT, +- fn GetInstallationPath( +- pbstrInstallationPath: *mut BSTR, +- ) -> HRESULT, +- fn GetInstallationVersion( +- pbstrInstallationVersion: *mut BSTR, +- ) -> HRESULT, +- fn GetDisplayName( +- lcid: LCID, +- pbstrDisplayName: *mut BSTR, +- ) -> HRESULT, +- fn GetDescription( +- lcid: LCID, +- pbstrDescription: *mut BSTR, +- ) -> HRESULT, +- fn ResolvePath( +- pwszRelativePath: LPCOLESTR, +- pbstrAbsolutePath: *mut BSTR, +- ) -> HRESULT, +-}} +- +-RIDL! {#[uuid(0x89143c9a, 0x05af, 0x49b0, 0xb7, 0x17, 0x72, 0xe2, 0x18, 0xa2, 0x18, 0x5c)] +-interface ISetupInstance2(ISetupInstance2Vtbl): ISetupInstance(ISetupInstanceVtbl) { +- fn GetState( +- pState: *mut InstanceState, +- ) -> HRESULT, +- fn GetPackages( +- ppsaPackages: *mut LPSAFEARRAY, +- ) -> HRESULT, +- fn GetProduct( +- ppPackage: *mut *mut ISetupPackageReference, +- ) -> HRESULT, +- fn GetProductPath( +- pbstrProductPath: *mut BSTR, +- ) -> HRESULT, +-}} +- +-RIDL! {#[uuid(0x6380bcff, 0x41d3, 0x4b2e, 0x8b, 0x2e, 0xbf, 0x8a, 0x68, 0x10, 0xc8, 0x48)] +-interface IEnumSetupInstances(IEnumSetupInstancesVtbl): IUnknown(IUnknownVtbl) { +- fn Next( +- celt: ULONG, +- rgelt: *mut *mut ISetupInstance, +- pceltFetched: *mut ULONG, +- ) -> HRESULT, +- fn Skip( +- celt: ULONG, +- ) -> HRESULT, +- fn Reset() -> HRESULT, +- fn Clone( +- ppenum: *mut *mut IEnumSetupInstances, +- ) -> HRESULT, +-}} +- +-RIDL! {#[uuid(0x42843719, 0xdb4c, 0x46c2, 0x8e, 0x7c, 0x64, 0xf1, 0x81, 0x6e, 0xfd, 0x5b)] +-interface ISetupConfiguration(ISetupConfigurationVtbl): IUnknown(IUnknownVtbl) { +- fn EnumInstances( +- ppEnumInstances: *mut *mut IEnumSetupInstances, +- ) -> HRESULT, +- fn GetInstanceForCurrentProcess( +- ppInstance: *mut *mut ISetupInstance, +- ) -> HRESULT, +- fn GetInstanceForPath( +- wzPath: LPCWSTR, +- ppInstance: *mut *mut ISetupInstance, +- ) -> HRESULT, +-}} +- +-RIDL! {#[uuid(0x26aab78c, 0x4a60, 0x49d6, 0xaf, 0x3b, 0x3c, 0x35, 0xbc, 0x93, 0x36, 0x5d)] +-interface ISetupConfiguration2(ISetupConfiguration2Vtbl): +- ISetupConfiguration(ISetupConfigurationVtbl) { +- fn EnumAllInstances( +- ppEnumInstances: *mut *mut IEnumSetupInstances, +- ) -> HRESULT, +-}} +- +-RIDL! {#[uuid(0xda8d8a16, 0xb2b6, 0x4487, 0xa2, 0xf1, 0x59, 0x4c, 0xcc, 0xcd, 0x6b, 0xf5)] +-interface ISetupPackageReference(ISetupPackageReferenceVtbl): IUnknown(IUnknownVtbl) { +- fn GetId( +- pbstrId: *mut BSTR, +- ) -> HRESULT, +- fn GetVersion( +- pbstrVersion: *mut BSTR, +- ) -> HRESULT, +- fn GetChip( +- pbstrChip: *mut BSTR, +- ) -> HRESULT, +- fn GetLanguage( +- pbstrLanguage: *mut BSTR, +- ) -> HRESULT, +- fn GetBranch( +- pbstrBranch: *mut BSTR, +- ) -> HRESULT, +- fn GetType( +- pbstrType: *mut BSTR, +- ) -> HRESULT, +- fn GetUniqueId( +- pbstrUniqueId: *mut BSTR, +- ) -> HRESULT, +-}} +- +-RIDL! {#[uuid(0x42b21b78, 0x6192, 0x463e, 0x87, 0xbf, 0xd5, 0x77, 0x83, 0x8f, 0x1d, 0x5c)] +-interface ISetupHelper(ISetupHelperVtbl): IUnknown(IUnknownVtbl) { +- fn ParseVersion( +- pwszVersion: LPCOLESTR, +- pullVersion: PULONGLONG, +- ) -> HRESULT, +- fn ParseVersionRange( +- pwszVersionRange: LPCOLESTR, +- pullMinVersion: PULONGLONG, +- pullMaxVersion: PULONGLONG, +- ) -> HRESULT, +-}} +- +-DEFINE_GUID! {CLSID_SetupConfiguration, +-0x177f0c4a, 0x1cd3, 0x4de7, 0xa3, 0x2c, 0x71, 0xdb, 0xbb, 0x9f, 0xa3, 0x6d} +- +-// Safe wrapper around the COM interfaces +-pub struct SetupConfiguration(ComPtr); +- +-impl SetupConfiguration { +- pub fn new() -> Result { +- let mut obj = null_mut(); +- let err = unsafe { +- CoCreateInstance( +- &CLSID_SetupConfiguration, +- null_mut(), +- CLSCTX_ALL, +- &ISetupConfiguration::uuidof(), +- &mut obj, +- ) +- }; +- if err < 0 { +- return Err(err); +- } +- let obj = unsafe { ComPtr::from_raw(obj as *mut ISetupConfiguration) }; +- Ok(SetupConfiguration(obj)) +- } +- pub fn get_instance_for_current_process(&self) -> Result { +- let mut obj = null_mut(); +- let err = unsafe { self.0.GetInstanceForCurrentProcess(&mut obj) }; +- if err < 0 { +- return Err(err); +- } +- Ok(unsafe { SetupInstance::from_raw(obj) }) +- } +- pub fn enum_instances(&self) -> Result { +- let mut obj = null_mut(); +- let err = unsafe { self.0.EnumInstances(&mut obj) }; +- if err < 0 { +- return Err(err); +- } +- Ok(unsafe { EnumSetupInstances::from_raw(obj) }) +- } +- pub fn enum_all_instances(&self) -> Result { +- let mut obj = null_mut(); +- let this = self.0.cast::()?; +- let err = unsafe { this.EnumAllInstances(&mut obj) }; +- if err < 0 { +- return Err(err); +- } +- Ok(unsafe { EnumSetupInstances::from_raw(obj) }) +- } +-} +- +-pub struct SetupInstance(ComPtr); +- +-impl SetupInstance { +- pub unsafe fn from_raw(obj: *mut ISetupInstance) -> SetupInstance { +- SetupInstance(ComPtr::from_raw(obj)) +- } +- pub fn instance_id(&self) -> Result { +- let mut s = null_mut(); +- let err = unsafe { self.0.GetInstanceId(&mut s) }; +- let bstr = unsafe { BStr::from_raw(s) }; +- if err < 0 { +- return Err(err); +- } +- Ok(bstr.to_osstring()) +- } +- pub fn installation_name(&self) -> Result { +- let mut s = null_mut(); +- let err = unsafe { self.0.GetInstallationName(&mut s) }; +- let bstr = unsafe { BStr::from_raw(s) }; +- if err < 0 { +- return Err(err); +- } +- Ok(bstr.to_osstring()) +- } +- pub fn installation_path(&self) -> Result { +- let mut s = null_mut(); +- let err = unsafe { self.0.GetInstallationPath(&mut s) }; +- let bstr = unsafe { BStr::from_raw(s) }; +- if err < 0 { +- return Err(err); +- } +- Ok(bstr.to_osstring()) +- } +- pub fn installation_version(&self) -> Result { +- let mut s = null_mut(); +- let err = unsafe { self.0.GetInstallationVersion(&mut s) }; +- let bstr = unsafe { BStr::from_raw(s) }; +- if err < 0 { +- return Err(err); +- } +- Ok(bstr.to_osstring()) +- } +- pub fn product_path(&self) -> Result { +- let mut s = null_mut(); +- let this = self.0.cast::()?; +- let err = unsafe { this.GetProductPath(&mut s) }; +- let bstr = unsafe { BStr::from_raw(s) }; +- if err < 0 { +- return Err(err); +- } +- Ok(bstr.to_osstring()) +- } +-} +- +-pub struct EnumSetupInstances(ComPtr); +- +-impl EnumSetupInstances { +- pub unsafe fn from_raw(obj: *mut IEnumSetupInstances) -> EnumSetupInstances { +- EnumSetupInstances(ComPtr::from_raw(obj)) +- } +-} +- +-impl Iterator for EnumSetupInstances { +- type Item = Result; +- fn next(&mut self) -> Option> { +- let mut obj = null_mut(); +- let err = unsafe { self.0.Next(1, &mut obj, null_mut()) }; +- if err < 0 { +- return Some(Err(err)); +- } +- if err == S_FALSE { +- return None; +- } +- Some(Ok(unsafe { SetupInstance::from_raw(obj) })) +- } +-} +diff --git a/vendor/cc/src/vs_instances.rs b/vendor/cc/src/vs_instances.rs +deleted file mode 100644 +index 31d3dd1..0000000 +--- a/vendor/cc/src/vs_instances.rs ++++ /dev/null +@@ -1,199 +0,0 @@ +-use std::borrow::Cow; +-use std::collections::HashMap; +-use std::convert::TryFrom; +-use std::io::BufRead; +-use std::path::PathBuf; +- +-use crate::setup_config::{EnumSetupInstances, SetupInstance}; +- +-pub enum VsInstance { +- Com(SetupInstance), +- Vswhere(VswhereInstance), +-} +- +-impl VsInstance { +- pub fn installation_name(&self) -> Option> { +- match self { +- VsInstance::Com(s) => s +- .installation_name() +- .ok() +- .and_then(|s| s.into_string().ok()) +- .map(Cow::from), +- VsInstance::Vswhere(v) => v.map.get("installationName").map(Cow::from), +- } +- } +- +- pub fn installation_path(&self) -> Option { +- match self { +- VsInstance::Com(s) => s.installation_path().ok().map(PathBuf::from), +- VsInstance::Vswhere(v) => v.map.get("installationPath").map(PathBuf::from), +- } +- } +- +- pub fn installation_version(&self) -> Option> { +- match self { +- VsInstance::Com(s) => s +- .installation_version() +- .ok() +- .and_then(|s| s.into_string().ok()) +- .map(Cow::from), +- VsInstance::Vswhere(v) => v.map.get("installationVersion").map(Cow::from), +- } +- } +-} +- +-pub enum VsInstances { +- ComBased(EnumSetupInstances), +- VswhereBased(VswhereInstance), +-} +- +-impl IntoIterator for VsInstances { +- type Item = VsInstance; +- #[allow(bare_trait_objects)] +- type IntoIter = Box>; +- +- fn into_iter(self) -> Self::IntoIter { +- match self { +- VsInstances::ComBased(e) => { +- Box::new(e.into_iter().filter_map(Result::ok).map(VsInstance::Com)) +- } +- VsInstances::VswhereBased(v) => Box::new(std::iter::once(VsInstance::Vswhere(v))), +- } +- } +-} +- +-#[derive(Debug)] +-pub struct VswhereInstance { +- map: HashMap, +-} +- +-impl TryFrom<&Vec> for VswhereInstance { +- type Error = &'static str; +- +- fn try_from(output: &Vec) -> Result { +- let map: HashMap<_, _> = output +- .lines() +- .filter_map(Result::ok) +- .filter_map(|s| { +- let mut splitn = s.splitn(2, ": "); +- Some((splitn.next()?.to_owned(), splitn.next()?.to_owned())) +- }) +- .collect(); +- +- if !map.contains_key("installationName") +- || !map.contains_key("installationPath") +- || !map.contains_key("installationVersion") +- { +- return Err("required properties not found"); +- } +- +- Ok(Self { map }) +- } +-} +- +-#[cfg(test)] +-mod tests_ { +- use std::borrow::Cow; +- use std::convert::TryFrom; +- use std::path::PathBuf; +- +- #[test] +- fn it_parses_vswhere_output_correctly() { +- let output = br"instanceId: 58104422 +-installDate: 21/02/2021 21:50:33 +-installationName: VisualStudio/16.9.2+31112.23 +-installationPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools +-installationVersion: 16.9.31112.23 +-productId: Microsoft.VisualStudio.Product.BuildTools +-productPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\LaunchDevCmd.bat +-state: 4294967295 +-isComplete: 1 +-isLaunchable: 1 +-isPrerelease: 0 +-isRebootRequired: 0 +-displayName: Visual Studio Build Tools 2019 +-description: The Visual Studio Build Tools allows you to build native and managed MSBuild-based applications without requiring the Visual Studio IDE. There are options to install the Visual C++ compilers and libraries, MFC, ATL, and C++/CLI support. +-channelId: VisualStudio.16.Release +-channelUri: https://aka.ms/vs/16/release/channel +-enginePath: C:\Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\ServiceHub\Services\Microsoft.VisualStudio.Setup.Service +-releaseNotes: https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes-v16.9#16.9.2 +-thirdPartyNotices: https://go.microsoft.com/fwlink/?LinkId=660909 +-updateDate: 2021-03-17T21:16:46.5963702Z +-catalog_buildBranch: d16.9 +-catalog_buildVersion: 16.9.31112.23 +-catalog_id: VisualStudio/16.9.2+31112.23 +-catalog_localBuild: build-lab +-catalog_manifestName: VisualStudio +-catalog_manifestType: installer +-catalog_productDisplayVersion: 16.9.2 +-catalog_productLine: Dev16 +-catalog_productLineVersion: 2019 +-catalog_productMilestone: RTW +-catalog_productMilestoneIsPreRelease: False +-catalog_productName: Visual Studio +-catalog_productPatchVersion: 2 +-catalog_productPreReleaseMilestoneSuffix: 1.0 +-catalog_productSemanticVersion: 16.9.2+31112.23 +-catalog_requiredEngineVersion: 2.9.3365.38425 +-properties_campaignId: 156063665.1613940062 +-properties_channelManifestId: VisualStudio.16.Release/16.9.2+31112.23 +-properties_nickname: +-properties_setupEngineFilePath: C:\Program Files (x86)\Microsoft Visual Studio\Installer\vs_installershell.exe +-" +- .to_vec(); +- +- let vswhere_instance = super::VswhereInstance::try_from(&output); +- assert!(vswhere_instance.is_ok()); +- +- let vs_instance = super::VsInstance::Vswhere(vswhere_instance.unwrap()); +- assert_eq!( +- vs_instance.installation_name(), +- Some(Cow::from("VisualStudio/16.9.2+31112.23")) +- ); +- assert_eq!( +- vs_instance.installation_path(), +- Some(PathBuf::from( +- r"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools" +- )) +- ); +- assert_eq!( +- vs_instance.installation_version(), +- Some(Cow::from("16.9.31112.23")) +- ); +- } +- +- #[test] +- fn it_returns_an_error_for_empty_output() { +- let output = b"".to_vec(); +- +- let vswhere_instance = super::VswhereInstance::try_from(&output); +- +- assert!(vswhere_instance.is_err()); +- } +- +- #[test] +- fn it_returns_an_error_for_output_consisting_of_empty_lines() { +- let output = br" +- +-" +- .to_vec(); +- +- let vswhere_instance = super::VswhereInstance::try_from(&output); +- +- assert!(vswhere_instance.is_err()); +- } +- +- #[test] +- fn it_returns_an_error_for_output_without_required_properties() { +- let output = br"instanceId: 58104422 +-installDate: 21/02/2021 21:50:33 +-productId: Microsoft.VisualStudio.Product.BuildTools +-productPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\LaunchDevCmd.bat +-" +- .to_vec(); +- +- let vswhere_instance = super::VswhereInstance::try_from(&output); +- +- assert!(vswhere_instance.is_err()); +- } +-} +diff --git a/vendor/cc/src/winapi.rs b/vendor/cc/src/winapi.rs +deleted file mode 100644 +index c416325..0000000 +--- a/vendor/cc/src/winapi.rs ++++ /dev/null +@@ -1,218 +0,0 @@ +-// Copyright © 2015-2017 winapi-rs developers +-// Licensed under the Apache License, Version 2.0 +-// or the MIT license +-// , at your option. +-// All files in the project carrying such notice may not be copied, modified, or distributed +-// except according to those terms. +- +-#![allow(bad_style)] +- +-use std::os::raw; +- +-pub type wchar_t = u16; +- +-pub type UINT = raw::c_uint; +-pub type LPUNKNOWN = *mut IUnknown; +-pub type REFIID = *const IID; +-pub type IID = GUID; +-pub type REFCLSID = *const IID; +-pub type PVOID = *mut raw::c_void; +-pub type USHORT = raw::c_ushort; +-pub type ULONG = raw::c_ulong; +-pub type LONG = raw::c_long; +-pub type DWORD = u32; +-pub type LPVOID = *mut raw::c_void; +-pub type HRESULT = raw::c_long; +-pub type LPFILETIME = *mut FILETIME; +-pub type BSTR = *mut OLECHAR; +-pub type OLECHAR = WCHAR; +-pub type WCHAR = wchar_t; +-pub type LPCOLESTR = *const OLECHAR; +-pub type LCID = DWORD; +-pub type LPCWSTR = *const WCHAR; +-pub type PULONGLONG = *mut ULONGLONG; +-pub type ULONGLONG = u64; +- +-pub const S_OK: HRESULT = 0; +-pub const S_FALSE: HRESULT = 1; +-pub const COINIT_MULTITHREADED: u32 = 0x0; +- +-pub type CLSCTX = u32; +- +-pub const CLSCTX_INPROC_SERVER: CLSCTX = 0x1; +-pub const CLSCTX_INPROC_HANDLER: CLSCTX = 0x2; +-pub const CLSCTX_LOCAL_SERVER: CLSCTX = 0x4; +-pub const CLSCTX_REMOTE_SERVER: CLSCTX = 0x10; +- +-pub const CLSCTX_ALL: CLSCTX = +- CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER; +- +-#[repr(C)] +-#[derive(Copy, Clone)] +-pub struct GUID { +- pub Data1: raw::c_ulong, +- pub Data2: raw::c_ushort, +- pub Data3: raw::c_ushort, +- pub Data4: [raw::c_uchar; 8], +-} +- +-#[repr(C)] +-#[derive(Copy, Clone)] +-pub struct FILETIME { +- pub dwLowDateTime: DWORD, +- pub dwHighDateTime: DWORD, +-} +- +-pub trait Interface { +- fn uuidof() -> GUID; +-} +- +-#[link(name = "ole32")] +-#[link(name = "oleaut32")] +-extern "C" {} +- +-extern "system" { +- pub fn CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) -> HRESULT; +- pub fn CoCreateInstance( +- rclsid: REFCLSID, +- pUnkOuter: LPUNKNOWN, +- dwClsContext: DWORD, +- riid: REFIID, +- ppv: *mut LPVOID, +- ) -> HRESULT; +- pub fn SysFreeString(bstrString: BSTR); +- pub fn SysStringLen(pbstr: BSTR) -> UINT; +-} +- +-#[repr(C)] +-#[derive(Copy, Clone)] +-pub struct SAFEARRAYBOUND { +- pub cElements: ULONG, +- pub lLbound: LONG, +-} +- +-#[repr(C)] +-#[derive(Copy, Clone)] +-pub struct SAFEARRAY { +- pub cDims: USHORT, +- pub fFeatures: USHORT, +- pub cbElements: ULONG, +- pub cLocks: ULONG, +- pub pvData: PVOID, +- pub rgsabound: [SAFEARRAYBOUND; 1], +-} +- +-pub type LPSAFEARRAY = *mut SAFEARRAY; +- +-macro_rules! DEFINE_GUID { +- ( +- $name:ident, $l:expr, $w1:expr, $w2:expr, +- $b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr +- ) => { +- pub const $name: $crate::winapi::GUID = $crate::winapi::GUID { +- Data1: $l, +- Data2: $w1, +- Data3: $w2, +- Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8], +- }; +- }; +-} +- +-macro_rules! RIDL { +- (#[uuid($($uuid:expr),+)] +- interface $interface:ident ($vtbl:ident) {$( +- fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty, +- )+}) => ( +- #[repr(C)] +- pub struct $vtbl { +- $(pub $method: unsafe extern "system" fn( +- This: *mut $interface, +- $($p: $t),* +- ) -> $rtr,)+ +- } +- #[repr(C)] +- pub struct $interface { +- pub lpVtbl: *const $vtbl, +- } +- RIDL!{@impl $interface {$(fn $method($($p: $t,)*) -> $rtr,)+}} +- RIDL!{@uuid $interface $($uuid),+} +- ); +- (#[uuid($($uuid:expr),+)] +- interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) { +- }) => ( +- #[repr(C)] +- pub struct $vtbl { +- pub parent: $pvtbl, +- } +- #[repr(C)] +- pub struct $interface { +- pub lpVtbl: *const $vtbl, +- } +- RIDL!{@deref $interface $pinterface} +- RIDL!{@uuid $interface $($uuid),+} +- ); +- (#[uuid($($uuid:expr),+)] +- interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) {$( +- fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty, +- )+}) => ( +- #[repr(C)] +- pub struct $vtbl { +- pub parent: $pvtbl, +- $(pub $method: unsafe extern "system" fn( +- This: *mut $interface, +- $($p: $t,)* +- ) -> $rtr,)+ +- } +- #[repr(C)] +- pub struct $interface { +- pub lpVtbl: *const $vtbl, +- } +- RIDL!{@impl $interface {$(fn $method($($p: $t,)*) -> $rtr,)+}} +- RIDL!{@deref $interface $pinterface} +- RIDL!{@uuid $interface $($uuid),+} +- ); +- (@deref $interface:ident $pinterface:ident) => ( +- impl ::std::ops::Deref for $interface { +- type Target = $pinterface; +- #[inline] +- fn deref(&self) -> &$pinterface { +- unsafe { &*(self as *const $interface as *const $pinterface) } +- } +- } +- ); +- (@impl $interface:ident {$( +- fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty, +- )+}) => ( +- impl $interface { +- $(#[inline] pub unsafe fn $method(&self, $($p: $t,)*) -> $rtr { +- ((*self.lpVtbl).$method)(self as *const _ as *mut _, $($p,)*) +- })+ +- } +- ); +- (@uuid $interface:ident +- $l:expr, $w1:expr, $w2:expr, +- $b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr +- ) => ( +- impl $crate::winapi::Interface for $interface { +- #[inline] +- fn uuidof() -> $crate::winapi::GUID { +- $crate::winapi::GUID { +- Data1: $l, +- Data2: $w1, +- Data3: $w2, +- Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8], +- } +- } +- } +- ); +-} +- +-RIDL! {#[uuid(0x00000000, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46)] +-interface IUnknown(IUnknownVtbl) { +- fn QueryInterface( +- riid: REFIID, +- ppvObject: *mut *mut raw::c_void, +- ) -> HRESULT, +- fn AddRef() -> ULONG, +- fn Release() -> ULONG, +-}} +diff --git a/vendor/cc/src/windows_registry.rs b/vendor/cc/src/windows_registry.rs +deleted file mode 100644 +index 40101a6..0000000 +--- a/vendor/cc/src/windows_registry.rs ++++ /dev/null +@@ -1,870 +0,0 @@ +-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +-// file at the top-level directory of this distribution and at +-// http://rust-lang.org/COPYRIGHT. +-// +-// Licensed under the Apache License, Version 2.0 or the MIT license +-// , at your +-// option. This file may not be copied, modified, or distributed +-// except according to those terms. +- +-//! A helper module to probe the Windows Registry when looking for +-//! windows-specific tools. +- +-use std::process::Command; +- +-use crate::Tool; +-#[cfg(windows)] +-use crate::ToolFamily; +- +-#[cfg(windows)] +-const MSVC_FAMILY: ToolFamily = ToolFamily::Msvc { clang_cl: false }; +- +-/// Attempts to find a tool within an MSVC installation using the Windows +-/// registry as a point to search from. +-/// +-/// The `target` argument is the target that the tool should work for (e.g. +-/// compile or link for) and the `tool` argument is the tool to find (e.g. +-/// `cl.exe` or `link.exe`). +-/// +-/// This function will return `None` if the tool could not be found, or it will +-/// return `Some(cmd)` which represents a command that's ready to execute the +-/// tool with the appropriate environment variables set. +-/// +-/// Note that this function always returns `None` for non-MSVC targets. +-pub fn find(target: &str, tool: &str) -> Option { +- find_tool(target, tool).map(|c| c.to_command()) +-} +- +-/// Similar to the `find` function above, this function will attempt the same +-/// operation (finding a MSVC tool in a local install) but instead returns a +-/// `Tool` which may be introspected. +-#[cfg(not(windows))] +-pub fn find_tool(_target: &str, _tool: &str) -> Option { +- None +-} +- +-/// Documented above. +-#[cfg(windows)] +-pub fn find_tool(target: &str, tool: &str) -> Option { +- // This logic is all tailored for MSVC, if we're not that then bail out +- // early. +- if !target.contains("msvc") { +- return None; +- } +- +- // Looks like msbuild isn't located in the same location as other tools like +- // cl.exe and lib.exe. To handle this we probe for it manually with +- // dedicated registry keys. +- if tool.contains("msbuild") { +- return impl_::find_msbuild(target); +- } +- +- if tool.contains("devenv") { +- return impl_::find_devenv(target); +- } +- +- // Ok, if we're here, now comes the fun part of the probing. Default shells +- // or shells like MSYS aren't really configured to execute `cl.exe` and the +- // various compiler tools shipped as part of Visual Studio. Here we try to +- // first find the relevant tool, then we also have to be sure to fill in +- // environment variables like `LIB`, `INCLUDE`, and `PATH` to ensure that +- // the tool is actually usable. +- +- return impl_::find_msvc_environment(tool, target) +- .or_else(|| impl_::find_msvc_15plus(tool, target)) +- .or_else(|| impl_::find_msvc_14(tool, target)) +- .or_else(|| impl_::find_msvc_12(tool, target)) +- .or_else(|| impl_::find_msvc_11(tool, target)); +-} +- +-/// A version of Visual Studio +-#[derive(Debug, PartialEq, Eq, Copy, Clone)] +-pub enum VsVers { +- /// Visual Studio 12 (2013) +- Vs12, +- /// Visual Studio 14 (2015) +- Vs14, +- /// Visual Studio 15 (2017) +- Vs15, +- /// Visual Studio 16 (2019) +- Vs16, +- +- /// Hidden variant that should not be matched on. Callers that want to +- /// handle an enumeration of `VsVers` instances should always have a default +- /// case meaning that it's a VS version they don't understand. +- #[doc(hidden)] +- #[allow(bad_style)] +- __Nonexhaustive_do_not_match_this_or_your_code_will_break, +-} +- +-/// Find the most recent installed version of Visual Studio +-/// +-/// This is used by the cmake crate to figure out the correct +-/// generator. +-#[cfg(not(windows))] +-pub fn find_vs_version() -> Result { +- Err(format!("not windows")) +-} +- +-/// Documented above +-#[cfg(windows)] +-pub fn find_vs_version() -> Result { +- use std::env; +- +- match env::var("VisualStudioVersion") { +- Ok(version) => match &version[..] { +- "16.0" => Ok(VsVers::Vs16), +- "15.0" => Ok(VsVers::Vs15), +- "14.0" => Ok(VsVers::Vs14), +- "12.0" => Ok(VsVers::Vs12), +- vers => Err(format!( +- "\n\n\ +- unsupported or unknown VisualStudio version: {}\n\ +- if another version is installed consider running \ +- the appropriate vcvars script before building this \ +- crate\n\ +- ", +- vers +- )), +- }, +- _ => { +- // Check for the presense of a specific registry key +- // that indicates visual studio is installed. +- if impl_::has_msbuild_version("16.0") { +- Ok(VsVers::Vs16) +- } else if impl_::has_msbuild_version("15.0") { +- Ok(VsVers::Vs15) +- } else if impl_::has_msbuild_version("14.0") { +- Ok(VsVers::Vs14) +- } else if impl_::has_msbuild_version("12.0") { +- Ok(VsVers::Vs12) +- } else { +- Err(format!( +- "\n\n\ +- couldn't determine visual studio generator\n\ +- if VisualStudio is installed, however, consider \ +- running the appropriate vcvars script before building \ +- this crate\n\ +- " +- )) +- } +- } +- } +-} +- +-#[cfg(windows)] +-mod impl_ { +- use crate::com; +- use crate::registry::{RegistryKey, LOCAL_MACHINE}; +- use crate::setup_config::SetupConfiguration; +- use crate::vs_instances::{VsInstances, VswhereInstance}; +- use std::convert::TryFrom; +- use std::env; +- use std::ffi::OsString; +- use std::fs::File; +- use std::io::Read; +- use std::iter; +- use std::mem; +- use std::path::{Path, PathBuf}; +- use std::process::Command; +- use std::str::FromStr; +- +- use super::MSVC_FAMILY; +- use crate::Tool; +- +- struct MsvcTool { +- tool: PathBuf, +- libs: Vec, +- path: Vec, +- include: Vec, +- } +- +- impl MsvcTool { +- fn new(tool: PathBuf) -> MsvcTool { +- MsvcTool { +- tool: tool, +- libs: Vec::new(), +- path: Vec::new(), +- include: Vec::new(), +- } +- } +- +- fn into_tool(self) -> Tool { +- let MsvcTool { +- tool, +- libs, +- path, +- include, +- } = self; +- let mut tool = Tool::with_family(tool.into(), MSVC_FAMILY); +- add_env(&mut tool, "LIB", libs); +- add_env(&mut tool, "PATH", path); +- add_env(&mut tool, "INCLUDE", include); +- tool +- } +- } +- +- /// Checks to see if the `VSCMD_ARG_TGT_ARCH` environment variable matches the +- /// given target's arch. Returns `None` if the variable does not exist. +- #[cfg(windows)] +- fn is_vscmd_target(target: &str) -> Option { +- let vscmd_arch = env::var("VSCMD_ARG_TGT_ARCH").ok()?; +- // Convert the Rust target arch to its VS arch equivalent. +- let arch = match target.split("-").next() { +- Some("x86_64") => "x64", +- Some("aarch64") => "arm64", +- Some("i686") | Some("i586") => "x86", +- Some("thumbv7a") => "arm", +- // An unrecognized arch. +- _ => return Some(false), +- }; +- Some(vscmd_arch == arch) +- } +- +- /// Attempt to find the tool using environment variables set by vcvars. +- pub fn find_msvc_environment(target: &str, tool: &str) -> Option { +- // Early return if the environment doesn't contain a VC install. +- if env::var_os("VCINSTALLDIR").is_none() { +- return None; +- } +- let vs_install_dir = env::var_os("VSINSTALLDIR")?.into(); +- +- // If the vscmd target differs from the requested target then +- // attempt to get the tool using the VS install directory. +- if is_vscmd_target(target) == Some(false) { +- // We will only get here with versions 15+. +- tool_from_vs15plus_instance(tool, target, &vs_install_dir) +- } else { +- // Fallback to simply using the current environment. +- env::var_os("PATH") +- .and_then(|path| { +- env::split_paths(&path) +- .map(|p| p.join(tool)) +- .find(|p| p.exists()) +- }) +- .map(|path| Tool::with_family(path.into(), MSVC_FAMILY)) +- } +- } +- +- #[allow(bare_trait_objects)] +- fn vs16_instances(target: &str) -> Box> { +- let instances = if let Some(instances) = vs15plus_instances(target) { +- instances +- } else { +- return Box::new(iter::empty()); +- }; +- Box::new(instances.into_iter().filter_map(|instance| { +- let installation_name = instance.installation_name()?; +- if installation_name.starts_with("VisualStudio/16.") { +- Some(instance.installation_path()?) +- } else if installation_name.starts_with("VisualStudioPreview/16.") { +- Some(instance.installation_path()?) +- } else { +- None +- } +- })) +- } +- +- fn find_tool_in_vs16_path(tool: &str, target: &str) -> Option { +- vs16_instances(target) +- .filter_map(|path| { +- let path = path.join(tool); +- if !path.is_file() { +- return None; +- } +- let mut tool = Tool::with_family(path, MSVC_FAMILY); +- if target.contains("x86_64") { +- tool.env.push(("Platform".into(), "X64".into())); +- } +- Some(tool) +- }) +- .next() +- } +- +- fn find_msbuild_vs16(target: &str) -> Option { +- find_tool_in_vs16_path(r"MSBuild\Current\Bin\MSBuild.exe", target) +- } +- +- // In MSVC 15 (2017) MS once again changed the scheme for locating +- // the tooling. Now we must go through some COM interfaces, which +- // is super fun for Rust. +- // +- // Note that much of this logic can be found [online] wrt paths, COM, etc. +- // +- // [online]: https://blogs.msdn.microsoft.com/vcblog/2017/03/06/finding-the-visual-c-compiler-tools-in-visual-studio-2017/ +- // +- // Returns MSVC 15+ instances (15, 16 right now), the order should be consider undefined. +- // +- // However, on ARM64 this method doesn't work because VS Installer fails to register COM component on ARM64. +- // Hence, as the last resort we try to use vswhere.exe to list available instances. +- fn vs15plus_instances(target: &str) -> Option { +- vs15plus_instances_using_com().or_else(|| vs15plus_instances_using_vswhere(target)) +- } +- +- fn vs15plus_instances_using_com() -> Option { +- com::initialize().ok()?; +- +- let config = SetupConfiguration::new().ok()?; +- let enum_setup_instances = config.enum_all_instances().ok()?; +- +- Some(VsInstances::ComBased(enum_setup_instances)) +- } +- +- fn vs15plus_instances_using_vswhere(target: &str) -> Option { +- let program_files_path: PathBuf = env::var("ProgramFiles(x86)") +- .or_else(|_| env::var("ProgramFiles")) +- .ok()? +- .into(); +- +- let vswhere_path = +- program_files_path.join(r"Microsoft Visual Studio\Installer\vswhere.exe"); +- +- if !vswhere_path.exists() { +- return None; +- } +- +- let arch = target.split('-').next().unwrap(); +- let tools_arch = match arch { +- "i586" | "i686" | "x86_64" => Some("x86.x64"), +- "arm" | "thumbv7a" => Some("ARM"), +- "aarch64" => Some("ARM64"), +- _ => None, +- }; +- +- let vswhere_output = Command::new(vswhere_path) +- .args(&[ +- "-latest", +- "-products", +- "*", +- "-requires", +- &format!("Microsoft.VisualStudio.Component.VC.Tools.{}", tools_arch?), +- "-format", +- "text", +- "-nologo", +- ]) +- .stderr(std::process::Stdio::inherit()) +- .output() +- .ok()?; +- +- let vs_instances = +- VsInstances::VswhereBased(VswhereInstance::try_from(&vswhere_output.stdout).ok()?); +- +- Some(vs_instances) +- } +- +- // Inspired from official microsoft/vswhere ParseVersionString +- // i.e. at most four u16 numbers separated by '.' +- fn parse_version(version: &str) -> Option> { +- version +- .split('.') +- .map(|chunk| u16::from_str(chunk).ok()) +- .collect() +- } +- +- pub fn find_msvc_15plus(tool: &str, target: &str) -> Option { +- let iter = vs15plus_instances(target)?; +- iter.into_iter() +- .filter_map(|instance| { +- let version = parse_version(&instance.installation_version()?)?; +- let instance_path = instance.installation_path()?; +- let tool = tool_from_vs15plus_instance(tool, target, &instance_path)?; +- Some((version, tool)) +- }) +- .max_by(|(a_version, _), (b_version, _)| a_version.cmp(b_version)) +- .map(|(_version, tool)| tool) +- } +- +- // While the paths to Visual Studio 2017's devenv and MSBuild could +- // potentially be retrieved from the registry, finding them via +- // SetupConfiguration has shown to be [more reliable], and is preferred +- // according to Microsoft. To help head off potential regressions though, +- // we keep the registry method as a fallback option. +- // +- // [more reliable]: https://github.com/alexcrichton/cc-rs/pull/331 +- fn find_tool_in_vs15_path(tool: &str, target: &str) -> Option { +- let mut path = match vs15plus_instances(target) { +- Some(instances) => instances +- .into_iter() +- .filter_map(|instance| instance.installation_path()) +- .map(|path| path.join(tool)) +- .find(|ref path| path.is_file()), +- None => None, +- }; +- +- if path.is_none() { +- let key = r"SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7"; +- path = LOCAL_MACHINE +- .open(key.as_ref()) +- .ok() +- .and_then(|key| key.query_str("15.0").ok()) +- .map(|path| PathBuf::from(path).join(tool)) +- .and_then(|path| if path.is_file() { Some(path) } else { None }); +- } +- +- path.map(|path| { +- let mut tool = Tool::with_family(path, MSVC_FAMILY); +- if target.contains("x86_64") { +- tool.env.push(("Platform".into(), "X64".into())); +- } +- tool +- }) +- } +- +- fn tool_from_vs15plus_instance( +- tool: &str, +- target: &str, +- instance_path: &PathBuf, +- ) -> Option { +- let (bin_path, host_dylib_path, lib_path, include_path) = +- vs15plus_vc_paths(target, instance_path)?; +- let tool_path = bin_path.join(tool); +- if !tool_path.exists() { +- return None; +- }; +- +- let mut tool = MsvcTool::new(tool_path); +- tool.path.push(bin_path.clone()); +- tool.path.push(host_dylib_path); +- tool.libs.push(lib_path); +- tool.include.push(include_path); +- +- if let Some((atl_lib_path, atl_include_path)) = atl_paths(target, &bin_path) { +- tool.libs.push(atl_lib_path); +- tool.include.push(atl_include_path); +- } +- +- add_sdks(&mut tool, target)?; +- +- Some(tool.into_tool()) +- } +- +- fn vs15plus_vc_paths( +- target: &str, +- instance_path: &PathBuf, +- ) -> Option<(PathBuf, PathBuf, PathBuf, PathBuf)> { +- let version_path = +- instance_path.join(r"VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt"); +- let mut version_file = File::open(version_path).ok()?; +- let mut version = String::new(); +- version_file.read_to_string(&mut version).ok()?; +- let version = version.trim(); +- let host = match host_arch() { +- X86 => "X86", +- X86_64 => "X64", +- // There is no natively hosted compiler on ARM64. +- // Instead, use the x86 toolchain under emulation (there is no x64 emulation). +- AARCH64 => "X86", +- _ => return None, +- }; +- let target = lib_subdir(target)?; +- // The directory layout here is MSVC/bin/Host$host/$target/ +- let path = instance_path.join(r"VC\Tools\MSVC").join(version); +- // This is the path to the toolchain for a particular target, running +- // on a given host +- let bin_path = path +- .join("bin") +- .join(&format!("Host{}", host)) +- .join(&target); +- // But! we also need PATH to contain the target directory for the host +- // architecture, because it contains dlls like mspdb140.dll compiled for +- // the host architecture. +- let host_dylib_path = path +- .join("bin") +- .join(&format!("Host{}", host)) +- .join(&host.to_lowercase()); +- let lib_path = path.join("lib").join(&target); +- let include_path = path.join("include"); +- Some((bin_path, host_dylib_path, lib_path, include_path)) +- } +- +- fn atl_paths(target: &str, path: &Path) -> Option<(PathBuf, PathBuf)> { +- let atl_path = path.join("atlmfc"); +- let sub = lib_subdir(target)?; +- if atl_path.exists() { +- Some((atl_path.join("lib").join(sub), atl_path.join("include"))) +- } else { +- None +- } +- } +- +- // For MSVC 14 we need to find the Universal CRT as well as either +- // the Windows 10 SDK or Windows 8.1 SDK. +- pub fn find_msvc_14(tool: &str, target: &str) -> Option { +- let vcdir = get_vc_dir("14.0")?; +- let mut tool = get_tool(tool, &vcdir, target)?; +- add_sdks(&mut tool, target)?; +- Some(tool.into_tool()) +- } +- +- fn add_sdks(tool: &mut MsvcTool, target: &str) -> Option<()> { +- let sub = lib_subdir(target)?; +- let (ucrt, ucrt_version) = get_ucrt_dir()?; +- +- let host = match host_arch() { +- X86 => "x86", +- X86_64 => "x64", +- AARCH64 => "arm64", +- _ => return None, +- }; +- +- tool.path +- .push(ucrt.join("bin").join(&ucrt_version).join(host)); +- +- let ucrt_include = ucrt.join("include").join(&ucrt_version); +- tool.include.push(ucrt_include.join("ucrt")); +- +- let ucrt_lib = ucrt.join("lib").join(&ucrt_version); +- tool.libs.push(ucrt_lib.join("ucrt").join(sub)); +- +- if let Some((sdk, version)) = get_sdk10_dir() { +- tool.path.push(sdk.join("bin").join(host)); +- let sdk_lib = sdk.join("lib").join(&version); +- tool.libs.push(sdk_lib.join("um").join(sub)); +- let sdk_include = sdk.join("include").join(&version); +- tool.include.push(sdk_include.join("um")); +- tool.include.push(sdk_include.join("cppwinrt")); +- tool.include.push(sdk_include.join("winrt")); +- tool.include.push(sdk_include.join("shared")); +- } else if let Some(sdk) = get_sdk81_dir() { +- tool.path.push(sdk.join("bin").join(host)); +- let sdk_lib = sdk.join("lib").join("winv6.3"); +- tool.libs.push(sdk_lib.join("um").join(sub)); +- let sdk_include = sdk.join("include"); +- tool.include.push(sdk_include.join("um")); +- tool.include.push(sdk_include.join("winrt")); +- tool.include.push(sdk_include.join("shared")); +- } +- +- Some(()) +- } +- +- // For MSVC 12 we need to find the Windows 8.1 SDK. +- pub fn find_msvc_12(tool: &str, target: &str) -> Option { +- let vcdir = get_vc_dir("12.0")?; +- let mut tool = get_tool(tool, &vcdir, target)?; +- let sub = lib_subdir(target)?; +- let sdk81 = get_sdk81_dir()?; +- tool.path.push(sdk81.join("bin").join(sub)); +- let sdk_lib = sdk81.join("lib").join("winv6.3"); +- tool.libs.push(sdk_lib.join("um").join(sub)); +- let sdk_include = sdk81.join("include"); +- tool.include.push(sdk_include.join("shared")); +- tool.include.push(sdk_include.join("um")); +- tool.include.push(sdk_include.join("winrt")); +- Some(tool.into_tool()) +- } +- +- // For MSVC 11 we need to find the Windows 8 SDK. +- pub fn find_msvc_11(tool: &str, target: &str) -> Option { +- let vcdir = get_vc_dir("11.0")?; +- let mut tool = get_tool(tool, &vcdir, target)?; +- let sub = lib_subdir(target)?; +- let sdk8 = get_sdk8_dir()?; +- tool.path.push(sdk8.join("bin").join(sub)); +- let sdk_lib = sdk8.join("lib").join("win8"); +- tool.libs.push(sdk_lib.join("um").join(sub)); +- let sdk_include = sdk8.join("include"); +- tool.include.push(sdk_include.join("shared")); +- tool.include.push(sdk_include.join("um")); +- tool.include.push(sdk_include.join("winrt")); +- Some(tool.into_tool()) +- } +- +- fn add_env(tool: &mut Tool, env: &str, paths: Vec) { +- let prev = env::var_os(env).unwrap_or(OsString::new()); +- let prev = env::split_paths(&prev); +- let new = paths.into_iter().chain(prev); +- tool.env +- .push((env.to_string().into(), env::join_paths(new).unwrap())); +- } +- +- // Given a possible MSVC installation directory, we look for the linker and +- // then add the MSVC library path. +- fn get_tool(tool: &str, path: &Path, target: &str) -> Option { +- bin_subdir(target) +- .into_iter() +- .map(|(sub, host)| { +- ( +- path.join("bin").join(sub).join(tool), +- path.join("bin").join(host), +- ) +- }) +- .filter(|&(ref path, _)| path.is_file()) +- .map(|(path, host)| { +- let mut tool = MsvcTool::new(path); +- tool.path.push(host); +- tool +- }) +- .filter_map(|mut tool| { +- let sub = vc_lib_subdir(target)?; +- tool.libs.push(path.join("lib").join(sub)); +- tool.include.push(path.join("include")); +- let atlmfc_path = path.join("atlmfc"); +- if atlmfc_path.exists() { +- tool.libs.push(atlmfc_path.join("lib").join(sub)); +- tool.include.push(atlmfc_path.join("include")); +- } +- Some(tool) +- }) +- .next() +- } +- +- // To find MSVC we look in a specific registry key for the version we are +- // trying to find. +- fn get_vc_dir(ver: &str) -> Option { +- let key = r"SOFTWARE\Microsoft\VisualStudio\SxS\VC7"; +- let key = LOCAL_MACHINE.open(key.as_ref()).ok()?; +- let path = key.query_str(ver).ok()?; +- Some(path.into()) +- } +- +- // To find the Universal CRT we look in a specific registry key for where +- // all the Universal CRTs are located and then sort them asciibetically to +- // find the newest version. While this sort of sorting isn't ideal, it is +- // what vcvars does so that's good enough for us. +- // +- // Returns a pair of (root, version) for the ucrt dir if found +- fn get_ucrt_dir() -> Option<(PathBuf, String)> { +- let key = r"SOFTWARE\Microsoft\Windows Kits\Installed Roots"; +- let key = LOCAL_MACHINE.open(key.as_ref()).ok()?; +- let root = key.query_str("KitsRoot10").ok()?; +- let readdir = Path::new(&root).join("lib").read_dir().ok()?; +- let max_libdir = readdir +- .filter_map(|dir| dir.ok()) +- .map(|dir| dir.path()) +- .filter(|dir| { +- dir.components() +- .last() +- .and_then(|c| c.as_os_str().to_str()) +- .map(|c| c.starts_with("10.") && dir.join("ucrt").is_dir()) +- .unwrap_or(false) +- }) +- .max()?; +- let version = max_libdir.components().last().unwrap(); +- let version = version.as_os_str().to_str().unwrap().to_string(); +- Some((root.into(), version)) +- } +- +- // Vcvars finds the correct version of the Windows 10 SDK by looking +- // for the include `um\Windows.h` because sometimes a given version will +- // only have UCRT bits without the rest of the SDK. Since we only care about +- // libraries and not includes, we instead look for `um\x64\kernel32.lib`. +- // Since the 32-bit and 64-bit libraries are always installed together we +- // only need to bother checking x64, making this code a tiny bit simpler. +- // Like we do for the Universal CRT, we sort the possibilities +- // asciibetically to find the newest one as that is what vcvars does. +- fn get_sdk10_dir() -> Option<(PathBuf, String)> { +- let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0"; +- let key = LOCAL_MACHINE.open(key.as_ref()).ok()?; +- let root = key.query_str("InstallationFolder").ok()?; +- let readdir = Path::new(&root).join("lib").read_dir().ok()?; +- let mut dirs = readdir +- .filter_map(|dir| dir.ok()) +- .map(|dir| dir.path()) +- .collect::>(); +- dirs.sort(); +- let dir = dirs +- .into_iter() +- .rev() +- .filter(|dir| dir.join("um").join("x64").join("kernel32.lib").is_file()) +- .next()?; +- let version = dir.components().last().unwrap(); +- let version = version.as_os_str().to_str().unwrap().to_string(); +- Some((root.into(), version)) +- } +- +- // Interestingly there are several subdirectories, `win7` `win8` and +- // `winv6.3`. Vcvars seems to only care about `winv6.3` though, so the same +- // applies to us. Note that if we were targetting kernel mode drivers +- // instead of user mode applications, we would care. +- fn get_sdk81_dir() -> Option { +- let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.1"; +- let key = LOCAL_MACHINE.open(key.as_ref()).ok()?; +- let root = key.query_str("InstallationFolder").ok()?; +- Some(root.into()) +- } +- +- fn get_sdk8_dir() -> Option { +- let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0"; +- let key = LOCAL_MACHINE.open(key.as_ref()).ok()?; +- let root = key.query_str("InstallationFolder").ok()?; +- Some(root.into()) +- } +- +- const PROCESSOR_ARCHITECTURE_INTEL: u16 = 0; +- const PROCESSOR_ARCHITECTURE_AMD64: u16 = 9; +- const PROCESSOR_ARCHITECTURE_ARM64: u16 = 12; +- const X86: u16 = PROCESSOR_ARCHITECTURE_INTEL; +- const X86_64: u16 = PROCESSOR_ARCHITECTURE_AMD64; +- const AARCH64: u16 = PROCESSOR_ARCHITECTURE_ARM64; +- +- // When choosing the tool to use, we have to choose the one which matches +- // the target architecture. Otherwise we end up in situations where someone +- // on 32-bit Windows is trying to cross compile to 64-bit and it tries to +- // invoke the native 64-bit compiler which won't work. +- // +- // For the return value of this function, the first member of the tuple is +- // the folder of the tool we will be invoking, while the second member is +- // the folder of the host toolchain for that tool which is essential when +- // using a cross linker. We return a Vec since on x64 there are often two +- // linkers that can target the architecture we desire. The 64-bit host +- // linker is preferred, and hence first, due to 64-bit allowing it more +- // address space to work with and potentially being faster. +- fn bin_subdir(target: &str) -> Vec<(&'static str, &'static str)> { +- let arch = target.split('-').next().unwrap(); +- match (arch, host_arch()) { +- ("i586", X86) | ("i686", X86) => vec![("", "")], +- ("i586", X86_64) | ("i686", X86_64) => vec![("amd64_x86", "amd64"), ("", "")], +- ("x86_64", X86) => vec![("x86_amd64", "")], +- ("x86_64", X86_64) => vec![("amd64", "amd64"), ("x86_amd64", "")], +- ("arm", X86) | ("thumbv7a", X86) => vec![("x86_arm", "")], +- ("arm", X86_64) | ("thumbv7a", X86_64) => vec![("amd64_arm", "amd64"), ("x86_arm", "")], +- _ => vec![], +- } +- } +- +- fn lib_subdir(target: &str) -> Option<&'static str> { +- let arch = target.split('-').next().unwrap(); +- match arch { +- "i586" | "i686" => Some("x86"), +- "x86_64" => Some("x64"), +- "arm" | "thumbv7a" => Some("arm"), +- "aarch64" => Some("arm64"), +- _ => None, +- } +- } +- +- // MSVC's x86 libraries are not in a subfolder +- fn vc_lib_subdir(target: &str) -> Option<&'static str> { +- let arch = target.split('-').next().unwrap(); +- match arch { +- "i586" | "i686" => Some(""), +- "x86_64" => Some("amd64"), +- "arm" | "thumbv7a" => Some("arm"), +- "aarch64" => Some("arm64"), +- _ => None, +- } +- } +- +- #[allow(bad_style)] +- fn host_arch() -> u16 { +- type DWORD = u32; +- type WORD = u16; +- type LPVOID = *mut u8; +- type DWORD_PTR = usize; +- +- #[repr(C)] +- struct SYSTEM_INFO { +- wProcessorArchitecture: WORD, +- _wReserved: WORD, +- _dwPageSize: DWORD, +- _lpMinimumApplicationAddress: LPVOID, +- _lpMaximumApplicationAddress: LPVOID, +- _dwActiveProcessorMask: DWORD_PTR, +- _dwNumberOfProcessors: DWORD, +- _dwProcessorType: DWORD, +- _dwAllocationGranularity: DWORD, +- _wProcessorLevel: WORD, +- _wProcessorRevision: WORD, +- } +- +- extern "system" { +- fn GetNativeSystemInfo(lpSystemInfo: *mut SYSTEM_INFO); +- } +- +- unsafe { +- let mut info = mem::zeroed(); +- GetNativeSystemInfo(&mut info); +- info.wProcessorArchitecture +- } +- } +- +- // Given a registry key, look at all the sub keys and find the one which has +- // the maximal numeric value. +- // +- // Returns the name of the maximal key as well as the opened maximal key. +- fn max_version(key: &RegistryKey) -> Option<(OsString, RegistryKey)> { +- let mut max_vers = 0; +- let mut max_key = None; +- for subkey in key.iter().filter_map(|k| k.ok()) { +- let val = subkey +- .to_str() +- .and_then(|s| s.trim_left_matches("v").replace(".", "").parse().ok()); +- let val = match val { +- Some(s) => s, +- None => continue, +- }; +- if val > max_vers { +- if let Ok(k) = key.open(&subkey) { +- max_vers = val; +- max_key = Some((subkey, k)); +- } +- } +- } +- max_key +- } +- +- pub fn has_msbuild_version(version: &str) -> bool { +- match version { +- "16.0" => { +- find_msbuild_vs16("x86_64-pc-windows-msvc").is_some() +- || find_msbuild_vs16("i686-pc-windows-msvc").is_some() +- } +- "15.0" => { +- find_msbuild_vs15("x86_64-pc-windows-msvc").is_some() +- || find_msbuild_vs15("i686-pc-windows-msvc").is_some() +- } +- "12.0" | "14.0" => LOCAL_MACHINE +- .open(&OsString::from(format!( +- "SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\{}", +- version +- ))) +- .is_ok(), +- _ => false, +- } +- } +- +- pub fn find_devenv(target: &str) -> Option { +- find_devenv_vs15(&target) +- } +- +- fn find_devenv_vs15(target: &str) -> Option { +- find_tool_in_vs15_path(r"Common7\IDE\devenv.exe", target) +- } +- +- // see http://stackoverflow.com/questions/328017/path-to-msbuild +- pub fn find_msbuild(target: &str) -> Option { +- // VS 15 (2017) changed how to locate msbuild +- if let Some(r) = find_msbuild_vs16(target) { +- return Some(r); +- } else if let Some(r) = find_msbuild_vs15(target) { +- return Some(r); +- } else { +- find_old_msbuild(target) +- } +- } +- +- fn find_msbuild_vs15(target: &str) -> Option { +- find_tool_in_vs15_path(r"MSBuild\15.0\Bin\MSBuild.exe", target) +- } +- +- fn find_old_msbuild(target: &str) -> Option { +- let key = r"SOFTWARE\Microsoft\MSBuild\ToolsVersions"; +- LOCAL_MACHINE +- .open(key.as_ref()) +- .ok() +- .and_then(|key| { +- max_version(&key).and_then(|(_vers, key)| key.query_str("MSBuildToolsPath").ok()) +- }) +- .map(|path| { +- let mut path = PathBuf::from(path); +- path.push("MSBuild.exe"); +- let mut tool = Tool::with_family(path, MSVC_FAMILY); +- if target.contains("x86_64") { +- tool.env.push(("Platform".into(), "X64".into())); +- } +- tool +- }) +- } +-} +diff --git a/vendor/cc/tests/cc_env.rs b/vendor/cc/tests/cc_env.rs +deleted file mode 100644 +index 43eb689..0000000 +--- a/vendor/cc/tests/cc_env.rs ++++ /dev/null +@@ -1,118 +0,0 @@ +-use std::env; +-use std::ffi::OsString; +-use std::path::Path; +- +-mod support; +-use crate::support::Test; +- +-#[test] +-fn main() { +- ccache(); +- distcc(); +- ccache_spaces(); +- ccache_env_flags(); +- leading_spaces(); +- extra_flags(); +- path_to_ccache(); +- more_spaces(); +-} +- +-fn ccache() { +- let test = Test::gnu(); +- +- env::set_var("CC", "ccache cc"); +- let compiler = test.gcc().file("foo.c").get_compiler(); +- +- assert_eq!(compiler.path(), Path::new("cc")); +-} +- +-fn ccache_spaces() { +- let test = Test::gnu(); +- test.shim("ccache"); +- +- env::set_var("CC", "ccache cc"); +- let compiler = test.gcc().file("foo.c").get_compiler(); +- assert_eq!(compiler.path(), Path::new("cc")); +-} +- +-fn distcc() { +- let test = Test::gnu(); +- test.shim("distcc"); +- +- env::set_var("CC", "distcc cc"); +- let compiler = test.gcc().file("foo.c").get_compiler(); +- assert_eq!(compiler.path(), Path::new("cc")); +-} +- +-fn ccache_env_flags() { +- let test = Test::gnu(); +- test.shim("ccache"); +- +- env::set_var("CC", "ccache lol-this-is-not-a-compiler"); +- let compiler = test.gcc().file("foo.c").get_compiler(); +- assert_eq!(compiler.path(), Path::new("lol-this-is-not-a-compiler")); +- assert_eq!( +- compiler.cc_env(), +- OsString::from("ccache lol-this-is-not-a-compiler") +- ); +- assert!( +- compiler +- .cflags_env() +- .into_string() +- .unwrap() +- .contains("ccache") +- == false +- ); +- assert!( +- compiler +- .cflags_env() +- .into_string() +- .unwrap() +- .contains(" lol-this-is-not-a-compiler") +- == false +- ); +- +- env::set_var("CC", ""); +-} +- +-fn leading_spaces() { +- let test = Test::gnu(); +- test.shim("ccache"); +- +- env::set_var("CC", " test "); +- let compiler = test.gcc().file("foo.c").get_compiler(); +- assert_eq!(compiler.path(), Path::new("test")); +- +- env::set_var("CC", ""); +-} +- +-fn extra_flags() { +- let test = Test::gnu(); +- test.shim("ccache"); +- +- env::set_var("CC", "ccache cc -m32"); +- let compiler = test.gcc().file("foo.c").get_compiler(); +- assert_eq!(compiler.path(), Path::new("cc")); +-} +- +-fn path_to_ccache() { +- let test = Test::gnu(); +- test.shim("ccache"); +- +- env::set_var("CC", "/path/to/ccache.exe cc -m32"); +- let compiler = test.gcc().file("foo.c").get_compiler(); +- assert_eq!(compiler.path(), Path::new("cc")); +- assert_eq!( +- compiler.cc_env(), +- OsString::from("/path/to/ccache.exe cc -m32"), +- ); +-} +- +-fn more_spaces() { +- let test = Test::gnu(); +- test.shim("ccache"); +- +- env::set_var("CC", "cc -m32"); +- let compiler = test.gcc().file("foo.c").get_compiler(); +- assert_eq!(compiler.path(), Path::new("cc")); +-} +diff --git a/vendor/cc/tests/cflags.rs b/vendor/cc/tests/cflags.rs +deleted file mode 100644 +index caec6ea..0000000 +--- a/vendor/cc/tests/cflags.rs ++++ /dev/null +@@ -1,15 +0,0 @@ +-mod support; +- +-use crate::support::Test; +-use std::env; +- +-/// This test is in its own module because it modifies the environment and would affect other tests +-/// when run in parallel with them. +-#[test] +-fn gnu_no_warnings_if_cflags() { +- env::set_var("CFLAGS", "-arbitrary"); +- let test = Test::gnu(); +- test.gcc().file("foo.c").compile("foo"); +- +- test.cmd(0).must_not_have("-Wall").must_not_have("-Wextra"); +-} +diff --git a/vendor/cc/tests/cxxflags.rs b/vendor/cc/tests/cxxflags.rs +deleted file mode 100644 +index c524c7d..0000000 +--- a/vendor/cc/tests/cxxflags.rs ++++ /dev/null +@@ -1,15 +0,0 @@ +-mod support; +- +-use crate::support::Test; +-use std::env; +- +-/// This test is in its own module because it modifies the environment and would affect other tests +-/// when run in parallel with them. +-#[test] +-fn gnu_no_warnings_if_cxxflags() { +- env::set_var("CXXFLAGS", "-arbitrary"); +- let test = Test::gnu(); +- test.gcc().file("foo.cpp").cpp(true).compile("foo"); +- +- test.cmd(0).must_not_have("-Wall").must_not_have("-Wextra"); +-} +diff --git a/vendor/cc/tests/support/mod.rs b/vendor/cc/tests/support/mod.rs +deleted file mode 100644 +index cde930e..0000000 +--- a/vendor/cc/tests/support/mod.rs ++++ /dev/null +@@ -1,173 +0,0 @@ +-#![allow(dead_code)] +- +-use std::env; +-use std::ffi::{OsStr, OsString}; +-use std::fs::{self, File}; +-use std::io; +-use std::io::prelude::*; +-use std::path::{Path, PathBuf}; +- +-use cc; +-use tempfile::{Builder, TempDir}; +- +-pub struct Test { +- pub td: TempDir, +- pub gcc: PathBuf, +- pub msvc: bool, +-} +- +-pub struct Execution { +- args: Vec, +-} +- +-impl Test { +- pub fn new() -> Test { +- // This is ugly: `sccache` needs to introspect the compiler it is +- // executing, as it adjusts its behavior depending on the +- // language/compiler. This crate's test driver uses mock compilers that +- // are obviously not supported by sccache, so the tests fail if +- // RUSTC_WRAPPER is set. rust doesn't build test dependencies with +- // the `test` feature enabled, so we can't conditionally disable the +- // usage of `sccache` if running in a test environment, at least not +- // without setting an environment variable here and testing for it +- // there. Explicitly deasserting RUSTC_WRAPPER here seems to be the +- // lesser of the two evils. +- env::remove_var("RUSTC_WRAPPER"); +- +- let mut gcc = PathBuf::from(env::current_exe().unwrap()); +- gcc.pop(); +- if gcc.ends_with("deps") { +- gcc.pop(); +- } +- let td = Builder::new().prefix("gcc-test").tempdir_in(&gcc).unwrap(); +- gcc.push(format!("gcc-shim{}", env::consts::EXE_SUFFIX)); +- Test { +- td: td, +- gcc: gcc, +- msvc: false, +- } +- } +- +- pub fn gnu() -> Test { +- let t = Test::new(); +- t.shim("cc").shim("c++").shim("ar"); +- t +- } +- +- pub fn msvc() -> Test { +- let mut t = Test::new(); +- t.shim("cl").shim("lib.exe"); +- t.msvc = true; +- t +- } +- +- pub fn shim(&self, name: &str) -> &Test { +- link_or_copy( +- &self.gcc, +- self.td +- .path() +- .join(&format!("{}{}", name, env::consts::EXE_SUFFIX)), +- ) +- .unwrap(); +- self +- } +- +- pub fn gcc(&self) -> cc::Build { +- let mut cfg = cc::Build::new(); +- let target = if self.msvc { +- "x86_64-pc-windows-msvc" +- } else { +- "x86_64-unknown-linux-gnu" +- }; +- +- cfg.target(target) +- .host(target) +- .opt_level(2) +- .debug(false) +- .out_dir(self.td.path()) +- .__set_env("PATH", self.path()) +- .__set_env("GCCTEST_OUT_DIR", self.td.path()); +- if self.msvc { +- cfg.compiler(self.td.path().join("cl")); +- cfg.archiver(self.td.path().join("lib.exe")); +- } +- cfg +- } +- +- fn path(&self) -> OsString { +- let mut path = env::split_paths(&env::var_os("PATH").unwrap()).collect::>(); +- path.insert(0, self.td.path().to_owned()); +- env::join_paths(path).unwrap() +- } +- +- pub fn cmd(&self, i: u32) -> Execution { +- let mut s = String::new(); +- File::open(self.td.path().join(format!("out{}", i))) +- .unwrap() +- .read_to_string(&mut s) +- .unwrap(); +- Execution { +- args: s.lines().map(|s| s.to_string()).collect(), +- } +- } +-} +- +-impl Execution { +- pub fn must_have>(&self, p: P) -> &Execution { +- if !self.has(p.as_ref()) { +- panic!("didn't find {:?} in {:?}", p.as_ref(), self.args); +- } else { +- self +- } +- } +- +- pub fn must_not_have>(&self, p: P) -> &Execution { +- if self.has(p.as_ref()) { +- panic!("found {:?}", p.as_ref()); +- } else { +- self +- } +- } +- +- pub fn has(&self, p: &OsStr) -> bool { +- self.args.iter().any(|arg| OsStr::new(arg) == p) +- } +- +- pub fn must_have_in_order(&self, before: &str, after: &str) -> &Execution { +- let before_position = self +- .args +- .iter() +- .rposition(|x| OsStr::new(x) == OsStr::new(before)); +- let after_position = self +- .args +- .iter() +- .rposition(|x| OsStr::new(x) == OsStr::new(after)); +- match (before_position, after_position) { +- (Some(b), Some(a)) if b < a => {} +- (b, a) => panic!( +- "{:?} (last position: {:?}) did not appear before {:?} (last position: {:?})", +- before, b, after, a +- ), +- }; +- self +- } +-} +- +-/// Hard link an executable or copy it if that fails. +-/// +-/// We first try to hard link an executable to save space. If that fails (as on Windows with +-/// different mount points, issue #60), we copy. +-#[cfg(not(target_os = "macos"))] +-fn link_or_copy, Q: AsRef>(from: P, to: Q) -> io::Result<()> { +- let from = from.as_ref(); +- let to = to.as_ref(); +- fs::hard_link(from, to).or_else(|_| fs::copy(from, to).map(|_| ())) +-} +- +-/// Copy an executable. +-/// +-/// On macOS, hard linking the executable leads to strange failures (issue #419), so we just copy. +-#[cfg(target_os = "macos")] +-fn link_or_copy, Q: AsRef>(from: P, to: Q) -> io::Result<()> { +- fs::copy(from, to).map(|_| ()) +-} +diff --git a/vendor/cc/tests/test.rs b/vendor/cc/tests/test.rs +deleted file mode 100644 +index 3c9b4dc..0000000 +--- a/vendor/cc/tests/test.rs ++++ /dev/null +@@ -1,413 +0,0 @@ +-use crate::support::Test; +- +-mod support; +- +-// Some tests check that a flag is *not* present. These tests might fail if the flag is set in the +-// CFLAGS or CXXFLAGS environment variables. This function clears the CFLAGS and CXXFLAGS +-// variables to make sure that the tests can run correctly. +-fn reset_env() { +- std::env::set_var("CFLAGS", ""); +- std::env::set_var("CXXFLAGS", ""); +-} +- +-#[test] +-fn gnu_smoke() { +- reset_env(); +- +- let test = Test::gnu(); +- test.gcc().file("foo.c").compile("foo"); +- +- test.cmd(0) +- .must_have("-O2") +- .must_have("foo.c") +- .must_not_have("-g") +- .must_have("-c") +- .must_have("-ffunction-sections") +- .must_have("-fdata-sections"); +- test.cmd(1).must_have(test.td.path().join("foo.o")); +-} +- +-#[test] +-fn gnu_opt_level_1() { +- reset_env(); +- +- let test = Test::gnu(); +- test.gcc().opt_level(1).file("foo.c").compile("foo"); +- +- test.cmd(0).must_have("-O1").must_not_have("-O2"); +-} +- +-#[test] +-fn gnu_opt_level_s() { +- reset_env(); +- +- let test = Test::gnu(); +- test.gcc().opt_level_str("s").file("foo.c").compile("foo"); +- +- test.cmd(0) +- .must_have("-Os") +- .must_not_have("-O1") +- .must_not_have("-O2") +- .must_not_have("-O3") +- .must_not_have("-Oz"); +-} +- +-#[test] +-fn gnu_debug_fp_auto() { +- let test = Test::gnu(); +- test.gcc().debug(true).file("foo.c").compile("foo"); +- test.cmd(0).must_have("-g"); +- test.cmd(0).must_have("-fno-omit-frame-pointer"); +-} +- +-#[test] +-fn gnu_debug_fp() { +- let test = Test::gnu(); +- test.gcc().debug(true).file("foo.c").compile("foo"); +- test.cmd(0).must_have("-g"); +- test.cmd(0).must_have("-fno-omit-frame-pointer"); +-} +- +-#[test] +-fn gnu_debug_nofp() { +- reset_env(); +- +- let test = Test::gnu(); +- test.gcc() +- .debug(true) +- .force_frame_pointer(false) +- .file("foo.c") +- .compile("foo"); +- test.cmd(0).must_have("-g"); +- test.cmd(0).must_not_have("-fno-omit-frame-pointer"); +- +- let test = Test::gnu(); +- test.gcc() +- .force_frame_pointer(false) +- .debug(true) +- .file("foo.c") +- .compile("foo"); +- test.cmd(0).must_have("-g"); +- test.cmd(0).must_not_have("-fno-omit-frame-pointer"); +-} +- +-#[test] +-fn gnu_warnings_into_errors() { +- let test = Test::gnu(); +- test.gcc() +- .warnings_into_errors(true) +- .file("foo.c") +- .compile("foo"); +- +- test.cmd(0).must_have("-Werror"); +-} +- +-#[test] +-fn gnu_warnings() { +- let test = Test::gnu(); +- test.gcc() +- .warnings(true) +- .flag("-Wno-missing-field-initializers") +- .file("foo.c") +- .compile("foo"); +- +- test.cmd(0).must_have("-Wall").must_have("-Wextra"); +-} +- +-#[test] +-fn gnu_extra_warnings0() { +- reset_env(); +- +- let test = Test::gnu(); +- test.gcc() +- .warnings(true) +- .extra_warnings(false) +- .flag("-Wno-missing-field-initializers") +- .file("foo.c") +- .compile("foo"); +- +- test.cmd(0).must_have("-Wall").must_not_have("-Wextra"); +-} +- +-#[test] +-fn gnu_extra_warnings1() { +- reset_env(); +- +- let test = Test::gnu(); +- test.gcc() +- .warnings(false) +- .extra_warnings(true) +- .flag("-Wno-missing-field-initializers") +- .file("foo.c") +- .compile("foo"); +- +- test.cmd(0).must_not_have("-Wall").must_have("-Wextra"); +-} +- +-#[test] +-fn gnu_warnings_overridable() { +- reset_env(); +- +- let test = Test::gnu(); +- test.gcc() +- .warnings(true) +- .flag("-Wno-missing-field-initializers") +- .file("foo.c") +- .compile("foo"); +- +- test.cmd(0) +- .must_have_in_order("-Wall", "-Wno-missing-field-initializers"); +-} +- +-#[test] +-fn gnu_x86_64() { +- for vendor in &["unknown-linux-gnu", "apple-darwin"] { +- let target = format!("x86_64-{}", vendor); +- let test = Test::gnu(); +- test.gcc() +- .target(&target) +- .host(&target) +- .file("foo.c") +- .compile("foo"); +- +- test.cmd(0).must_have("-fPIC").must_have("-m64"); +- } +-} +- +-#[test] +-fn gnu_x86_64_no_pic() { +- reset_env(); +- +- for vendor in &["unknown-linux-gnu", "apple-darwin"] { +- let target = format!("x86_64-{}", vendor); +- let test = Test::gnu(); +- test.gcc() +- .pic(false) +- .target(&target) +- .host(&target) +- .file("foo.c") +- .compile("foo"); +- +- test.cmd(0).must_not_have("-fPIC"); +- } +-} +- +-#[test] +-fn gnu_i686() { +- for vendor in &["unknown-linux-gnu", "apple-darwin"] { +- let target = format!("i686-{}", vendor); +- let test = Test::gnu(); +- test.gcc() +- .target(&target) +- .host(&target) +- .file("foo.c") +- .compile("foo"); +- +- test.cmd(0).must_have("-m32"); +- } +-} +- +-#[test] +-fn gnu_i686_pic() { +- for vendor in &["unknown-linux-gnu", "apple-darwin"] { +- let target = format!("i686-{}", vendor); +- let test = Test::gnu(); +- test.gcc() +- .pic(true) +- .target(&target) +- .host(&target) +- .file("foo.c") +- .compile("foo"); +- +- test.cmd(0).must_have("-fPIC"); +- } +-} +- +-#[test] +-fn gnu_x86_64_no_plt() { +- let target = "x86_64-unknown-linux-gnu"; +- let test = Test::gnu(); +- test.gcc() +- .pic(true) +- .use_plt(false) +- .target(&target) +- .host(&target) +- .file("foo.c") +- .compile("foo"); +- test.cmd(0).must_have("-fno-plt"); +-} +- +-#[test] +-fn gnu_set_stdlib() { +- reset_env(); +- +- let test = Test::gnu(); +- test.gcc() +- .cpp_set_stdlib(Some("foo")) +- .file("foo.c") +- .compile("foo"); +- +- test.cmd(0).must_not_have("-stdlib=foo"); +-} +- +-#[test] +-fn gnu_include() { +- let test = Test::gnu(); +- test.gcc().include("foo/bar").file("foo.c").compile("foo"); +- +- test.cmd(0).must_have("-I").must_have("foo/bar"); +-} +- +-#[test] +-fn gnu_define() { +- let test = Test::gnu(); +- test.gcc() +- .define("FOO", "bar") +- .define("BAR", None) +- .file("foo.c") +- .compile("foo"); +- +- test.cmd(0).must_have("-DFOO=bar").must_have("-DBAR"); +-} +- +-#[test] +-fn gnu_compile_assembly() { +- let test = Test::gnu(); +- test.gcc().file("foo.S").compile("foo"); +- test.cmd(0).must_have("foo.S"); +-} +- +-#[test] +-fn gnu_shared() { +- reset_env(); +- +- let test = Test::gnu(); +- test.gcc() +- .file("foo.c") +- .shared_flag(true) +- .static_flag(false) +- .compile("foo"); +- +- test.cmd(0).must_have("-shared").must_not_have("-static"); +-} +- +-#[test] +-fn gnu_flag_if_supported() { +- reset_env(); +- +- if cfg!(windows) { +- return; +- } +- let test = Test::gnu(); +- test.gcc() +- .file("foo.c") +- .flag("-v") +- .flag_if_supported("-Wall") +- .flag_if_supported("-Wflag-does-not-exist") +- .flag_if_supported("-std=c++11") +- .compile("foo"); +- +- test.cmd(0) +- .must_have("-v") +- .must_have("-Wall") +- .must_not_have("-Wflag-does-not-exist") +- .must_not_have("-std=c++11"); +-} +- +-#[test] +-fn gnu_flag_if_supported_cpp() { +- if cfg!(windows) { +- return; +- } +- let test = Test::gnu(); +- test.gcc() +- .cpp(true) +- .file("foo.cpp") +- .flag_if_supported("-std=c++11") +- .compile("foo"); +- +- test.cmd(0).must_have("-std=c++11"); +-} +- +-#[test] +-fn gnu_static() { +- reset_env(); +- +- let test = Test::gnu(); +- test.gcc() +- .file("foo.c") +- .shared_flag(false) +- .static_flag(true) +- .compile("foo"); +- +- test.cmd(0).must_have("-static").must_not_have("-shared"); +-} +- +-#[test] +-fn msvc_smoke() { +- reset_env(); +- +- let test = Test::msvc(); +- test.gcc().file("foo.c").compile("foo"); +- +- test.cmd(0) +- .must_have("-O2") +- .must_have("foo.c") +- .must_not_have("-Z7") +- .must_have("-c") +- .must_have("-MD"); +- test.cmd(1).must_have(test.td.path().join("foo.o")); +-} +- +-#[test] +-fn msvc_opt_level_0() { +- reset_env(); +- +- let test = Test::msvc(); +- test.gcc().opt_level(0).file("foo.c").compile("foo"); +- +- test.cmd(0).must_not_have("-O2"); +-} +- +-#[test] +-fn msvc_debug() { +- let test = Test::msvc(); +- test.gcc().debug(true).file("foo.c").compile("foo"); +- test.cmd(0).must_have("-Z7"); +-} +- +-#[test] +-fn msvc_include() { +- let test = Test::msvc(); +- test.gcc().include("foo/bar").file("foo.c").compile("foo"); +- +- test.cmd(0).must_have("-I").must_have("foo/bar"); +-} +- +-#[test] +-fn msvc_define() { +- let test = Test::msvc(); +- test.gcc() +- .define("FOO", "bar") +- .define("BAR", None) +- .file("foo.c") +- .compile("foo"); +- +- test.cmd(0).must_have("-DFOO=bar").must_have("-DBAR"); +-} +- +-#[test] +-fn msvc_static_crt() { +- let test = Test::msvc(); +- test.gcc().static_crt(true).file("foo.c").compile("foo"); +- +- test.cmd(0).must_have("-MT"); +-} +- +-#[test] +-fn msvc_no_static_crt() { +- let test = Test::msvc(); +- test.gcc().static_crt(false).file("foo.c").compile("foo"); +- +- test.cmd(0).must_have("-MD"); +-} +diff --git a/vendor/cfg-if-0.1.10/.cargo-checksum.json b/vendor/cfg-if-0.1.10/.cargo-checksum.json +deleted file mode 100644 +index c0c9f9d..0000000 +--- a/vendor/cfg-if-0.1.10/.cargo-checksum.json ++++ /dev/null +@@ -1 +0,0 @@ +-{"files":{"Cargo.toml":"2cb2370b62c56a7d51b51f9e405b2f377b3ad6f7f8d33bc69e20eb819ad66012","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"2406e83ee174e30aa67f8ab266836fa78545012b196395aff37c152321e2c713","src/lib.rs":"8dfd667d32d8b06e529643c975dfa14c29ce9a894a80e381a1bd867252e65e56","tests/xcrate.rs":"c0734dae6e63beafcd60bf53546115a2320735b51035c9e2387fdf9301580934"},"package":"4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"} +\ No newline at end of file +diff --git a/vendor/cfg-if-0.1.10/Cargo.toml b/vendor/cfg-if-0.1.10/Cargo.toml +deleted file mode 100644 +index 5da1d1b..0000000 +--- a/vendor/cfg-if-0.1.10/Cargo.toml ++++ /dev/null +@@ -1,36 +0,0 @@ +-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +-# +-# When uploading crates to the registry Cargo will automatically +-# "normalize" Cargo.toml files for maximal compatibility +-# with all versions of Cargo and also rewrite `path` dependencies +-# to registry (e.g., crates.io) dependencies +-# +-# If you believe there's an error in this file please file an +-# issue against the rust-lang/cargo repository. If you're +-# editing this file be aware that the upstream Cargo.toml +-# will likely look very different (and much more reasonable) +- +-[package] +-edition = "2018" +-name = "cfg-if" +-version = "0.1.10" +-authors = ["Alex Crichton "] +-description = "A macro to ergonomically define an item depending on a large number of #[cfg]\nparameters. Structured like an if-else chain, the first matching branch is the\nitem that gets emitted.\n" +-homepage = "https://github.com/alexcrichton/cfg-if" +-documentation = "https://docs.rs/cfg-if" +-readme = "README.md" +-license = "MIT/Apache-2.0" +-repository = "https://github.com/alexcrichton/cfg-if" +-[dependencies.compiler_builtins] +-version = "0.1.2" +-optional = true +- +-[dependencies.core] +-version = "1.0.0" +-optional = true +-package = "rustc-std-workspace-core" +- +-[features] +-rustc-dep-of-std = ["core", "compiler_builtins"] +-[badges.travis-ci] +-repository = "alexcrichton/cfg-if" +diff --git a/vendor/cfg-if-0.1.10/LICENSE-MIT b/vendor/cfg-if-0.1.10/LICENSE-MIT +deleted file mode 100644 +index 39e0ed6..0000000 +--- a/vendor/cfg-if-0.1.10/LICENSE-MIT ++++ /dev/null +@@ -1,25 +0,0 @@ +-Copyright (c) 2014 Alex Crichton +- +-Permission is hereby granted, free of charge, to any +-person obtaining a copy of this software and associated +-documentation files (the "Software"), to deal in the +-Software without restriction, including without +-limitation the rights to use, copy, modify, merge, +-publish, distribute, sublicense, and/or sell copies of +-the Software, and to permit persons to whom the Software +-is furnished to do so, subject to the following +-conditions: +- +-The above copyright notice and this permission notice +-shall be included in all copies or substantial portions +-of the Software. +- +-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +-DEALINGS IN THE SOFTWARE. +diff --git a/vendor/cfg-if-0.1.10/README.md b/vendor/cfg-if-0.1.10/README.md +deleted file mode 100644 +index 50b5e3b..0000000 +--- a/vendor/cfg-if-0.1.10/README.md ++++ /dev/null +@@ -1,47 +0,0 @@ +-# cfg-if +- +-[Documentation](https://docs.rs/cfg-if) +- +-A macro to ergonomically define an item depending on a large number of #[cfg] +-parameters. Structured like an if-else chain, the first matching branch is the +-item that gets emitted. +- +-```toml +-[dependencies] +-cfg-if = "0.1" +-``` +- +-## Example +- +-```rust +-cfg_if::cfg_if! { +- if #[cfg(unix)] { +- fn foo() { /* unix specific functionality */ } +- } else if #[cfg(target_pointer_width = "32")] { +- fn foo() { /* non-unix, 32-bit functionality */ } +- } else { +- fn foo() { /* fallback implementation */ } +- } +-} +- +-fn main() { +- foo(); +-} +-``` +- +-# License +- +-This project is licensed under either of +- +- * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or +- http://www.apache.org/licenses/LICENSE-2.0) +- * MIT license ([LICENSE-MIT](LICENSE-MIT) or +- http://opensource.org/licenses/MIT) +- +-at your option. +- +-### Contribution +- +-Unless you explicitly state otherwise, any contribution intentionally submitted +-for inclusion in `cfg-if` by you, as defined in the Apache-2.0 license, shall be +-dual licensed as above, without any additional terms or conditions. +diff --git a/vendor/cfg-if-0.1.10/src/lib.rs b/vendor/cfg-if-0.1.10/src/lib.rs +deleted file mode 100644 +index 6c5058d..0000000 +--- a/vendor/cfg-if-0.1.10/src/lib.rs ++++ /dev/null +@@ -1,176 +0,0 @@ +-//! A macro for defining `#[cfg]` if-else statements. +-//! +-//! The macro provided by this crate, `cfg_if`, is similar to the `if/elif` C +-//! preprocessor macro by allowing definition of a cascade of `#[cfg]` cases, +-//! emitting the implementation which matches first. +-//! +-//! This allows you to conveniently provide a long list `#[cfg]`'d blocks of code +-//! without having to rewrite each clause multiple times. +-//! +-//! # Example +-//! +-//! ``` +-//! cfg_if::cfg_if! { +-//! if #[cfg(unix)] { +-//! fn foo() { /* unix specific functionality */ } +-//! } else if #[cfg(target_pointer_width = "32")] { +-//! fn foo() { /* non-unix, 32-bit functionality */ } +-//! } else { +-//! fn foo() { /* fallback implementation */ } +-//! } +-//! } +-//! +-//! # fn main() {} +-//! ``` +- +-#![no_std] +-#![doc(html_root_url = "https://docs.rs/cfg-if")] +-#![deny(missing_docs)] +-#![cfg_attr(test, deny(warnings))] +- +-/// The main macro provided by this crate. See crate documentation for more +-/// information. +-#[macro_export] +-macro_rules! cfg_if { +- // match if/else chains with a final `else` +- ($( +- if #[cfg($($meta:meta),*)] { $($tokens:tt)* } +- ) else * else { +- $($tokens2:tt)* +- }) => { +- $crate::cfg_if! { +- @__items +- () ; +- $( ( ($($meta),*) ($($tokens)*) ), )* +- ( () ($($tokens2)*) ), +- } +- }; +- +- // match if/else chains lacking a final `else` +- ( +- if #[cfg($($i_met:meta),*)] { $($i_tokens:tt)* } +- $( +- else if #[cfg($($e_met:meta),*)] { $($e_tokens:tt)* } +- )* +- ) => { +- $crate::cfg_if! { +- @__items +- () ; +- ( ($($i_met),*) ($($i_tokens)*) ), +- $( ( ($($e_met),*) ($($e_tokens)*) ), )* +- ( () () ), +- } +- }; +- +- // Internal and recursive macro to emit all the items +- // +- // Collects all the negated cfgs in a list at the beginning and after the +- // semicolon is all the remaining items +- (@__items ($($not:meta,)*) ; ) => {}; +- (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($tokens:tt)*) ), $($rest:tt)*) => { +- // Emit all items within one block, applying an appropriate #[cfg]. The +- // #[cfg] will require all `$m` matchers specified and must also negate +- // all previous matchers. +- #[cfg(all($($m,)* not(any($($not),*))))] $crate::cfg_if! { @__identity $($tokens)* } +- +- // Recurse to emit all other items in `$rest`, and when we do so add all +- // our `$m` matchers to the list of `$not` matchers as future emissions +- // will have to negate everything we just matched as well. +- $crate::cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* } +- }; +- +- // Internal macro to make __apply work out right for different match types, +- // because of how macros matching/expand stuff. +- (@__identity $($tokens:tt)*) => { +- $($tokens)* +- }; +-} +- +-#[cfg(test)] +-mod tests { +- cfg_if! { +- if #[cfg(test)] { +- use core::option::Option as Option2; +- fn works1() -> Option2 { Some(1) } +- } else { +- fn works1() -> Option { None } +- } +- } +- +- cfg_if! { +- if #[cfg(foo)] { +- fn works2() -> bool { false } +- } else if #[cfg(test)] { +- fn works2() -> bool { true } +- } else { +- fn works2() -> bool { false } +- } +- } +- +- cfg_if! { +- if #[cfg(foo)] { +- fn works3() -> bool { false } +- } else { +- fn works3() -> bool { true } +- } +- } +- +- cfg_if! { +- if #[cfg(test)] { +- use core::option::Option as Option3; +- fn works4() -> Option3 { Some(1) } +- } +- } +- +- cfg_if! { +- if #[cfg(foo)] { +- fn works5() -> bool { false } +- } else if #[cfg(test)] { +- fn works5() -> bool { true } +- } +- } +- +- #[test] +- fn it_works() { +- assert!(works1().is_some()); +- assert!(works2()); +- assert!(works3()); +- assert!(works4().is_some()); +- assert!(works5()); +- } +- +- #[test] +- #[allow(clippy::assertions_on_constants)] +- fn test_usage_within_a_function() { +- cfg_if! {if #[cfg(debug_assertions)] { +- // we want to put more than one thing here to make sure that they +- // all get configured properly. +- assert!(cfg!(debug_assertions)); +- assert_eq!(4, 2+2); +- } else { +- assert!(works1().is_some()); +- assert_eq!(10, 5+5); +- }} +- } +- +- trait Trait { +- fn blah(&self); +- } +- +- #[allow(dead_code)] +- struct Struct; +- +- impl Trait for Struct { +- cfg_if! { +- if #[cfg(feature = "blah")] { +- fn blah(&self) { +- unimplemented!(); +- } +- } else { +- fn blah(&self) { +- unimplemented!(); +- } +- } +- } +- } +-} +diff --git a/vendor/cfg-if-0.1.10/tests/xcrate.rs b/vendor/cfg-if-0.1.10/tests/xcrate.rs +deleted file mode 100644 +index e7b4a36..0000000 +--- a/vendor/cfg-if-0.1.10/tests/xcrate.rs ++++ /dev/null +@@ -1,14 +0,0 @@ +-cfg_if::cfg_if! { +- if #[cfg(foo)] { +- fn works() -> bool { false } +- } else if #[cfg(test)] { +- fn works() -> bool { true } +- } else { +- fn works() -> bool { false } +- } +-} +- +-#[test] +-fn smoke() { +- assert!(works()); +-} +diff --git a/vendor/libc/.cargo-checksum.json b/vendor/libc/.cargo-checksum.json +index 9fb4ab8..b89a9cf 100644 +--- a/vendor/libc/.cargo-checksum.json ++++ b/vendor/libc/.cargo-checksum.json +@@ -1 +1 @@ +-{"files":{"CONTRIBUTING.md":"752eea5a703d11b485c6b5f195f51bd2c79aa5159b619ce09555c779e1fb586b","Cargo.toml":"aa731450974dd87888707735003b1741e1c3aa49efb58f6884f74c762bf4dd34","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"a8d47ff51ca256f56a8932dba07660672dbfe3004257ca8de708aac1415937a1","README.md":"8228847944f1332882fbb00275b6f30e4a8aad08a13569c25d52cac012cc2a47","build.rs":"8e0e8d33cc9e7c25cde75c2b502420f943266a681024169f94084774b422681d","rustfmt.toml":"eaa2ea84fc1ba0359b77680804903e07bb38d257ab11986b95b158e460f787b2","src/fixed_width_ints.rs":"34c60f12ec5eeb90f13ec3b954427532111c2446e69617616a97aefc1086a9f1","src/fuchsia/aarch64.rs":"378776a9e40766154a54c94c2a7b4675b5c302a38e6e42da99e67bfbaee60e56","src/fuchsia/align.rs":"ae1cf8f011a99737eabeb14ffff768e60f13b13363d7646744dbb0f443dab3d6","src/fuchsia/mod.rs":"dd7a673e4da1e476551af578be02d0409b65db43132a7fd4b5ffd222b171db56","src/fuchsia/no_align.rs":"303f3f1b255e0088b5715094353cf00476131d8e94e6aebb3f469557771c8b8a","src/fuchsia/x86_64.rs":"93a3632b5cf67d2a6bcb7dc0a558605252d5fe689e0f38d8aa2ec5852255ac87","src/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/hermit/mod.rs":"d3bfce41e4463d4be8020a2d063c9bfa8b665f45f1cc6cbf3163f5d01e7cb21f","src/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/lib.rs":"d4f7452c0fe720f3a961b918b74ec86d19cef33e6b4aac08efbbad6f6d818e09","src/macros.rs":"7844312c233a6889fa15395fe3106f6a8f6229211104a92f33ea3c9536eef763","src/psp.rs":"dd31aabd46171d474ec5828372e28588935120e7355c90c105360d8fa9264c1c","src/sgx.rs":"16a95cdefc81c5ee00d8353a60db363c4cc3e0f75abcd5d0144723f2a306ed1b","src/switch.rs":"9da3dd39b3de45a7928789926e8572d00e1e11a39e6f7289a1349aadce90edba","src/unix/align.rs":"2cdc7c826ef7ae61f5171c5ae8c445a743d86f1a7f2d9d7e4ceeec56d6874f65","src/unix/bsd/apple/b32/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b32/mod.rs":"6a4ce300da0d2b0db04b18548286603ffe4b47d679a41cf60f1902895894aa1f","src/unix/bsd/apple/b64/aarch64/align.rs":"f0c321265dd7671f16106b84951ac7dd77ed2e65c6623cbf2d29e76531984770","src/unix/bsd/apple/b64/aarch64/mod.rs":"46d5d061c7a74cbc09cbdfb3bee9a600867bf4e04c0e4d0ca6c817e6033b32e1","src/unix/bsd/apple/b64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/mod.rs":"f5e278a1af7fb358891d1c9be4eb7e815aaca0c5cb738d0c3604ba2208a856f7","src/unix/bsd/apple/b64/x86_64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/x86_64/mod.rs":"cc6878dd130c3f255418e4da74992ae9ba6a3cdb0530772de76c518077d3b12a","src/unix/bsd/apple/mod.rs":"2fb2750861f0d057c62088ffcccf62a9e20393c76e39e1349100212eabc6dfc8","src/unix/bsd/freebsdlike/dragonfly/errno.rs":"8295b8bb0dfd38d2cdb4d9192cdeeb534cc6c3b208170e64615fa3e0edb3e578","src/unix/bsd/freebsdlike/dragonfly/mod.rs":"50e93d3081b5cf87669d91e9fa96026902153f033c272d60cbe8e8a6f9a8f620","src/unix/bsd/freebsdlike/freebsd/aarch64.rs":"14f0bd6693967d4fedec904f7042bd51f2138cb843ec4df18c911b357417cdd2","src/unix/bsd/freebsdlike/freebsd/arm.rs":"59d6a670eea562fb87686e243e0a84603d29a2028a3d4b3f99ccc01bd04d2f47","src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs":"9808d152c1196aa647f1b0f0cf84dac8c930da7d7f897a44975545e3d9d17681","src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs":"6523af60c0e4937ad374003c1653e9e721f5b6f11572c747732f76522d07d034","src/unix/bsd/freebsdlike/freebsd/freebsd12/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs":"c0e8a99f61efed0578f92918d60d445d25463e9aed782675025d191cc0fae9bf","src/unix/bsd/freebsdlike/freebsd/freebsd13/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs":"40e43d320fc2466e34db474290da24bd66d5d80c41245db73caa1325a1900f83","src/unix/bsd/freebsdlike/freebsd/mod.rs":"41d515604759841da5ff0a9cf679ef0ccd11e1c5550824822272893145e2376c","src/unix/bsd/freebsdlike/freebsd/powerpc64.rs":"2dae3ecc87eac3b11657aa98915def55fc4b5c0de11fe26aae23329a54628a9a","src/unix/bsd/freebsdlike/freebsd/x86.rs":"c5005e3249eb7c93cfbac72a9e9272320d80ce7983da990ceb05a447f59a02c5","src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs":"0e1f69a88fca1c32874b1daf5db3d446fefbe518dca497f096cc9168c39dde70","src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs":"6132aa0973454379674ea6cbc77e6eace1e1032dd9f38182071388a036f1bc08","src/unix/bsd/freebsdlike/mod.rs":"dcc6bffbc77e84ff405ae4ea1b123984e51a46e65ed643008771b1db3f62960b","src/unix/bsd/mod.rs":"33df9bc4e6f92f78842defe59d9ac2c2afa0942ba990134ec0bf57aa76faa798","src/unix/bsd/netbsdlike/mod.rs":"e627dea0f663deb311f7428b5ca54c0363789c154e3648835699a00b25d32489","src/unix/bsd/netbsdlike/netbsd/aarch64.rs":"b38fc046f9a40fea28bd26328b96629f4d5d63d7524936bd6af1865d401a8716","src/unix/bsd/netbsdlike/netbsd/arm.rs":"58cdbb70b0d6f536551f0f3bb3725d2d75c4690db12c26c034e7d6ec4a924452","src/unix/bsd/netbsdlike/netbsd/mod.rs":"ace373270809e41c8fd2c74a7bc1aba307375c67385befc69bb8f651c839ed48","src/unix/bsd/netbsdlike/netbsd/powerpc.rs":"ee7ff5d89d0ed22f531237b5059aa669df93a3b5c489fa641465ace8d405bf41","src/unix/bsd/netbsdlike/netbsd/sparc64.rs":"9489f4b3e4566f43bb12dfb92238960613dac7f6a45cc13068a8d152b902d7d9","src/unix/bsd/netbsdlike/netbsd/x86.rs":"20692320e36bfe028d1a34d16fe12ca77aa909cb02bda167376f98f1a09aefe7","src/unix/bsd/netbsdlike/netbsd/x86_64.rs":"1afe5ef46b14397cdd68664b5b232e4f5b035b6db1d4cf411c899d51ebca9f30","src/unix/bsd/netbsdlike/openbsd/aarch64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/mod.rs":"00bad09852ae8133748465e333cdb60dcd97a0ab594c21353d5e3099f976389d","src/unix/bsd/netbsdlike/openbsd/sparc64.rs":"d04fd287afbaa2c5df9d48c94e8374a532a3ba491b424ddf018270c7312f4085","src/unix/bsd/netbsdlike/openbsd/x86.rs":"6f7f5c4fde2a2259eb547890cbd86570cea04ef85347d7569e94e679448bec87","src/unix/bsd/netbsdlike/openbsd/x86_64.rs":"e59b7fd65f68f8e857eec39e0c03bac1d3af6ddc26c9ba58494336b83659bb9b","src/unix/haiku/b32.rs":"69ae47fc52c6880e85416b4744500d5655c9ec6131cb737f3b649fceaadce15a","src/unix/haiku/b64.rs":"73e64db09275a8da8d50a13cce2cfa2b136036ddf3a930d2939f337fc995900b","src/unix/haiku/mod.rs":"34d74b3f86953c4bdba363b7b629fd3fc72d3842260ba208f91b9dc6024634ff","src/unix/haiku/native.rs":"7d21ea1c9bb2d9fd17ef30eab1cd61bacd111f2cdbafee1f44f7b9fc5fbd919d","src/unix/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/unix/hermit/mod.rs":"859814f5df89e28fd4b345db399d181e11e7ed413841b6ff703a1fcbdbf013ae","src/unix/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/unix/linux_like/android/b32/arm.rs":"d611801c875a1066ff596ba813a80c1689aa54489bbd5bd8af4610c786d97a36","src/unix/linux_like/android/b32/mod.rs":"47aab6a6babd5382db49d48aa82729931c429344984e47d7467334fb9fb31c79","src/unix/linux_like/android/b32/x86/align.rs":"812914e4241df82e32b12375ca3374615dc3a4bdd4cf31f0423c5815320c0dab","src/unix/linux_like/android/b32/x86/mod.rs":"8388bd3a0fcb5636bf965eee6dc95ae6860b85a2b555b387c868aa4d4e01ec89","src/unix/linux_like/android/b64/aarch64/align.rs":"2179c3b1608fa4bf68840482bfc2b2fa3ee2faf6fcae3770f9e505cddca35c7b","src/unix/linux_like/android/b64/aarch64/mod.rs":"424c548e1d328475136cddbfeb4bb452880cc8e6ec878758ccc0667f0ea588b9","src/unix/linux_like/android/b64/mod.rs":"e3078e856e43fde9b57d8a5aa840a590f2e18517a3e8de23e9c2a3d798596f43","src/unix/linux_like/android/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/android/b64/x86_64/mod.rs":"e84176d838e663d351450bad218715db1fafbb531e47ea0e262cbb45829dae89","src/unix/linux_like/android/mod.rs":"ee2c9b90b8d898b1ca1dd24d0f1340fa697ecce205720cd613c0efd68318904b","src/unix/linux_like/emscripten/align.rs":"86c95cbed7a7161b1f23ee06843e7b0e2340ad92b2cb86fe2a8ef3e0e8c36216","src/unix/linux_like/emscripten/mod.rs":"6ef97140ca6fb24125fdd0aacb986ef785aa21993229660d7f703f8875ebfe49","src/unix/linux_like/emscripten/no_align.rs":"0128e4aa721a9902754828b61b5ec7d8a86619983ed1e0544a85d35b1051fad6","src/unix/linux_like/linux/align.rs":"213e70ebed2703e14a9cf17666b21ecbf180b7bff7fa22fdbb36dbbd52df326d","src/unix/linux_like/linux/arch/generic/mod.rs":"ff1fe8fad4ea15d9bec3db25efcfcb4939190c5189f86cfa4d05825aa8c10956","src/unix/linux_like/linux/arch/mips/mod.rs":"e4a980b002105aaa057eb6568e1e2c6168ade5c00e13a31ef67e316ddffdb900","src/unix/linux_like/linux/arch/mod.rs":"466a29622e47c6c7f1500682b2eb17f5566dd81b322cd6348f0fdd355cec593a","src/unix/linux_like/linux/arch/powerpc/mod.rs":"1789eb5b41f75c29239795124a4a7cdcf7c8d213b88cf581b2f5bda08d7cf15b","src/unix/linux_like/linux/arch/sparc/mod.rs":"ded708124ee610267d011dee31fb02d1ec697c334aa822776ec95a7ddf6fc541","src/unix/linux_like/linux/gnu/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/gnu/b32/arm/align.rs":"3fed009dc9af3cc81be7087da9d2d7d1f39845e4497e290259c5cdbae25f039d","src/unix/linux_like/linux/gnu/b32/arm/mod.rs":"07adf9f4b96854062db518aaf08521fde0ad4a21a5c049efccba437bd97b2b5a","src/unix/linux_like/linux/gnu/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/gnu/b32/mips/mod.rs":"1cb5c0c9df3af2bbe131a91593583259fac9118931744c8435e197a394eb0462","src/unix/linux_like/linux/gnu/b32/mod.rs":"1e05278ab6295e95165d0fab1698bdc82a511bcbda3250093af4e5edf08991f8","src/unix/linux_like/linux/gnu/b32/powerpc.rs":"0cd7348badb9c4f8a0db31a2503b30c456a2bfcc7a0e5919762b1e12f912c5ad","src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs":"9c628cd97806181dc4d34b072f63fe1eb42f08108712002e0628ffe27f2fa93f","src/unix/linux_like/linux/gnu/b32/sparc/align.rs":"21adbed27df73e2d1ed934aaf733a643003d7baf2bde9c48ea440895bcca6d41","src/unix/linux_like/linux/gnu/b32/sparc/mod.rs":"1bcec269a8416ccc48a384ca5765eaaa23f30f39f32311f50008ef4eeadafb2f","src/unix/linux_like/linux/gnu/b32/x86/align.rs":"e4bafdc4a519a7922a81b37a62bbfd1177a2f620890eef8f1fbc47162e9eb413","src/unix/linux_like/linux/gnu/b32/x86/mod.rs":"5317dbf2323577b89370bbee3894882b89d8333176db4f7b271ddc2f036ef43c","src/unix/linux_like/linux/gnu/b64/aarch64/align.rs":"2179c3b1608fa4bf68840482bfc2b2fa3ee2faf6fcae3770f9e505cddca35c7b","src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs":"21a21503ef2e095f4371044915d4bfb07a8578011cb5c713cd9f45947b0b5730","src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs":"e78c3cd197f44832338b414d1a9bc0d194f44c74db77bd7bf830c1fff62b2690","src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs":"c3730792dabcc166d8fd22929ef2633d49bc626875382dfcd401e8e125fb7a84","src/unix/linux_like/linux/gnu/b64/mips64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/mips64/mod.rs":"68bcb71bbfccb4e8648948e494366d94767ce96f36daab9c1329375cdd32a459","src/unix/linux_like/linux/gnu/b64/mod.rs":"7bf5c9813032db77b964ccb90bdce15236ae9ea06ea185595278ea4565c21b7b","src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs":"dbb8905e363ed4a2dfb984554ad9b6389d27f6a2d599ec2d80e38a6c7551a019","src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs":"18edaa89c9746125863ff53182e0ef32cb1e1612e1ed9a2672558a9de85440e9","src/unix/linux_like/linux/gnu/b64/s390x.rs":"d9bb4e524e70d6fef49e0f77d89a92f478fd95d9a1aea32f4dc845275a7465d4","src/unix/linux_like/linux/gnu/b64/sparc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs":"26fda11bdce99372c2c246e60866b56d98beb9fb49a2f6b69347ecfd03d18255","src/unix/linux_like/linux/gnu/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs":"5a5ce7c5c92f60d8900dce63d363a38f3126aaf5be981710e172bec96ef95ac6","src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs":"f775ac2b754f90b63053fe22afe1d19d306b5404995568d6805baa9249fb617f","src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs":"4ba1b58468f55254717366f50fdfd3e4114fde6dc442a56681926c4d7e5b6b0d","src/unix/linux_like/linux/gnu/mod.rs":"61a7c0b6616d4efa3b68653942218b35a29d2c50bcb7acf2f072f24fc8dfda79","src/unix/linux_like/linux/gnu/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/mod.rs":"e3f5780e126b0b6d938bf0750d90b672ed4d82e1273becf349f341cf5ab9418b","src/unix/linux_like/linux/musl/b32/arm/align.rs":"3e8ac052c1043764776b54c93ba4260e061df998631737a897d9d47d54f7b80c","src/unix/linux_like/linux/musl/b32/arm/mod.rs":"6255abe2ee04986832d12b7b2190589580f2a43e9bfb285b32b5747227f62727","src/unix/linux_like/linux/musl/b32/hexagon.rs":"a8811791809672be8338e6e27d1c4fcf383c2f26585be8bf9ab2923b219de032","src/unix/linux_like/linux/musl/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/musl/b32/mips/mod.rs":"b9e9ff42363ebbb884ddf6445129ec4164471df45846874fc08f5f458e659254","src/unix/linux_like/linux/musl/b32/mod.rs":"8ede3985e6243882814ce91e8ce543e7edbafc0cee5932816072b6f14207a671","src/unix/linux_like/linux/musl/b32/powerpc.rs":"4592dc5f1f2fe888dfef85fa862d42d168e73a2c6f4fc052b58287d0f4d4ffcd","src/unix/linux_like/linux/musl/b32/x86/align.rs":"08e77fbd7435d7dec2ff56932433bece3f02e47ce810f89004a275a86d39cbe1","src/unix/linux_like/linux/musl/b32/x86/mod.rs":"a19a8decfab185af3cebd34aae4b15082e7552be573904b8c1a3f0c0e493ef34","src/unix/linux_like/linux/musl/b64/aarch64/align.rs":"798a9229d70ce235394f2dd625f6c4c1e10519a94382dc5b091952b638ae2928","src/unix/linux_like/linux/musl/b64/aarch64/mod.rs":"a73035c6d9b776f13b839008e15c04c2c53455571efd06664affcb047e457112","src/unix/linux_like/linux/musl/b64/mips64.rs":"2744895451f3a777fbe54f7f2695be53310b965fd62084c9b7e9121c7fe28346","src/unix/linux_like/linux/musl/b64/mod.rs":"d18abc0aeba2e26342bf3416a4dba0836db2bb0ee013b0a39629475cf8640289","src/unix/linux_like/linux/musl/b64/powerpc64.rs":"e5a55525b42493923956d668f978fb45e22d51deea00ce5edbfddf76ff19c741","src/unix/linux_like/linux/musl/b64/s390x.rs":"03dfec6794d93cb31a7c52b2d53a0973755168f91f8fa437cc5dbd54882c8ee7","src/unix/linux_like/linux/musl/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/musl/b64/x86_64/mod.rs":"0dd168f5a6881f32e5239fb312b23cf137b800d0ff323286a92c8a2c382b5456","src/unix/linux_like/linux/musl/mod.rs":"f0e202a92ea839c42c1176f416ece21e69ba809795b8035768b10d3813c95892","src/unix/linux_like/linux/no_align.rs":"5ed04c53bf9d27da9b4d65ba7625c6ac53330162683d1b3df98950caafa3507b","src/unix/linux_like/linux/uclibc/align.rs":"9ed16138d8e439bd90930845a65eafa7ebd67366e6bf633936d44014f6e4c959","src/unix/linux_like/linux/uclibc/arm/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/arm/mod.rs":"9b691eeec0a9bf7b2abb87e09062d2c148d18e11c96ecad0edd0b74d1d0509fd","src/unix/linux_like/linux/uclibc/arm/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips32/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs":"18753a99b820d69e062e3ba22a63fa86577b6dcc42f740479c7be1a4c658e1be","src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips64/align.rs":"a7bdcb18a37a2d91e64d5fad83ea3edc78f5412adb28f77ab077dbb26dd08b2d","src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs":"e3085ba56cfbc528d7c3c55065880603238c333b6047ef51c58177508a487fcd","src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs":"4a18e3875698c85229599225ac3401a2a40da87e77b2ad4ef47c6fcd5a24ed30","src/unix/linux_like/linux/uclibc/mips/mod.rs":"656fbf5157ab6d06fc365a8353b138818ad5b8429ea5628ff35a3972c63a1a7c","src/unix/linux_like/linux/uclibc/mod.rs":"22f712c3e08fd8cb37e274718de1bac09966a4cd4b0f018f28737bc30940b8af","src/unix/linux_like/linux/uclibc/no_align.rs":"3f28637046524618adaa1012e26cb7ffe94b9396e6b518cccdc69d59f274d709","src/unix/linux_like/linux/uclibc/x86_64/l4re.rs":"bb31053d6403091e11f95ac2203982f279f8b984a19adf30796878c45fdd8c25","src/unix/linux_like/linux/uclibc/x86_64/mod.rs":"02e21c0550a423a3f6db0a0af6a0f37cf5937feb2562a490e0ad0e09a8d9fc77","src/unix/linux_like/linux/uclibc/x86_64/other.rs":"42c3f71e58cabba373f6a55a623f3c31b85049eb64824c09c2b082b3b2d6a0a8","src/unix/linux_like/mod.rs":"363b0c11766fae2a43ff62e78ff719c97832cc80f9eca1ab67e570fe3a062a0c","src/unix/mod.rs":"a5fbb90b99244f04bb37dc7d79d56261f5c5a41e9a09b7958aed9a2b4882eae8","src/unix/newlib/aarch64/mod.rs":"bb269c1468a9676442554600e87417079a787fe6220dfc23b3109639259e8710","src/unix/newlib/align.rs":"28aaf87fafbc6b312622719d472d8cf65f9e5467d15339df5f73e66d8502b28a","src/unix/newlib/arm/mod.rs":"c71be856bfd7f576b2db28af9f680211cbe6c1cac7d537bbc8020b39591af07c","src/unix/newlib/mod.rs":"407fe7e3c77f4c4c129788b3888a7da5d4b7b818ed3e96abb8de8cd780f83fb6","src/unix/newlib/no_align.rs":"e0743b2179495a9514bc3a4d1781e492878c4ec834ee0085d0891dd1712e82fb","src/unix/newlib/powerpc/mod.rs":"2d0f7af28b47f7a2a6c210ebd1c1f33ed8eac62e56b5af2b856de2ad3fdc5187","src/unix/newlib/xtensa/mod.rs":"08b314a27797ee27989f48f5a0e66e0d73670071ceabd341076cdce7ea67201c","src/unix/no_align.rs":"c06e95373b9088266e0b14bba0954eef95f93fb2b01d951855e382d22de78e53","src/unix/redox/mod.rs":"6dcfe2212ea37e8e293c8fe7acc1319035594e9b951bd64c071f1a2a8be9b91e","src/unix/solarish/compat.rs":"b07a5bfac925eb012003a459ba6bddbd3bfa9c44b3394da2ac5a602e54beae9c","src/unix/solarish/illumos.rs":"e01acc1b176e15268ac0ca4d1de50bf372ba80a465af35cd612c8f7e702baf92","src/unix/solarish/mod.rs":"be9f7a37d17a7616f6dbebd871fe4ae83612af6b582ebf153284cff1e7162334","src/unix/solarish/solaris.rs":"65b005453aefa9b9d4fc860fe77cfec80d8c97a51342b15daf55fc3e808bb384","src/vxworks/aarch64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/arm.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/mod.rs":"9caf6ff3faad5b39c9deb8eae497a61ef15aa5e03aa409a16299e700240c3b63","src/vxworks/powerpc.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/powerpc64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/x86.rs":"552f007f38317620b23889cb7c49d1d115841252439060122f52f434fbc6e5ba","src/vxworks/x86_64.rs":"018d92be3ad628a129eff9f2f5dfbc0883d8b8e5f2fa917b900a7f98ed6b514a","src/wasi.rs":"1f70ff346e8944d90805ddbe96629bf55fd3327c50ffc3b9b27b2b011934dd69","src/windows/gnu/align.rs":"b2c13ec1b9f3b39a75c452c80c951dff9d0215e31d77e883b4502afb31794647","src/windows/gnu/mod.rs":"3c8c7edb7cdf5d0c44af936db2a94869585c69dfabeef30571b4f4e38375767a","src/windows/mod.rs":"2b960d585c2fc0c82659cc4caeaa3268e67a8de0a0390d084629eefd39a14c8d","src/windows/msvc.rs":"ea6d87a6a9cd668261b1c043e7c36cf599e80b5d09f6e4502e85daa4797c7927","tests/const_fn.rs":"cb75a1f0864f926aebe79118fc34d51a0d1ade2c20a394e7774c7e545f21f1f4"},"package":"12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"} +\ No newline at end of file ++{"files":{"CONTRIBUTING.md":"bdc90b52cf803faac96e594069a86dd8ea150d5ba7fb3e6cadfc08dac4c7b0ce","Cargo.toml":"6d2a763005b4eeebbb37e75dd3d3edaa88cba6e4b48fb557cfbfa22678daec38","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"a8d47ff51ca256f56a8932dba07660672dbfe3004257ca8de708aac1415937a1","README.md":"776affa26b66843a2b4f1a1c8f88d92f6461b74568911450fea717e9db6f877b","build.rs":"5bd78d7e4e79b183fb1dab92cd640a611330131d54c479c69adbe87cbdc95ae3","rustfmt.toml":"eaa2ea84fc1ba0359b77680804903e07bb38d257ab11986b95b158e460f787b2","src/fixed_width_ints.rs":"7f986e5f5e68d25ef04d386fd2f640e8be8f15427a8d4a458ea01d26b8dca0ca","src/fuchsia/aarch64.rs":"893fcec48142d273063ffd814dca33fbec92205fd39ada97075f85201d803996","src/fuchsia/align.rs":"ae1cf8f011a99737eabeb14ffff768e60f13b13363d7646744dbb0f443dab3d6","src/fuchsia/mod.rs":"0d48e0669c737c7e2ba8f7d2148424d4580c3cdc7f5d0153c323b1f8b3462bc3","src/fuchsia/no_align.rs":"303f3f1b255e0088b5715094353cf00476131d8e94e6aebb3f469557771c8b8a","src/fuchsia/riscv64.rs":"617cd75e79e0e20f664db764a4dc2a396d9fd11a4d95371acd91ed4811293b11","src/fuchsia/x86_64.rs":"93a3632b5cf67d2a6bcb7dc0a558605252d5fe689e0f38d8aa2ec5852255ac87","src/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/hermit/mod.rs":"d3bfce41e4463d4be8020a2d063c9bfa8b665f45f1cc6cbf3163f5d01e7cb21f","src/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/lib.rs":"24111461547739f3646f95bcb66c43f2ae679a727ff5938299434c522c02e458","src/macros.rs":"b457eb028b8e8ab3c24bb7292b874ad4e491edbb83594f6a3da024df5348c088","src/psp.rs":"dd31aabd46171d474ec5828372e28588935120e7355c90c105360d8fa9264c1c","src/sgx.rs":"16a95cdefc81c5ee00d8353a60db363c4cc3e0f75abcd5d0144723f2a306ed1b","src/solid/aarch64.rs":"a726e47f324adf73a4a0b67a2c183408d0cad105ae66acf36db37a42ab7f8707","src/solid/arm.rs":"e39a4f74ebbef3b97b8c95758ad741123d84ed3eb48d9cf4f1f4872097fc27fe","src/solid/mod.rs":"5f4151dca5132e4b4e4c23ab9737e12856dddbdc0ca3f7dbc004328ef3c8acde","src/switch.rs":"9da3dd39b3de45a7928789926e8572d00e1e11a39e6f7289a1349aadce90edba","src/unix/aix/mod.rs":"47ca7ca4215b2c147d44e6eea8331f52f063e8e55e2e454589f6d3609fca4ccd","src/unix/aix/powerpc64.rs":"cf374d81139d45f9d77c6a764f640bfbf7e0a5903689652c8296f8e10d55169b","src/unix/align.rs":"2cdc7c826ef7ae61f5171c5ae8c445a743d86f1a7f2d9d7e4ceeec56d6874f65","src/unix/bsd/apple/b32/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b32/mod.rs":"2546ad3eb6aecb95f916648bc63264117c92b4b4859532b34cb011e4c75a5a72","src/unix/bsd/apple/b64/aarch64/align.rs":"e8eb38d064b5fefec6f37d42873820a0483e7c758ed336cc59a7155455ca89c9","src/unix/bsd/apple/b64/aarch64/mod.rs":"44c217a4f263afe7a97435de9323d20a96c37836f899ca0925306d4b7e073c27","src/unix/bsd/apple/b64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/mod.rs":"f5e278a1af7fb358891d1c9be4eb7e815aaca0c5cb738d0c3604ba2208a856f7","src/unix/bsd/apple/b64/x86_64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/x86_64/mod.rs":"8c87c5855038aae5d433c8f5eb3b29b0a175879a0245342b3bfd83bdf4cfd936","src/unix/bsd/apple/long_array.rs":"3cf1f19b812e6d093c819dc65ce55b13491963e0780eda0d0bd1577603e81948","src/unix/bsd/apple/mod.rs":"3998cf832a003712c3c0b04974ae1731ad16e4755fc0ba9921bfdb292a95a627","src/unix/bsd/freebsdlike/dragonfly/errno.rs":"8295b8bb0dfd38d2cdb4d9192cdeeb534cc6c3b208170e64615fa3e0edb3e578","src/unix/bsd/freebsdlike/dragonfly/mod.rs":"090e9fb9a81a9d9ea80f49595a8b6cf656334106389940f282d33a969809e383","src/unix/bsd/freebsdlike/freebsd/aarch64.rs":"6c8e216385f53a4bf5f171749b57602fc34a4e4b160a44ca31c058cb0c8a2126","src/unix/bsd/freebsdlike/freebsd/arm.rs":"59d6a670eea562fb87686e243e0a84603d29a2028a3d4b3f99ccc01bd04d2f47","src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs":"9808d152c1196aa647f1b0f0cf84dac8c930da7d7f897a44975545e3d9d17681","src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs":"fa83dcd4597c6621b95228d80ea6250c37136463300f80a9961a09bdab5e25c3","src/unix/bsd/freebsdlike/freebsd/freebsd12/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs":"c7c574d65a8408f6eee32bd5d0cc40e33e41c7e61d98d338609ae5beec72f390","src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd13/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs":"834ec71df759e8d38489986b7720f1b296ca774c23c8034e2d9b02b9f55ab781","src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs":"61cbe45f8499bedb168106b686d4f8239472f25c7553b069eec2afe197ff2df6","src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs":"58b7766136a22ace828c974f34240eb38feec2c8aa2ee8b6ca38e3b44a6fa348","src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/mod.rs":"c4e3f8549cbf61deb23b2f3bdda711ac0d6d7f3be9e2d8bfca81d290d220eaf3","src/unix/bsd/freebsdlike/freebsd/powerpc.rs":"9ca3f82f88974e6db5569f2d76a5a3749b248a31747a6c0da5820492bdfeca42","src/unix/bsd/freebsdlike/freebsd/powerpc64.rs":"2dae3ecc87eac3b11657aa98915def55fc4b5c0de11fe26aae23329a54628a9a","src/unix/bsd/freebsdlike/freebsd/riscv64.rs":"fa4bed4c58cad24ba3395941c7fa6b11e089551a04714f9561078e400f5b2b62","src/unix/bsd/freebsdlike/freebsd/x86.rs":"6766e2ce85e187b306cd3b0b8d7e15b8f4042c5cff81d89b3af69ecc99c70ab0","src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs":"0e1f69a88fca1c32874b1daf5db3d446fefbe518dca497f096cc9168c39dde70","src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs":"51e4dd0c8ae247bb652feda5adad9333ea3bb30c750c3a3935e0b0e47d7803eb","src/unix/bsd/freebsdlike/mod.rs":"f5ebb2f36dffd9c897b18b168cf28fbff9cc68983ae2d4910cb1ba9764693381","src/unix/bsd/mod.rs":"0c672b075b5616fca2cc56c00ee31c3f554dcbd2e88a7c2ba1437aa6e5604319","src/unix/bsd/netbsdlike/mod.rs":"0a66f7de43710e35a6a546e6c39066aa8b91a6efadb71db88738b0a577fd5537","src/unix/bsd/netbsdlike/netbsd/aarch64.rs":"65dcb58d11e8d8028401a9d07ca3eb4cb4f053e04249cc877353449d84ccc4cb","src/unix/bsd/netbsdlike/netbsd/arm.rs":"58cdbb70b0d6f536551f0f3bb3725d2d75c4690db12c26c034e7d6ec4a924452","src/unix/bsd/netbsdlike/netbsd/mod.rs":"27a4733a50a296167319573f4a55bfab192a109719e11d70601818d0945ceb62","src/unix/bsd/netbsdlike/netbsd/powerpc.rs":"ee7ff5d89d0ed22f531237b5059aa669df93a3b5c489fa641465ace8d405bf41","src/unix/bsd/netbsdlike/netbsd/sparc64.rs":"9489f4b3e4566f43bb12dfb92238960613dac7f6a45cc13068a8d152b902d7d9","src/unix/bsd/netbsdlike/netbsd/x86.rs":"20692320e36bfe028d1a34d16fe12ca77aa909cb02bda167376f98f1a09aefe7","src/unix/bsd/netbsdlike/netbsd/x86_64.rs":"1afe5ef46b14397cdd68664b5b232e4f5b035b6db1d4cf411c899d51ebca9f30","src/unix/bsd/netbsdlike/openbsd/aarch64.rs":"dd91931d373b7ecaf6e2de25adadee10d16fa9b12c2cbacdff3eb291e1ba36af","src/unix/bsd/netbsdlike/openbsd/arm.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/mips64.rs":"8532a189ae10c7d668d9d4065da8b05d124e09bd39442c9f74a7f231c43eca48","src/unix/bsd/netbsdlike/openbsd/mod.rs":"95c10c5b630495a44fc3a1e077c4934a265371ec010aa2c07c87ac5f711fe5ab","src/unix/bsd/netbsdlike/openbsd/powerpc.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/powerpc64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/riscv64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/sparc64.rs":"d04fd287afbaa2c5df9d48c94e8374a532a3ba491b424ddf018270c7312f4085","src/unix/bsd/netbsdlike/openbsd/x86.rs":"6f7f5c4fde2a2259eb547890cbd86570cea04ef85347d7569e94e679448bec87","src/unix/bsd/netbsdlike/openbsd/x86_64.rs":"d31db31630289c85af3339dbe357998a21ca584cbae31607448fe2cf7675a4e1","src/unix/haiku/b32.rs":"a2efdbf7158a6da341e1db9176b0ab193ba88b449616239ed95dced11f54d87b","src/unix/haiku/b64.rs":"ff8115367d3d7d354f792d6176dfaaa26353f57056197b563bf4681f91ff7985","src/unix/haiku/mod.rs":"30ba7d482c652b4c9ed03fb0d5b783e9ea2975eeeebbdf9d4e300134136dfcba","src/unix/haiku/native.rs":"dbfcbf4954a79d1df2ff58e0590bbcb8c57dfc7a32392aa73ee4726b66bd6cc8","src/unix/haiku/x86_64.rs":"3ec3aeeb7ed208b8916f3e32d42bfd085ff5e16936a1a35d9a52789f043b7237","src/unix/hermit/aarch64.rs":"86048676e335944c37a63d0083d0f368ae10ceccefeed9debb3bbe08777fc682","src/unix/hermit/mod.rs":"a1494a0bddf301cceb0d9b8529a84b5882fe855ceae77a1c4e8d6034e705e26c","src/unix/hermit/x86_64.rs":"ab832b7524e5fb15c49ff7431165ab1a37dc4667ae0b58e8306f4c539bfa110c","src/unix/linux_like/android/b32/arm.rs":"ce582de7e983a33d3bfad13075c53aac9016cee35f06ad8653ee9072c3ec2564","src/unix/linux_like/android/b32/mod.rs":"7c173e0375119bf06a3081652faede95e5bcd6858e7576b7533d037978737c8f","src/unix/linux_like/android/b32/x86/align.rs":"812914e4241df82e32b12375ca3374615dc3a4bdd4cf31f0423c5815320c0dab","src/unix/linux_like/android/b32/x86/mod.rs":"e6d107efbcd37b5b85dfa18f683300cbf768ffa0237997a9fa52b184a53323ac","src/unix/linux_like/android/b64/aarch64/align.rs":"2179c3b1608fa4bf68840482bfc2b2fa3ee2faf6fcae3770f9e505cddca35c7b","src/unix/linux_like/android/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/android/b64/aarch64/mod.rs":"171f8c37a2d2e45065bd3547dfcec70b02aa3da34cd99d259d150c753f620846","src/unix/linux_like/android/b64/mod.rs":"71e4fcbe952bfa4a5f9022f3972e906917b38f729b9d8ef57cd5d179104894ac","src/unix/linux_like/android/b64/riscv64/align.rs":"0bf138f84e5327d8339bcd4adf071a6832b516445e597552c82bbd881095e3a8","src/unix/linux_like/android/b64/riscv64/mod.rs":"19d4bf2237c47127eba9144e0b82e995bc079315e719179a91813b0ae7b0e49d","src/unix/linux_like/android/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/android/b64/x86_64/mod.rs":"4ec2de11a9b65c4325b7b991f0b99a414975e0e61ba8668caca5d921e9b314d1","src/unix/linux_like/android/mod.rs":"e6536383a652e1a9a755d350c5a60c2abcadea03e9cdc92e3cf7f7229fe8e2a5","src/unix/linux_like/emscripten/align.rs":"86c95cbed7a7161b1f23ee06843e7b0e2340ad92b2cb86fe2a8ef3e0e8c36216","src/unix/linux_like/emscripten/mod.rs":"712c52856ee323b8057b9452e4ab484a0e652581a530b67c3db25e819919d718","src/unix/linux_like/emscripten/no_align.rs":"0128e4aa721a9902754828b61b5ec7d8a86619983ed1e0544a85d35b1051fad6","src/unix/linux_like/linux/align.rs":"28b2cd7c3eddc53c247aa11340da205d1d2e478f199493d330c61e75ec16ee96","src/unix/linux_like/linux/arch/generic/mod.rs":"0d182608339b4237c8a793274b5410a8f39558c1a1c9c2461a599bea6dac0451","src/unix/linux_like/linux/arch/mips/mod.rs":"2d166054a586bb4bf6e4a4ba35f7574907b217225eff8f1a43adc4277e142460","src/unix/linux_like/linux/arch/mod.rs":"466a29622e47c6c7f1500682b2eb17f5566dd81b322cd6348f0fdd355cec593a","src/unix/linux_like/linux/arch/powerpc/mod.rs":"3f6da7b0fa7b394c7d4eea2bb3caa7a7729ab0d6c1491fef02206a912c41b815","src/unix/linux_like/linux/arch/sparc/mod.rs":"91593ec0440f1dd8f8e612028f432c44c14089286e2aca50e10511ab942db8c3","src/unix/linux_like/linux/gnu/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/gnu/b32/arm/align.rs":"6ec0eb3ee93f7ae99fd714b4deabfb5e97fbcefd8c26f5a45fb8e7150899cdeb","src/unix/linux_like/linux/gnu/b32/arm/mod.rs":"9ab3e97b579a9122690cd01026e14528862860346b700aafbb755a7e04054f7f","src/unix/linux_like/linux/gnu/b32/m68k/align.rs":"8faa92f77a9232c035418d45331774e64a9a841d99c91791570a203bf2b45bcb","src/unix/linux_like/linux/gnu/b32/m68k/mod.rs":"6aab7f1b864e9691d14aa7d389f717c4077b8eed72a7f11e3b8c7fef245e4046","src/unix/linux_like/linux/gnu/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/gnu/b32/mips/mod.rs":"6b9a5dac6f937ddc1453e808e3c43502c87143332df9e43ac64fb8b1eda6c116","src/unix/linux_like/linux/gnu/b32/mod.rs":"caade9dc8b7179711102da342819bdf330c42c796b4587d0ed419550dab2e9ad","src/unix/linux_like/linux/gnu/b32/powerpc.rs":"5c5d90326b54b57b98eff4745fe7a3fb02f053b2dc782241a73e807b491936a3","src/unix/linux_like/linux/gnu/b32/riscv32/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs":"491a9a97cf712985b75d3ad714691ef60898d88c78bc386a6917de0a6774cc26","src/unix/linux_like/linux/gnu/b32/sparc/align.rs":"21adbed27df73e2d1ed934aaf733a643003d7baf2bde9c48ea440895bcca6d41","src/unix/linux_like/linux/gnu/b32/sparc/mod.rs":"80894eece66e9348f45d1b07ad37c757ea694bbd10ed49d3f920b34e9f51a9a3","src/unix/linux_like/linux/gnu/b32/x86/align.rs":"e4bafdc4a519a7922a81b37a62bbfd1177a2f620890eef8f1fbc47162e9eb413","src/unix/linux_like/linux/gnu/b32/x86/mod.rs":"c703cc5e9de2dc31d9e5831bfb6f354d6e3518b2ae02263f68a9a70f1c0167e2","src/unix/linux_like/linux/gnu/b64/aarch64/align.rs":"ea39d5fd8ca5a71314127d1e1f542bca34ac566eac9a95662076d91ea4bee548","src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs":"bf4611b737813deef6787babf6c01698605f3b75482269b8546318667bc68e29","src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs":"11a950697fdda0258c6e37c6b13993348c8de4134105ed4faa79358e53175072","src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs":"d7be998105fc2f6248b7fdfcedb5a0519122d28625fcfd5dccf72617fb30c45e","src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs":"6616c38bf8cab53034dce9f968adae8fb7771334445a93876d000cfd08f117a8","src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs":"9c39dfc3843e72bd8dba21aa5ef2795411cd8a0004a0cfe79c9b9f89ab92eb55","src/unix/linux_like/linux/gnu/b64/mips64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/mips64/mod.rs":"628c410b9aaec3c8f43838a28616b577a1d6de60a9799b09bb884d80281f96eb","src/unix/linux_like/linux/gnu/b64/mod.rs":"3c6555f30a7a8852757b31a542ea73fb6a16a6e27e838397e819278ad56e57a4","src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs":"c778a136f06c2ffeacea19fa14ce79b828f91b67a002dec5ce87289bae36234e","src/unix/linux_like/linux/gnu/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs":"c8f07efc5ddd5d874f1ebc329cd6907818d132ac3e30f4f2a4b04be3fb388551","src/unix/linux_like/linux/gnu/b64/s390x.rs":"a2fd9277c2dcf76f7a16a3bcca745d5a9932c765c0dc2feb31c3641be25eb0aa","src/unix/linux_like/linux/gnu/b64/sparc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs":"e8047e9966a2b90063e0151a0278c54885e7b323286cf5ab55cbaf151fc772d3","src/unix/linux_like/linux/gnu/b64/x86_64/align.rs":"62e822478356db4a73b6bbd1b36d825b893939ab4b308ec11b0578bcc4b49769","src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs":"891e595d33714b9883b92f0554d1d361fba2b6c3f6cac09a288252f44c6ec667","src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs":"38f74ce15d9662ce4818815a2b87be1618d5e45f190f7e4db84ff3285b4421fb","src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs":"b20218a11364a6dec87f96d6c0d8b19e660697ab09ad5ee0e9b3a9dafedaaebb","src/unix/linux_like/linux/gnu/mod.rs":"e8d56078ddc354e2b311d904c3894b631f5bb031cefc6e6675e82c9a6387ab8a","src/unix/linux_like/linux/gnu/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/mod.rs":"67763e106794b69311e094c09f128ac2c0fcd7ea17b6d74f20c5b3b50fb9b2b1","src/unix/linux_like/linux/musl/b32/arm/align.rs":"3e8ac052c1043764776b54c93ba4260e061df998631737a897d9d47d54f7b80c","src/unix/linux_like/linux/musl/b32/arm/mod.rs":"f5b217a93f99c2852f7fd1459f529798372fa7df84ee0cfd3d8cdd5b2021b8cf","src/unix/linux_like/linux/musl/b32/hexagon.rs":"226a8b64ce9c75abbbee6d2dceb0b44f7b6c750c4102ebd4d015194afee6666e","src/unix/linux_like/linux/musl/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/musl/b32/mips/mod.rs":"16f614dd59695497a01b542deacd1669335678bdd0b14d16dde482fb5c4e02f4","src/unix/linux_like/linux/musl/b32/mod.rs":"31677597fd9544c4b1ec1477628288f6273fabbc06e38f33da862ad55f019ce1","src/unix/linux_like/linux/musl/b32/powerpc.rs":"80479a91d817ac2bce7cbd62d0c5d20a949fb28b0c41cb765604313dba36829e","src/unix/linux_like/linux/musl/b32/riscv32/align.rs":"efd2accf33b87de7c7547903359a5da896edc33cd6c719552c7474b60d4a5d48","src/unix/linux_like/linux/musl/b32/riscv32/mod.rs":"b857ccbc8f0fbc8a6a5959f3496a4fd5a9a1dd986c15c8e716f3e2902c25181c","src/unix/linux_like/linux/musl/b32/x86/align.rs":"08e77fbd7435d7dec2ff56932433bece3f02e47ce810f89004a275a86d39cbe1","src/unix/linux_like/linux/musl/b32/x86/mod.rs":"7a1586f77bb693f0b319ec720c35963da056287fc42f8e2ccf1d5b2bcccf4fd6","src/unix/linux_like/linux/musl/b64/aarch64/align.rs":"6ba32725d24d7d8e6aa111f3b57aafa318f83b606abe96561329151829821133","src/unix/linux_like/linux/musl/b64/aarch64/int128.rs":"1735f6f5c56770d20dd426442f09724d9b2052b46a7cd82f23f3288a4a7276de","src/unix/linux_like/linux/musl/b64/aarch64/mod.rs":"31e75179cbb4e26425b3f5b052e358f593153da662884655e60801d852e55dc2","src/unix/linux_like/linux/musl/b64/mips64.rs":"9a5d29f666332bb056d0e2951e9de989aa1dc016075f009db3f2f628e0cdda8c","src/unix/linux_like/linux/musl/b64/mod.rs":"884243eb5af7df963d858d5baf47e622b45f04e0ae701728b134e986191b614b","src/unix/linux_like/linux/musl/b64/powerpc64.rs":"455dc0ffa55afc1db6ffaf461f6f2a7b49d31658bfebe0bb4efac5967a6f956c","src/unix/linux_like/linux/musl/b64/riscv64/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/musl/b64/riscv64/mod.rs":"42d4b6d36807f37759094a732a321080cccdf498b174d632cebba147051de294","src/unix/linux_like/linux/musl/b64/s390x.rs":"508d083cca50ca91042f01a9618909e890b755287ea4c7885cdab0fc0d75e1b3","src/unix/linux_like/linux/musl/b64/x86_64/align.rs":"77309276ad7a42cbe59ca381f23590b7a143aded05555b34a5b307b808cbca6e","src/unix/linux_like/linux/musl/b64/x86_64/mod.rs":"7a877cd23b64be66d28e6b8dddae32d59a88d69115637539daf19381f4e39330","src/unix/linux_like/linux/musl/mod.rs":"8965596cc33a032f7495c74d0d25ff9169e425491b36c4563b291e9f12e2a1b6","src/unix/linux_like/linux/no_align.rs":"1a754a4af299894a79835aa092d8322d301179e2b20609defd6bb4bc880e6b4a","src/unix/linux_like/linux/non_exhaustive.rs":"181a05bf94fdb911db83ce793b993bd6548a4115b306a7ef3c10f745a8fea3e9","src/unix/linux_like/linux/uclibc/align.rs":"9ed16138d8e439bd90930845a65eafa7ebd67366e6bf633936d44014f6e4c959","src/unix/linux_like/linux/uclibc/arm/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/arm/mod.rs":"50288ff9e411ab0966da24838f2c2a5618021bc19c422a04f577b2979ef4081e","src/unix/linux_like/linux/uclibc/arm/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips32/align.rs":"e4a3c27fe20a57b8d612c34cb05bc70646edb5cec7251957315afa53a7b9f936","src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs":"d0c4434e2bf813372c418a8f516c706cdccc9f7be2f0921b2207b0afdb66fe81","src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/uclibc/mips/mips64/align.rs":"a7bdcb18a37a2d91e64d5fad83ea3edc78f5412adb28f77ab077dbb26dd08b2d","src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs":"3f38ee6a4690b9d7594be20d216467a34d955f7653c2c8ce1e6147daeb53f1e0","src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs":"4a18e3875698c85229599225ac3401a2a40da87e77b2ad4ef47c6fcd5a24ed30","src/unix/linux_like/linux/uclibc/mips/mod.rs":"a048fce1c2d9b1ad57305642e8ad05ca0f0c7e4753267a2e2d6b4fee5db3b072","src/unix/linux_like/linux/uclibc/mod.rs":"1c3d25cddcfefa2bd17bdc81550826be31a08eef235e13f825f169a5029c8bca","src/unix/linux_like/linux/uclibc/no_align.rs":"3f28637046524618adaa1012e26cb7ffe94b9396e6b518cccdc69d59f274d709","src/unix/linux_like/linux/uclibc/x86_64/l4re.rs":"024eba5753e852dbdd212427351affe7e83f9916c1864bce414d7aa2618f192e","src/unix/linux_like/linux/uclibc/x86_64/mod.rs":"196d03affbefb85716937c15904831e731eb222ee906e05e42102d639a8152ea","src/unix/linux_like/linux/uclibc/x86_64/other.rs":"42c3f71e58cabba373f6a55a623f3c31b85049eb64824c09c2b082b3b2d6a0a8","src/unix/linux_like/mod.rs":"d5f241802aebc04f7eb05089e03ae9d760fe863e7bd72a587f3b954c3367753c","src/unix/mod.rs":"13d0eb3b15294623bb3c08b45aea89b06f14860675f5e777670aae42a0cc43a9","src/unix/newlib/aarch64/mod.rs":"bac93836a9a57b2c710f32f852e92a4d11ad6759ab0fb6ad33e71d60e53278af","src/unix/newlib/align.rs":"28aaf87fafbc6b312622719d472d8cf65f9e5467d15339df5f73e66d8502b28a","src/unix/newlib/arm/mod.rs":"cbba6b3e957eceb496806e60de8725a23ff3fa0015983b4b4fa27b233732b526","src/unix/newlib/espidf/mod.rs":"816f235f4aa4baabba7f2606b31d0fdb03988c52194c966728de8690bf17299d","src/unix/newlib/generic.rs":"eab066d9f0a0f3eb53cc1073d01496bba0110989e1f6a59838afd19f870cd599","src/unix/newlib/horizon/mod.rs":"7cc5cc120437421db139bfa6a90b18168cd3070bdd0f5be96d40fe4c996f3ca1","src/unix/newlib/mod.rs":"fcf8b307933cba5e9c485537499386326d665fe83b6fcfb9e9e1837f73332668","src/unix/newlib/no_align.rs":"e0743b2179495a9514bc3a4d1781e492878c4ec834ee0085d0891dd1712e82fb","src/unix/newlib/powerpc/mod.rs":"0202ffd57caf75b6afa2c9717750ffb96e375ac33df0ae9609a3f831be393b67","src/unix/no_align.rs":"c06e95373b9088266e0b14bba0954eef95f93fb2b01d951855e382d22de78e53","src/unix/nto/aarch64.rs":"4709c9afdc8d583be876598e7c238499ee3e8da5bd2baa614d9c7dd414851555","src/unix/nto/mod.rs":"44b74cd89794aecd7db67aad1c4114273f70be8d2e4633e3965f144fe53a7b88","src/unix/nto/neutrino.rs":"62198d95ccc0fe7ece6f9d5c0b29fc22303ef458886efb5e09aad524eca2ab7b","src/unix/nto/x86_64.rs":"a3e18e93c2999da1cd7a6f748a4b60c07aefb73d8ea2aafec19a84cfb040bc8e","src/unix/redox/mod.rs":"5ace39d26406bb89d04de70d827aa947f1565fd2b648b50cd5f8f1e92bacbd60","src/unix/solarish/compat.rs":"00f1ee3faec9da69204e42f025f6735dd13d894071a154425dcc43ecbdd06e7f","src/unix/solarish/illumos.rs":"cd93c2d84722bbf9933a92842a8998eb0b2afc962f50bc2546ad127b82809fa7","src/unix/solarish/mod.rs":"ab1ce2da7e11f86493752561da2ecfccc03bbbc281136a60accdd8fef3be75aa","src/unix/solarish/solaris.rs":"41b350a89ddf01cd12a10f93640f92be53be0b0d976021cdc08da17bf3e72edf","src/unix/solarish/x86.rs":"e86e806df0caed72765040eaa2f3c883198d1aa91508540adf9b7008c77f522e","src/unix/solarish/x86_64.rs":"ec2b01f194eb8a6a27133c57681da195a949e03098f3ea1e847227a9c09ef5fc","src/unix/solarish/x86_common.rs":"ac869d9c3c95645c22460468391eb1982023c3a8e02b9e06a72e3aef3d5f1eac","src/vxworks/aarch64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/arm.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/mod.rs":"ff063860fc4fe3bca6332742764e29c1506884added21aa7722144c1fb3f4018","src/vxworks/powerpc.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/powerpc64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/x86.rs":"552f007f38317620b23889cb7c49d1d115841252439060122f52f434fbc6e5ba","src/vxworks/x86_64.rs":"018d92be3ad628a129eff9f2f5dfbc0883d8b8e5f2fa917b900a7f98ed6b514a","src/wasi.rs":"09ee3b3348b212b050f6ca8ae008a28679ea44a375674307a4e7c9ca0d3ed7d5","src/windows/gnu/align.rs":"b2c13ec1b9f3b39a75c452c80c951dff9d0215e31d77e883b4502afb31794647","src/windows/gnu/mod.rs":"3c8c7edb7cdf5d0c44af936db2a94869585c69dfabeef30571b4f4e38375767a","src/windows/mod.rs":"5421b92f47cb69845f4323b1a14e533d8a17acc6412c58e67f4d41def749de2f","src/windows/msvc/mod.rs":"c068271e00fca6b62bc4bf44bcf142cfc38caeded9b6c4e01d1ceef3ccf986f4","src/xous.rs":"eb0675f25ba01f73072d2b70907fb8abb1148facefe5a20756c49250f3d65fae","tests/const_fn.rs":"cb75a1f0864f926aebe79118fc34d51a0d1ade2c20a394e7774c7e545f21f1f4"},"package":"6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317"} +\ No newline at end of file +diff --git a/vendor/libc/CONTRIBUTING.md b/vendor/libc/CONTRIBUTING.md +index 5be6eb9..8c551db 100644 +--- a/vendor/libc/CONTRIBUTING.md ++++ b/vendor/libc/CONTRIBUTING.md +@@ -72,6 +72,10 @@ after a certain period. The steps are: + If you're using it, please comment on #XXX"). + 2. If we don't see any concerns for a while, do the change actually. + ++## Supported target policy ++ ++When Rust removes a support for a target, the libc crate also may remove the support anytime. ++ + ## Releasing your change to crates.io + + Now that you've done the amazing job of landing your new API or your new +@@ -82,7 +86,7 @@ it. If you'd like to get a release out ASAP you can follow these steps: + 1. Increment the patch version number in `Cargo.toml` and `libc-test/Cargo.toml`. + 1. Send a PR to this repository. It should [look like this][example-pr], but it'd + also be nice to fill out the description with a small rationale for the +- release (any rationale is ok though!) ++ release (any rationale is ok though!). + 1. Once merged, the release will be tagged and published by one of the libc crate + maintainers. + +diff --git a/vendor/libc/Cargo.toml b/vendor/libc/Cargo.toml +index 9277941..707db43 100644 +--- a/vendor/libc/Cargo.toml ++++ b/vendor/libc/Cargo.toml +@@ -3,27 +3,50 @@ + # When uploading crates to the registry Cargo will automatically + # "normalize" Cargo.toml files for maximal compatibility + # with all versions of Cargo and also rewrite `path` dependencies +-# to registry (e.g., crates.io) dependencies ++# to registry (e.g., crates.io) dependencies. + # +-# If you believe there's an error in this file please file an +-# issue against the rust-lang/cargo repository. If you're +-# editing this file be aware that the upstream Cargo.toml +-# will likely look very different (and much more reasonable) ++# If you are reading this file be aware that the original Cargo.toml ++# will likely look very different (and much more reasonable). ++# See Cargo.toml.orig for the original contents. + + [package] + name = "libc" +-version = "0.2.97" ++version = "0.2.142" + authors = ["The Rust Project Developers"] + build = "build.rs" +-exclude = ["/ci/*", "/.github/*", "/.cirrus.yml", "/triagebot.toml"] +-description = "Raw FFI bindings to platform libraries like libc.\n" ++exclude = [ ++ "/ci/*", ++ "/.github/*", ++ "/.cirrus.yml", ++ "/triagebot.toml", ++] ++description = """ ++Raw FFI bindings to platform libraries like libc. ++""" + homepage = "https://github.com/rust-lang/libc" + documentation = "https://docs.rs/libc/" + readme = "README.md" +-keywords = ["libc", "ffi", "bindings", "operating", "system"] +-categories = ["external-ffi-bindings", "no-std", "os"] ++keywords = [ ++ "libc", ++ "ffi", ++ "bindings", ++ "operating", ++ "system", ++] ++categories = [ ++ "external-ffi-bindings", ++ "no-std", ++ "os", ++] + license = "MIT OR Apache-2.0" + repository = "https://github.com/rust-lang/libc" ++ ++[package.metadata.docs.rs] ++features = [ ++ "const-extern-fn", ++ "extra_traits", ++] ++ + [dependencies.rustc-std-workspace-core] + version = "1.0.0" + optional = true +@@ -33,6 +56,9 @@ align = [] + const-extern-fn = [] + default = ["std"] + extra_traits = [] +-rustc-dep-of-std = ["align", "rustc-std-workspace-core"] ++rustc-dep-of-std = [ ++ "align", ++ "rustc-std-workspace-core", ++] + std = [] + use_std = ["std"] +diff --git a/vendor/libc/LICENSE-APACHE b/vendor/libc/LICENSE-APACHE +index 16fe87b..1b5ec8b 100644 +--- a/vendor/libc/LICENSE-APACHE ++++ b/vendor/libc/LICENSE-APACHE +@@ -174,28 +174,3 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS +- +-APPENDIX: How to apply the Apache License to your work. +- +- To apply the Apache License to your work, attach the following +- boilerplate notice, with the fields enclosed by brackets "[]" +- replaced with your own identifying information. (Don't include +- the brackets!) The text should be enclosed in the appropriate +- comment syntax for the file format. We also recommend that a +- file or class name and description of purpose be included on the +- same "printed page" as the copyright notice for easier +- identification within third-party archives. +- +-Copyright [yyyy] [name of copyright owner] +- +-Licensed under the Apache License, Version 2.0 (the "License"); +-you may not use this file except in compliance with the License. +-You may obtain a copy of the License at +- +- http://www.apache.org/licenses/LICENSE-2.0 +- +-Unless required by applicable law or agreed to in writing, software +-distributed under the License is distributed on an "AS IS" BASIS, +-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-See the License for the specific language governing permissions and +-limitations under the License. +diff --git a/vendor/libc/README.md b/vendor/libc/README.md +index a8a3afd..bc5ad18 100644 +--- a/vendor/libc/README.md ++++ b/vendor/libc/README.md +@@ -35,13 +35,16 @@ libc = "0.2" + This feature derives `Debug`, `Eq`, `Hash`, and `PartialEq`. + + * `const-extern-fn`: Changes some `extern fn`s into `const extern fn`s. +- This feature requires a nightly rustc. ++ If you use Rust >= 1.62, this feature is implicitly enabled. ++ Otherwise it requires a nightly rustc. + + * **deprecated**: `use_std` is deprecated, and is equivalent to `std`. + + ## Rust version support + +-The minimum supported Rust toolchain version is **Rust 1.13.0** . APIs requiring ++The minimum supported Rust toolchain version is currently **Rust 1.13.0**. ++(libc does not currently have any policy regarding changes to the minimum ++supported Rust version; such policy is a work in progress.) APIs requiring + newer Rust features are only available on newer Rust toolchains: + + | Feature | Version | +@@ -53,6 +56,7 @@ newer Rust features are only available on newer Rust toolchains: + | `core::ffi::c_void` | 1.30.0 | + | `repr(packed(N))` | 1.33.0 | + | `cfg(target_vendor)` | 1.33.0 | ++| `const-extern-fn` | 1.62.0 | + + ## Platform support + +diff --git a/vendor/libc/build.rs b/vendor/libc/build.rs +index c498211..79bec0e 100644 +--- a/vendor/libc/build.rs ++++ b/vendor/libc/build.rs +@@ -1,16 +1,52 @@ + use std::env; + use std::process::Command; + use std::str; ++use std::string::String; ++ ++// List of cfgs this build script is allowed to set. The list is needed to support check-cfg, as we ++// need to know all the possible cfgs that this script will set. If you need to set another cfg ++// make sure to add it to this list as well. ++const ALLOWED_CFGS: &'static [&'static str] = &[ ++ "freebsd10", ++ "freebsd11", ++ "freebsd12", ++ "freebsd13", ++ "freebsd14", ++ "libc_align", ++ "libc_cfg_target_vendor", ++ "libc_const_extern_fn", ++ "libc_const_extern_fn_unstable", ++ "libc_const_size_of", ++ "libc_core_cvoid", ++ "libc_deny_warnings", ++ "libc_int128", ++ "libc_long_array", ++ "libc_non_exhaustive", ++ "libc_packedN", ++ "libc_priv_mod_use", ++ "libc_ptr_addr_of", ++ "libc_thread_local", ++ "libc_underscore_const_names", ++ "libc_union", ++]; ++ ++// Extra values to allow for check-cfg. ++const CHECK_CFG_EXTRA: &'static [(&'static str, &'static [&'static str])] = &[ ++ ("target_os", &["switch", "aix", "ohos"]), ++ ("target_env", &["illumos", "wasi", "aix", "ohos"]), ++ ("target_arch", &["loongarch64"]), ++]; + + fn main() { + // Avoid unnecessary re-building. + println!("cargo:rerun-if-changed=build.rs"); + +- let (rustc_minor_ver, is_nightly) = rustc_minor_nightly().expect("Failed to get rustc version"); ++ let (rustc_minor_ver, is_nightly) = rustc_minor_nightly(); + let rustc_dep_of_std = env::var("CARGO_FEATURE_RUSTC_DEP_OF_STD").is_ok(); + let align_cargo_feature = env::var("CARGO_FEATURE_ALIGN").is_ok(); + let const_extern_fn_cargo_feature = env::var("CARGO_FEATURE_CONST_EXTERN_FN").is_ok(); + let libc_ci = env::var("LIBC_CI").is_ok(); ++ let libc_check_cfg = env::var("LIBC_CHECK_CFG").is_ok(); + + if env::var("CARGO_FEATURE_USE_STD").is_ok() { + println!( +@@ -25,83 +61,139 @@ fn main() { + // On CI, we detect the actual FreeBSD version and match its ABI exactly, + // running tests to ensure that the ABI is correct. + match which_freebsd() { +- Some(10) if libc_ci || rustc_dep_of_std => { +- println!("cargo:rustc-cfg=freebsd10") +- } +- Some(11) if libc_ci => println!("cargo:rustc-cfg=freebsd11"), +- Some(12) if libc_ci => println!("cargo:rustc-cfg=freebsd12"), +- Some(13) if libc_ci => println!("cargo:rustc-cfg=freebsd13"), +- Some(_) | None => println!("cargo:rustc-cfg=freebsd11"), ++ Some(10) if libc_ci || rustc_dep_of_std => set_cfg("freebsd10"), ++ Some(11) if libc_ci => set_cfg("freebsd11"), ++ Some(12) if libc_ci => set_cfg("freebsd12"), ++ Some(13) if libc_ci => set_cfg("freebsd13"), ++ Some(14) if libc_ci => set_cfg("freebsd14"), ++ Some(_) | None => set_cfg("freebsd11"), + } + + // On CI: deny all warnings + if libc_ci { +- println!("cargo:rustc-cfg=libc_deny_warnings"); ++ set_cfg("libc_deny_warnings"); + } + + // Rust >= 1.15 supports private module use: + if rustc_minor_ver >= 15 || rustc_dep_of_std { +- println!("cargo:rustc-cfg=libc_priv_mod_use"); ++ set_cfg("libc_priv_mod_use"); + } + + // Rust >= 1.19 supports unions: + if rustc_minor_ver >= 19 || rustc_dep_of_std { +- println!("cargo:rustc-cfg=libc_union"); ++ set_cfg("libc_union"); + } + + // Rust >= 1.24 supports const mem::size_of: + if rustc_minor_ver >= 24 || rustc_dep_of_std { +- println!("cargo:rustc-cfg=libc_const_size_of"); ++ set_cfg("libc_const_size_of"); + } + + // Rust >= 1.25 supports repr(align): + if rustc_minor_ver >= 25 || rustc_dep_of_std || align_cargo_feature { +- println!("cargo:rustc-cfg=libc_align"); ++ set_cfg("libc_align"); ++ } ++ ++ // Rust >= 1.26 supports i128 and u128: ++ if rustc_minor_ver >= 26 || rustc_dep_of_std { ++ set_cfg("libc_int128"); + } + + // Rust >= 1.30 supports `core::ffi::c_void`, so libc can just re-export it. + // Otherwise, it defines an incompatible type to retaining + // backwards-compatibility. + if rustc_minor_ver >= 30 || rustc_dep_of_std { +- println!("cargo:rustc-cfg=libc_core_cvoid"); ++ set_cfg("libc_core_cvoid"); + } + + // Rust >= 1.33 supports repr(packed(N)) and cfg(target_vendor). + if rustc_minor_ver >= 33 || rustc_dep_of_std { +- println!("cargo:rustc-cfg=libc_packedN"); +- println!("cargo:rustc-cfg=libc_cfg_target_vendor"); ++ set_cfg("libc_packedN"); ++ set_cfg("libc_cfg_target_vendor"); ++ } ++ ++ // Rust >= 1.40 supports #[non_exhaustive]. ++ if rustc_minor_ver >= 40 || rustc_dep_of_std { ++ set_cfg("libc_non_exhaustive"); ++ } ++ ++ // Rust >= 1.47 supports long array: ++ if rustc_minor_ver >= 47 || rustc_dep_of_std { ++ set_cfg("libc_long_array"); ++ } ++ ++ if rustc_minor_ver >= 51 || rustc_dep_of_std { ++ set_cfg("libc_ptr_addr_of"); ++ } ++ ++ // Rust >= 1.37.0 allows underscores as anonymous constant names. ++ if rustc_minor_ver >= 37 || rustc_dep_of_std { ++ set_cfg("libc_underscore_const_names"); + } + + // #[thread_local] is currently unstable + if rustc_dep_of_std { +- println!("cargo:rustc-cfg=libc_thread_local"); ++ set_cfg("libc_thread_local"); + } + +- if const_extern_fn_cargo_feature { +- if !is_nightly || rustc_minor_ver < 40 { +- panic!("const-extern-fn requires a nightly compiler >= 1.40") ++ // Rust >= 1.62.0 allows to use `const_extern_fn` for "Rust" and "C". ++ if rustc_minor_ver >= 62 { ++ set_cfg("libc_const_extern_fn"); ++ } else { ++ // Rust < 1.62.0 requires a crate feature and feature gate. ++ if const_extern_fn_cargo_feature { ++ if !is_nightly || rustc_minor_ver < 40 { ++ panic!("const-extern-fn requires a nightly compiler >= 1.40"); ++ } ++ set_cfg("libc_const_extern_fn_unstable"); ++ set_cfg("libc_const_extern_fn"); ++ } ++ } ++ ++ // check-cfg is a nightly cargo/rustc feature to warn when unknown cfgs are used across the ++ // codebase. libc can configure it if the appropriate environment variable is passed. Since ++ // rust-lang/rust enforces it, this is useful when using a custom libc fork there. ++ // ++ // https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg ++ if libc_check_cfg { ++ for cfg in ALLOWED_CFGS { ++ println!("cargo:rustc-check-cfg=values({})", cfg); ++ } ++ for &(name, values) in CHECK_CFG_EXTRA { ++ let values = values.join("\",\""); ++ println!("cargo:rustc-check-cfg=values({},\"{}\")", name, values); + } +- println!("cargo:rustc-cfg=libc_const_extern_fn"); + } + } + +-fn rustc_minor_nightly() -> Option<(u32, bool)> { ++fn rustc_minor_nightly() -> (u32, bool) { + macro_rules! otry { + ($e:expr) => { + match $e { + Some(e) => e, +- None => return None, ++ None => panic!("Failed to get rustc version"), + } + }; + } + + let rustc = otry!(env::var_os("RUSTC")); +- let output = otry!(Command::new(rustc).arg("--version").output().ok()); ++ let output = Command::new(rustc) ++ .arg("--version") ++ .output() ++ .ok() ++ .expect("Failed to get rustc version"); ++ if !output.status.success() { ++ panic!( ++ "failed to run rustc: {}", ++ String::from_utf8_lossy(output.stderr.as_slice()) ++ ); ++ } ++ + let version = otry!(str::from_utf8(&output.stdout).ok()); + let mut pieces = version.split('.'); + + if pieces.next() != Some("rustc 1") { +- return None; ++ panic!("Failed to get rustc version"); + } + + let minor = pieces.next(); +@@ -117,7 +209,7 @@ fn rustc_minor_nightly() -> Option<(u32, bool)> { + .unwrap_or(false); + let minor = otry!(otry!(minor).parse().ok()); + +- Some((minor, nightly)) ++ (minor, nightly) + } + + fn which_freebsd() -> Option { +@@ -141,6 +233,14 @@ fn which_freebsd() -> Option { + s if s.starts_with("11") => Some(11), + s if s.starts_with("12") => Some(12), + s if s.starts_with("13") => Some(13), ++ s if s.starts_with("14") => Some(14), + _ => None, + } + } ++ ++fn set_cfg(cfg: &str) { ++ if !ALLOWED_CFGS.contains(&cfg) { ++ panic!("trying to set cfg {}, but it is not in ALLOWED_CFGS", cfg); ++ } ++ println!("cargo:rustc-cfg={}", cfg); ++} +diff --git a/vendor/libc/src/fixed_width_ints.rs b/vendor/libc/src/fixed_width_ints.rs +index 0146408..999de8f 100644 +--- a/vendor/libc/src/fixed_width_ints.rs ++++ b/vendor/libc/src/fixed_width_ints.rs +@@ -18,3 +18,82 @@ pub type uint16_t = u16; + pub type uint32_t = u32; + #[deprecated(since = "0.2.55", note = "Use u64 instead.")] + pub type uint64_t = u64; ++ ++cfg_if! { ++ if #[cfg(all(libc_int128, target_arch = "aarch64", not(target_os = "windows")))] { ++ // This introduces partial support for FFI with __int128 and ++ // equivalent types on platforms where Rust's definition is validated ++ // to match the standard C ABI of that platform. ++ // ++ // Rust does not guarantee u128/i128 are sound for FFI, and its ++ // definitions are in fact known to be incompatible. [0] ++ // ++ // However these problems aren't fundamental, and are just platform ++ // inconsistencies. Specifically at the time of this writing: ++ // ++ // * For x64 SysV ABIs (everything but Windows), the types are underaligned. ++ // * For all Windows ABIs, Microsoft doesn't actually officially define __int128, ++ // and as a result different implementations don't actually agree on its ABI. ++ // ++ // But on the other major aarch64 platforms (android, linux, ios, macos) we have ++ // validated that rustc has the right ABI for these types. This is important because ++ // aarch64 uses these types in some fundamental OS types like user_fpsimd_struct, ++ // which represents saved simd registers. ++ // ++ // Any API which uses these types will need to `#[ignore(improper_ctypes)]` ++ // until the upstream rust issue is resolved, but this at least lets us make ++ // progress on platforms where this type is important. ++ // ++ // The list of supported architectures and OSes is intentionally very restricted, ++ // as careful work needs to be done to verify that a particular platform ++ // has a conformant ABI. ++ // ++ // [0]: https://github.com/rust-lang/rust/issues/54341 ++ ++ /// C `__int128` (a GCC extension that's part of many ABIs) ++ pub type __int128 = i128; ++ /// C `unsigned __int128` (a GCC extension that's part of many ABIs) ++ pub type __uint128 = u128; ++ /// C __int128_t (alternate name for [__int128][]) ++ pub type __int128_t = i128; ++ /// C __uint128_t (alternate name for [__uint128][]) ++ pub type __uint128_t = u128; ++ ++ cfg_if! { ++ if #[cfg(libc_underscore_const_names)] { ++ macro_rules! static_assert_eq { ++ ($a:expr, $b:expr) => { ++ const _: [(); $a] = [(); $b]; ++ }; ++ } ++ ++ // NOTE: if you add more platforms to here, you may need to cfg ++ // these consts. They should always match the platform's values ++ // for `sizeof(__int128)` and `_Alignof(__int128)`. ++ const _SIZE_128: usize = 16; ++ const _ALIGN_128: usize = 16; ++ ++ // Since Rust doesn't officially guarantee that these types ++ // have compatible ABIs, we const assert that these values have the ++ // known size/align of the target platform's libc. If rustc ever ++ // tries to regress things, it will cause a compilation error. ++ // ++ // This isn't a bullet-proof solution because e.g. it doesn't ++ // catch the fact that llvm and gcc disagree on how x64 __int128 ++ // is actually *passed* on the stack (clang underaligns it for ++ // the same reason that rustc *never* properly aligns it). ++ static_assert_eq!(core::mem::size_of::<__int128>(), _SIZE_128); ++ static_assert_eq!(core::mem::align_of::<__int128>(), _ALIGN_128); ++ ++ static_assert_eq!(core::mem::size_of::<__uint128>(), _SIZE_128); ++ static_assert_eq!(core::mem::align_of::<__uint128>(), _ALIGN_128); ++ ++ static_assert_eq!(core::mem::size_of::<__int128_t>(), _SIZE_128); ++ static_assert_eq!(core::mem::align_of::<__int128_t>(), _ALIGN_128); ++ ++ static_assert_eq!(core::mem::size_of::<__uint128_t>(), _SIZE_128); ++ static_assert_eq!(core::mem::align_of::<__uint128_t>(), _ALIGN_128); ++ } ++ } ++ } ++} +diff --git a/vendor/libc/src/fuchsia/aarch64.rs b/vendor/libc/src/fuchsia/aarch64.rs +index 259893c..33e3934 100644 +--- a/vendor/libc/src/fuchsia/aarch64.rs ++++ b/vendor/libc/src/fuchsia/aarch64.rs +@@ -62,5 +62,6 @@ s! { + } + } + ++// From https://cs.opensource.google/fuchsia/fuchsia/+/main:zircon/third_party/ulib/musl/include/bits/signal.h;l=20-21;drc=0827b18ab9540c46f8037f407d17ea15a79e9ba7 + pub const MINSIGSTKSZ: ::size_t = 6144; + pub const SIGSTKSZ: ::size_t = 12288; +diff --git a/vendor/libc/src/fuchsia/mod.rs b/vendor/libc/src/fuchsia/mod.rs +index 4300338..6b12185 100644 +--- a/vendor/libc/src/fuchsia/mod.rs ++++ b/vendor/libc/src/fuchsia/mod.rs +@@ -877,6 +877,11 @@ s! { + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } ++ ++ pub struct in6_pktinfo { ++ pub ipi6_addr: ::in6_addr, ++ pub ipi6_ifindex: ::c_uint, ++ } + } + + s_no_extra_traits! { +@@ -904,8 +909,8 @@ s_no_extra_traits! { + + pub struct sockaddr_storage { + pub ss_family: sa_family_t, ++ __ss_pad2: [u8; 128 - 2 - 8], + __ss_align: ::size_t, +- __ss_pad2: [u8; 128 - 2 * 8], + } + + pub struct utsname { +@@ -1313,6 +1318,7 @@ pub const SIG_DFL: sighandler_t = 0 as sighandler_t; + pub const SIG_IGN: sighandler_t = 1 as sighandler_t; + pub const SIG_ERR: sighandler_t = !0 as sighandler_t; + ++pub const DT_UNKNOWN: u8 = 0; + pub const DT_FIFO: u8 = 1; + pub const DT_CHR: u8 = 2; + pub const DT_DIR: u8 = 4; +@@ -1787,6 +1793,9 @@ pub const IPV6_MULTICAST_LOOP: ::c_int = 19; + pub const IPV6_ADD_MEMBERSHIP: ::c_int = 20; + pub const IPV6_DROP_MEMBERSHIP: ::c_int = 21; + pub const IPV6_V6ONLY: ::c_int = 26; ++pub const IPV6_RECVPKTINFO: ::c_int = 49; ++pub const IPV6_RECVTCLASS: ::c_int = 66; ++pub const IPV6_TCLASS: ::c_int = 67; + + pub const TCP_NODELAY: ::c_int = 1; + pub const TCP_MAXSEG: ::c_int = 2; +@@ -2593,6 +2602,7 @@ pub const PR_SET_MM_MAP: ::c_int = 14; + pub const PR_SET_MM_MAP_SIZE: ::c_int = 15; + + pub const PR_SET_PTRACER: ::c_int = 0x59616d61; ++pub const PR_SET_PTRACER_ANY: ::c_ulong = 0xffffffffffffffff; + + pub const PR_SET_CHILD_SUBREAPER: ::c_int = 36; + pub const PR_GET_CHILD_SUBREAPER: ::c_int = 37; +@@ -2668,6 +2678,9 @@ pub const PT_GNU_EH_FRAME: u32 = 0x6474e550; + pub const PT_GNU_STACK: u32 = 0x6474e551; + pub const PT_GNU_RELRO: u32 = 0x6474e552; + ++// Ethernet protocol IDs. ++pub const ETH_P_IP: ::c_int = 0x0800; ++ + pub const SFD_CLOEXEC: ::c_int = 0x080000; + + pub const NCCS: usize = 32; +@@ -3158,7 +3171,7 @@ f! { + return + } + +- pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool { ++ pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0 +@@ -3223,17 +3236,6 @@ f! { + minor as ::c_uint + } + +- pub fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { +- let major = major as ::dev_t; +- let minor = minor as ::dev_t; +- let mut dev = 0; +- dev |= (major & 0x00000fff) << 8; +- dev |= (major & 0xfffff000) << 32; +- dev |= (minor & 0x000000ff) << 0; +- dev |= (minor & 0xffffff00) << 12; +- dev +- } +- + pub fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { + cmsg.offset(1) as *mut c_uchar + } +@@ -3310,6 +3312,17 @@ safe_f! { + pub {const} fn QCMD(cmd: ::c_int, type_: ::c_int) -> ::c_int { + (cmd << 8) | (type_ & 0x00ff) + } ++ ++ pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { ++ let major = major as ::dev_t; ++ let minor = minor as ::dev_t; ++ let mut dev = 0; ++ dev |= (major & 0x00000fff) << 8; ++ dev |= (major & 0xfffff000) << 32; ++ dev |= (minor & 0x000000ff) << 0; ++ dev |= (minor & 0xffffff00) << 12; ++ dev ++ } + } + + fn __CMSG_LEN(cmsg: *const cmsghdr) -> ::ssize_t { +@@ -3390,10 +3403,16 @@ extern "C" { + pub fn feof(stream: *mut FILE) -> c_int; + pub fn ferror(stream: *mut FILE) -> c_int; + pub fn perror(s: *const c_char); ++ pub fn atof(s: *const c_char) -> c_double; + pub fn atoi(s: *const c_char) -> c_int; ++ pub fn atol(s: *const c_char) -> c_long; ++ pub fn atoll(s: *const c_char) -> c_longlong; + pub fn strtod(s: *const c_char, endp: *mut *mut c_char) -> c_double; ++ pub fn strtof(s: *const c_char, endp: *mut *mut c_char) -> c_float; + pub fn strtol(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_long; ++ pub fn strtoll(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_longlong; + pub fn strtoul(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulong; ++ pub fn strtoull(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulonglong; + pub fn calloc(nobj: size_t, size: size_t) -> *mut c_void; + pub fn malloc(size: size_t) -> *mut c_void; + pub fn realloc(p: *mut c_void, size: size_t) -> *mut c_void; +@@ -3435,7 +3454,6 @@ extern "C" { + pub fn memset(dest: *mut c_void, c: c_int, n: size_t) -> *mut c_void; + + pub fn abs(i: c_int) -> c_int; +- pub fn atof(s: *const c_char) -> c_double; + pub fn labs(i: c_long) -> c_long; + pub fn rand() -> c_int; + pub fn srand(seed: c_uint); +@@ -3767,7 +3785,7 @@ extern "C" { + pub fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: ::c_int) -> ::c_int; + pub fn select( + nfds: ::c_int, +- readfs: *mut fd_set, ++ readfds: *mut fd_set, + writefds: *mut fd_set, + errorfds: *mut fd_set, + timeout: *mut timeval, +@@ -3804,7 +3822,7 @@ extern "C" { + + pub fn pselect( + nfds: ::c_int, +- readfs: *mut fd_set, ++ readfds: *mut fd_set, + writefds: *mut fd_set, + errorfds: *mut fd_set, + timeout: *const timespec, +@@ -4199,6 +4217,11 @@ extern "C" { + child: ::Option, + ) -> ::c_int; + pub fn getgrgid(gid: ::gid_t) -> *mut ::group; ++ ++ pub fn setgrent(); ++ pub fn endgrent(); ++ pub fn getgrent() -> *mut ::group; ++ + pub fn getgrouplist( + user: *const ::c_char, + group: ::gid_t, +@@ -4237,6 +4260,9 @@ cfg_if! { + } else if #[cfg(any(target_arch = "x86_64"))] { + mod x86_64; + pub use self::x86_64::*; ++ } else if #[cfg(any(target_arch = "riscv64"))] { ++ mod riscv64; ++ pub use self::riscv64::*; + } else { + // Unknown target_arch + } +diff --git a/vendor/libc/src/fuchsia/riscv64.rs b/vendor/libc/src/fuchsia/riscv64.rs +new file mode 100644 +index 0000000..de2b719 +--- /dev/null ++++ b/vendor/libc/src/fuchsia/riscv64.rs +@@ -0,0 +1,44 @@ ++// From psABI Calling Convention for RV64 ++pub type c_char = u8; ++pub type __u64 = ::c_ulonglong; ++pub type wchar_t = i32; ++ ++pub type nlink_t = ::c_ulong; ++pub type blksize_t = ::c_long; ++ ++pub type stat64 = stat; ++s! { ++ pub struct stat { ++ pub st_dev: ::dev_t, ++ pub st_ino: ::ino_t, ++ pub st_nlink: ::nlink_t, ++ pub st_mode: ::mode_t, ++ pub st_uid: ::uid_t, ++ pub st_gid: ::gid_t, ++ __pad0: ::c_int, ++ pub st_rdev: ::dev_t, ++ pub st_size: ::off_t, ++ pub st_blksize: ::blksize_t, ++ pub st_blocks: ::blkcnt_t, ++ pub st_atime: ::time_t, ++ pub st_atime_nsec: ::c_long, ++ pub st_mtime: ::time_t, ++ pub st_mtime_nsec: ::c_long, ++ pub st_ctime: ::time_t, ++ pub st_ctime_nsec: ::c_long, ++ __unused: [::c_long; 3], ++ } ++ ++ // Not actually used, IPC calls just return ENOSYS ++ pub struct ipc_perm { ++ pub __ipc_perm_key: ::key_t, ++ pub uid: ::uid_t, ++ pub gid: ::gid_t, ++ pub cuid: ::uid_t, ++ pub cgid: ::gid_t, ++ pub mode: ::mode_t, ++ pub __seq: ::c_ushort, ++ __unused1: ::c_ulong, ++ __unused2: ::c_ulong, ++ } ++} +diff --git a/vendor/libc/src/lib.rs b/vendor/libc/src/lib.rs +index 30c94b0..d9bd318 100644 +--- a/vendor/libc/src/lib.rs ++++ b/vendor/libc/src/lib.rs +@@ -13,7 +13,9 @@ + improper_ctypes, + // This lint is renamed but we run CI for old stable rustc so should be here. + redundant_semicolon, +- redundant_semicolons ++ redundant_semicolons, ++ unused_macros, ++ unused_macro_rules, + )] + #![cfg_attr(libc_deny_warnings, deny(warnings))] + // Attributes needed when building as part of the standard library +@@ -24,11 +26,7 @@ + #![deny(missing_copy_implementations, safe_packed_borrows)] + #![cfg_attr(not(feature = "rustc-dep-of-std"), no_std)] + #![cfg_attr(feature = "rustc-dep-of-std", no_core)] +-#![cfg_attr( +- any(feature = "rustc-dep-of-std", target_os = "redox"), +- feature(static_nobundle) +-)] +-#![cfg_attr(libc_const_extern_fn, feature(const_extern_fn))] ++#![cfg_attr(libc_const_extern_fn_unstable, feature(const_extern_fn))] + + #[macro_use] + mod macros; +@@ -63,7 +61,7 @@ cfg_if! { + use core::clone::Clone; + #[doc(hidden)] + #[allow(unused_imports)] +- use core::marker::Copy; ++ use core::marker::{Copy, Send, Sync}; + #[doc(hidden)] + #[allow(unused_imports)] + use core::option::Option; +@@ -85,7 +83,7 @@ cfg_if! { + pub use core::clone::Clone; + #[doc(hidden)] + #[allow(unused_imports)] +- pub use core::marker::Copy; ++ pub use core::marker::{Copy, Send, Sync}; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::option::Option; +@@ -123,6 +121,12 @@ cfg_if! { + + mod vxworks; + pub use vxworks::*; ++ } else if #[cfg(target_os = "solid_asp3")] { ++ mod fixed_width_ints; ++ pub use fixed_width_ints::*; ++ ++ mod solid; ++ pub use solid::*; + } else if #[cfg(unix)] { + mod fixed_width_ints; + pub use fixed_width_ints::*; +@@ -147,6 +151,12 @@ cfg_if! { + + mod wasi; + pub use wasi::*; ++ } else if #[cfg(target_os = "xous")] { ++ mod fixed_width_ints; ++ pub use fixed_width_ints::*; ++ ++ mod xous; ++ pub use xous::*; + } else { + // non-supported targets: empty... + } +diff --git a/vendor/libc/src/macros.rs b/vendor/libc/src/macros.rs +index 1871cfa..fd47370 100644 +--- a/vendor/libc/src/macros.rs ++++ b/vendor/libc/src/macros.rs +@@ -6,7 +6,6 @@ + /// + /// This allows you to conveniently provide a long list #[cfg]'d blocks of code + /// without having to rewrite each clause multiple times. +-#[allow(unused_macros)] + macro_rules! cfg_if { + // match if/else chains with a final `else` + ($( +@@ -62,7 +61,6 @@ macro_rules! cfg_if { + }; + } + +-#[allow(unused_macros)] + macro_rules! s { + ($($(#[$attr:meta])* pub $t:ident $i:ident { $($field:tt)* })*) => ($( + s!(it: $(#[$attr])* pub $t $i { $($field)* }); +@@ -87,7 +85,6 @@ macro_rules! s { + ); + } + +-#[allow(unused_macros)] + macro_rules! s_no_extra_traits { + ($($(#[$attr:meta])* pub $t:ident $i:ident { $($field:tt)* })*) => ($( + s_no_extra_traits!(it: $(#[$attr])* pub $t $i { $($field)* }); +@@ -123,7 +120,6 @@ macro_rules! s_no_extra_traits { + ); + } + +-#[allow(unused_macros)] + macro_rules! e { + ($($(#[$attr:meta])* pub enum $i:ident { $($field:tt)* })*) => ($( + __item! { +@@ -138,7 +134,6 @@ macro_rules! e { + )*); + } + +-#[allow(unused_macros)] + macro_rules! s_paren { + ($($(#[$attr:meta])* pub struct $i:ident ( $($field:tt)* ); )* ) => ($( + __item! { +@@ -182,7 +177,6 @@ macro_rules! s_paren { + // 'f!' block + cfg_if! { + if #[cfg(libc_const_extern_fn)] { +- #[allow(unused_macros)] + macro_rules! f { + ($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* +@@ -198,7 +192,6 @@ cfg_if! { + )*) + } + +- #[allow(unused_macros)] + macro_rules! safe_f { + ($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* +@@ -214,7 +207,6 @@ cfg_if! { + )*) + } + +- #[allow(unused_macros)] + macro_rules! const_fn { + ($($(#[$attr:meta])* $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* +@@ -231,7 +223,6 @@ cfg_if! { + } + + } else { +- #[allow(unused_macros)] + macro_rules! f { + ($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* +@@ -247,7 +238,6 @@ cfg_if! { + )*) + } + +- #[allow(unused_macros)] + macro_rules! safe_f { + ($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* +@@ -263,7 +253,6 @@ cfg_if! { + )*) + } + +- #[allow(unused_macros)] + macro_rules! const_fn { + ($($(#[$attr:meta])* $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* +@@ -281,14 +270,12 @@ cfg_if! { + } + } + +-#[allow(unused_macros)] + macro_rules! __item { + ($i:item) => { + $i + }; + } + +-#[allow(unused_macros)] + macro_rules! align_const { + ($($(#[$attr:meta])* + pub const $name:ident : $t1:ty +@@ -307,13 +294,12 @@ macro_rules! align_const { + )*) + } + +-// This macro is used to deprecate items that should be accessed via the mach crate +-#[allow(unused_macros)] ++// This macro is used to deprecate items that should be accessed via the mach2 crate + macro_rules! deprecated_mach { + (pub const $id:ident: $ty:ty = $expr:expr;) => { + #[deprecated( + since = "0.2.55", +- note = "Use the `mach` crate instead", ++ note = "Use the `mach2` crate instead", + )] + #[allow(deprecated)] + pub const $id: $ty = $expr; +@@ -328,7 +314,7 @@ macro_rules! deprecated_mach { + (pub type $id:ident = $ty:ty;) => { + #[deprecated( + since = "0.2.55", +- note = "Use the `mach` crate instead", ++ note = "Use the `mach2` crate instead", + )] + #[allow(deprecated)] + pub type $id = $ty; +@@ -341,3 +327,17 @@ macro_rules! deprecated_mach { + )* + } + } ++ ++#[cfg(not(libc_ptr_addr_of))] ++macro_rules! ptr_addr_of { ++ ($place:expr) => { ++ &$place ++ }; ++} ++ ++#[cfg(libc_ptr_addr_of)] ++macro_rules! ptr_addr_of { ++ ($place:expr) => { ++ ::core::ptr::addr_of!($place) ++ }; ++} +diff --git a/vendor/libc/src/solid/aarch64.rs b/vendor/libc/src/solid/aarch64.rs +new file mode 100644 +index 0000000..ceabea3 +--- /dev/null ++++ b/vendor/libc/src/solid/aarch64.rs +@@ -0,0 +1,4 @@ ++pub type c_char = i8; ++pub type wchar_t = u32; ++pub type c_long = i64; ++pub type c_ulong = u64; +diff --git a/vendor/libc/src/solid/arm.rs b/vendor/libc/src/solid/arm.rs +new file mode 100644 +index 0000000..04cc154 +--- /dev/null ++++ b/vendor/libc/src/solid/arm.rs +@@ -0,0 +1,4 @@ ++pub type c_char = i8; ++pub type wchar_t = u32; ++pub type c_long = i32; ++pub type c_ulong = u32; +diff --git a/vendor/libc/src/solid/mod.rs b/vendor/libc/src/solid/mod.rs +new file mode 100644 +index 0000000..f0f2ae8 +--- /dev/null ++++ b/vendor/libc/src/solid/mod.rs +@@ -0,0 +1,904 @@ ++//! Interface to the [SOLID] C library ++//! ++//! [SOLID]: https://solid.kmckk.com/ ++ ++pub type c_schar = i8; ++pub type c_uchar = u8; ++pub type c_short = i16; ++pub type c_ushort = u16; ++pub type c_int = i32; ++pub type c_uint = u32; ++pub type c_float = f32; ++pub type c_double = f64; ++pub type c_longlong = i64; ++pub type c_ulonglong = u64; ++pub type intmax_t = i64; ++pub type uintmax_t = u64; ++ ++pub type uintptr_t = usize; ++pub type intptr_t = isize; ++pub type ptrdiff_t = isize; ++pub type size_t = ::uintptr_t; ++pub type ssize_t = ::intptr_t; ++ ++pub type clock_t = c_uint; ++pub type time_t = i64; ++pub type clockid_t = c_int; ++pub type timer_t = c_int; ++pub type suseconds_t = c_int; ++pub type useconds_t = c_uint; ++ ++pub type sighandler_t = size_t; ++ ++// sys/ansi.h ++pub type __caddr_t = *mut c_char; ++pub type __gid_t = u32; ++pub type __in_addr_t = u32; ++pub type __in_port_t = u16; ++pub type __mode_t = u32; ++pub type __off_t = i64; ++pub type __pid_t = i32; ++pub type __sa_family_t = u8; ++pub type __socklen_t = c_uint; ++pub type __uid_t = u32; ++pub type __fsblkcnt_t = u64; ++pub type __fsfilcnt_t = u64; ++ ++// locale.h ++pub type locale_t = usize; ++ ++// nl_types.h ++pub type nl_item = c_long; ++ ++// sys/types.h ++pub type __va_list = *mut c_char; ++pub type u_int8_t = u8; ++pub type u_int16_t = u16; ++pub type u_int32_t = u32; ++pub type u_int64_t = u64; ++pub type u_char = c_uchar; ++pub type u_short = c_ushort; ++pub type u_int = c_uint; ++pub type u_long = c_ulong; ++pub type unchar = c_uchar; ++pub type ushort = c_ushort; ++pub type uint = c_uint; ++pub type ulong = c_ulong; ++pub type u_quad_t = u64; ++pub type quad_t = i64; ++pub type qaddr_t = *mut quad_t; ++pub type longlong_t = i64; ++pub type u_longlong_t = u64; ++pub type blkcnt_t = i64; ++pub type blksize_t = i32; ++pub type fsblkcnt_t = __fsblkcnt_t; ++pub type fsfilcnt_t = __fsfilcnt_t; ++pub type caddr_t = __caddr_t; ++pub type daddr_t = i64; ++pub type dev_t = u64; ++pub type fixpt_t = u32; ++pub type gid_t = __gid_t; ++pub type idtype_t = c_int; ++pub type id_t = u32; ++pub type ino_t = u64; ++pub type key_t = c_long; ++pub type mode_t = __mode_t; ++pub type nlink_t = u32; ++pub type off_t = __off_t; ++pub type pid_t = __pid_t; ++pub type lwpid_t = i32; ++pub type rlim_t = u64; ++pub type segsz_t = i32; ++pub type swblk_t = i32; ++pub type mqd_t = c_int; ++pub type cpuid_t = c_ulong; ++pub type psetid_t = c_int; ++ ++s! { ++ // stat.h ++ pub struct stat { ++ pub st_dev: dev_t, ++ pub st_ino: ino_t, ++ pub st_mode: c_short, ++ pub st_nlink: c_short, ++ pub st_uid: c_short, ++ pub st_gid: c_short, ++ pub st_rdev: dev_t, ++ pub st_size: off_t, ++ pub st_atime: time_t, ++ pub st_mtime: time_t, ++ pub st_ctime: time_t, ++ pub st_blksize: blksize_t, ++ } ++ ++ // time.h ++ pub struct tm { ++ pub tm_sec: c_int, ++ pub tm_min: c_int, ++ pub tm_hour: c_int, ++ pub tm_mday: c_int, ++ pub tm_mon: c_int, ++ pub tm_year: c_int, ++ pub tm_wday: c_int, ++ pub tm_yday: c_int, ++ pub tm_isdst: c_int, ++ pub tm_gmtoff: c_long, ++ pub tm_zone: *mut c_char, ++ } ++ ++ // stdlib.h ++ pub struct qdiv_t { ++ pub quot: quad_t, ++ pub rem: quad_t, ++ } ++ pub struct lldiv_t { ++ pub quot: c_longlong, ++ pub rem: c_longlong, ++ } ++ pub struct div_t { ++ pub quot: c_int, ++ pub rem: c_int, ++ } ++ pub struct ldiv_t { ++ pub quot: c_long, ++ pub rem: c_long, ++ } ++ ++ // locale.h ++ pub struct lconv { ++ pub decimal_point: *mut c_char, ++ pub thousands_sep: *mut c_char, ++ pub grouping: *mut c_char, ++ pub int_curr_symbol: *mut c_char, ++ pub currency_symbol: *mut c_char, ++ pub mon_decimal_point: *mut c_char, ++ pub mon_thousands_sep: *mut c_char, ++ pub mon_grouping: *mut c_char, ++ pub positive_sign: *mut c_char, ++ pub negative_sign: *mut c_char, ++ pub int_frac_digits: c_char, ++ pub frac_digits: c_char, ++ pub p_cs_precedes: c_char, ++ pub p_sep_by_space: c_char, ++ pub n_cs_precedes: c_char, ++ pub n_sep_by_space: c_char, ++ pub p_sign_posn: c_char, ++ pub n_sign_posn: c_char, ++ pub int_p_cs_precedes: c_char, ++ pub int_n_cs_precedes: c_char, ++ pub int_p_sep_by_space: c_char, ++ pub int_n_sep_by_space: c_char, ++ pub int_p_sign_posn: c_char, ++ pub int_n_sign_posn: c_char, ++ } ++ ++ pub struct iovec { ++ pub iov_base: *mut c_void, ++ pub iov_len: size_t, ++ } ++ ++ pub struct timeval { ++ pub tv_sec: c_long, ++ pub tv_usec: c_long, ++ } ++} ++ ++pub const INT_MIN: c_int = -2147483648; ++pub const INT_MAX: c_int = 2147483647; ++ ++pub const EXIT_FAILURE: c_int = 1; ++pub const EXIT_SUCCESS: c_int = 0; ++pub const RAND_MAX: c_int = 0x7fffffff; ++pub const EOF: c_int = -1; ++pub const SEEK_SET: c_int = 0; ++pub const SEEK_CUR: c_int = 1; ++pub const SEEK_END: c_int = 2; ++pub const _IOFBF: c_int = 0; ++pub const _IONBF: c_int = 2; ++pub const _IOLBF: c_int = 1; ++pub const BUFSIZ: c_uint = 1024; ++pub const FOPEN_MAX: c_uint = 20; ++pub const FILENAME_MAX: c_uint = 1024; ++ ++pub const O_RDONLY: c_int = 1; ++pub const O_WRONLY: c_int = 2; ++pub const O_RDWR: c_int = 4; ++pub const O_APPEND: c_int = 8; ++pub const O_CREAT: c_int = 0x10; ++pub const O_EXCL: c_int = 0x400; ++pub const O_TEXT: c_int = 0x100; ++pub const O_BINARY: c_int = 0x200; ++pub const O_TRUNC: c_int = 0x20; ++pub const S_IEXEC: c_short = 0x0040; ++pub const S_IWRITE: c_short = 0x0080; ++pub const S_IREAD: c_short = 0x0100; ++pub const S_IFCHR: c_short = 0x2000; ++pub const S_IFDIR: c_short = 0x4000; ++pub const S_IFMT: c_short = 0o160000; ++pub const S_IFIFO: c_short = 0o0010000; ++pub const S_IFBLK: c_short = 0o0060000; ++pub const S_IFREG: c_short = 0o0100000; ++ ++pub const LC_ALL: c_int = 0; ++pub const LC_COLLATE: c_int = 1; ++pub const LC_CTYPE: c_int = 2; ++pub const LC_MONETARY: c_int = 3; ++pub const LC_NUMERIC: c_int = 4; ++pub const LC_TIME: c_int = 5; ++pub const LC_MESSAGES: c_int = 6; ++pub const _LC_LAST: c_int = 7; ++ ++pub const EPERM: c_int = 1; ++pub const ENOENT: c_int = 2; ++pub const ESRCH: c_int = 3; ++pub const EINTR: c_int = 4; ++pub const EIO: c_int = 5; ++pub const ENXIO: c_int = 6; ++pub const E2BIG: c_int = 7; ++pub const ENOEXEC: c_int = 8; ++pub const EBADF: c_int = 9; ++pub const ECHILD: c_int = 10; ++pub const EAGAIN: c_int = 11; ++pub const ENOMEM: c_int = 12; ++pub const EACCES: c_int = 13; ++pub const EFAULT: c_int = 14; ++pub const ENOTBLK: c_int = 15; ++pub const EBUSY: c_int = 16; ++pub const EEXIST: c_int = 17; ++pub const EXDEV: c_int = 18; ++pub const ENODEV: c_int = 19; ++pub const ENOTDIR: c_int = 20; ++pub const EISDIR: c_int = 21; ++pub const EINVAL: c_int = 22; ++pub const ENFILE: c_int = 23; ++pub const EMFILE: c_int = 24; ++pub const ENOTTY: c_int = 25; ++pub const ETXTBSY: c_int = 26; ++pub const EFBIG: c_int = 27; ++pub const ENOSPC: c_int = 28; ++pub const ESPIPE: c_int = 29; ++pub const EROFS: c_int = 30; ++pub const EMLINK: c_int = 31; ++pub const EPIPE: c_int = 32; ++pub const EDOM: c_int = 33; ++pub const ERANGE: c_int = 34; ++ ++pub const EDEADLK: c_int = 35; ++pub const ENAMETOOLONG: c_int = 36; ++pub const ENOLCK: c_int = 37; ++pub const ENOSYS: c_int = 38; ++pub const ENOTEMPTY: c_int = 39; ++pub const ELOOP: c_int = 40; ++pub const EWOULDBLOCK: c_int = EAGAIN; ++pub const ENOMSG: c_int = 42; ++pub const EIDRM: c_int = 43; ++pub const ECHRNG: c_int = 44; ++pub const EL2NSYNC: c_int = 45; ++pub const EL3HLT: c_int = 46; ++pub const EL3RST: c_int = 47; ++pub const ELNRNG: c_int = 48; ++pub const EUNATCH: c_int = 49; ++pub const ENOCSI: c_int = 50; ++pub const EL2HLT: c_int = 51; ++pub const EBADE: c_int = 52; ++pub const EBADR: c_int = 53; ++pub const EXFULL: c_int = 54; ++pub const ENOANO: c_int = 55; ++pub const EBADRQC: c_int = 56; ++pub const EBADSLT: c_int = 57; ++ ++pub const EDEADLOCK: c_int = EDEADLK; ++ ++pub const EBFONT: c_int = 59; ++pub const ENOSTR: c_int = 60; ++pub const ENODATA: c_int = 61; ++pub const ETIME: c_int = 62; ++pub const ENOSR: c_int = 63; ++pub const ENONET: c_int = 64; ++pub const ENOPKG: c_int = 65; ++pub const EREMOTE: c_int = 66; ++pub const ENOLINK: c_int = 67; ++pub const EADV: c_int = 68; ++pub const ESRMNT: c_int = 69; ++pub const ECOMM: c_int = 70; ++pub const EPROTO: c_int = 71; ++pub const EMULTIHOP: c_int = 72; ++pub const EDOTDOT: c_int = 73; ++pub const EBADMSG: c_int = 74; ++pub const EOVERFLOW: c_int = 75; ++pub const ENOTUNIQ: c_int = 76; ++pub const EBADFD: c_int = 77; ++pub const EREMCHG: c_int = 78; ++pub const ELIBACC: c_int = 79; ++pub const ELIBBAD: c_int = 80; ++pub const ELIBSCN: c_int = 81; ++pub const ELIBMAX: c_int = 82; ++pub const ELIBEXEC: c_int = 83; ++pub const EILSEQ: c_int = 84; ++pub const ERESTART: c_int = 85; ++pub const ESTRPIPE: c_int = 86; ++pub const EUSERS: c_int = 87; ++pub const ENOTSOCK: c_int = 88; ++pub const EDESTADDRREQ: c_int = 89; ++pub const EMSGSIZE: c_int = 90; ++pub const EPROTOTYPE: c_int = 91; ++pub const ENOPROTOOPT: c_int = 92; ++pub const EPROTONOSUPPORT: c_int = 93; ++pub const ESOCKTNOSUPPORT: c_int = 94; ++pub const EOPNOTSUPP: c_int = 95; ++pub const EPFNOSUPPORT: c_int = 96; ++pub const EAFNOSUPPORT: c_int = 97; ++pub const EADDRINUSE: c_int = 98; ++pub const EADDRNOTAVAIL: c_int = 99; ++pub const ENETDOWN: c_int = 100; ++pub const ENETUNREACH: c_int = 101; ++pub const ENETRESET: c_int = 102; ++pub const ECONNABORTED: c_int = 103; ++pub const ECONNRESET: c_int = 104; ++pub const ENOBUFS: c_int = 105; ++pub const EISCONN: c_int = 106; ++pub const ENOTCONN: c_int = 107; ++pub const ESHUTDOWN: c_int = 108; ++pub const ETOOMANYREFS: c_int = 109; ++pub const ETIMEDOUT: c_int = 110; ++pub const ECONNREFUSED: c_int = 111; ++pub const EHOSTDOWN: c_int = 112; ++pub const EHOSTUNREACH: c_int = 113; ++pub const EALREADY: c_int = 114; ++pub const EINPROGRESS: c_int = 115; ++pub const ESTALE: c_int = 116; ++pub const EUCLEAN: c_int = 117; ++pub const ENOTNAM: c_int = 118; ++pub const ENAVAIL: c_int = 119; ++pub const EISNAM: c_int = 120; ++pub const EREMOTEIO: c_int = 121; ++pub const EDQUOT: c_int = 122; ++ ++pub const ENOMEDIUM: c_int = 123; ++pub const EMEDIUMTYPE: c_int = 124; ++pub const ECANCELED: c_int = 125; ++pub const ENOKEY: c_int = 126; ++pub const EKEYEXPIRED: c_int = 127; ++pub const EKEYREVOKED: c_int = 128; ++pub const EKEYREJECTED: c_int = 129; ++ ++pub const EOWNERDEAD: c_int = 130; ++pub const ENOTRECOVERABLE: c_int = 131; ++ ++pub const ENOTSUP: c_int = 132; ++pub const EFTYPE: c_int = 133; ++ ++// signal codes ++pub const SIGHUP: c_int = 1; ++pub const SIGINT: c_int = 2; ++pub const SIGQUIT: c_int = 3; ++pub const SIGILL: c_int = 4; ++pub const SIGTRAP: c_int = 5; ++pub const SIGABRT: c_int = 6; ++pub const SIGIOT: c_int = SIGABRT; ++pub const SIGEMT: c_int = 7; ++pub const SIGFPE: c_int = 8; ++pub const SIGKILL: c_int = 9; ++pub const SIGBUS: c_int = 10; ++pub const SIGSEGV: c_int = 11; ++pub const SIGSYS: c_int = 12; ++pub const SIGPIPE: c_int = 13; ++pub const SIGALRM: c_int = 14; ++pub const SIGTERM: c_int = 15; ++pub const SIGURG: c_int = 16; ++pub const SIGSTOP: c_int = 17; ++pub const SIGTSTP: c_int = 18; ++pub const SIGCONT: c_int = 19; ++pub const SIGCHLD: c_int = 20; ++pub const SIGTTIN: c_int = 21; ++pub const SIGTTOU: c_int = 22; ++pub const SIGIO: c_int = 23; ++pub const SIGXCPU: c_int = 24; ++pub const SIGXFSZ: c_int = 25; ++pub const SIGVTALRM: c_int = 26; ++pub const SIGPROF: c_int = 27; ++pub const SIGWINCH: c_int = 28; ++pub const SIGINFO: c_int = 29; ++pub const SIGUSR1: c_int = 30; ++pub const SIGUSR2: c_int = 31; ++pub const SIGPWR: c_int = 32; ++ ++#[cfg_attr(feature = "extra_traits", derive(Debug))] ++pub enum FILE {} ++impl ::Copy for FILE {} ++impl ::Clone for FILE { ++ fn clone(&self) -> FILE { ++ *self ++ } ++} ++#[cfg_attr(feature = "extra_traits", derive(Debug))] ++pub enum fpos_t {} ++impl ::Copy for fpos_t {} ++impl ::Clone for fpos_t { ++ fn clone(&self) -> fpos_t { ++ *self ++ } ++} ++ ++extern "C" { ++ // ctype.h ++ pub fn isalnum(c: c_int) -> c_int; ++ pub fn isalpha(c: c_int) -> c_int; ++ pub fn iscntrl(c: c_int) -> c_int; ++ pub fn isdigit(c: c_int) -> c_int; ++ pub fn isgraph(c: c_int) -> c_int; ++ pub fn islower(c: c_int) -> c_int; ++ pub fn isprint(c: c_int) -> c_int; ++ pub fn ispunct(c: c_int) -> c_int; ++ pub fn isspace(c: c_int) -> c_int; ++ pub fn isupper(c: c_int) -> c_int; ++ pub fn isxdigit(c: c_int) -> c_int; ++ pub fn isblank(c: c_int) -> c_int; ++ pub fn tolower(c: c_int) -> c_int; ++ pub fn toupper(c: c_int) -> c_int; ++ ++ // stdio.h ++ pub fn __get_stdio_file(fileno: c_int) -> *mut FILE; ++ pub fn clearerr(arg1: *mut FILE); ++ pub fn fclose(arg1: *mut FILE) -> c_int; ++ pub fn feof(arg1: *mut FILE) -> c_int; ++ pub fn ferror(arg1: *mut FILE) -> c_int; ++ pub fn fflush(arg1: *mut FILE) -> c_int; ++ pub fn fgetc(arg1: *mut FILE) -> c_int; ++ pub fn fgets(arg1: *mut c_char, arg2: c_int, arg3: *mut FILE) -> *mut c_char; ++ pub fn fopen(arg1: *const c_char, arg2: *const c_char) -> *mut FILE; ++ pub fn fprintf(arg1: *mut FILE, arg2: *const c_char, ...) -> c_int; ++ pub fn fputc(arg1: c_int, arg2: *mut FILE) -> c_int; ++ pub fn fputs(arg1: *const c_char, arg2: *mut FILE) -> c_int; ++ pub fn fread(arg1: *mut c_void, arg2: size_t, arg3: size_t, arg4: *mut FILE) -> size_t; ++ pub fn freopen(arg1: *const c_char, arg2: *const c_char, arg3: *mut FILE) -> *mut FILE; ++ pub fn fscanf(arg1: *mut FILE, arg2: *const c_char, ...) -> c_int; ++ pub fn fseek(arg1: *mut FILE, arg2: c_long, arg3: c_int) -> c_int; ++ pub fn ftell(arg1: *mut FILE) -> c_long; ++ pub fn fwrite(arg1: *const c_void, arg2: size_t, arg3: size_t, arg4: *mut FILE) -> size_t; ++ pub fn getc(arg1: *mut FILE) -> c_int; ++ pub fn getchar() -> c_int; ++ pub fn perror(arg1: *const c_char); ++ pub fn printf(arg1: *const c_char, ...) -> c_int; ++ pub fn putc(arg1: c_int, arg2: *mut FILE) -> c_int; ++ pub fn putchar(arg1: c_int) -> c_int; ++ pub fn puts(arg1: *const c_char) -> c_int; ++ pub fn remove(arg1: *const c_char) -> c_int; ++ pub fn rewind(arg1: *mut FILE); ++ pub fn scanf(arg1: *const c_char, ...) -> c_int; ++ pub fn setbuf(arg1: *mut FILE, arg2: *mut c_char); ++ pub fn setvbuf(arg1: *mut FILE, arg2: *mut c_char, arg3: c_int, arg4: size_t) -> c_int; ++ pub fn sscanf(arg1: *const c_char, arg2: *const c_char, ...) -> c_int; ++ pub fn tmpfile() -> *mut FILE; ++ pub fn ungetc(arg1: c_int, arg2: *mut FILE) -> c_int; ++ pub fn vfprintf(arg1: *mut FILE, arg2: *const c_char, arg3: __va_list) -> c_int; ++ pub fn vprintf(arg1: *const c_char, arg2: __va_list) -> c_int; ++ pub fn gets(arg1: *mut c_char) -> *mut c_char; ++ pub fn sprintf(arg1: *mut c_char, arg2: *const c_char, ...) -> c_int; ++ pub fn tmpnam(arg1: *const c_char) -> *mut c_char; ++ pub fn vsprintf(arg1: *mut c_char, arg2: *const c_char, arg3: __va_list) -> c_int; ++ pub fn rename(arg1: *const c_char, arg2: *const c_char) -> c_int; ++ pub fn asiprintf(arg1: *mut *mut c_char, arg2: *const c_char, ...) -> c_int; ++ pub fn fiprintf(arg1: *mut FILE, arg2: *const c_char, ...) -> c_int; ++ pub fn fiscanf(arg1: *mut FILE, arg2: *const c_char, ...) -> c_int; ++ pub fn iprintf(arg1: *const c_char, ...) -> c_int; ++ pub fn iscanf(arg1: *const c_char, ...) -> c_int; ++ pub fn siprintf(arg1: *mut c_char, arg2: *const c_char, ...) -> c_int; ++ pub fn siscanf(arg1: *mut c_char, arg2: *const c_char, ...) -> c_int; ++ pub fn sniprintf(arg1: *mut c_char, arg2: size_t, arg3: *const c_char, ...) -> c_int; ++ pub fn vasiprintf(arg1: *mut *mut c_char, arg2: *const c_char, arg3: __va_list) -> c_int; ++ pub fn vfiprintf(arg1: *mut FILE, arg2: *const c_char, arg3: __va_list) -> c_int; ++ pub fn vfiscanf(arg1: *mut FILE, arg2: *const c_char, arg3: __va_list) -> c_int; ++ pub fn viprintf(arg1: *const c_char, arg2: __va_list) -> c_int; ++ pub fn viscanf(arg1: *const c_char, arg2: __va_list) -> c_int; ++ pub fn vsiprintf(arg1: *mut c_char, arg2: *const c_char, arg3: __va_list) -> c_int; ++ pub fn vsiscanf(arg1: *const c_char, arg2: *const c_char, arg3: __va_list) -> c_int; ++ pub fn vsniprintf( ++ arg1: *mut c_char, ++ arg2: size_t, ++ arg3: *const c_char, ++ arg4: __va_list, ++ ) -> c_int; ++ pub fn vdiprintf(arg1: c_int, arg2: *const c_char, arg3: __va_list) -> c_int; ++ pub fn diprintf(arg1: c_int, arg2: *const c_char, ...) -> c_int; ++ pub fn fgetpos(arg1: *mut FILE, arg2: *mut fpos_t) -> c_int; ++ pub fn fsetpos(arg1: *mut FILE, arg2: *const fpos_t) -> c_int; ++ pub fn fdopen(arg1: c_int, arg2: *const c_char) -> *mut FILE; ++ pub fn fileno(arg1: *mut FILE) -> c_int; ++ pub fn flockfile(arg1: *mut FILE); ++ pub fn ftrylockfile(arg1: *mut FILE) -> c_int; ++ pub fn funlockfile(arg1: *mut FILE); ++ pub fn getc_unlocked(arg1: *mut FILE) -> c_int; ++ pub fn getchar_unlocked() -> c_int; ++ pub fn putc_unlocked(arg1: c_int, arg2: *mut FILE) -> c_int; ++ pub fn putchar_unlocked(arg1: c_int) -> c_int; ++ pub fn snprintf(arg1: *mut c_char, arg2: size_t, arg3: *const c_char, ...) -> c_int; ++ pub fn vsnprintf( ++ arg1: *mut c_char, ++ arg2: size_t, ++ arg3: *const c_char, ++ arg4: __va_list, ++ ) -> c_int; ++ pub fn getw(arg1: *mut FILE) -> c_int; ++ pub fn putw(arg1: c_int, arg2: *mut FILE) -> c_int; ++ pub fn tempnam(arg1: *const c_char, arg2: *const c_char) -> *mut c_char; ++ pub fn fseeko(stream: *mut FILE, offset: off_t, whence: c_int) -> c_int; ++ pub fn ftello(stream: *mut FILE) -> off_t; ++ ++ // stdlib.h ++ pub fn atof(arg1: *const c_char) -> f64; ++ pub fn strtod(arg1: *const c_char, arg2: *mut *mut c_char) -> f64; ++ pub fn drand48() -> f64; ++ pub fn erand48(arg1: *mut c_ushort) -> f64; ++ pub fn strtof(arg1: *const c_char, arg2: *mut *mut c_char) -> f32; ++ pub fn strtold(arg1: *const c_char, arg2: *mut *mut c_char) -> f64; ++ pub fn strtod_l(arg1: *const c_char, arg2: *mut *mut c_char, arg3: locale_t) -> f64; ++ pub fn strtof_l(arg1: *const c_char, arg2: *mut *mut c_char, arg3: locale_t) -> f32; ++ pub fn strtold_l(arg1: *const c_char, arg2: *mut *mut c_char, arg3: locale_t) -> f64; ++ pub fn _Exit(arg1: c_int) -> !; ++ pub fn abort() -> !; ++ pub fn abs(arg1: c_int) -> c_int; ++ pub fn atexit(arg1: ::Option) -> c_int; ++ pub fn atoi(arg1: *const c_char) -> c_int; ++ pub fn atol(arg1: *const c_char) -> c_long; ++ pub fn itoa(arg1: c_int, arg2: *mut c_char, arg3: c_int) -> *mut c_char; ++ pub fn ltoa(arg1: c_long, arg2: *mut c_char, arg3: c_int) -> *mut c_char; ++ pub fn ultoa(arg1: c_ulong, arg2: *mut c_char, arg3: c_int) -> *mut c_char; ++ pub fn bsearch( ++ arg1: *const c_void, ++ arg2: *const c_void, ++ arg3: size_t, ++ arg4: size_t, ++ arg5: ::Option c_int>, ++ ) -> *mut c_void; ++ pub fn calloc(arg1: size_t, arg2: size_t) -> *mut c_void; ++ pub fn div(arg1: c_int, arg2: c_int) -> div_t; ++ pub fn exit(arg1: c_int) -> !; ++ pub fn free(arg1: *mut c_void); ++ pub fn getenv(arg1: *const c_char) -> *mut c_char; ++ pub fn labs(arg1: c_long) -> c_long; ++ pub fn ldiv(arg1: c_long, arg2: c_long) -> ldiv_t; ++ pub fn malloc(arg1: size_t) -> *mut c_void; ++ pub fn qsort( ++ arg1: *mut c_void, ++ arg2: size_t, ++ arg3: size_t, ++ arg4: ::Option c_int>, ++ ); ++ pub fn rand() -> c_int; ++ pub fn realloc(arg1: *mut c_void, arg2: size_t) -> *mut c_void; ++ pub fn srand(arg1: c_uint); ++ pub fn strtol(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> c_long; ++ pub fn strtoul(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> c_ulong; ++ pub fn mblen(arg1: *const c_char, arg2: size_t) -> c_int; ++ pub fn mbstowcs(arg1: *mut wchar_t, arg2: *const c_char, arg3: size_t) -> size_t; ++ pub fn wctomb(arg1: *mut c_char, arg2: wchar_t) -> c_int; ++ pub fn mbtowc(arg1: *mut wchar_t, arg2: *const c_char, arg3: size_t) -> c_int; ++ pub fn wcstombs(arg1: *mut c_char, arg2: *const wchar_t, arg3: size_t) -> size_t; ++ pub fn rand_r(arg1: *mut c_uint) -> c_int; ++ pub fn jrand48(arg1: *mut c_ushort) -> c_long; ++ pub fn lcong48(arg1: *mut c_ushort); ++ pub fn lrand48() -> c_long; ++ pub fn mrand48() -> c_long; ++ pub fn nrand48(arg1: *mut c_ushort) -> c_long; ++ pub fn seed48(arg1: *mut c_ushort) -> *mut c_ushort; ++ pub fn srand48(arg1: c_long); ++ pub fn putenv(arg1: *mut c_char) -> c_int; ++ pub fn a64l(arg1: *const c_char) -> c_long; ++ pub fn l64a(arg1: c_long) -> *mut c_char; ++ pub fn random() -> c_long; ++ pub fn setstate(arg1: *mut c_char) -> *mut c_char; ++ pub fn initstate(arg1: c_uint, arg2: *mut c_char, arg3: size_t) -> *mut c_char; ++ pub fn srandom(arg1: c_uint); ++ pub fn mkostemp(arg1: *mut c_char, arg2: c_int) -> c_int; ++ pub fn mkostemps(arg1: *mut c_char, arg2: c_int, arg3: c_int) -> c_int; ++ pub fn mkdtemp(arg1: *mut c_char) -> *mut c_char; ++ pub fn mkstemp(arg1: *mut c_char) -> c_int; ++ pub fn mktemp(arg1: *mut c_char) -> *mut c_char; ++ pub fn atoll(arg1: *const c_char) -> c_longlong; ++ pub fn llabs(arg1: c_longlong) -> c_longlong; ++ pub fn lldiv(arg1: c_longlong, arg2: c_longlong) -> lldiv_t; ++ pub fn strtoll(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> c_longlong; ++ pub fn strtoull(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> c_ulonglong; ++ pub fn aligned_alloc(arg1: size_t, arg2: size_t) -> *mut c_void; ++ pub fn at_quick_exit(arg1: ::Option) -> c_int; ++ pub fn quick_exit(arg1: c_int); ++ pub fn setenv(arg1: *const c_char, arg2: *const c_char, arg3: c_int) -> c_int; ++ pub fn unsetenv(arg1: *const c_char) -> c_int; ++ pub fn humanize_number( ++ arg1: *mut c_char, ++ arg2: size_t, ++ arg3: i64, ++ arg4: *const c_char, ++ arg5: c_int, ++ arg6: c_int, ++ ) -> c_int; ++ pub fn dehumanize_number(arg1: *const c_char, arg2: *mut i64) -> c_int; ++ pub fn getenv_r(arg1: *const c_char, arg2: *mut c_char, arg3: size_t) -> c_int; ++ pub fn heapsort( ++ arg1: *mut c_void, ++ arg2: size_t, ++ arg3: size_t, ++ arg4: ::Option c_int>, ++ ) -> c_int; ++ pub fn mergesort( ++ arg1: *mut c_void, ++ arg2: size_t, ++ arg3: size_t, ++ arg4: ::Option c_int>, ++ ) -> c_int; ++ pub fn radixsort( ++ arg1: *mut *const c_uchar, ++ arg2: c_int, ++ arg3: *const c_uchar, ++ arg4: c_uint, ++ ) -> c_int; ++ pub fn sradixsort( ++ arg1: *mut *const c_uchar, ++ arg2: c_int, ++ arg3: *const c_uchar, ++ arg4: c_uint, ++ ) -> c_int; ++ pub fn getprogname() -> *const c_char; ++ pub fn setprogname(arg1: *const c_char); ++ pub fn qabs(arg1: quad_t) -> quad_t; ++ pub fn strtoq(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> quad_t; ++ pub fn strtouq(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> u_quad_t; ++ pub fn strsuftoll( ++ arg1: *const c_char, ++ arg2: *const c_char, ++ arg3: c_longlong, ++ arg4: c_longlong, ++ ) -> c_longlong; ++ pub fn strsuftollx( ++ arg1: *const c_char, ++ arg2: *const c_char, ++ arg3: c_longlong, ++ arg4: c_longlong, ++ arg5: *mut c_char, ++ arg6: size_t, ++ ) -> c_longlong; ++ pub fn l64a_r(arg1: c_long, arg2: *mut c_char, arg3: c_int) -> c_int; ++ pub fn qdiv(arg1: quad_t, arg2: quad_t) -> qdiv_t; ++ pub fn strtol_l( ++ arg1: *const c_char, ++ arg2: *mut *mut c_char, ++ arg3: c_int, ++ arg4: locale_t, ++ ) -> c_long; ++ pub fn strtoul_l( ++ arg1: *const c_char, ++ arg2: *mut *mut c_char, ++ arg3: c_int, ++ arg4: locale_t, ++ ) -> c_ulong; ++ pub fn strtoll_l( ++ arg1: *const c_char, ++ arg2: *mut *mut c_char, ++ arg3: c_int, ++ arg4: locale_t, ++ ) -> c_longlong; ++ pub fn strtoull_l( ++ arg1: *const c_char, ++ arg2: *mut *mut c_char, ++ arg3: c_int, ++ arg4: locale_t, ++ ) -> c_ulonglong; ++ pub fn strtoq_l( ++ arg1: *const c_char, ++ arg2: *mut *mut c_char, ++ arg3: c_int, ++ arg4: locale_t, ++ ) -> quad_t; ++ pub fn strtouq_l( ++ arg1: *const c_char, ++ arg2: *mut *mut c_char, ++ arg3: c_int, ++ arg4: locale_t, ++ ) -> u_quad_t; ++ pub fn _mb_cur_max_l(arg1: locale_t) -> size_t; ++ pub fn mblen_l(arg1: *const c_char, arg2: size_t, arg3: locale_t) -> c_int; ++ pub fn mbstowcs_l( ++ arg1: *mut wchar_t, ++ arg2: *const c_char, ++ arg3: size_t, ++ arg4: locale_t, ++ ) -> size_t; ++ pub fn wctomb_l(arg1: *mut c_char, arg2: wchar_t, arg3: locale_t) -> c_int; ++ pub fn mbtowc_l(arg1: *mut wchar_t, arg2: *const c_char, arg3: size_t, arg4: locale_t) ++ -> c_int; ++ pub fn wcstombs_l( ++ arg1: *mut c_char, ++ arg2: *const wchar_t, ++ arg3: size_t, ++ arg4: locale_t, ++ ) -> size_t; ++ ++ // string.h ++ pub fn memchr(arg1: *const c_void, arg2: c_int, arg3: size_t) -> *mut c_void; ++ pub fn memcmp(arg1: *const c_void, arg2: *const c_void, arg3: size_t) -> c_int; ++ pub fn memcpy(arg1: *mut c_void, arg2: *const c_void, arg3: size_t) -> *mut c_void; ++ pub fn memmove(arg1: *mut c_void, arg2: *const c_void, arg3: size_t) -> *mut c_void; ++ pub fn memset(arg1: *mut c_void, arg2: c_int, arg3: size_t) -> *mut c_void; ++ pub fn strcat(arg1: *mut c_char, arg2: *const c_char) -> *mut c_char; ++ pub fn strchr(arg1: *const c_char, arg2: c_int) -> *mut c_char; ++ pub fn strcmp(arg1: *const c_char, arg2: *const c_char) -> c_int; ++ pub fn strcoll(arg1: *const c_char, arg2: *const c_char) -> c_int; ++ pub fn strcpy(arg1: *mut c_char, arg2: *const c_char) -> *mut c_char; ++ pub fn strcspn(arg1: *const c_char, arg2: *const c_char) -> size_t; ++ pub fn strerror(arg1: c_int) -> *mut c_char; ++ pub fn strlen(arg1: *const c_char) -> size_t; ++ pub fn strncat(arg1: *mut c_char, arg2: *const c_char, arg3: size_t) -> *mut c_char; ++ pub fn strncmp(arg1: *const c_char, arg2: *const c_char, arg3: size_t) -> c_int; ++ pub fn strncpy(arg1: *mut c_char, arg2: *const c_char, arg3: size_t) -> *mut c_char; ++ pub fn strpbrk(arg1: *const c_char, arg2: *const c_char) -> *mut c_char; ++ pub fn strrchr(arg1: *const c_char, arg2: c_int) -> *mut c_char; ++ pub fn strspn(arg1: *const c_char, arg2: *const c_char) -> size_t; ++ pub fn strstr(arg1: *const c_char, arg2: *const c_char) -> *mut c_char; ++ pub fn strtok(arg1: *mut c_char, arg2: *const c_char) -> *mut c_char; ++ pub fn strtok_r(arg1: *mut c_char, arg2: *const c_char, arg3: *mut *mut c_char) -> *mut c_char; ++ pub fn strerror_r(arg1: c_int, arg2: *mut c_char, arg3: size_t) -> c_int; ++ pub fn strxfrm(arg1: *mut c_char, arg2: *const c_char, arg3: size_t) -> size_t; ++ pub fn memccpy( ++ arg1: *mut c_void, ++ arg2: *const c_void, ++ arg3: c_int, ++ arg4: size_t, ++ ) -> *mut c_void; ++ pub fn strdup(arg1: *const c_char) -> *mut c_char; ++ pub fn stpcpy(arg1: *mut c_char, arg2: *const c_char) -> *mut c_char; ++ pub fn stpncpy(arg1: *mut c_char, arg2: *const c_char, arg3: size_t) -> *mut c_char; ++ pub fn strnlen(arg1: *const c_char, arg2: size_t) -> size_t; ++ pub fn memmem( ++ arg1: *const c_void, ++ arg2: size_t, ++ arg3: *const c_void, ++ arg4: size_t, ++ ) -> *mut c_void; ++ pub fn strcasestr(arg1: *const c_char, arg2: *const c_char) -> *mut c_char; ++ pub fn strlcat(arg1: *mut c_char, arg2: *const c_char, arg3: size_t) -> size_t; ++ pub fn strlcpy(arg1: *mut c_char, arg2: *const c_char, arg3: size_t) -> size_t; ++ pub fn strsep(arg1: *mut *mut c_char, arg2: *const c_char) -> *mut c_char; ++ pub fn stresep(arg1: *mut *mut c_char, arg2: *const c_char, arg3: c_int) -> *mut c_char; ++ pub fn strndup(arg1: *const c_char, arg2: size_t) -> *mut c_char; ++ pub fn memrchr(arg1: *const c_void, arg2: c_int, arg3: size_t) -> *mut c_void; ++ pub fn explicit_memset(arg1: *mut c_void, arg2: c_int, arg3: size_t) -> *mut c_void; ++ pub fn consttime_memequal(arg1: *const c_void, arg2: *const c_void, arg3: size_t) -> c_int; ++ pub fn strcoll_l(arg1: *const c_char, arg2: *const c_char, arg3: locale_t) -> c_int; ++ pub fn strxfrm_l( ++ arg1: *mut c_char, ++ arg2: *const c_char, ++ arg3: size_t, ++ arg4: locale_t, ++ ) -> size_t; ++ pub fn strerror_l(arg1: c_int, arg2: locale_t) -> *mut c_char; ++ ++ // strings.h ++ pub fn bcmp(arg1: *const c_void, arg2: *const c_void, arg3: size_t) -> c_int; ++ pub fn bcopy(arg1: *const c_void, arg2: *mut c_void, arg3: size_t); ++ pub fn bzero(arg1: *mut c_void, arg2: size_t); ++ pub fn ffs(arg1: c_int) -> c_int; ++ pub fn popcount(arg1: c_uint) -> c_uint; ++ pub fn popcountl(arg1: c_ulong) -> c_uint; ++ pub fn popcountll(arg1: c_ulonglong) -> c_uint; ++ pub fn popcount32(arg1: u32) -> c_uint; ++ pub fn popcount64(arg1: u64) -> c_uint; ++ pub fn rindex(arg1: *const c_char, arg2: c_int) -> *mut c_char; ++ pub fn strcasecmp(arg1: *const c_char, arg2: *const c_char) -> c_int; ++ pub fn strncasecmp(arg1: *const c_char, arg2: *const c_char, arg3: size_t) -> c_int; ++ ++ // signal.h ++ pub fn signal(arg1: c_int, arg2: sighandler_t) -> sighandler_t; ++ pub fn raise(arg1: c_int) -> c_int; ++ ++ // time.h ++ pub fn asctime(arg1: *const tm) -> *mut c_char; ++ pub fn clock() -> clock_t; ++ pub fn ctime(arg1: *const time_t) -> *mut c_char; ++ pub fn difftime(arg1: time_t, arg2: time_t) -> f64; ++ pub fn gmtime(arg1: *const time_t) -> *mut tm; ++ pub fn localtime(arg1: *const time_t) -> *mut tm; ++ pub fn time(arg1: *mut time_t) -> time_t; ++ pub fn mktime(arg1: *mut tm) -> time_t; ++ pub fn strftime( ++ arg1: *mut c_char, ++ arg2: size_t, ++ arg3: *const c_char, ++ arg4: *const tm, ++ ) -> size_t; ++ pub fn utime(arg1: *const c_char, arg2: *mut time_t) -> c_int; ++ pub fn asctime_r(arg1: *const tm, arg2: *mut c_char) -> *mut c_char; ++ pub fn ctime_r(arg1: *const time_t, arg2: *mut c_char) -> *mut c_char; ++ pub fn gmtime_r(arg1: *const time_t, arg2: *mut tm) -> *mut tm; ++ pub fn localtime_r(arg1: *const time_t, arg2: *mut tm) -> *mut tm; ++ ++ // sys/stat.h ++ pub fn stat(arg1: *const c_char, arg2: *mut stat) -> c_int; ++ pub fn lstat(arg1: *const c_char, arg2: *mut stat) -> c_int; ++ pub fn fstat(arg1: c_int, arg2: *mut stat) -> c_int; ++ pub fn chmod(arg1: *const c_char, arg2: __mode_t) -> c_int; ++ pub fn mkdir(arg1: *const c_char, arg2: __mode_t) -> c_int; ++ ++ // fcntl.h ++ pub fn open(arg1: *const c_char, arg2: c_int, ...) -> c_int; ++ pub fn creat(arg1: *const c_char, arg2: c_int) -> c_int; ++ pub fn close(arg1: c_int) -> c_int; ++ pub fn read(arg1: c_int, arg2: *mut c_void, arg3: c_int) -> c_int; ++ pub fn write(arg1: c_int, arg2: *const c_void, arg3: c_int) -> c_int; ++ pub fn unlink(arg1: *const c_char) -> c_int; ++ pub fn tell(arg1: c_int) -> c_long; ++ pub fn dup(arg1: c_int) -> c_int; ++ pub fn dup2(arg1: c_int, arg2: c_int) -> c_int; ++ pub fn access(arg1: *const c_char, arg2: c_int) -> c_int; ++ pub fn rmdir(arg1: *const c_char) -> c_int; ++ pub fn chdir(arg1: *const c_char) -> c_int; ++ pub fn _exit(arg1: c_int); ++ pub fn getwd(arg1: *mut c_char) -> *mut c_char; ++ pub fn getcwd(arg1: *mut c_char, arg2: size_t) -> *mut c_char; ++ pub static mut optarg: *mut c_char; ++ pub static mut opterr: c_int; ++ pub static mut optind: c_int; ++ pub static mut optopt: c_int; ++ pub static mut optreset: c_int; ++ pub fn getopt(arg1: c_int, arg2: *mut *mut c_char, arg3: *const c_char) -> c_int; ++ pub static mut suboptarg: *mut c_char; ++ pub fn getsubopt( ++ arg1: *mut *mut c_char, ++ arg2: *const *mut c_char, ++ arg3: *mut *mut c_char, ++ ) -> c_int; ++ pub fn fcntl(arg1: c_int, arg2: c_int, ...) -> c_int; ++ pub fn getpid() -> pid_t; ++ pub fn sleep(arg1: c_uint) -> c_uint; ++ pub fn usleep(arg1: useconds_t) -> c_int; ++ ++ // locale.h ++ pub fn localeconv() -> *mut lconv; ++ pub fn setlocale(arg1: c_int, arg2: *const c_char) -> *mut c_char; ++ pub fn duplocale(arg1: locale_t) -> locale_t; ++ pub fn freelocale(arg1: locale_t); ++ pub fn localeconv_l(arg1: locale_t) -> *mut lconv; ++ pub fn newlocale(arg1: c_int, arg2: *const c_char, arg3: locale_t) -> locale_t; ++ ++ // langinfo.h ++ pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; ++ pub fn nl_langinfo_l(item: ::nl_item, locale: locale_t) -> *mut ::c_char; ++ ++ // malloc.h ++ pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; ++ ++ // sys/types.h ++ pub fn lseek(arg1: c_int, arg2: __off_t, arg3: c_int) -> __off_t; ++} ++ ++cfg_if! { ++ if #[cfg(libc_core_cvoid)] { ++ pub use ::ffi::c_void; ++ } else { ++ // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help ++ // enable more optimization opportunities around it recognizing things ++ // like malloc/free. ++ #[repr(u8)] ++ #[allow(missing_copy_implementations)] ++ #[allow(missing_debug_implementations)] ++ pub enum c_void { ++ // Two dummy variants so the #[repr] attribute can be used. ++ #[doc(hidden)] ++ __variant1, ++ #[doc(hidden)] ++ __variant2, ++ } ++ } ++} ++ ++cfg_if! { ++ if #[cfg(target_arch = "aarch64")] { ++ mod aarch64; ++ pub use self::aarch64::*; ++ } else if #[cfg(any(target_arch = "arm"))] { ++ mod arm; ++ pub use self::arm::*; ++ } else { ++ // Unknown target_arch ++ } ++} +diff --git a/vendor/libc/src/unix/aix/mod.rs b/vendor/libc/src/unix/aix/mod.rs +new file mode 100644 +index 0000000..ffe3f18 +--- /dev/null ++++ b/vendor/libc/src/unix/aix/mod.rs +@@ -0,0 +1,3355 @@ ++pub type c_char = i8; ++pub type caddr_t = *mut ::c_char; ++// FIXME: clockid_t must be c_long, but time.rs accepts only i32 ++pub type clockid_t = ::c_int; ++pub type blkcnt_t = ::c_long; ++pub type clock_t = ::c_int; ++pub type daddr_t = ::c_long; ++pub type dev_t = ::c_ulong; ++pub type fpos64_t = ::c_longlong; ++pub type fsblkcnt_t = ::c_ulong; ++pub type fsfilcnt_t = ::c_ulong; ++pub type idtype_t = ::c_int; ++pub type ino_t = ::c_ulong; ++pub type key_t = ::c_int; ++pub type mode_t = ::c_uint; ++pub type nlink_t = ::c_short; ++pub type rlim_t = ::c_ulong; ++pub type speed_t = ::c_uint; ++pub type tcflag_t = ::c_uint; ++pub type time_t = ::c_long; ++pub type time64_t = ::int64_t; ++pub type timer_t = ::c_long; ++pub type wchar_t = ::c_uint; ++pub type nfds_t = ::c_int; ++pub type projid_t = ::c_int; ++pub type id_t = ::c_uint; ++pub type blksize64_t = ::c_ulonglong; ++pub type blkcnt64_t = ::c_ulonglong; ++pub type sctp_assoc_t = ::uint32_t; ++ ++pub type suseconds_t = ::c_int; ++pub type useconds_t = ::c_uint; ++pub type off_t = ::c_long; ++pub type off64_t = ::c_longlong; ++ ++pub type socklen_t = ::c_uint; ++pub type sa_family_t = ::c_uchar; ++pub type in_port_t = ::c_ushort; ++pub type in_addr_t = ::c_uint; ++ ++pub type signal_t = ::c_int; ++pub type pthread_t = ::c_uint; ++pub type pthread_key_t = ::c_uint; ++pub type thread_t = pthread_t; ++pub type blksize_t = ::c_long; ++pub type nl_item = ::c_int; ++pub type mqd_t = ::c_int; ++pub type shmatt_t = ::c_ulong; ++pub type regoff_t = ::c_long; ++pub type rlim64_t = ::c_ulonglong; ++ ++pub type sem_t = ::c_int; ++pub type pollset_t = ::c_int; ++ ++pub type pthread_rwlockattr_t = *mut ::c_void; ++pub type pthread_condattr_t = *mut ::c_void; ++pub type pthread_mutexattr_t = *mut ::c_void; ++pub type pthread_attr_t = *mut ::c_void; ++pub type pthread_barrierattr_t = *mut ::c_void; ++pub type posix_spawn_file_actions_t = *mut ::c_char; ++pub type iconv_t = *mut ::c_void; ++ ++e! { ++ pub enum uio_rw { ++ UIO_READ = 0, ++ UIO_WRITE, ++ UIO_READ_NO_MOVE, ++ UIO_WRITE_NO_MOVE, ++ UIO_PWRITE, ++ } ++} ++ ++s! { ++ pub struct fsid_t { ++ pub val: [::c_uint; 2], ++ } ++ ++ pub struct fsid64_t { ++ pub val: [::uint64_t; 2], ++ } ++ ++ pub struct timezone { ++ pub tz_minuteswest: ::c_int, ++ pub tz_dsttime: ::c_int, ++ } ++ ++ pub struct ip_mreq { ++ pub imr_multiaddr: in_addr, ++ pub imr_interface: in_addr, ++ } ++ ++ pub struct dirent { ++ pub d_offset: ::c_ulong, ++ pub d_ino: ::ino_t, ++ pub d_reclen: ::c_ushort, ++ pub d_namlen: ::c_ushort, ++ pub d_name: [::c_char; 256] ++ } ++ ++ pub struct termios { ++ pub c_iflag: ::tcflag_t, ++ pub c_oflag: ::tcflag_t, ++ pub c_cflag: ::tcflag_t, ++ pub c_lflag: ::tcflag_t, ++ pub c_cc: [::cc_t; ::NCCS] ++ } ++ ++ pub struct flock64 { ++ pub l_type: ::c_short, ++ pub l_whence: ::c_short, ++ pub l_sysid: ::c_uint, ++ pub l_pid: ::pid_t, ++ pub l_vfs: ::c_int, ++ pub l_start: ::off64_t, ++ pub l_len: ::off64_t, ++ } ++ ++ pub struct msghdr { ++ pub msg_name: *mut ::c_void, ++ pub msg_namelen: ::socklen_t, ++ pub msg_iov: *mut ::iovec, ++ pub msg_iovlen: ::c_int, ++ pub msg_control: *mut ::c_void, ++ pub msg_controllen: socklen_t, ++ pub msg_flags: ::c_int, ++ } ++ ++ pub struct statvfs64 { ++ pub f_bsize: ::blksize64_t, ++ pub f_frsize: ::blksize64_t, ++ pub f_blocks: ::blkcnt64_t, ++ pub f_bfree: ::blkcnt64_t, ++ pub f_bavail: ::blkcnt64_t, ++ pub f_files: ::blkcnt64_t, ++ pub f_ffree: ::blkcnt64_t, ++ pub f_favail: ::blkcnt64_t, ++ pub f_fsid: fsid64_t, ++ pub f_basetype: [::c_char; 16], ++ pub f_flag: ::c_ulong, ++ pub f_namemax: ::c_ulong, ++ pub f_fstr: [::c_char; 32], ++ pub f_filler: [::c_ulong; 16] ++ } ++ ++ pub struct lconv { ++ pub decimal_point: *mut ::c_char, ++ pub thousands_sep: *mut ::c_char, ++ pub grouping: *mut ::c_char, ++ pub int_curr_symbol: *mut ::c_char, ++ pub currency_symbol: *mut ::c_char, ++ pub mon_decimal_point: *mut ::c_char, ++ pub mon_thousands_sep: *mut ::c_char, ++ pub mon_grouping: *mut ::c_char, ++ pub positive_sign: *mut ::c_char, ++ pub negative_sign: *mut ::c_char, ++ pub int_frac_digits: ::c_char, ++ pub frac_digits: ::c_char, ++ pub p_cs_precedes: ::c_char, ++ pub p_sep_by_space: ::c_char, ++ pub n_cs_precedes: ::c_char, ++ pub n_sep_by_space: ::c_char, ++ pub p_sign_posn: ::c_char, ++ pub n_sign_posn: ::c_char, ++ pub left_parenthesis: *mut ::c_char, ++ pub right_parenthesis: *mut ::c_char, ++ pub int_p_cs_precedes: ::c_char, ++ pub int_p_sep_by_space: ::c_char, ++ pub int_n_cs_precedes: ::c_char, ++ pub int_n_sep_by_space: ::c_char, ++ pub int_p_sign_posn: ::c_char, ++ pub int_n_sign_posn: ::c_char, ++ } ++ ++ pub struct tm { ++ pub tm_sec: ::c_int, ++ pub tm_min: ::c_int, ++ pub tm_hour: ::c_int, ++ pub tm_mday: ::c_int, ++ pub tm_mon: ::c_int, ++ pub tm_year: ::c_int, ++ pub tm_wday: ::c_int, ++ pub tm_yday: ::c_int, ++ pub tm_isdst: ::c_int ++ } ++ ++ pub struct addrinfo { ++ pub ai_flags: ::c_int, ++ pub ai_family: ::c_int, ++ pub ai_socktype: ::c_int, ++ pub ai_protocol: ::c_int, ++ pub ai_addrlen: ::c_ulong, ++ pub ai_canonname: *mut ::c_char, ++ pub ai_addr: *mut ::sockaddr, ++ pub ai_next: *mut addrinfo, ++ pub ai_eflags: ::c_int, ++ } ++ ++ pub struct in_addr { ++ pub s_addr: in_addr_t ++ } ++ ++ pub struct ip_mreq_source { ++ pub imr_multiaddr: in_addr, ++ pub imr_sourceaddr: in_addr, ++ pub imr_interface: in_addr, ++ } ++ ++ pub struct sockaddr { ++ pub sa_len: ::c_uchar, ++ pub sa_family: sa_family_t, ++ pub sa_data: [::c_char; 14], ++ } ++ ++ pub struct sockaddr_dl { ++ pub sdl_len: ::c_uchar, ++ pub sdl_family: ::c_uchar, ++ pub sdl_index: ::c_ushort, ++ pub sdl_type: ::c_uchar, ++ pub sdl_nlen: ::c_uchar, ++ pub sdl_alen: ::c_uchar, ++ pub sdl_slen: ::c_uchar, ++ pub sdl_data: [::c_char; 120], ++ } ++ ++ pub struct sockaddr_in { ++ pub sin_len: ::c_uchar, ++ pub sin_family: sa_family_t, ++ pub sin_port: in_port_t, ++ pub sin_addr: in_addr, ++ pub sin_zero: [::c_char; 8] ++ } ++ ++ pub struct sockaddr_in6 { ++ pub sin6_len: ::c_uchar, ++ pub sin6_family: ::c_uchar, ++ pub sin6_port: ::uint16_t, ++ pub sin6_flowinfo: ::uint32_t, ++ pub sin6_addr: ::in6_addr, ++ pub sin6_scope_id: ::uint32_t ++ } ++ ++ pub struct sockaddr_storage { ++ pub __ss_len: ::c_uchar, ++ pub ss_family: sa_family_t, ++ __ss_pad1: [::c_char; 6], ++ __ss_align: ::int64_t, ++ __ss_pad2: [::c_char; 1265], ++ } ++ ++ pub struct sockaddr_un { ++ pub sun_len: ::c_uchar, ++ pub sun_family: sa_family_t, ++ pub sun_path: [::c_char; 1023] ++ } ++ ++ pub struct st_timespec { ++ pub tv_sec: ::time_t, ++ pub tv_nsec: ::c_int, ++ } ++ ++ pub struct statfs64 { ++ pub f_version: ::c_int, ++ pub f_type: ::c_int, ++ pub f_bsize: blksize64_t, ++ pub f_blocks: blkcnt64_t, ++ pub f_bfree: blkcnt64_t, ++ pub f_bavail: blkcnt64_t, ++ pub f_files: ::uint64_t, ++ pub f_ffree: ::uint64_t, ++ pub f_fsid: fsid64_t, ++ pub f_vfstype: ::c_int, ++ pub f_fsize: blksize64_t, ++ pub f_vfsnumber: ::c_int, ++ pub f_vfsoff: ::c_int, ++ pub f_vfslen: ::c_int, ++ pub f_vfsvers: ::c_int, ++ pub f_fname: [::c_char; 32], ++ pub f_fpack: [::c_char; 32], ++ pub f_name_max: ::c_int, ++ } ++ ++ pub struct passwd { ++ pub pw_name: *mut ::c_char, ++ pub pw_passwd: *mut ::c_char, ++ pub pw_uid: ::uid_t, ++ pub pw_gid: ::gid_t, ++ pub pw_gecos: *mut ::c_char, ++ pub pw_dir: *mut ::c_char, ++ pub pw_shell: *mut ::c_char ++ } ++ ++ pub struct utsname { ++ pub sysname: [::c_char; 32], ++ pub nodename: [::c_char; 32], ++ pub release: [::c_char; 32], ++ pub version: [::c_char; 32], ++ pub machine: [::c_char; 32], ++ } ++ ++ pub struct xutsname { ++ pub nid: ::c_uint, ++ pub reserved: ::c_int, ++ pub longnid: ::c_ulonglong, ++ } ++ ++ pub struct cmsghdr { ++ pub cmsg_len: ::socklen_t, ++ pub cmsg_level: ::c_int, ++ pub cmsg_type: ::c_int, ++ } ++ ++ pub struct sigevent { ++ pub sigev_value: ::sigval, ++ pub sigev_signo: ::c_int, ++ pub sigev_notify: ::c_int, ++ pub sigev_notify_function: extern fn(val: ::sigval), ++ pub sigev_notify_attributes: *mut pthread_attr_t, ++ } ++ ++ // Should be union with another 'sival_int' ++ pub struct sigval64 { ++ pub sival_ptr: ::c_ulonglong, ++ } ++ ++ pub struct sigevent64 { ++ pub sigev_value: sigval64, ++ pub sigev_signo: ::c_int, ++ pub sigev_notify: ::c_int, ++ pub sigev_notify_function: ::c_ulonglong, ++ pub sigev_notify_attributes: ::c_ulonglong, ++ } ++ ++ pub struct osigevent { ++ pub sevt_value: *mut ::c_void, ++ pub sevt_signo: signal_t, ++ } ++ ++ pub struct poll_ctl { ++ pub cmd: ::c_short, ++ pub events: ::c_short, ++ pub fd: ::c_int, ++ } ++ ++ pub struct sf_parms { ++ pub header_data: *mut ::c_void, ++ pub header_length: ::c_uint, ++ pub file_descriptor: ::c_int, ++ pub file_size: ::uint64_t, ++ pub file_offset: ::uint64_t, ++ pub file_bytes: ::int64_t, ++ pub trailer_data: *mut ::c_void, ++ pub trailer_length: ::c_uint, ++ pub bytes_sent: ::uint64_t, ++ } ++ ++ pub struct mmsghdr { ++ pub msg_hdr: ::msghdr, ++ pub msg_len: ::c_uint, ++ } ++ ++ pub struct sched_param { ++ pub sched_priority: ::c_int, ++ pub sched_policy: ::c_int, ++ pub sched_reserved: [::c_int; 6], ++ } ++ ++ pub struct stack_t { ++ pub ss_sp: *mut ::c_void, ++ pub ss_size: ::size_t, ++ pub ss_flags: ::c_int, ++ pub __pad: [::c_int; 4], ++ } ++ ++ pub struct posix_spawnattr_t { ++ pub posix_attr_flags: ::c_short, ++ pub posix_attr_pgroup: ::pid_t, ++ pub posix_attr_sigmask: ::sigset_t, ++ pub posix_attr_sigdefault: ::sigset_t, ++ pub posix_attr_schedpolicy: ::c_int, ++ pub posix_attr_schedparam: sched_param, ++ } ++ ++ pub struct glob_t { ++ pub gl_pathc: ::size_t, ++ pub gl_pathv: *mut *mut c_char, ++ pub gl_offs: ::size_t, ++ pub gl_padr: *mut ::c_void, ++ pub gl_ptx: *mut ::c_void, ++ } ++ ++ pub struct mallinfo { ++ pub arena: ::c_ulong, ++ pub ordblks: ::c_int, ++ pub smblks: ::c_int, ++ pub hblks: ::c_int, ++ pub hblkhd: ::c_int, ++ pub usmblks: ::c_ulong, ++ pub fsmblks: ::c_ulong, ++ pub uordblks: ::c_ulong, ++ pub fordblks: ::c_ulong, ++ pub keepcost: ::c_int, ++ } ++ ++ pub struct utmp_exit_status { ++ pub e_termination: ::c_short, ++ pub e_exit: ::c_short, ++ } ++ ++ pub struct utmp { ++ pub ut_user: [::c_char; 256], ++ pub ut_id: [::c_char; 14], ++ pub ut_line: [::c_char; 64], ++ pub ut_pid: ::pid_t, ++ pub ut_type: ::c_short, ++ pub ut_time: time64_t, ++ pub ut_exit: utmp_exit_status, ++ pub ut_host: [::c_char; 256], ++ pub __dbl_word_pad: ::c_int, ++ pub __reservedA: [::c_int; 2], ++ pub __reservedV: [::c_int; 6], ++ } ++ ++ pub struct regmatch_t { ++ pub rm_so: regoff_t, ++ pub rm_eo: regoff_t, ++ } ++ ++ pub struct regex_t { ++ pub re_nsub: ::size_t, ++ pub re_comp: *mut ::c_void, ++ pub re_cflags: ::c_int, ++ pub re_erroff: ::size_t, ++ pub re_len: ::size_t, ++ pub re_ucoll: [::wchar_t; 2], ++ pub re_lsub: [*mut ::c_void; 24], ++ pub re_esub: [*mut ::c_void; 24], ++ pub re_map: *mut ::c_uchar, ++ pub __maxsub: ::c_int, ++ pub __unused: [*mut ::c_void; 34], ++ } ++ ++ pub struct rlimit64 { ++ pub rlim_cur: rlim64_t, ++ pub rlim_max: rlim64_t, ++ } ++ ++ pub struct shmid_ds { ++ pub shm_perm: ipc_perm, ++ pub shm_segsz: ::size_t, ++ pub shm_lpid: ::pid_t, ++ pub shm_cpid: ::pid_t, ++ pub shm_nattch: shmatt_t, ++ pub shm_cnattch: shmatt_t, ++ pub shm_atime: time_t, ++ pub shm_dtime: time_t, ++ pub shm_ctime: time_t, ++ pub shm_handle: ::uint32_t, ++ pub shm_extshm: ::c_int, ++ pub shm_pagesize: ::int64_t, ++ pub shm_lba: ::uint64_t, ++ pub shm_reserved: ::int64_t, ++ pub shm_reserved1: ::int64_t, ++ } ++ ++ pub struct stat64 { ++ pub st_dev: dev_t, ++ pub st_ino: ino_t, ++ pub st_mode: mode_t, ++ pub st_nlink: nlink_t, ++ pub st_flag: ::c_ushort, ++ pub st_uid: ::uid_t, ++ pub st_gid: ::gid_t, ++ pub st_rdev: dev_t, ++ pub st_ssize: ::c_int, ++ pub st_atim: st_timespec, ++ pub st_mtim: st_timespec, ++ pub st_ctim: st_timespec, ++ pub st_blksize: blksize_t, ++ pub st_blocks: blkcnt_t, ++ pub st_vfstype: ::c_int, ++ pub st_vfs: ::c_uint, ++ pub st_type: ::c_uint, ++ pub st_gen: ::c_uint, ++ pub st_reserved: [::c_uint; 10], ++ pub st_size: off64_t, ++ } ++ ++ pub struct mntent { ++ pub mnt_fsname: *mut ::c_char, ++ pub mnt_dir: *mut ::c_char, ++ pub mnt_type: *mut ::c_char, ++ pub mnt_opts: *mut ::c_char, ++ pub mnt_freq: ::c_int, ++ pub mnt_passno: ::c_int, ++ } ++ ++ pub struct ipc_perm { ++ pub uid: ::uid_t, ++ pub gid: ::gid_t, ++ pub cuid: ::uid_t, ++ pub cgid: ::gid_t, ++ pub mode: mode_t, ++ pub seq: ::c_ushort, ++ pub __reserved: ::c_ushort, ++ pub key: key_t, ++ } ++ ++ pub struct entry { ++ pub key: *mut ::c_char, ++ pub data: *mut ::c_void, ++ } ++ ++ pub struct mq_attr { ++ pub mq_flags: ::c_long, ++ pub mq_maxmsg: ::c_long, ++ pub mq_msgsize: ::c_long, ++ pub mq_curmsgs: ::c_long, ++ } ++ ++ pub struct sembuf { ++ pub sem_num: ::c_ushort, ++ pub sem_op: ::c_short, ++ pub sem_flg: ::c_short, ++ } ++ ++ pub struct if_nameindex { ++ pub if_index: ::c_uint, ++ pub if_name: *mut ::c_char, ++ } ++ ++ pub struct itimerspec { ++ pub it_interval: ::timespec, ++ pub it_value: ::timespec, ++ } ++} ++ ++s_no_extra_traits! { ++ #[cfg(libc_union)] ++ pub union __sigaction_sa_union { ++ pub __su_handler: extern fn(c: ::c_int), ++ pub __su_sigaction: extern fn(c: ::c_int, info: *mut siginfo_t, ptr: *mut ::c_void), ++ } ++ ++ pub struct sigaction { ++ #[cfg(libc_union)] ++ pub sa_union: __sigaction_sa_union, ++ pub sa_mask: sigset_t, ++ pub sa_flags: ::c_int, ++ } ++ ++ #[cfg(libc_union)] ++ pub union __poll_ctl_ext_u { ++ pub addr: *mut ::c_void, ++ pub data32: u32, ++ pub data: u64, ++ } ++ ++ pub struct poll_ctl_ext { ++ pub version: u8, ++ pub command: u8, ++ pub events: ::c_short, ++ pub fd: ::c_int, ++ #[cfg(libc_union)] ++ pub u: __poll_ctl_ext_u, ++ pub reversed64: [u64; 6], ++ } ++} ++ ++cfg_if! { ++ if #[cfg(feature = "extra_traits")] { ++ #[cfg(libc_union)] ++ impl PartialEq for __sigaction_sa_union { ++ fn eq(&self, other: &__sigaction_sa_union) -> bool { ++ unsafe { ++ self.__su_handler == other.__su_handler ++ && self.__su_sigaction == other.__su_sigaction ++ } ++ } ++ } ++ #[cfg(libc_union)] ++ impl Eq for __sigaction_sa_union {} ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for __sigaction_sa_union { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("__sigaction_sa_union") ++ .field("__su_handler", unsafe { &self.__su_handler }) ++ .field("__su_sigaction", unsafe { &self.__su_sigaction }) ++ .finish() ++ } ++ } ++ #[cfg(libc_union)] ++ impl ::hash::Hash for __sigaction_sa_union { ++ fn hash(&self, state: &mut H) { ++ unsafe { ++ self.__su_handler.hash(state); ++ self.__su_sigaction.hash(state); ++ } ++ } ++ } ++ ++ impl PartialEq for sigaction { ++ fn eq(&self, other: &sigaction) -> bool { ++ #[cfg(libc_union)] ++ let union_eq = self.sa_union == other.sa_union; ++ #[cfg(not(libc_union))] ++ let union_eq = true; ++ self.sa_mask == other.sa_mask ++ && self.sa_flags == other.sa_flags ++ && union_eq ++ } ++ } ++ impl Eq for sigaction {} ++ impl ::fmt::Debug for sigaction { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let mut struct_formatter = f.debug_struct("sigaction"); ++ #[cfg(libc_union)] ++ struct_formatter.field("sa_union", &self.sa_union); ++ struct_formatter.field("sa_mask", &self.sa_mask); ++ struct_formatter.field("sa_flags", &self.sa_flags); ++ struct_formatter.finish() ++ } ++ } ++ impl ::hash::Hash for sigaction { ++ fn hash(&self, state: &mut H) { ++ #[cfg(libc_union)] ++ self.sa_union.hash(state); ++ self.sa_mask.hash(state); ++ self.sa_flags.hash(state); ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl PartialEq for __poll_ctl_ext_u { ++ fn eq(&self, other: &__poll_ctl_ext_u) -> bool { ++ unsafe { ++ self.addr == other.addr ++ && self.data32 == other.data32 ++ && self.data == other.data ++ } ++ } ++ } ++ #[cfg(libc_union)] ++ impl Eq for __poll_ctl_ext_u {} ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for __poll_ctl_ext_u { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("__poll_ctl_ext_u") ++ .field("addr", unsafe { &self.addr }) ++ .field("data32", unsafe { &self.data32 }) ++ .field("data", unsafe { &self.data }) ++ .finish() ++ } ++ } ++ #[cfg(libc_union)] ++ impl ::hash::Hash for __poll_ctl_ext_u { ++ fn hash(&self, state: &mut H) { ++ unsafe { ++ self.addr.hash(state); ++ self.data32.hash(state); ++ self.data.hash(state); ++ } ++ } ++ } ++ ++ impl PartialEq for poll_ctl_ext { ++ fn eq(&self, other: &poll_ctl_ext) -> bool { ++ #[cfg(libc_union)] ++ let union_eq = self.u == other.u; ++ #[cfg(not(libc_union))] ++ let union_eq = true; ++ self.version == other.version ++ && self.command == other.command ++ && self.events == other.events ++ && self.fd == other.fd ++ && self.reversed64 == other.reversed64 ++ && union_eq ++ } ++ } ++ impl Eq for poll_ctl_ext {} ++ impl ::fmt::Debug for poll_ctl_ext { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let mut struct_formatter = f.debug_struct("poll_ctl_ext"); ++ struct_formatter.field("version", &self.version); ++ struct_formatter.field("command", &self.command); ++ struct_formatter.field("events", &self.events); ++ struct_formatter.field("fd", &self.fd); ++ #[cfg(libc_union)] ++ struct_formatter.field("u", &self.u); ++ struct_formatter.field("reversed64", &self.reversed64); ++ struct_formatter.finish() ++ } ++ } ++ impl ::hash::Hash for poll_ctl_ext { ++ fn hash(&self, state: &mut H) { ++ self.version.hash(state); ++ self.command.hash(state); ++ self.events.hash(state); ++ self.fd.hash(state); ++ #[cfg(libc_union)] ++ self.u.hash(state); ++ self.reversed64.hash(state); ++ } ++ } ++ } ++} ++ ++// dlfcn.h ++pub const RTLD_LAZY: ::c_int = 0x4; ++pub const RTLD_NOW: ::c_int = 0x2; ++pub const RTLD_GLOBAL: ::c_int = 0x10000; ++pub const RTLD_LOCAL: ::c_int = 0x80000; ++pub const RTLD_DEFAULT: *mut ::c_void = -1isize as *mut ::c_void; ++pub const RTLD_MYSELF: *mut ::c_void = -2isize as *mut ::c_void; ++pub const RTLD_NEXT: *mut ::c_void = -3isize as *mut ::c_void; ++ ++// fcntl.h ++pub const O_RDONLY: ::c_int = 0x0; ++pub const O_WRONLY: ::c_int = 0x1; ++pub const O_RDWR: ::c_int = 0x2; ++pub const O_NDELAY: ::c_int = 0x8000; ++pub const O_APPEND: ::c_int = 0x8; ++pub const O_DSYNC: ::c_int = 0x400000; ++pub const O_CREAT: ::c_int = 0x100; ++pub const O_EXCL: ::c_int = 0x400; ++pub const O_NOCTTY: ::c_int = 0x800; ++pub const O_TRUNC: ::c_int = 0x200; ++pub const O_NOFOLLOW: ::c_int = 0x1000000; ++pub const O_DIRECTORY: ::c_int = 0x80000; ++pub const O_SEARCH: ::c_int = 0x20; ++pub const O_EXEC: ::c_int = 0x20; ++pub const O_CLOEXEC: ::c_int = 0x800000; ++pub const O_ACCMODE: ::c_int = O_RDONLY | O_WRONLY | O_RDWR; ++pub const O_DIRECT: ::c_int = 0x8000000; ++pub const O_TTY_INIT: ::c_int = 0; ++pub const O_RSYNC: ::c_int = 0x200000; ++pub const O_LARGEFILE: ::c_int = 0x4000000; ++pub const F_CLOSEM: ::c_int = 10; ++pub const F_DUPFD_CLOEXEC: ::c_int = 16; ++pub const F_GETLK64: ::c_int = 11; ++pub const F_SETLK64: ::c_int = 12; ++pub const F_SETLKW64: ::c_int = 13; ++pub const F_DUP2FD: ::c_int = 14; ++pub const F_TSTLK: ::c_int = 15; ++pub const F_GETLK: ::c_int = F_GETLK64; ++pub const F_SETLK: ::c_int = F_SETLK64; ++pub const F_SETLKW: ::c_int = F_SETLKW64; ++pub const F_GETOWN: ::c_int = 8; ++pub const F_SETOWN: ::c_int = 9; ++pub const AT_FDCWD: ::c_int = -2; ++pub const AT_SYMLINK_NOFOLLOW: ::c_int = 1; ++pub const AT_SYMLINK_FOLLOW: ::c_int = 2; ++pub const AT_REMOVEDIR: ::c_int = 1; ++pub const AT_EACCESS: ::c_int = 1; ++pub const F_DUPFD: ::c_int = 0; ++pub const F_GETFD: ::c_int = 1; ++pub const F_SETFD: ::c_int = 2; ++pub const F_GETFL: ::c_int = 3; ++pub const F_SETFL: ::c_int = 4; ++pub const O_SYNC: ::c_int = 16; ++pub const O_NONBLOCK: ::c_int = 4; ++pub const FASYNC: ::c_int = 0x20000; ++pub const POSIX_FADV_NORMAL: ::c_int = 1; ++pub const POSIX_FADV_SEQUENTIAL: ::c_int = 2; ++pub const POSIX_FADV_RANDOM: ::c_int = 3; ++pub const POSIX_FADV_WILLNEED: ::c_int = 4; ++pub const POSIX_FADV_DONTNEED: ::c_int = 5; ++pub const POSIX_FADV_NOREUSE: ::c_int = 6; ++ ++// glob.h ++pub const GLOB_APPEND: ::c_int = 0x1; ++pub const GLOB_DOOFFS: ::c_int = 0x2; ++pub const GLOB_ERR: ::c_int = 0x4; ++pub const GLOB_MARK: ::c_int = 0x8; ++pub const GLOB_NOCHECK: ::c_int = 0x10; ++pub const GLOB_NOSORT: ::c_int = 0x20; ++pub const GLOB_NOESCAPE: ::c_int = 0x80; ++pub const GLOB_NOSPACE: ::c_int = 0x2000; ++pub const GLOB_ABORTED: ::c_int = 0x1000; ++pub const GLOB_NOMATCH: ::c_int = 0x4000; ++pub const GLOB_NOSYS: ::c_int = 0x8000; ++ ++// langinfo.h ++pub const DAY_1: ::nl_item = 13; ++pub const DAY_2: ::nl_item = 14; ++pub const DAY_3: ::nl_item = 15; ++pub const DAY_4: ::nl_item = 16; ++pub const DAY_5: ::nl_item = 17; ++pub const DAY_6: ::nl_item = 18; ++pub const DAY_7: ::nl_item = 19; ++pub const ABDAY_1: ::nl_item = 6; ++pub const ABDAY_2: ::nl_item = 7; ++pub const ABDAY_3: ::nl_item = 8; ++pub const ABDAY_4: ::nl_item = 9; ++pub const ABDAY_5: ::nl_item = 10; ++pub const ABDAY_6: ::nl_item = 11; ++pub const ABDAY_7: ::nl_item = 12; ++pub const MON_1: ::nl_item = 32; ++pub const MON_2: ::nl_item = 33; ++pub const MON_3: ::nl_item = 34; ++pub const MON_4: ::nl_item = 35; ++pub const MON_5: ::nl_item = 36; ++pub const MON_6: ::nl_item = 37; ++pub const MON_7: ::nl_item = 38; ++pub const MON_8: ::nl_item = 39; ++pub const MON_9: ::nl_item = 40; ++pub const MON_10: ::nl_item = 41; ++pub const MON_11: ::nl_item = 42; ++pub const MON_12: ::nl_item = 43; ++pub const ABMON_1: ::nl_item = 20; ++pub const ABMON_2: ::nl_item = 21; ++pub const ABMON_3: ::nl_item = 22; ++pub const ABMON_4: ::nl_item = 23; ++pub const ABMON_5: ::nl_item = 24; ++pub const ABMON_6: ::nl_item = 25; ++pub const ABMON_7: ::nl_item = 26; ++pub const ABMON_8: ::nl_item = 27; ++pub const ABMON_9: ::nl_item = 28; ++pub const ABMON_10: ::nl_item = 29; ++pub const ABMON_11: ::nl_item = 30; ++pub const ABMON_12: ::nl_item = 31; ++pub const RADIXCHAR: ::nl_item = 44; ++pub const THOUSEP: ::nl_item = 45; ++pub const YESSTR: ::nl_item = 46; ++pub const NOSTR: ::nl_item = 47; ++pub const CRNCYSTR: ::nl_item = 48; ++pub const D_T_FMT: ::nl_item = 1; ++pub const D_FMT: ::nl_item = 2; ++pub const T_FMT: ::nl_item = 3; ++pub const AM_STR: ::nl_item = 4; ++pub const PM_STR: ::nl_item = 5; ++pub const CODESET: ::nl_item = 49; ++pub const T_FMT_AMPM: ::nl_item = 55; ++pub const ERA: ::nl_item = 56; ++pub const ERA_D_FMT: ::nl_item = 57; ++pub const ERA_D_T_FMT: ::nl_item = 58; ++pub const ERA_T_FMT: ::nl_item = 59; ++pub const ALT_DIGITS: ::nl_item = 60; ++pub const YESEXPR: ::nl_item = 61; ++pub const NOEXPR: ::nl_item = 62; ++ ++// locale.h ++pub const LC_GLOBAL_LOCALE: ::locale_t = -1isize as ::locale_t; ++pub const LC_CTYPE: ::c_int = 1; ++pub const LC_NUMERIC: ::c_int = 3; ++pub const LC_TIME: ::c_int = 4; ++pub const LC_COLLATE: ::c_int = 0; ++pub const LC_MONETARY: ::c_int = 2; ++pub const LC_MESSAGES: ::c_int = 4; ++pub const LC_ALL: ::c_int = -1; ++pub const LC_CTYPE_MASK: ::c_int = 2; ++pub const LC_NUMERIC_MASK: ::c_int = 16; ++pub const LC_TIME_MASK: ::c_int = 32; ++pub const LC_COLLATE_MASK: ::c_int = 1; ++pub const LC_MONETARY_MASK: ::c_int = 8; ++pub const LC_MESSAGES_MASK: ::c_int = 4; ++pub const LC_ALL_MASK: ::c_int = LC_CTYPE_MASK ++ | LC_NUMERIC_MASK ++ | LC_TIME_MASK ++ | LC_COLLATE_MASK ++ | LC_MONETARY_MASK ++ | LC_MESSAGES_MASK; ++ ++// netdb.h ++pub const NI_MAXHOST: ::socklen_t = 1025; ++pub const NI_MAXSERV: ::socklen_t = 32; ++pub const NI_NOFQDN: ::socklen_t = 0x1; ++pub const NI_NUMERICHOST: ::socklen_t = 0x2; ++pub const NI_NAMEREQD: ::socklen_t = 0x4; ++pub const NI_NUMERICSERV: ::socklen_t = 0x8; ++pub const NI_DGRAM: ::socklen_t = 0x10; ++pub const NI_NUMERICSCOPE: ::socklen_t = 0x40; ++pub const EAI_AGAIN: ::c_int = 2; ++pub const EAI_BADFLAGS: ::c_int = 3; ++pub const EAI_FAIL: ::c_int = 4; ++pub const EAI_FAMILY: ::c_int = 5; ++pub const EAI_MEMORY: ::c_int = 6; ++pub const EAI_NODATA: ::c_int = 7; ++pub const EAI_NONAME: ::c_int = 8; ++pub const EAI_SERVICE: ::c_int = 9; ++pub const EAI_SOCKTYPE: ::c_int = 10; ++pub const EAI_SYSTEM: ::c_int = 11; ++pub const EAI_OVERFLOW: ::c_int = 13; ++pub const AI_CANONNAME: ::c_int = 0x01; ++pub const AI_PASSIVE: ::c_int = 0x02; ++pub const AI_NUMERICHOST: ::c_int = 0x04; ++pub const AI_ADDRCONFIG: ::c_int = 0x08; ++pub const AI_V4MAPPED: ::c_int = 0x10; ++pub const AI_ALL: ::c_int = 0x20; ++pub const AI_NUMERICSERV: ::c_int = 0x40; ++pub const AI_EXTFLAGS: ::c_int = 0x80; ++pub const AI_DEFAULT: ::c_int = AI_V4MAPPED | AI_ADDRCONFIG; ++pub const IPV6_ADDRFORM: ::c_int = 22; ++pub const IPV6_ADDR_PREFERENCES: ::c_int = 74; ++pub const IPV6_CHECKSUM: ::c_int = 39; ++pub const IPV6_DONTFRAG: ::c_int = 45; ++pub const IPV6_DSTOPTS: ::c_int = 54; ++pub const IPV6_FLOWINFO_FLOWLABEL: ::c_int = 16777215; ++pub const IPV6_FLOWINFO_PRIORITY: ::c_int = 251658240; ++pub const IPV6_HOPLIMIT: ::c_int = 40; ++pub const IPV6_HOPOPTS: ::c_int = 52; ++pub const IPV6_NEXTHOP: ::c_int = 48; ++pub const IPV6_PATHMTU: ::c_int = 46; ++pub const IPV6_PKTINFO: ::c_int = 33; ++pub const IPV6_PREFER_SRC_CGA: ::c_int = 16; ++pub const IPV6_PREFER_SRC_COA: ::c_int = 2; ++pub const IPV6_PREFER_SRC_HOME: ::c_int = 1; ++pub const IPV6_PREFER_SRC_NONCGA: ::c_int = 32; ++pub const IPV6_PREFER_SRC_PUBLIC: ::c_int = 4; ++pub const IPV6_PREFER_SRC_TMP: ::c_int = 8; ++pub const IPV6_RECVDSTOPTS: ::c_int = 56; ++pub const IPV6_RECVHOPLIMIT: ::c_int = 41; ++pub const IPV6_RECVHOPOPTS: ::c_int = 53; ++pub const IPV6_RECVPATHMTU: ::c_int = 47; ++pub const IPV6_RECVRTHDR: ::c_int = 51; ++pub const IPV6_RECVTCLASS: ::c_int = 42; ++pub const IPV6_RTHDR: ::c_int = 50; ++pub const IPV6_RTHDRDSTOPTS: ::c_int = 55; ++pub const IPV6_TCLASS: ::c_int = 43; ++ ++// net/bpf.h ++pub const DLT_NULL: ::c_int = 0x18; ++pub const DLT_EN10MB: ::c_int = 0x6; ++pub const DLT_EN3MB: ::c_int = 0x1a; ++pub const DLT_AX25: ::c_int = 0x5; ++pub const DLT_PRONET: ::c_int = 0xd; ++pub const DLT_IEEE802: ::c_int = 0x7; ++pub const DLT_ARCNET: ::c_int = 0x23; ++pub const DLT_SLIP: ::c_int = 0x1c; ++pub const DLT_PPP: ::c_int = 0x17; ++pub const DLT_FDDI: ::c_int = 0xf; ++pub const DLT_ATM: ::c_int = 0x25; ++pub const DLT_IPOIB: ::c_int = 0xc7; ++pub const BIOCSETF: ::c_ulong = 0x80104267; ++pub const BIOCGRTIMEOUT: ::c_ulong = 0x4010426e; ++pub const BIOCGBLEN: ::c_int = 0x40044266; ++pub const BIOCSBLEN: ::c_int = 0xc0044266; ++pub const BIOCFLUSH: ::c_int = 0x20004268; ++pub const BIOCPROMISC: ::c_int = 0x20004269; ++pub const BIOCGDLT: ::c_int = 0x4004426a; ++pub const BIOCSRTIMEOUT: ::c_int = 0x8010426d; ++pub const BIOCGSTATS: ::c_int = 0x4008426f; ++pub const BIOCIMMEDIATE: ::c_int = 0x80044270; ++pub const BIOCVERSION: ::c_int = 0x40044271; ++pub const BIOCSDEVNO: ::c_int = 0x20004272; ++pub const BIOCGETIF: ::c_ulong = 0x4020426b; ++pub const BIOCSETIF: ::c_ulong = 0xffffffff8020426c; ++pub const BPF_ABS: ::c_int = 32; ++pub const BPF_ADD: ::c_int = 0; ++pub const BPF_ALIGNMENT: ::c_ulong = 4; ++pub const BPF_ALU: ::c_int = 4; ++pub const BPF_AND: ::c_int = 80; ++pub const BPF_B: ::c_int = 16; ++pub const BPF_DIV: ::c_int = 48; ++pub const BPF_H: ::c_int = 8; ++pub const BPF_IMM: ::c_int = 0; ++pub const BPF_IND: ::c_int = 64; ++pub const BPF_JA: ::c_int = 0; ++pub const BPF_JEQ: ::c_int = 16; ++pub const BPF_JGE: ::c_int = 48; ++pub const BPF_JGT: ::c_int = 32; ++pub const BPF_JMP: ::c_int = 5; ++pub const BPF_JSET: ::c_int = 64; ++pub const BPF_K: ::c_int = 0; ++pub const BPF_LD: ::c_int = 0; ++pub const BPF_LDX: ::c_int = 1; ++pub const BPF_LEN: ::c_int = 128; ++pub const BPF_LSH: ::c_int = 96; ++pub const BPF_MAXINSNS: ::c_int = 512; ++pub const BPF_MEM: ::c_int = 96; ++pub const BPF_MEMWORDS: ::c_int = 16; ++pub const BPF_MISC: ::c_int = 7; ++pub const BPF_MSH: ::c_int = 160; ++pub const BPF_MUL: ::c_int = 32; ++pub const BPF_NEG: ::c_int = 128; ++pub const BPF_OR: ::c_int = 64; ++pub const BPF_RET: ::c_int = 6; ++pub const BPF_RSH: ::c_int = 112; ++pub const BPF_ST: ::c_int = 2; ++pub const BPF_STX: ::c_int = 3; ++pub const BPF_SUB: ::c_int = 16; ++pub const BPF_W: ::c_int = 0; ++pub const BPF_X: ::c_int = 8; ++ ++// net/if.h ++pub const IFNET_SLOWHZ: ::c_int = 1; ++pub const IFQ_MAXLEN: ::c_int = 50; ++pub const IF_NAMESIZE: ::c_int = 16; ++pub const IFNAMSIZ: ::c_int = 16; ++pub const IFF_UP: ::c_int = 0x1; ++pub const IFF_BROADCAST: ::c_int = 0x2; ++pub const IFF_DEBUG: ::c_int = 0x4; ++pub const IFF_LOOPBACK: ::c_int = 0x8; ++pub const IFF_POINTOPOINT: ::c_int = 0x10; ++pub const IFF_NOTRAILERS: ::c_int = 0x20; ++pub const IFF_RUNNING: ::c_int = 0x40; ++pub const IFF_NOARP: ::c_int = 0x80; ++pub const IFF_PROMISC: ::c_int = 0x100; ++pub const IFF_ALLMULTI: ::c_int = 0x200; ++pub const IFF_MULTICAST: ::c_int = 0x80000; ++pub const IFF_LINK0: ::c_int = 0x100000; ++pub const IFF_LINK1: ::c_int = 0x200000; ++pub const IFF_LINK2: ::c_int = 0x400000; ++pub const IFF_OACTIVE: ::c_int = 0x400; ++pub const IFF_SIMPLEX: ::c_int = 0x800; ++ ++// net/if_arp.h ++pub const ARPHRD_ETHER: ::c_int = 1; ++pub const ARPHRD_802_5: ::c_int = 6; ++pub const ARPHRD_802_3: ::c_int = 6; ++pub const ARPHRD_FDDI: ::c_int = 1; ++pub const ARPOP_REQUEST: ::c_int = 1; ++pub const ARPOP_REPLY: ::c_int = 2; ++ ++// net/route.h ++pub const RTM_ADD: ::c_int = 0x1; ++pub const RTM_DELETE: ::c_int = 0x2; ++pub const RTM_CHANGE: ::c_int = 0x3; ++pub const RTM_GET: ::c_int = 0x4; ++pub const RTM_LOSING: ::c_int = 0x5; ++pub const RTM_REDIRECT: ::c_int = 0x6; ++pub const RTM_MISS: ::c_int = 0x7; ++pub const RTM_LOCK: ::c_int = 0x8; ++pub const RTM_OLDADD: ::c_int = 0x9; ++pub const RTM_OLDDEL: ::c_int = 0xa; ++pub const RTM_RESOLVE: ::c_int = 0xb; ++pub const RTM_NEWADDR: ::c_int = 0xc; ++pub const RTM_DELADDR: ::c_int = 0xd; ++pub const RTM_IFINFO: ::c_int = 0xe; ++pub const RTM_EXPIRE: ::c_int = 0xf; ++pub const RTM_RTLOST: ::c_int = 0x10; ++pub const RTM_GETNEXT: ::c_int = 0x11; ++pub const RTM_SAMEADDR: ::c_int = 0x12; ++pub const RTM_SET: ::c_int = 0x13; ++pub const RTV_MTU: ::c_int = 0x1; ++pub const RTV_HOPCOUNT: ::c_int = 0x2; ++pub const RTV_EXPIRE: ::c_int = 0x4; ++pub const RTV_RPIPE: ::c_int = 0x8; ++pub const RTV_SPIPE: ::c_int = 0x10; ++pub const RTV_SSTHRESH: ::c_int = 0x20; ++pub const RTV_RTT: ::c_int = 0x40; ++pub const RTV_RTTVAR: ::c_int = 0x80; ++pub const RTA_DST: ::c_int = 0x1; ++pub const RTA_GATEWAY: ::c_int = 0x2; ++pub const RTA_NETMASK: ::c_int = 0x4; ++pub const RTA_GENMASK: ::c_int = 0x8; ++pub const RTA_IFP: ::c_int = 0x10; ++pub const RTA_IFA: ::c_int = 0x20; ++pub const RTA_AUTHOR: ::c_int = 0x40; ++pub const RTA_BRD: ::c_int = 0x80; ++pub const RTA_DOWNSTREAM: ::c_int = 0x100; ++pub const RTAX_DST: ::c_int = 0; ++pub const RTAX_GATEWAY: ::c_int = 1; ++pub const RTAX_NETMASK: ::c_int = 2; ++pub const RTAX_GENMASK: ::c_int = 3; ++pub const RTAX_IFP: ::c_int = 4; ++pub const RTAX_IFA: ::c_int = 5; ++pub const RTAX_AUTHOR: ::c_int = 6; ++pub const RTAX_BRD: ::c_int = 7; ++pub const RTAX_MAX: ::c_int = 8; ++pub const RTF_UP: ::c_int = 0x1; ++pub const RTF_GATEWAY: ::c_int = 0x2; ++pub const RTF_HOST: ::c_int = 0x4; ++pub const RTF_REJECT: ::c_int = 0x8; ++pub const RTF_DYNAMIC: ::c_int = 0x10; ++pub const RTF_MODIFIED: ::c_int = 0x20; ++pub const RTF_DONE: ::c_int = 0x40; ++pub const RTF_MASK: ::c_int = 0x80; ++pub const RTF_CLONING: ::c_int = 0x100; ++pub const RTF_XRESOLVE: ::c_int = 0x200; ++pub const RTF_LLINFO: ::c_int = 0x400; ++pub const RTF_STATIC: ::c_int = 0x800; ++pub const RTF_BLACKHOLE: ::c_int = 0x1000; ++pub const RTF_BUL: ::c_int = 0x2000; ++pub const RTF_PROTO2: ::c_int = 0x4000; ++pub const RTF_PROTO1: ::c_int = 0x8000; ++pub const RTF_CLONE: ::c_int = 0x10000; ++pub const RTF_CLONED: ::c_int = 0x20000; ++pub const RTF_PROTO3: ::c_int = 0x40000; ++pub const RTF_BCE: ::c_int = 0x80000; ++pub const RTF_PINNED: ::c_int = 0x100000; ++pub const RTF_LOCAL: ::c_int = 0x200000; ++pub const RTF_BROADCAST: ::c_int = 0x400000; ++pub const RTF_MULTICAST: ::c_int = 0x800000; ++pub const RTF_ACTIVE_DGD: ::c_int = 0x1000000; ++pub const RTF_STOPSRCH: ::c_int = 0x2000000; ++pub const RTF_FREE_IN_PROG: ::c_int = 0x4000000; ++pub const RTF_PERMANENT6: ::c_int = 0x8000000; ++pub const RTF_UNREACHABLE: ::c_int = 0x10000000; ++pub const RTF_CACHED: ::c_int = 0x20000000; ++pub const RTF_SMALLMTU: ::c_int = 0x40000; ++ ++// netinet/in.h ++pub const IPPROTO_HOPOPTS: ::c_int = 0; ++pub const IPPROTO_IGMP: ::c_int = 2; ++pub const IPPROTO_GGP: ::c_int = 3; ++pub const IPPROTO_IPIP: ::c_int = 4; ++pub const IPPROTO_EGP: ::c_int = 8; ++pub const IPPROTO_PUP: ::c_int = 12; ++pub const IPPROTO_IDP: ::c_int = 22; ++pub const IPPROTO_TP: ::c_int = 29; ++pub const IPPROTO_ROUTING: ::c_int = 43; ++pub const IPPROTO_FRAGMENT: ::c_int = 44; ++pub const IPPROTO_QOS: ::c_int = 45; ++pub const IPPROTO_RSVP: ::c_int = 46; ++pub const IPPROTO_GRE: ::c_int = 47; ++pub const IPPROTO_ESP: ::c_int = 50; ++pub const IPPROTO_AH: ::c_int = 51; ++pub const IPPROTO_NONE: ::c_int = 59; ++pub const IPPROTO_DSTOPTS: ::c_int = 60; ++pub const IPPROTO_LOCAL: ::c_int = 63; ++pub const IPPROTO_EON: ::c_int = 80; ++pub const IPPROTO_BIP: ::c_int = 0x53; ++pub const IPPROTO_SCTP: ::c_int = 132; ++pub const IPPROTO_MH: ::c_int = 135; ++pub const IPPROTO_GIF: ::c_int = 140; ++pub const IPPROTO_RAW: ::c_int = 255; ++pub const IPPROTO_MAX: ::c_int = 256; ++pub const IP_OPTIONS: ::c_int = 1; ++pub const IP_HDRINCL: ::c_int = 2; ++pub const IP_TOS: ::c_int = 3; ++pub const IP_TTL: ::c_int = 4; ++pub const IP_UNICAST_HOPS: ::c_int = 4; ++pub const IP_RECVOPTS: ::c_int = 5; ++pub const IP_RECVRETOPTS: ::c_int = 6; ++pub const IP_RECVDSTADDR: ::c_int = 7; ++pub const IP_RETOPTS: ::c_int = 8; ++pub const IP_MULTICAST_IF: ::c_int = 9; ++pub const IP_MULTICAST_TTL: ::c_int = 10; ++pub const IP_MULTICAST_HOPS: ::c_int = 10; ++pub const IP_MULTICAST_LOOP: ::c_int = 11; ++pub const IP_ADD_MEMBERSHIP: ::c_int = 12; ++pub const IP_DROP_MEMBERSHIP: ::c_int = 13; ++pub const IP_RECVMACHDR: ::c_int = 14; ++pub const IP_RECVIFINFO: ::c_int = 15; ++pub const IP_BROADCAST_IF: ::c_int = 16; ++pub const IP_DHCPMODE: ::c_int = 17; ++pub const IP_RECVIF: ::c_int = 20; ++pub const IP_ADDRFORM: ::c_int = 22; ++pub const IP_DONTFRAG: ::c_int = 25; ++pub const IP_FINDPMTU: ::c_int = 26; ++pub const IP_PMTUAGE: ::c_int = 27; ++pub const IP_RECVINTERFACE: ::c_int = 32; ++pub const IP_RECVTTL: ::c_int = 34; ++pub const IP_BLOCK_SOURCE: ::c_int = 58; ++pub const IP_UNBLOCK_SOURCE: ::c_int = 59; ++pub const IP_ADD_SOURCE_MEMBERSHIP: ::c_int = 60; ++pub const IP_DROP_SOURCE_MEMBERSHIP: ::c_int = 61; ++pub const IP_DEFAULT_MULTICAST_TTL: ::c_int = 1; ++pub const IP_DEFAULT_MULTICAST_LOOP: ::c_int = 1; ++pub const IP_INC_MEMBERSHIPS: ::c_int = 20; ++pub const IP_INIT_MEMBERSHIP: ::c_int = 20; ++pub const IPV6_UNICAST_HOPS: ::c_int = IP_TTL; ++pub const IPV6_MULTICAST_IF: ::c_int = IP_MULTICAST_IF; ++pub const IPV6_MULTICAST_HOPS: ::c_int = IP_MULTICAST_TTL; ++pub const IPV6_MULTICAST_LOOP: ::c_int = IP_MULTICAST_LOOP; ++pub const IPV6_RECVPKTINFO: ::c_int = 35; ++pub const IPV6_V6ONLY: ::c_int = 37; ++pub const IPV6_ADD_MEMBERSHIP: ::c_int = IP_ADD_MEMBERSHIP; ++pub const IPV6_DROP_MEMBERSHIP: ::c_int = IP_DROP_MEMBERSHIP; ++pub const IPV6_JOIN_GROUP: ::c_int = IP_ADD_MEMBERSHIP; ++pub const IPV6_LEAVE_GROUP: ::c_int = IP_DROP_MEMBERSHIP; ++pub const MCAST_BLOCK_SOURCE: ::c_int = 64; ++pub const MCAST_EXCLUDE: ::c_int = 2; ++pub const MCAST_INCLUDE: ::c_int = 1; ++pub const MCAST_JOIN_GROUP: ::c_int = 62; ++pub const MCAST_JOIN_SOURCE_GROUP: ::c_int = 66; ++pub const MCAST_LEAVE_GROUP: ::c_int = 63; ++pub const MCAST_LEAVE_SOURCE_GROUP: ::c_int = 67; ++pub const MCAST_UNBLOCK_SOURCE: ::c_int = 65; ++ ++// netinet/ip.h ++pub const MAXTTL: ::c_int = 255; ++pub const IPDEFTTL: ::c_int = 64; ++pub const IPOPT_CONTROL: ::c_int = 0; ++pub const IPOPT_EOL: ::c_int = 0; ++pub const IPOPT_LSRR: ::c_int = 131; ++pub const IPOPT_MINOFF: ::c_int = 4; ++pub const IPOPT_NOP: ::c_int = 1; ++pub const IPOPT_OFFSET: ::c_int = 2; ++pub const IPOPT_OLEN: ::c_int = 1; ++pub const IPOPT_OPTVAL: ::c_int = 0; ++pub const IPOPT_RESERVED1: ::c_int = 0x20; ++pub const IPOPT_RESERVED2: ::c_int = 0x60; ++pub const IPOPT_RR: ::c_int = 7; ++pub const IPOPT_SSRR: ::c_int = 137; ++pub const IPOPT_TS: ::c_int = 68; ++pub const IPOPT_TS_PRESPEC: ::c_int = 3; ++pub const IPOPT_TS_TSANDADDR: ::c_int = 1; ++pub const IPOPT_TS_TSONLY: ::c_int = 0; ++pub const IPTOS_LOWDELAY: ::c_int = 16; ++pub const IPTOS_PREC_CRITIC_ECP: ::c_int = 160; ++pub const IPTOS_PREC_FLASH: ::c_int = 96; ++pub const IPTOS_PREC_FLASHOVERRIDE: ::c_int = 128; ++pub const IPTOS_PREC_IMMEDIATE: ::c_int = 64; ++pub const IPTOS_PREC_INTERNETCONTROL: ::c_int = 192; ++pub const IPTOS_PREC_NETCONTROL: ::c_int = 224; ++pub const IPTOS_PREC_PRIORITY: ::c_int = 32; ++pub const IPTOS_PREC_ROUTINE: ::c_int = 16; ++pub const IPTOS_RELIABILITY: ::c_int = 4; ++pub const IPTOS_THROUGHPUT: ::c_int = 8; ++pub const IPVERSION: ::c_int = 4; ++ ++// netinet/tcp.h ++pub const TCP_NODELAY: ::c_int = 0x1; ++pub const TCP_MAXSEG: ::c_int = 0x2; ++pub const TCP_RFC1323: ::c_int = 0x4; ++pub const TCP_KEEPALIVE: ::c_int = 0x8; ++pub const TCP_KEEPIDLE: ::c_int = 0x11; ++pub const TCP_KEEPINTVL: ::c_int = 0x12; ++pub const TCP_KEEPCNT: ::c_int = 0x13; ++pub const TCP_NODELAYACK: ::c_int = 0x14; ++ ++// pthread.h ++pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0; ++pub const PTHREAD_CREATE_DETACHED: ::c_int = 1; ++pub const PTHREAD_PROCESS_SHARED: ::c_int = 0; ++pub const PTHREAD_PROCESS_PRIVATE: ::c_ushort = 1; ++pub const PTHREAD_STACK_MIN: ::size_t = PAGESIZE as ::size_t * 4; ++pub const PTHREAD_MUTEX_NORMAL: ::c_int = 5; ++pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 3; ++pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 4; ++pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; ++pub const PTHREAD_MUTEX_ROBUST: ::c_int = 1; ++pub const PTHREAD_MUTEX_STALLED: ::c_int = 0; ++pub const PTHREAD_PRIO_INHERIT: ::c_int = 3; ++pub const PTHREAD_PRIO_NONE: ::c_int = 1; ++pub const PTHREAD_PRIO_PROTECT: ::c_int = 2; ++ ++// regex.h ++pub const REG_EXTENDED: ::c_int = 1; ++pub const REG_ICASE: ::c_int = 2; ++pub const REG_NEWLINE: ::c_int = 4; ++pub const REG_NOSUB: ::c_int = 8; ++pub const REG_NOTBOL: ::c_int = 0x100; ++pub const REG_NOTEOL: ::c_int = 0x200; ++pub const REG_NOMATCH: ::c_int = 1; ++pub const REG_BADPAT: ::c_int = 2; ++pub const REG_ECOLLATE: ::c_int = 3; ++pub const REG_ECTYPE: ::c_int = 4; ++pub const REG_EESCAPE: ::c_int = 5; ++pub const REG_ESUBREG: ::c_int = 6; ++pub const REG_EBRACK: ::c_int = 7; ++pub const REG_EPAREN: ::c_int = 8; ++pub const REG_EBRACE: ::c_int = 9; ++pub const REG_BADBR: ::c_int = 10; ++pub const REG_ERANGE: ::c_int = 11; ++pub const REG_ESPACE: ::c_int = 12; ++pub const REG_BADRPT: ::c_int = 13; ++pub const REG_ECHAR: ::c_int = 14; ++pub const REG_EBOL: ::c_int = 15; ++pub const REG_EEOL: ::c_int = 16; ++pub const REG_ENOSYS: ::c_int = 17; ++ ++// rpcsvc/mount.h ++pub const NFSMNT_ACDIRMAX: ::c_int = 2048; ++pub const NFSMNT_ACDIRMIN: ::c_int = 1024; ++pub const NFSMNT_ACREGMAX: ::c_int = 512; ++pub const NFSMNT_ACREGMIN: ::c_int = 256; ++pub const NFSMNT_INT: ::c_int = 64; ++pub const NFSMNT_NOAC: ::c_int = 128; ++pub const NFSMNT_RETRANS: ::c_int = 16; ++pub const NFSMNT_RSIZE: ::c_int = 4; ++pub const NFSMNT_SOFT: ::c_int = 1; ++pub const NFSMNT_TIMEO: ::c_int = 8; ++pub const NFSMNT_WSIZE: ::c_int = 2; ++ ++// rpcsvc/rstat.h ++pub const CPUSTATES: ::c_int = 4; ++ ++// search.h ++pub const FIND: ::c_int = 0; ++pub const ENTER: ::c_int = 1; ++ ++// semaphore.h ++pub const SEM_FAILED: *mut sem_t = -1isize as *mut ::sem_t; ++ ++// spawn.h ++pub const POSIX_SPAWN_SETPGROUP: ::c_int = 0x1; ++pub const POSIX_SPAWN_SETSIGMASK: ::c_int = 0x2; ++pub const POSIX_SPAWN_SETSIGDEF: ::c_int = 0x4; ++pub const POSIX_SPAWN_SETSCHEDULER: ::c_int = 0x8; ++pub const POSIX_SPAWN_SETSCHEDPARAM: ::c_int = 0x10; ++pub const POSIX_SPAWN_RESETIDS: ::c_int = 0x20; ++pub const POSIX_SPAWN_FORK_HANDLERS: ::c_int = 0x1000; ++ ++// stdio.h ++pub const EOF: ::c_int = -1; ++pub const SEEK_SET: ::c_int = 0; ++pub const SEEK_CUR: ::c_int = 1; ++pub const SEEK_END: ::c_int = 2; ++pub const _IOFBF: ::c_int = 0o000; ++pub const _IONBF: ::c_int = 0o004; ++pub const _IOLBF: ::c_int = 0o100; ++pub const BUFSIZ: ::c_uint = 4096; ++pub const FOPEN_MAX: ::c_uint = 32767; ++pub const FILENAME_MAX: ::c_uint = 255; ++pub const L_tmpnam: ::c_uint = 21; ++pub const TMP_MAX: ::c_uint = 16384; ++ ++// stdlib.h ++pub const EXIT_FAILURE: ::c_int = 1; ++pub const EXIT_SUCCESS: ::c_int = 0; ++pub const RAND_MAX: ::c_int = 32767; ++ ++// sys/access.h ++pub const F_OK: ::c_int = 0; ++pub const R_OK: ::c_int = 4; ++pub const W_OK: ::c_int = 2; ++pub const X_OK: ::c_int = 1; ++ ++// sys/aio.h ++pub const LIO_NOP: ::c_int = 0; ++pub const LIO_READ: ::c_int = 1; ++pub const LIO_WRITE: ::c_int = 2; ++pub const LIO_NOWAIT: ::c_int = 0; ++pub const LIO_WAIT: ::c_int = 1; ++pub const AIO_ALLDONE: ::c_int = 2; ++pub const AIO_CANCELED: ::c_int = 0; ++pub const AIO_NOTCANCELED: ::c_int = 1; ++ ++// sys/errno.h ++pub const EPERM: ::c_int = 1; ++pub const ENOENT: ::c_int = 2; ++pub const ESRCH: ::c_int = 3; ++pub const EINTR: ::c_int = 4; ++pub const EIO: ::c_int = 5; ++pub const ENXIO: ::c_int = 6; ++pub const E2BIG: ::c_int = 7; ++pub const ENOEXEC: ::c_int = 8; ++pub const EBADF: ::c_int = 9; ++pub const ECHILD: ::c_int = 10; ++pub const EAGAIN: ::c_int = 11; ++pub const ENOMEM: ::c_int = 12; ++pub const EACCES: ::c_int = 13; ++pub const EFAULT: ::c_int = 14; ++pub const ENOTBLK: ::c_int = 15; ++pub const EBUSY: ::c_int = 16; ++pub const EEXIST: ::c_int = 17; ++pub const EXDEV: ::c_int = 18; ++pub const ENODEV: ::c_int = 19; ++pub const ENOTDIR: ::c_int = 20; ++pub const EISDIR: ::c_int = 21; ++pub const EINVAL: ::c_int = 22; ++pub const ENFILE: ::c_int = 23; ++pub const EMFILE: ::c_int = 24; ++pub const ENOTTY: ::c_int = 25; ++pub const ETXTBSY: ::c_int = 26; ++pub const EFBIG: ::c_int = 27; ++pub const ENOSPC: ::c_int = 28; ++pub const ESPIPE: ::c_int = 29; ++pub const EROFS: ::c_int = 30; ++pub const EMLINK: ::c_int = 31; ++pub const EPIPE: ::c_int = 32; ++pub const EDOM: ::c_int = 33; ++pub const ERANGE: ::c_int = 34; ++pub const ENOMSG: ::c_int = 35; ++pub const EIDRM: ::c_int = 36; ++pub const ECHRNG: ::c_int = 37; ++pub const EL2NSYNC: ::c_int = 38; ++pub const EL3HLT: ::c_int = 39; ++pub const EL3RST: ::c_int = 40; ++pub const ELNRNG: ::c_int = 41; ++pub const EUNATCH: ::c_int = 42; ++pub const ENOCSI: ::c_int = 43; ++pub const EL2HLT: ::c_int = 44; ++pub const EDEADLK: ::c_int = 45; ++pub const ENOLCK: ::c_int = 49; ++pub const ECANCELED: ::c_int = 117; ++pub const ENOTSUP: ::c_int = 124; ++pub const EPROCLIM: ::c_int = 83; ++pub const EDQUOT: ::c_int = 88; ++pub const EOWNERDEAD: ::c_int = 95; ++pub const ENOTRECOVERABLE: ::c_int = 94; ++pub const ENOSTR: ::c_int = 123; ++pub const ENODATA: ::c_int = 122; ++pub const ETIME: ::c_int = 119; ++pub const ENOSR: ::c_int = 118; ++pub const EREMOTE: ::c_int = 93; ++pub const ENOATTR: ::c_int = 112; ++pub const ESAD: ::c_int = 113; ++pub const ENOTRUST: ::c_int = 114; ++pub const ENOLINK: ::c_int = 126; ++pub const EPROTO: ::c_int = 121; ++pub const EMULTIHOP: ::c_int = 125; ++pub const EBADMSG: ::c_int = 120; ++pub const ENAMETOOLONG: ::c_int = 86; ++pub const EOVERFLOW: ::c_int = 127; ++pub const EILSEQ: ::c_int = 116; ++pub const ENOSYS: ::c_int = 109; ++pub const ELOOP: ::c_int = 85; ++pub const ERESTART: ::c_int = 82; ++pub const ENOTEMPTY: ::c_int = 87; ++pub const EUSERS: ::c_int = 84; ++pub const ENOTSOCK: ::c_int = 57; ++pub const EDESTADDRREQ: ::c_int = 58; ++pub const EMSGSIZE: ::c_int = 59; ++pub const EPROTOTYPE: ::c_int = 60; ++pub const ENOPROTOOPT: ::c_int = 61; ++pub const EPROTONOSUPPORT: ::c_int = 62; ++pub const ESOCKTNOSUPPORT: ::c_int = 63; ++pub const EOPNOTSUPP: ::c_int = 64; ++pub const EPFNOSUPPORT: ::c_int = 65; ++pub const EAFNOSUPPORT: ::c_int = 66; ++pub const EADDRINUSE: ::c_int = 67; ++pub const EADDRNOTAVAIL: ::c_int = 68; ++pub const ENETDOWN: ::c_int = 69; ++pub const ENETUNREACH: ::c_int = 70; ++pub const ENETRESET: ::c_int = 71; ++pub const ECONNABORTED: ::c_int = 72; ++pub const ECONNRESET: ::c_int = 73; ++pub const ENOBUFS: ::c_int = 74; ++pub const EISCONN: ::c_int = 75; ++pub const ENOTCONN: ::c_int = 76; ++pub const ESHUTDOWN: ::c_int = 77; ++pub const ETOOMANYREFS: ::c_int = 115; ++pub const ETIMEDOUT: ::c_int = 78; ++pub const ECONNREFUSED: ::c_int = 79; ++pub const EHOSTDOWN: ::c_int = 80; ++pub const EHOSTUNREACH: ::c_int = 81; ++pub const EWOULDBLOCK: ::c_int = EAGAIN; ++pub const EALREADY: ::c_int = 56; ++pub const EINPROGRESS: ::c_int = 55; ++pub const ESTALE: ::c_int = 52; ++ ++// sys/dr.h ++pub const LPAR_INFO_FORMAT1: ::c_int = 1; ++pub const LPAR_INFO_FORMAT2: ::c_int = 2; ++pub const WPAR_INFO_FORMAT: ::c_int = 3; ++pub const PROC_MODULE_INFO: ::c_int = 4; ++pub const NUM_PROC_MODULE_TYPES: ::c_int = 5; ++pub const LPAR_INFO_VRME_NUM_POOLS: ::c_int = 6; ++pub const LPAR_INFO_VRME_POOLS: ::c_int = 7; ++pub const LPAR_INFO_VRME_LPAR: ::c_int = 8; ++pub const LPAR_INFO_VRME_RESET_HWMARKS: ::c_int = 9; ++pub const LPAR_INFO_VRME_ALLOW_DESIRED: ::c_int = 10; ++pub const EMTP_INFO_FORMAT: ::c_int = 11; ++pub const LPAR_INFO_LPM_CAPABILITY: ::c_int = 12; ++pub const ENERGYSCALE_INFO: ::c_int = 13; ++ ++// sys/file.h ++pub const LOCK_SH: ::c_int = 1; ++pub const LOCK_EX: ::c_int = 2; ++pub const LOCK_NB: ::c_int = 4; ++pub const LOCK_UN: ::c_int = 8; ++ ++// sys/flock.h ++pub const F_RDLCK: ::c_short = 0o01; ++pub const F_WRLCK: ::c_short = 0o02; ++pub const F_UNLCK: ::c_short = 0o03; ++ ++// sys/fs/quota_common.h ++pub const Q_QUOTAON: ::c_int = 0x100; ++pub const Q_QUOTAOFF: ::c_int = 0x200; ++pub const Q_SETUSE: ::c_int = 0x500; ++pub const Q_SYNC: ::c_int = 0x600; ++pub const Q_GETQUOTA: ::c_int = 0x300; ++pub const Q_SETQLIM: ::c_int = 0x400; ++pub const Q_SETQUOTA: ::c_int = 0x400; ++ ++// sys/ioctl.h ++pub const IOCPARM_MASK: ::c_int = 0x7f; ++pub const IOC_VOID: ::c_int = 0x20000000; ++pub const IOC_OUT: ::c_int = 0x40000000; ++pub const IOC_IN: ::c_int = 0x40000000 << 1; ++pub const IOC_INOUT: ::c_int = IOC_IN | IOC_OUT; ++pub const FIOCLEX: ::c_int = 536897025; ++pub const FIONCLEX: ::c_int = 536897026; ++pub const FIONREAD: ::c_int = 1074030207; ++pub const FIONBIO: ::c_int = -2147195266; ++pub const FIOASYNC: ::c_int = -2147195267; ++pub const FIOSETOWN: ::c_int = -2147195268; ++pub const FIOGETOWN: ::c_int = 1074030203; ++pub const TIOCGETD: ::c_int = 0x40047400; ++pub const TIOCSETD: ::c_int = 0x80047401; ++pub const TIOCHPCL: ::c_int = 0x20007402; ++pub const TIOCMODG: ::c_int = 0x40047403; ++pub const TIOCMODS: ::c_int = 0x80047404; ++pub const TIOCM_LE: ::c_int = 0x1; ++pub const TIOCM_DTR: ::c_int = 0x2; ++pub const TIOCM_RTS: ::c_int = 0x4; ++pub const TIOCM_ST: ::c_int = 0x8; ++pub const TIOCM_SR: ::c_int = 0x10; ++pub const TIOCM_CTS: ::c_int = 0x20; ++pub const TIOCM_CAR: ::c_int = 0x40; ++pub const TIOCM_CD: ::c_int = 0x40; ++pub const TIOCM_RNG: ::c_int = 0x80; ++pub const TIOCM_RI: ::c_int = 0x80; ++pub const TIOCM_DSR: ::c_int = 0x100; ++pub const TIOCGETP: ::c_int = 0x40067408; ++pub const TIOCSETP: ::c_int = 0x80067409; ++pub const TIOCSETN: ::c_int = 0x8006740a; ++pub const TIOCEXCL: ::c_int = 0x2000740d; ++pub const TIOCNXCL: ::c_int = 0x2000740e; ++pub const TIOCFLUSH: ::c_int = 0x80047410; ++pub const TIOCSETC: ::c_int = 0x80067411; ++pub const TIOCGETC: ::c_int = 0x40067412; ++pub const TANDEM: ::c_int = 0x1; ++pub const CBREAK: ::c_int = 0x2; ++pub const LCASE: ::c_int = 0x4; ++pub const MDMBUF: ::c_int = 0x800000; ++pub const XTABS: ::c_int = 0xc00; ++pub const SIOCADDMULTI: ::c_int = -2145359567; ++pub const SIOCADDRT: ::c_int = -2143784438; ++pub const SIOCDARP: ::c_int = -2142476000; ++pub const SIOCDELMULTI: ::c_int = -2145359566; ++pub const SIOCDELRT: ::c_int = -2143784437; ++pub const SIOCDIFADDR: ::c_int = -2144835303; ++pub const SIOCGARP: ::c_int = -1068734170; ++pub const SIOCGIFADDR: ::c_int = -1071093471; ++pub const SIOCGIFBRDADDR: ::c_int = -1071093469; ++pub const SIOCGIFCONF: ::c_int = -1072666299; ++pub const SIOCGIFDSTADDR: ::c_int = -1071093470; ++pub const SIOCGIFFLAGS: ::c_int = -1071093487; ++pub const SIOCGIFHWADDR: ::c_int = -1068209771; ++pub const SIOCGIFMETRIC: ::c_int = -1071093481; ++pub const SIOCGIFMTU: ::c_int = -1071093418; ++pub const SIOCGIFNETMASK: ::c_int = -1071093467; ++pub const SIOCSARP: ::c_int = -2142476002; ++pub const SIOCSIFADDR: ::c_int = -2144835316; ++pub const SIOCSIFBRDADDR: ::c_int = -2144835309; ++pub const SIOCSIFDSTADDR: ::c_int = -2144835314; ++pub const SIOCSIFFLAGS: ::c_int = -2144835312; ++pub const SIOCSIFMETRIC: ::c_int = -2144835304; ++pub const SIOCSIFMTU: ::c_int = -2144835240; ++pub const SIOCSIFNETMASK: ::c_int = -2144835306; ++pub const TIOCUCNTL: ::c_int = -2147191706; ++pub const TIOCCONS: ::c_int = -2147191710; ++pub const TIOCPKT: ::c_int = -2147191696; ++pub const TIOCPKT_DATA: ::c_int = 0; ++pub const TIOCPKT_FLUSHREAD: ::c_int = 1; ++pub const TIOCPKT_FLUSHWRITE: ::c_int = 2; ++pub const TIOCPKT_NOSTOP: ::c_int = 0x10; ++pub const TIOCPKT_DOSTOP: ::c_int = 0x20; ++pub const TIOCPKT_START: ::c_int = 8; ++pub const TIOCPKT_STOP: ::c_int = 4; ++ ++// sys/ipc.h ++pub const IPC_ALLOC: ::c_int = 0o100000; ++pub const IPC_CREAT: ::c_int = 0o020000; ++pub const IPC_EXCL: ::c_int = 0o002000; ++pub const IPC_NOWAIT: ::c_int = 0o004000; ++pub const IPC_RMID: ::c_int = 0; ++pub const IPC_SET: ::c_int = 101; ++pub const IPC_R: ::c_int = 0o0400; ++pub const IPC_W: ::c_int = 0o0200; ++pub const IPC_O: ::c_int = 0o1000; ++pub const IPC_NOERROR: ::c_int = 0o10000; ++pub const IPC_STAT: ::c_int = 102; ++pub const IPC_PRIVATE: ::key_t = -1; ++pub const SHM_LOCK: ::c_int = 201; ++pub const SHM_UNLOCK: ::c_int = 202; ++ ++// sys/ldr.h ++pub const L_GETINFO: ::c_int = 2; ++pub const L_GETMESSAGE: ::c_int = 1; ++pub const L_GETLIBPATH: ::c_int = 3; ++pub const L_GETXINFO: ::c_int = 8; ++ ++// sys/limits.h ++pub const PATH_MAX: ::c_int = 1023; ++pub const PAGESIZE: ::c_int = 4096; ++pub const IOV_MAX: ::c_int = 16; ++pub const AIO_LISTIO_MAX: ::c_int = 4096; ++pub const PIPE_BUF: usize = 32768; ++pub const OPEN_MAX: ::c_int = 65534; ++pub const MAX_INPUT: ::c_int = 512; ++pub const MAX_CANON: ::c_int = 256; ++pub const ARG_MAX: ::c_int = 1048576; ++pub const BC_BASE_MAX: ::c_int = 99; ++pub const BC_DIM_MAX: ::c_int = 0x800; ++pub const BC_SCALE_MAX: ::c_int = 99; ++pub const BC_STRING_MAX: ::c_int = 0x800; ++pub const CHARCLASS_NAME_MAX: ::c_int = 14; ++pub const CHILD_MAX: ::c_int = 128; ++pub const COLL_WEIGHTS_MAX: ::c_int = 4; ++pub const EXPR_NEST_MAX: ::c_int = 32; ++pub const NZERO: ::c_int = 20; ++ ++// sys/lockf.h ++pub const F_LOCK: ::c_int = 1; ++pub const F_TEST: ::c_int = 3; ++pub const F_TLOCK: ::c_int = 2; ++pub const F_ULOCK: ::c_int = 0; ++ ++// sys/machine.h ++pub const BIG_ENDIAN: ::c_int = 4321; ++pub const LITTLE_ENDIAN: ::c_int = 1234; ++pub const PDP_ENDIAN: ::c_int = 3412; ++ ++// sys/mman.h ++pub const PROT_NONE: ::c_int = 0; ++pub const PROT_READ: ::c_int = 1; ++pub const PROT_WRITE: ::c_int = 2; ++pub const PROT_EXEC: ::c_int = 4; ++pub const MAP_FILE: ::c_int = 0; ++pub const MAP_SHARED: ::c_int = 1; ++pub const MAP_PRIVATE: ::c_int = 2; ++pub const MAP_FIXED: ::c_int = 0x100; ++pub const MAP_ANON: ::c_int = 0x10; ++pub const MAP_ANONYMOUS: ::c_int = 0x10; ++pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; ++pub const MAP_TYPE: ::c_int = 0xf0; ++pub const MCL_CURRENT: ::c_int = 0x100; ++pub const MCL_FUTURE: ::c_int = 0x200; ++pub const MS_SYNC: ::c_int = 0x20; ++pub const MS_ASYNC: ::c_int = 0x10; ++pub const MS_INVALIDATE: ::c_int = 0x40; ++pub const POSIX_MADV_NORMAL: ::c_int = 1; ++pub const POSIX_MADV_RANDOM: ::c_int = 3; ++pub const POSIX_MADV_SEQUENTIAL: ::c_int = 2; ++pub const POSIX_MADV_WILLNEED: ::c_int = 4; ++pub const POSIX_MADV_DONTNEED: ::c_int = 5; ++pub const MADV_NORMAL: ::c_int = 0; ++pub const MADV_RANDOM: ::c_int = 1; ++pub const MADV_SEQUENTIAL: ::c_int = 2; ++pub const MADV_WILLNEED: ::c_int = 3; ++pub const MADV_DONTNEED: ::c_int = 4; ++ ++// sys/mode.h ++pub const S_IFMT: mode_t = 0o170000; ++pub const S_IFREG: mode_t = 0o100000; ++pub const S_IFDIR: mode_t = 0o40000; ++pub const S_IFBLK: mode_t = 0o60000; ++pub const S_IFCHR: mode_t = 0o20000; ++pub const S_IFIFO: mode_t = 0o10000; ++pub const S_IRWXU: mode_t = 0o700; ++pub const S_IRUSR: mode_t = 0o400; ++pub const S_IWUSR: mode_t = 0o200; ++pub const S_IXUSR: mode_t = 0o100; ++pub const S_IRWXG: mode_t = 0o70; ++pub const S_IRGRP: mode_t = 0o40; ++pub const S_IWGRP: mode_t = 0o20; ++pub const S_IXGRP: mode_t = 0o10; ++pub const S_IRWXO: mode_t = 7; ++pub const S_IROTH: mode_t = 4; ++pub const S_IWOTH: mode_t = 2; ++pub const S_IXOTH: mode_t = 1; ++pub const S_IFLNK: mode_t = 0o120000; ++pub const S_IFSOCK: mode_t = 0o140000; ++pub const S_IEXEC: mode_t = 0o100; ++pub const S_IWRITE: mode_t = 0o200; ++pub const S_IREAD: mode_t = 0o400; ++ ++// sys/msg.h ++pub const MSG_NOERROR: ::c_int = 0o10000; ++ ++// sys/m_signal.h ++pub const SIGSTKSZ: ::size_t = 4096; ++pub const MINSIGSTKSZ: ::size_t = 1200; ++ ++// sys/params.h ++pub const MAXPATHLEN: ::c_int = PATH_MAX + 1; ++pub const MAXSYMLINKS: ::c_int = 20; ++pub const MAXHOSTNAMELEN: ::c_int = 256; ++pub const MAXUPRC: ::c_int = 128; ++pub const NGROUPS_MAX: ::c_ulong = 2048; ++pub const NGROUPS: ::c_ulong = NGROUPS_MAX; ++pub const NOFILE: ::c_int = OPEN_MAX; ++ ++// sys/poll.h ++pub const POLLIN: ::c_short = 0x0001; ++pub const POLLPRI: ::c_short = 0x0004; ++pub const POLLOUT: ::c_short = 0x0002; ++pub const POLLERR: ::c_short = 0x4000; ++pub const POLLHUP: ::c_short = 0x2000; ++pub const POLLMSG: ::c_short = 0x0080; ++pub const POLLSYNC: ::c_short = 0x8000; ++pub const POLLNVAL: ::c_short = POLLSYNC; ++pub const POLLNORM: ::c_short = POLLIN; ++pub const POLLRDNORM: ::c_short = 0x0010; ++pub const POLLWRNORM: ::c_short = POLLOUT; ++pub const POLLRDBAND: ::c_short = 0x0020; ++pub const POLLWRBAND: ::c_short = 0x0040; ++ ++// sys/pollset.h ++pub const PS_ADD: ::c_uchar = 0; ++pub const PS_MOD: ::c_uchar = 1; ++pub const PS_DELETE: ::c_uchar = 2; ++pub const PS_REPLACE: ::c_uchar = 3; ++ ++// sys/ptrace.h ++pub const PT_TRACE_ME: ::c_int = 0; ++pub const PT_READ_I: ::c_int = 1; ++pub const PT_READ_D: ::c_int = 2; ++pub const PT_WRITE_I: ::c_int = 4; ++pub const PT_WRITE_D: ::c_int = 5; ++pub const PT_CONTINUE: ::c_int = 7; ++pub const PT_KILL: ::c_int = 8; ++pub const PT_STEP: ::c_int = 9; ++pub const PT_READ_GPR: ::c_int = 11; ++pub const PT_READ_FPR: ::c_int = 12; ++pub const PT_WRITE_GPR: ::c_int = 14; ++pub const PT_WRITE_FPR: ::c_int = 15; ++pub const PT_READ_BLOCK: ::c_int = 17; ++pub const PT_WRITE_BLOCK: ::c_int = 19; ++pub const PT_ATTACH: ::c_int = 30; ++pub const PT_DETACH: ::c_int = 31; ++pub const PT_REGSET: ::c_int = 32; ++pub const PT_REATT: ::c_int = 33; ++pub const PT_LDINFO: ::c_int = 34; ++pub const PT_MULTI: ::c_int = 35; ++pub const PT_NEXT: ::c_int = 36; ++pub const PT_SET: ::c_int = 37; ++pub const PT_CLEAR: ::c_int = 38; ++pub const PT_LDXINFO: ::c_int = 39; ++pub const PT_QUERY: ::c_int = 40; ++pub const PT_WATCH: ::c_int = 41; ++pub const PTT_CONTINUE: ::c_int = 50; ++pub const PTT_STEP: ::c_int = 51; ++pub const PTT_READ_SPRS: ::c_int = 52; ++pub const PTT_WRITE_SPRS: ::c_int = 53; ++pub const PTT_READ_GPRS: ::c_int = 54; ++pub const PTT_WRITE_GPRS: ::c_int = 55; ++pub const PTT_READ_FPRS: ::c_int = 56; ++pub const PTT_WRITE_FPRS: ::c_int = 57; ++pub const PTT_READ_VEC: ::c_int = 58; ++pub const PTT_WRITE_VEC: ::c_int = 59; ++pub const PTT_WATCH: ::c_int = 60; ++pub const PTT_SET_TRAP: ::c_int = 61; ++pub const PTT_CLEAR_TRAP: ::c_int = 62; ++pub const PTT_READ_UKEYSET: ::c_int = 63; ++pub const PT_GET_UKEY: ::c_int = 64; ++pub const PTT_READ_FPSCR_HI: ::c_int = 65; ++pub const PTT_WRITE_FPSCR_HI: ::c_int = 66; ++pub const PTT_READ_VSX: ::c_int = 67; ++pub const PTT_WRITE_VSX: ::c_int = 68; ++pub const PTT_READ_TM: ::c_int = 69; ++pub const PTRACE_ATTACH: ::c_int = 14; ++pub const PTRACE_CONT: ::c_int = 7; ++pub const PTRACE_DETACH: ::c_int = 15; ++pub const PTRACE_GETFPREGS: ::c_int = 12; ++pub const PTRACE_GETREGS: ::c_int = 10; ++pub const PTRACE_KILL: ::c_int = 8; ++pub const PTRACE_PEEKDATA: ::c_int = 2; ++pub const PTRACE_PEEKTEXT: ::c_int = 1; ++pub const PTRACE_PEEKUSER: ::c_int = 3; ++pub const PTRACE_POKEDATA: ::c_int = 5; ++pub const PTRACE_POKETEXT: ::c_int = 4; ++pub const PTRACE_POKEUSER: ::c_int = 6; ++pub const PTRACE_SETFPREGS: ::c_int = 13; ++pub const PTRACE_SETREGS: ::c_int = 11; ++pub const PTRACE_SINGLESTEP: ::c_int = 9; ++pub const PTRACE_SYSCALL: ::c_int = 16; ++pub const PTRACE_TRACEME: ::c_int = 0; ++ ++// sys/resource.h ++pub const RLIMIT_CPU: ::c_int = 0; ++pub const RLIMIT_FSIZE: ::c_int = 1; ++pub const RLIMIT_DATA: ::c_int = 2; ++pub const RLIMIT_STACK: ::c_int = 3; ++pub const RLIMIT_CORE: ::c_int = 4; ++pub const RLIMIT_RSS: ::c_int = 5; ++pub const RLIMIT_AS: ::c_int = 6; ++pub const RLIMIT_NOFILE: ::c_int = 7; ++pub const RLIMIT_THREADS: ::c_int = 8; ++pub const RLIMIT_NPROC: ::c_int = 9; ++pub const RUSAGE_SELF: ::c_int = 0; ++pub const RUSAGE_CHILDREN: ::c_int = -1; ++pub const PRIO_PROCESS: ::c_int = 0; ++pub const PRIO_PGRP: ::c_int = 1; ++pub const PRIO_USER: ::c_int = 2; ++pub const RUSAGE_THREAD: ::c_int = 1; ++pub const RLIM_SAVED_MAX: ::c_ulong = RLIM_INFINITY - 1; ++pub const RLIM_SAVED_CUR: ::c_ulong = RLIM_INFINITY - 2; ++pub const RLIM_NLIMITS: ::c_int = 10; ++ ++// sys/sched.h ++pub const SCHED_OTHER: ::c_int = 0; ++pub const SCHED_FIFO: ::c_int = 1; ++pub const SCHED_RR: ::c_int = 2; ++pub const SCHED_LOCAL: ::c_int = 3; ++pub const SCHED_GLOBAL: ::c_int = 4; ++pub const SCHED_FIFO2: ::c_int = 5; ++pub const SCHED_FIFO3: ::c_int = 6; ++pub const SCHED_FIFO4: ::c_int = 7; ++ ++// sys/sem.h ++pub const SEM_UNDO: ::c_int = 0o10000; ++pub const GETNCNT: ::c_int = 3; ++pub const GETPID: ::c_int = 4; ++pub const GETVAL: ::c_int = 5; ++pub const GETALL: ::c_int = 6; ++pub const GETZCNT: ::c_int = 7; ++pub const SETVAL: ::c_int = 8; ++pub const SETALL: ::c_int = 9; ++ ++// sys/shm.h ++pub const SHMLBA: ::c_int = 0x10000000; ++pub const SHMLBA_EXTSHM: ::c_int = 0x1000; ++pub const SHM_SHMAT: ::c_int = 0x80000000; ++pub const SHM_RDONLY: ::c_int = 0o10000; ++pub const SHM_RND: ::c_int = 0o20000; ++pub const SHM_PIN: ::c_int = 0o4000; ++pub const SHM_LGPAGE: ::c_int = 0o20000000000; ++pub const SHM_MAP: ::c_int = 0o4000; ++pub const SHM_FMAP: ::c_int = 0o2000; ++pub const SHM_COPY: ::c_int = 0o40000; ++pub const SHM_CLEAR: ::c_int = 0; ++pub const SHM_HGSEG: ::c_int = 0o10000000000; ++pub const SHM_R: ::c_int = IPC_R; ++pub const SHM_W: ::c_int = IPC_W; ++pub const SHM_DEST: ::c_int = 0o2000; ++ ++// sys/signal.h ++pub const SA_ONSTACK: ::c_int = 0x00000001; ++pub const SA_RESETHAND: ::c_int = 0x00000002; ++pub const SA_RESTART: ::c_int = 0x00000008; ++pub const SA_SIGINFO: ::c_int = 0x00000100; ++pub const SA_NODEFER: ::c_int = 0x00000200; ++pub const SA_NOCLDWAIT: ::c_int = 0x00000400; ++pub const SA_NOCLDSTOP: ::c_int = 0x00000004; ++pub const SS_ONSTACK: ::c_int = 0x00000001; ++pub const SS_DISABLE: ::c_int = 0x00000002; ++pub const SIGCHLD: ::c_int = 20; ++pub const SIGBUS: ::c_int = 10; ++pub const SIG_BLOCK: ::c_int = 0; ++pub const SIG_UNBLOCK: ::c_int = 1; ++pub const SIG_SETMASK: ::c_int = 2; ++pub const SIGEV_NONE: ::c_int = 1; ++pub const SIGEV_SIGNAL: ::c_int = 2; ++pub const SIGEV_THREAD: ::c_int = 3; ++pub const SIGHUP: ::c_int = 1; ++pub const SIGINT: ::c_int = 2; ++pub const SIGQUIT: ::c_int = 3; ++pub const SIGILL: ::c_int = 4; ++pub const SIGABRT: ::c_int = 6; ++pub const SIGEMT: ::c_int = 7; ++pub const SIGFPE: ::c_int = 8; ++pub const SIGKILL: ::c_int = 9; ++pub const SIGSEGV: ::c_int = 11; ++pub const SIGSYS: ::c_int = 12; ++pub const SIGPIPE: ::c_int = 13; ++pub const SIGALRM: ::c_int = 14; ++pub const SIGTERM: ::c_int = 15; ++pub const SIGUSR1: ::c_int = 30; ++pub const SIGUSR2: ::c_int = 31; ++pub const SIGPWR: ::c_int = 29; ++pub const SIGWINCH: ::c_int = 28; ++pub const SIGURG: ::c_int = 16; ++pub const SIGPOLL: ::c_int = SIGIO; ++pub const SIGIO: ::c_int = 23; ++pub const SIGSTOP: ::c_int = 17; ++pub const SIGTSTP: ::c_int = 18; ++pub const SIGCONT: ::c_int = 19; ++pub const SIGTTIN: ::c_int = 21; ++pub const SIGTTOU: ::c_int = 22; ++pub const SIGVTALRM: ::c_int = 34; ++pub const SIGPROF: ::c_int = 32; ++pub const SIGXCPU: ::c_int = 24; ++pub const SIGXFSZ: ::c_int = 25; ++pub const SIGTRAP: ::c_int = 5; ++pub const SIGCLD: ::c_int = 20; ++pub const SIGRTMAX: ::c_int = 57; ++pub const SIGRTMIN: ::c_int = 50; ++pub const SI_USER: ::c_int = 0; ++pub const SI_UNDEFINED: ::c_int = 8; ++pub const SI_EMPTY: ::c_int = 9; ++pub const BUS_ADRALN: ::c_int = 1; ++pub const BUS_ADRERR: ::c_int = 2; ++pub const BUS_OBJERR: ::c_int = 3; ++pub const BUS_UEGARD: ::c_int = 4; ++pub const CLD_EXITED: ::c_int = 10; ++pub const CLD_KILLED: ::c_int = 11; ++pub const CLD_DUMPED: ::c_int = 12; ++pub const CLD_TRAPPED: ::c_int = 13; ++pub const CLD_STOPPED: ::c_int = 14; ++pub const CLD_CONTINUED: ::c_int = 15; ++pub const FPE_INTDIV: ::c_int = 20; ++pub const FPE_INTOVF: ::c_int = 21; ++pub const FPE_FLTDIV: ::c_int = 22; ++pub const FPE_FLTOVF: ::c_int = 23; ++pub const FPE_FLTUND: ::c_int = 24; ++pub const FPE_FLTRES: ::c_int = 25; ++pub const FPE_FLTINV: ::c_int = 26; ++pub const FPE_FLTSUB: ::c_int = 27; ++pub const ILL_ILLOPC: ::c_int = 30; ++pub const ILL_ILLOPN: ::c_int = 31; ++pub const ILL_ILLADR: ::c_int = 32; ++pub const ILL_ILLTRP: ::c_int = 33; ++pub const ILL_PRVOPC: ::c_int = 34; ++pub const ILL_PRVREG: ::c_int = 35; ++pub const ILL_COPROC: ::c_int = 36; ++pub const ILL_BADSTK: ::c_int = 37; ++pub const ILL_TMBADTHING: ::c_int = 38; ++pub const POLL_IN: ::c_int = 40; ++pub const POLL_OUT: ::c_int = 41; ++pub const POLL_MSG: ::c_int = -3; ++pub const POLL_ERR: ::c_int = 43; ++pub const POLL_PRI: ::c_int = 44; ++pub const POLL_HUP: ::c_int = 45; ++pub const SEGV_MAPERR: ::c_int = 50; ++pub const SEGV_ACCERR: ::c_int = 51; ++pub const SEGV_KEYERR: ::c_int = 52; ++pub const TRAP_BRKPT: ::c_int = 60; ++pub const TRAP_TRACE: ::c_int = 61; ++pub const SI_QUEUE: ::c_int = 71; ++pub const SI_TIMER: ::c_int = 72; ++pub const SI_ASYNCIO: ::c_int = 73; ++pub const SI_MESGQ: ::c_int = 74; ++ ++// sys/socket.h ++pub const AF_UNSPEC: ::c_int = 0; ++pub const AF_UNIX: ::c_int = 1; ++pub const AF_INET: ::c_int = 2; ++pub const AF_IMPLINK: ::c_int = 3; ++pub const AF_PUP: ::c_int = 4; ++pub const AF_CHAOS: ::c_int = 5; ++pub const AF_NS: ::c_int = 6; ++pub const AF_ECMA: ::c_int = 8; ++pub const AF_DATAKIT: ::c_int = 9; ++pub const AF_CCITT: ::c_int = 10; ++pub const AF_SNA: ::c_int = 11; ++pub const AF_DECnet: ::c_int = 12; ++pub const AF_DLI: ::c_int = 13; ++pub const AF_LAT: ::c_int = 14; ++pub const SO_TIMESTAMPNS: ::c_int = 0x100a; ++pub const SOMAXCONN: ::c_int = 1024; ++pub const AF_LOCAL: ::c_int = AF_UNIX; ++pub const UIO_MAXIOV: ::c_int = 1024; ++pub const pseudo_AF_XTP: ::c_int = 19; ++pub const AF_HYLINK: ::c_int = 15; ++pub const AF_APPLETALK: ::c_int = 16; ++pub const AF_ISO: ::c_int = 7; ++pub const AF_OSI: ::c_int = AF_ISO; ++pub const AF_ROUTE: ::c_int = 17; ++pub const AF_LINK: ::c_int = 18; ++pub const AF_INET6: ::c_int = 24; ++pub const AF_INTF: ::c_int = 20; ++pub const AF_RIF: ::c_int = 21; ++pub const AF_NDD: ::c_int = 23; ++pub const AF_MAX: ::c_int = 30; ++pub const PF_UNSPEC: ::c_int = AF_UNSPEC; ++pub const PF_UNIX: ::c_int = AF_UNIX; ++pub const PF_INET: ::c_int = AF_INET; ++pub const PF_IMPLINK: ::c_int = AF_IMPLINK; ++pub const PF_PUP: ::c_int = AF_PUP; ++pub const PF_CHAOS: ::c_int = AF_CHAOS; ++pub const PF_NS: ::c_int = AF_NS; ++pub const PF_ISO: ::c_int = AF_ISO; ++pub const PF_OSI: ::c_int = AF_ISO; ++pub const PF_ECMA: ::c_int = AF_ECMA; ++pub const PF_DATAKIT: ::c_int = AF_DATAKIT; ++pub const PF_CCITT: ::c_int = AF_CCITT; ++pub const PF_SNA: ::c_int = AF_SNA; ++pub const PF_DECnet: ::c_int = AF_DECnet; ++pub const PF_DLI: ::c_int = AF_DLI; ++pub const PF_LAT: ::c_int = AF_LAT; ++pub const PF_HYLINK: ::c_int = AF_HYLINK; ++pub const PF_APPLETALK: ::c_int = AF_APPLETALK; ++pub const PF_ROUTE: ::c_int = AF_ROUTE; ++pub const PF_LINK: ::c_int = AF_LINK; ++pub const PF_XTP: ::c_int = 19; ++pub const PF_RIF: ::c_int = AF_RIF; ++pub const PF_INTF: ::c_int = AF_INTF; ++pub const PF_NDD: ::c_int = AF_NDD; ++pub const PF_INET6: ::c_int = AF_INET6; ++pub const PF_MAX: ::c_int = AF_MAX; ++pub const SF_CLOSE: ::c_int = 1; ++pub const SF_REUSE: ::c_int = 2; ++pub const SF_DONT_CACHE: ::c_int = 4; ++pub const SF_SYNC_CACHE: ::c_int = 8; ++pub const SOCK_DGRAM: ::c_int = 2; ++pub const SOCK_STREAM: ::c_int = 1; ++pub const SOCK_RAW: ::c_int = 3; ++pub const SOCK_RDM: ::c_int = 4; ++pub const SOCK_SEQPACKET: ::c_int = 5; ++pub const SOL_SOCKET: ::c_int = 0xffff; ++pub const SO_DEBUG: ::c_int = 0x0001; ++pub const SO_ACCEPTCONN: ::c_int = 0x0002; ++pub const SO_REUSEADDR: ::c_int = 0x0004; ++pub const SO_KEEPALIVE: ::c_int = 0x0008; ++pub const SO_DONTROUTE: ::c_int = 0x0010; ++pub const SO_BROADCAST: ::c_int = 0x0020; ++pub const SO_USELOOPBACK: ::c_int = 0x0040; ++pub const SO_LINGER: ::c_int = 0x0080; ++pub const SO_OOBINLINE: ::c_int = 0x0100; ++pub const SO_REUSEPORT: ::c_int = 0x0200; ++pub const SO_USE_IFBUFS: ::c_int = 0x0400; ++pub const SO_CKSUMRECV: ::c_int = 0x0800; ++pub const SO_NOREUSEADDR: ::c_int = 0x1000; ++pub const SO_KERNACCEPT: ::c_int = 0x2000; ++pub const SO_NOMULTIPATH: ::c_int = 0x4000; ++pub const SO_AUDIT: ::c_int = 0x8000; ++pub const SO_SNDBUF: ::c_int = 0x1001; ++pub const SO_RCVBUF: ::c_int = 0x1002; ++pub const SO_SNDLOWAT: ::c_int = 0x1003; ++pub const SO_RCVLOWAT: ::c_int = 0x1004; ++pub const SO_SNDTIMEO: ::c_int = 0x1005; ++pub const SO_RCVTIMEO: ::c_int = 0x1006; ++pub const SO_ERROR: ::c_int = 0x1007; ++pub const SO_TYPE: ::c_int = 0x1008; ++pub const SCM_RIGHTS: ::c_int = 0x01; ++pub const MSG_OOB: ::c_int = 0x1; ++pub const MSG_PEEK: ::c_int = 0x2; ++pub const MSG_DONTROUTE: ::c_int = 0x4; ++pub const MSG_EOR: ::c_int = 0x8; ++pub const MSG_TRUNC: ::c_int = 0x10; ++pub const MSG_CTRUNC: ::c_int = 0x20; ++pub const MSG_WAITALL: ::c_int = 0x40; ++pub const MSG_MPEG2: ::c_int = 0x80; ++pub const MSG_NOSIGNAL: ::c_int = 0x100; ++pub const MSG_WAITFORONE: ::c_int = 0x200; ++pub const MSG_ARGEXT: ::c_int = 0x400; ++pub const MSG_NONBLOCK: ::c_int = 0x4000; ++pub const MSG_COMPAT: ::c_int = 0x8000; ++pub const MSG_MAXIOVLEN: ::c_int = 16; ++pub const SHUT_RD: ::c_int = 0; ++pub const SHUT_WR: ::c_int = 1; ++pub const SHUT_RDWR: ::c_int = 2; ++ ++// sys/stat.h ++pub const UTIME_NOW: ::c_int = -2; ++pub const UTIME_OMIT: ::c_int = -3; ++ ++// sys/statvfs.h ++pub const ST_RDONLY: ::c_ulong = 0x0001; ++pub const ST_NOSUID: ::c_ulong = 0x0040; ++pub const ST_NODEV: ::c_ulong = 0x0080; ++ ++// sys/stropts.h ++pub const I_NREAD: ::c_int = 0x20005301; ++pub const I_PUSH: ::c_int = 0x20005302; ++pub const I_POP: ::c_int = 0x20005303; ++pub const I_LOOK: ::c_int = 0x20005304; ++pub const I_FLUSH: ::c_int = 0x20005305; ++pub const I_SRDOPT: ::c_int = 0x20005306; ++pub const I_GRDOPT: ::c_int = 0x20005307; ++pub const I_STR: ::c_int = 0x20005308; ++pub const I_SETSIG: ::c_int = 0x20005309; ++pub const I_GETSIG: ::c_int = 0x2000530a; ++pub const I_FIND: ::c_int = 0x2000530b; ++pub const I_LINK: ::c_int = 0x2000530c; ++pub const I_UNLINK: ::c_int = 0x2000530d; ++pub const I_PEEK: ::c_int = 0x2000530f; ++pub const I_FDINSERT: ::c_int = 0x20005310; ++pub const I_SENDFD: ::c_int = 0x20005311; ++pub const I_RECVFD: ::c_int = 0x20005312; ++pub const I_SWROPT: ::c_int = 0x20005314; ++pub const I_GWROPT: ::c_int = 0x20005315; ++pub const I_LIST: ::c_int = 0x20005316; ++pub const I_PLINK: ::c_int = 0x2000531d; ++pub const I_PUNLINK: ::c_int = 0x2000531e; ++pub const I_FLUSHBAND: ::c_int = 0x20005313; ++pub const I_CKBAND: ::c_int = 0x20005318; ++pub const I_GETBAND: ::c_int = 0x20005319; ++pub const I_ATMARK: ::c_int = 0x20005317; ++pub const I_SETCLTIME: ::c_int = 0x2000531b; ++pub const I_GETCLTIME: ::c_int = 0x2000531c; ++pub const I_CANPUT: ::c_int = 0x2000531a; ++ ++// sys/syslog.h ++pub const LOG_CRON: ::c_int = 9 << 3; ++pub const LOG_AUTHPRIV: ::c_int = 10 << 3; ++pub const LOG_NFACILITIES: ::c_int = 24; ++pub const LOG_PERROR: ::c_int = 0x20; ++ ++// sys/systemcfg.h ++pub const SC_ARCH: ::c_int = 1; ++pub const SC_IMPL: ::c_int = 2; ++pub const SC_VERS: ::c_int = 3; ++pub const SC_WIDTH: ::c_int = 4; ++pub const SC_NCPUS: ::c_int = 5; ++pub const SC_L1C_ATTR: ::c_int = 6; ++pub const SC_L1C_ISZ: ::c_int = 7; ++pub const SC_L1C_DSZ: ::c_int = 8; ++pub const SC_L1C_ICA: ::c_int = 9; ++pub const SC_L1C_DCA: ::c_int = 10; ++pub const SC_L1C_IBS: ::c_int = 11; ++pub const SC_L1C_DBS: ::c_int = 12; ++pub const SC_L1C_ILS: ::c_int = 13; ++pub const SC_L1C_DLS: ::c_int = 14; ++pub const SC_L2C_SZ: ::c_int = 15; ++pub const SC_L2C_AS: ::c_int = 16; ++pub const SC_TLB_ATTR: ::c_int = 17; ++pub const SC_ITLB_SZ: ::c_int = 18; ++pub const SC_DTLB_SZ: ::c_int = 19; ++pub const SC_ITLB_ATT: ::c_int = 20; ++pub const SC_DTLB_ATT: ::c_int = 21; ++pub const SC_RESRV_SZ: ::c_int = 22; ++pub const SC_PRI_LC: ::c_int = 23; ++pub const SC_PRO_LC: ::c_int = 24; ++pub const SC_RTC_TYPE: ::c_int = 25; ++pub const SC_VIRT_AL: ::c_int = 26; ++pub const SC_CAC_CONG: ::c_int = 27; ++pub const SC_MOD_ARCH: ::c_int = 28; ++pub const SC_MOD_IMPL: ::c_int = 29; ++pub const SC_XINT: ::c_int = 30; ++pub const SC_XFRAC: ::c_int = 31; ++pub const SC_KRN_ATTR: ::c_int = 32; ++pub const SC_PHYSMEM: ::c_int = 33; ++pub const SC_SLB_ATTR: ::c_int = 34; ++pub const SC_SLB_SZ: ::c_int = 35; ++pub const SC_MAX_NCPUS: ::c_int = 37; ++pub const SC_MAX_REALADDR: ::c_int = 38; ++pub const SC_ORIG_ENT_CAP: ::c_int = 39; ++pub const SC_ENT_CAP: ::c_int = 40; ++pub const SC_DISP_WHE: ::c_int = 41; ++pub const SC_CAPINC: ::c_int = 42; ++pub const SC_VCAPW: ::c_int = 43; ++pub const SC_SPLP_STAT: ::c_int = 44; ++pub const SC_SMT_STAT: ::c_int = 45; ++pub const SC_SMT_TC: ::c_int = 46; ++pub const SC_VMX_VER: ::c_int = 47; ++pub const SC_LMB_SZ: ::c_int = 48; ++pub const SC_MAX_XCPU: ::c_int = 49; ++pub const SC_EC_LVL: ::c_int = 50; ++pub const SC_AME_STAT: ::c_int = 51; ++pub const SC_ECO_STAT: ::c_int = 52; ++pub const SC_DFP_VER: ::c_int = 53; ++pub const SC_VRM_STAT: ::c_int = 54; ++pub const SC_PHYS_IMP: ::c_int = 55; ++pub const SC_PHYS_VER: ::c_int = 56; ++pub const SC_SPCM_STATUS: ::c_int = 57; ++pub const SC_SPCM_MAX: ::c_int = 58; ++pub const SC_TM_VER: ::c_int = 59; ++pub const SC_NX_CAP: ::c_int = 60; ++pub const SC_PKS_STATE: ::c_int = 61; ++pub const SC_MMA_VER: ::c_int = 62; ++pub const POWER_RS: ::c_int = 1; ++pub const POWER_PC: ::c_int = 2; ++pub const IA64: ::c_int = 3; ++pub const POWER_RS1: ::c_int = 0x1; ++pub const POWER_RSC: ::c_int = 0x2; ++pub const POWER_RS2: ::c_int = 0x4; ++pub const POWER_601: ::c_int = 0x8; ++pub const POWER_604: ::c_int = 0x10; ++pub const POWER_603: ::c_int = 0x20; ++pub const POWER_620: ::c_int = 0x40; ++pub const POWER_630: ::c_int = 0x80; ++pub const POWER_A35: ::c_int = 0x100; ++pub const POWER_RS64II: ::c_int = 0x200; ++pub const POWER_RS64III: ::c_int = 0x400; ++pub const POWER_4: ::c_int = 0x800; ++pub const POWER_RS64IV: ::c_int = POWER_4; ++pub const POWER_MPC7450: ::c_int = 0x1000; ++pub const POWER_5: ::c_int = 0x2000; ++pub const POWER_6: ::c_int = 0x4000; ++pub const POWER_7: ::c_int = 0x8000; ++pub const POWER_8: ::c_int = 0x10000; ++pub const POWER_9: ::c_int = 0x20000; ++ ++// sys/time.h ++pub const FD_SETSIZE: usize = 65534; ++pub const TIMEOFDAY: ::c_int = 9; ++pub const CLOCK_REALTIME: ::clockid_t = TIMEOFDAY as clockid_t; ++pub const CLOCK_MONOTONIC: ::clockid_t = 10; ++pub const TIMER_ABSTIME: ::c_int = 999; ++pub const ITIMER_REAL: ::c_int = 0; ++pub const ITIMER_VIRTUAL: ::c_int = 1; ++pub const ITIMER_PROF: ::c_int = 2; ++pub const ITIMER_VIRT: ::c_int = 3; ++pub const ITIMER_REAL1: ::c_int = 20; ++pub const ITIMER_REAL_TH: ::c_int = ITIMER_REAL1; ++pub const DST_AUST: ::c_int = 2; ++pub const DST_CAN: ::c_int = 6; ++pub const DST_EET: ::c_int = 5; ++pub const DST_MET: ::c_int = 4; ++pub const DST_NONE: ::c_int = 0; ++pub const DST_USA: ::c_int = 1; ++pub const DST_WET: ::c_int = 3; ++ ++// sys/termio.h ++pub const CSTART: ::tcflag_t = 0o21; ++pub const CSTOP: ::tcflag_t = 0o23; ++pub const TCGETA: ::c_int = TIOC | 5; ++pub const TCSETA: ::c_int = TIOC | 6; ++pub const TCSETAW: ::c_int = TIOC | 7; ++pub const TCSETAF: ::c_int = TIOC | 8; ++pub const TCSBRK: ::c_int = TIOC | 9; ++pub const TCXONC: ::c_int = TIOC | 11; ++pub const TCFLSH: ::c_int = TIOC | 12; ++pub const TCGETS: ::c_int = TIOC | 1; ++pub const TCSETS: ::c_int = TIOC | 2; ++pub const TCSANOW: ::c_int = 0; ++pub const TCSETSW: ::c_int = TIOC | 3; ++pub const TCSADRAIN: ::c_int = 1; ++pub const TCSETSF: ::c_int = TIOC | 4; ++pub const TCSAFLUSH: ::c_int = 2; ++pub const TCIFLUSH: ::c_int = 0; ++pub const TCOFLUSH: ::c_int = 1; ++pub const TCIOFLUSH: ::c_int = 2; ++pub const TCOOFF: ::c_int = 0; ++pub const TCOON: ::c_int = 1; ++pub const TCIOFF: ::c_int = 2; ++pub const TCION: ::c_int = 3; ++pub const TIOC: ::c_int = 0x5400; ++pub const TIOCGWINSZ: ::c_int = 0x40087468; ++pub const TIOCSWINSZ: ::c_int = 0x80087467; ++pub const TIOCLBIS: ::c_int = 0x8004747f; ++pub const TIOCLBIC: ::c_int = 0x8004747e; ++pub const TIOCLSET: ::c_int = 0x8004747d; ++pub const TIOCLGET: ::c_int = 0x4004747c; ++pub const TIOCSBRK: ::c_int = 0x2000747b; ++pub const TIOCCBRK: ::c_int = 0x2000747a; ++pub const TIOCSDTR: ::c_int = 0x20007479; ++pub const TIOCCDTR: ::c_int = 0x20007478; ++pub const TIOCSLTC: ::c_int = 0x80067475; ++pub const TIOCGLTC: ::c_int = 0x40067474; ++pub const TIOCOUTQ: ::c_int = 0x40047473; ++pub const TIOCNOTTY: ::c_int = 0x20007471; ++pub const TIOCSTOP: ::c_int = 0x2000746f; ++pub const TIOCSTART: ::c_int = 0x2000746e; ++pub const TIOCGPGRP: ::c_int = 0x40047477; ++pub const TIOCSPGRP: ::c_int = 0x80047476; ++pub const TIOCGSID: ::c_int = 0x40047448; ++pub const TIOCSTI: ::c_int = 0x80017472; ++pub const TIOCMSET: ::c_int = 0x8004746d; ++pub const TIOCMBIS: ::c_int = 0x8004746c; ++pub const TIOCMBIC: ::c_int = 0x8004746b; ++pub const TIOCMGET: ::c_int = 0x4004746a; ++pub const TIOCREMOTE: ::c_int = 0x80047469; ++ ++// sys/user.h ++pub const MAXCOMLEN: ::c_int = 32; ++pub const UF_SYSTEM: ::c_int = 0x1000; ++ ++// sys/vattr.h ++pub const AT_FLAGS: ::c_int = 0x80; ++pub const AT_GID: ::c_int = 8; ++pub const AT_UID: ::c_int = 4; ++ ++// sys/wait.h ++pub const P_ALL: ::c_int = 0; ++pub const P_PID: ::c_int = 1; ++pub const P_PGID: ::c_int = 2; ++pub const WNOHANG: ::c_int = 0x1; ++pub const WUNTRACED: ::c_int = 0x2; ++pub const WEXITED: ::c_int = 0x04; ++pub const WCONTINUED: ::c_int = 0x01000000; ++pub const WNOWAIT: ::c_int = 0x10; ++pub const WSTOPPED: ::c_int = _W_STOPPED; ++pub const _W_STOPPED: ::c_int = 0x00000040; ++pub const _W_SLWTED: ::c_int = 0x0000007c; ++pub const _W_SEWTED: ::c_int = 0x0000007d; ++pub const _W_SFWTED: ::c_int = 0x0000007e; ++pub const _W_STRC: ::c_int = 0x0000007f; ++ ++// termios.h ++pub const NCCS: usize = 16; ++pub const OLCUC: ::tcflag_t = 2; ++pub const CSIZE: ::tcflag_t = 0x00000030; ++pub const CS5: ::tcflag_t = 0x00000000; ++pub const CS6: ::tcflag_t = 0x00000010; ++pub const CS7: ::tcflag_t = 0x00000020; ++pub const CS8: ::tcflag_t = 0x00000030; ++pub const CSTOPB: ::tcflag_t = 0x00000040; ++pub const ECHO: ::tcflag_t = 0x20000; ++pub const ECHOE: ::tcflag_t = 0x00000010; ++pub const ECHOK: ::tcflag_t = 0x00000020; ++pub const ECHONL: ::tcflag_t = 0x00000040; ++pub const ECHOCTL: ::tcflag_t = 0x00020000; ++pub const ECHOPRT: ::tcflag_t = 0x00040000; ++pub const ECHOKE: ::tcflag_t = 0x00080000; ++pub const IGNBRK: ::tcflag_t = 0x00000001; ++pub const BRKINT: ::tcflag_t = 0x00000002; ++pub const IGNPAR: ::tcflag_t = 0x00000004; ++pub const PARMRK: ::tcflag_t = 0x00000008; ++pub const INPCK: ::tcflag_t = 0x00000010; ++pub const ISTRIP: ::tcflag_t = 0x00000020; ++pub const INLCR: ::tcflag_t = 0x00000040; ++pub const IGNCR: ::tcflag_t = 0x00000080; ++pub const ICRNL: ::tcflag_t = 0x00000100; ++pub const IXON: ::tcflag_t = 0x0001; ++pub const IXOFF: ::tcflag_t = 0x00000400; ++pub const IXANY: ::tcflag_t = 0x00001000; ++pub const IMAXBEL: ::tcflag_t = 0x00010000; ++pub const OPOST: ::tcflag_t = 0x00000001; ++pub const ONLCR: ::tcflag_t = 0x00000004; ++pub const OCRNL: ::tcflag_t = 0x00000008; ++pub const ONOCR: ::tcflag_t = 0x00000010; ++pub const ONLRET: ::tcflag_t = 0x00000020; ++pub const CREAD: ::tcflag_t = 0x00000080; ++pub const IEXTEN: ::tcflag_t = 0x00200000; ++pub const TOSTOP: ::tcflag_t = 0x00010000; ++pub const FLUSHO: ::tcflag_t = 0x00100000; ++pub const PENDIN: ::tcflag_t = 0x20000000; ++pub const NOFLSH: ::tcflag_t = 0x00000080; ++pub const VINTR: usize = 0; ++pub const VQUIT: usize = 1; ++pub const VERASE: usize = 2; ++pub const VKILL: usize = 3; ++pub const VEOF: usize = 4; ++pub const VEOL: usize = 5; ++pub const VSTART: usize = 7; ++pub const VSTOP: usize = 8; ++pub const VSUSP: usize = 9; ++pub const VMIN: usize = 4; ++pub const VTIME: usize = 5; ++pub const VEOL2: usize = 6; ++pub const VDSUSP: usize = 10; ++pub const VREPRINT: usize = 11; ++pub const VDISCRD: usize = 12; ++pub const VWERSE: usize = 13; ++pub const VLNEXT: usize = 14; ++pub const B0: ::speed_t = 0x0; ++pub const B50: ::speed_t = 0x1; ++pub const B75: ::speed_t = 0x2; ++pub const B110: ::speed_t = 0x3; ++pub const B134: ::speed_t = 0x4; ++pub const B150: ::speed_t = 0x5; ++pub const B200: ::speed_t = 0x6; ++pub const B300: ::speed_t = 0x7; ++pub const B600: ::speed_t = 0x8; ++pub const B1200: ::speed_t = 0x9; ++pub const B1800: ::speed_t = 0xa; ++pub const B2400: ::speed_t = 0xb; ++pub const B4800: ::speed_t = 0xc; ++pub const B9600: ::speed_t = 0xd; ++pub const B19200: ::speed_t = 0xe; ++pub const B38400: ::speed_t = 0xf; ++pub const EXTA: ::speed_t = B19200; ++pub const EXTB: ::speed_t = B38400; ++pub const IUCLC: ::tcflag_t = 0x00000800; ++pub const OFILL: ::tcflag_t = 0x00000040; ++pub const OFDEL: ::tcflag_t = 0x00000080; ++pub const CRDLY: ::tcflag_t = 0x00000300; ++pub const CR0: ::tcflag_t = 0x00000000; ++pub const CR1: ::tcflag_t = 0x00000100; ++pub const CR2: ::tcflag_t = 0x00000200; ++pub const CR3: ::tcflag_t = 0x00000300; ++pub const TABDLY: ::tcflag_t = 0x00000c00; ++pub const TAB0: ::tcflag_t = 0x00000000; ++pub const TAB1: ::tcflag_t = 0x00000400; ++pub const TAB2: ::tcflag_t = 0x00000800; ++pub const TAB3: ::tcflag_t = 0x00000c00; ++pub const BSDLY: ::tcflag_t = 0x00001000; ++pub const BS0: ::tcflag_t = 0x00000000; ++pub const BS1: ::tcflag_t = 0x00001000; ++pub const FFDLY: ::tcflag_t = 0x00002000; ++pub const FF0: ::tcflag_t = 0x00000000; ++pub const FF1: ::tcflag_t = 0x00002000; ++pub const NLDLY: ::tcflag_t = 0x00004000; ++pub const NL0: ::tcflag_t = 0x00000000; ++pub const NL1: ::tcflag_t = 0x00004000; ++pub const VTDLY: ::tcflag_t = 0x00008000; ++pub const VT0: ::tcflag_t = 0x00000000; ++pub const VT1: ::tcflag_t = 0x00008000; ++pub const OXTABS: ::tcflag_t = 0x00040000; ++pub const ONOEOT: ::tcflag_t = 0x00080000; ++pub const CBAUD: ::tcflag_t = 0x0000000f; ++pub const PARENB: ::tcflag_t = 0x00000100; ++pub const PARODD: ::tcflag_t = 0x00000200; ++pub const HUPCL: ::tcflag_t = 0x00000400; ++pub const CLOCAL: ::tcflag_t = 0x00000800; ++pub const CIBAUD: ::tcflag_t = 0x000f0000; ++pub const IBSHIFT: ::tcflag_t = 16; ++pub const PAREXT: ::tcflag_t = 0x00100000; ++pub const ISIG: ::tcflag_t = 0x00000001; ++pub const ICANON: ::tcflag_t = 0x00000002; ++pub const XCASE: ::tcflag_t = 0x00000004; ++pub const ALTWERASE: ::tcflag_t = 0x00400000; ++ ++// time.h ++pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 11; ++pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 12; ++ ++// unistd.h ++pub const STDIN_FILENO: ::c_int = 0; ++pub const STDOUT_FILENO: ::c_int = 1; ++pub const STDERR_FILENO: ::c_int = 2; ++pub const _POSIX_VDISABLE: ::c_int = 0xff; ++pub const _PC_LINK_MAX: ::c_int = 11; ++pub const _PC_MAX_CANON: ::c_int = 12; ++pub const _PC_MAX_INPUT: ::c_int = 13; ++pub const _PC_NAME_MAX: ::c_int = 14; ++pub const _PC_PATH_MAX: ::c_int = 16; ++pub const _PC_PIPE_BUF: ::c_int = 17; ++pub const _PC_NO_TRUNC: ::c_int = 15; ++pub const _PC_VDISABLE: ::c_int = 18; ++pub const _PC_CHOWN_RESTRICTED: ::c_int = 10; ++pub const _PC_ASYNC_IO: ::c_int = 19; ++pub const _PC_PRIO_IO: ::c_int = 21; ++pub const _PC_SYNC_IO: ::c_int = 20; ++pub const _PC_ALLOC_SIZE_MIN: ::c_int = 26; ++pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 27; ++pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 28; ++pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 29; ++pub const _PC_REC_XFER_ALIGN: ::c_int = 30; ++pub const _PC_SYMLINK_MAX: ::c_int = 25; ++pub const _PC_2_SYMLINKS: ::c_int = 31; ++pub const _PC_TIMESTAMP_RESOLUTION: ::c_int = 32; ++pub const _PC_FILESIZEBITS: ::c_int = 22; ++pub const _SC_ARG_MAX: ::c_int = 0; ++pub const _SC_CHILD_MAX: ::c_int = 1; ++pub const _SC_CLK_TCK: ::c_int = 2; ++pub const _SC_NGROUPS_MAX: ::c_int = 3; ++pub const _SC_OPEN_MAX: ::c_int = 4; ++pub const _SC_JOB_CONTROL: ::c_int = 7; ++pub const _SC_SAVED_IDS: ::c_int = 8; ++pub const _SC_VERSION: ::c_int = 9; ++pub const _SC_PASS_MAX: ::c_int = 45; ++pub const _SC_PAGESIZE: ::c_int = _SC_PAGE_SIZE; ++pub const _SC_PAGE_SIZE: ::c_int = 48; ++pub const _SC_XOPEN_VERSION: ::c_int = 46; ++pub const _SC_NPROCESSORS_CONF: ::c_int = 71; ++pub const _SC_NPROCESSORS_ONLN: ::c_int = 72; ++pub const _SC_STREAM_MAX: ::c_int = 5; ++pub const _SC_TZNAME_MAX: ::c_int = 6; ++pub const _SC_AIO_LISTIO_MAX: ::c_int = 75; ++pub const _SC_AIO_MAX: ::c_int = 76; ++pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 77; ++pub const _SC_ASYNCHRONOUS_IO: ::c_int = 78; ++pub const _SC_DELAYTIMER_MAX: ::c_int = 79; ++pub const _SC_FSYNC: ::c_int = 80; ++pub const _SC_MAPPED_FILES: ::c_int = 84; ++pub const _SC_MEMLOCK: ::c_int = 85; ++pub const _SC_MEMLOCK_RANGE: ::c_int = 86; ++pub const _SC_MEMORY_PROTECTION: ::c_int = 87; ++pub const _SC_MESSAGE_PASSING: ::c_int = 88; ++pub const _SC_MQ_OPEN_MAX: ::c_int = 89; ++pub const _SC_MQ_PRIO_MAX: ::c_int = 90; ++pub const _SC_PRIORITIZED_IO: ::c_int = 91; ++pub const _SC_PRIORITY_SCHEDULING: ::c_int = 92; ++pub const _SC_REALTIME_SIGNALS: ::c_int = 93; ++pub const _SC_RTSIG_MAX: ::c_int = 94; ++pub const _SC_SEMAPHORES: ::c_int = 95; ++pub const _SC_SEM_NSEMS_MAX: ::c_int = 96; ++pub const _SC_SEM_VALUE_MAX: ::c_int = 97; ++pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 98; ++pub const _SC_SIGQUEUE_MAX: ::c_int = 99; ++pub const _SC_SYNCHRONIZED_IO: ::c_int = 100; ++pub const _SC_TIMERS: ::c_int = 102; ++pub const _SC_TIMER_MAX: ::c_int = 103; ++pub const _SC_2_C_BIND: ::c_int = 51; ++pub const _SC_2_C_DEV: ::c_int = 32; ++pub const _SC_2_C_VERSION: ::c_int = 52; ++pub const _SC_2_FORT_DEV: ::c_int = 33; ++pub const _SC_2_FORT_RUN: ::c_int = 34; ++pub const _SC_2_LOCALEDEF: ::c_int = 35; ++pub const _SC_2_SW_DEV: ::c_int = 36; ++pub const _SC_2_UPE: ::c_int = 53; ++pub const _SC_2_VERSION: ::c_int = 31; ++pub const _SC_BC_BASE_MAX: ::c_int = 23; ++pub const _SC_BC_DIM_MAX: ::c_int = 24; ++pub const _SC_BC_SCALE_MAX: ::c_int = 25; ++pub const _SC_BC_STRING_MAX: ::c_int = 26; ++pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 50; ++pub const _SC_EXPR_NEST_MAX: ::c_int = 28; ++pub const _SC_LINE_MAX: ::c_int = 29; ++pub const _SC_RE_DUP_MAX: ::c_int = 30; ++pub const _SC_XOPEN_CRYPT: ::c_int = 56; ++pub const _SC_XOPEN_ENH_I18N: ::c_int = 57; ++pub const _SC_XOPEN_SHM: ::c_int = 55; ++pub const _SC_2_CHAR_TERM: ::c_int = 54; ++pub const _SC_XOPEN_XCU_VERSION: ::c_int = 109; ++pub const _SC_ATEXIT_MAX: ::c_int = 47; ++pub const _SC_IOV_MAX: ::c_int = 58; ++pub const _SC_XOPEN_UNIX: ::c_int = 73; ++pub const _SC_T_IOV_MAX: ::c_int = 0; ++pub const _SC_PHYS_PAGES: ::c_int = 113; ++pub const _SC_AVPHYS_PAGES: ::c_int = 114; ++pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 101; ++pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 81; ++pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 82; ++pub const _SC_LOGIN_NAME_MAX: ::c_int = 83; ++pub const _SC_THREAD_KEYS_MAX: ::c_int = 68; ++pub const _SC_THREAD_STACK_MIN: ::c_int = 69; ++pub const _SC_THREAD_THREADS_MAX: ::c_int = 70; ++pub const _SC_TTY_NAME_MAX: ::c_int = 104; ++pub const _SC_THREADS: ::c_int = 60; ++pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 61; ++pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 62; ++pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 64; ++pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 65; ++pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 66; ++pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 67; ++pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 59; ++pub const _SC_XOPEN_LEGACY: ::c_int = 112; ++pub const _SC_XOPEN_REALTIME: ::c_int = 110; ++pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 111; ++pub const _SC_XBS5_ILP32_OFF32: ::c_int = 105; ++pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 106; ++pub const _SC_XBS5_LP64_OFF64: ::c_int = 107; ++pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 108; ++pub const _SC_2_PBS: ::c_int = 132; ++pub const _SC_2_PBS_ACCOUNTING: ::c_int = 133; ++pub const _SC_2_PBS_CHECKPOINT: ::c_int = 134; ++pub const _SC_2_PBS_LOCATE: ::c_int = 135; ++pub const _SC_2_PBS_MESSAGE: ::c_int = 136; ++pub const _SC_2_PBS_TRACK: ::c_int = 137; ++pub const _SC_ADVISORY_INFO: ::c_int = 130; ++pub const _SC_BARRIERS: ::c_int = 138; ++pub const _SC_CLOCK_SELECTION: ::c_int = 139; ++pub const _SC_CPUTIME: ::c_int = 140; ++pub const _SC_HOST_NAME_MAX: ::c_int = 126; ++pub const _SC_MONOTONIC_CLOCK: ::c_int = 141; ++pub const _SC_READER_WRITER_LOCKS: ::c_int = 142; ++pub const _SC_REGEXP: ::c_int = 127; ++pub const _SC_SHELL: ::c_int = 128; ++pub const _SC_SPAWN: ::c_int = 143; ++pub const _SC_SPIN_LOCKS: ::c_int = 144; ++pub const _SC_SPORADIC_SERVER: ::c_int = 145; ++pub const _SC_SS_REPL_MAX: ::c_int = 156; ++pub const _SC_SYMLOOP_MAX: ::c_int = 129; ++pub const _SC_THREAD_CPUTIME: ::c_int = 146; ++pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 147; ++pub const _SC_TIMEOUTS: ::c_int = 148; ++pub const _SC_TRACE: ::c_int = 149; ++pub const _SC_TRACE_EVENT_FILTER: ::c_int = 150; ++pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 157; ++pub const _SC_TRACE_INHERIT: ::c_int = 151; ++pub const _SC_TRACE_LOG: ::c_int = 152; ++pub const _SC_TRACE_NAME_MAX: ::c_int = 158; ++pub const _SC_TRACE_SYS_MAX: ::c_int = 159; ++pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 160; ++pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 153; ++pub const _SC_V6_ILP32_OFF32: ::c_int = 121; ++pub const _SC_V6_ILP32_OFFBIG: ::c_int = 122; ++pub const _SC_V6_LP64_OFF64: ::c_int = 123; ++pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 124; ++pub const _SC_XOPEN_STREAMS: ::c_int = 125; ++pub const _SC_IPV6: ::c_int = 154; ++pub const _SC_RAW_SOCKETS: ::c_int = 155; ++ ++// utmp.h ++pub const EMPTY: ::c_short = -1; ++pub const RUN_LVL: ::c_short = 1; ++pub const BOOT_TIME: ::c_short = 2; ++pub const OLD_TIME: ::c_short = 3; ++pub const NEW_TIME: ::c_short = 4; ++pub const INIT_PROCESS: ::c_short = 5; ++pub const LOGIN_PROCESS: ::c_short = 6; ++pub const USER_PROCESS: ::c_short = 7; ++pub const DEAD_PROCESS: ::c_short = 8; ++pub const ACCOUNTING: ::c_short = 9; ++ ++f! { ++ pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { ++ if (*mhdr).msg_controllen as usize >= ::mem::size_of::() { ++ (*mhdr).msg_control as *mut cmsghdr ++ } else { ++ 0 as *mut cmsghdr ++ } ++ } ++ ++ pub fn CMSG_NXTHDR(mhdr: *const msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr { ++ if cmsg.is_null() { ++ CMSG_FIRSTHDR(mhdr) ++ } else { ++ if (cmsg as usize + (*cmsg).cmsg_len as usize + ::mem::size_of::<::cmsghdr>()) > ++ ((*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize) { ++ 0 as *mut ::cmsghdr ++ } else { ++ // AIX does not have any alignment/padding for ancillary data, so we don't need _CMSG_ALIGN here. ++ (cmsg as usize + (*cmsg).cmsg_len as usize) as *mut cmsghdr ++ } ++ } ++ } ++ ++ pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { ++ (cmsg as *mut ::c_uchar).offset(::mem::size_of::<::cmsghdr>() as isize) ++ } ++ ++ pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint { ++ ::mem::size_of::<::cmsghdr>() as ::c_uint + length ++ } ++ ++ pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { ++ ::mem::size_of::<::cmsghdr>() as ::c_uint + length ++ } ++ ++ pub fn FD_ZERO(set: *mut fd_set) -> () { ++ for slot in (*set).fds_bits.iter_mut() { ++ *slot = 0; ++ } ++ } ++ ++ pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { ++ let bits = ::mem::size_of::<::c_long>() * 8; ++ let fd = fd as usize; ++ (*set).fds_bits[fd / bits] |= 1 << (fd % bits); ++ return ++ } ++ ++ pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { ++ let bits = ::mem::size_of::<::c_long>() * 8; ++ let fd = fd as usize; ++ (*set).fds_bits[fd / bits] &= !(1 << (fd % bits)); ++ return ++ } ++ ++ pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { ++ let bits = ::mem::size_of::<::c_long>() * 8; ++ let fd = fd as usize; ++ return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0 ++ } ++ ++ pub fn major(dev: ::dev_t) -> ::c_uint { ++ let x = dev >> 16; ++ x as ::c_uint ++ } ++ ++ pub fn minor(dev: ::dev_t) -> ::c_uint { ++ let y = dev & 0xFFFF; ++ y as ::c_uint ++ } ++ ++ pub fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { ++ let major = major as ::dev_t; ++ let minor = minor as ::dev_t; ++ let mut dev = 0; ++ dev |= major << 16; ++ dev |= minor; ++ dev ++ } ++} ++ ++safe_f! { ++ pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { ++ (status & _W_STOPPED) != 0 ++ } ++ ++ pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { ++ if WIFSTOPPED(status) { ++ (((status as ::c_uint) >> 8) & 0xff) as ::c_int ++ } else { ++ -1 ++ } ++ } ++ ++ pub {const} fn WIFEXITED(status: ::c_int) -> bool { ++ (status & 0xFF) == 0 ++ } ++ ++ pub {const} fn WEXITSTATUS(status: ::c_int) -> ::c_int { ++ if WIFEXITED(status) { ++ (((status as ::c_uint) >> 8) & 0xff) as ::c_int ++ } else { ++ -1 ++ } ++ } ++ ++ pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { ++ !WIFEXITED(status) && !WIFSTOPPED(status) ++ } ++ ++ pub {const} fn WTERMSIG(status: ::c_int) -> ::c_int { ++ if WIFSIGNALED(status) { ++ (((status as ::c_uint) >> 16) & 0xff) as ::c_int ++ } else { ++ -1 ++ } ++ } ++ ++ pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { ++ (status & WCONTINUED) != 0 ++ } ++ ++ // AIX doesn't have native WCOREDUMP. ++ pub {const} fn WCOREDUMP(_status: ::c_int) -> bool { ++ false ++ } ++} ++ ++#[link(name = "thread")] ++extern "C" { ++ pub fn thr_kill(id: thread_t, sig: ::c_int) -> ::c_int; ++ pub fn thr_self() -> thread_t; ++} ++ ++#[link(name = "pthread")] ++extern "C" { ++ pub fn pthread_atfork( ++ prepare: ::Option, ++ parent: ::Option, ++ child: ::Option, ++ ) -> ::c_int; ++ pub fn pthread_attr_getguardsize( ++ attr: *const ::pthread_attr_t, ++ guardsize: *mut ::size_t, ++ ) -> ::c_int; ++ pub fn pthread_attr_getschedparam( ++ attr: *const ::pthread_attr_t, ++ param: *mut sched_param, ++ ) -> ::c_int; ++ pub fn pthread_attr_getstack( ++ attr: *const ::pthread_attr_t, ++ stackaddr: *mut *mut ::c_void, ++ stacksize: *mut ::size_t, ++ ) -> ::c_int; ++ pub fn pthread_attr_setschedparam( ++ attr: *mut ::pthread_attr_t, ++ param: *const sched_param, ++ ) -> ::c_int; ++ pub fn pthread_barrier_destroy(barrier: *mut pthread_barrier_t) -> ::c_int; ++ pub fn pthread_barrier_init( ++ barrier: *mut pthread_barrier_t, ++ attr: *const ::pthread_barrierattr_t, ++ count: ::c_uint, ++ ) -> ::c_int; ++ pub fn pthread_barrier_wait(barrier: *mut pthread_barrier_t) -> ::c_int; ++ pub fn pthread_barrierattr_destroy(attr: *mut ::pthread_barrierattr_t) -> ::c_int; ++ pub fn pthread_barrierattr_getpshared( ++ attr: *const ::pthread_barrierattr_t, ++ shared: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_barrierattr_init(attr: *mut ::pthread_barrierattr_t) -> ::c_int; ++ pub fn pthread_barrierattr_setpshared( ++ attr: *mut ::pthread_barrierattr_t, ++ shared: ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_cancel(thread: ::pthread_t) -> ::c_int; ++ pub fn pthread_condattr_getclock( ++ attr: *const pthread_condattr_t, ++ clock_id: *mut clockid_t, ++ ) -> ::c_int; ++ pub fn pthread_condattr_getpshared( ++ attr: *const pthread_condattr_t, ++ pshared: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_condattr_setclock( ++ attr: *mut pthread_condattr_t, ++ clock_id: ::clockid_t, ++ ) -> ::c_int; ++ pub fn pthread_condattr_setpshared(attr: *mut pthread_condattr_t, pshared: ::c_int) -> ::c_int; ++ pub fn pthread_create( ++ native: *mut ::pthread_t, ++ attr: *const ::pthread_attr_t, ++ f: extern "C" fn(*mut ::c_void) -> *mut ::c_void, ++ value: *mut ::c_void, ++ ) -> ::c_int; ++ pub fn pthread_getattr_np(native: ::pthread_t, attr: *mut ::pthread_attr_t) -> ::c_int; ++ pub fn pthread_getcpuclockid(thread: ::pthread_t, clk_id: *mut ::clockid_t) -> ::c_int; ++ pub fn pthread_getschedparam( ++ thread: ::pthread_t, ++ policy: *mut ::c_int, ++ param: *mut sched_param, ++ ) -> ::c_int; ++ pub fn pthread_kill(thread: ::pthread_t, signal: ::c_int) -> ::c_int; ++ pub fn pthread_mutex_consistent(mutex: *mut ::pthread_mutex_t) -> ::c_int; ++ pub fn pthread_mutex_timedlock( ++ lock: *mut pthread_mutex_t, ++ abstime: *const ::timespec, ++ ) -> ::c_int; ++ pub fn pthread_mutexattr_getprotocol( ++ attr: *const pthread_mutexattr_t, ++ protocol: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_mutexattr_getpshared( ++ attr: *const pthread_mutexattr_t, ++ pshared: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_mutexattr_getrobust( ++ attr: *mut ::pthread_mutexattr_t, ++ robust: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_mutexattr_setprotocol( ++ attr: *mut pthread_mutexattr_t, ++ protocol: ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_mutexattr_setpshared( ++ attr: *mut pthread_mutexattr_t, ++ pshared: ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_mutexattr_setrobust( ++ attr: *mut ::pthread_mutexattr_t, ++ robust: ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_rwlockattr_getpshared( ++ attr: *const pthread_rwlockattr_t, ++ val: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_rwlockattr_setpshared(attr: *mut pthread_rwlockattr_t, val: ::c_int) -> ::c_int; ++ pub fn pthread_setschedparam( ++ thread: ::pthread_t, ++ policy: ::c_int, ++ param: *const sched_param, ++ ) -> ::c_int; ++ pub fn pthread_setschedprio(native: ::pthread_t, priority: ::c_int) -> ::c_int; ++ pub fn pthread_sigmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; ++ pub fn pthread_spin_destroy(lock: *mut pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_init(lock: *mut pthread_spinlock_t, pshared: ::c_int) -> ::c_int; ++ pub fn pthread_spin_lock(lock: *mut pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_trylock(lock: *mut pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_unlock(lock: *mut pthread_spinlock_t) -> ::c_int; ++} ++ ++#[link(name = "iconv")] ++extern "C" { ++ pub fn iconv( ++ cd: iconv_t, ++ inbuf: *mut *mut ::c_char, ++ inbytesleft: *mut ::size_t, ++ outbuf: *mut *mut ::c_char, ++ outbytesleft: *mut ::size_t, ++ ) -> ::size_t; ++ pub fn iconv_close(cd: iconv_t) -> ::c_int; ++ pub fn iconv_open(tocode: *const ::c_char, fromcode: *const ::c_char) -> iconv_t; ++} ++ ++extern "C" { ++ pub fn acct(filename: *const ::c_char) -> ::c_int; ++ pub fn aio_cancel(fildes: ::c_int, aiocbp: *mut ::aiocb) -> ::c_int; ++ pub fn aio_error(aiocbp: *mut ::aiocb) -> ::c_int; ++ #[link_name = "_posix_aio_fsync"] ++ pub fn aio_fsync(op: ::c_int, aiocbp: *mut ::aiocb) -> ::c_int; ++ pub fn aio_read(aiocbp: *mut ::aiocb) -> ::c_int; ++ // pub fn aio_suspend ++ // pub fn aio_write ++ pub fn basename(path: *mut ::c_char) -> *mut ::c_char; ++ pub fn bind(socket: ::c_int, address: *const ::sockaddr, address_len: ::socklen_t) -> ::c_int; ++ pub fn brk(addr: *mut ::c_void) -> ::c_int; ++ pub fn clearenv() -> ::c_int; ++ pub fn clock_getcpuclockid(pid: ::pid_t, clk_id: *mut ::clockid_t) -> ::c_int; ++ pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; ++ pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; ++ pub fn clock_nanosleep( ++ clk_id: ::clockid_t, ++ flags: ::c_int, ++ rqtp: *const ::timespec, ++ rmtp: *mut ::timespec, ++ ) -> ::c_int; ++ pub fn clock_settime(clock_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; ++ pub fn creat64(path: *const c_char, mode: mode_t) -> ::c_int; ++ pub fn ctermid(s: *mut ::c_char) -> *mut ::c_char; ++ pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; ++ pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; ++ pub fn drand48() -> ::c_double; ++ pub fn duplocale(arg1: ::locale_t) -> ::locale_t; ++ pub fn endgrent(); ++ pub fn endmntent(streamp: *mut ::FILE) -> ::c_int; ++ pub fn endpwent(); ++ pub fn endutent(); ++ pub fn endutxent(); ++ pub fn erand48(xseed: *mut ::c_ushort) -> ::c_double; ++ pub fn faccessat( ++ dirfd: ::c_int, ++ pathname: *const ::c_char, ++ mode: ::c_int, ++ flags: ::c_int, ++ ) -> ::c_int; ++ pub fn fattach(fildes: ::c_int, path: *const ::c_char) -> ::c_int; ++ pub fn fdatasync(fd: ::c_int) -> ::c_int; ++ pub fn fexecve( ++ fd: ::c_int, ++ argv: *const *const ::c_char, ++ envp: *const *const ::c_char, ++ ) -> ::c_int; ++ pub fn ffs(value: ::c_int) -> ::c_int; ++ pub fn ffsl(value: ::c_long) -> ::c_int; ++ pub fn ffsll(value: ::c_longlong) -> ::c_int; ++ pub fn fgetgrent(file: *mut ::FILE) -> *mut ::group; ++ pub fn fgetpos64(stream: *mut ::FILE, ptr: *mut fpos64_t) -> ::c_int; ++ pub fn fgetpwent(file: *mut ::FILE) -> *mut ::passwd; ++ pub fn fopen64(filename: *const c_char, mode: *const c_char) -> *mut ::FILE; ++ pub fn freelocale(loc: ::locale_t); ++ pub fn freopen64( ++ filename: *const c_char, ++ mode: *const c_char, ++ file: *mut ::FILE, ++ ) -> *mut ::FILE; ++ pub fn fseeko64(stream: *mut ::FILE, offset: ::off64_t, whence: ::c_int) -> ::c_int; ++ pub fn fsetpos64(stream: *mut ::FILE, ptr: *const fpos64_t) -> ::c_int; ++ pub fn fstat64(fildes: ::c_int, buf: *mut stat64) -> ::c_int; ++ pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int; ++ pub fn fstatfs64(fd: ::c_int, buf: *mut statfs64) -> ::c_int; ++ pub fn fstatvfs64(fd: ::c_int, buf: *mut statvfs64) -> ::c_int; ++ pub fn ftello64(stream: *mut ::FILE) -> ::off64_t; ++ pub fn ftok(path: *const ::c_char, id: ::c_int) -> ::key_t; ++ pub fn ftruncate64(fd: ::c_int, length: off64_t) -> ::c_int; ++ pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; ++ pub fn getcontext(ucp: *mut ucontext_t) -> ::c_int; ++ pub fn getdomainname(name: *mut ::c_char, len: ::c_int) -> ::c_int; ++ pub fn getdtablesize() -> ::c_int; ++ pub fn getgrent() -> *mut ::group; ++ pub fn getgrgid(gid: ::gid_t) -> *mut ::group; ++ pub fn getgrgid_r( ++ gid: ::gid_t, ++ grp: *mut ::group, ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ result: *mut *mut ::group, ++ ) -> ::c_int; ++ pub fn getgrnam(name: *const ::c_char) -> *mut ::group; ++ pub fn getgrnam_r( ++ name: *const ::c_char, ++ grp: *mut ::group, ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ result: *mut *mut ::group, ++ ) -> ::c_int; ++ pub fn getgrset(user: *mut ::c_char) -> *mut ::c_char; ++ pub fn gethostid() -> ::c_long; ++ pub fn getmntent(stream: *mut ::FILE) -> *mut ::mntent; ++ pub fn getnameinfo( ++ sa: *const ::sockaddr, ++ salen: ::size_t, ++ host: *mut ::c_char, ++ hostlen: ::size_t, ++ serv: *mut ::c_char, ++ sevlen: ::size_t, ++ flags: ::c_int, ++ ) -> ::c_int; ++ pub fn getpagesize() -> ::c_int; ++ pub fn getpeereid(socket: ::c_int, euid: *mut ::uid_t, egid: *mut ::gid_t) -> ::c_int; ++ pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int; ++ pub fn getpwent() -> *mut ::passwd; ++ pub fn getpwnam_r( ++ name: *const ::c_char, ++ pwd: *mut passwd, ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ result: *mut *mut passwd, ++ ) -> ::c_int; ++ pub fn getpwuid_r( ++ uid: ::uid_t, ++ pwd: *mut passwd, ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ result: *mut *mut passwd, ++ ) -> ::c_int; ++ pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; ++ pub fn getrlimit64(resource: ::c_int, rlim: *mut rlimit64) -> ::c_int; ++ pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; ++ pub fn getitimer(which: ::c_int, curr_value: *mut ::itimerval) -> ::c_int; ++ pub fn getutent() -> *mut utmp; ++ pub fn getutid(u: *const utmp) -> *mut utmp; ++ pub fn getutline(u: *const utmp) -> *mut utmp; ++ pub fn getutxent() -> *mut utmpx; ++ pub fn getutxid(ut: *const utmpx) -> *mut utmpx; ++ pub fn getutxline(ut: *const utmpx) -> *mut utmpx; ++ pub fn glob( ++ pattern: *const ::c_char, ++ flags: ::c_int, ++ errfunc: ::Option ::c_int>, ++ pglob: *mut ::glob_t, ++ ) -> ::c_int; ++ pub fn globfree(pglob: *mut ::glob_t); ++ pub fn hasmntopt(mnt: *const ::mntent, opt: *const ::c_char) -> *mut ::c_char; ++ pub fn hcreate(nelt: ::size_t) -> ::c_int; ++ pub fn hdestroy(); ++ pub fn hsearch(entry: entry, action: ::c_int) -> *mut entry; ++ pub fn if_freenameindex(ptr: *mut if_nameindex); ++ pub fn if_nameindex() -> *mut if_nameindex; ++ pub fn initgroups(name: *const ::c_char, basegid: ::gid_t) -> ::c_int; ++ pub fn ioctl(fildes: ::c_int, request: ::c_int, ...) -> ::c_int; ++ pub fn jrand48(xseed: *mut ::c_ushort) -> ::c_long; ++ pub fn lcong48(p: *mut ::c_ushort); ++ pub fn lfind( ++ key: *const ::c_void, ++ base: *const ::c_void, ++ nelp: *mut ::size_t, ++ width: ::size_t, ++ compar: ::Option ::c_int>, ++ ) -> *mut ::c_void; ++ pub fn lio_listio( ++ mode: ::c_int, ++ aiocb_list: *const *mut aiocb, ++ nitems: ::c_int, ++ sevp: *mut sigevent, ++ ) -> ::c_int; ++ pub fn loadquery(flags: ::c_int, buf: *mut ::c_char, buflen: ::c_uint) -> ::c_int; ++ pub fn lpar_get_info(command: ::c_int, buf: *mut ::c_void, bufsize: ::size_t) -> ::c_int; ++ pub fn lpar_set_resources(id: ::c_int, resource: *mut ::c_void) -> ::c_int; ++ pub fn lrand48() -> c_long; ++ pub fn lsearch( ++ key: *const ::c_void, ++ base: *mut ::c_void, ++ nelp: *mut ::size_t, ++ width: ::size_t, ++ compar: ::Option ::c_int>, ++ ) -> *mut ::c_void; ++ pub fn lseek64(fd: ::c_int, offset: off64_t, whence: ::c_int) -> off64_t; ++ pub fn lstat64(path: *const c_char, buf: *mut stat64) -> ::c_int; ++ pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; ++ pub fn makecontext(ucp: *mut ::ucontext_t, func: extern "C" fn(), argc: ::c_int, ...); ++ pub fn mallinfo() -> ::mallinfo; ++ pub fn mallopt(param: ::c_int, value: ::c_int) -> ::c_int; ++ pub fn memmem( ++ haystack: *const ::c_void, ++ haystacklen: ::size_t, ++ needle: *const ::c_void, ++ needlelen: ::size_t, ++ ) -> *mut ::c_void; ++ pub fn memset_s(s: *mut ::c_void, smax: ::size_t, c: ::c_int, n: ::size_t) -> ::c_int; ++ pub fn mincore(addr: *const ::c_void, len: ::size_t, vec: *mut ::c_char) -> ::c_int; ++ pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; ++ pub fn mknodat( ++ dirfd: ::c_int, ++ pathname: *const ::c_char, ++ mode: ::mode_t, ++ dev: dev_t, ++ ) -> ::c_int; ++ pub fn mount(device: *const ::c_char, path: *const ::c_char, flags: ::c_int) -> ::c_int; ++ pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; ++ pub fn mq_close(mqd: ::mqd_t) -> ::c_int; ++ pub fn mq_getattr(mqd: ::mqd_t, attr: *mut ::mq_attr) -> ::c_int; ++ pub fn mq_notify(mqd: ::mqd_t, notification: *const ::sigevent) -> ::c_int; ++ pub fn mq_open(name: *const ::c_char, oflag: ::c_int, ...) -> ::mqd_t; ++ pub fn mq_receive( ++ mqd: ::mqd_t, ++ msg_ptr: *mut ::c_char, ++ msg_len: ::size_t, ++ msg_prio: *mut ::c_uint, ++ ) -> ::ssize_t; ++ pub fn mq_send( ++ mqd: ::mqd_t, ++ msg_ptr: *const ::c_char, ++ msg_len: ::size_t, ++ msg_prio: ::c_uint, ++ ) -> ::c_int; ++ pub fn mq_setattr(mqd: ::mqd_t, newattr: *const ::mq_attr, oldattr: *mut ::mq_attr) -> ::c_int; ++ pub fn mq_timedreceive( ++ mqd: ::mqd_t, ++ msg_ptr: *mut ::c_char, ++ msg_len: ::size_t, ++ msg_prio: *mut ::c_uint, ++ abs_timeout: *const ::timespec, ++ ) -> ::ssize_t; ++ pub fn mq_timedsend( ++ mqd: ::mqd_t, ++ msg_ptr: *const ::c_char, ++ msg_len: ::size_t, ++ msg_prio: ::c_uint, ++ abs_timeout: *const ::timespec, ++ ) -> ::c_int; ++ pub fn mq_unlink(name: *const ::c_char) -> ::c_int; ++ pub fn mrand48() -> c_long; ++ pub fn msgctl(msqid: ::c_int, cmd: ::c_int, buf: *mut msqid_ds) -> ::c_int; ++ pub fn msgget(key: ::key_t, msgflg: ::c_int) -> ::c_int; ++ pub fn msgrcv( ++ msqid: ::c_int, ++ msgp: *mut ::c_void, ++ msgsz: ::size_t, ++ msgtyp: ::c_long, ++ msgflg: ::c_int, ++ ) -> ::ssize_t; ++ pub fn msgsnd( ++ msqid: ::c_int, ++ msgp: *const ::c_void, ++ msgsz: ::size_t, ++ msgflg: ::c_int, ++ ) -> ::c_int; ++ pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; ++ pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t; ++ pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; ++ pub fn nl_langinfo_l(item: ::nl_item, loc: ::locale_t) -> *mut ::c_char; ++ pub fn nrand48(xseed: *mut ::c_ushort) -> ::c_long; ++ pub fn open64(path: *const c_char, oflag: ::c_int, ...) -> ::c_int; ++ pub fn pollset_create(maxfd: ::c_int) -> pollset_t; ++ pub fn pollset_ctl( ++ ps: pollset_t, ++ pollctl_array: *mut poll_ctl, ++ array_length: ::c_int, ++ ) -> ::c_int; ++ pub fn pollset_destroy(ps: pollset_t) -> ::c_int; ++ pub fn pollset_poll( ++ ps: pollset_t, ++ polldata_array: *mut ::pollfd, ++ array_length: ::c_int, ++ timeout: ::c_int, ++ ) -> ::c_int; ++ pub fn pollset_query(ps: pollset_t, pollfd_query: *mut ::pollfd) -> ::c_int; ++ pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; ++ pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, advise: ::c_int) -> ::c_int; ++ pub fn posix_fadvise64( ++ fd: ::c_int, ++ offset: ::off64_t, ++ len: ::off64_t, ++ advise: ::c_int, ++ ) -> ::c_int; ++ pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; ++ pub fn posix_fallocate64(fd: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::c_int; ++ pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; ++ pub fn posix_spawn( ++ pid: *mut ::pid_t, ++ path: *const ::c_char, ++ file_actions: *const ::posix_spawn_file_actions_t, ++ attrp: *const ::posix_spawnattr_t, ++ argv: *const *mut ::c_char, ++ envp: *const *mut ::c_char, ++ ) -> ::c_int; ++ pub fn posix_spawn_file_actions_addclose( ++ actions: *mut posix_spawn_file_actions_t, ++ fd: ::c_int, ++ ) -> ::c_int; ++ pub fn posix_spawn_file_actions_adddup2( ++ actions: *mut posix_spawn_file_actions_t, ++ fd: ::c_int, ++ newfd: ::c_int, ++ ) -> ::c_int; ++ pub fn posix_spawn_file_actions_addopen( ++ actions: *mut posix_spawn_file_actions_t, ++ fd: ::c_int, ++ path: *const ::c_char, ++ oflag: ::c_int, ++ mode: ::mode_t, ++ ) -> ::c_int; ++ pub fn posix_spawn_file_actions_destroy(actions: *mut posix_spawn_file_actions_t) -> ::c_int; ++ pub fn posix_spawn_file_actions_init(actions: *mut posix_spawn_file_actions_t) -> ::c_int; ++ pub fn posix_spawnattr_destroy(attr: *mut posix_spawnattr_t) -> ::c_int; ++ pub fn posix_spawnattr_getflags( ++ attr: *const posix_spawnattr_t, ++ flags: *mut ::c_short, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_getpgroup( ++ attr: *const posix_spawnattr_t, ++ flags: *mut ::pid_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_getschedparam( ++ attr: *const posix_spawnattr_t, ++ param: *mut ::sched_param, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_getschedpolicy( ++ attr: *const posix_spawnattr_t, ++ flags: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_getsigdefault( ++ attr: *const posix_spawnattr_t, ++ default: *mut sigset_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_getsigmask( ++ attr: *const posix_spawnattr_t, ++ default: *mut sigset_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_init(attr: *mut posix_spawnattr_t) -> ::c_int; ++ pub fn posix_spawnattr_setflags(attr: *mut posix_spawnattr_t, flags: ::c_short) -> ::c_int; ++ pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: ::pid_t) -> ::c_int; ++ pub fn posix_spawnattr_setschedparam( ++ attr: *mut posix_spawnattr_t, ++ param: *const ::sched_param, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setschedpolicy(attr: *mut posix_spawnattr_t, flags: ::c_int) -> ::c_int; ++ pub fn posix_spawnattr_setsigdefault( ++ attr: *mut posix_spawnattr_t, ++ default: *const ::sigset_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setsigmask( ++ attr: *mut posix_spawnattr_t, ++ default: *const ::sigset_t, ++ ) -> ::c_int; ++ pub fn posix_spawnp( ++ pid: *mut ::pid_t, ++ file: *const ::c_char, ++ file_actions: *const ::posix_spawn_file_actions_t, ++ attrp: *const ::posix_spawnattr_t, ++ argv: *const *mut ::c_char, ++ envp: *const *mut ::c_char, ++ ) -> ::c_int; ++ pub fn pread64(fd: ::c_int, buf: *mut ::c_void, count: ::size_t, offset: off64_t) -> ::ssize_t; ++ pub fn preadv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) -> ::ssize_t; ++ pub fn ptrace64( ++ request: ::c_int, ++ id: ::c_longlong, ++ addr: ::c_longlong, ++ data: ::c_int, ++ buff: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pututline(u: *const utmp) -> *mut utmp; ++ pub fn pututxline(ut: *const utmpx) -> *mut utmpx; ++ pub fn pwrite64( ++ fd: ::c_int, ++ buf: *const ::c_void, ++ count: ::size_t, ++ offset: off64_t, ++ ) -> ::ssize_t; ++ pub fn pwritev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) ++ -> ::ssize_t; ++ #[link_name = "__linux_quotactl"] ++ pub fn quotactl( ++ cmd: ::c_int, ++ special: *const ::c_char, ++ id: ::c_int, ++ data: *mut ::c_char, ++ ) -> ::c_int; ++ pub fn rand() -> ::c_int; ++ pub fn readv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; ++ pub fn recvfrom( ++ socket: ::c_int, ++ buf: *mut ::c_void, ++ len: ::size_t, ++ flags: ::c_int, ++ addr: *mut ::sockaddr, ++ addrlen: *mut ::socklen_t, ++ ) -> ::ssize_t; ++ pub fn recvmmsg( ++ sockfd: ::c_int, ++ msgvec: *mut ::mmsghdr, ++ vlen: ::c_uint, ++ flags: ::c_int, ++ timeout: *mut ::timespec, ++ ) -> ::c_int; ++ pub fn recvmsg(sockfd: ::c_int, msg: *mut msghdr, flags: ::c_int) -> ::ssize_t; ++ pub fn regcomp(preg: *mut regex_t, pattern: *const ::c_char, cflags: ::c_int) -> ::c_int; ++ pub fn regerror( ++ errcode: ::c_int, ++ preg: *const ::regex_t, ++ errbuf: *mut ::c_char, ++ errbuf_size: ::size_t, ++ ) -> ::size_t; ++ pub fn regexec( ++ preg: *const regex_t, ++ input: *const ::c_char, ++ nmatch: ::size_t, ++ pmatch: *mut regmatch_t, ++ eflags: ::c_int, ++ ) -> ::c_int; ++ pub fn regfree(preg: *mut regex_t); ++ pub fn sbrk(increment: ::intptr_t) -> *mut ::c_void; ++ pub fn sched_getparam(pid: ::pid_t, param: *mut sched_param) -> ::c_int; ++ pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int; ++ pub fn sched_get_priority_max(policy: ::c_int) -> ::c_int; ++ pub fn sched_get_priority_min(policy: ::c_int) -> ::c_int; ++ pub fn sched_rr_get_interval(pid: ::pid_t, tp: *mut ::timespec) -> ::c_int; ++ pub fn sched_setparam(pid: ::pid_t, param: *const ::sched_param) -> ::c_int; ++ pub fn sched_setscheduler( ++ pid: ::pid_t, ++ policy: ::c_int, ++ param: *const ::sched_param, ++ ) -> ::c_int; ++ pub fn sctp_opt_info( ++ sd: ::c_int, ++ id: ::sctp_assoc_t, ++ opt: ::c_int, ++ arg_size: *mut ::c_void, ++ size: *mut ::size_t, ++ ) -> ::c_int; ++ pub fn sctp_peeloff(s: ::c_int, id: ::sctp_assoc_t) -> ::c_int; ++ pub fn seed48(xseed: *mut ::c_ushort) -> *mut ::c_ushort; ++ pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); ++ pub fn sem_close(sem: *mut sem_t) -> ::c_int; ++ pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; ++ pub fn sem_getvalue(sem: *mut sem_t, sval: *mut ::c_int) -> ::c_int; ++ pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; ++ pub fn sem_open(name: *const ::c_char, oflag: ::c_int, ...) -> *mut sem_t; ++ pub fn sem_timedwait(sem: *mut sem_t, abstime: *const ::timespec) -> ::c_int; ++ pub fn sem_unlink(name: *const ::c_char) -> ::c_int; ++ pub fn semctl(semid: ::c_int, semnum: ::c_int, cmd: ::c_int, ...) -> ::c_int; ++ pub fn semget(key: ::key_t, nsems: ::c_int, semflag: ::c_int) -> ::c_int; ++ pub fn semop(semid: ::c_int, sops: *mut sembuf, nsops: ::size_t) -> ::c_int; ++ pub fn send_file(socket: *mut ::c_int, iobuf: *mut sf_parms, flags: ::c_uint) -> ::ssize_t; ++ pub fn sendmmsg( ++ sockfd: ::c_int, ++ msgvec: *mut mmsghdr, ++ vlen: ::c_uint, ++ flags: ::c_int, ++ ) -> ::c_int; ++ pub fn sendmsg(sockfd: ::c_int, msg: *const msghdr, flags: ::c_int) -> ::ssize_t; ++ pub fn setcontext(ucp: *const ucontext_t) -> ::c_int; ++ pub fn setdomainname(name: *const ::c_char, len: ::c_int) -> ::c_int; ++ pub fn setgroups(ngroups: ::c_int, ptr: *const ::gid_t) -> ::c_int; ++ pub fn setgrent(); ++ pub fn sethostid(hostid: ::c_int) -> ::c_int; ++ pub fn sethostname(name: *const ::c_char, len: ::c_int) -> ::c_int; ++ pub fn setmntent(filename: *const ::c_char, ty: *const ::c_char) -> *mut ::FILE; ++ pub fn setpriority(which: ::c_int, who: id_t, priority: ::c_int) -> ::c_int; ++ pub fn setpwent(); ++ pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; ++ pub fn setrlimit64(resource: ::c_int, rlim: *const rlimit64) -> ::c_int; ++ pub fn settimeofday(tv: *const ::timeval, tz: *const ::timezone) -> ::c_int; ++ pub fn setitimer( ++ which: ::c_int, ++ new_value: *const ::itimerval, ++ old_value: *mut ::itimerval, ++ ) -> ::c_int; ++ pub fn setutent(); ++ pub fn setutxent(); ++ pub fn sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> ::c_int; ++ pub fn sigsuspend(mask: *const ::sigset_t) -> ::c_int; ++ pub fn sigtimedwait( ++ set: *const sigset_t, ++ info: *mut siginfo_t, ++ timeout: *const ::timespec, ++ ) -> ::c_int; ++ pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; ++ pub fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> ::c_int; ++ pub fn shmat(shmid: ::c_int, shmaddr: *const ::c_void, shmflg: ::c_int) -> *mut ::c_void; ++ pub fn shmdt(shmaddr: *const ::c_void) -> ::c_int; ++ pub fn shmctl(shmid: ::c_int, cmd: ::c_int, buf: *mut ::shmid_ds) -> ::c_int; ++ pub fn shmget(key: key_t, size: ::size_t, shmflg: ::c_int) -> ::c_int; ++ pub fn shm_open(name: *const ::c_char, oflag: ::c_int, mode: ::mode_t) -> ::c_int; ++ pub fn shm_unlink(name: *const ::c_char) -> ::c_int; ++ pub fn splice(socket1: ::c_int, socket2: ::c_int, flags: ::c_int) -> ::c_int; ++ pub fn srand(seed: ::c_uint); ++ pub fn srand48(seed: ::c_long); ++ pub fn stat64(path: *const c_char, buf: *mut stat64) -> ::c_int; ++ pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int; ++ pub fn statfs64(path: *const ::c_char, buf: *mut statfs64) -> ::c_int; ++ pub fn statvfs64(path: *const ::c_char, buf: *mut statvfs64) -> ::c_int; ++ pub fn statx( ++ path: *const ::c_char, ++ buf: *mut stat, ++ length: ::c_int, ++ command: ::c_int, ++ ) -> ::c_int; ++ pub fn strcasecmp_l( ++ string1: *const ::c_char, ++ string2: *const ::c_char, ++ locale: ::locale_t, ++ ) -> ::c_int; ++ pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; ++ pub fn strftime( ++ arg1: *mut c_char, ++ arg2: ::size_t, ++ arg3: *const c_char, ++ arg4: *const tm, ++ ) -> ::size_t; ++ pub fn strncasecmp_l( ++ string1: *const ::c_char, ++ string2: *const ::c_char, ++ length: ::size_t, ++ locale: ::locale_t, ++ ) -> ::c_int; ++ pub fn strptime(s: *const ::c_char, format: *const ::c_char, tm: *mut ::tm) -> *mut ::c_char; ++ pub fn strsep(string: *mut *mut ::c_char, delim: *const ::c_char) -> *mut ::c_char; ++ pub fn swapcontext(uocp: *mut ucontext_t, ucp: *const ucontext_t) -> ::c_int; ++ pub fn swapoff(puath: *const ::c_char) -> ::c_int; ++ pub fn swapon(path: *const ::c_char) -> ::c_int; ++ pub fn sync(); ++ pub fn telldir(dirp: *mut ::DIR) -> ::c_long; ++ pub fn timer_create( ++ clockid: ::clockid_t, ++ sevp: *mut ::sigevent, ++ timerid: *mut ::timer_t, ++ ) -> ::c_int; ++ pub fn timer_delete(timerid: timer_t) -> ::c_int; ++ pub fn timer_getoverrun(timerid: timer_t) -> ::c_int; ++ pub fn timer_gettime(timerid: timer_t, value: *mut itimerspec) -> ::c_int; ++ pub fn timer_settime( ++ timerid: ::timer_t, ++ flags: ::c_int, ++ new_value: *const ::itimerspec, ++ old_value: *mut ::itimerspec, ++ ) -> ::c_int; ++ pub fn truncate64(path: *const c_char, length: off64_t) -> ::c_int; ++ pub fn uname(buf: *mut ::utsname) -> ::c_int; ++ pub fn updwtmp(file: *const ::c_char, u: *mut utmp); ++ pub fn uselocale(loc: ::locale_t) -> ::locale_t; ++ pub fn utmpname(file: *const ::c_char) -> ::c_int; ++ pub fn utimensat( ++ dirfd: ::c_int, ++ path: *const ::c_char, ++ times: *const ::timespec, ++ flag: ::c_int, ++ ) -> ::c_int; ++ pub fn wait4( ++ pid: ::pid_t, ++ status: *mut ::c_int, ++ options: ::c_int, ++ rusage: *mut ::rusage, ++ ) -> ::pid_t; ++ pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t, options: ::c_int) ++ -> ::c_int; ++ pub fn writev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; ++ ++ // Use AIX thread-safe version errno. ++ pub fn _Errno() -> *mut ::c_int; ++} ++ ++cfg_if! { ++ if #[cfg(target_arch = "powerpc64")] { ++ mod powerpc64; ++ pub use self::powerpc64::*; ++ } ++} +diff --git a/vendor/libc/src/unix/aix/powerpc64.rs b/vendor/libc/src/unix/aix/powerpc64.rs +new file mode 100644 +index 0000000..2cacf29 +--- /dev/null ++++ b/vendor/libc/src/unix/aix/powerpc64.rs +@@ -0,0 +1,644 @@ ++pub type c_long = i64; ++pub type c_ulong = u64; ++ ++s! { ++ pub struct sigset_t { ++ pub ss_set: [c_ulong; 4], ++ } ++ ++ pub struct fd_set { ++ pub fds_bits: [c_long; 1024], ++ } ++ ++ pub struct flock { ++ pub l_type: ::c_short, ++ pub l_whence: ::c_short, ++ pub l_sysid: ::c_uint, ++ pub l_pid: ::pid_t, ++ pub l_vfs: ::c_int, ++ pub l_start: ::off_t, ++ pub l_len: ::off_t, ++ } ++ ++ pub struct statvfs { ++ pub f_bsize: ::c_ulong, ++ pub f_frsize: ::c_ulong, ++ pub f_blocks: ::fsblkcnt_t, ++ pub f_bfree: ::fsblkcnt_t, ++ pub f_bavail: ::fsblkcnt_t, ++ pub f_files: ::fsfilcnt_t, ++ pub f_ffree: ::fsfilcnt_t, ++ pub f_favail: ::fsfilcnt_t, ++ pub f_fsid: ::c_ulong, ++ pub f_basetype: [::c_char; 16], ++ pub f_flag: ::c_ulong, ++ pub f_namemax: ::c_ulong, ++ pub f_fstr: [::c_char; 32], ++ pub f_filler: [::c_ulong; 16] ++ } ++ ++ pub struct pthread_rwlock_t { ++ __rw_word: [::c_long; 10], ++ } ++ ++ pub struct pthread_cond_t { ++ __cv_word: [::c_long; 6], ++ } ++ ++ pub struct pthread_mutex_t { ++ __mt_word: [::c_long; 8], ++ } ++ ++ pub struct stat { ++ pub st_dev: ::dev_t, ++ pub st_ino: ::ino_t, ++ pub st_mode: ::mode_t, ++ pub st_nlink: ::nlink_t, ++ pub st_flag: ::c_ushort, ++ pub st_uid: ::uid_t, ++ pub st_gid: ::gid_t, ++ pub st_rdev: ::dev_t, ++ pub st_ssize: ::c_int, ++ pub st_atime: ::st_timespec, ++ pub st_mtime: ::st_timespec, ++ pub st_ctime: ::st_timespec, ++ pub st_blksize: ::blksize_t, ++ pub st_blocks: ::blkcnt_t, ++ pub st_vfstype: ::c_int, ++ pub st_vfs: ::c_uint, ++ pub st_type: ::c_uint, ++ pub st_gen: ::c_uint, ++ pub st_reserved: [::c_uint; 9], ++ pub st_padto_ll: ::c_uint, ++ pub st_size: ::off_t, ++ } ++ ++ pub struct statfs { ++ pub f_version: ::c_int, ++ pub f_type: ::c_int, ++ pub f_bsize: ::c_ulong, ++ pub f_blocks: ::fsblkcnt_t, ++ pub f_bfree: ::fsblkcnt_t, ++ pub f_bavail: ::fsblkcnt_t, ++ pub f_files: ::fsblkcnt_t, ++ pub f_ffree: ::fsblkcnt_t, ++ pub f_fsid: ::fsid64_t, ++ pub f_vfstype: ::c_int, ++ pub f_fsize: ::c_ulong, ++ pub f_vfsnumber: ::c_int, ++ pub f_vfsoff: ::c_int, ++ pub f_vfslen: ::c_int, ++ pub f_vfsvers: ::c_int, ++ pub f_fname: [::c_char; 32], ++ pub f_fpack: [::c_char; 32], ++ pub f_name_max: ::c_int, ++ } ++ ++ pub struct aiocb { ++ pub aio_lio_opcode: ::c_int, ++ pub aio_fildes: ::c_int, ++ pub aio_word1: ::c_int, ++ pub aio_offset: ::off_t, ++ pub aio_buf: *mut ::c_void, ++ pub aio_return: ::ssize_t, ++ pub aio_errno: ::c_int, ++ pub aio_nbytes: ::size_t, ++ pub aio_reqprio: ::c_int, ++ pub aio_sigevent: ::sigevent, ++ pub aio_word2: ::c_int, ++ pub aio_fp: ::c_int, ++ pub aio_handle: *mut aiocb, ++ pub aio_reserved: [::c_uint; 2], ++ pub aio_sigev_tid: c_long, ++ } ++ ++ pub struct ucontext_t { ++ pub __sc_onstack: ::c_int, ++ pub uc_sigmask: ::sigset_t, ++ pub __sc_uerror: ::c_int, ++ pub uc_mcontext: ::mcontext_t, ++ pub uc_link: *mut ucontext_t, ++ pub uc_stack: ::stack_t, ++ // Should be pointer to __extctx_t ++ pub __extctx: *mut ::c_void, ++ pub __extctx_magic: ::c_int, ++ pub __pad: [::c_int; 1], ++ } ++ ++ pub struct mcontext_t { ++ pub gpr: [::c_ulonglong; 32], ++ pub msr: ::c_ulonglong, ++ pub iar: ::c_ulonglong, ++ pub lr: ::c_ulonglong, ++ pub ctr: ::c_ulonglong, ++ pub cr: ::c_uint, ++ pub xer: ::c_uint, ++ pub fpscr: ::c_uint, ++ pub fpscrx: ::c_uint, ++ pub except: [::c_ulonglong; 1], ++ // Should be array of double type ++ pub fpr: [::uint64_t; 32], ++ pub fpeu: ::c_char, ++ pub fpinfo: ::c_char, ++ pub fpscr24_31: ::c_char, ++ pub pad: [::c_char; 1], ++ pub excp_type: ::c_int, ++ } ++ ++ pub struct utmpx { ++ pub ut_user: [::c_char; 256], ++ pub ut_id: [::c_char; 14], ++ pub ut_line: [::c_char; 64], ++ pub ut_pid: ::pid_t, ++ pub ut_type: ::c_short, ++ pub ut_tv: ::timeval, ++ pub ut_host: [::c_char; 256], ++ pub __dbl_word_pad: ::c_int, ++ pub __reservedA: [::c_int; 2], ++ pub __reservedV: [::c_int; 6], ++ } ++ ++ pub struct pthread_spinlock_t { ++ pub __sp_word: [::c_long; 3], ++ } ++ ++ pub struct pthread_barrier_t { ++ pub __br_word: [::c_long; 5], ++ } ++ ++ pub struct msqid_ds { ++ pub msg_perm: ::ipc_perm, ++ pub msg_first: ::c_uint, ++ pub msg_last: ::c_uint, ++ pub msg_cbytes: ::c_uint, ++ pub msg_qnum: ::c_uint, ++ pub msg_qbytes: ::c_ulong, ++ pub msg_lspid: ::pid_t, ++ pub msg_lrpid: ::pid_t, ++ pub msg_stime: ::time_t, ++ pub msg_rtime: ::time_t, ++ pub msg_ctime: ::time_t, ++ pub msg_rwait: ::c_int, ++ pub msg_wwait: ::c_int, ++ pub msg_reqevents: ::c_ushort, ++ } ++} ++ ++s_no_extra_traits! { ++ pub struct siginfo_t { ++ pub si_signo: ::c_int, ++ pub si_errno: ::c_int, ++ pub si_code: ::c_int, ++ pub si_pid: ::pid_t, ++ pub si_uid: ::uid_t, ++ pub si_status: ::c_int, ++ pub si_addr: *mut ::c_void, ++ pub si_band: ::c_long, ++ pub si_value: ::sigval, ++ pub __si_flags: ::c_int, ++ pub __pad: [::c_int; 3], ++ } ++ ++ #[cfg(libc_union)] ++ pub union _kernel_simple_lock { ++ pub _slock: ::c_long, ++ // Should be pointer to 'lock_data_instrumented' ++ pub _slockp: *mut ::c_void, ++ } ++ ++ pub struct fileops_t { ++ pub fo_rw: extern fn(file: *mut file, rw: ::uio_rw, io: *mut ::c_void, ext: ::c_long, ++ secattr: *mut ::c_void) -> ::c_int, ++ pub fo_ioctl: extern fn(file: *mut file, a: ::c_long, b: ::caddr_t, c: ::c_long, ++ d: ::c_long) -> ::c_int, ++ pub fo_select: extern fn(file: *mut file, a: ::c_int, b: *mut ::c_ushort, ++ c: extern fn()) -> ::c_int, ++ pub fo_close: extern fn(file: *mut file) -> ::c_int, ++ pub fo_fstat: extern fn(file: *mut file, sstat: *mut ::stat) -> ::c_int, ++ } ++ ++ pub struct file { ++ pub f_flag: ::c_long, ++ pub f_count: ::c_int, ++ pub f_options: ::c_short, ++ pub f_type: ::c_short, ++ // Should be pointer to 'vnode' ++ pub f_data: *mut ::c_void, ++ pub f_offset: ::c_longlong, ++ pub f_dir_off: ::c_long, ++ // Should be pointer to 'cred' ++ pub f_cred: *mut ::c_void, ++ #[cfg(libc_union)] ++ pub f_lock: _kernel_simple_lock, ++ #[cfg(libc_union)] ++ pub f_offset_lock: _kernel_simple_lock, ++ pub f_vinfo: ::caddr_t, ++ pub f_ops: *mut fileops_t, ++ pub f_parentp: ::caddr_t, ++ pub f_fnamep: ::caddr_t, ++ pub f_fdata: [::c_char; 160], ++ } ++ ++ #[cfg(libc_union)] ++ pub union __ld_info_file { ++ pub _ldinfo_fd: ::c_int, ++ pub _ldinfo_fp: *mut file, ++ pub _core_offset: ::c_long, ++ } ++ ++ pub struct ld_info { ++ pub ldinfo_next: ::c_uint, ++ pub ldinfo_flags: ::c_uint, ++ #[cfg(libc_union)] ++ pub _file: __ld_info_file, ++ pub ldinfo_textorg: *mut ::c_void, ++ pub ldinfo_textsize: ::c_ulong, ++ pub ldinfo_dataorg: *mut ::c_void, ++ pub ldinfo_datasize: ::c_ulong, ++ pub ldinfo_filename: [::c_char; 2], ++ } ++ ++ #[cfg(libc_union)] ++ pub union __pollfd_ext_u { ++ pub addr: *mut ::c_void, ++ pub data32: u32, ++ pub data: u64, ++ } ++ ++ pub struct pollfd_ext { ++ pub fd: ::c_int, ++ pub events: ::c_ushort, ++ pub revents: ::c_ushort, ++ #[cfg(libc_union)] ++ pub data: __pollfd_ext_u, ++ } ++} ++ ++impl siginfo_t { ++ pub unsafe fn si_addr(&self) -> *mut ::c_void { ++ self.si_addr ++ } ++ ++ pub unsafe fn si_value(&self) -> ::sigval { ++ self.si_value ++ } ++ ++ pub unsafe fn si_pid(&self) -> ::pid_t { ++ self.si_pid ++ } ++ ++ pub unsafe fn si_uid(&self) -> ::uid_t { ++ self.si_uid ++ } ++ ++ pub unsafe fn si_status(&self) -> ::c_int { ++ self.si_status ++ } ++} ++ ++cfg_if! { ++ if #[cfg(feature = "extra_traits")] { ++ impl PartialEq for siginfo_t { ++ fn eq(&self, other: &siginfo_t) -> bool { ++ #[cfg(libc_union)] ++ let value_eq = self.si_value == other.si_value; ++ #[cfg(not(libc_union))] ++ let value_eq = true; ++ self.si_signo == other.si_signo ++ && self.si_errno == other.si_errno ++ && self.si_code == other.si_code ++ && self.si_pid == other.si_pid ++ && self.si_uid == other.si_uid ++ && self.si_status == other.si_status ++ && self.si_addr == other.si_addr ++ && self.si_band == other.si_band ++ && self.__si_flags == other.__si_flags ++ && value_eq ++ } ++ } ++ impl Eq for siginfo_t {} ++ impl ::fmt::Debug for siginfo_t { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let mut struct_formatter = f.debug_struct("siginfo_t"); ++ struct_formatter.field("si_signo", &self.si_signo); ++ struct_formatter.field("si_errno", &self.si_errno); ++ struct_formatter.field("si_code", &self.si_code); ++ struct_formatter.field("si_pid", &self.si_pid); ++ struct_formatter.field("si_uid", &self.si_uid); ++ struct_formatter.field("si_status", &self.si_status); ++ struct_formatter.field("si_addr", &self.si_addr); ++ struct_formatter.field("si_band", &self.si_band); ++ #[cfg(libc_union)] ++ struct_formatter.field("si_value", &self.si_value); ++ struct_formatter.field("__si_flags", &self.__si_flags); ++ struct_formatter.finish() ++ } ++ } ++ impl ::hash::Hash for siginfo_t { ++ fn hash(&self, state: &mut H) { ++ self.si_signo.hash(state); ++ self.si_errno.hash(state); ++ self.si_code.hash(state); ++ self.si_pid.hash(state); ++ self.si_uid.hash(state); ++ self.si_status.hash(state); ++ self.si_addr.hash(state); ++ self.si_band.hash(state); ++ #[cfg(libc_union)] ++ self.si_value.hash(state); ++ self.__si_flags.hash(state); ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl PartialEq for _kernel_simple_lock { ++ fn eq(&self, other: &_kernel_simple_lock) -> bool { ++ unsafe { ++ self._slock == other._slock ++ && self._slockp == other._slockp ++ } ++ } ++ } ++ #[cfg(libc_union)] ++ impl Eq for _kernel_simple_lock {} ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for _kernel_simple_lock { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("_kernel_simple_lock") ++ .field("_slock", unsafe { &self._slock }) ++ .field("_slockp", unsafe { &self._slockp }) ++ .finish() ++ } ++ } ++ #[cfg(libc_union)] ++ impl ::hash::Hash for _kernel_simple_lock { ++ fn hash(&self, state: &mut H) { ++ unsafe { ++ self._slock.hash(state); ++ self._slockp.hash(state); ++ } ++ } ++ } ++ ++ impl PartialEq for fileops_t { ++ fn eq(&self, other: &fileops_t) -> bool { ++ self.fo_rw == other.fo_rw ++ && self.fo_ioctl == other.fo_ioctl ++ && self.fo_select == other.fo_select ++ && self.fo_close == other.fo_close ++ && self.fo_fstat == other.fo_fstat ++ } ++ } ++ impl Eq for fileops_t {} ++ impl ::fmt::Debug for fileops_t { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let mut struct_formatter = f.debug_struct("fileops_t"); ++ struct_formatter.field("fo_rw", &self.fo_rw); ++ struct_formatter.field("fo_ioctl", &self.fo_ioctl); ++ struct_formatter.field("fo_select", &self.fo_select); ++ struct_formatter.field("fo_close", &self.fo_close); ++ struct_formatter.field("fo_fstat", &self.fo_fstat); ++ struct_formatter.finish() ++ } ++ } ++ impl ::hash::Hash for fileops_t { ++ fn hash(&self, state: &mut H) { ++ self.fo_rw.hash(state); ++ self.fo_ioctl.hash(state); ++ self.fo_select.hash(state); ++ self.fo_close.hash(state); ++ self.fo_fstat.hash(state); ++ } ++ } ++ ++ impl PartialEq for file { ++ fn eq(&self, other: &file) -> bool { ++ #[cfg(libc_union)] ++ let lock_eq = self.f_lock == other.f_lock ++ && self.f_offset_lock == other.f_offset_lock; ++ #[cfg(not(libc_union))] ++ let lock_eq = true; ++ self.f_flag == other.f_flag ++ && self.f_count == other.f_count ++ && self.f_options == other.f_options ++ && self.f_type == other.f_type ++ && self.f_data == other.f_data ++ && self.f_offset == other.f_offset ++ && self.f_dir_off == other.f_dir_off ++ && self.f_cred == other.f_cred ++ && self.f_vinfo == other.f_vinfo ++ && self.f_ops == other.f_ops ++ && self.f_parentp == other.f_parentp ++ && self.f_fnamep == other.f_fnamep ++ && self.f_fdata == other.f_fdata ++ && lock_eq ++ } ++ } ++ impl Eq for file {} ++ impl ::fmt::Debug for file { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let mut struct_formatter = f.debug_struct("file"); ++ struct_formatter.field("f_flag", &self.f_flag); ++ struct_formatter.field("f_count", &self.f_count); ++ struct_formatter.field("f_options", &self.f_options); ++ struct_formatter.field("f_type", &self.f_type); ++ struct_formatter.field("f_data", &self.f_data); ++ struct_formatter.field("f_offset", &self.f_offset); ++ struct_formatter.field("f_dir_off", &self.f_dir_off); ++ struct_formatter.field("f_cred", &self.f_cred); ++ #[cfg(libc_union)] ++ struct_formatter.field("f_lock", &self.f_lock); ++ #[cfg(libc_union)] ++ struct_formatter.field("f_offset_lock", &self.f_offset_lock); ++ struct_formatter.field("f_vinfo", &self.f_vinfo); ++ struct_formatter.field("f_ops", &self.f_ops); ++ struct_formatter.field("f_parentp", &self.f_parentp); ++ struct_formatter.field("f_fnamep", &self.f_fnamep); ++ struct_formatter.field("f_fdata", &self.f_fdata); ++ struct_formatter.finish() ++ } ++ } ++ impl ::hash::Hash for file { ++ fn hash(&self, state: &mut H) { ++ self.f_flag.hash(state); ++ self.f_count.hash(state); ++ self.f_options.hash(state); ++ self.f_type.hash(state); ++ self.f_data.hash(state); ++ self.f_offset.hash(state); ++ self.f_dir_off.hash(state); ++ self.f_cred.hash(state); ++ #[cfg(libc_union)] ++ self.f_lock.hash(state); ++ #[cfg(libc_union)] ++ self.f_offset_lock.hash(state); ++ self.f_vinfo.hash(state); ++ self.f_ops.hash(state); ++ self.f_parentp.hash(state); ++ self.f_fnamep.hash(state); ++ self.f_fdata.hash(state); ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl PartialEq for __ld_info_file { ++ fn eq(&self, other: &__ld_info_file) -> bool { ++ unsafe { ++ self._ldinfo_fd == other._ldinfo_fd ++ && self._ldinfo_fp == other._ldinfo_fp ++ && self._core_offset == other._core_offset ++ } ++ } ++ } ++ #[cfg(libc_union)] ++ impl Eq for __ld_info_file {} ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for __ld_info_file { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("__ld_info_file") ++ .field("_ldinfo_fd", unsafe { &self._ldinfo_fd }) ++ .field("_ldinfo_fp", unsafe { &self._ldinfo_fp }) ++ .field("_core_offset", unsafe { &self._core_offset }) ++ .finish() ++ } ++ } ++ #[cfg(libc_union)] ++ impl ::hash::Hash for __ld_info_file { ++ fn hash(&self, state: &mut H) { ++ unsafe { ++ self._ldinfo_fd.hash(state); ++ self._ldinfo_fp.hash(state); ++ self._core_offset.hash(state); ++ } ++ } ++ } ++ ++ impl PartialEq for ld_info { ++ fn eq(&self, other: &ld_info) -> bool { ++ #[cfg(libc_union)] ++ let file_eq = self._file == other._file; ++ #[cfg(not(libc_union))] ++ let file_eq = true; ++ self.ldinfo_next == other.ldinfo_next ++ && self.ldinfo_flags == other.ldinfo_flags ++ && self.ldinfo_textorg == other.ldinfo_textorg ++ && self.ldinfo_textsize == other.ldinfo_textsize ++ && self.ldinfo_dataorg == other.ldinfo_dataorg ++ && self.ldinfo_datasize == other.ldinfo_datasize ++ && self.ldinfo_filename == other.ldinfo_filename ++ && file_eq ++ } ++ } ++ impl Eq for ld_info {} ++ impl ::fmt::Debug for ld_info { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let mut struct_formatter = f.debug_struct("ld_info"); ++ struct_formatter.field("ldinfo_next", &self.ldinfo_next); ++ struct_formatter.field("ldinfo_flags", &self.ldinfo_flags); ++ struct_formatter.field("ldinfo_textorg", &self.ldinfo_textorg); ++ struct_formatter.field("ldinfo_textsize", &self.ldinfo_textsize); ++ struct_formatter.field("ldinfo_dataorg", &self.ldinfo_dataorg); ++ struct_formatter.field("ldinfo_datasize", &self.ldinfo_datasize); ++ struct_formatter.field("ldinfo_filename", &self.ldinfo_filename); ++ #[cfg(libc_union)] ++ struct_formatter.field("_file", &self._file); ++ struct_formatter.finish() ++ } ++ } ++ impl ::hash::Hash for ld_info { ++ fn hash(&self, state: &mut H) { ++ self.ldinfo_next.hash(state); ++ self.ldinfo_flags.hash(state); ++ self.ldinfo_textorg.hash(state); ++ self.ldinfo_textsize.hash(state); ++ self.ldinfo_dataorg.hash(state); ++ self.ldinfo_datasize.hash(state); ++ self.ldinfo_filename.hash(state); ++ #[cfg(libc_union)] ++ self._file.hash(state); ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl PartialEq for __pollfd_ext_u { ++ fn eq(&self, other: &__pollfd_ext_u) -> bool { ++ unsafe { ++ self.addr == other.addr ++ && self.data32 == other.data32 ++ && self.data == other.data ++ } ++ } ++ } ++ #[cfg(libc_union)] ++ impl Eq for __pollfd_ext_u {} ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for __pollfd_ext_u { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("__pollfd_ext_u") ++ .field("addr", unsafe { &self.addr }) ++ .field("data32", unsafe { &self.data32 }) ++ .field("data", unsafe { &self.data }) ++ .finish() ++ } ++ } ++ #[cfg(libc_union)] ++ impl ::hash::Hash for __pollfd_ext_u { ++ fn hash(&self, state: &mut H) { ++ unsafe { ++ self.addr.hash(state); ++ self.data.hash(state); ++ self.data32.hash(state); ++ } ++ } ++ } ++ ++ impl PartialEq for pollfd_ext { ++ fn eq(&self, other: &pollfd_ext) -> bool { ++ #[cfg(libc_union)] ++ let data_eq = self.data == other.data; ++ #[cfg(not(libc_union))] ++ let data_eq = true; ++ self.fd == other.fd ++ && self.events == other.events ++ && self.revents == other.revents ++ && data_eq ++ } ++ } ++ impl Eq for pollfd_ext {} ++ impl ::fmt::Debug for pollfd_ext { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let mut struct_formatter = f.debug_struct("pollfd_ext"); ++ struct_formatter.field("fd", &self.fd); ++ struct_formatter.field("events", &self.events); ++ struct_formatter.field("revents", &self.revents); ++ #[cfg(libc_union)] ++ struct_formatter.field("data", &self.data); ++ struct_formatter.finish() ++ } ++ } ++ impl ::hash::Hash for pollfd_ext { ++ fn hash(&self, state: &mut H) { ++ self.fd.hash(state); ++ self.events.hash(state); ++ self.revents.hash(state); ++ #[cfg(libc_union)] ++ self.data.hash(state); ++ } ++ } ++ } ++} ++ ++pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { ++ __mt_word: [0, 2, 0, 0, 0, 0, 0, 0], ++}; ++pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { ++ __cv_word: [0, 0, 0, 0, 2, 0], ++}; ++pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { ++ __rw_word: [2, 0, 0, 0, 0, 0, 0, 0, 0, 0], ++}; ++pub const RLIM_INFINITY: ::c_ulong = 0x7fffffffffffffff; ++ ++extern "C" { ++ pub fn getsystemcfg(label: ::c_int) -> ::c_ulong; ++} +diff --git a/vendor/libc/src/unix/bsd/apple/b32/mod.rs b/vendor/libc/src/unix/bsd/apple/b32/mod.rs +index 9248e3a..0f1722f 100644 +--- a/vendor/libc/src/unix/bsd/apple/b32/mod.rs ++++ b/vendor/libc/src/unix/bsd/apple/b32/mod.rs +@@ -43,6 +43,10 @@ s! { + pub bh_datalen: u32, + pub bh_hdrlen: ::c_ushort, + } ++ ++ pub struct malloc_zone_t { ++ __private: [::uintptr_t; 18], // FIXME: keeping private for now ++ } + } + + s_no_extra_traits! { +diff --git a/vendor/libc/src/unix/bsd/apple/b64/aarch64/align.rs b/vendor/libc/src/unix/bsd/apple/b64/aarch64/align.rs +index 10d5503..29db97e 100644 +--- a/vendor/libc/src/unix/bsd/apple/b64/aarch64/align.rs ++++ b/vendor/libc/src/unix/bsd/apple/b64/aarch64/align.rs +@@ -15,6 +15,7 @@ s! { + pub uc_link: *mut ::ucontext_t, + pub uc_mcsize: usize, + pub uc_mcontext: mcontext_t, ++ __mcontext_data: __darwin_mcontext64, + } + + pub struct __darwin_mcontext64 { +@@ -39,8 +40,15 @@ s! { + pub __pad: u32, + } + +- #[repr(align(16))] ++ // This type natively uses a uint128, but for a while we hacked ++ // it in with repr(align) and `[u64; 2]`. uint128 isn't available ++ // all the way back to our earliest supported versions so we ++ // preserver the old shim. ++ #[cfg_attr(not(libc_int128), repr(align(16)))] + pub struct __darwin_arm_neon_state64 { ++ #[cfg(libc_int128)] ++ pub __v: [::__uint128_t; 32], ++ #[cfg(not(libc_int128))] + pub __v: [[u64; 2]; 32], + pub __fpsr: u32, + pub __fpcr: u32, +diff --git a/vendor/libc/src/unix/bsd/apple/b64/aarch64/mod.rs b/vendor/libc/src/unix/bsd/apple/b64/aarch64/mod.rs +index 83b62e9..79e9ac8 100644 +--- a/vendor/libc/src/unix/bsd/apple/b64/aarch64/mod.rs ++++ b/vendor/libc/src/unix/bsd/apple/b64/aarch64/mod.rs +@@ -1,5 +1,11 @@ + pub type boolean_t = ::c_int; + ++s! { ++ pub struct malloc_zone_t { ++ __private: [::uintptr_t; 18], // FIXME: needs arm64 auth pointers support ++ } ++} ++ + cfg_if! { + if #[cfg(libc_align)] { + mod align; +diff --git a/vendor/libc/src/unix/bsd/apple/b64/x86_64/mod.rs b/vendor/libc/src/unix/bsd/apple/b64/x86_64/mod.rs +index 0786666..653650c 100644 +--- a/vendor/libc/src/unix/bsd/apple/b64/x86_64/mod.rs ++++ b/vendor/libc/src/unix/bsd/apple/b64/x86_64/mod.rs +@@ -102,6 +102,74 @@ s! { + pub struct __darwin_xmm_reg { + pub __xmm_reg: [::c_char; 16], + } ++ ++ pub struct malloc_introspection_t { ++ _private: [::uintptr_t; 16], // FIXME: keeping private for now ++ } ++ ++ pub struct malloc_zone_t { ++ _reserved1: *mut ::c_void, ++ _reserved2: *mut ::c_void, ++ pub size: ::Option ::size_t>, ++ pub malloc: ::Option *mut ::c_void>, ++ pub calloc: ::Option *mut ::c_void>, ++ pub valloc: ::Option *mut ::c_void>, ++ pub free: ::Option, ++ pub realloc: ::Option *mut ::c_void>, ++ pub destroy: ::Option, ++ pub zone_name: *const ::c_char, ++ pub batch_malloc: ::Option ::c_uint>, ++ pub batch_free: ::Option, ++ pub introspect: *mut malloc_introspection_t, ++ pub version: ::c_uint, ++ pub memalign: ::Option *mut ::c_void>, ++ pub free_definite_size: ::Option, ++ pub pressure_relief: ::Option ::size_t>, ++ pub claimed_address: ::Option ::boolean_t>, ++ } + } + + cfg_if! { +diff --git a/vendor/libc/src/unix/bsd/apple/long_array.rs b/vendor/libc/src/unix/bsd/apple/long_array.rs +new file mode 100644 +index 0000000..4c56a27 +--- /dev/null ++++ b/vendor/libc/src/unix/bsd/apple/long_array.rs +@@ -0,0 +1,8 @@ ++s! { ++ pub struct ctl_info { ++ pub ctl_id: u32, ++ pub ctl_name: [::c_char; MAX_KCTL_NAME], ++ } ++} ++ ++pub const MAX_KCTL_NAME: usize = 96; +diff --git a/vendor/libc/src/unix/bsd/apple/mod.rs b/vendor/libc/src/unix/bsd/apple/mod.rs +index 9cfe16c..3348a7a 100644 +--- a/vendor/libc/src/unix/bsd/apple/mod.rs ++++ b/vendor/libc/src/unix/bsd/apple/mod.rs +@@ -30,6 +30,13 @@ pub type natural_t = u32; + pub type mach_msg_type_number_t = natural_t; + pub type kern_return_t = ::c_int; + pub type uuid_t = [u8; 16]; ++pub type task_info_t = *mut integer_t; ++pub type host_info_t = *mut integer_t; ++pub type task_flavor_t = natural_t; ++pub type rusage_info_t = *mut ::c_void; ++pub type vm_offset_t = ::uintptr_t; ++pub type vm_size_t = ::uintptr_t; ++pub type vm_address_t = vm_offset_t; + + pub type posix_spawnattr_t = *mut ::c_void; + pub type posix_spawn_file_actions_t = *mut ::c_void; +@@ -40,7 +47,27 @@ pub type sae_associd_t = u32; + pub type sae_connid_t = u32; + + pub type mach_port_t = ::c_uint; ++pub type host_t = ::c_uint; ++pub type host_flavor_t = integer_t; ++pub type host_info64_t = *mut integer_t; + pub type processor_flavor_t = ::c_int; ++pub type thread_flavor_t = natural_t; ++pub type thread_inspect_t = ::mach_port_t; ++pub type thread_act_t = ::mach_port_t; ++pub type thread_act_array_t = *mut ::thread_act_t; ++pub type policy_t = ::c_int; ++pub type mach_vm_address_t = u64; ++pub type mach_vm_offset_t = u64; ++pub type mach_vm_size_t = u64; ++pub type vm_map_t = ::mach_port_t; ++pub type mem_entry_name_port_t = ::mach_port_t; ++pub type memory_object_t = ::mach_port_t; ++pub type memory_object_offset_t = ::c_ulonglong; ++pub type vm_inherit_t = ::c_uint; ++pub type vm_prot_t = ::c_int; ++ ++pub type ledger_t = ::mach_port_t; ++pub type ledger_array_t = *mut ::ledger_t; + + pub type iconv_t = *mut ::c_void; + +@@ -55,7 +82,20 @@ pub type processor_set_load_info_t = *mut processor_set_load_info; + pub type processor_info_t = *mut integer_t; + pub type processor_info_array_t = *mut integer_t; + +-pub type thread_t = mach_port_t; ++pub type mach_task_basic_info_data_t = mach_task_basic_info; ++pub type mach_task_basic_info_t = *mut mach_task_basic_info; ++pub type task_thread_times_info_data_t = task_thread_times_info; ++pub type task_thread_times_info_t = *mut task_thread_times_info; ++ ++pub type thread_info_t = *mut integer_t; ++pub type thread_basic_info_t = *mut thread_basic_info; ++pub type thread_basic_info_data_t = thread_basic_info; ++pub type thread_identifier_info_t = *mut thread_identifier_info; ++pub type thread_identifier_info_data_t = thread_identifier_info; ++pub type thread_extended_info_t = *mut thread_extended_info; ++pub type thread_extended_info_data_t = thread_extended_info; ++ ++pub type thread_t = ::mach_port_t; + pub type thread_policy_flavor_t = natural_t; + pub type thread_policy_t = *mut integer_t; + pub type thread_latency_qos_t = integer_t; +@@ -77,9 +117,39 @@ pub type thread_latency_qos_policy_t = *mut thread_latency_qos_policy; + pub type thread_throughput_qos_policy_data_t = thread_throughput_qos_policy; + pub type thread_throughput_qos_policy_t = *mut thread_throughput_qos_policy; + ++pub type pthread_introspection_hook_t = ++ extern "C" fn(event: ::c_uint, thread: ::pthread_t, addr: *mut ::c_void, size: ::size_t); ++pub type pthread_jit_write_callback_t = ::Option ::c_int>; ++ ++pub type os_unfair_lock = os_unfair_lock_s; ++pub type os_unfair_lock_t = *mut os_unfair_lock; ++ ++pub type os_log_t = *mut ::c_void; ++pub type os_log_type_t = u8; ++pub type os_signpost_id_t = u64; ++pub type os_signpost_type_t = u8; ++ ++pub type vm_statistics_t = *mut vm_statistics; ++pub type vm_statistics_data_t = vm_statistics; ++pub type vm_statistics64_t = *mut vm_statistics64; ++pub type vm_statistics64_data_t = vm_statistics64; ++ ++pub type task_t = ::mach_port_t; ++pub type task_inspect_t = ::mach_port_t; ++ ++pub type sysdir_search_path_enumeration_state = ::c_uint; ++ ++pub type CCStatus = i32; ++pub type CCCryptorStatus = i32; ++pub type CCRNGStatus = ::CCCryptorStatus; ++ ++pub type copyfile_state_t = *mut ::c_void; ++pub type copyfile_flags_t = u32; ++ ++pub type attrgroup_t = u32; ++pub type vol_capabilities_set_t = [u32; 4]; ++ + deprecated_mach! { +- pub type vm_prot_t = ::c_int; +- pub type vm_size_t = ::uintptr_t; + pub type mach_timebase_info_data_t = mach_timebase_info; + } + +@@ -109,12 +179,75 @@ impl ::Clone for qos_class_t { + } + } + ++#[cfg_attr(feature = "extra_traits", derive(Debug))] ++#[repr(u32)] ++pub enum sysdir_search_path_directory_t { ++ SYSDIR_DIRECTORY_APPLICATION = 1, ++ SYSDIR_DIRECTORY_DEMO_APPLICATION = 2, ++ SYSDIR_DIRECTORY_DEVELOPER_APPLICATION = 3, ++ SYSDIR_DIRECTORY_ADMIN_APPLICATION = 4, ++ SYSDIR_DIRECTORY_LIBRARY = 5, ++ SYSDIR_DIRECTORY_DEVELOPER = 6, ++ SYSDIR_DIRECTORY_USER = 7, ++ SYSDIR_DIRECTORY_DOCUMENTATION = 8, ++ SYSDIR_DIRECTORY_DOCUMENT = 9, ++ SYSDIR_DIRECTORY_CORESERVICE = 10, ++ SYSDIR_DIRECTORY_AUTOSAVED_INFORMATION = 11, ++ SYSDIR_DIRECTORY_DESKTOP = 12, ++ SYSDIR_DIRECTORY_CACHES = 13, ++ SYSDIR_DIRECTORY_APPLICATION_SUPPORT = 14, ++ SYSDIR_DIRECTORY_DOWNLOADS = 15, ++ SYSDIR_DIRECTORY_INPUT_METHODS = 16, ++ SYSDIR_DIRECTORY_MOVIES = 17, ++ SYSDIR_DIRECTORY_MUSIC = 18, ++ SYSDIR_DIRECTORY_PICTURES = 19, ++ SYSDIR_DIRECTORY_PRINTER_DESCRIPTION = 20, ++ SYSDIR_DIRECTORY_SHARED_PUBLIC = 21, ++ SYSDIR_DIRECTORY_PREFERENCE_PANES = 22, ++ SYSDIR_DIRECTORY_ALL_APPLICATIONS = 100, ++ SYSDIR_DIRECTORY_ALL_LIBRARIES = 101, ++} ++impl ::Copy for sysdir_search_path_directory_t {} ++impl ::Clone for sysdir_search_path_directory_t { ++ fn clone(&self) -> sysdir_search_path_directory_t { ++ *self ++ } ++} ++ ++#[cfg_attr(feature = "extra_traits", derive(Debug))] ++#[repr(u32)] ++pub enum sysdir_search_path_domain_mask_t { ++ SYSDIR_DOMAIN_MASK_USER = (1 << 0), ++ SYSDIR_DOMAIN_MASK_LOCAL = (1 << 1), ++ SYSDIR_DOMAIN_MASK_NETWORK = (1 << 2), ++ SYSDIR_DOMAIN_MASK_SYSTEM = (1 << 3), ++ SYSDIR_DOMAIN_MASK_ALL = 0x0ffff, ++} ++impl ::Copy for sysdir_search_path_domain_mask_t {} ++impl ::Clone for sysdir_search_path_domain_mask_t { ++ fn clone(&self) -> sysdir_search_path_domain_mask_t { ++ *self ++ } ++} ++ + s! { + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + ++ pub struct ip_mreqn { ++ pub imr_multiaddr: in_addr, ++ pub imr_address: in_addr, ++ pub imr_ifindex: ::c_int, ++ } ++ ++ pub struct ip_mreq_source { ++ pub imr_multiaddr: in_addr, ++ pub imr_sourceaddr: in_addr, ++ pub imr_interface: in_addr, ++ } ++ + pub struct aiocb { + pub aio_fildes: ::c_int, + pub aio_offset: ::off_t, +@@ -154,7 +287,7 @@ s! { + + #[deprecated( + since = "0.2.55", +- note = "Use the `mach` crate instead", ++ note = "Use the `mach2` crate instead", + )] + pub struct mach_timebase_info { + pub numer: u32, +@@ -422,7 +555,7 @@ s! { + + #[deprecated( + since = "0.2.55", +- note = "Use the `mach` crate instead", ++ note = "Use the `mach2` crate instead", + )] + pub struct mach_header { + pub magic: u32, +@@ -436,7 +569,7 @@ s! { + + #[deprecated( + since = "0.2.55", +- note = "Use the `mach` crate instead", ++ note = "Use the `mach2` crate instead", + )] + pub struct mach_header_64 { + pub magic: u32, +@@ -557,6 +690,13 @@ s! { + pub s_addr: ::in_addr_t, + } + ++ // net/ndrv.h ++ pub struct sockaddr_ndrv { ++ pub snd_len: ::c_uchar, ++ pub snd_family: ::c_uchar, ++ pub snd_name: [::c_uchar; 16] // IFNAMSIZ from if.h ++ } ++ + // sys/socket.h + + pub struct sa_endpoints_t { +@@ -645,6 +785,247 @@ s! { + pub chunks_free: ::size_t, + pub bytes_free: ::size_t, + } ++ ++ pub struct vm_range_t { ++ pub address: ::vm_address_t, ++ pub size: ::vm_size_t, ++ } ++ ++ // sched.h ++ pub struct sched_param { ++ pub sched_priority: ::c_int, ++ __opaque: [::c_char; 4], ++ } ++ ++ pub struct vinfo_stat { ++ pub vst_dev: u32, ++ pub vst_mode: u16, ++ pub vst_nlink: u16, ++ pub vst_ino: u64, ++ pub vst_uid: ::uid_t, ++ pub vst_gid: ::gid_t, ++ pub vst_atime: i64, ++ pub vst_atimensec: i64, ++ pub vst_mtime: i64, ++ pub vst_mtimensec: i64, ++ pub vst_ctime: i64, ++ pub vst_ctimensec: i64, ++ pub vst_birthtime: i64, ++ pub vst_birthtimensec: i64, ++ pub vst_size: ::off_t, ++ pub vst_blocks: i64, ++ pub vst_blksize: i32, ++ pub vst_flags: u32, ++ pub vst_gen: u32, ++ pub vst_rdev: u32, ++ pub vst_qspare: [i64; 2], ++ } ++ ++ pub struct vnode_info { ++ pub vi_stat: vinfo_stat, ++ pub vi_type: ::c_int, ++ pub vi_pad: ::c_int, ++ pub vi_fsid: ::fsid_t, ++ } ++ ++ pub struct vnode_info_path { ++ pub vip_vi: vnode_info, ++ // Normally it's `vip_path: [::c_char; MAXPATHLEN]` but because libc supports an old rustc ++ // version, we go around this limitation like this. ++ pub vip_path: [[::c_char; 32]; 32], ++ } ++ ++ pub struct proc_vnodepathinfo { ++ pub pvi_cdir: vnode_info_path, ++ pub pvi_rdir: vnode_info_path, ++ } ++ ++ pub struct vm_statistics { ++ pub free_count: natural_t, ++ pub active_count: natural_t, ++ pub inactive_count: natural_t, ++ pub wire_count: natural_t, ++ pub zero_fill_count: natural_t, ++ pub reactivations: natural_t, ++ pub pageins: natural_t, ++ pub pageouts: natural_t, ++ pub faults: natural_t, ++ pub cow_faults: natural_t, ++ pub lookups: natural_t, ++ pub hits: natural_t, ++ pub purgeable_count: natural_t, ++ pub purges: natural_t, ++ pub speculative_count: natural_t, ++ } ++ ++ pub struct task_thread_times_info { ++ pub user_time: time_value_t, ++ pub system_time: time_value_t, ++ } ++ ++ pub struct rusage_info_v0 { ++ pub ri_uuid: [u8; 16], ++ pub ri_user_time: u64, ++ pub ri_system_time: u64, ++ pub ri_pkg_idle_wkups: u64, ++ pub ri_interrupt_wkups: u64, ++ pub ri_pageins: u64, ++ pub ri_wired_size: u64, ++ pub ri_resident_size: u64, ++ pub ri_phys_footprint: u64, ++ pub ri_proc_start_abstime: u64, ++ pub ri_proc_exit_abstime: u64, ++ } ++ ++ pub struct rusage_info_v1 { ++ pub ri_uuid: [u8; 16], ++ pub ri_user_time: u64, ++ pub ri_system_time: u64, ++ pub ri_pkg_idle_wkups: u64, ++ pub ri_interrupt_wkups: u64, ++ pub ri_pageins: u64, ++ pub ri_wired_size: u64, ++ pub ri_resident_size: u64, ++ pub ri_phys_footprint: u64, ++ pub ri_proc_start_abstime: u64, ++ pub ri_proc_exit_abstime: u64, ++ pub ri_child_user_time: u64, ++ pub ri_child_system_time: u64, ++ pub ri_child_pkg_idle_wkups: u64, ++ pub ri_child_interrupt_wkups: u64, ++ pub ri_child_pageins: u64, ++ pub ri_child_elapsed_abstime: u64, ++ } ++ ++ pub struct rusage_info_v2 { ++ pub ri_uuid: [u8; 16], ++ pub ri_user_time: u64, ++ pub ri_system_time: u64, ++ pub ri_pkg_idle_wkups: u64, ++ pub ri_interrupt_wkups: u64, ++ pub ri_pageins: u64, ++ pub ri_wired_size: u64, ++ pub ri_resident_size: u64, ++ pub ri_phys_footprint: u64, ++ pub ri_proc_start_abstime: u64, ++ pub ri_proc_exit_abstime: u64, ++ pub ri_child_user_time: u64, ++ pub ri_child_system_time: u64, ++ pub ri_child_pkg_idle_wkups: u64, ++ pub ri_child_interrupt_wkups: u64, ++ pub ri_child_pageins: u64, ++ pub ri_child_elapsed_abstime: u64, ++ pub ri_diskio_bytesread: u64, ++ pub ri_diskio_byteswritten: u64, ++ } ++ ++ pub struct rusage_info_v3 { ++ pub ri_uuid: [u8; 16], ++ pub ri_user_time: u64, ++ pub ri_system_time: u64, ++ pub ri_pkg_idle_wkups: u64, ++ pub ri_interrupt_wkups: u64, ++ pub ri_pageins: u64, ++ pub ri_wired_size: u64, ++ pub ri_resident_size: u64, ++ pub ri_phys_footprint: u64, ++ pub ri_proc_start_abstime: u64, ++ pub ri_proc_exit_abstime: u64, ++ pub ri_child_user_time: u64, ++ pub ri_child_system_time: u64, ++ pub ri_child_pkg_idle_wkups: u64, ++ pub ri_child_interrupt_wkups: u64, ++ pub ri_child_pageins: u64, ++ pub ri_child_elapsed_abstime: u64, ++ pub ri_diskio_bytesread: u64, ++ pub ri_diskio_byteswritten: u64, ++ pub ri_cpu_time_qos_default: u64, ++ pub ri_cpu_time_qos_maintenance: u64, ++ pub ri_cpu_time_qos_background: u64, ++ pub ri_cpu_time_qos_utility: u64, ++ pub ri_cpu_time_qos_legacy: u64, ++ pub ri_cpu_time_qos_user_initiated: u64, ++ pub ri_cpu_time_qos_user_interactive: u64, ++ pub ri_billed_system_time: u64, ++ pub ri_serviced_system_time: u64, ++ } ++ ++ pub struct rusage_info_v4 { ++ pub ri_uuid: [u8; 16], ++ pub ri_user_time: u64, ++ pub ri_system_time: u64, ++ pub ri_pkg_idle_wkups: u64, ++ pub ri_interrupt_wkups: u64, ++ pub ri_pageins: u64, ++ pub ri_wired_size: u64, ++ pub ri_resident_size: u64, ++ pub ri_phys_footprint: u64, ++ pub ri_proc_start_abstime: u64, ++ pub ri_proc_exit_abstime: u64, ++ pub ri_child_user_time: u64, ++ pub ri_child_system_time: u64, ++ pub ri_child_pkg_idle_wkups: u64, ++ pub ri_child_interrupt_wkups: u64, ++ pub ri_child_pageins: u64, ++ pub ri_child_elapsed_abstime: u64, ++ pub ri_diskio_bytesread: u64, ++ pub ri_diskio_byteswritten: u64, ++ pub ri_cpu_time_qos_default: u64, ++ pub ri_cpu_time_qos_maintenance: u64, ++ pub ri_cpu_time_qos_background: u64, ++ pub ri_cpu_time_qos_utility: u64, ++ pub ri_cpu_time_qos_legacy: u64, ++ pub ri_cpu_time_qos_user_initiated: u64, ++ pub ri_cpu_time_qos_user_interactive: u64, ++ pub ri_billed_system_time: u64, ++ pub ri_serviced_system_time: u64, ++ pub ri_logical_writes: u64, ++ pub ri_lifetime_max_phys_footprint: u64, ++ pub ri_instructions: u64, ++ pub ri_cycles: u64, ++ pub ri_billed_energy: u64, ++ pub ri_serviced_energy: u64, ++ pub ri_interval_max_phys_footprint: u64, ++ pub ri_runnable_time: u64, ++ } ++ ++ pub struct image_offset { ++ pub uuid: ::uuid_t, ++ pub offset: u32, ++ } ++ ++ pub struct attrlist { ++ pub bitmapcount: ::c_ushort, ++ pub reserved: u16, ++ pub commonattr: attrgroup_t, ++ pub volattr: attrgroup_t, ++ pub dirattr: attrgroup_t, ++ pub fileattr: attrgroup_t, ++ pub forkattr: attrgroup_t, ++ } ++ ++ pub struct attrreference_t { ++ pub attr_dataoffset: i32, ++ pub attr_length: u32, ++ } ++ ++ pub struct vol_capabilities_attr_t { ++ pub capabilities: vol_capabilities_set_t, ++ pub valid: vol_capabilities_set_t, ++ } ++ ++ pub struct attribute_set_t { ++ pub commonattr: attrgroup_t, ++ pub volattr: attrgroup_t, ++ pub dirattr: attrgroup_t, ++ pub fileattr: attrgroup_t, ++ pub forkattr: attrgroup_t, ++ } ++ ++ pub struct vol_attributes_attr_t { ++ pub validattr: attribute_set_t, ++ pub nativeattr: attribute_set_t, ++ } + } + + s_no_extra_traits! { +@@ -715,7 +1096,8 @@ s_no_extra_traits! { + pub f_fstypename: [::c_char; 16], + pub f_mntonname: [::c_char; 1024], + pub f_mntfromname: [::c_char; 1024], +- pub f_reserved: [u32; 8], ++ pub f_flags_ext: u32, ++ pub f_reserved: [u32; 7], + } + + pub struct dirent { +@@ -792,6 +1174,139 @@ s_no_extra_traits! { + pub load_average: integer_t, + pub mach_factor: integer_t, + } ++ ++ pub struct time_value_t { ++ pub seconds: integer_t, ++ pub microseconds: integer_t, ++ } ++ ++ pub struct thread_basic_info { ++ pub user_time: time_value_t, ++ pub system_time: time_value_t, ++ pub cpu_usage: ::integer_t, ++ pub policy: ::policy_t, ++ pub run_state: ::integer_t, ++ pub flags: ::integer_t, ++ pub suspend_count: ::integer_t, ++ pub sleep_time: ::integer_t, ++ } ++ ++ pub struct thread_identifier_info { ++ pub thread_id: u64, ++ pub thread_handle: u64, ++ pub dispatch_qaddr: u64, ++ } ++ ++ pub struct thread_extended_info { ++ pub pth_user_time: u64, ++ pub pth_system_time: u64, ++ pub pth_cpu_usage: i32, ++ pub pth_policy: i32, ++ pub pth_run_state: i32, ++ pub pth_flags: i32, ++ pub pth_sleep_time: i32, ++ pub pth_curpri: i32, ++ pub pth_priority: i32, ++ pub pth_maxpriority: i32, ++ pub pth_name: [::c_char; MAXTHREADNAMESIZE], ++ } ++ ++ #[cfg_attr(libc_packedN, repr(packed(4)))] ++ pub struct if_data64 { ++ pub ifi_type: ::c_uchar, ++ pub ifi_typelen: ::c_uchar, ++ pub ifi_physical: ::c_uchar, ++ pub ifi_addrlen: ::c_uchar, ++ pub ifi_hdrlen: ::c_uchar, ++ pub ifi_recvquota: ::c_uchar, ++ pub ifi_xmitquota: ::c_uchar, ++ pub ifi_unused1: ::c_uchar, ++ pub ifi_mtu: u32, ++ pub ifi_metric: u32, ++ pub ifi_baudrate: u64, ++ pub ifi_ipackets: u64, ++ pub ifi_ierrors: u64, ++ pub ifi_opackets: u64, ++ pub ifi_oerrors: u64, ++ pub ifi_collisions: u64, ++ pub ifi_ibytes: u64, ++ pub ifi_obytes: u64, ++ pub ifi_imcasts: u64, ++ pub ifi_omcasts: u64, ++ pub ifi_iqdrops: u64, ++ pub ifi_noproto: u64, ++ pub ifi_recvtiming: u32, ++ pub ifi_xmittiming: u32, ++ #[cfg(target_pointer_width = "32")] ++ pub ifi_lastchange: ::timeval, ++ #[cfg(not(target_pointer_width = "32"))] ++ pub ifi_lastchange: timeval32, ++ } ++ ++ #[cfg_attr(libc_packedN, repr(packed(4)))] ++ pub struct if_msghdr2 { ++ pub ifm_msglen: ::c_ushort, ++ pub ifm_version: ::c_uchar, ++ pub ifm_type: ::c_uchar, ++ pub ifm_addrs: ::c_int, ++ pub ifm_flags: ::c_int, ++ pub ifm_index: ::c_ushort, ++ pub ifm_snd_len: ::c_int, ++ pub ifm_snd_maxlen: ::c_int, ++ pub ifm_snd_drops: ::c_int, ++ pub ifm_timer: ::c_int, ++ pub ifm_data: if_data64, ++ } ++ ++ #[cfg_attr(libc_packedN, repr(packed(8)))] ++ pub struct vm_statistics64 { ++ pub free_count: natural_t, ++ pub active_count: natural_t, ++ pub inactive_count: natural_t, ++ pub wire_count: natural_t, ++ pub zero_fill_count: u64, ++ pub reactivations: u64, ++ pub pageins: u64, ++ pub pageouts: u64, ++ pub faults: u64, ++ pub cow_faults: u64, ++ pub lookups: u64, ++ pub hits: u64, ++ pub purges: u64, ++ pub purgeable_count: natural_t, ++ pub speculative_count: natural_t, ++ pub decompressions: u64, ++ pub compressions: u64, ++ pub swapins: u64, ++ pub swapouts: u64, ++ pub compressor_page_count: natural_t, ++ pub throttled_count: natural_t, ++ pub external_page_count: natural_t, ++ pub internal_page_count: natural_t, ++ pub total_uncompressed_pages_in_compressor: u64, ++ } ++ ++ #[cfg_attr(libc_packedN, repr(packed(4)))] ++ pub struct mach_task_basic_info { ++ pub virtual_size: mach_vm_size_t, ++ pub resident_size: mach_vm_size_t, ++ pub resident_size_max: mach_vm_size_t, ++ pub user_time: time_value_t, ++ pub system_time: time_value_t, ++ pub policy: ::policy_t, ++ pub suspend_count: integer_t, ++ } ++ ++ #[cfg_attr(libc_packedN, repr(packed(4)))] ++ pub struct log2phys { ++ pub l2p_flags: ::c_uint, ++ pub l2p_contigbytes: ::off_t, ++ pub l2p_devoffset: ::off_t, ++ } ++ ++ pub struct os_unfair_lock_s { ++ _os_unfair_lock_opaque: u32, ++ } + } + + impl siginfo_t { +@@ -1506,6 +2021,594 @@ cfg_if! { + self.mach_factor.hash(state); + } + } ++ ++ impl PartialEq for time_value_t { ++ fn eq(&self, other: &time_value_t) -> bool { ++ self.seconds == other.seconds ++ && self.microseconds == other.microseconds ++ } ++ } ++ impl Eq for time_value_t {} ++ impl ::fmt::Debug for time_value_t { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("time_value_t") ++ .field("seconds", &self.seconds) ++ .field("microseconds", &self.microseconds) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for time_value_t { ++ fn hash(&self, state: &mut H) { ++ self.seconds.hash(state); ++ self.microseconds.hash(state); ++ } ++ } ++ impl PartialEq for thread_basic_info { ++ fn eq(&self, other: &thread_basic_info) -> bool { ++ self.user_time == other.user_time ++ && self.system_time == other.system_time ++ && self.cpu_usage == other.cpu_usage ++ && self.policy == other.policy ++ && self.run_state == other.run_state ++ && self.flags == other.flags ++ && self.suspend_count == other.suspend_count ++ && self.sleep_time == other.sleep_time ++ } ++ } ++ impl Eq for thread_basic_info {} ++ impl ::fmt::Debug for thread_basic_info { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("thread_basic_info") ++ .field("user_time", &self.user_time) ++ .field("system_time", &self.system_time) ++ .field("cpu_usage", &self.cpu_usage) ++ .field("policy", &self.policy) ++ .field("run_state", &self.run_state) ++ .field("flags", &self.flags) ++ .field("suspend_count", &self.suspend_count) ++ .field("sleep_time", &self.sleep_time) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for thread_basic_info { ++ fn hash(&self, state: &mut H) { ++ self.user_time.hash(state); ++ self.system_time.hash(state); ++ self.cpu_usage.hash(state); ++ self.policy.hash(state); ++ self.run_state.hash(state); ++ self.flags.hash(state); ++ self.suspend_count.hash(state); ++ self.sleep_time.hash(state); ++ } ++ } ++ impl PartialEq for thread_extended_info { ++ fn eq(&self, other: &thread_extended_info) -> bool { ++ self.pth_user_time == other.pth_user_time ++ && self.pth_system_time == other.pth_system_time ++ && self.pth_cpu_usage == other.pth_cpu_usage ++ && self.pth_policy == other.pth_policy ++ && self.pth_run_state == other.pth_run_state ++ && self.pth_flags == other.pth_flags ++ && self.pth_sleep_time == other.pth_sleep_time ++ && self.pth_curpri == other.pth_curpri ++ && self.pth_priority == other.pth_priority ++ && self.pth_maxpriority == other.pth_maxpriority ++ && self.pth_name ++ .iter() ++ .zip(other.pth_name.iter()) ++ .all(|(a,b)| a == b) ++ } ++ } ++ impl Eq for thread_extended_info {} ++ impl ::fmt::Debug for thread_extended_info { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("proc_threadinfo") ++ .field("pth_user_time", &self.pth_user_time) ++ .field("pth_system_time", &self.pth_system_time) ++ .field("pth_cpu_usage", &self.pth_cpu_usage) ++ .field("pth_policy", &self.pth_policy) ++ .field("pth_run_state", &self.pth_run_state) ++ .field("pth_flags", &self.pth_flags) ++ .field("pth_sleep_time", &self.pth_sleep_time) ++ .field("pth_curpri", &self.pth_curpri) ++ .field("pth_priority", &self.pth_priority) ++ .field("pth_maxpriority", &self.pth_maxpriority) ++ // FIXME: .field("pth_name", &self.pth_name) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for thread_extended_info { ++ fn hash(&self, state: &mut H) { ++ self.pth_user_time.hash(state); ++ self.pth_system_time.hash(state); ++ self.pth_cpu_usage.hash(state); ++ self.pth_policy.hash(state); ++ self.pth_run_state.hash(state); ++ self.pth_flags.hash(state); ++ self.pth_sleep_time.hash(state); ++ self.pth_curpri.hash(state); ++ self.pth_priority.hash(state); ++ self.pth_maxpriority.hash(state); ++ self.pth_name.hash(state); ++ } ++ } ++ impl PartialEq for thread_identifier_info { ++ fn eq(&self, other: &thread_identifier_info) -> bool { ++ self.thread_id == other.thread_id ++ && self.thread_handle == other.thread_handle ++ && self.dispatch_qaddr == other.dispatch_qaddr ++ } ++ } ++ impl Eq for thread_identifier_info {} ++ impl ::fmt::Debug for thread_identifier_info { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("thread_identifier_info") ++ .field("thread_id", &self.thread_id) ++ .field("thread_handle", &self.thread_handle) ++ .field("dispatch_qaddr", &self.dispatch_qaddr) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for thread_identifier_info { ++ fn hash(&self, state: &mut H) { ++ self.thread_id.hash(state); ++ self.thread_handle.hash(state); ++ self.dispatch_qaddr.hash(state); ++ } ++ } ++ impl PartialEq for if_data64 { ++ fn eq(&self, other: &if_data64) -> bool { ++ self.ifi_type == other.ifi_type && ++ self.ifi_typelen == other.ifi_typelen && ++ self.ifi_physical == other.ifi_physical && ++ self.ifi_addrlen == other.ifi_addrlen && ++ self.ifi_hdrlen == other.ifi_hdrlen && ++ self.ifi_recvquota == other.ifi_recvquota && ++ self.ifi_xmitquota == other.ifi_xmitquota && ++ self.ifi_unused1 == other.ifi_unused1 && ++ self.ifi_mtu == other.ifi_mtu && ++ self.ifi_metric == other.ifi_metric && ++ self.ifi_baudrate == other.ifi_baudrate && ++ self.ifi_ipackets == other.ifi_ipackets && ++ self.ifi_ierrors == other.ifi_ierrors && ++ self.ifi_opackets == other.ifi_opackets && ++ self.ifi_oerrors == other.ifi_oerrors && ++ self.ifi_collisions == other.ifi_collisions && ++ self.ifi_ibytes == other.ifi_ibytes && ++ self.ifi_obytes == other.ifi_obytes && ++ self.ifi_imcasts == other.ifi_imcasts && ++ self.ifi_omcasts == other.ifi_omcasts && ++ self.ifi_iqdrops == other.ifi_iqdrops && ++ self.ifi_noproto == other.ifi_noproto && ++ self.ifi_recvtiming == other.ifi_recvtiming && ++ self.ifi_xmittiming == other.ifi_xmittiming && ++ self.ifi_lastchange == other.ifi_lastchange ++ } ++ } ++ impl Eq for if_data64 {} ++ impl ::fmt::Debug for if_data64 { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let ifi_type = self.ifi_type; ++ let ifi_typelen = self.ifi_typelen; ++ let ifi_physical = self.ifi_physical; ++ let ifi_addrlen = self.ifi_addrlen; ++ let ifi_hdrlen = self.ifi_hdrlen; ++ let ifi_recvquota = self.ifi_recvquota; ++ let ifi_xmitquota = self.ifi_xmitquota; ++ let ifi_unused1 = self.ifi_unused1; ++ let ifi_mtu = self.ifi_mtu; ++ let ifi_metric = self.ifi_metric; ++ let ifi_baudrate = self.ifi_baudrate; ++ let ifi_ipackets = self.ifi_ipackets; ++ let ifi_ierrors = self.ifi_ierrors; ++ let ifi_opackets = self.ifi_opackets; ++ let ifi_oerrors = self.ifi_oerrors; ++ let ifi_collisions = self.ifi_collisions; ++ let ifi_ibytes = self.ifi_ibytes; ++ let ifi_obytes = self.ifi_obytes; ++ let ifi_imcasts = self.ifi_imcasts; ++ let ifi_omcasts = self.ifi_omcasts; ++ let ifi_iqdrops = self.ifi_iqdrops; ++ let ifi_noproto = self.ifi_noproto; ++ let ifi_recvtiming = self.ifi_recvtiming; ++ let ifi_xmittiming = self.ifi_xmittiming; ++ let ifi_lastchange = self.ifi_lastchange; ++ f.debug_struct("if_data64") ++ .field("ifi_type", &ifi_type) ++ .field("ifi_typelen", &ifi_typelen) ++ .field("ifi_physical", &ifi_physical) ++ .field("ifi_addrlen", &ifi_addrlen) ++ .field("ifi_hdrlen", &ifi_hdrlen) ++ .field("ifi_recvquota", &ifi_recvquota) ++ .field("ifi_xmitquota", &ifi_xmitquota) ++ .field("ifi_unused1", &ifi_unused1) ++ .field("ifi_mtu", &ifi_mtu) ++ .field("ifi_metric", &ifi_metric) ++ .field("ifi_baudrate", &ifi_baudrate) ++ .field("ifi_ipackets", &ifi_ipackets) ++ .field("ifi_ierrors", &ifi_ierrors) ++ .field("ifi_opackets", &ifi_opackets) ++ .field("ifi_oerrors", &ifi_oerrors) ++ .field("ifi_collisions", &ifi_collisions) ++ .field("ifi_ibytes", &ifi_ibytes) ++ .field("ifi_obytes", &ifi_obytes) ++ .field("ifi_imcasts", &ifi_imcasts) ++ .field("ifi_omcasts", &ifi_omcasts) ++ .field("ifi_iqdrops", &ifi_iqdrops) ++ .field("ifi_noproto", &ifi_noproto) ++ .field("ifi_recvtiming", &ifi_recvtiming) ++ .field("ifi_xmittiming", &ifi_xmittiming) ++ .field("ifi_lastchange", &ifi_lastchange) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for if_data64 { ++ fn hash(&self, state: &mut H) { ++ let ifi_type = self.ifi_type; ++ let ifi_typelen = self.ifi_typelen; ++ let ifi_physical = self.ifi_physical; ++ let ifi_addrlen = self.ifi_addrlen; ++ let ifi_hdrlen = self.ifi_hdrlen; ++ let ifi_recvquota = self.ifi_recvquota; ++ let ifi_xmitquota = self.ifi_xmitquota; ++ let ifi_unused1 = self.ifi_unused1; ++ let ifi_mtu = self.ifi_mtu; ++ let ifi_metric = self.ifi_metric; ++ let ifi_baudrate = self.ifi_baudrate; ++ let ifi_ipackets = self.ifi_ipackets; ++ let ifi_ierrors = self.ifi_ierrors; ++ let ifi_opackets = self.ifi_opackets; ++ let ifi_oerrors = self.ifi_oerrors; ++ let ifi_collisions = self.ifi_collisions; ++ let ifi_ibytes = self.ifi_ibytes; ++ let ifi_obytes = self.ifi_obytes; ++ let ifi_imcasts = self.ifi_imcasts; ++ let ifi_omcasts = self.ifi_omcasts; ++ let ifi_iqdrops = self.ifi_iqdrops; ++ let ifi_noproto = self.ifi_noproto; ++ let ifi_recvtiming = self.ifi_recvtiming; ++ let ifi_xmittiming = self.ifi_xmittiming; ++ let ifi_lastchange = self.ifi_lastchange; ++ ifi_type.hash(state); ++ ifi_typelen.hash(state); ++ ifi_physical.hash(state); ++ ifi_addrlen.hash(state); ++ ifi_hdrlen.hash(state); ++ ifi_recvquota.hash(state); ++ ifi_xmitquota.hash(state); ++ ifi_unused1.hash(state); ++ ifi_mtu.hash(state); ++ ifi_metric.hash(state); ++ ifi_baudrate.hash(state); ++ ifi_ipackets.hash(state); ++ ifi_ierrors.hash(state); ++ ifi_opackets.hash(state); ++ ifi_oerrors.hash(state); ++ ifi_collisions.hash(state); ++ ifi_ibytes.hash(state); ++ ifi_obytes.hash(state); ++ ifi_imcasts.hash(state); ++ ifi_omcasts.hash(state); ++ ifi_iqdrops.hash(state); ++ ifi_noproto.hash(state); ++ ifi_recvtiming.hash(state); ++ ifi_xmittiming.hash(state); ++ ifi_lastchange.hash(state); ++ } ++ } ++ impl PartialEq for if_msghdr2 { ++ fn eq(&self, other: &if_msghdr2) -> bool { ++ self.ifm_msglen == other.ifm_msglen && ++ self.ifm_version == other.ifm_version && ++ self.ifm_type == other.ifm_type && ++ self.ifm_addrs == other.ifm_addrs && ++ self.ifm_flags == other.ifm_flags && ++ self.ifm_index == other.ifm_index && ++ self.ifm_snd_len == other.ifm_snd_len && ++ self.ifm_snd_maxlen == other.ifm_snd_maxlen && ++ self.ifm_snd_drops == other.ifm_snd_drops && ++ self.ifm_timer == other.ifm_timer && ++ self.ifm_data == other.ifm_data ++ } ++ } ++ impl Eq for if_msghdr2 {} ++ impl ::fmt::Debug for if_msghdr2 { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let ifm_msglen = self.ifm_msglen; ++ let ifm_version = self.ifm_version; ++ let ifm_type = self.ifm_type; ++ let ifm_addrs = self.ifm_addrs; ++ let ifm_flags = self.ifm_flags; ++ let ifm_index = self.ifm_index; ++ let ifm_snd_len = self.ifm_snd_len; ++ let ifm_snd_maxlen = self.ifm_snd_maxlen; ++ let ifm_snd_drops = self.ifm_snd_drops; ++ let ifm_timer = self.ifm_timer; ++ let ifm_data = self.ifm_data; ++ f.debug_struct("if_msghdr2") ++ .field("ifm_msglen", &ifm_msglen) ++ .field("ifm_version", &ifm_version) ++ .field("ifm_type", &ifm_type) ++ .field("ifm_addrs", &ifm_addrs) ++ .field("ifm_flags", &ifm_flags) ++ .field("ifm_index", &ifm_index) ++ .field("ifm_snd_len", &ifm_snd_len) ++ .field("ifm_snd_maxlen", &ifm_snd_maxlen) ++ .field("ifm_snd_drops", &ifm_snd_drops) ++ .field("ifm_timer", &ifm_timer) ++ .field("ifm_data", &ifm_data) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for if_msghdr2 { ++ fn hash(&self, state: &mut H) { ++ let ifm_msglen = self.ifm_msglen; ++ let ifm_version = self.ifm_version; ++ let ifm_type = self.ifm_type; ++ let ifm_addrs = self.ifm_addrs; ++ let ifm_flags = self.ifm_flags; ++ let ifm_index = self.ifm_index; ++ let ifm_snd_len = self.ifm_snd_len; ++ let ifm_snd_maxlen = self.ifm_snd_maxlen; ++ let ifm_snd_drops = self.ifm_snd_drops; ++ let ifm_timer = self.ifm_timer; ++ let ifm_data = self.ifm_data; ++ ifm_msglen.hash(state); ++ ifm_version.hash(state); ++ ifm_type.hash(state); ++ ifm_addrs.hash(state); ++ ifm_flags.hash(state); ++ ifm_index.hash(state); ++ ifm_snd_len.hash(state); ++ ifm_snd_maxlen.hash(state); ++ ifm_snd_drops.hash(state); ++ ifm_timer.hash(state); ++ ifm_data.hash(state); ++ } ++ } ++ impl PartialEq for vm_statistics64 { ++ fn eq(&self, other: &vm_statistics64) -> bool { ++ // Otherwise rustfmt crashes... ++ let total_uncompressed = self.total_uncompressed_pages_in_compressor; ++ self.free_count == other.free_count && ++ self.active_count == other.active_count && ++ self.inactive_count == other.inactive_count && ++ self.wire_count == other.wire_count && ++ self.zero_fill_count == other.zero_fill_count && ++ self.reactivations == other.reactivations && ++ self.pageins == other.pageins && ++ self.pageouts == other.pageouts && ++ self.faults == other.faults && ++ self.cow_faults == other.cow_faults && ++ self.lookups == other.lookups && ++ self.hits == other.hits && ++ self.purges == other.purges && ++ self.purgeable_count == other.purgeable_count && ++ self.speculative_count == other.speculative_count && ++ self.decompressions == other.decompressions && ++ self.compressions == other.compressions && ++ self.swapins == other.swapins && ++ self.swapouts == other.swapouts && ++ self.compressor_page_count == other.compressor_page_count && ++ self.throttled_count == other.throttled_count && ++ self.external_page_count == other.external_page_count && ++ self.internal_page_count == other.internal_page_count && ++ total_uncompressed == other.total_uncompressed_pages_in_compressor ++ } ++ } ++ impl Eq for vm_statistics64 {} ++ impl ::fmt::Debug for vm_statistics64 { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let free_count = self.free_count; ++ let active_count = self.active_count; ++ let inactive_count = self.inactive_count; ++ let wire_count = self.wire_count; ++ let zero_fill_count = self.zero_fill_count; ++ let reactivations = self.reactivations; ++ let pageins = self.pageins; ++ let pageouts = self.pageouts; ++ let faults = self.faults; ++ let cow_faults = self.cow_faults; ++ let lookups = self.lookups; ++ let hits = self.hits; ++ let purges = self.purges; ++ let purgeable_count = self.purgeable_count; ++ let speculative_count = self.speculative_count; ++ let decompressions = self.decompressions; ++ let compressions = self.compressions; ++ let swapins = self.swapins; ++ let swapouts = self.swapouts; ++ let compressor_page_count = self.compressor_page_count; ++ let throttled_count = self.throttled_count; ++ let external_page_count = self.external_page_count; ++ let internal_page_count = self.internal_page_count; ++ // Otherwise rustfmt crashes... ++ let total_uncompressed = self.total_uncompressed_pages_in_compressor; ++ f.debug_struct("vm_statistics64") ++ .field("free_count", &free_count) ++ .field("active_count", &active_count) ++ .field("inactive_count", &inactive_count) ++ .field("wire_count", &wire_count) ++ .field("zero_fill_count", &zero_fill_count) ++ .field("reactivations", &reactivations) ++ .field("pageins", &pageins) ++ .field("pageouts", &pageouts) ++ .field("faults", &faults) ++ .field("cow_faults", &cow_faults) ++ .field("lookups", &lookups) ++ .field("hits", &hits) ++ .field("purges", &purges) ++ .field("purgeable_count", &purgeable_count) ++ .field("speculative_count", &speculative_count) ++ .field("decompressions", &decompressions) ++ .field("compressions", &compressions) ++ .field("swapins", &swapins) ++ .field("swapouts", &swapouts) ++ .field("compressor_page_count", &compressor_page_count) ++ .field("throttled_count", &throttled_count) ++ .field("external_page_count", &external_page_count) ++ .field("internal_page_count", &internal_page_count) ++ .field("total_uncompressed_pages_in_compressor", &total_uncompressed) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for vm_statistics64 { ++ fn hash(&self, state: &mut H) { ++ let free_count = self.free_count; ++ let active_count = self.active_count; ++ let inactive_count = self.inactive_count; ++ let wire_count = self.wire_count; ++ let zero_fill_count = self.zero_fill_count; ++ let reactivations = self.reactivations; ++ let pageins = self.pageins; ++ let pageouts = self.pageouts; ++ let faults = self.faults; ++ let cow_faults = self.cow_faults; ++ let lookups = self.lookups; ++ let hits = self.hits; ++ let purges = self.purges; ++ let purgeable_count = self.purgeable_count; ++ let speculative_count = self.speculative_count; ++ let decompressions = self.decompressions; ++ let compressions = self.compressions; ++ let swapins = self.swapins; ++ let swapouts = self.swapouts; ++ let compressor_page_count = self.compressor_page_count; ++ let throttled_count = self.throttled_count; ++ let external_page_count = self.external_page_count; ++ let internal_page_count = self.internal_page_count; ++ // Otherwise rustfmt crashes... ++ let total_uncompressed = self.total_uncompressed_pages_in_compressor; ++ free_count.hash(state); ++ active_count.hash(state); ++ inactive_count.hash(state); ++ wire_count.hash(state); ++ zero_fill_count.hash(state); ++ reactivations.hash(state); ++ pageins.hash(state); ++ pageouts.hash(state); ++ faults.hash(state); ++ cow_faults.hash(state); ++ lookups.hash(state); ++ hits.hash(state); ++ purges.hash(state); ++ purgeable_count.hash(state); ++ speculative_count.hash(state); ++ decompressions.hash(state); ++ compressions.hash(state); ++ swapins.hash(state); ++ swapouts.hash(state); ++ compressor_page_count.hash(state); ++ throttled_count.hash(state); ++ external_page_count.hash(state); ++ internal_page_count.hash(state); ++ total_uncompressed.hash(state); ++ } ++ } ++ ++ impl PartialEq for mach_task_basic_info { ++ fn eq(&self, other: &mach_task_basic_info) -> bool { ++ self.virtual_size == other.virtual_size ++ && self.resident_size == other.resident_size ++ && self.resident_size_max == other.resident_size_max ++ && self.user_time == other.user_time ++ && self.system_time == other.system_time ++ && self.policy == other.policy ++ && self.suspend_count == other.suspend_count ++ } ++ } ++ impl Eq for mach_task_basic_info {} ++ impl ::fmt::Debug for mach_task_basic_info { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let virtual_size = self.virtual_size; ++ let resident_size = self.resident_size; ++ let resident_size_max = self.resident_size_max; ++ let user_time = self.user_time; ++ let system_time = self.system_time; ++ let policy = self.policy; ++ let suspend_count = self.suspend_count; ++ f.debug_struct("mach_task_basic_info") ++ .field("virtual_size", &virtual_size) ++ .field("resident_size", &resident_size) ++ .field("resident_size_max", &resident_size_max) ++ .field("user_time", &user_time) ++ .field("system_time", &system_time) ++ .field("policy", &policy) ++ .field("suspend_count", &suspend_count) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for mach_task_basic_info { ++ fn hash(&self, state: &mut H) { ++ let virtual_size = self.virtual_size; ++ let resident_size = self.resident_size; ++ let resident_size_max = self.resident_size_max; ++ let user_time = self.user_time; ++ let system_time = self.system_time; ++ let policy = self.policy; ++ let suspend_count = self.suspend_count; ++ virtual_size.hash(state); ++ resident_size.hash(state); ++ resident_size_max.hash(state); ++ user_time.hash(state); ++ system_time.hash(state); ++ policy.hash(state); ++ suspend_count.hash(state); ++ } ++ } ++ ++ impl PartialEq for log2phys { ++ fn eq(&self, other: &log2phys) -> bool { ++ self.l2p_flags == other.l2p_flags ++ && self.l2p_contigbytes == other.l2p_contigbytes ++ && self.l2p_devoffset == other.l2p_devoffset ++ } ++ } ++ impl Eq for log2phys {} ++ impl ::fmt::Debug for log2phys { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let l2p_flags = self.l2p_flags; ++ let l2p_contigbytes = self.l2p_contigbytes; ++ let l2p_devoffset = self.l2p_devoffset; ++ f.debug_struct("log2phys") ++ .field("l2p_flags", &l2p_flags) ++ .field("l2p_contigbytes", &l2p_contigbytes) ++ .field("l2p_devoffset", &l2p_devoffset) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for log2phys { ++ fn hash(&self, state: &mut H) { ++ let l2p_flags = self.l2p_flags; ++ let l2p_contigbytes = self.l2p_contigbytes; ++ let l2p_devoffset = self.l2p_devoffset; ++ l2p_flags.hash(state); ++ l2p_contigbytes.hash(state); ++ l2p_devoffset.hash(state); ++ } ++ } ++ impl PartialEq for os_unfair_lock { ++ fn eq(&self, other: &os_unfair_lock) -> bool { ++ self._os_unfair_lock_opaque == other._os_unfair_lock_opaque ++ } ++ } ++ ++ impl Eq for os_unfair_lock {} ++ ++ impl ::fmt::Debug for os_unfair_lock { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("os_unfair_lock") ++ .field("_os_unfair_lock_opaque", &self._os_unfair_lock_opaque) ++ .finish() ++ } ++ } ++ ++ impl ::hash::Hash for os_unfair_lock { ++ fn hash(&self, state: &mut H) { ++ self._os_unfair_lock_opaque.hash(state); ++ } ++ } + } + } + +@@ -1591,7 +2694,11 @@ pub const ABMON_11: ::nl_item = 43; + pub const ABMON_12: ::nl_item = 44; + + pub const CLOCK_REALTIME: ::clockid_t = 0; ++pub const CLOCK_MONOTONIC_RAW: ::clockid_t = 4; ++pub const CLOCK_MONOTONIC_RAW_APPROX: ::clockid_t = 5; + pub const CLOCK_MONOTONIC: ::clockid_t = 6; ++pub const CLOCK_UPTIME_RAW: ::clockid_t = 8; ++pub const CLOCK_UPTIME_RAW_APPROX: ::clockid_t = 9; + pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 12; + pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 16; + +@@ -1621,6 +2728,8 @@ pub const EOF: ::c_int = -1; + pub const SEEK_SET: ::c_int = 0; + pub const SEEK_CUR: ::c_int = 1; + pub const SEEK_END: ::c_int = 2; ++pub const SEEK_HOLE: ::c_int = 3; ++pub const SEEK_DATA: ::c_int = 4; + pub const _IOFBF: ::c_int = 0; + pub const _IONBF: ::c_int = 2; + pub const _IOLBF: ::c_int = 1; +@@ -1638,11 +2747,13 @@ pub const _PC_PIPE_BUF: ::c_int = 6; + pub const _PC_CHOWN_RESTRICTED: ::c_int = 7; + pub const _PC_NO_TRUNC: ::c_int = 8; + pub const _PC_VDISABLE: ::c_int = 9; +-pub const O_DSYNC: ::c_int = 0x400000; +-pub const O_NOCTTY: ::c_int = 0x20000; +-pub const O_CLOEXEC: ::c_int = 0x1000000; +-pub const O_DIRECTORY: ::c_int = 0x100000; +-pub const O_SYMLINK: ::c_int = 0x200000; ++pub const O_EVTONLY: ::c_int = 0x00008000; ++pub const O_NOCTTY: ::c_int = 0x00020000; ++pub const O_DIRECTORY: ::c_int = 0x00100000; ++pub const O_SYMLINK: ::c_int = 0x00200000; ++pub const O_DSYNC: ::c_int = 0x00400000; ++pub const O_CLOEXEC: ::c_int = 0x01000000; ++pub const O_NOFOLLOW_ANY: ::c_int = 0x20000000; + pub const S_IFIFO: mode_t = 4096; + pub const S_IFCHR: mode_t = 8192; + pub const S_IFBLK: mode_t = 24576; +@@ -1982,12 +3093,16 @@ pub const F_PREALLOCATE: ::c_int = 42; + pub const F_RDADVISE: ::c_int = 44; + pub const F_RDAHEAD: ::c_int = 45; + pub const F_NOCACHE: ::c_int = 48; ++pub const F_LOG2PHYS: ::c_int = 49; + pub const F_GETPATH: ::c_int = 50; + pub const F_FULLFSYNC: ::c_int = 51; + pub const F_FREEZE_FS: ::c_int = 53; + pub const F_THAW_FS: ::c_int = 54; + pub const F_GLOBAL_NOCACHE: ::c_int = 55; + pub const F_NODIRECT: ::c_int = 62; ++pub const F_LOG2PHYS_EXT: ::c_int = 65; ++pub const F_BARRIERFSYNC: ::c_int = 85; ++pub const F_GETPATH_NOFIRMLINK: ::c_int = 102; + + pub const F_ALLOCATECONTIG: ::c_uint = 0x02; + pub const F_ALLOCATEALL: ::c_uint = 0x04; +@@ -2001,6 +3116,11 @@ pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x0020; + pub const AT_SYMLINK_FOLLOW: ::c_int = 0x0040; + pub const AT_REMOVEDIR: ::c_int = 0x0080; + ++pub const PTHREAD_INTROSPECTION_THREAD_CREATE: ::c_uint = 1; ++pub const PTHREAD_INTROSPECTION_THREAD_START: ::c_uint = 2; ++pub const PTHREAD_INTROSPECTION_THREAD_TERMINATE: ::c_uint = 3; ++pub const PTHREAD_INTROSPECTION_THREAD_DESTROY: ::c_uint = 4; ++ + pub const TIOCMODG: ::c_ulong = 0x40047403; + pub const TIOCMODS: ::c_ulong = 0x80047404; + pub const TIOCM_LE: ::c_int = 0x1; +@@ -2193,6 +3313,8 @@ pub const MINCORE_MODIFIED: ::c_int = 0x4; + pub const MINCORE_REFERENCED_OTHER: ::c_int = 0x8; + pub const MINCORE_MODIFIED_OTHER: ::c_int = 0x10; + ++pub const CTLIOCGINFO: c_ulong = 0xc0644e03; ++ + // + // sys/netinet/in.h + // Protocols (RFC 1700) +@@ -2438,6 +3560,7 @@ pub const pseudo_AF_RTIP: ::c_int = 22; + pub const AF_IPX: ::c_int = 23; + pub const AF_SIP: ::c_int = 24; + pub const pseudo_AF_PIP: ::c_int = 25; ++pub const AF_NDRV: ::c_int = 27; + pub const AF_ISDN: ::c_int = 28; + pub const AF_E164: ::c_int = AF_ISDN; + pub const pseudo_AF_KEY: ::c_int = 29; +@@ -2480,6 +3603,7 @@ pub const PF_SIP: ::c_int = AF_SIP; + pub const PF_IPX: ::c_int = AF_IPX; + pub const PF_RTIP: ::c_int = pseudo_AF_RTIP; + pub const PF_PIP: ::c_int = pseudo_AF_PIP; ++pub const PF_NDRV: ::c_int = AF_NDRV; + pub const PF_ISDN: ::c_int = AF_ISDN; + pub const PF_KEY: ::c_int = pseudo_AF_KEY; + pub const PF_INET6: ::c_int = AF_INET6; +@@ -2510,6 +3634,7 @@ pub const IP_RECVIF: ::c_int = 20; + pub const IP_BOUND_IF: ::c_int = 25; + pub const IP_PKTINFO: ::c_int = 26; + pub const IP_RECVTOS: ::c_int = 27; ++pub const IP_DONTFRAG: ::c_int = 28; + pub const IPV6_JOIN_GROUP: ::c_int = 12; + pub const IPV6_LEAVE_GROUP: ::c_int = 13; + pub const IPV6_CHECKSUM: ::c_int = 26; +@@ -2518,6 +3643,12 @@ pub const IPV6_TCLASS: ::c_int = 36; + pub const IPV6_PKTINFO: ::c_int = 46; + pub const IPV6_HOPLIMIT: ::c_int = 47; + pub const IPV6_RECVPKTINFO: ::c_int = 61; ++pub const IPV6_DONTFRAG: ::c_int = 62; ++pub const IP_ADD_SOURCE_MEMBERSHIP: ::c_int = 70; ++pub const IP_DROP_SOURCE_MEMBERSHIP: ::c_int = 71; ++pub const IP_BLOCK_SOURCE: ::c_int = 72; ++pub const IP_UNBLOCK_SOURCE: ::c_int = 73; ++pub const IPV6_BOUND_IF: ::c_int = 125; + + pub const TCP_NOPUSH: ::c_int = 4; + pub const TCP_NOOPT: ::c_int = 8; +@@ -2745,6 +3876,11 @@ pub const _SC_TRACE_NAME_MAX: ::c_int = 128; + pub const _SC_TRACE_SYS_MAX: ::c_int = 129; + pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 130; + pub const _SC_PASS_MAX: ::c_int = 131; ++// `confstr` keys (only the values guaranteed by `man confstr`). ++pub const _CS_PATH: ::c_int = 1; ++pub const _CS_DARWIN_USER_DIR: ::c_int = 65536; ++pub const _CS_DARWIN_USER_TEMP_DIR: ::c_int = 65537; ++pub const _CS_DARWIN_USER_CACHE_DIR: ::c_int = 65538; + + pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; + pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 1; +@@ -2766,6 +3902,20 @@ pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + __opaque: [0; __PTHREAD_RWLOCK_SIZE__], + }; + ++pub const OS_UNFAIR_LOCK_INIT: os_unfair_lock = os_unfair_lock { ++ _os_unfair_lock_opaque: 0, ++}; ++ ++pub const OS_LOG_TYPE_DEFAULT: ::os_log_type_t = 0x00; ++pub const OS_LOG_TYPE_INFO: ::os_log_type_t = 0x01; ++pub const OS_LOG_TYPE_DEBUG: ::os_log_type_t = 0x02; ++pub const OS_LOG_TYPE_ERROR: ::os_log_type_t = 0x10; ++pub const OS_LOG_TYPE_FAULT: ::os_log_type_t = 0x11; ++ ++pub const OS_SIGNPOST_EVENT: ::os_signpost_type_t = 0x00; ++pub const OS_SIGNPOST_INTERVAL_BEGIN: ::os_signpost_type_t = 0x01; ++pub const OS_SIGNPOST_INTERVAL_END: ::os_signpost_type_t = 0x02; ++ + pub const MINSIGSTKSZ: ::size_t = 32768; + pub const SIGSTKSZ: ::size_t = 131072; + +@@ -2773,6 +3923,10 @@ pub const FD_SETSIZE: usize = 1024; + + pub const ST_NOSUID: ::c_ulong = 2; + ++pub const SCHED_OTHER: ::c_int = 1; ++pub const SCHED_FIFO: ::c_int = 4; ++pub const SCHED_RR: ::c_int = 2; ++ + pub const EVFILT_READ: i16 = -1; + pub const EVFILT_WRITE: i16 = -2; + pub const EVFILT_AIO: i16 = -3; +@@ -3121,6 +4275,11 @@ pub const VM_LOADAVG: ::c_int = 2; + pub const VM_MACHFACTOR: ::c_int = 4; + pub const VM_SWAPUSAGE: ::c_int = 5; + pub const VM_MAXID: ::c_int = 6; ++pub const VM_PROT_NONE: ::vm_prot_t = 0x00; ++pub const VM_PROT_READ: ::vm_prot_t = 0x01; ++pub const VM_PROT_WRITE: ::vm_prot_t = 0x02; ++pub const VM_PROT_EXECUTE: ::vm_prot_t = 0x04; ++pub const MEMORY_OBJECT_NULL: ::memory_object_t = 0; + pub const HW_MACHINE: ::c_int = 1; + pub const HW_MODEL: ::c_int = 2; + pub const HW_NCPU: ::c_int = 3; +@@ -3262,6 +4421,8 @@ pub const RTF_CONDEMNED: ::c_int = 0x2000000; + pub const RTF_IFREF: ::c_int = 0x4000000; + pub const RTF_PROXY: ::c_int = 0x8000000; + pub const RTF_ROUTER: ::c_int = 0x10000000; ++pub const RTF_DEAD: ::c_int = 0x20000000; ++pub const RTF_GLOBAL: ::c_int = 0x40000000; + + pub const RTM_VERSION: ::c_int = 5; + +@@ -3320,8 +4481,14 @@ pub const RTAX_MAX: ::c_int = 8; + pub const KERN_PROCARGS2: ::c_int = 49; + + pub const PROC_PIDTASKALLINFO: ::c_int = 2; ++pub const PROC_PIDTBSDINFO: ::c_int = 3; + pub const PROC_PIDTASKINFO: ::c_int = 4; + pub const PROC_PIDTHREADINFO: ::c_int = 5; ++pub const PROC_PIDVNODEPATHINFO: ::c_int = 9; ++pub const PROC_PIDPATHINFO_MAXSIZE: ::c_int = 4096; ++pub const PROC_CSM_ALL: ::c_uint = 0x0001; ++pub const PROC_CSM_NOSMT: ::c_uint = 0x0002; ++pub const PROC_CSM_TECS: ::c_uint = 0x0004; + pub const MAXCOMLEN: usize = 16; + pub const MAXTHREADNAMESIZE: usize = 64; + +@@ -3358,18 +4525,10 @@ pub const DLT_LOOP: ::c_uint = 108; + pub const BPF_ALIGNMENT: ::c_int = 4; + + // sys/mount.h +-pub const MNT_RDONLY: ::c_int = 0x00000001; +-pub const MNT_SYNCHRONOUS: ::c_int = 0x00000002; +-pub const MNT_NOEXEC: ::c_int = 0x00000004; +-pub const MNT_NOSUID: ::c_int = 0x00000008; + pub const MNT_NODEV: ::c_int = 0x00000010; + pub const MNT_UNION: ::c_int = 0x00000020; +-pub const MNT_ASYNC: ::c_int = 0x00000040; + pub const MNT_CPROTECT: ::c_int = 0x00000080; + +-// NFS export related mount flags. +-pub const MNT_EXPORTED: ::c_int = 0x00000100; +- + // MAC labeled / "quarantined" flag + pub const MNT_QUARANTINE: ::c_int = 0x00000400; + +@@ -3390,9 +4549,7 @@ pub const MNT_NOATIME: ::c_int = 0x10000000; + pub const MNT_SNAPSHOT: ::c_int = 0x40000000; + + // External filesystem command modifier flags. +-pub const MNT_UPDATE: ::c_int = 0x00010000; + pub const MNT_NOBLOCK: ::c_int = 0x00020000; +-pub const MNT_RELOAD: ::c_int = 0x00040000; + + // sys/spawn.h: + pub const POSIX_SPAWN_RESETIDS: ::c_int = 0x01; +@@ -3521,6 +4678,244 @@ pub const THREAD_BACKGROUND_POLICY_DARWIN_BG: ::c_int = 0x1000; + pub const THREAD_LATENCY_QOS_POLICY: ::c_int = 7; + pub const THREAD_THROUGHPUT_QOS_POLICY: ::c_int = 8; + ++// ++pub const TH_STATE_RUNNING: ::c_int = 1; ++pub const TH_STATE_STOPPED: ::c_int = 2; ++pub const TH_STATE_WAITING: ::c_int = 3; ++pub const TH_STATE_UNINTERRUPTIBLE: ::c_int = 4; ++pub const TH_STATE_HALTED: ::c_int = 5; ++pub const TH_FLAGS_SWAPPED: ::c_int = 0x1; ++pub const TH_FLAGS_IDLE: ::c_int = 0x2; ++pub const TH_FLAGS_GLOBAL_FORCED_IDLE: ::c_int = 0x4; ++pub const THREAD_BASIC_INFO: ::c_int = 3; ++pub const THREAD_IDENTIFIER_INFO: ::c_int = 4; ++pub const THREAD_EXTENDED_INFO: ::c_int = 5; ++ ++// CommonCrypto/CommonCryptoError.h ++pub const kCCSuccess: i32 = 0; ++pub const kCCParamError: i32 = -4300; ++pub const kCCBufferTooSmall: i32 = -4301; ++pub const kCCMemoryFailure: i32 = -4302; ++pub const kCCAlignmentError: i32 = -4303; ++pub const kCCDecodeError: i32 = -4304; ++pub const kCCUnimplemented: i32 = -4305; ++pub const kCCOverflow: i32 = -4306; ++pub const kCCRNGFailure: i32 = -4307; ++pub const kCCUnspecifiedError: i32 = -4308; ++pub const kCCCallSequenceError: i32 = -4309; ++pub const kCCKeySizeError: i32 = -4310; ++pub const kCCInvalidKey: i32 = -4311; ++ ++// mach/host_info.h ++pub const HOST_LOAD_INFO: i32 = 1; ++pub const HOST_VM_INFO: i32 = 2; ++pub const HOST_CPU_LOAD_INFO: i32 = 3; ++pub const HOST_VM_INFO64: i32 = 4; ++pub const HOST_EXTMOD_INFO64: i32 = 5; ++pub const HOST_EXPIRED_TASK_INFO: i32 = 6; ++ ++// mach/vm_statistics.h ++pub const VM_PAGE_QUERY_PAGE_PRESENT: i32 = 0x1; ++pub const VM_PAGE_QUERY_PAGE_FICTITIOUS: i32 = 0x2; ++pub const VM_PAGE_QUERY_PAGE_REF: i32 = 0x4; ++pub const VM_PAGE_QUERY_PAGE_DIRTY: i32 = 0x8; ++pub const VM_PAGE_QUERY_PAGE_PAGED_OUT: i32 = 0x10; ++pub const VM_PAGE_QUERY_PAGE_COPIED: i32 = 0x20; ++pub const VM_PAGE_QUERY_PAGE_SPECULATIVE: i32 = 0x40; ++pub const VM_PAGE_QUERY_PAGE_EXTERNAL: i32 = 0x80; ++pub const VM_PAGE_QUERY_PAGE_CS_VALIDATED: i32 = 0x100; ++pub const VM_PAGE_QUERY_PAGE_CS_TAINTED: i32 = 0x200; ++pub const VM_PAGE_QUERY_PAGE_CS_NX: i32 = 0x400; ++ ++// mach/task_info.h ++pub const TASK_THREAD_TIMES_INFO: u32 = 3; ++pub const HOST_CPU_LOAD_INFO_COUNT: u32 = 4; ++pub const MACH_TASK_BASIC_INFO: u32 = 20; ++ ++pub const MACH_PORT_NULL: i32 = 0; ++ ++pub const RUSAGE_INFO_V0: ::c_int = 0; ++pub const RUSAGE_INFO_V1: ::c_int = 1; ++pub const RUSAGE_INFO_V2: ::c_int = 2; ++pub const RUSAGE_INFO_V3: ::c_int = 3; ++pub const RUSAGE_INFO_V4: ::c_int = 4; ++ ++// copyfile.h ++pub const COPYFILE_ACL: ::copyfile_flags_t = 1 << 0; ++pub const COPYFILE_STAT: ::copyfile_flags_t = 1 << 1; ++pub const COPYFILE_XATTR: ::copyfile_flags_t = 1 << 2; ++pub const COPYFILE_DATA: ::copyfile_flags_t = 1 << 3; ++pub const COPYFILE_SECURITY: ::copyfile_flags_t = COPYFILE_STAT | COPYFILE_ACL; ++pub const COPYFILE_METADATA: ::copyfile_flags_t = COPYFILE_SECURITY | COPYFILE_XATTR; ++pub const COPYFILE_RECURSIVE: ::copyfile_flags_t = 1 << 15; ++pub const COPYFILE_CHECK: ::copyfile_flags_t = 1 << 16; ++pub const COPYFILE_EXCL: ::copyfile_flags_t = 1 << 17; ++pub const COPYFILE_NOFOLLOW_SRC: ::copyfile_flags_t = 1 << 18; ++pub const COPYFILE_NOFOLLOW_DST: ::copyfile_flags_t = 1 << 19; ++pub const COPYFILE_MOVE: ::copyfile_flags_t = 1 << 20; ++pub const COPYFILE_UNLINK: ::copyfile_flags_t = 1 << 21; ++pub const COPYFILE_NOFOLLOW: ::copyfile_flags_t = COPYFILE_NOFOLLOW_SRC | COPYFILE_NOFOLLOW_DST; ++pub const COPYFILE_PACK: ::copyfile_flags_t = 1 << 22; ++pub const COPYFILE_UNPACK: ::copyfile_flags_t = 1 << 23; ++pub const COPYFILE_CLONE: ::copyfile_flags_t = 1 << 24; ++pub const COPYFILE_CLONE_FORCE: ::copyfile_flags_t = 1 << 25; ++pub const COPYFILE_RUN_IN_PLACE: ::copyfile_flags_t = 1 << 26; ++pub const COPYFILE_DATA_SPARSE: ::copyfile_flags_t = 1 << 27; ++pub const COPYFILE_PRESERVE_DST_TRACKED: ::copyfile_flags_t = 1 << 28; ++pub const COPYFILE_VERBOSE: ::copyfile_flags_t = 1 << 30; ++pub const COPYFILE_RECURSE_ERROR: ::c_int = 0; ++pub const COPYFILE_RECURSE_FILE: ::c_int = 1; ++pub const COPYFILE_RECURSE_DIR: ::c_int = 2; ++pub const COPYFILE_RECURSE_DIR_CLEANUP: ::c_int = 3; ++pub const COPYFILE_COPY_DATA: ::c_int = 4; ++pub const COPYFILE_COPY_XATTR: ::c_int = 5; ++pub const COPYFILE_START: ::c_int = 1; ++pub const COPYFILE_FINISH: ::c_int = 2; ++pub const COPYFILE_ERR: ::c_int = 3; ++pub const COPYFILE_PROGRESS: ::c_int = 4; ++pub const COPYFILE_CONTINUE: ::c_int = 0; ++pub const COPYFILE_SKIP: ::c_int = 1; ++pub const COPYFILE_QUIT: ::c_int = 2; ++ ++// ++pub const ATTR_BIT_MAP_COUNT: ::c_ushort = 5; ++pub const FSOPT_NOFOLLOW: u32 = 0x1; ++pub const FSOPT_NOFOLLOW_ANY: u32 = 0x800; ++pub const FSOPT_REPORT_FULLSIZE: u32 = 0x4; ++pub const FSOPT_PACK_INVAL_ATTRS: u32 = 0x8; ++pub const FSOPT_ATTR_CMN_EXTENDED: u32 = 0x20; ++pub const FSOPT_RETURN_REALDEV: u32 = 0x200; ++pub const ATTR_CMN_NAME: attrgroup_t = 0x00000001; ++pub const ATTR_CMN_DEVID: attrgroup_t = 0x00000002; ++pub const ATTR_CMN_FSID: attrgroup_t = 0x00000004; ++pub const ATTR_CMN_OBJTYPE: attrgroup_t = 0x00000008; ++pub const ATTR_CMN_OBJTAG: attrgroup_t = 0x00000010; ++pub const ATTR_CMN_OBJID: attrgroup_t = 0x00000020; ++pub const ATTR_CMN_OBJPERMANENTID: attrgroup_t = 0x00000040; ++pub const ATTR_CMN_PAROBJID: attrgroup_t = 0x00000080; ++pub const ATTR_CMN_SCRIPT: attrgroup_t = 0x00000100; ++pub const ATTR_CMN_CRTIME: attrgroup_t = 0x00000200; ++pub const ATTR_CMN_MODTIME: attrgroup_t = 0x00000400; ++pub const ATTR_CMN_CHGTIME: attrgroup_t = 0x00000800; ++pub const ATTR_CMN_ACCTIME: attrgroup_t = 0x00001000; ++pub const ATTR_CMN_BKUPTIME: attrgroup_t = 0x00002000; ++pub const ATTR_CMN_FNDRINFO: attrgroup_t = 0x00004000; ++pub const ATTR_CMN_OWNERID: attrgroup_t = 0x00008000; ++pub const ATTR_CMN_GRPID: attrgroup_t = 0x00010000; ++pub const ATTR_CMN_ACCESSMASK: attrgroup_t = 0x00020000; ++pub const ATTR_CMN_FLAGS: attrgroup_t = 0x00040000; ++pub const ATTR_CMN_GEN_COUNT: attrgroup_t = 0x00080000; ++pub const ATTR_CMN_DOCUMENT_ID: attrgroup_t = 0x00100000; ++pub const ATTR_CMN_USERACCESS: attrgroup_t = 0x00200000; ++pub const ATTR_CMN_EXTENDED_SECURITY: attrgroup_t = 0x00400000; ++pub const ATTR_CMN_UUID: attrgroup_t = 0x00800000; ++pub const ATTR_CMN_GRPUUID: attrgroup_t = 0x01000000; ++pub const ATTR_CMN_FILEID: attrgroup_t = 0x02000000; ++pub const ATTR_CMN_PARENTID: attrgroup_t = 0x04000000; ++pub const ATTR_CMN_FULLPATH: attrgroup_t = 0x08000000; ++pub const ATTR_CMN_ADDEDTIME: attrgroup_t = 0x10000000; ++pub const ATTR_CMN_DATA_PROTECT_FLAGS: attrgroup_t = 0x40000000; ++pub const ATTR_CMN_RETURNED_ATTRS: attrgroup_t = 0x80000000; ++pub const ATTR_VOL_FSTYPE: attrgroup_t = 0x00000001; ++pub const ATTR_VOL_SIGNATURE: attrgroup_t = 0x00000002; ++pub const ATTR_VOL_SIZE: attrgroup_t = 0x00000004; ++pub const ATTR_VOL_SPACEFREE: attrgroup_t = 0x00000008; ++pub const ATTR_VOL_SPACEAVAIL: attrgroup_t = 0x00000010; ++pub const ATTR_VOL_MINALLOCATION: attrgroup_t = 0x00000020; ++pub const ATTR_VOL_ALLOCATIONCLUMP: attrgroup_t = 0x00000040; ++pub const ATTR_VOL_IOBLOCKSIZE: attrgroup_t = 0x00000080; ++pub const ATTR_VOL_OBJCOUNT: attrgroup_t = 0x00000100; ++pub const ATTR_VOL_FILECOUNT: attrgroup_t = 0x00000200; ++pub const ATTR_VOL_DIRCOUNT: attrgroup_t = 0x00000400; ++pub const ATTR_VOL_MAXOBJCOUNT: attrgroup_t = 0x00000800; ++pub const ATTR_VOL_MOUNTPOINT: attrgroup_t = 0x00001000; ++pub const ATTR_VOL_NAME: attrgroup_t = 0x00002000; ++pub const ATTR_VOL_MOUNTFLAGS: attrgroup_t = 0x00004000; ++pub const ATTR_VOL_MOUNTEDDEVICE: attrgroup_t = 0x00008000; ++pub const ATTR_VOL_ENCODINGSUSED: attrgroup_t = 0x00010000; ++pub const ATTR_VOL_CAPABILITIES: attrgroup_t = 0x00020000; ++pub const ATTR_VOL_UUID: attrgroup_t = 0x00040000; ++pub const ATTR_VOL_SPACEUSED: attrgroup_t = 0x00800000; ++pub const ATTR_VOL_QUOTA_SIZE: attrgroup_t = 0x10000000; ++pub const ATTR_VOL_RESERVED_SIZE: attrgroup_t = 0x20000000; ++pub const ATTR_VOL_ATTRIBUTES: attrgroup_t = 0x40000000; ++pub const ATTR_VOL_INFO: attrgroup_t = 0x80000000; ++pub const ATTR_DIR_LINKCOUNT: attrgroup_t = 0x00000001; ++pub const ATTR_DIR_ENTRYCOUNT: attrgroup_t = 0x00000002; ++pub const ATTR_DIR_MOUNTSTATUS: attrgroup_t = 0x00000004; ++pub const ATTR_DIR_ALLOCSIZE: attrgroup_t = 0x00000008; ++pub const ATTR_DIR_IOBLOCKSIZE: attrgroup_t = 0x00000010; ++pub const ATTR_DIR_DATALENGTH: attrgroup_t = 0x00000020; ++pub const ATTR_FILE_LINKCOUNT: attrgroup_t = 0x00000001; ++pub const ATTR_FILE_TOTALSIZE: attrgroup_t = 0x00000002; ++pub const ATTR_FILE_ALLOCSIZE: attrgroup_t = 0x00000004; ++pub const ATTR_FILE_IOBLOCKSIZE: attrgroup_t = 0x00000008; ++pub const ATTR_FILE_DEVTYPE: attrgroup_t = 0x00000020; ++pub const ATTR_FILE_FORKCOUNT: attrgroup_t = 0x00000080; ++pub const ATTR_FILE_FORKLIST: attrgroup_t = 0x00000100; ++pub const ATTR_FILE_DATALENGTH: attrgroup_t = 0x00000200; ++pub const ATTR_FILE_DATAALLOCSIZE: attrgroup_t = 0x00000400; ++pub const ATTR_FILE_RSRCLENGTH: attrgroup_t = 0x00001000; ++pub const ATTR_FILE_RSRCALLOCSIZE: attrgroup_t = 0x00002000; ++pub const ATTR_CMNEXT_RELPATH: attrgroup_t = 0x00000004; ++pub const ATTR_CMNEXT_PRIVATESIZE: attrgroup_t = 0x00000008; ++pub const ATTR_CMNEXT_LINKID: attrgroup_t = 0x00000010; ++pub const ATTR_CMNEXT_NOFIRMLINKPATH: attrgroup_t = 0x00000020; ++pub const ATTR_CMNEXT_REALDEVID: attrgroup_t = 0x00000040; ++pub const ATTR_CMNEXT_REALFSID: attrgroup_t = 0x00000080; ++pub const ATTR_CMNEXT_CLONEID: attrgroup_t = 0x00000100; ++pub const ATTR_CMNEXT_EXT_FLAGS: attrgroup_t = 0x00000200; ++pub const ATTR_CMNEXT_RECURSIVE_GENCOUNT: attrgroup_t = 0x00000400; ++pub const DIR_MNTSTATUS_MNTPOINT: u32 = 0x1; ++pub const VOL_CAPABILITIES_FORMAT: usize = 0; ++pub const VOL_CAPABILITIES_INTERFACES: usize = 1; ++pub const VOL_CAP_FMT_PERSISTENTOBJECTIDS: attrgroup_t = 0x00000001; ++pub const VOL_CAP_FMT_SYMBOLICLINKS: attrgroup_t = 0x00000002; ++pub const VOL_CAP_FMT_HARDLINKS: attrgroup_t = 0x00000004; ++pub const VOL_CAP_FMT_JOURNAL: attrgroup_t = 0x00000008; ++pub const VOL_CAP_FMT_JOURNAL_ACTIVE: attrgroup_t = 0x00000010; ++pub const VOL_CAP_FMT_NO_ROOT_TIMES: attrgroup_t = 0x00000020; ++pub const VOL_CAP_FMT_SPARSE_FILES: attrgroup_t = 0x00000040; ++pub const VOL_CAP_FMT_ZERO_RUNS: attrgroup_t = 0x00000080; ++pub const VOL_CAP_FMT_CASE_SENSITIVE: attrgroup_t = 0x00000100; ++pub const VOL_CAP_FMT_CASE_PRESERVING: attrgroup_t = 0x00000200; ++pub const VOL_CAP_FMT_FAST_STATFS: attrgroup_t = 0x00000400; ++pub const VOL_CAP_FMT_2TB_FILESIZE: attrgroup_t = 0x00000800; ++pub const VOL_CAP_FMT_OPENDENYMODES: attrgroup_t = 0x00001000; ++pub const VOL_CAP_FMT_HIDDEN_FILES: attrgroup_t = 0x00002000; ++pub const VOL_CAP_FMT_PATH_FROM_ID: attrgroup_t = 0x00004000; ++pub const VOL_CAP_FMT_NO_VOLUME_SIZES: attrgroup_t = 0x00008000; ++pub const VOL_CAP_FMT_DECMPFS_COMPRESSION: attrgroup_t = 0x00010000; ++pub const VOL_CAP_FMT_64BIT_OBJECT_IDS: attrgroup_t = 0x00020000; ++pub const VOL_CAP_FMT_DIR_HARDLINKS: attrgroup_t = 0x00040000; ++pub const VOL_CAP_FMT_DOCUMENT_ID: attrgroup_t = 0x00080000; ++pub const VOL_CAP_FMT_WRITE_GENERATION_COUNT: attrgroup_t = 0x00100000; ++pub const VOL_CAP_FMT_NO_IMMUTABLE_FILES: attrgroup_t = 0x00200000; ++pub const VOL_CAP_FMT_NO_PERMISSIONS: attrgroup_t = 0x00400000; ++pub const VOL_CAP_FMT_SHARED_SPACE: attrgroup_t = 0x00800000; ++pub const VOL_CAP_FMT_VOL_GROUPS: attrgroup_t = 0x01000000; ++pub const VOL_CAP_FMT_SEALED: attrgroup_t = 0x02000000; ++pub const VOL_CAP_INT_SEARCHFS: attrgroup_t = 0x00000001; ++pub const VOL_CAP_INT_ATTRLIST: attrgroup_t = 0x00000002; ++pub const VOL_CAP_INT_NFSEXPORT: attrgroup_t = 0x00000004; ++pub const VOL_CAP_INT_READDIRATTR: attrgroup_t = 0x00000008; ++pub const VOL_CAP_INT_EXCHANGEDATA: attrgroup_t = 0x00000010; ++pub const VOL_CAP_INT_COPYFILE: attrgroup_t = 0x00000020; ++pub const VOL_CAP_INT_ALLOCATE: attrgroup_t = 0x00000040; ++pub const VOL_CAP_INT_VOL_RENAME: attrgroup_t = 0x00000080; ++pub const VOL_CAP_INT_ADVLOCK: attrgroup_t = 0x00000100; ++pub const VOL_CAP_INT_FLOCK: attrgroup_t = 0x00000200; ++pub const VOL_CAP_INT_EXTENDED_SECURITY: attrgroup_t = 0x00000400; ++pub const VOL_CAP_INT_USERACCESS: attrgroup_t = 0x00000800; ++pub const VOL_CAP_INT_MANLOCK: attrgroup_t = 0x00001000; ++pub const VOL_CAP_INT_NAMEDSTREAMS: attrgroup_t = 0x00002000; ++pub const VOL_CAP_INT_EXTENDED_ATTR: attrgroup_t = 0x00004000; ++pub const VOL_CAP_INT_CLONE: attrgroup_t = 0x00010000; ++pub const VOL_CAP_INT_SNAPSHOT: attrgroup_t = 0x00020000; ++pub const VOL_CAP_INT_RENAME_SWAP: attrgroup_t = 0x00040000; ++pub const VOL_CAP_INT_RENAME_EXCL: attrgroup_t = 0x00080000; ++pub const VOL_CAP_INT_RENAME_OPENFAIL: attrgroup_t = 0x00100000; ++ + cfg_if! { + if #[cfg(libc_const_extern_fn)] { + const fn __DARWIN_ALIGN32(p: usize) -> usize { +@@ -3532,6 +4927,16 @@ cfg_if! { + const __DARWIN_ALIGNBYTES32: usize = ::mem::size_of::() - 1; + p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32 + } ++ } else { ++ fn __DARWIN_ALIGN32(p: usize) -> usize { ++ let __DARWIN_ALIGNBYTES32: usize = ::mem::size_of::() - 1; ++ p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32 ++ } ++ } ++} ++ ++cfg_if! { ++ if #[cfg(libc_const_size_of)] { + pub const THREAD_EXTENDED_POLICY_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / ::mem::size_of::()) + as mach_msg_type_number_t; +@@ -3553,11 +4958,25 @@ cfg_if! { + pub const THREAD_THROUGHPUT_QOS_POLICY_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / + ::mem::size_of::()) as mach_msg_type_number_t; ++ pub const THREAD_BASIC_INFO_COUNT: mach_msg_type_number_t = ++ (::mem::size_of::() / ::mem::size_of::()) ++ as mach_msg_type_number_t; ++ pub const THREAD_IDENTIFIER_INFO_COUNT: mach_msg_type_number_t = ++ (::mem::size_of::() / ::mem::size_of::()) ++ as mach_msg_type_number_t; ++ pub const THREAD_EXTENDED_INFO_COUNT: mach_msg_type_number_t = ++ (::mem::size_of::() / ::mem::size_of::()) ++ as mach_msg_type_number_t; ++ ++ pub const TASK_THREAD_TIMES_INFO_COUNT: u32 = ++ (::mem::size_of::() ++ / ::mem::size_of::()) as u32; ++ pub const MACH_TASK_BASIC_INFO_COUNT: u32 = (::mem::size_of::() ++ / ::mem::size_of::()) as u32; ++ pub const HOST_VM_INFO64_COUNT: mach_msg_type_number_t = ++ (::mem::size_of::() / ::mem::size_of::()) ++ as mach_msg_type_number_t; + } else { +- fn __DARWIN_ALIGN32(p: usize) -> usize { +- let __DARWIN_ALIGNBYTES32: usize = ::mem::size_of::() - 1; +- p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32 +- } + pub const THREAD_EXTENDED_POLICY_COUNT: mach_msg_type_number_t = 1; + pub const THREAD_TIME_CONSTRAINT_POLICY_COUNT: mach_msg_type_number_t = 4; + pub const THREAD_PRECEDENCE_POLICY_COUNT: mach_msg_type_number_t = 1; +@@ -3565,6 +4984,12 @@ cfg_if! { + pub const THREAD_BACKGROUND_POLICY_COUNT: mach_msg_type_number_t = 1; + pub const THREAD_LATENCY_QOS_POLICY_COUNT: mach_msg_type_number_t = 1; + pub const THREAD_THROUGHPUT_QOS_POLICY_COUNT: mach_msg_type_number_t = 1; ++ pub const THREAD_BASIC_INFO_COUNT: mach_msg_type_number_t = 10; ++ pub const THREAD_IDENTIFIER_INFO_COUNT: mach_msg_type_number_t = 6; ++ pub const THREAD_EXTENDED_INFO_COUNT: mach_msg_type_number_t = 28; ++ pub const TASK_THREAD_TIMES_INFO_COUNT: u32 = 4; ++ pub const MACH_TASK_BASIC_INFO_COUNT: u32 = 12; ++ pub const HOST_VM_INFO64_COUNT: mach_msg_type_number_t = 38; + } + } + +@@ -3600,6 +5025,22 @@ f! { + (__DARWIN_ALIGN32(::mem::size_of::<::cmsghdr>()) + length as usize) + as ::c_uint + } ++ ++ pub {const} fn VM_MAKE_TAG(id: u8) -> u32 { ++ (id as u32) << 24u32 ++ } ++ ++ pub fn major(dev: dev_t) -> i32 { ++ (dev >> 24) & 0xff ++ } ++ ++ pub fn minor(dev: dev_t) -> i32 { ++ dev & 0xffffff ++ } ++ ++ pub fn makedev(major: i32, minor: i32) -> dev_t { ++ (major << 24) | minor ++ } + } + + safe_f! { +@@ -3655,6 +5096,11 @@ extern "C" { + pub fn fchflags(fd: ::c_int, flags: ::c_uint) -> ::c_int; + pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; ++ #[cfg_attr( ++ all(target_os = "macos", target_arch = "x86"), ++ link_name = "confstr$UNIX2003" ++ )] ++ pub fn confstr(name: ::c_int, buf: *mut ::c_char, len: ::size_t) -> ::size_t; + pub fn lio_listio( + mode: ::c_int, + aiocb_list: *const *mut aiocb, +@@ -3675,6 +5121,23 @@ extern "C" { + pub fn endutxent(); + pub fn utmpxname(file: *const ::c_char) -> ::c_int; + ++ pub fn asctime(tm: *const ::tm) -> *mut ::c_char; ++ pub fn ctime(clock: *const time_t) -> *mut ::c_char; ++ pub fn getdate(datestr: *const ::c_char) -> *mut ::tm; ++ pub fn strftime( ++ buf: *mut ::c_char, ++ maxsize: ::size_t, ++ format: *const ::c_char, ++ timeptr: *const ::tm, ++ ) -> ::size_t; ++ pub fn strptime( ++ buf: *const ::c_char, ++ format: *const ::c_char, ++ timeptr: *mut ::tm, ++ ) -> *mut ::c_char; ++ pub fn asctime_r(tm: *const ::tm, result: *mut ::c_char) -> *mut ::c_char; ++ pub fn ctime_r(clock: *const time_t, result: *mut ::c_char) -> *mut ::c_char; ++ + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, +@@ -3727,16 +5190,27 @@ extern "C" { + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; +- #[deprecated(since = "0.2.55", note = "Use the mach crate")] ++ #[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] + pub fn mach_absolute_time() -> u64; +- #[deprecated(since = "0.2.55", note = "Use the mach crate")] ++ #[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] + #[allow(deprecated)] + pub fn mach_timebase_info(info: *mut ::mach_timebase_info) -> ::c_int; + pub fn mach_host_self() -> mach_port_t; + pub fn mach_thread_self() -> mach_port_t; + pub fn pthread_setname_np(name: *const ::c_char) -> ::c_int; + pub fn pthread_getname_np(thread: ::pthread_t, name: *mut ::c_char, len: ::size_t) -> ::c_int; ++ pub fn pthread_mach_thread_np(thread: ::pthread_t) -> ::mach_port_t; + pub fn pthread_from_mach_thread_np(port: ::mach_port_t) -> ::pthread_t; ++ pub fn pthread_create_from_mach_thread( ++ thread: *mut ::pthread_t, ++ attr: *const ::pthread_attr_t, ++ f: extern "C" fn(*mut ::c_void) -> *mut ::c_void, ++ value: *mut ::c_void, ++ ) -> ::c_int; ++ pub fn pthread_stack_frame_decode_np( ++ frame_addr: ::uintptr_t, ++ return_addr: *mut ::uintptr_t, ++ ) -> ::uintptr_t; + pub fn pthread_get_stackaddr_np(thread: ::pthread_t) -> *mut ::c_void; + pub fn pthread_get_stacksize_np(thread: ::pthread_t) -> ::size_t; + pub fn pthread_condattr_setpshared(attr: *mut pthread_condattr_t, pshared: ::c_int) -> ::c_int; +@@ -3744,6 +5218,7 @@ extern "C" { + attr: *const pthread_condattr_t, + pshared: *mut ::c_int, + ) -> ::c_int; ++ pub fn pthread_main_np() -> ::c_int; + pub fn pthread_mutexattr_setpshared( + attr: *mut pthread_mutexattr_t, + pshared: ::c_int, +@@ -3774,6 +5249,68 @@ extern "C" { + class: *mut qos_class_t, + priority: *mut ::c_int, + ) -> ::c_int; ++ pub fn pthread_attr_getschedparam( ++ attr: *const ::pthread_attr_t, ++ param: *mut sched_param, ++ ) -> ::c_int; ++ pub fn pthread_attr_setschedparam( ++ attr: *mut ::pthread_attr_t, ++ param: *const sched_param, ++ ) -> ::c_int; ++ pub fn pthread_getschedparam( ++ thread: ::pthread_t, ++ policy: *mut ::c_int, ++ param: *mut sched_param, ++ ) -> ::c_int; ++ pub fn pthread_setschedparam( ++ thread: ::pthread_t, ++ policy: ::c_int, ++ param: *const sched_param, ++ ) -> ::c_int; ++ ++ // Available from Big Sur ++ pub fn pthread_introspection_hook_install( ++ hook: ::pthread_introspection_hook_t, ++ ) -> ::pthread_introspection_hook_t; ++ pub fn pthread_introspection_setspecific_np( ++ thread: ::pthread_t, ++ key: ::pthread_key_t, ++ value: *const ::c_void, ++ ) -> ::c_int; ++ pub fn pthread_introspection_getspecific_np( ++ thread: ::pthread_t, ++ key: ::pthread_key_t, ++ ) -> *mut ::c_void; ++ pub fn pthread_jit_write_protect_np(enabled: ::c_int); ++ pub fn pthread_jit_write_protect_supported_np() -> ::c_int; ++ // An array of pthread_jit_write_with_callback_np must declare ++ // the list of callbacks e.g. ++ // #[link_section = "__DATA_CONST,__pth_jit_func"] ++ // static callbacks: [libc::pthread_jit_write_callback_t; 2] = [native_jit_write_cb, ++ // std::mem::transmute::(std::ptr::null())]; ++ // (a handy PTHREAD_JIT_WRITE_CALLBACK_NP macro for other languages). ++ pub fn pthread_jit_write_with_callback_np( ++ callback: ::pthread_jit_write_callback_t, ++ ctx: *mut ::c_void, ++ ) -> ::c_int; ++ pub fn pthread_jit_write_freeze_callbacks_np(); ++ pub fn pthread_cpu_number_np(cpu_number_out: *mut ::size_t) -> ::c_int; ++ ++ pub fn os_unfair_lock_lock(lock: os_unfair_lock_t); ++ pub fn os_unfair_lock_trylock(lock: os_unfair_lock_t) -> bool; ++ pub fn os_unfair_lock_unlock(lock: os_unfair_lock_t); ++ pub fn os_unfair_lock_assert_owner(lock: os_unfair_lock_t); ++ pub fn os_unfair_lock_assert_not_owner(lock: os_unfair_lock_t); ++ ++ pub fn os_log_create(subsystem: *const ::c_char, category: *const ::c_char) -> ::os_log_t; ++ pub fn os_log_type_enabled(oslog: ::os_log_t, tpe: ::os_log_type_t) -> bool; ++ pub fn os_signpost_id_make_with_pointer( ++ log: ::os_log_t, ++ ptr: *const ::c_void, ++ ) -> ::os_signpost_id_t; ++ pub fn os_signpost_id_generate(log: ::os_log_t) -> ::os_signpost_id_t; ++ pub fn os_signpost_enabled(log: ::os_log_t) -> bool; ++ + pub fn thread_policy_set( + thread: thread_t, + flavor: thread_policy_flavor_t, +@@ -3787,8 +5324,33 @@ extern "C" { + count: *mut mach_msg_type_number_t, + get_default: *mut boolean_t, + ) -> kern_return_t; ++ pub fn thread_info( ++ target_act: thread_inspect_t, ++ flavor: thread_flavor_t, ++ thread_info_out: thread_info_t, ++ thread_info_outCnt: *mut mach_msg_type_number_t, ++ ) -> kern_return_t; ++ #[cfg_attr(doc, doc(alias = "__errno_location"))] ++ #[cfg_attr(doc, doc(alias = "errno"))] + pub fn __error() -> *mut ::c_int; + pub fn backtrace(buf: *mut *mut ::c_void, sz: ::c_int) -> ::c_int; ++ pub fn backtrace_symbols(addrs: *const *mut ::c_void, sz: ::c_int) -> *mut *mut ::c_char; ++ pub fn backtrace_symbols_fd(addrs: *const *mut ::c_void, sz: ::c_int, fd: ::c_int); ++ pub fn backtrace_from_fp( ++ startfp: *mut ::c_void, ++ array: *mut *mut ::c_void, ++ size: ::c_int, ++ ) -> ::c_int; ++ pub fn backtrace_image_offsets( ++ array: *const *mut ::c_void, ++ image_offsets: *mut image_offset, ++ size: ::c_int, ++ ); ++ pub fn backtrace_async( ++ array: *mut *mut ::c_void, ++ length: ::size_t, ++ task_id: *mut u32, ++ ) -> ::size_t; + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "statfs$INODE64" +@@ -3822,6 +5384,12 @@ extern "C" { + flags: ::c_int, + data: *mut ::c_void, + ) -> ::c_int; ++ pub fn fmount( ++ src: *const ::c_char, ++ fd: ::c_int, ++ flags: ::c_int, ++ data: *mut ::c_void, ++ ) -> ::c_int; + pub fn ptrace(request: ::c_int, pid: ::pid_t, addr: *mut ::c_char, data: ::c_int) -> ::c_int; + pub fn quotactl( + special: *const ::c_char, +@@ -3944,14 +5512,14 @@ extern "C" { + pub fn brk(addr: *const ::c_void) -> *mut ::c_void; + pub fn sbrk(increment: ::c_int) -> *mut ::c_void; + pub fn settimeofday(tv: *const ::timeval, tz: *const ::timezone) -> ::c_int; +- #[deprecated(since = "0.2.55", note = "Use the mach crate")] ++ #[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] + pub fn _dyld_image_count() -> u32; +- #[deprecated(since = "0.2.55", note = "Use the mach crate")] ++ #[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] + #[allow(deprecated)] + pub fn _dyld_get_image_header(image_index: u32) -> *const mach_header; +- #[deprecated(since = "0.2.55", note = "Use the mach crate")] ++ #[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] + pub fn _dyld_get_image_vmaddr_slide(image_index: u32) -> ::intptr_t; +- #[deprecated(since = "0.2.55", note = "Use the mach crate")] ++ #[deprecated(since = "0.2.55", note = "Use the `mach2` crate instead")] + pub fn _dyld_get_image_name(image_index: u32) -> *const ::c_char; + + pub fn posix_spawn( +@@ -3998,6 +5566,28 @@ extern "C" { + flags: *mut ::pid_t, + ) -> ::c_int; + pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: ::pid_t) -> ::c_int; ++ pub fn posix_spawnattr_setarchpref_np( ++ attr: *mut posix_spawnattr_t, ++ count: ::size_t, ++ pref: *mut ::cpu_type_t, ++ subpref: *mut ::cpu_subtype_t, ++ ocount: *mut ::size_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_getarchpref_np( ++ attr: *const posix_spawnattr_t, ++ count: ::size_t, ++ pref: *mut ::cpu_type_t, ++ subpref: *mut ::cpu_subtype_t, ++ ocount: *mut ::size_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_set_qos_class_np( ++ attr: *mut posix_spawnattr_t, ++ qos_class: ::qos_class_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_get_qos_class_np( ++ attr: *const posix_spawnattr_t, ++ qos_class: *mut ::qos_class_t, ++ ) -> ::c_int; + + pub fn posix_spawn_file_actions_init(actions: *mut posix_spawn_file_actions_t) -> ::c_int; + pub fn posix_spawn_file_actions_destroy(actions: *mut posix_spawn_file_actions_t) -> ::c_int; +@@ -4063,6 +5653,19 @@ extern "C" { + flags: u32, + ) -> ::c_int; + ++ pub fn copyfile( ++ from: *const ::c_char, ++ to: *const ::c_char, ++ state: copyfile_state_t, ++ flags: copyfile_flags_t, ++ ) -> ::c_int; ++ pub fn fcopyfile( ++ from: ::c_int, ++ to: ::c_int, ++ state: copyfile_state_t, ++ flags: copyfile_flags_t, ++ ) -> ::c_int; ++ + // Added in macOS 10.13 + // ISO/IEC 9899:2011 ("ISO C11") K.3.7.4.1 + pub fn memset_s(s: *mut ::c_void, smax: ::size_t, c: ::c_int, n: ::size_t) -> ::c_int; +@@ -4071,7 +5674,36 @@ extern "C" { + pub fn memset_pattern8(b: *mut ::c_void, pattern8: *const ::c_void, len: ::size_t); + pub fn memset_pattern16(b: *mut ::c_void, pattern16: *const ::c_void, len: ::size_t); + ++ // Inherited from BSD but available from Big Sur only ++ pub fn strtonum( ++ __numstr: *const ::c_char, ++ __minval: ::c_longlong, ++ __maxval: ::c_longlong, ++ errstrp: *mut *const ::c_char, ++ ) -> ::c_longlong; ++ + pub fn mstats() -> mstats; ++ pub fn malloc_printf(format: *const ::c_char, ...); ++ pub fn malloc_zone_check(zone: *mut ::malloc_zone_t) -> ::boolean_t; ++ pub fn malloc_zone_print(zone: *mut ::malloc_zone_t, verbose: ::boolean_t); ++ pub fn malloc_zone_statistics(zone: *mut ::malloc_zone_t, stats: *mut malloc_statistics_t); ++ pub fn malloc_zone_log(zone: *mut ::malloc_zone_t, address: *mut ::c_void); ++ pub fn malloc_zone_print_ptr_info(ptr: *mut ::c_void); ++ pub fn malloc_default_zone() -> *mut ::malloc_zone_t; ++ pub fn malloc_zone_from_ptr(ptr: *const ::c_void) -> *mut ::malloc_zone_t; ++ pub fn malloc_zone_malloc(zone: *mut ::malloc_zone_t, size: ::size_t) -> *mut ::c_void; ++ pub fn malloc_zone_valloc(zone: *mut ::malloc_zone_t, size: ::size_t) -> *mut ::c_void; ++ pub fn malloc_zone_calloc( ++ zone: *mut ::malloc_zone_t, ++ num_items: ::size_t, ++ size: ::size_t, ++ ) -> *mut ::c_void; ++ pub fn malloc_zone_realloc( ++ zone: *mut ::malloc_zone_t, ++ ptr: *mut ::c_void, ++ size: ::size_t, ++ ) -> *mut ::c_void; ++ pub fn malloc_zone_free(zone: *mut ::malloc_zone_t, ptr: *mut ::c_void); + + pub fn proc_listpids( + t: u32, +@@ -4116,15 +5748,178 @@ extern "C" { + buffer: *mut ::c_void, + buffersize: u32, + ) -> ::c_int; ++ pub fn proc_kmsgbuf(buffer: *mut ::c_void, buffersize: u32) -> ::c_int; + pub fn proc_libversion(major: *mut ::c_int, mintor: *mut ::c_int) -> ::c_int; ++ pub fn proc_pid_rusage(pid: ::c_int, flavor: ::c_int, buffer: *mut rusage_info_t) -> ::c_int; ++ ++ // Available from Big Sur ++ pub fn proc_set_no_smt() -> ::c_int; ++ pub fn proc_setthread_no_smt() -> ::c_int; ++ pub fn proc_set_csm(flags: u32) -> ::c_int; ++ pub fn proc_setthread_csm(flags: u32) -> ::c_int; + /// # Notes + /// + /// `id` is of type [`uuid_t`]. + pub fn gethostuuid(id: *mut u8, timeout: *const ::timespec) -> ::c_int; ++ ++ pub fn gethostid() -> ::c_long; ++ pub fn sethostid(hostid: ::c_long); ++ ++ pub fn CCRandomGenerateBytes(bytes: *mut ::c_void, size: ::size_t) -> ::CCRNGStatus; ++ ++ pub fn _NSGetExecutablePath(buf: *mut ::c_char, bufsize: *mut u32) -> ::c_int; ++ pub fn _NSGetEnviron() -> *mut *mut *mut ::c_char; ++ ++ pub fn mach_vm_map( ++ target_task: ::vm_map_t, ++ address: *mut ::mach_vm_address_t, ++ size: ::mach_vm_size_t, ++ mask: ::mach_vm_offset_t, ++ flags: ::c_int, ++ object: ::mem_entry_name_port_t, ++ offset: ::memory_object_offset_t, ++ copy: ::boolean_t, ++ cur_protection: ::vm_prot_t, ++ max_protection: ::vm_prot_t, ++ inheritance: ::vm_inherit_t, ++ ) -> ::kern_return_t; ++ ++ pub fn vm_deallocate( ++ target_task: vm_map_t, ++ address: vm_address_t, ++ size: vm_size_t, ++ ) -> ::kern_return_t; ++ ++ pub fn host_statistics64( ++ host_priv: host_t, ++ flavor: host_flavor_t, ++ host_info64_out: host_info64_t, ++ host_info64_outCnt: *mut mach_msg_type_number_t, ++ ) -> ::kern_return_t; ++ pub fn host_processor_info( ++ host: host_t, ++ flavor: processor_flavor_t, ++ out_processor_count: *mut natural_t, ++ out_processor_info: *mut processor_info_array_t, ++ out_processor_infoCnt: *mut mach_msg_type_number_t, ++ ) -> ::kern_return_t; ++ ++ pub static mut mach_task_self_: ::mach_port_t; ++ pub fn task_for_pid( ++ host: ::mach_port_t, ++ pid: ::pid_t, ++ task: *mut ::mach_port_t, ++ ) -> ::kern_return_t; ++ pub fn task_info( ++ host: ::mach_port_t, ++ flavor: task_flavor_t, ++ task_info_out: task_info_t, ++ task_info_count: *mut mach_msg_type_number_t, ++ ) -> ::kern_return_t; ++ pub fn task_create( ++ target_task: ::task_t, ++ ledgers: ::ledger_array_t, ++ ledgersCnt: ::mach_msg_type_number_t, ++ inherit_memory: ::boolean_t, ++ child_task: *mut ::task_t, ++ ) -> ::kern_return_t; ++ pub fn task_terminate(target_task: ::task_t) -> ::kern_return_t; ++ pub fn task_threads( ++ target_task: ::task_inspect_t, ++ act_list: *mut ::thread_act_array_t, ++ act_listCnt: *mut ::mach_msg_type_number_t, ++ ) -> ::kern_return_t; ++ pub fn host_statistics( ++ host_priv: host_t, ++ flavor: host_flavor_t, ++ host_info_out: host_info_t, ++ host_info_outCnt: *mut mach_msg_type_number_t, ++ ) -> ::kern_return_t; ++ ++ // sysdir.h ++ pub fn sysdir_start_search_path_enumeration( ++ dir: sysdir_search_path_directory_t, ++ domainMask: sysdir_search_path_domain_mask_t, ++ ) -> ::sysdir_search_path_enumeration_state; ++ pub fn sysdir_get_next_search_path_enumeration( ++ state: ::sysdir_search_path_enumeration_state, ++ path: *mut ::c_char, ++ ) -> ::sysdir_search_path_enumeration_state; ++ ++ pub static vm_page_size: vm_size_t; ++ ++ pub fn getattrlist( ++ path: *const ::c_char, ++ attrList: *mut ::c_void, ++ attrBuf: *mut ::c_void, ++ attrBufSize: ::size_t, ++ options: u32, ++ ) -> ::c_int; ++ pub fn fgetattrlist( ++ fd: ::c_int, ++ attrList: *mut ::c_void, ++ attrBuf: *mut ::c_void, ++ attrBufSize: ::size_t, ++ options: u32, ++ ) -> ::c_int; ++ pub fn getattrlistat( ++ fd: ::c_int, ++ path: *const ::c_char, ++ attrList: *mut ::c_void, ++ attrBuf: *mut ::c_void, ++ attrBufSize: ::size_t, ++ options: ::c_ulong, ++ ) -> ::c_int; ++ pub fn setattrlist( ++ path: *const ::c_char, ++ attrList: *mut ::c_void, ++ attrBuf: *mut ::c_void, ++ attrBufSize: ::size_t, ++ options: u32, ++ ) -> ::c_int; ++ pub fn fsetattrlist( ++ fd: ::c_int, ++ attrList: *mut ::c_void, ++ attrBuf: *mut ::c_void, ++ attrBufSize: ::size_t, ++ options: u32, ++ ) -> ::c_int; ++ pub fn setattrlistat( ++ dir_fd: ::c_int, ++ path: *const ::c_char, ++ attrList: *mut ::c_void, ++ attrBuf: *mut ::c_void, ++ attrBufSize: ::size_t, ++ options: u32, ++ ) -> ::c_int; ++ pub fn getattrlistbulk( ++ dirfd: ::c_int, ++ attrList: *mut ::c_void, ++ attrBuf: *mut ::c_void, ++ attrBufSize: ::size_t, ++ options: u64, ++ ) -> ::c_int; ++ ++ pub fn malloc_size(ptr: *const ::c_void) -> ::size_t; ++ pub fn malloc_good_size(size: ::size_t) -> ::size_t; ++ ++ pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; ++ pub fn basename(path: *mut ::c_char) -> *mut ::c_char; ++} ++ ++pub unsafe fn mach_task_self() -> ::mach_port_t { ++ mach_task_self_ + } + + cfg_if! { + if #[cfg(target_os = "macos")] { ++ extern "C" { ++ pub fn clock_settime(clock_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; ++ } ++ } ++} ++cfg_if! { ++ if #[cfg(any(target_os = "macos", target_os = "ios"))] { + extern "C" { + pub fn memmem( + haystack: *const ::c_void, +@@ -4132,11 +5927,19 @@ cfg_if! { + needle: *const ::c_void, + needlelen: ::size_t, + ) -> *mut ::c_void; ++ pub fn task_set_info(target_task: ::task_t, ++ flavor: ::task_flavor_t, ++ task_info_in: ::task_info_t, ++ task_info_inCnt: ::mach_msg_type_number_t ++ ) -> ::kern_return_t; + } + } + } + +-#[link(name = "iconv")] ++// These require a dependency on `libiconv`, and including this when built as ++// part of `std` means every Rust program gets it. Ideally we would have a link ++// modifier to only include these if they are used, but we do not. ++#[cfg_attr(not(feature = "rustc-dep-of-std"), link(name = "iconv"))] + extern "C" { + pub fn iconv_open(tocode: *const ::c_char, fromcode: *const ::c_char) -> iconv_t; + pub fn iconv( +@@ -4150,13 +5953,20 @@ extern "C" { + } + + cfg_if! { +- if #[cfg(any(target_arch = "arm", target_arch = "x86"))] { ++ if #[cfg(target_pointer_width = "32")] { + mod b32; + pub use self::b32::*; +- } else if #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] { ++ } else if #[cfg(target_pointer_width = "64")] { + mod b64; + pub use self::b64::*; + } else { + // Unknown target_arch + } + } ++ ++cfg_if! { ++ if #[cfg(libc_long_array)] { ++ mod long_array; ++ pub use self::long_array::*; ++ } ++} +diff --git a/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs +index b9bdafe..63c0594 100644 +--- a/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs ++++ b/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs +@@ -18,6 +18,7 @@ pub type uuid_t = ::uuid; + pub type fsblkcnt_t = u64; + pub type fsfilcnt_t = u64; + pub type idtype_t = ::c_uint; ++pub type shmatt_t = ::c_uint; + + pub type mqd_t = ::c_int; + pub type sem_t = *mut sem; +@@ -26,6 +27,23 @@ pub type cpuset_t = cpumask_t; + pub type cpu_set_t = cpumask_t; + + pub type register_t = ::c_long; ++pub type umtx_t = ::c_int; ++pub type pthread_barrierattr_t = ::c_int; ++pub type pthread_barrier_t = ::uintptr_t; ++pub type pthread_spinlock_t = ::uintptr_t; ++ ++pub type segsz_t = usize; ++ ++pub type vm_prot_t = u8; ++pub type vm_maptype_t = u8; ++pub type vm_inherit_t = i8; ++pub type vm_subsys_t = ::c_int; ++pub type vm_eflags_t = ::c_uint; ++ ++pub type vm_map_t = *mut __c_anonymous_vm_map; ++pub type vm_map_entry_t = *mut vm_map_entry; ++ ++pub type pmap = __c_anonymous_pmap; + + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub enum sem {} +@@ -36,6 +54,24 @@ impl ::Clone for sem { + } + } + ++e! { ++ #[repr(u32)] ++ pub enum lwpstat { ++ LSRUN = 1, ++ LSSTOP = 2, ++ LSSLEEP = 3, ++ } ++ ++ #[repr(u32)] ++ pub enum procstat { ++ SIDL = 1, ++ SACTIVE = 2, ++ SSTOP = 3, ++ SZOMB = 4, ++ SCORE = 5, ++ } ++} ++ + s! { + pub struct kevent { + pub ident: ::uintptr_t, +@@ -118,11 +154,11 @@ s! { + pub st_ctime_nsec: ::c_long, + pub st_size: ::off_t, + pub st_blocks: i64, +- pub st_blksize: u32, ++ pub __old_st_blksize: u32, + pub st_flags: u32, + pub st_gen: u32, + pub st_lspare: i32, +- pub st_qspare1: i64, ++ pub st_blksize: i64, + pub st_qspare2: i64, + } + +@@ -185,7 +221,7 @@ s! { + } + + pub struct stack_t { +- pub ss_sp: *mut ::c_char, ++ pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } +@@ -193,6 +229,188 @@ s! { + pub struct cpumask_t { + ary: [u64; 4], + } ++ ++ pub struct shmid_ds { ++ pub shm_perm: ::ipc_perm, ++ pub shm_segsz: ::size_t, ++ pub shm_lpid: ::pid_t, ++ pub shm_cpid: ::pid_t, ++ pub shm_nattch: ::shmatt_t, ++ pub shm_atime: ::time_t, ++ pub shm_dtime: ::time_t, ++ pub shm_ctime: ::time_t, ++ shm_internal: *mut ::c_void, ++ } ++ ++ pub struct kinfo_file { ++ pub f_size: ::size_t, ++ pub f_pid: ::pid_t, ++ pub f_uid: ::uid_t, ++ pub f_fd: ::c_int, ++ pub f_file: *mut ::c_void, ++ pub f_type: ::c_short, ++ pub f_count: ::c_int, ++ pub f_msgcount: ::c_int, ++ pub f_offset: ::off_t, ++ pub f_data: *mut ::c_void, ++ pub f_flag: ::c_uint, ++ } ++ ++ pub struct kinfo_cputime { ++ pub cp_user: u64, ++ pub cp_nice: u64, ++ pub cp_sys: u64, ++ pub cp_intr: u64, ++ pub cp_idel: u64, ++ cp_unused01: u64, ++ cp_unused02: u64, ++ pub cp_sample_pc: u64, ++ pub cp_sample_sp: u64, ++ pub cp_msg: [::c_char; 32], ++ } ++ ++ pub struct kinfo_lwp { ++ pub kl_pid: ::pid_t, ++ pub kl_tid: ::lwpid_t, ++ pub kl_flags: ::c_int, ++ pub kl_stat: ::lwpstat, ++ pub kl_lock: ::c_int, ++ pub kl_tdflags: ::c_int, ++ pub kl_mpcount: ::c_int, ++ pub kl_prio: ::c_int, ++ pub kl_tdprio: ::c_int, ++ pub kl_rtprio: ::rtprio, ++ pub kl_uticks: u64, ++ pub kl_sticks: u64, ++ pub kl_iticks: u64, ++ pub kl_cpticks: u64, ++ pub kl_pctcpu: ::c_uint, ++ pub kl_slptime: ::c_uint, ++ pub kl_origcpu: ::c_int, ++ pub kl_estcpu: ::c_int, ++ pub kl_cpuid: ::c_int, ++ pub kl_ru: ::rusage, ++ pub kl_siglist: ::sigset_t, ++ pub kl_sigmask: ::sigset_t, ++ pub kl_wchan: ::uintptr_t, ++ pub kl_wmesg: [::c_char; 9], ++ pub kl_comm: [::c_char; MAXCOMLEN+1], ++ } ++ ++ pub struct kinfo_proc { ++ pub kp_paddr: ::uintptr_t, ++ pub kp_flags: ::c_int, ++ pub kp_stat: ::procstat, ++ pub kp_lock: ::c_int, ++ pub kp_acflag: ::c_int, ++ pub kp_traceflag: ::c_int, ++ pub kp_fd: ::uintptr_t, ++ pub kp_siglist: ::sigset_t, ++ pub kp_sigignore: ::sigset_t, ++ pub kp_sigcatch: ::sigset_t, ++ pub kp_sigflag: ::c_int, ++ pub kp_start: ::timeval, ++ pub kp_comm: [::c_char; MAXCOMLEN+1], ++ pub kp_uid: ::uid_t, ++ pub kp_ngroups: ::c_short, ++ pub kp_groups: [::gid_t; NGROUPS], ++ pub kp_ruid: ::uid_t, ++ pub kp_svuid: ::uid_t, ++ pub kp_rgid: ::gid_t, ++ pub kp_svgid: ::gid_t, ++ pub kp_pid: ::pid_t, ++ pub kp_ppid: ::pid_t, ++ pub kp_pgid: ::pid_t, ++ pub kp_jobc: ::c_int, ++ pub kp_sid: ::pid_t, ++ pub kp_login: [::c_char; 40], // MAXNAMELEN rounded up to the nearest sizeof(long) ++ pub kp_tdev: ::dev_t, ++ pub kp_tpgid: ::pid_t, ++ pub kp_tsid: ::pid_t, ++ pub kp_exitstat: ::c_ushort, ++ pub kp_nthreads: ::c_int, ++ pub kp_nice: ::c_int, ++ pub kp_swtime: ::c_uint, ++ pub kp_vm_map_size: ::size_t, ++ pub kp_vm_rssize: ::segsz_t, ++ pub kp_vm_swrss: ::segsz_t, ++ pub kp_vm_tsize: ::segsz_t, ++ pub kp_vm_dsize: ::segsz_t, ++ pub kp_vm_ssize: ::segsz_t, ++ pub kp_vm_prssize: ::c_uint, ++ pub kp_jailid: ::c_int, ++ pub kp_ru: ::rusage, ++ pub kp_cru: ::rusage, ++ pub kp_auxflags: ::c_int, ++ pub kp_lwp: ::kinfo_lwp, ++ pub kp_ktaddr: ::uintptr_t, ++ kp_spare: [::c_int; 2], ++ } ++ ++ pub struct __c_anonymous_vm_map { ++ _priv: [::uintptr_t; 36], ++ } ++ ++ pub struct vm_map_entry { ++ _priv: [::uintptr_t; 15], ++ pub eflags: ::vm_eflags_t, ++ pub maptype: ::vm_maptype_t, ++ pub protection: ::vm_prot_t, ++ pub max_protection: ::vm_prot_t, ++ pub inheritance: ::vm_inherit_t, ++ pub wired_count: ::c_int, ++ pub id: ::vm_subsys_t, ++ } ++ ++ pub struct __c_anonymous_pmap { ++ _priv1: [::uintptr_t; 32], ++ _priv2: [::uintptr_t; 32], ++ _priv3: [::uintptr_t; 32], ++ _priv4: [::uintptr_t; 32], ++ _priv5: [::uintptr_t; 8], ++ } ++ ++ pub struct vmspace { ++ vm_map: __c_anonymous_vm_map, ++ vm_pmap: __c_anonymous_pmap, ++ pub vm_flags: ::c_int, ++ pub vm_shm: *mut ::c_char, ++ pub vm_rssize: ::segsz_t, ++ pub vm_swrss: ::segsz_t, ++ pub vm_tsize: ::segsz_t, ++ pub vm_dsize: ::segsz_t, ++ pub vm_ssize: ::segsz_t, ++ pub vm_taddr: *mut ::c_char, ++ pub vm_daddr: *mut ::c_char, ++ pub vm_maxsaddr: *mut ::c_char, ++ pub vm_minsaddr: *mut ::c_char, ++ _unused1: ::c_int, ++ _unused2: ::c_int, ++ pub vm_pagesupply: ::c_int, ++ pub vm_holdcnt: ::c_uint, ++ pub vm_refcnt: ::c_uint, ++ } ++ ++ pub struct cpuctl_msr_args_t { ++ pub msr: ::c_int, ++ pub data: u64, ++ } ++ ++ pub struct cpuctl_cpuid_args_t { ++ pub level: ::c_int, ++ pub data: [u32; 4], ++ } ++ ++ pub struct cpuctl_cpuid_count_args_t { ++ pub level: ::c_int, ++ pub level_type: ::c_int, ++ pub data: [u32; 4], ++ } ++ ++ pub struct cpuctl_update_args_t { ++ pub data: *mut ::c_void, ++ pub size: ::size_t, ++ } + } + + s_no_extra_traits! { +@@ -213,6 +431,13 @@ s_no_extra_traits! { + pub ut_unused2: [u8; 16], + } + ++ pub struct lastlogx { ++ pub ll_tv: ::timeval, ++ pub ll_line: [::c_char; _UTX_LINESIZE], ++ pub ll_host: [::c_char; _UTX_HOSTSIZE], ++ pub ll_ss: ::sockaddr_storage, ++ } ++ + pub struct dirent { + pub d_fileno: ::ino_t, + pub d_namlen: u16, +@@ -223,6 +448,7 @@ s_no_extra_traits! { + } + + pub struct statfs { ++ __spare2: ::c_long, + pub f_bsize: ::c_long, + pub f_iosize: ::c_long, + pub f_blocks: ::c_long, +@@ -232,15 +458,18 @@ s_no_extra_traits! { + pub f_ffree: ::c_long, + pub f_fsid: ::fsid_t, + pub f_owner: ::uid_t, +- pub f_type: i32, +- pub f_flags: i32, ++ pub f_type: ::c_int, ++ pub f_flags: ::c_int, + pub f_syncwrites: ::c_long, + pub f_asyncwrites: ::c_long, + pub f_fstypename: [::c_char; 16], +- pub f_mntonname: [::c_char; 90], ++ pub f_mntonname: [::c_char; 80], + pub f_syncreads: ::c_long, + pub f_asyncreads: ::c_long, +- pub f_mntfromname: [::c_char; 90], ++ __spares1: ::c_short, ++ pub f_mntfromname: [::c_char; 80], ++ __spares2: ::c_short, ++ __spare: [::c_long; 2], + } + + pub struct sigevent { +@@ -359,6 +588,33 @@ cfg_if! { + self.ut_unused2.hash(state); + } + } ++ impl PartialEq for lastlogx { ++ fn eq(&self, other: &lastlogx) -> bool { ++ self.ll_tv == other.ll_tv ++ && self.ll_line == other.ll_line ++ && self.ll_host == other.ll_host ++ && self.ll_ss == other.ll_ss ++ } ++ } ++ impl Eq for lastlogx {} ++ impl ::fmt::Debug for lastlogx { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("lastlogx") ++ .field("ll_tv", &self.ll_tv) ++ .field("ll_line", &self.ll_line) ++ .field("ll_host", &self.ll_host) ++ .field("ll_ss", &self.ll_ss) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for lastlogx { ++ fn hash(&self, state: &mut H) { ++ self.ll_tv.hash(state); ++ self.ll_line.hash(state); ++ self.ll_host.hash(state); ++ self.ll_ss.hash(state); ++ } ++ } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { +@@ -529,8 +785,9 @@ cfg_if! { + self.mc_ss == other.mc_ss && + self.mc_len == other.mc_len && + self.mc_fpformat == other.mc_fpformat && +- self.mc_ownedfp == other.mc_ownedfp +- // FIXME: self.mc_fpregs == other.mc_fpregs ++ self.mc_ownedfp == other.mc_ownedfp && ++ self.mc_fpregs.iter().zip(other.mc_fpregs.iter()). ++ all(|(a, b)| a == b) + } + } + impl Eq for mcontext_t {} +@@ -566,10 +823,46 @@ cfg_if! { + .field("mc_len", &self.mc_len) + .field("mc_fpformat", &self.mc_fpformat) + .field("mc_ownedfp", &self.mc_ownedfp) +- // FIXME: .field("mc_fpregs", &self.mc_fpregs) ++ .field("mc_fpregs", &self.mc_fpregs) + .finish() + } + } ++ impl ::hash::Hash for mcontext_t { ++ fn hash(&self, state: &mut H) { ++ self.mc_onstack.hash(state); ++ self.mc_rdi.hash(state); ++ self.mc_rsi.hash(state); ++ self.mc_rdx.hash(state); ++ self.mc_rcx.hash(state); ++ self.mc_r8.hash(state); ++ self.mc_r9.hash(state); ++ self.mc_rax.hash(state); ++ self.mc_rbx.hash(state); ++ self.mc_rbp.hash(state); ++ self.mc_r10.hash(state); ++ self.mc_r11.hash(state); ++ self.mc_r10.hash(state); ++ self.mc_r11.hash(state); ++ self.mc_r12.hash(state); ++ self.mc_r13.hash(state); ++ self.mc_r14.hash(state); ++ self.mc_r15.hash(state); ++ self.mc_xflags.hash(state); ++ self.mc_trapno.hash(state); ++ self.mc_addr.hash(state); ++ self.mc_flags.hash(state); ++ self.mc_err.hash(state); ++ self.mc_rip.hash(state); ++ self.mc_cs.hash(state); ++ self.mc_rflags.hash(state); ++ self.mc_rsp.hash(state); ++ self.mc_ss.hash(state); ++ self.mc_len.hash(state); ++ self.mc_fpformat.hash(state); ++ self.mc_ownedfp.hash(state); ++ self.mc_fpregs.hash(state); ++ } ++ } + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_sigmask == other.uc_sigmask +@@ -593,12 +886,26 @@ cfg_if! { + .finish() + } + } ++ impl ::hash::Hash for ucontext_t { ++ fn hash(&self, state: &mut H) { ++ self.uc_sigmask.hash(state); ++ self.uc_mcontext.hash(state); ++ self.uc_link.hash(state); ++ self.uc_stack.hash(state); ++ self.uc_cofunc.hash(state); ++ self.uc_arg.hash(state); ++ } ++ } + } + } + + pub const RAND_MAX: ::c_int = 0x7fff_ffff; + pub const PTHREAD_STACK_MIN: ::size_t = 16384; + pub const SIGSTKSZ: ::size_t = 40960; ++pub const SIGCKPT: ::c_int = 33; ++pub const SIGCKPTEXIT: ::c_int = 34; ++pub const CKPT_FREEZE: ::c_int = 0x1; ++pub const CKPT_THAW: ::c_int = 0x2; + pub const MADV_INVAL: ::c_int = 10; + pub const MADV_SETMAP: ::c_int = 11; + pub const O_CLOEXEC: ::c_int = 0x00020000; +@@ -606,7 +913,10 @@ pub const O_DIRECTORY: ::c_int = 0x08000000; + pub const F_GETLK: ::c_int = 7; + pub const F_SETLK: ::c_int = 8; + pub const F_SETLKW: ::c_int = 9; ++pub const F_GETPATH: ::c_int = 19; + pub const ENOMEDIUM: ::c_int = 93; ++pub const ENOTRECOVERABLE: ::c_int = 94; ++pub const EOWNERDEAD: ::c_int = 95; + pub const EASYNC: ::c_int = 99; + pub const ELAST: ::c_int = 99; + pub const RLIMIT_POSIXLOCKS: ::c_int = 11; +@@ -748,6 +1058,16 @@ pub const CTL_P1003_1B_SIGQUEUE_MAX: ::c_int = 24; + pub const CTL_P1003_1B_TIMER_MAX: ::c_int = 25; + pub const CTL_P1003_1B_MAXID: ::c_int = 26; + ++pub const CPUCTL_RSMSR: ::c_int = 0xc0106301; ++pub const CPUCTL_WRMSR: ::c_int = 0xc0106302; ++pub const CPUCTL_CPUID: ::c_int = 0xc0106303; ++pub const CPUCTL_UPDATE: ::c_int = 0xc0106304; ++pub const CPUCTL_MSRSBIT: ::c_int = 0xc0106305; ++pub const CPUCTL_MSRCBIT: ::c_int = 0xc0106306; ++pub const CPUCTL_CPUID_COUNT: ::c_int = 0xc0106307; ++ ++pub const CPU_SETSIZE: ::size_t = ::mem::size_of::<::cpumask_t>() * 8; ++ + pub const EVFILT_READ: i16 = -1; + pub const EVFILT_WRITE: i16 = -2; + pub const EVFILT_AIO: i16 = -3; +@@ -771,8 +1091,11 @@ pub const EV_NODATA: u16 = 0x1000; + pub const EV_FLAG1: u16 = 0x2000; + pub const EV_ERROR: u16 = 0x4000; + pub const EV_EOF: u16 = 0x8000; ++pub const EV_HUP: u16 = 0x8000; + pub const EV_SYSFLAGS: u16 = 0xf000; + ++pub const FIODNAME: ::c_ulong = 0x80106678; ++ + pub const NOTE_TRIGGER: u32 = 0x01000000; + pub const NOTE_FFNOP: u32 = 0x00000000; + pub const NOTE_FFAND: u32 = 0x40000000; +@@ -800,9 +1123,16 @@ pub const NOTE_CHILD: u32 = 0x00000004; + + pub const SO_SNDSPACE: ::c_int = 0x100a; + pub const SO_CPUHINT: ::c_int = 0x1030; ++pub const SO_PASSCRED: ::c_int = 0x4000; + + pub const PT_FIRSTMACH: ::c_int = 32; + ++pub const PROC_REAP_ACQUIRE: ::c_int = 0x0001; ++pub const PROC_REAP_RELEASE: ::c_int = 0x0002; ++pub const PROC_REAP_STATUS: ::c_int = 0x0003; ++pub const PROC_PDEATHSIG_CTL: ::c_int = 0x0004; ++pub const PROC_PDEATHSIG_STATUS: ::c_int = 0x0005; ++ + // https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sys/net/if.h#L101 + pub const IFF_UP: ::c_int = 0x1; // interface is up + pub const IFF_BROADCAST: ::c_int = 0x2; // broadcast address valid +@@ -1080,6 +1410,16 @@ pub const MSG_FBLOCKING: ::c_int = 0x00010000; + pub const MSG_FNONBLOCKING: ::c_int = 0x00020000; + pub const MSG_FMASK: ::c_int = 0xFFFF0000; + ++// sys/mount.h ++pub const MNT_NODEV: ::c_int = 0x00000010; ++pub const MNT_AUTOMOUNTED: ::c_int = 0x00000020; ++pub const MNT_TRIM: ::c_int = 0x01000000; ++pub const MNT_LOCAL: ::c_int = 0x00001000; ++pub const MNT_QUOTA: ::c_int = 0x00002000; ++pub const MNT_ROOTFS: ::c_int = 0x00004000; ++pub const MNT_USER: ::c_int = 0x00008000; ++pub const MNT_IGNORE: ::c_int = 0x00800000; ++ + // utmpx entry types + pub const EMPTY: ::c_short = 0; + pub const RUN_LVL: ::c_short = 1; +@@ -1097,6 +1437,10 @@ pub const DOWNTIME: ::c_short = 11; + pub const UTX_DB_UTMPX: ::c_uint = 0; + pub const UTX_DB_WTMPX: ::c_uint = 1; + pub const UTX_DB_LASTLOG: ::c_uint = 2; ++pub const _UTX_LINESIZE: usize = 32; ++pub const _UTX_USERSIZE: usize = 32; ++pub const _UTX_IDSIZE: usize = 4; ++pub const _UTX_HOSTSIZE: usize = 256; + + pub const LC_COLLATE_MASK: ::c_int = 1 << 0; + pub const LC_CTYPE_MASK: ::c_int = 1 << 1; +@@ -1111,11 +1455,11 @@ pub const LC_ALL_MASK: ::c_int = LC_COLLATE_MASK + | LC_NUMERIC_MASK + | LC_TIME_MASK; + +-pub const TIOCSIG: ::c_uint = 0x2000745f; ++pub const TIOCSIG: ::c_ulong = 0x2000745f; + pub const BTUARTDISC: ::c_int = 0x7; +-pub const TIOCDCDTIMESTAMP: ::c_uint = 0x40107458; +-pub const TIOCISPTMASTER: ::c_uint = 0x20007455; +-pub const TIOCMODG: ::c_uint = 0x40047403; ++pub const TIOCDCDTIMESTAMP: ::c_ulong = 0x40107458; ++pub const TIOCISPTMASTER: ::c_ulong = 0x20007455; ++pub const TIOCMODG: ::c_ulong = 0x40047403; + pub const TIOCMODS: ::c_ulong = 0x80047404; + pub const TIOCREMOTE: ::c_ulong = 0x80047469; + +@@ -1168,9 +1512,16 @@ pub const SF_XLINK: ::c_ulong = 0x01000000; + pub const UTIME_OMIT: c_long = -2; + pub const UTIME_NOW: c_long = -1; + ++pub const MINCORE_SUPER: ::c_int = 0x20; ++ ++// kinfo_proc constants ++pub const MAXCOMLEN: usize = 16; ++pub const MAXLOGNAME: usize = 33; ++pub const NGROUPS: usize = 16; ++ + const_fn! { + {const} fn _CMSG_ALIGN(n: usize) -> usize { +- (n + 3) & !3 ++ (n + (::mem::size_of::<::c_long>() - 1)) & !(::mem::size_of::<::c_long>() - 1) + } + } + +@@ -1223,7 +1574,7 @@ f! { + () + } + +- pub fn CPU_ISSET(cpu: usize, cpuset: &mut cpu_set_t) -> bool { ++ pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { + let (idx, offset) = ((cpu >> 6) & 3, cpu & 63); + 0 != cpuset.ary[idx] & (1 << offset) + } +@@ -1233,6 +1584,15 @@ safe_f! { + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + (status & 0o177) != 0o177 && (status & 0o177) != 0 + } ++ ++ pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { ++ let major = major as ::dev_t; ++ let minor = minor as ::dev_t; ++ let mut dev = 0; ++ dev |= major << 8; ++ dev |= minor; ++ dev ++ } + } + + extern "C" { +@@ -1244,6 +1604,13 @@ extern "C" { + + pub fn aio_waitcomplete(iocbp: *mut *mut aiocb, timeout: *mut ::timespec) -> ::c_int; + ++ pub fn devname_r( ++ dev: ::dev_t, ++ mode: ::mode_t, ++ buf: *mut ::c_char, ++ len: ::size_t, ++ ) -> *mut ::c_char; ++ + pub fn waitid( + idtype: idtype_t, + id: ::id_t, +@@ -1269,10 +1636,37 @@ extern "C" { + needle: *const ::c_void, + needlelen: ::size_t, + ) -> *mut ::c_void; ++ pub fn pthread_spin_init(lock: *mut pthread_spinlock_t, pshared: ::c_int) -> ::c_int; ++ pub fn pthread_spin_destroy(lock: *mut pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_lock(lock: *mut pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_trylock(lock: *mut pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_unlock(lock: *mut pthread_spinlock_t) -> ::c_int; ++ + pub fn sched_getaffinity(pid: ::pid_t, cpusetsize: ::size_t, mask: *mut cpu_set_t) -> ::c_int; + pub fn sched_setaffinity(pid: ::pid_t, cpusetsize: ::size_t, mask: *const cpu_set_t) + -> ::c_int; ++ pub fn sched_getcpu() -> ::c_int; + pub fn setproctitle(fmt: *const ::c_char, ...); ++ ++ pub fn shmget(key: ::key_t, size: ::size_t, shmflg: ::c_int) -> ::c_int; ++ pub fn shmat(shmid: ::c_int, shmaddr: *const ::c_void, shmflg: ::c_int) -> *mut ::c_void; ++ pub fn shmdt(shmaddr: *const ::c_void) -> ::c_int; ++ pub fn shmctl(shmid: ::c_int, cmd: ::c_int, buf: *mut ::shmid_ds) -> ::c_int; ++ pub fn procctl(idtype: ::idtype_t, id: ::id_t, cmd: ::c_int, data: *mut ::c_void) -> ::c_int; ++ ++ pub fn updwtmpx(file: *const ::c_char, ut: *const utmpx) -> ::c_int; ++ pub fn getlastlogx(fname: *const ::c_char, uid: ::uid_t, ll: *mut lastlogx) -> *mut lastlogx; ++ pub fn updlastlogx(fname: *const ::c_char, uid: ::uid_t, ll: *mut lastlogx) -> ::c_int; ++ pub fn getutxuser(name: *const ::c_char) -> utmpx; ++ pub fn utmpxname(file: *const ::c_char) -> ::c_int; ++ ++ pub fn sys_checkpoint(tpe: ::c_int, fd: ::c_int, pid: ::pid_t, retval: ::c_int) -> ::c_int; ++ ++ pub fn umtx_sleep(ptr: *const ::c_int, value: ::c_int, timeout: ::c_int) -> ::c_int; ++ pub fn umtx_wakeup(ptr: *const ::c_int, count: ::c_int) -> ::c_int; ++ ++ pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; ++ pub fn basename(path: *mut ::c_char) -> *mut ::c_char; + } + + #[link(name = "rt")] +@@ -1294,6 +1688,23 @@ extern "C" { + nitems: ::c_int, + sevp: *mut sigevent, + ) -> ::c_int; ++ ++ pub fn reallocf(ptr: *mut ::c_void, size: ::size_t) -> *mut ::c_void; ++ pub fn freezero(ptr: *mut ::c_void, size: ::size_t); ++} ++ ++#[link(name = "kvm")] ++extern "C" { ++ pub fn kvm_vm_map_entry_first( ++ kvm: *mut ::kvm_t, ++ map: vm_map_t, ++ entry: vm_map_entry_t, ++ ) -> vm_map_entry_t; ++ pub fn kvm_vm_map_entry_next( ++ kvm: *mut ::kvm_t, ++ map: vm_map_entry_t, ++ entry: vm_map_entry_t, ++ ) -> vm_map_entry_t; + } + + cfg_if! { +diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/aarch64.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/aarch64.rs +index db0093a..e8be881 100644 +--- a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/aarch64.rs ++++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/aarch64.rs +@@ -6,6 +6,33 @@ pub type time_t = i64; + pub type suseconds_t = i64; + pub type register_t = i64; + ++s_no_extra_traits! { ++ pub struct gpregs { ++ pub gp_x: [::register_t; 30], ++ pub gp_lr: ::register_t, ++ pub gp_sp: ::register_t, ++ pub gp_elr: ::register_t, ++ pub gp_spsr: u32, ++ pub gp_pad: ::c_int, ++ } ++ ++ pub struct fpregs { ++ pub fp_q: u128, ++ pub fp_sr: u32, ++ pub fp_cr: u32, ++ pub fp_flags: ::c_int, ++ pub fp_pad: ::c_int, ++ } ++ ++ pub struct mcontext_t { ++ pub mc_gpregs: gpregs, ++ pub mc_fpregs: fpregs, ++ pub mc_flags: ::c_int, ++ pub mc_pad: ::c_int, ++ pub mc_spare: [u64; 8], ++ } ++} ++ + // should be pub(crate), but that requires Rust 1.18.0 + cfg_if! { + if #[cfg(libc_const_size_of)] { +@@ -17,5 +44,103 @@ cfg_if! { + } + } + ++cfg_if! { ++ if #[cfg(feature = "extra_traits")] { ++ impl PartialEq for gpregs { ++ fn eq(&self, other: &gpregs) -> bool { ++ self.gp_x.iter().zip(other.gp_x.iter()).all(|(a, b)| a == b) && ++ self.gp_lr == other.gp_lr && ++ self.gp_sp == other.gp_sp && ++ self.gp_elr == other.gp_elr && ++ self.gp_spsr == other.gp_spsr && ++ self.gp_pad == other.gp_pad ++ } ++ } ++ impl Eq for gpregs {} ++ impl ::fmt::Debug for gpregs { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("gpregs") ++ .field("gp_x", &self.gp_x) ++ .field("gp_lr", &self.gp_lr) ++ .field("gp_sp", &self.gp_sp) ++ .field("gp_elr", &self.gp_elr) ++ .field("gp_spsr", &self.gp_spsr) ++ .field("gp_pad", &self.gp_pad) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for gpregs { ++ fn hash(&self, state: &mut H) { ++ self.gp_x.hash(state); ++ self.gp_lr.hash(state); ++ self.gp_sp.hash(state); ++ self.gp_elr.hash(state); ++ self.gp_spsr.hash(state); ++ self.gp_pad.hash(state); ++ } ++ } ++ impl PartialEq for fpregs { ++ fn eq(&self, other: &fpregs) -> bool { ++ self.fp_q == other.fp_q && ++ self.fp_sr == other.fp_sr && ++ self.fp_cr == other.fp_cr && ++ self.fp_flags == other.fp_flags && ++ self.fp_pad == other.fp_pad ++ } ++ } ++ impl Eq for fpregs {} ++ impl ::fmt::Debug for fpregs { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("fpregs") ++ .field("fp_q", &self.fp_q) ++ .field("fp_sr", &self.fp_sr) ++ .field("fp_cr", &self.fp_cr) ++ .field("fp_flags", &self.fp_flags) ++ .field("fp_pad", &self.fp_pad) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for fpregs { ++ fn hash(&self, state: &mut H) { ++ self.fp_q.hash(state); ++ self.fp_sr.hash(state); ++ self.fp_cr.hash(state); ++ self.fp_flags.hash(state); ++ self.fp_pad.hash(state); ++ } ++ } ++ impl PartialEq for mcontext_t { ++ fn eq(&self, other: &mcontext_t) -> bool { ++ self.mc_gpregs == other.mc_gpregs && ++ self.mc_fpregs == other.mc_fpregs && ++ self.mc_flags == other.mc_flags && ++ self.mc_pad == other.mc_pad && ++ self.mc_spare.iter().zip(other.mc_spare.iter()).all(|(a, b)| a == b) ++ } ++ } ++ impl Eq for mcontext_t {} ++ impl ::fmt::Debug for mcontext_t { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("mcontext_t") ++ .field("mc_gpregs", &self.mc_gpregs) ++ .field("mc_fpregs", &self.mc_fpregs) ++ .field("mc_flags", &self.mc_flags) ++ .field("mc_pad", &self.mc_pad) ++ .field("mc_spare", &self.mc_spare) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for mcontext_t { ++ fn hash(&self, state: &mut H) { ++ self.mc_gpregs.hash(state); ++ self.mc_fpregs.hash(state); ++ self.mc_flags.hash(state); ++ self.mc_pad.hash(state); ++ self.mc_spare.hash(state); ++ } ++ } ++ } ++} ++ + pub const MAP_32BIT: ::c_int = 0x00080000; + pub const MINSIGSTKSZ: ::size_t = 4096; // 1024 * 4 +diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs +index a0b5105..f2d170f 100644 +--- a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs ++++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs +@@ -29,6 +29,186 @@ s! { + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + } ++ ++ pub struct kinfo_proc { ++ /// Size of this structure. ++ pub ki_structsize: ::c_int, ++ /// Reserved: layout identifier. ++ pub ki_layout: ::c_int, ++ /// Address of command arguments. ++ pub ki_args: *mut ::pargs, ++ // This is normally "struct proc". ++ /// Address of proc. ++ pub ki_paddr: *mut ::c_void, ++ // This is normally "struct user". ++ /// Kernel virtual address of u-area. ++ pub ki_addr: *mut ::c_void, ++ // This is normally "struct vnode". ++ /// Pointer to trace file. ++ pub ki_tracep: *mut ::c_void, ++ // This is normally "struct vnode". ++ /// Pointer to executable file. ++ pub ki_textvp: *mut ::c_void, ++ // This is normally "struct filedesc". ++ /// Pointer to open file info. ++ pub ki_fd: *mut ::c_void, ++ // This is normally "struct vmspace". ++ /// Pointer to kernel vmspace struct. ++ pub ki_vmspace: *mut ::c_void, ++ /// Sleep address. ++ pub ki_wchan: *mut ::c_void, ++ /// Process identifier. ++ pub ki_pid: ::pid_t, ++ /// Parent process ID. ++ pub ki_ppid: ::pid_t, ++ /// Process group ID. ++ pub ki_pgid: ::pid_t, ++ /// tty process group ID. ++ pub ki_tpgid: ::pid_t, ++ /// Process session ID. ++ pub ki_sid: ::pid_t, ++ /// Terminal session ID. ++ pub ki_tsid: ::pid_t, ++ /// Job control counter. ++ pub ki_jobc: ::c_short, ++ /// Unused (just here for alignment). ++ pub ki_spare_short1: ::c_short, ++ /// Controlling tty dev. ++ pub ki_tdev: ::dev_t, ++ /// Signals arrived but not delivered. ++ pub ki_siglist: ::sigset_t, ++ /// Current signal mask. ++ pub ki_sigmask: ::sigset_t, ++ /// Signals being ignored. ++ pub ki_sigignore: ::sigset_t, ++ /// Signals being caught by user. ++ pub ki_sigcatch: ::sigset_t, ++ /// Effective user ID. ++ pub ki_uid: ::uid_t, ++ /// Real user ID. ++ pub ki_ruid: ::uid_t, ++ /// Saved effective user ID. ++ pub ki_svuid: ::uid_t, ++ /// Real group ID. ++ pub ki_rgid: ::gid_t, ++ /// Saved effective group ID. ++ pub ki_svgid: ::gid_t, ++ /// Number of groups. ++ pub ki_ngroups: ::c_short, ++ /// Unused (just here for alignment). ++ pub ki_spare_short2: ::c_short, ++ /// Groups. ++ pub ki_groups: [::gid_t; ::KI_NGROUPS], ++ /// Virtual size. ++ pub ki_size: ::vm_size_t, ++ /// Current resident set size in pages. ++ pub ki_rssize: ::segsz_t, ++ /// Resident set size before last swap. ++ pub ki_swrss: ::segsz_t, ++ /// Text size (pages) XXX. ++ pub ki_tsize: ::segsz_t, ++ /// Data size (pages) XXX. ++ pub ki_dsize: ::segsz_t, ++ /// Stack size (pages). ++ pub ki_ssize: ::segsz_t, ++ /// Exit status for wait & stop signal. ++ pub ki_xstat: ::u_short, ++ /// Accounting flags. ++ pub ki_acflag: ::u_short, ++ /// %cpu for process during `ki_swtime`. ++ pub ki_pctcpu: ::fixpt_t, ++ /// Time averaged value of `ki_cpticks`. ++ pub ki_estcpu: ::u_int, ++ /// Time since last blocked. ++ pub ki_slptime: ::u_int, ++ /// Time swapped in or out. ++ pub ki_swtime: ::u_int, ++ /// Number of copy-on-write faults. ++ pub ki_cow: ::u_int, ++ /// Real time in microsec. ++ pub ki_runtime: u64, ++ /// Starting time. ++ pub ki_start: ::timeval, ++ /// Time used by process children. ++ pub ki_childtime: ::timeval, ++ /// P_* flags. ++ pub ki_flag: ::c_long, ++ /// KI_* flags (below). ++ pub ki_kiflag: ::c_long, ++ /// Kernel trace points. ++ pub ki_traceflag: ::c_int, ++ /// S* process status. ++ pub ki_stat: ::c_char, ++ /// Process "nice" value. ++ pub ki_nice: i8, // signed char ++ /// Process lock (prevent swap) count. ++ pub ki_lock: ::c_char, ++ /// Run queue index. ++ pub ki_rqindex: ::c_char, ++ /// Which cpu we are on. ++ pub ki_oncpu_old: ::c_uchar, ++ /// Last cpu we were on. ++ pub ki_lastcpu_old: ::c_uchar, ++ /// Thread name. ++ pub ki_tdname: [::c_char; ::TDNAMLEN + 1], ++ /// Wchan message. ++ pub ki_wmesg: [::c_char; ::WMESGLEN + 1], ++ /// Setlogin name. ++ pub ki_login: [::c_char; ::LOGNAMELEN + 1], ++ /// Lock name. ++ pub ki_lockname: [::c_char; ::LOCKNAMELEN + 1], ++ /// Command name. ++ pub ki_comm: [::c_char; ::COMMLEN + 1], ++ /// Emulation name. ++ pub ki_emul: [::c_char; ::KI_EMULNAMELEN + 1], ++ /// Login class. ++ pub ki_loginclass: [::c_char; ::LOGINCLASSLEN + 1], ++ /// More thread name. ++ pub ki_moretdname: [::c_char; ::MAXCOMLEN - ::TDNAMLEN + 1], ++ /// Spare string space. ++ pub ki_sparestrings: [[::c_char; 23]; 2], // little hack to allow PartialEq ++ /// Spare room for growth. ++ pub ki_spareints: [::c_int; ::KI_NSPARE_INT], ++ /// Which cpu we are on. ++ pub ki_oncpu: ::c_int, ++ /// Last cpu we were on. ++ pub ki_lastcpu: ::c_int, ++ /// PID of tracing process. ++ pub ki_tracer: ::c_int, ++ /// P2_* flags. ++ pub ki_flag2: ::c_int, ++ /// Default FIB number. ++ pub ki_fibnum: ::c_int, ++ /// Credential flags. ++ pub ki_cr_flags: ::u_int, ++ /// Process jail ID. ++ pub ki_jid: ::c_int, ++ /// Number of threads in total. ++ pub ki_numthreads: ::c_int, ++ /// Thread ID. ++ pub ki_tid: ::lwpid_t, ++ /// Process priority. ++ pub ki_pri: ::priority, ++ /// Process rusage statistics. ++ pub ki_rusage: ::rusage, ++ /// rusage of children processes. ++ pub ki_rusage_ch: ::rusage, ++ // This is normally "struct pcb". ++ /// Kernel virtual addr of pcb. ++ pub ki_pcb: *mut ::c_void, ++ /// Kernel virtual addr of stack. ++ pub ki_kstack: *mut ::c_void, ++ /// User convenience pointer. ++ pub ki_udata: *mut ::c_void, ++ // This is normally "struct thread". ++ pub ki_tdaddr: *mut ::c_void, ++ pub ki_spareptrs: [*mut ::c_void; ::KI_NSPARE_PTR], ++ pub ki_sparelongs: [::c_long; ::KI_NSPARE_LONG], ++ /// PS_* flags. ++ pub ki_sflag: ::c_long, ++ /// kthread flag. ++ pub ki_tdflags: ::c_long, ++ } + } + + s_no_extra_traits! { +@@ -67,6 +247,17 @@ s_no_extra_traits! { + // Array length changed from 88 to 1024 in FreeBSD 12: + pub f_mntonname: [::c_char; 88], + } ++ ++ pub struct vnstat { ++ pub vn_fileid: u64, ++ pub vn_size: u64, ++ pub vn_mntdir: *mut ::c_char, ++ pub vn_dev: u32, ++ pub vn_fsid: u32, ++ pub vn_type: ::c_int, ++ pub vn_mode: u16, ++ pub vn_devname: [::c_char; ::SPECNAMELEN as usize + 1], ++ } + } + + cfg_if! { +@@ -186,11 +377,70 @@ cfg_if! { + self.d_name[..self.d_namlen as _].hash(state); + } + } ++ ++ impl PartialEq for vnstat { ++ fn eq(&self, other: &vnstat) -> bool { ++ let self_vn_devname: &[::c_char] = &self.vn_devname; ++ let other_vn_devname: &[::c_char] = &other.vn_devname; ++ ++ self.vn_fileid == other.vn_fileid && ++ self.vn_size == other.vn_size && ++ self.vn_mntdir == other.vn_mntdir && ++ self.vn_dev == other.vn_dev && ++ self.vn_fsid == other.vn_fsid && ++ self.vn_type == other.vn_type && ++ self.vn_mode == other.vn_mode && ++ self_vn_devname == other_vn_devname ++ } ++ } ++ impl Eq for vnstat {} ++ impl ::fmt::Debug for vnstat { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let self_vn_devname: &[::c_char] = &self.vn_devname; ++ ++ f.debug_struct("vnstat") ++ .field("vn_fileid", &self.vn_fileid) ++ .field("vn_size", &self.vn_size) ++ .field("vn_mntdir", &self.vn_mntdir) ++ .field("vn_dev", &self.vn_dev) ++ .field("vn_fsid", &self.vn_fsid) ++ .field("vn_type", &self.vn_type) ++ .field("vn_mode", &self.vn_mode) ++ .field("vn_devname", &self_vn_devname) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for vnstat { ++ fn hash(&self, state: &mut H) { ++ let self_vn_devname: &[::c_char] = &self.vn_devname; ++ ++ self.vn_fileid.hash(state); ++ self.vn_size.hash(state); ++ self.vn_mntdir.hash(state); ++ self.vn_dev.hash(state); ++ self.vn_fsid.hash(state); ++ self.vn_type.hash(state); ++ self.vn_mode.hash(state); ++ self_vn_devname.hash(state); ++ } ++ } + } + } + + pub const ELAST: ::c_int = 96; + pub const RAND_MAX: ::c_int = 0x7fff_fffd; ++pub const KI_NSPARE_PTR: usize = 6; ++pub const MINCORE_SUPER: ::c_int = 0x20; ++/// max length of devicename ++pub const SPECNAMELEN: ::c_int = 63; ++ ++safe_f! { ++ pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { ++ let major = major as ::dev_t; ++ let minor = minor as ::dev_t; ++ (major << 8) | minor ++ } ++} + + extern "C" { + // Return type ::c_int was removed in FreeBSD 12 +@@ -212,12 +462,16 @@ extern "C" { + msgflg: ::c_int, + ) -> ::c_int; + +- pub fn fdatasync(fd: ::c_int) -> ::c_int; ++ // Type of `path` argument changed from `const void*` to `void*` ++ // in FreeBSD 12 ++ pub fn dirname(path: *const ::c_char) -> *mut ::c_char; ++ pub fn basename(path: *const ::c_char) -> *mut ::c_char; + } + + cfg_if! { + if #[cfg(any(target_arch = "x86_64", +- target_arch = "aarch64"))] { ++ target_arch = "aarch64", ++ target_arch = "riscv64"))] { + mod b64; + pub use self::b64::*; + } +diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs +index 2def900..5cd4eff 100644 +--- a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs ++++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs +@@ -22,10 +22,202 @@ s! { + pub filter: ::c_short, + pub flags: ::c_ushort, + pub fflags: ::c_uint, +- pub data: ::intptr_t, ++ pub data: i64, + pub udata: *mut ::c_void, + pub ext: [u64; 4], + } ++ ++ pub struct kvm_page { ++ pub version: ::c_uint, ++ pub paddr: ::c_ulong, ++ pub kmap_vaddr: ::c_ulong, ++ pub dmap_vaddr: ::c_ulong, ++ pub prot: ::vm_prot_t, ++ pub offset: ::u_long, ++ pub len: ::size_t, ++ } ++ ++ pub struct kinfo_proc { ++ /// Size of this structure. ++ pub ki_structsize: ::c_int, ++ /// Reserved: layout identifier. ++ pub ki_layout: ::c_int, ++ /// Address of command arguments. ++ pub ki_args: *mut ::pargs, ++ // This is normally "struct proc". ++ /// Address of proc. ++ pub ki_paddr: *mut ::c_void, ++ // This is normally "struct user". ++ /// Kernel virtual address of u-area. ++ pub ki_addr: *mut ::c_void, ++ // This is normally "struct vnode". ++ /// Pointer to trace file. ++ pub ki_tracep: *mut ::c_void, ++ // This is normally "struct vnode". ++ /// Pointer to executable file. ++ pub ki_textvp: *mut ::c_void, ++ // This is normally "struct filedesc". ++ /// Pointer to open file info. ++ pub ki_fd: *mut ::c_void, ++ // This is normally "struct vmspace". ++ /// Pointer to kernel vmspace struct. ++ pub ki_vmspace: *mut ::c_void, ++ /// Sleep address. ++ pub ki_wchan: *mut ::c_void, ++ /// Process identifier. ++ pub ki_pid: ::pid_t, ++ /// Parent process ID. ++ pub ki_ppid: ::pid_t, ++ /// Process group ID. ++ pub ki_pgid: ::pid_t, ++ /// tty process group ID. ++ pub ki_tpgid: ::pid_t, ++ /// Process session ID. ++ pub ki_sid: ::pid_t, ++ /// Terminal session ID. ++ pub ki_tsid: ::pid_t, ++ /// Job control counter. ++ pub ki_jobc: ::c_short, ++ /// Unused (just here for alignment). ++ pub ki_spare_short1: ::c_short, ++ /// Controlling tty dev. ++ pub ki_tdev_freebsd11: u32, ++ /// Signals arrived but not delivered. ++ pub ki_siglist: ::sigset_t, ++ /// Current signal mask. ++ pub ki_sigmask: ::sigset_t, ++ /// Signals being ignored. ++ pub ki_sigignore: ::sigset_t, ++ /// Signals being caught by user. ++ pub ki_sigcatch: ::sigset_t, ++ /// Effective user ID. ++ pub ki_uid: ::uid_t, ++ /// Real user ID. ++ pub ki_ruid: ::uid_t, ++ /// Saved effective user ID. ++ pub ki_svuid: ::uid_t, ++ /// Real group ID. ++ pub ki_rgid: ::gid_t, ++ /// Saved effective group ID. ++ pub ki_svgid: ::gid_t, ++ /// Number of groups. ++ pub ki_ngroups: ::c_short, ++ /// Unused (just here for alignment). ++ pub ki_spare_short2: ::c_short, ++ /// Groups. ++ pub ki_groups: [::gid_t; ::KI_NGROUPS], ++ /// Virtual size. ++ pub ki_size: ::vm_size_t, ++ /// Current resident set size in pages. ++ pub ki_rssize: ::segsz_t, ++ /// Resident set size before last swap. ++ pub ki_swrss: ::segsz_t, ++ /// Text size (pages) XXX. ++ pub ki_tsize: ::segsz_t, ++ /// Data size (pages) XXX. ++ pub ki_dsize: ::segsz_t, ++ /// Stack size (pages). ++ pub ki_ssize: ::segsz_t, ++ /// Exit status for wait & stop signal. ++ pub ki_xstat: ::u_short, ++ /// Accounting flags. ++ pub ki_acflag: ::u_short, ++ /// %cpu for process during `ki_swtime`. ++ pub ki_pctcpu: ::fixpt_t, ++ /// Time averaged value of `ki_cpticks`. ++ pub ki_estcpu: ::u_int, ++ /// Time since last blocked. ++ pub ki_slptime: ::u_int, ++ /// Time swapped in or out. ++ pub ki_swtime: ::u_int, ++ /// Number of copy-on-write faults. ++ pub ki_cow: ::u_int, ++ /// Real time in microsec. ++ pub ki_runtime: u64, ++ /// Starting time. ++ pub ki_start: ::timeval, ++ /// Time used by process children. ++ pub ki_childtime: ::timeval, ++ /// P_* flags. ++ pub ki_flag: ::c_long, ++ /// KI_* flags (below). ++ pub ki_kiflag: ::c_long, ++ /// Kernel trace points. ++ pub ki_traceflag: ::c_int, ++ /// S* process status. ++ pub ki_stat: ::c_char, ++ /// Process "nice" value. ++ pub ki_nice: i8, // signed char ++ /// Process lock (prevent swap) count. ++ pub ki_lock: ::c_char, ++ /// Run queue index. ++ pub ki_rqindex: ::c_char, ++ /// Which cpu we are on. ++ pub ki_oncpu_old: ::c_uchar, ++ /// Last cpu we were on. ++ pub ki_lastcpu_old: ::c_uchar, ++ /// Thread name. ++ pub ki_tdname: [::c_char; ::TDNAMLEN + 1], ++ /// Wchan message. ++ pub ki_wmesg: [::c_char; ::WMESGLEN + 1], ++ /// Setlogin name. ++ pub ki_login: [::c_char; ::LOGNAMELEN + 1], ++ /// Lock name. ++ pub ki_lockname: [::c_char; ::LOCKNAMELEN + 1], ++ /// Command name. ++ pub ki_comm: [::c_char; ::COMMLEN + 1], ++ /// Emulation name. ++ pub ki_emul: [::c_char; ::KI_EMULNAMELEN + 1], ++ /// Login class. ++ pub ki_loginclass: [::c_char; ::LOGINCLASSLEN + 1], ++ /// More thread name. ++ pub ki_moretdname: [::c_char; ::MAXCOMLEN - ::TDNAMLEN + 1], ++ /// Spare string space. ++ pub ki_sparestrings: [[::c_char; 23]; 2], // little hack to allow PartialEq ++ /// Spare room for growth. ++ pub ki_spareints: [::c_int; ::KI_NSPARE_INT], ++ /// Controlling tty dev. ++ pub ki_tdev: ::dev_t, ++ /// Which cpu we are on. ++ pub ki_oncpu: ::c_int, ++ /// Last cpu we were on. ++ pub ki_lastcpu: ::c_int, ++ /// PID of tracing process. ++ pub ki_tracer: ::c_int, ++ /// P2_* flags. ++ pub ki_flag2: ::c_int, ++ /// Default FIB number. ++ pub ki_fibnum: ::c_int, ++ /// Credential flags. ++ pub ki_cr_flags: ::u_int, ++ /// Process jail ID. ++ pub ki_jid: ::c_int, ++ /// Number of threads in total. ++ pub ki_numthreads: ::c_int, ++ /// Thread ID. ++ pub ki_tid: ::lwpid_t, ++ /// Process priority. ++ pub ki_pri: ::priority, ++ /// Process rusage statistics. ++ pub ki_rusage: ::rusage, ++ /// rusage of children processes. ++ pub ki_rusage_ch: ::rusage, ++ // This is normally "struct pcb". ++ /// Kernel virtual addr of pcb. ++ pub ki_pcb: *mut ::c_void, ++ /// Kernel virtual addr of stack. ++ pub ki_kstack: *mut ::c_void, ++ /// User convenience pointer. ++ pub ki_udata: *mut ::c_void, ++ // This is normally "struct thread". ++ pub ki_tdaddr: *mut ::c_void, ++ pub ki_spareptrs: [*mut ::c_void; ::KI_NSPARE_PTR], ++ pub ki_sparelongs: [::c_long; ::KI_NSPARE_LONG], ++ /// PS_* flags. ++ pub ki_sflag: ::c_long, ++ /// kthread flag. ++ pub ki_tdflags: ::c_long, ++ } + } + + s_no_extra_traits! { +@@ -64,6 +256,17 @@ s_no_extra_traits! { + pub f_mntfromname: [::c_char; 1024], + pub f_mntonname: [::c_char; 1024], + } ++ ++ pub struct vnstat { ++ pub vn_fileid: u64, ++ pub vn_size: u64, ++ pub vn_dev: u64, ++ pub vn_fsid: u64, ++ pub vn_mntdir: *mut ::c_char, ++ pub vn_type: ::c_int, ++ pub vn_mode: u16, ++ pub vn_devname: [::c_char; ::SPECNAMELEN as usize + 1], ++ } + } + + cfg_if! { +@@ -187,24 +390,77 @@ cfg_if! { + self.d_name[..self.d_namlen as _].hash(state); + } + } +- } +-} + +-pub const F_ADD_SEALS: ::c_int = 19; +-pub const F_GET_SEALS: ::c_int = 20; +-pub const F_SEAL_SEAL: ::c_int = 0x0001; +-pub const F_SEAL_SHRINK: ::c_int = 0x0002; +-pub const F_SEAL_GROW: ::c_int = 0x0004; +-pub const F_SEAL_WRITE: ::c_int = 0x0008; ++ impl PartialEq for vnstat { ++ fn eq(&self, other: &vnstat) -> bool { ++ let self_vn_devname: &[::c_char] = &self.vn_devname; ++ let other_vn_devname: &[::c_char] = &other.vn_devname; + +-pub const GRND_NONBLOCK: ::c_uint = 0x1; +-pub const GRND_RANDOM: ::c_uint = 0x2; ++ self.vn_fileid == other.vn_fileid && ++ self.vn_size == other.vn_size && ++ self.vn_dev == other.vn_dev && ++ self.vn_fsid == other.vn_fsid && ++ self.vn_mntdir == other.vn_mntdir && ++ self.vn_type == other.vn_type && ++ self.vn_mode == other.vn_mode && ++ self_vn_devname == other_vn_devname ++ } ++ } ++ impl Eq for vnstat {} ++ impl ::fmt::Debug for vnstat { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let self_vn_devname: &[::c_char] = &self.vn_devname; ++ ++ f.debug_struct("vnstat") ++ .field("vn_fileid", &self.vn_fileid) ++ .field("vn_size", &self.vn_size) ++ .field("vn_dev", &self.vn_dev) ++ .field("vn_fsid", &self.vn_fsid) ++ .field("vn_mntdir", &self.vn_mntdir) ++ .field("vn_type", &self.vn_type) ++ .field("vn_mode", &self.vn_mode) ++ .field("vn_devname", &self_vn_devname) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for vnstat { ++ fn hash(&self, state: &mut H) { ++ let self_vn_devname: &[::c_char] = &self.vn_devname; ++ ++ self.vn_fileid.hash(state); ++ self.vn_size.hash(state); ++ self.vn_dev.hash(state); ++ self.vn_fsid.hash(state); ++ self.vn_mntdir.hash(state); ++ self.vn_type.hash(state); ++ self.vn_mode.hash(state); ++ self_vn_devname.hash(state); ++ } ++ } ++ } ++} + + pub const RAND_MAX: ::c_int = 0x7fff_fffd; ++pub const ELAST: ::c_int = 97; ++ ++/// max length of devicename ++pub const SPECNAMELEN: ::c_int = 63; ++pub const KI_NSPARE_PTR: usize = 6; + +-pub const SO_DOMAIN: ::c_int = 0x1019; ++pub const MINCORE_SUPER: ::c_int = 0x20; + +-pub const ELAST: ::c_int = 96; ++safe_f! { ++ pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { ++ let major = major as ::dev_t; ++ let minor = minor as ::dev_t; ++ let mut dev = 0; ++ dev |= ((major & 0xffffff00) as dev_t) << 32; ++ dev |= ((major & 0x000000ff) as dev_t) << 8; ++ dev |= ((minor & 0x0000ff00) as dev_t) << 24; ++ dev |= ((minor & 0xffff00ff) as dev_t) << 0; ++ dev ++ } ++} + + extern "C" { + pub fn setgrent(); +@@ -217,26 +473,23 @@ extern "C" { + msgtyp: ::c_long, + msgflg: ::c_int, + ) -> ::ssize_t; +- pub fn clock_nanosleep( +- clk_id: ::clockid_t, +- flags: ::c_int, +- rqtp: *const ::timespec, +- rmtp: *mut ::timespec, +- ) -> ::c_int; +- +- pub fn fdatasync(fd: ::c_int) -> ::c_int; +- +- pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; +- pub fn elf_aux_info(aux: ::c_int, buf: *mut ::c_void, buflen: ::c_int) -> ::c_int; +- pub fn setproctitle_fast(fmt: *const ::c_char, ...); +- pub fn timingsafe_bcmp(a: *const ::c_void, b: *const ::c_void, len: ::size_t) -> ::c_int; +- pub fn timingsafe_memcmp(a: *const ::c_void, b: *const ::c_void, len: ::size_t) -> ::c_int; ++ ++ pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; ++ pub fn basename(path: *mut ::c_char) -> *mut ::c_char; + } + + cfg_if! { + if #[cfg(any(target_arch = "x86_64", +- target_arch = "aarch64"))] { ++ target_arch = "aarch64", ++ target_arch = "riscv64"))] { + mod b64; + pub use self::b64::*; + } + } ++ ++cfg_if! { ++ if #[cfg(target_arch = "x86_64")] { ++ mod x86_64; ++ pub use self::x86_64::*; ++ } ++} +diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs +new file mode 100644 +index 0000000..7bf2534 +--- /dev/null ++++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs +@@ -0,0 +1,5 @@ ++pub const PROC_KPTI_CTL: ::c_int = ::PROC_PROCCTL_MD_MIN; ++pub const PROC_KPTI_CTL_ENABLE_ON_EXEC: ::c_int = 1; ++pub const PROC_KPTI_CTL_DISABLE_ON_EXEC: ::c_int = 2; ++pub const PROC_KPTI_STATUS: ::c_int = ::PROC_PROCCTL_MD_MIN + 1; ++pub const PROC_KPTI_STATUS_ACTIVE: ::c_int = 0x80000000; +diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs +index b150e04..56564ee 100644 +--- a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs ++++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs +@@ -1,9 +1,12 @@ +-// APIs in FreeBSD 13 that have changed since 11. ++// APIs in FreeBSD 14 that have changed since 11. + + pub type nlink_t = u64; + pub type dev_t = u64; + pub type ino_t = ::c_ulong; + pub type shmatt_t = ::c_uint; ++pub type kpaddr_t = u64; ++pub type kssize_t = i64; ++pub type domainset_t = __c_anonymous_domainset; + + s! { + pub struct shmid_ds { +@@ -22,10 +25,209 @@ s! { + pub filter: ::c_short, + pub flags: ::c_ushort, + pub fflags: ::c_uint, +- pub data: ::intptr_t, ++ pub data: i64, + pub udata: *mut ::c_void, + pub ext: [u64; 4], + } ++ ++ pub struct kvm_page { ++ pub kp_version: ::u_int, ++ pub kp_paddr: ::kpaddr_t, ++ pub kp_kmap_vaddr: ::kvaddr_t, ++ pub kp_dmap_vaddr: ::kvaddr_t, ++ pub kp_prot: ::vm_prot_t, ++ pub kp_offset: ::off_t, ++ pub kp_len: ::size_t, ++ } ++ ++ pub struct __c_anonymous_domainset { ++ _priv: [::uintptr_t; 4], ++ } ++ ++ pub struct kinfo_proc { ++ /// Size of this structure. ++ pub ki_structsize: ::c_int, ++ /// Reserved: layout identifier. ++ pub ki_layout: ::c_int, ++ /// Address of command arguments. ++ pub ki_args: *mut ::pargs, ++ // This is normally "struct proc". ++ /// Address of proc. ++ pub ki_paddr: *mut ::c_void, ++ // This is normally "struct user". ++ /// Kernel virtual address of u-area. ++ pub ki_addr: *mut ::c_void, ++ // This is normally "struct vnode". ++ /// Pointer to trace file. ++ pub ki_tracep: *mut ::c_void, ++ // This is normally "struct vnode". ++ /// Pointer to executable file. ++ pub ki_textvp: *mut ::c_void, ++ // This is normally "struct filedesc". ++ /// Pointer to open file info. ++ pub ki_fd: *mut ::c_void, ++ // This is normally "struct vmspace". ++ /// Pointer to kernel vmspace struct. ++ pub ki_vmspace: *mut ::c_void, ++ /// Sleep address. ++ pub ki_wchan: *const ::c_void, ++ /// Process identifier. ++ pub ki_pid: ::pid_t, ++ /// Parent process ID. ++ pub ki_ppid: ::pid_t, ++ /// Process group ID. ++ pub ki_pgid: ::pid_t, ++ /// tty process group ID. ++ pub ki_tpgid: ::pid_t, ++ /// Process session ID. ++ pub ki_sid: ::pid_t, ++ /// Terminal session ID. ++ pub ki_tsid: ::pid_t, ++ /// Job control counter. ++ pub ki_jobc: ::c_short, ++ /// Unused (just here for alignment). ++ pub ki_spare_short1: ::c_short, ++ /// Controlling tty dev. ++ pub ki_tdev_freebsd11: u32, ++ /// Signals arrived but not delivered. ++ pub ki_siglist: ::sigset_t, ++ /// Current signal mask. ++ pub ki_sigmask: ::sigset_t, ++ /// Signals being ignored. ++ pub ki_sigignore: ::sigset_t, ++ /// Signals being caught by user. ++ pub ki_sigcatch: ::sigset_t, ++ /// Effective user ID. ++ pub ki_uid: ::uid_t, ++ /// Real user ID. ++ pub ki_ruid: ::uid_t, ++ /// Saved effective user ID. ++ pub ki_svuid: ::uid_t, ++ /// Real group ID. ++ pub ki_rgid: ::gid_t, ++ /// Saved effective group ID. ++ pub ki_svgid: ::gid_t, ++ /// Number of groups. ++ pub ki_ngroups: ::c_short, ++ /// Unused (just here for alignment). ++ pub ki_spare_short2: ::c_short, ++ /// Groups. ++ pub ki_groups: [::gid_t; ::KI_NGROUPS], ++ /// Virtual size. ++ pub ki_size: ::vm_size_t, ++ /// Current resident set size in pages. ++ pub ki_rssize: ::segsz_t, ++ /// Resident set size before last swap. ++ pub ki_swrss: ::segsz_t, ++ /// Text size (pages) XXX. ++ pub ki_tsize: ::segsz_t, ++ /// Data size (pages) XXX. ++ pub ki_dsize: ::segsz_t, ++ /// Stack size (pages). ++ pub ki_ssize: ::segsz_t, ++ /// Exit status for wait & stop signal. ++ pub ki_xstat: ::u_short, ++ /// Accounting flags. ++ pub ki_acflag: ::u_short, ++ /// %cpu for process during `ki_swtime`. ++ pub ki_pctcpu: ::fixpt_t, ++ /// Time averaged value of `ki_cpticks`. ++ pub ki_estcpu: ::u_int, ++ /// Time since last blocked. ++ pub ki_slptime: ::u_int, ++ /// Time swapped in or out. ++ pub ki_swtime: ::u_int, ++ /// Number of copy-on-write faults. ++ pub ki_cow: ::u_int, ++ /// Real time in microsec. ++ pub ki_runtime: u64, ++ /// Starting time. ++ pub ki_start: ::timeval, ++ /// Time used by process children. ++ pub ki_childtime: ::timeval, ++ /// P_* flags. ++ pub ki_flag: ::c_long, ++ /// KI_* flags (below). ++ pub ki_kiflag: ::c_long, ++ /// Kernel trace points. ++ pub ki_traceflag: ::c_int, ++ /// S* process status. ++ pub ki_stat: ::c_char, ++ /// Process "nice" value. ++ pub ki_nice: i8, // signed char ++ /// Process lock (prevent swap) count. ++ pub ki_lock: ::c_char, ++ /// Run queue index. ++ pub ki_rqindex: ::c_char, ++ /// Which cpu we are on. ++ pub ki_oncpu_old: ::c_uchar, ++ /// Last cpu we were on. ++ pub ki_lastcpu_old: ::c_uchar, ++ /// Thread name. ++ pub ki_tdname: [::c_char; ::TDNAMLEN + 1], ++ /// Wchan message. ++ pub ki_wmesg: [::c_char; ::WMESGLEN + 1], ++ /// Setlogin name. ++ pub ki_login: [::c_char; ::LOGNAMELEN + 1], ++ /// Lock name. ++ pub ki_lockname: [::c_char; ::LOCKNAMELEN + 1], ++ /// Command name. ++ pub ki_comm: [::c_char; ::COMMLEN + 1], ++ /// Emulation name. ++ pub ki_emul: [::c_char; ::KI_EMULNAMELEN + 1], ++ /// Login class. ++ pub ki_loginclass: [::c_char; ::LOGINCLASSLEN + 1], ++ /// More thread name. ++ pub ki_moretdname: [::c_char; ::MAXCOMLEN - ::TDNAMLEN + 1], ++ /// Spare string space. ++ pub ki_sparestrings: [[::c_char; 23]; 2], // little hack to allow PartialEq ++ /// Spare room for growth. ++ pub ki_spareints: [::c_int; ::KI_NSPARE_INT], ++ /// Controlling tty dev. ++ pub ki_tdev: u64, ++ /// Which cpu we are on. ++ pub ki_oncpu: ::c_int, ++ /// Last cpu we were on. ++ pub ki_lastcpu: ::c_int, ++ /// PID of tracing process. ++ pub ki_tracer: ::c_int, ++ /// P2_* flags. ++ pub ki_flag2: ::c_int, ++ /// Default FIB number. ++ pub ki_fibnum: ::c_int, ++ /// Credential flags. ++ pub ki_cr_flags: ::u_int, ++ /// Process jail ID. ++ pub ki_jid: ::c_int, ++ /// Number of threads in total. ++ pub ki_numthreads: ::c_int, ++ /// Thread ID. ++ pub ki_tid: ::lwpid_t, ++ /// Process priority. ++ pub ki_pri: ::priority, ++ /// Process rusage statistics. ++ pub ki_rusage: ::rusage, ++ /// rusage of children processes. ++ pub ki_rusage_ch: ::rusage, ++ // This is normally "struct pcb". ++ /// Kernel virtual addr of pcb. ++ pub ki_pcb: *mut ::c_void, ++ /// Kernel virtual addr of stack. ++ pub ki_kstack: *mut ::c_void, ++ /// User convenience pointer. ++ pub ki_udata: *mut ::c_void, ++ // This is normally "struct thread". ++ pub ki_tdaddr: *mut ::c_void, ++ // This is normally "struct pwddesc". ++ /// Pointer to process paths info. ++ pub ki_pd: *mut ::c_void, ++ pub ki_spareptrs: [*mut ::c_void; ::KI_NSPARE_PTR], ++ pub ki_sparelongs: [::c_long; ::KI_NSPARE_LONG], ++ /// PS_* flags. ++ pub ki_sflag: ::c_long, ++ /// kthread flag. ++ pub ki_tdflags: ::c_long, ++ } + } + + s_no_extra_traits! { +@@ -64,6 +266,17 @@ s_no_extra_traits! { + pub f_mntfromname: [::c_char; 1024], + pub f_mntonname: [::c_char; 1024], + } ++ ++ pub struct vnstat { ++ pub vn_fileid: u64, ++ pub vn_size: u64, ++ pub vn_dev: u64, ++ pub vn_fsid: u64, ++ pub vn_mntdir: *mut ::c_char, ++ pub vn_type: ::c_int, ++ pub vn_mode: u16, ++ pub vn_devname: [::c_char; ::SPECNAMELEN as usize + 1], ++ } + } + + cfg_if! { +@@ -187,30 +400,88 @@ cfg_if! { + self.d_name[..self.d_namlen as _].hash(state); + } + } ++ ++ impl PartialEq for vnstat { ++ fn eq(&self, other: &vnstat) -> bool { ++ let self_vn_devname: &[::c_char] = &self.vn_devname; ++ let other_vn_devname: &[::c_char] = &other.vn_devname; ++ ++ self.vn_fileid == other.vn_fileid && ++ self.vn_size == other.vn_size && ++ self.vn_dev == other.vn_dev && ++ self.vn_fsid == other.vn_fsid && ++ self.vn_mntdir == other.vn_mntdir && ++ self.vn_type == other.vn_type && ++ self.vn_mode == other.vn_mode && ++ self_vn_devname == other_vn_devname ++ } ++ } ++ impl Eq for vnstat {} ++ impl ::fmt::Debug for vnstat { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let self_vn_devname: &[::c_char] = &self.vn_devname; ++ ++ f.debug_struct("vnstat") ++ .field("vn_fileid", &self.vn_fileid) ++ .field("vn_size", &self.vn_size) ++ .field("vn_dev", &self.vn_dev) ++ .field("vn_fsid", &self.vn_fsid) ++ .field("vn_mntdir", &self.vn_mntdir) ++ .field("vn_type", &self.vn_type) ++ .field("vn_mode", &self.vn_mode) ++ .field("vn_devname", &self_vn_devname) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for vnstat { ++ fn hash(&self, state: &mut H) { ++ let self_vn_devname: &[::c_char] = &self.vn_devname; ++ ++ self.vn_fileid.hash(state); ++ self.vn_size.hash(state); ++ self.vn_dev.hash(state); ++ self.vn_fsid.hash(state); ++ self.vn_mntdir.hash(state); ++ self.vn_type.hash(state); ++ self.vn_mode.hash(state); ++ self_vn_devname.hash(state); ++ } ++ } + } + } + +-pub const F_ADD_SEALS: ::c_int = 19; +-pub const F_GET_SEALS: ::c_int = 20; +-pub const F_SEAL_SEAL: ::c_int = 0x0001; +-pub const F_SEAL_SHRINK: ::c_int = 0x0002; +-pub const F_SEAL_GROW: ::c_int = 0x0004; +-pub const F_SEAL_WRITE: ::c_int = 0x0008; ++pub const RAND_MAX: ::c_int = 0x7fff_ffff; ++pub const ELAST: ::c_int = 97; + +-pub const GRND_NONBLOCK: ::c_uint = 0x1; +-pub const GRND_RANDOM: ::c_uint = 0x2; ++pub const KF_TYPE_EVENTFD: ::c_int = 13; + +-pub const RAND_MAX: ::c_int = 0x7fff_ffff; ++/// max length of devicename ++pub const SPECNAMELEN: ::c_int = 255; ++pub const KI_NSPARE_PTR: usize = 5; + +-pub const SO_DOMAIN: ::c_int = 0x1019; ++/// domainset policies ++pub const DOMAINSET_POLICY_INVALID: ::c_int = 0; ++pub const DOMAINSET_POLICY_ROUNDROBIN: ::c_int = 1; ++pub const DOMAINSET_POLICY_FIRSTTOUCH: ::c_int = 2; ++pub const DOMAINSET_POLICY_PREFER: ::c_int = 3; ++pub const DOMAINSET_POLICY_INTERLEAVE: ::c_int = 4; + +-pub const EINTEGRITY: ::c_int = 97; +-pub const ELAST: ::c_int = 97; +-pub const GRND_INSECURE: ::c_uint = 0x4; ++pub const MINCORE_SUPER: ::c_int = 0x20; ++ ++safe_f! { ++ pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { ++ let major = major as ::dev_t; ++ let minor = minor as ::dev_t; ++ let mut dev = 0; ++ dev |= ((major & 0xffffff00) as dev_t) << 32; ++ dev |= ((major & 0x000000ff) as dev_t) << 8; ++ dev |= ((minor & 0x0000ff00) as dev_t) << 24; ++ dev |= ((minor & 0xffff00ff) as dev_t) << 0; ++ dev ++ } ++} + + extern "C" { +- pub fn aio_readv(aiocbp: *mut ::aiocb) -> ::c_int; +- pub fn aio_writev(aiocbp: *mut ::aiocb) -> ::c_int; + pub fn setgrent(); + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn freelocale(loc: ::locale_t); +@@ -221,27 +492,45 @@ extern "C" { + msgtyp: ::c_long, + msgflg: ::c_int, + ) -> ::ssize_t; +- pub fn clock_nanosleep( +- clk_id: ::clockid_t, +- flags: ::c_int, +- rqtp: *const ::timespec, +- rmtp: *mut ::timespec, ++ ++ pub fn cpuset_getdomain( ++ level: ::cpulevel_t, ++ which: ::cpuwhich_t, ++ id: ::id_t, ++ setsize: ::size_t, ++ mask: *mut ::domainset_t, ++ policy: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn cpuset_setdomain( ++ level: ::cpulevel_t, ++ which: ::cpuwhich_t, ++ id: ::id_t, ++ setsize: ::size_t, ++ mask: *const ::domainset_t, ++ policy: ::c_int, + ) -> ::c_int; + +- pub fn fdatasync(fd: ::c_int) -> ::c_int; ++ pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; ++ pub fn basename(path: *mut ::c_char) -> *mut ::c_char; ++} + +- pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; +- pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; +- pub fn elf_aux_info(aux: ::c_int, buf: *mut ::c_void, buflen: ::c_int) -> ::c_int; +- pub fn setproctitle_fast(fmt: *const ::c_char, ...); +- pub fn timingsafe_bcmp(a: *const ::c_void, b: *const ::c_void, len: ::size_t) -> ::c_int; +- pub fn timingsafe_memcmp(a: *const ::c_void, b: *const ::c_void, len: ::size_t) -> ::c_int; ++#[link(name = "kvm")] ++extern "C" { ++ pub fn kvm_kerndisp(kd: *mut ::kvm_t) -> ::kssize_t; + } + + cfg_if! { + if #[cfg(any(target_arch = "x86_64", +- target_arch = "aarch64"))] { ++ target_arch = "aarch64", ++ target_arch = "riscv64"))] { + mod b64; + pub use self::b64::*; + } + } ++ ++cfg_if! { ++ if #[cfg(target_arch = "x86_64")] { ++ mod x86_64; ++ pub use self::x86_64::*; ++ } ++} +diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs +new file mode 100644 +index 0000000..7bf2534 +--- /dev/null ++++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs +@@ -0,0 +1,5 @@ ++pub const PROC_KPTI_CTL: ::c_int = ::PROC_PROCCTL_MD_MIN; ++pub const PROC_KPTI_CTL_ENABLE_ON_EXEC: ::c_int = 1; ++pub const PROC_KPTI_CTL_DISABLE_ON_EXEC: ::c_int = 2; ++pub const PROC_KPTI_STATUS: ::c_int = ::PROC_PROCCTL_MD_MIN + 1; ++pub const PROC_KPTI_STATUS_ACTIVE: ::c_int = 0x80000000; +diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs +new file mode 100644 +index 0000000..80c6fa1 +--- /dev/null ++++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/b64.rs +@@ -0,0 +1,34 @@ ++#[repr(C)] ++#[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))] ++pub struct stat { ++ pub st_dev: ::dev_t, ++ pub st_ino: ::ino_t, ++ pub st_nlink: ::nlink_t, ++ pub st_mode: ::mode_t, ++ st_padding0: i16, ++ pub st_uid: ::uid_t, ++ pub st_gid: ::gid_t, ++ st_padding1: i32, ++ pub st_rdev: ::dev_t, ++ pub st_atime: ::time_t, ++ pub st_atime_nsec: ::c_long, ++ pub st_mtime: ::time_t, ++ pub st_mtime_nsec: ::c_long, ++ pub st_ctime: ::time_t, ++ pub st_ctime_nsec: ::c_long, ++ pub st_birthtime: ::time_t, ++ pub st_birthtime_nsec: ::c_long, ++ pub st_size: ::off_t, ++ pub st_blocks: ::blkcnt_t, ++ pub st_blksize: ::blksize_t, ++ pub st_flags: ::fflags_t, ++ pub st_gen: u64, ++ pub st_spare: [u64; 10], ++} ++ ++impl ::Copy for ::stat {} ++impl ::Clone for ::stat { ++ fn clone(&self) -> ::stat { ++ *self ++ } ++} +diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs +new file mode 100644 +index 0000000..d60f1a1 +--- /dev/null ++++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs +@@ -0,0 +1,536 @@ ++// APIs in FreeBSD 13 that have changed since 11. ++ ++pub type nlink_t = u64; ++pub type dev_t = u64; ++pub type ino_t = ::c_ulong; ++pub type shmatt_t = ::c_uint; ++pub type kpaddr_t = u64; ++pub type kssize_t = i64; ++pub type domainset_t = __c_anonymous_domainset; ++ ++s! { ++ pub struct shmid_ds { ++ pub shm_perm: ::ipc_perm, ++ pub shm_segsz: ::size_t, ++ pub shm_lpid: ::pid_t, ++ pub shm_cpid: ::pid_t, ++ pub shm_nattch: ::shmatt_t, ++ pub shm_atime: ::time_t, ++ pub shm_dtime: ::time_t, ++ pub shm_ctime: ::time_t, ++ } ++ ++ pub struct kevent { ++ pub ident: ::uintptr_t, ++ pub filter: ::c_short, ++ pub flags: ::c_ushort, ++ pub fflags: ::c_uint, ++ pub data: i64, ++ pub udata: *mut ::c_void, ++ pub ext: [u64; 4], ++ } ++ ++ pub struct kvm_page { ++ pub kp_version: ::u_int, ++ pub kp_paddr: ::kpaddr_t, ++ pub kp_kmap_vaddr: ::kvaddr_t, ++ pub kp_dmap_vaddr: ::kvaddr_t, ++ pub kp_prot: ::vm_prot_t, ++ pub kp_offset: ::off_t, ++ pub kp_len: ::size_t, ++ } ++ ++ pub struct __c_anonymous_domainset { ++ _priv: [::uintptr_t; 4], ++ } ++ ++ pub struct kinfo_proc { ++ /// Size of this structure. ++ pub ki_structsize: ::c_int, ++ /// Reserved: layout identifier. ++ pub ki_layout: ::c_int, ++ /// Address of command arguments. ++ pub ki_args: *mut ::pargs, ++ // This is normally "struct proc". ++ /// Address of proc. ++ pub ki_paddr: *mut ::c_void, ++ // This is normally "struct user". ++ /// Kernel virtual address of u-area. ++ pub ki_addr: *mut ::c_void, ++ // This is normally "struct vnode". ++ /// Pointer to trace file. ++ pub ki_tracep: *mut ::c_void, ++ // This is normally "struct vnode". ++ /// Pointer to executable file. ++ pub ki_textvp: *mut ::c_void, ++ // This is normally "struct filedesc". ++ /// Pointer to open file info. ++ pub ki_fd: *mut ::c_void, ++ // This is normally "struct vmspace". ++ /// Pointer to kernel vmspace struct. ++ pub ki_vmspace: *mut ::c_void, ++ /// Sleep address. ++ pub ki_wchan: *const ::c_void, ++ /// Process identifier. ++ pub ki_pid: ::pid_t, ++ /// Parent process ID. ++ pub ki_ppid: ::pid_t, ++ /// Process group ID. ++ pub ki_pgid: ::pid_t, ++ /// tty process group ID. ++ pub ki_tpgid: ::pid_t, ++ /// Process session ID. ++ pub ki_sid: ::pid_t, ++ /// Terminal session ID. ++ pub ki_tsid: ::pid_t, ++ /// Job control counter. ++ pub ki_jobc: ::c_short, ++ /// Unused (just here for alignment). ++ pub ki_spare_short1: ::c_short, ++ /// Controlling tty dev. ++ pub ki_tdev_freebsd11: u32, ++ /// Signals arrived but not delivered. ++ pub ki_siglist: ::sigset_t, ++ /// Current signal mask. ++ pub ki_sigmask: ::sigset_t, ++ /// Signals being ignored. ++ pub ki_sigignore: ::sigset_t, ++ /// Signals being caught by user. ++ pub ki_sigcatch: ::sigset_t, ++ /// Effective user ID. ++ pub ki_uid: ::uid_t, ++ /// Real user ID. ++ pub ki_ruid: ::uid_t, ++ /// Saved effective user ID. ++ pub ki_svuid: ::uid_t, ++ /// Real group ID. ++ pub ki_rgid: ::gid_t, ++ /// Saved effective group ID. ++ pub ki_svgid: ::gid_t, ++ /// Number of groups. ++ pub ki_ngroups: ::c_short, ++ /// Unused (just here for alignment). ++ pub ki_spare_short2: ::c_short, ++ /// Groups. ++ pub ki_groups: [::gid_t; ::KI_NGROUPS], ++ /// Virtual size. ++ pub ki_size: ::vm_size_t, ++ /// Current resident set size in pages. ++ pub ki_rssize: ::segsz_t, ++ /// Resident set size before last swap. ++ pub ki_swrss: ::segsz_t, ++ /// Text size (pages) XXX. ++ pub ki_tsize: ::segsz_t, ++ /// Data size (pages) XXX. ++ pub ki_dsize: ::segsz_t, ++ /// Stack size (pages). ++ pub ki_ssize: ::segsz_t, ++ /// Exit status for wait & stop signal. ++ pub ki_xstat: ::u_short, ++ /// Accounting flags. ++ pub ki_acflag: ::u_short, ++ /// %cpu for process during `ki_swtime`. ++ pub ki_pctcpu: ::fixpt_t, ++ /// Time averaged value of `ki_cpticks`. ++ pub ki_estcpu: ::u_int, ++ /// Time since last blocked. ++ pub ki_slptime: ::u_int, ++ /// Time swapped in or out. ++ pub ki_swtime: ::u_int, ++ /// Number of copy-on-write faults. ++ pub ki_cow: ::u_int, ++ /// Real time in microsec. ++ pub ki_runtime: u64, ++ /// Starting time. ++ pub ki_start: ::timeval, ++ /// Time used by process children. ++ pub ki_childtime: ::timeval, ++ /// P_* flags. ++ pub ki_flag: ::c_long, ++ /// KI_* flags (below). ++ pub ki_kiflag: ::c_long, ++ /// Kernel trace points. ++ pub ki_traceflag: ::c_int, ++ /// S* process status. ++ pub ki_stat: ::c_char, ++ /// Process "nice" value. ++ pub ki_nice: i8, // signed char ++ /// Process lock (prevent swap) count. ++ pub ki_lock: ::c_char, ++ /// Run queue index. ++ pub ki_rqindex: ::c_char, ++ /// Which cpu we are on. ++ pub ki_oncpu_old: ::c_uchar, ++ /// Last cpu we were on. ++ pub ki_lastcpu_old: ::c_uchar, ++ /// Thread name. ++ pub ki_tdname: [::c_char; ::TDNAMLEN + 1], ++ /// Wchan message. ++ pub ki_wmesg: [::c_char; ::WMESGLEN + 1], ++ /// Setlogin name. ++ pub ki_login: [::c_char; ::LOGNAMELEN + 1], ++ /// Lock name. ++ pub ki_lockname: [::c_char; ::LOCKNAMELEN + 1], ++ /// Command name. ++ pub ki_comm: [::c_char; ::COMMLEN + 1], ++ /// Emulation name. ++ pub ki_emul: [::c_char; ::KI_EMULNAMELEN + 1], ++ /// Login class. ++ pub ki_loginclass: [::c_char; ::LOGINCLASSLEN + 1], ++ /// More thread name. ++ pub ki_moretdname: [::c_char; ::MAXCOMLEN - ::TDNAMLEN + 1], ++ /// Spare string space. ++ pub ki_sparestrings: [[::c_char; 23]; 2], // little hack to allow PartialEq ++ /// Spare room for growth. ++ pub ki_spareints: [::c_int; ::KI_NSPARE_INT], ++ /// Controlling tty dev. ++ pub ki_tdev: u64, ++ /// Which cpu we are on. ++ pub ki_oncpu: ::c_int, ++ /// Last cpu we were on. ++ pub ki_lastcpu: ::c_int, ++ /// PID of tracing process. ++ pub ki_tracer: ::c_int, ++ /// P2_* flags. ++ pub ki_flag2: ::c_int, ++ /// Default FIB number. ++ pub ki_fibnum: ::c_int, ++ /// Credential flags. ++ pub ki_cr_flags: ::u_int, ++ /// Process jail ID. ++ pub ki_jid: ::c_int, ++ /// Number of threads in total. ++ pub ki_numthreads: ::c_int, ++ /// Thread ID. ++ pub ki_tid: ::lwpid_t, ++ /// Process priority. ++ pub ki_pri: ::priority, ++ /// Process rusage statistics. ++ pub ki_rusage: ::rusage, ++ /// rusage of children processes. ++ pub ki_rusage_ch: ::rusage, ++ // This is normally "struct pcb". ++ /// Kernel virtual addr of pcb. ++ pub ki_pcb: *mut ::c_void, ++ /// Kernel virtual addr of stack. ++ pub ki_kstack: *mut ::c_void, ++ /// User convenience pointer. ++ pub ki_udata: *mut ::c_void, ++ // This is normally "struct thread". ++ pub ki_tdaddr: *mut ::c_void, ++ // This is normally "struct pwddesc". ++ /// Pointer to process paths info. ++ pub ki_pd: *mut ::c_void, ++ pub ki_spareptrs: [*mut ::c_void; ::KI_NSPARE_PTR], ++ pub ki_sparelongs: [::c_long; ::KI_NSPARE_LONG], ++ /// PS_* flags. ++ pub ki_sflag: ::c_long, ++ /// kthread flag. ++ pub ki_tdflags: ::c_long, ++ } ++} ++ ++s_no_extra_traits! { ++ pub struct dirent { ++ pub d_fileno: ::ino_t, ++ pub d_off: ::off_t, ++ pub d_reclen: u16, ++ pub d_type: u8, ++ d_pad0: u8, ++ pub d_namlen: u16, ++ d_pad1: u16, ++ pub d_name: [::c_char; 256], ++ } ++ ++ pub struct statfs { ++ pub f_version: u32, ++ pub f_type: u32, ++ pub f_flags: u64, ++ pub f_bsize: u64, ++ pub f_iosize: u64, ++ pub f_blocks: u64, ++ pub f_bfree: u64, ++ pub f_bavail: i64, ++ pub f_files: u64, ++ pub f_ffree: i64, ++ pub f_syncwrites: u64, ++ pub f_asyncwrites: u64, ++ pub f_syncreads: u64, ++ pub f_asyncreads: u64, ++ f_spare: [u64; 10], ++ pub f_namemax: u32, ++ pub f_owner: ::uid_t, ++ pub f_fsid: ::fsid_t, ++ f_charspare: [::c_char; 80], ++ pub f_fstypename: [::c_char; 16], ++ pub f_mntfromname: [::c_char; 1024], ++ pub f_mntonname: [::c_char; 1024], ++ } ++ ++ pub struct vnstat { ++ pub vn_fileid: u64, ++ pub vn_size: u64, ++ pub vn_dev: u64, ++ pub vn_fsid: u64, ++ pub vn_mntdir: *mut ::c_char, ++ pub vn_type: ::c_int, ++ pub vn_mode: u16, ++ pub vn_devname: [::c_char; ::SPECNAMELEN as usize + 1], ++ } ++} ++ ++cfg_if! { ++ if #[cfg(feature = "extra_traits")] { ++ impl PartialEq for statfs { ++ fn eq(&self, other: &statfs) -> bool { ++ self.f_version == other.f_version ++ && self.f_type == other.f_type ++ && self.f_flags == other.f_flags ++ && self.f_bsize == other.f_bsize ++ && self.f_iosize == other.f_iosize ++ && self.f_blocks == other.f_blocks ++ && self.f_bfree == other.f_bfree ++ && self.f_bavail == other.f_bavail ++ && self.f_files == other.f_files ++ && self.f_ffree == other.f_ffree ++ && self.f_syncwrites == other.f_syncwrites ++ && self.f_asyncwrites == other.f_asyncwrites ++ && self.f_syncreads == other.f_syncreads ++ && self.f_asyncreads == other.f_asyncreads ++ && self.f_namemax == other.f_namemax ++ && self.f_owner == other.f_owner ++ && self.f_fsid == other.f_fsid ++ && self.f_fstypename == other.f_fstypename ++ && self ++ .f_mntfromname ++ .iter() ++ .zip(other.f_mntfromname.iter()) ++ .all(|(a,b)| a == b) ++ && self ++ .f_mntonname ++ .iter() ++ .zip(other.f_mntonname.iter()) ++ .all(|(a,b)| a == b) ++ } ++ } ++ impl Eq for statfs {} ++ impl ::fmt::Debug for statfs { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("statfs") ++ .field("f_bsize", &self.f_bsize) ++ .field("f_iosize", &self.f_iosize) ++ .field("f_blocks", &self.f_blocks) ++ .field("f_bfree", &self.f_bfree) ++ .field("f_bavail", &self.f_bavail) ++ .field("f_files", &self.f_files) ++ .field("f_ffree", &self.f_ffree) ++ .field("f_syncwrites", &self.f_syncwrites) ++ .field("f_asyncwrites", &self.f_asyncwrites) ++ .field("f_syncreads", &self.f_syncreads) ++ .field("f_asyncreads", &self.f_asyncreads) ++ .field("f_namemax", &self.f_namemax) ++ .field("f_owner", &self.f_owner) ++ .field("f_fsid", &self.f_fsid) ++ .field("f_fstypename", &self.f_fstypename) ++ .field("f_mntfromname", &&self.f_mntfromname[..]) ++ .field("f_mntonname", &&self.f_mntonname[..]) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for statfs { ++ fn hash(&self, state: &mut H) { ++ self.f_version.hash(state); ++ self.f_type.hash(state); ++ self.f_flags.hash(state); ++ self.f_bsize.hash(state); ++ self.f_iosize.hash(state); ++ self.f_blocks.hash(state); ++ self.f_bfree.hash(state); ++ self.f_bavail.hash(state); ++ self.f_files.hash(state); ++ self.f_ffree.hash(state); ++ self.f_syncwrites.hash(state); ++ self.f_asyncwrites.hash(state); ++ self.f_syncreads.hash(state); ++ self.f_asyncreads.hash(state); ++ self.f_namemax.hash(state); ++ self.f_owner.hash(state); ++ self.f_fsid.hash(state); ++ self.f_charspare.hash(state); ++ self.f_fstypename.hash(state); ++ self.f_mntfromname.hash(state); ++ self.f_mntonname.hash(state); ++ } ++ } ++ ++ impl PartialEq for dirent { ++ fn eq(&self, other: &dirent) -> bool { ++ self.d_fileno == other.d_fileno ++ && self.d_off == other.d_off ++ && self.d_reclen == other.d_reclen ++ && self.d_type == other.d_type ++ && self.d_namlen == other.d_namlen ++ && self ++ .d_name[..self.d_namlen as _] ++ .iter() ++ .zip(other.d_name.iter()) ++ .all(|(a,b)| a == b) ++ } ++ } ++ impl Eq for dirent {} ++ impl ::fmt::Debug for dirent { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("dirent") ++ .field("d_fileno", &self.d_fileno) ++ .field("d_off", &self.d_off) ++ .field("d_reclen", &self.d_reclen) ++ .field("d_type", &self.d_type) ++ .field("d_namlen", &self.d_namlen) ++ .field("d_name", &&self.d_name[..self.d_namlen as _]) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for dirent { ++ fn hash(&self, state: &mut H) { ++ self.d_fileno.hash(state); ++ self.d_off.hash(state); ++ self.d_reclen.hash(state); ++ self.d_type.hash(state); ++ self.d_namlen.hash(state); ++ self.d_name[..self.d_namlen as _].hash(state); ++ } ++ } ++ ++ impl PartialEq for vnstat { ++ fn eq(&self, other: &vnstat) -> bool { ++ let self_vn_devname: &[::c_char] = &self.vn_devname; ++ let other_vn_devname: &[::c_char] = &other.vn_devname; ++ ++ self.vn_fileid == other.vn_fileid && ++ self.vn_size == other.vn_size && ++ self.vn_dev == other.vn_dev && ++ self.vn_fsid == other.vn_fsid && ++ self.vn_mntdir == other.vn_mntdir && ++ self.vn_type == other.vn_type && ++ self.vn_mode == other.vn_mode && ++ self_vn_devname == other_vn_devname ++ } ++ } ++ impl Eq for vnstat {} ++ impl ::fmt::Debug for vnstat { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let self_vn_devname: &[::c_char] = &self.vn_devname; ++ ++ f.debug_struct("vnstat") ++ .field("vn_fileid", &self.vn_fileid) ++ .field("vn_size", &self.vn_size) ++ .field("vn_dev", &self.vn_dev) ++ .field("vn_fsid", &self.vn_fsid) ++ .field("vn_mntdir", &self.vn_mntdir) ++ .field("vn_type", &self.vn_type) ++ .field("vn_mode", &self.vn_mode) ++ .field("vn_devname", &self_vn_devname) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for vnstat { ++ fn hash(&self, state: &mut H) { ++ let self_vn_devname: &[::c_char] = &self.vn_devname; ++ ++ self.vn_fileid.hash(state); ++ self.vn_size.hash(state); ++ self.vn_dev.hash(state); ++ self.vn_fsid.hash(state); ++ self.vn_mntdir.hash(state); ++ self.vn_type.hash(state); ++ self.vn_mode.hash(state); ++ self_vn_devname.hash(state); ++ } ++ } ++ } ++} ++ ++pub const RAND_MAX: ::c_int = 0x7fff_ffff; ++pub const ELAST: ::c_int = 97; ++ ++pub const KF_TYPE_EVENTFD: ::c_int = 13; ++ ++/// max length of devicename ++pub const SPECNAMELEN: ::c_int = 255; ++pub const KI_NSPARE_PTR: usize = 5; ++ ++/// domainset policies ++pub const DOMAINSET_POLICY_INVALID: ::c_int = 0; ++pub const DOMAINSET_POLICY_ROUNDROBIN: ::c_int = 1; ++pub const DOMAINSET_POLICY_FIRSTTOUCH: ::c_int = 2; ++pub const DOMAINSET_POLICY_PREFER: ::c_int = 3; ++pub const DOMAINSET_POLICY_INTERLEAVE: ::c_int = 4; ++ ++pub const MINCORE_SUPER: ::c_int = 0x60; ++ ++safe_f! { ++ pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { ++ let major = major as ::dev_t; ++ let minor = minor as ::dev_t; ++ let mut dev = 0; ++ dev |= ((major & 0xffffff00) as dev_t) << 32; ++ dev |= ((major & 0x000000ff) as dev_t) << 8; ++ dev |= ((minor & 0x0000ff00) as dev_t) << 24; ++ dev |= ((minor & 0xffff00ff) as dev_t) << 0; ++ dev ++ } ++} ++ ++extern "C" { ++ pub fn setgrent(); ++ pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; ++ pub fn freelocale(loc: ::locale_t); ++ pub fn msgrcv( ++ msqid: ::c_int, ++ msgp: *mut ::c_void, ++ msgsz: ::size_t, ++ msgtyp: ::c_long, ++ msgflg: ::c_int, ++ ) -> ::ssize_t; ++ ++ pub fn cpuset_getdomain( ++ level: ::cpulevel_t, ++ which: ::cpuwhich_t, ++ id: ::id_t, ++ setsize: ::size_t, ++ mask: *mut ::domainset_t, ++ policy: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn cpuset_setdomain( ++ level: ::cpulevel_t, ++ which: ::cpuwhich_t, ++ id: ::id_t, ++ setsize: ::size_t, ++ mask: *const ::domainset_t, ++ policy: ::c_int, ++ ) -> ::c_int; ++ ++ pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; ++ pub fn basename(path: *mut ::c_char) -> *mut ::c_char; ++} ++ ++#[link(name = "kvm")] ++extern "C" { ++ pub fn kvm_kerndisp(kd: *mut ::kvm_t) -> ::kssize_t; ++} ++ ++cfg_if! { ++ if #[cfg(any(target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "riscv64"))] { ++ mod b64; ++ pub use self::b64::*; ++ } ++} ++ ++cfg_if! { ++ if #[cfg(target_arch = "x86_64")] { ++ mod x86_64; ++ pub use self::x86_64::*; ++ } ++} +diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs +new file mode 100644 +index 0000000..7bf2534 +--- /dev/null ++++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs +@@ -0,0 +1,5 @@ ++pub const PROC_KPTI_CTL: ::c_int = ::PROC_PROCCTL_MD_MIN; ++pub const PROC_KPTI_CTL_ENABLE_ON_EXEC: ::c_int = 1; ++pub const PROC_KPTI_CTL_DISABLE_ON_EXEC: ::c_int = 2; ++pub const PROC_KPTI_STATUS: ::c_int = ::PROC_PROCCTL_MD_MIN + 1; ++pub const PROC_KPTI_STATUS_ACTIVE: ::c_int = 0x80000000; +diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs +index c634038..2ee676d 100644 +--- a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs ++++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs +@@ -1,16 +1,22 @@ + pub type fflags_t = u32; + pub type clock_t = i32; + +-pub type lwpid_t = i32; ++pub type vm_prot_t = u_char; ++pub type kvaddr_t = u64; ++pub type segsz_t = isize; ++pub type __fixpt_t = u32; ++pub type fixpt_t = __fixpt_t; ++pub type __lwpid_t = i32; ++pub type lwpid_t = __lwpid_t; + pub type blksize_t = i32; + pub type clockid_t = ::c_int; + pub type sem_t = _sem; ++pub type timer_t = *mut __c_anonymous__timer; + + pub type fsblkcnt_t = u64; + pub type fsfilcnt_t = u64; + pub type idtype_t = ::c_uint; + +-pub type key_t = ::c_long; + pub type msglen_t = ::c_ulong; + pub type msgqnum_t = ::c_ulong; + +@@ -21,6 +27,213 @@ pub type mqd_t = *mut ::c_void; + pub type posix_spawnattr_t = *mut ::c_void; + pub type posix_spawn_file_actions_t = *mut ::c_void; + ++pub type pthread_spinlock_t = *mut __c_anonymous_pthread_spinlock; ++pub type pthread_barrierattr_t = *mut __c_anonymous_pthread_barrierattr; ++pub type pthread_barrier_t = *mut __c_anonymous_pthread_barrier; ++ ++pub type uuid_t = ::uuid; ++pub type u_int = ::c_uint; ++pub type u_char = ::c_uchar; ++pub type u_long = ::c_ulong; ++pub type u_short = ::c_ushort; ++ ++pub type caddr_t = *mut ::c_char; ++ ++pub type fhandle_t = fhandle; ++ ++pub type au_id_t = ::uid_t; ++pub type au_asid_t = ::pid_t; ++ ++pub type cpusetid_t = ::c_int; ++ ++pub type sctp_assoc_t = u32; ++ ++#[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))] ++#[repr(u32)] ++pub enum devstat_support_flags { ++ DEVSTAT_ALL_SUPPORTED = 0x00, ++ DEVSTAT_NO_BLOCKSIZE = 0x01, ++ DEVSTAT_NO_ORDERED_TAGS = 0x02, ++ DEVSTAT_BS_UNAVAILABLE = 0x04, ++} ++impl ::Copy for devstat_support_flags {} ++impl ::Clone for devstat_support_flags { ++ fn clone(&self) -> devstat_support_flags { ++ *self ++ } ++} ++ ++#[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))] ++#[repr(u32)] ++pub enum devstat_trans_flags { ++ DEVSTAT_NO_DATA = 0x00, ++ DEVSTAT_READ = 0x01, ++ DEVSTAT_WRITE = 0x02, ++ DEVSTAT_FREE = 0x03, ++} ++ ++impl ::Copy for devstat_trans_flags {} ++impl ::Clone for devstat_trans_flags { ++ fn clone(&self) -> devstat_trans_flags { ++ *self ++ } ++} ++ ++#[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))] ++#[repr(u32)] ++pub enum devstat_tag_type { ++ DEVSTAT_TAG_SIMPLE = 0x00, ++ DEVSTAT_TAG_HEAD = 0x01, ++ DEVSTAT_TAG_ORDERED = 0x02, ++ DEVSTAT_TAG_NONE = 0x03, ++} ++impl ::Copy for devstat_tag_type {} ++impl ::Clone for devstat_tag_type { ++ fn clone(&self) -> devstat_tag_type { ++ *self ++ } ++} ++ ++#[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))] ++#[repr(u32)] ++pub enum devstat_match_flags { ++ DEVSTAT_MATCH_NONE = 0x00, ++ DEVSTAT_MATCH_TYPE = 0x01, ++ DEVSTAT_MATCH_IF = 0x02, ++ DEVSTAT_MATCH_PASS = 0x04, ++} ++impl ::Copy for devstat_match_flags {} ++impl ::Clone for devstat_match_flags { ++ fn clone(&self) -> devstat_match_flags { ++ *self ++ } ++} ++ ++#[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))] ++#[repr(u32)] ++pub enum devstat_priority { ++ DEVSTAT_PRIORITY_MIN = 0x000, ++ DEVSTAT_PRIORITY_OTHER = 0x020, ++ DEVSTAT_PRIORITY_PASS = 0x030, ++ DEVSTAT_PRIORITY_FD = 0x040, ++ DEVSTAT_PRIORITY_WFD = 0x050, ++ DEVSTAT_PRIORITY_TAPE = 0x060, ++ DEVSTAT_PRIORITY_CD = 0x090, ++ DEVSTAT_PRIORITY_DISK = 0x110, ++ DEVSTAT_PRIORITY_ARRAY = 0x120, ++ DEVSTAT_PRIORITY_MAX = 0xfff, ++} ++impl ::Copy for devstat_priority {} ++impl ::Clone for devstat_priority { ++ fn clone(&self) -> devstat_priority { ++ *self ++ } ++} ++ ++#[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))] ++#[repr(u32)] ++pub enum devstat_type_flags { ++ DEVSTAT_TYPE_DIRECT = 0x000, ++ DEVSTAT_TYPE_SEQUENTIAL = 0x001, ++ DEVSTAT_TYPE_PRINTER = 0x002, ++ DEVSTAT_TYPE_PROCESSOR = 0x003, ++ DEVSTAT_TYPE_WORM = 0x004, ++ DEVSTAT_TYPE_CDROM = 0x005, ++ DEVSTAT_TYPE_SCANNER = 0x006, ++ DEVSTAT_TYPE_OPTICAL = 0x007, ++ DEVSTAT_TYPE_CHANGER = 0x008, ++ DEVSTAT_TYPE_COMM = 0x009, ++ DEVSTAT_TYPE_ASC0 = 0x00a, ++ DEVSTAT_TYPE_ASC1 = 0x00b, ++ DEVSTAT_TYPE_STORARRAY = 0x00c, ++ DEVSTAT_TYPE_ENCLOSURE = 0x00d, ++ DEVSTAT_TYPE_FLOPPY = 0x00e, ++ DEVSTAT_TYPE_MASK = 0x00f, ++ DEVSTAT_TYPE_IF_SCSI = 0x010, ++ DEVSTAT_TYPE_IF_IDE = 0x020, ++ DEVSTAT_TYPE_IF_OTHER = 0x030, ++ DEVSTAT_TYPE_IF_MASK = 0x0f0, ++ DEVSTAT_TYPE_PASS = 0x100, ++} ++impl ::Copy for devstat_type_flags {} ++impl ::Clone for devstat_type_flags { ++ fn clone(&self) -> devstat_type_flags { ++ *self ++ } ++} ++ ++#[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))] ++#[repr(u32)] ++pub enum devstat_metric { ++ DSM_NONE, ++ DSM_TOTAL_BYTES, ++ DSM_TOTAL_BYTES_READ, ++ DSM_TOTAL_BYTES_WRITE, ++ DSM_TOTAL_TRANSFERS, ++ DSM_TOTAL_TRANSFERS_READ, ++ DSM_TOTAL_TRANSFERS_WRITE, ++ DSM_TOTAL_TRANSFERS_OTHER, ++ DSM_TOTAL_BLOCKS, ++ DSM_TOTAL_BLOCKS_READ, ++ DSM_TOTAL_BLOCKS_WRITE, ++ DSM_KB_PER_TRANSFER, ++ DSM_KB_PER_TRANSFER_READ, ++ DSM_KB_PER_TRANSFER_WRITE, ++ DSM_TRANSFERS_PER_SECOND, ++ DSM_TRANSFERS_PER_SECOND_READ, ++ DSM_TRANSFERS_PER_SECOND_WRITE, ++ DSM_TRANSFERS_PER_SECOND_OTHER, ++ DSM_MB_PER_SECOND, ++ DSM_MB_PER_SECOND_READ, ++ DSM_MB_PER_SECOND_WRITE, ++ DSM_BLOCKS_PER_SECOND, ++ DSM_BLOCKS_PER_SECOND_READ, ++ DSM_BLOCKS_PER_SECOND_WRITE, ++ DSM_MS_PER_TRANSACTION, ++ DSM_MS_PER_TRANSACTION_READ, ++ DSM_MS_PER_TRANSACTION_WRITE, ++ DSM_SKIP, ++ DSM_TOTAL_BYTES_FREE, ++ DSM_TOTAL_TRANSFERS_FREE, ++ DSM_TOTAL_BLOCKS_FREE, ++ DSM_KB_PER_TRANSFER_FREE, ++ DSM_MB_PER_SECOND_FREE, ++ DSM_TRANSFERS_PER_SECOND_FREE, ++ DSM_BLOCKS_PER_SECOND_FREE, ++ DSM_MS_PER_TRANSACTION_OTHER, ++ DSM_MS_PER_TRANSACTION_FREE, ++ DSM_BUSY_PCT, ++ DSM_QUEUE_LENGTH, ++ DSM_TOTAL_DURATION, ++ DSM_TOTAL_DURATION_READ, ++ DSM_TOTAL_DURATION_WRITE, ++ DSM_TOTAL_DURATION_FREE, ++ DSM_TOTAL_DURATION_OTHER, ++ DSM_TOTAL_BUSY_TIME, ++ DSM_MAX, ++} ++impl ::Copy for devstat_metric {} ++impl ::Clone for devstat_metric { ++ fn clone(&self) -> devstat_metric { ++ *self ++ } ++} ++ ++#[cfg_attr(feature = "extra_traits", derive(Debug, Hash, PartialEq, Eq))] ++#[repr(u32)] ++pub enum devstat_select_mode { ++ DS_SELECT_ADD, ++ DS_SELECT_ONLY, ++ DS_SELECT_REMOVE, ++ DS_SELECT_ADDONLY, ++} ++impl ::Copy for devstat_select_mode {} ++impl ::Clone for devstat_select_mode { ++ fn clone(&self) -> devstat_select_mode { ++ *self ++ } ++} ++ + s! { + pub struct aiocb { + pub aio_fildes: ::c_int, +@@ -67,15 +280,10 @@ s! { + pub struct _sem { + data: [u32; 4], + } +- +- pub struct ipc_perm { +- pub cuid: ::uid_t, +- pub cgid: ::gid_t, +- pub uid: ::uid_t, +- pub gid: ::gid_t, +- pub mode: ::mode_t, +- pub seq: ::c_ushort, +- pub key: ::key_t, ++ pub struct sembuf { ++ pub sem_num: ::c_ushort, ++ pub sem_op: ::c_short, ++ pub sem_flg: ::c_short, + } + + pub struct msqid_ds { +@@ -112,11 +320,6 @@ s! { + pub sc_groups: [::gid_t; 1], + } + +- pub struct accept_filter_arg { +- pub af_name: [::c_char; 16], +- af_arg: [[::c_char; 10]; 24], +- } +- + pub struct ptrace_vm_entry { + pub pve_entry: ::c_int, + pub pve_timestamp: ::c_int, +@@ -130,6 +333,37 @@ s! { + pub pve_path: *mut ::c_char, + } + ++ pub struct ptrace_lwpinfo { ++ pub pl_lwpid: lwpid_t, ++ pub pl_event: ::c_int, ++ pub pl_flags: ::c_int, ++ pub pl_sigmask: ::sigset_t, ++ pub pl_siglist: ::sigset_t, ++ pub pl_siginfo: ::siginfo_t, ++ pub pl_tdname: [::c_char; ::MAXCOMLEN as usize + 1], ++ pub pl_child_pid: ::pid_t, ++ pub pl_syscall_code: ::c_uint, ++ pub pl_syscall_narg: ::c_uint, ++ } ++ ++ pub struct ptrace_sc_ret { ++ pub sr_retval: [::register_t; 2], ++ pub sr_error: ::c_int, ++ } ++ ++ pub struct ptrace_coredump { ++ pub pc_fd: ::c_int, ++ pub pc_flags: u32, ++ pub pc_limit: ::off_t, ++ } ++ ++ pub struct ptrace_sc_remote { ++ pub pscr_ret: ptrace_sc_ret, ++ pub pscr_syscall: ::c_uint, ++ pub pscr_nargs: ::c_uint, ++ pub pscr_args: *mut ::register_t, ++ } ++ + pub struct cpuset_t { + #[cfg(target_pointer_width = "64")] + __bits: [::c_long; 4], +@@ -140,6 +374,951 @@ s! { + pub struct cap_rights_t { + cr_rights: [u64; 2], + } ++ ++ pub struct umutex { ++ m_owner: ::lwpid_t, ++ m_flags: u32, ++ m_ceilings: [u32; 2], ++ m_rb_link: ::uintptr_t, ++ #[cfg(target_pointer_width = "32")] ++ m_pad: u32, ++ m_spare: [u32; 2], ++ ++ } ++ ++ pub struct ucond { ++ c_has_waiters: u32, ++ c_flags: u32, ++ c_clockid: u32, ++ c_spare: [u32; 1], ++ } ++ ++ pub struct uuid { ++ pub time_low: u32, ++ pub time_mid: u16, ++ pub time_hi_and_version: u16, ++ pub clock_seq_hi_and_reserved: u8, ++ pub clock_seq_low: u8, ++ pub node: [u8; _UUID_NODE_LEN], ++ } ++ ++ pub struct __c_anonymous_pthread_spinlock { ++ s_clock: umutex, ++ } ++ ++ pub struct __c_anonymous_pthread_barrierattr { ++ pshared: ::c_int, ++ } ++ ++ pub struct __c_anonymous_pthread_barrier { ++ b_lock: umutex, ++ b_cv: ucond, ++ b_cycle: i64, ++ b_count: ::c_int, ++ b_waiters: ::c_int, ++ b_refcount: ::c_int, ++ b_destroying: ::c_int, ++ } ++ ++ pub struct kinfo_vmentry { ++ pub kve_structsize: ::c_int, ++ pub kve_type: ::c_int, ++ pub kve_start: u64, ++ pub kve_end: u64, ++ pub kve_offset: u64, ++ pub kve_vn_fileid: u64, ++ #[cfg(not(freebsd11))] ++ pub kve_vn_fsid_freebsd11: u32, ++ #[cfg(freebsd11)] ++ pub kve_vn_fsid: u32, ++ pub kve_flags: ::c_int, ++ pub kve_resident: ::c_int, ++ pub kve_private_resident: ::c_int, ++ pub kve_protection: ::c_int, ++ pub kve_ref_count: ::c_int, ++ pub kve_shadow_count: ::c_int, ++ pub kve_vn_type: ::c_int, ++ pub kve_vn_size: u64, ++ #[cfg(not(freebsd11))] ++ pub kve_vn_rdev_freebsd11: u32, ++ #[cfg(freebsd11)] ++ pub kve_vn_rdev: u32, ++ pub kve_vn_mode: u16, ++ pub kve_status: u16, ++ #[cfg(not(freebsd11))] ++ pub kve_vn_fsid: u64, ++ #[cfg(not(freebsd11))] ++ pub kve_vn_rdev: u64, ++ #[cfg(not(freebsd11))] ++ _kve_is_spare: [::c_int; 8], ++ #[cfg(freebsd11)] ++ _kve_is_spare: [::c_int; 12], ++ pub kve_path: [[::c_char; 32]; 32], ++ } ++ ++ pub struct __c_anonymous_filestat { ++ pub stqe_next: *mut filestat, ++ } ++ ++ pub struct filestat { ++ pub fs_type: ::c_int, ++ pub fs_flags: ::c_int, ++ pub fs_fflags: ::c_int, ++ pub fs_uflags: ::c_int, ++ pub fs_fd: ::c_int, ++ pub fs_ref_count: ::c_int, ++ pub fs_offset: ::off_t, ++ pub fs_typedep: *mut ::c_void, ++ pub fs_path: *mut ::c_char, ++ pub next: __c_anonymous_filestat, ++ pub fs_cap_rights: cap_rights_t, ++ } ++ ++ pub struct filestat_list { ++ pub stqh_first: *mut filestat, ++ pub stqh_last: *mut *mut filestat, ++ } ++ ++ pub struct procstat { ++ pub tpe: ::c_int, ++ pub kd: ::uintptr_t, ++ pub vmentries: *mut ::c_void, ++ pub files: *mut ::c_void, ++ pub argv: *mut ::c_void, ++ pub envv: *mut ::c_void, ++ pub core: ::uintptr_t, ++ } ++ ++ pub struct itimerspec { ++ pub it_interval: ::timespec, ++ pub it_value: ::timespec, ++ } ++ ++ pub struct __c_anonymous__timer { ++ _priv: [::c_int; 3], ++ } ++ ++ /// Used to hold a copy of the command line, if it had a sane length. ++ pub struct pargs { ++ /// Reference count. ++ pub ar_ref: u_int, ++ /// Length. ++ pub ar_length: u_int, ++ /// Arguments. ++ pub ar_args: [::c_uchar; 1], ++ } ++ ++ pub struct priority { ++ /// Scheduling class. ++ pub pri_class: u_char, ++ /// Normal priority level. ++ pub pri_level: u_char, ++ /// Priority before propagation. ++ pub pri_native: u_char, ++ /// User priority based on p_cpu and p_nice. ++ pub pri_user: u_char, ++ } ++ ++ pub struct kvm_swap { ++ pub ksw_devname: [::c_char; 32], ++ pub ksw_used: u_int, ++ pub ksw_total: u_int, ++ pub ksw_flags: ::c_int, ++ pub ksw_reserved1: u_int, ++ pub ksw_reserved2: u_int, ++ } ++ ++ pub struct nlist { ++ /// symbol name (in memory) ++ pub n_name: *const ::c_char, ++ /// type defines ++ pub n_type: ::c_uchar, ++ /// "type" and binding information ++ pub n_other: ::c_char, ++ /// used by stab entries ++ pub n_desc: ::c_short, ++ pub n_value: ::c_ulong, ++ } ++ ++ pub struct kvm_nlist { ++ pub n_name: *const ::c_char, ++ pub n_type: ::c_uchar, ++ pub n_value: ::kvaddr_t, ++ } ++ ++ pub struct __c_anonymous_sem { ++ _priv: ::uintptr_t, ++ } ++ ++ pub struct semid_ds { ++ pub sem_perm: ::ipc_perm, ++ pub __sem_base: *mut __c_anonymous_sem, ++ pub sem_nsems: ::c_ushort, ++ pub sem_otime: ::time_t, ++ pub sem_ctime: ::time_t, ++ } ++ ++ pub struct vmtotal { ++ pub t_vm: u64, ++ pub t_avm: u64, ++ pub t_rm: u64, ++ pub t_arm: u64, ++ pub t_vmshr: u64, ++ pub t_avmshr: u64, ++ pub t_rmshr: u64, ++ pub t_armshr: u64, ++ pub t_free: u64, ++ pub t_rq: i16, ++ pub t_dw: i16, ++ pub t_pw: i16, ++ pub t_sl: i16, ++ pub t_sw: i16, ++ pub t_pad: [u16; 3], ++ } ++ ++ pub struct sockstat { ++ pub inp_ppcb: u64, ++ pub so_addr: u64, ++ pub so_pcb: u64, ++ pub unp_conn: u64, ++ pub dom_family: ::c_int, ++ pub proto: ::c_int, ++ pub so_rcv_sb_state: ::c_int, ++ pub so_snd_sb_state: ::c_int, ++ /// Socket address. ++ pub sa_local: ::sockaddr_storage, ++ /// Peer address. ++ pub sa_peer: ::sockaddr_storage, ++ pub type_: ::c_int, ++ pub dname: [::c_char; 32], ++ #[cfg(any(freebsd12, freebsd13, freebsd14))] ++ pub sendq: ::c_uint, ++ #[cfg(any(freebsd12, freebsd13, freebsd14))] ++ pub recvq: ::c_uint, ++ } ++ ++ pub struct shmstat { ++ pub size: u64, ++ pub mode: u16, ++ } ++ ++ pub struct spacectl_range { ++ pub r_offset: ::off_t, ++ pub r_len: ::off_t ++ } ++ ++ pub struct rusage_ext { ++ pub rux_runtime: u64, ++ pub rux_uticks: u64, ++ pub rux_sticks: u64, ++ pub rux_iticks: u64, ++ pub rux_uu: u64, ++ pub rux_su: u64, ++ pub rux_tu: u64, ++ } ++ ++ pub struct if_clonereq { ++ pub ifcr_total: ::c_int, ++ pub ifcr_count: ::c_int, ++ pub ifcr_buffer: *mut ::c_char, ++ } ++ ++ pub struct if_msghdr { ++ /// to skip over non-understood messages ++ pub ifm_msglen: ::c_ushort, ++ /// future binary compatibility ++ pub ifm_version: ::c_uchar, ++ /// message type ++ pub ifm_type: ::c_uchar, ++ /// like rtm_addrs ++ pub ifm_addrs: ::c_int, ++ /// value of if_flags ++ pub ifm_flags: ::c_int, ++ /// index for associated ifp ++ pub ifm_index: ::c_ushort, ++ pub _ifm_spare1: ::c_ushort, ++ /// statistics and other data about if ++ pub ifm_data: if_data, ++ } ++ ++ pub struct if_msghdrl { ++ /// to skip over non-understood messages ++ pub ifm_msglen: ::c_ushort, ++ /// future binary compatibility ++ pub ifm_version: ::c_uchar, ++ /// message type ++ pub ifm_type: ::c_uchar, ++ /// like rtm_addrs ++ pub ifm_addrs: ::c_int, ++ /// value of if_flags ++ pub ifm_flags: ::c_int, ++ /// index for associated ifp ++ pub ifm_index: ::c_ushort, ++ /// spare space to grow if_index, see if_var.h ++ pub _ifm_spare1: ::c_ushort, ++ /// length of if_msghdrl incl. if_data ++ pub ifm_len: ::c_ushort, ++ /// offset of if_data from beginning ++ pub ifm_data_off: ::c_ushort, ++ pub _ifm_spare2: ::c_int, ++ /// statistics and other data about if ++ pub ifm_data: if_data, ++ } ++ ++ pub struct ifa_msghdr { ++ /// to skip over non-understood messages ++ pub ifam_msglen: ::c_ushort, ++ /// future binary compatibility ++ pub ifam_version: ::c_uchar, ++ /// message type ++ pub ifam_type: ::c_uchar, ++ /// like rtm_addrs ++ pub ifam_addrs: ::c_int, ++ /// value of ifa_flags ++ pub ifam_flags: ::c_int, ++ /// index for associated ifp ++ pub ifam_index: ::c_ushort, ++ pub _ifam_spare1: ::c_ushort, ++ /// value of ifa_ifp->if_metric ++ pub ifam_metric: ::c_int, ++ } ++ ++ pub struct ifa_msghdrl { ++ /// to skip over non-understood messages ++ pub ifam_msglen: ::c_ushort, ++ /// future binary compatibility ++ pub ifam_version: ::c_uchar, ++ /// message type ++ pub ifam_type: ::c_uchar, ++ /// like rtm_addrs ++ pub ifam_addrs: ::c_int, ++ /// value of ifa_flags ++ pub ifam_flags: ::c_int, ++ /// index for associated ifp ++ pub ifam_index: ::c_ushort, ++ /// spare space to grow if_index, see if_var.h ++ pub _ifam_spare1: ::c_ushort, ++ /// length of ifa_msghdrl incl. if_data ++ pub ifam_len: ::c_ushort, ++ /// offset of if_data from beginning ++ pub ifam_data_off: ::c_ushort, ++ /// value of ifa_ifp->if_metric ++ pub ifam_metric: ::c_int, ++ /// statistics and other data about if or address ++ pub ifam_data: if_data, ++ } ++ ++ pub struct ifma_msghdr { ++ /// to skip over non-understood messages ++ pub ifmam_msglen: ::c_ushort, ++ /// future binary compatibility ++ pub ifmam_version: ::c_uchar, ++ /// message type ++ pub ifmam_type: ::c_uchar, ++ /// like rtm_addrs ++ pub ifmam_addrs: ::c_int, ++ /// value of ifa_flags ++ pub ifmam_flags: ::c_int, ++ /// index for associated ifp ++ pub ifmam_index: ::c_ushort, ++ pub _ifmam_spare1: ::c_ushort, ++ } ++ ++ pub struct if_announcemsghdr { ++ /// to skip over non-understood messages ++ pub ifan_msglen: ::c_ushort, ++ /// future binary compatibility ++ pub ifan_version: ::c_uchar, ++ /// message type ++ pub ifan_type: ::c_uchar, ++ /// index for associated ifp ++ pub ifan_index: ::c_ushort, ++ /// if name, e.g. "en0" ++ pub ifan_name: [::c_char; ::IFNAMSIZ as usize], ++ /// what type of announcement ++ pub ifan_what: ::c_ushort, ++ } ++ ++ pub struct ifreq_buffer { ++ pub length: ::size_t, ++ pub buffer: *mut ::c_void, ++ } ++ ++ pub struct ifaliasreq { ++ /// if name, e.g. "en0" ++ pub ifra_name: [::c_char; ::IFNAMSIZ as usize], ++ pub ifra_addr: ::sockaddr, ++ pub ifra_broadaddr: ::sockaddr, ++ pub ifra_mask: ::sockaddr, ++ pub ifra_vhid: ::c_int, ++ } ++ ++ /// 9.x compat ++ pub struct oifaliasreq { ++ /// if name, e.g. "en0" ++ pub ifra_name: [::c_char; ::IFNAMSIZ as usize], ++ pub ifra_addr: ::sockaddr, ++ pub ifra_broadaddr: ::sockaddr, ++ pub ifra_mask: ::sockaddr, ++ } ++ ++ pub struct ifmediareq { ++ /// if name, e.g. "en0" ++ pub ifm_name: [::c_char; ::IFNAMSIZ as usize], ++ /// current media options ++ pub ifm_current: ::c_int, ++ /// don't care mask ++ pub ifm_mask: ::c_int, ++ /// media status ++ pub ifm_status: ::c_int, ++ /// active options ++ pub ifm_active: ::c_int, ++ /// # entries in ifm_ulist array ++ pub ifm_count: ::c_int, ++ /// media words ++ pub ifm_ulist: *mut ::c_int, ++ } ++ ++ pub struct ifdrv { ++ /// if name, e.g. "en0" ++ pub ifd_name: [::c_char; ::IFNAMSIZ as usize], ++ pub ifd_cmd: ::c_ulong, ++ pub ifd_len: ::size_t, ++ pub ifd_data: *mut ::c_void, ++ } ++ ++ pub struct ifi2creq { ++ /// i2c address (0xA0, 0xA2) ++ pub dev_addr: u8, ++ /// read offset ++ pub offset: u8, ++ /// read length ++ pub len: u8, ++ pub spare0: u8, ++ pub spare1: u32, ++ /// read buffer ++ pub data: [u8; 8], ++ } ++ ++ pub struct ifrsshash { ++ /// if name, e.g. "en0" ++ pub ifrh_name: [::c_char; ::IFNAMSIZ as usize], ++ /// RSS_FUNC_ ++ pub ifrh_func: u8, ++ pub ifrh_spare0: u8, ++ pub ifrh_spare1: u16, ++ /// RSS_TYPE_ ++ pub ifrh_types: u32, ++ } ++ ++ pub struct ifmibdata { ++ /// name of interface ++ pub ifmd_name: [::c_char; ::IFNAMSIZ as usize], ++ /// number of promiscuous listeners ++ pub ifmd_pcount: ::c_int, ++ /// interface flags ++ pub ifmd_flags: ::c_int, ++ /// instantaneous length of send queue ++ pub ifmd_snd_len: ::c_int, ++ /// maximum length of send queue ++ pub ifmd_snd_maxlen: ::c_int, ++ /// number of drops in send queue ++ pub ifmd_snd_drops: ::c_int, ++ /// for future expansion ++ pub ifmd_filler: [::c_int; 4], ++ /// generic information and statistics ++ pub ifmd_data: if_data, ++ } ++ ++ pub struct ifmib_iso_8802_3 { ++ pub dot3StatsAlignmentErrors: u32, ++ pub dot3StatsFCSErrors: u32, ++ pub dot3StatsSingleCollisionFrames: u32, ++ pub dot3StatsMultipleCollisionFrames: u32, ++ pub dot3StatsSQETestErrors: u32, ++ pub dot3StatsDeferredTransmissions: u32, ++ pub dot3StatsLateCollisions: u32, ++ pub dot3StatsExcessiveCollisions: u32, ++ pub dot3StatsInternalMacTransmitErrors: u32, ++ pub dot3StatsCarrierSenseErrors: u32, ++ pub dot3StatsFrameTooLongs: u32, ++ pub dot3StatsInternalMacReceiveErrors: u32, ++ pub dot3StatsEtherChipSet: u32, ++ pub dot3StatsMissedFrames: u32, ++ pub dot3StatsCollFrequencies: [u32; 16], ++ pub dot3Compliance: u32, ++ } ++ ++ pub struct __c_anonymous_ph { ++ pub ph1: u64, ++ pub ph2: u64, ++ } ++ ++ pub struct fid { ++ pub fid_len: ::c_ushort, ++ pub fid_data0: ::c_ushort, ++ pub fid_data: [::c_char; ::MAXFIDSZ as usize], ++ } ++ ++ pub struct fhandle { ++ pub fh_fsid: ::fsid_t, ++ pub fh_fid: fid, ++ } ++ ++ pub struct bintime { ++ pub sec: ::time_t, ++ pub frac: u64, ++ } ++ ++ pub struct clockinfo { ++ /// clock frequency ++ pub hz: ::c_int, ++ /// micro-seconds per hz tick ++ pub tick: ::c_int, ++ pub spare: ::c_int, ++ /// statistics clock frequency ++ pub stathz: ::c_int, ++ /// profiling clock frequency ++ pub profhz: ::c_int, ++ } ++ ++ pub struct __c_anonymous_stailq_entry_devstat { ++ pub stqe_next: *mut devstat, ++ } ++ ++ pub struct devstat { ++ /// Update sequence ++ pub sequence0: ::u_int, ++ /// Allocated entry ++ pub allocated: ::c_int, ++ /// started ops ++ pub start_count: ::u_int, ++ /// completed ops ++ pub end_count: ::u_int, ++ /// busy time unaccounted for since this time ++ pub busy_from: bintime, ++ pub dev_links: __c_anonymous_stailq_entry_devstat, ++ /// Devstat device number. ++ pub device_number: u32, ++ pub device_name: [::c_char; DEVSTAT_NAME_LEN as usize], ++ pub unit_number: ::c_int, ++ pub bytes: [u64; DEVSTAT_N_TRANS_FLAGS as usize], ++ pub operations: [u64; DEVSTAT_N_TRANS_FLAGS as usize], ++ pub duration: [bintime; DEVSTAT_N_TRANS_FLAGS as usize], ++ pub busy_time: bintime, ++ /// Time the device was created. ++ pub creation_time: bintime, ++ /// Block size, bytes ++ pub block_size: u32, ++ /// The number of simple, ordered, and head of queue tags sent. ++ pub tag_types: [u64; 3], ++ /// Which statistics are supported by a given device. ++ pub flags: devstat_support_flags, ++ /// Device type ++ pub device_type: devstat_type_flags, ++ /// Controls list pos. ++ pub priority: devstat_priority, ++ /// Identification for GEOM nodes ++ pub id: *const ::c_void, ++ /// Update sequence ++ pub sequence1: ::u_int, ++ } ++ ++ pub struct devstat_match { ++ pub match_fields: devstat_match_flags, ++ pub device_type: devstat_type_flags, ++ pub num_match_categories: ::c_int, ++ } ++ ++ pub struct devstat_match_table { ++ pub match_str: *const ::c_char, ++ pub type_: devstat_type_flags, ++ pub match_field: devstat_match_flags, ++ } ++ ++ pub struct device_selection { ++ pub device_number: u32, ++ pub device_name: [::c_char; DEVSTAT_NAME_LEN as usize], ++ pub unit_number: ::c_int, ++ pub selected: ::c_int, ++ pub bytes: u64, ++ pub position: ::c_int, ++ } ++ ++ pub struct devinfo { ++ pub devices: *mut devstat, ++ pub mem_ptr: *mut u8, ++ pub generation: ::c_long, ++ pub numdevs: ::c_int, ++ } ++ ++ pub struct sockcred2 { ++ pub sc_version: ::c_int, ++ pub sc_pid: ::pid_t, ++ pub sc_uid: ::uid_t, ++ pub sc_euid: ::uid_t, ++ pub sc_gid: ::gid_t, ++ pub sc_egid: ::gid_t, ++ pub sc_ngroups: ::c_int, ++ pub sc_groups: [::gid_t; 1], ++ } ++ ++ pub struct ifconf { ++ pub ifc_len: ::c_int, ++ #[cfg(libc_union)] ++ pub ifc_ifcu: __c_anonymous_ifc_ifcu, ++ } ++ ++ pub struct au_mask_t { ++ pub am_success: ::c_uint, ++ pub am_failure: ::c_uint, ++ } ++ ++ pub struct au_tid_t { ++ pub port: u32, ++ pub machine: u32, ++ } ++ ++ pub struct auditinfo_t { ++ pub ai_auid: ::au_id_t, ++ pub ai_mask: ::au_mask_t, ++ pub ai_termid: au_tid_t, ++ pub ai_asid: ::au_asid_t, ++ } ++ ++ pub struct tcp_fastopen { ++ pub enable: ::c_int, ++ pub psk: [u8; ::TCP_FASTOPEN_PSK_LEN as usize], ++ } ++ ++ pub struct tcp_function_set { ++ pub function_set_name: [::c_char; ::TCP_FUNCTION_NAME_LEN_MAX as usize], ++ pub pcbcnt: u32, ++ } ++ ++ pub struct tcp_info { ++ pub tcpi_state: u8, ++ pub __tcpi_ca_state: u8, ++ pub __tcpi_retransmits: u8, ++ pub __tcpi_probes: u8, ++ pub __tcpi_backoff: u8, ++ pub tcpi_options: u8, ++ pub tcp_snd_wscale: u8, ++ pub tcp_rcv_wscale: u8, ++ pub tcpi_rto: u32, ++ pub __tcpi_ato: u32, ++ pub tcpi_snd_mss: u32, ++ pub tcpi_rcv_mss: u32, ++ pub __tcpi_unacked: u32, ++ pub __tcpi_sacked: u32, ++ pub __tcpi_lost: u32, ++ pub __tcpi_retrans: u32, ++ pub __tcpi_fackets: u32, ++ pub __tcpi_last_data_sent: u32, ++ pub __tcpi_last_ack_sent: u32, ++ pub tcpi_last_data_recv: u32, ++ pub __tcpi_last_ack_recv: u32, ++ pub __tcpi_pmtu: u32, ++ pub __tcpi_rcv_ssthresh: u32, ++ pub tcpi_rtt: u32, ++ pub tcpi_rttvar: u32, ++ pub tcpi_snd_ssthresh: u32, ++ pub tcpi_snd_cwnd: u32, ++ pub __tcpi_advmss: u32, ++ pub __tcpi_reordering: u32, ++ pub __tcpi_rcv_rtt: u32, ++ pub tcpi_rcv_space: u32, ++ pub tcpi_snd_wnd: u32, ++ pub tcpi_snd_bwnd: u32, ++ pub tcpi_snd_nxt: u32, ++ pub tcpi_rcv_nxt: u32, ++ pub tcpi_toe_tid: u32, ++ pub tcpi_snd_rexmitpack: u32, ++ pub tcpi_rcv_ooopack: u32, ++ pub tcpi_snd_zerowin: u32, ++ #[cfg(freebsd14)] ++ pub tcpi_delivered_ce: u32, ++ #[cfg(freebsd14)] ++ pub tcpi_received_ce: u32, ++ #[cfg(freebsd14)] ++ pub __tcpi_delivered_e1_bytes: u32, ++ #[cfg(freebsd14)] ++ pub __tcpi_delivered_e0_bytes: u32, ++ #[cfg(freebsd14)] ++ pub __tcpi_delivered_ce_bytes: u32, ++ #[cfg(freebsd14)] ++ pub __tcpi_received_e1_bytes: u32, ++ #[cfg(freebsd14)] ++ pub __tcpi_received_e0_bytes: u32, ++ #[cfg(freebsd14)] ++ pub __tcpi_received_ce_bytes: u32, ++ #[cfg(freebsd14)] ++ pub __tcpi_pad: [u32; 19], ++ #[cfg(not(freebsd14))] ++ pub __tcpi_pad: [u32; 26], ++ } ++ ++ pub struct _umtx_time { ++ pub _timeout: ::timespec, ++ pub _flags: u32, ++ pub _clockid: u32, ++ } ++ ++ pub struct shm_largepage_conf { ++ pub psind: ::c_int, ++ pub alloc_policy: ::c_int, ++ __pad: [::c_int; 10], ++ } ++ ++ pub struct memory_type { ++ __priva: [::uintptr_t; 32], ++ __privb: [::uintptr_t; 26], ++ } ++ ++ pub struct memory_type_list { ++ __priv: [::uintptr_t; 2], ++ } ++ ++ pub struct pidfh { ++ __priva: [[::uintptr_t; 32]; 8], ++ __privb: [::uintptr_t; 2], ++ } ++ ++ pub struct sctp_event { ++ pub se_assoc_id: ::sctp_assoc_t, ++ pub se_type: u16, ++ pub se_on: u8, ++ } ++ ++ pub struct sctp_event_subscribe { ++ pub sctp_data_io_event: u8, ++ pub sctp_association_event: u8, ++ pub sctp_address_event: u8, ++ pub sctp_send_failure_event: u8, ++ pub sctp_peer_error_event: u8, ++ pub sctp_shutdown_event: u8, ++ pub sctp_partial_delivery_event: u8, ++ pub sctp_adaptation_layer_event: u8, ++ pub sctp_authentication_event: u8, ++ pub sctp_sender_dry_event: u8, ++ pub sctp_stream_reset_event: u8, ++ } ++ ++ pub struct sctp_initmsg { ++ pub sinit_num_ostreams: u16, ++ pub sinit_max_instreams: u16, ++ pub sinit_max_attempts: u16, ++ pub sinit_max_init_timeo: u16, ++ } ++ ++ pub struct sctp_sndrcvinfo { ++ pub sinfo_stream: u16, ++ pub sinfo_ssn: u16, ++ pub sinfo_flags: u16, ++ pub sinfo_ppid: u32, ++ pub sinfo_context: u32, ++ pub sinfo_timetolive: u32, ++ pub sinfo_tsn: u32, ++ pub sinfo_cumtsn: u32, ++ pub sinfo_assoc_id: ::sctp_assoc_t, ++ pub sinfo_keynumber: u16, ++ pub sinfo_keynumber_valid: u16, ++ pub __reserve_pad: [[u8; 23]; 4], ++ } ++ ++ pub struct sctp_extrcvinfo { ++ pub sinfo_stream: u16, ++ pub sinfo_ssn: u16, ++ pub sinfo_flags: u16, ++ pub sinfo_ppid: u32, ++ pub sinfo_context: u32, ++ pub sinfo_timetolive: u32, ++ pub sinfo_tsn: u32, ++ pub sinfo_cumtsn: u32, ++ pub sinfo_assoc_id: ::sctp_assoc_t, ++ pub serinfo_next_flags: u16, ++ pub serinfo_next_stream: u16, ++ pub serinfo_next_aid: u32, ++ pub serinfo_next_length: u32, ++ pub serinfo_next_ppid: u32, ++ pub sinfo_keynumber: u16, ++ pub sinfo_keynumber_valid: u16, ++ pub __reserve_pad: [[u8; 19]; 4], ++ } ++ ++ pub struct sctp_sndinfo { ++ pub snd_sid: u16, ++ pub snd_flags: u16, ++ pub snd_ppid: u32, ++ pub snd_context: u32, ++ pub snd_assoc_id: ::sctp_assoc_t, ++ } ++ ++ pub struct sctp_prinfo { ++ pub pr_policy: u16, ++ pub pr_value: u32, ++ } ++ ++ pub struct sctp_default_prinfo { ++ pub pr_policy: u16, ++ pub pr_value: u32, ++ pub pr_assoc_id: ::sctp_assoc_t, ++ } ++ ++ pub struct sctp_authinfo { ++ pub auth_keynumber: u16, ++ } ++ ++ pub struct sctp_rcvinfo { ++ pub rcv_sid: u16, ++ pub rcv_ssn: u16, ++ pub rcv_flags: u16, ++ pub rcv_ppid: u32, ++ pub rcv_tsn: u32, ++ pub rcv_cumtsn: u32, ++ pub rcv_context: u32, ++ pub rcv_assoc_id: ::sctp_assoc_t, ++ } ++ ++ pub struct sctp_nxtinfo { ++ pub nxt_sid: u16, ++ pub nxt_flags: u16, ++ pub nxt_ppid: u32, ++ pub nxt_length: u32, ++ pub nxt_assoc_id: ::sctp_assoc_t, ++ } ++ ++ pub struct sctp_recvv_rn { ++ pub recvv_rcvinfo: sctp_rcvinfo, ++ pub recvv_nxtinfo: sctp_nxtinfo, ++ } ++ ++ pub struct sctp_sendv_spa { ++ pub sendv_flags: u32, ++ pub sendv_sndinfo: sctp_sndinfo, ++ pub sendv_prinfo: sctp_prinfo, ++ pub sendv_authinfo: sctp_authinfo, ++ } ++ ++ pub struct sctp_snd_all_completes { ++ pub sall_stream: u16, ++ pub sall_flags: u16, ++ pub sall_ppid: u32, ++ pub sall_context: u32, ++ pub sall_num_sent: u32, ++ pub sall_num_failed: u32, ++ } ++ ++ pub struct sctp_pcbinfo { ++ pub ep_count: u32, ++ pub asoc_count: u32, ++ pub laddr_count: u32, ++ pub raddr_count: u32, ++ pub chk_count: u32, ++ pub readq_count: u32, ++ pub free_chunks: u32, ++ pub stream_oque: u32, ++ } ++ ++ pub struct sctp_sockstat { ++ pub ss_assoc_id: ::sctp_assoc_t, ++ pub ss_total_sndbuf: u32, ++ pub ss_total_recv_buf: u32, ++ } ++ ++ pub struct sctp_assoc_change { ++ pub sac_type: u16, ++ pub sac_flags: u16, ++ pub sac_length: u32, ++ pub sac_state: u16, ++ pub sac_error: u16, ++ pub sac_outbound_streams: u16, ++ pub sac_inbound_streams: u16, ++ pub sac_assoc_id: ::sctp_assoc_t, ++ pub sac_info: [u8; 0], ++ } ++ ++ pub struct sctp_paddr_change { ++ pub spc_type: u16, ++ pub spc_flags: u16, ++ pub spc_length: u32, ++ pub spc_aaddr: ::sockaddr_storage, ++ pub spc_state: u32, ++ pub spc_error: u32, ++ pub spc_assoc_id: ::sctp_assoc_t, ++ } ++ ++ pub struct sctp_remote_error { ++ pub sre_type: u16, ++ pub sre_flags: u16, ++ pub sre_length: u32, ++ pub sre_error: u16, ++ pub sre_assoc_id: ::sctp_assoc_t, ++ pub sre_data: [u8; 0], ++ } ++ ++ pub struct sctp_send_failed_event { ++ pub ssfe_type: u16, ++ pub ssfe_flags: u16, ++ pub ssfe_length: u32, ++ pub ssfe_error: u32, ++ pub ssfe_info: sctp_sndinfo, ++ pub ssfe_assoc_id: ::sctp_assoc_t, ++ pub ssfe_data: [u8; 0], ++ } ++ ++ pub struct sctp_shutdown_event { ++ pub sse_type: u16, ++ pub sse_flags: u16, ++ pub sse_length: u32, ++ pub sse_assoc_id: ::sctp_assoc_t, ++ } ++ ++ pub struct sctp_adaptation_event { ++ pub sai_type: u16, ++ pub sai_flags: u16, ++ pub sai_length: u32, ++ pub sai_adaptation_ind: u32, ++ pub sai_assoc_id: ::sctp_assoc_t, ++ } ++ ++ pub struct sctp_setadaptation { ++ pub ssb_adaptation_ind: u32, ++ } ++ ++ pub struct sctp_pdapi_event { ++ pub pdapi_type: u16, ++ pub pdapi_flags: u16, ++ pub pdapi_length: u32, ++ pub pdapi_indication: u32, ++ pub pdapi_stream: u16, ++ pub pdapi_seq: u16, ++ pub pdapi_assoc_id: ::sctp_assoc_t, ++ } ++ ++ pub struct sctp_sender_dry_event { ++ pub sender_dry_type: u16, ++ pub sender_dry_flags: u16, ++ pub sender_dry_length: u32, ++ pub sender_dry_assoc_id: ::sctp_assoc_t, ++ } ++ ++ pub struct sctp_stream_reset_event { ++ pub strreset_type: u16, ++ pub strreset_flags: u16, ++ pub strreset_length: u32, ++ pub strreset_assoc_id: ::sctp_assoc_t, ++ pub strreset_stream_list: [u16; 0], ++ } ++ ++ pub struct sctp_stream_change_event { ++ pub strchange_type: u16, ++ pub strchange_flags: u16, ++ pub strchange_length: u32, ++ pub strchange_assoc_id: ::sctp_assoc_t, ++ pub strchange_instrms: u16, ++ pub strchange_outstrms: u16, ++ } + } + + s_no_extra_traits! { +@@ -201,229 +1380,1225 @@ s_no_extra_traits! { + __unused1: ::c_int, + __unused2: [::c_long; 7] + } +-} + +-cfg_if! { +- if #[cfg(feature = "extra_traits")] { +- impl PartialEq for utmpx { +- fn eq(&self, other: &utmpx) -> bool { +- self.ut_type == other.ut_type +- && self.ut_tv == other.ut_tv +- && self.ut_id == other.ut_id +- && self.ut_pid == other.ut_pid +- && self.ut_user == other.ut_user +- && self.ut_line == other.ut_line +- && self +- .ut_host +- .iter() +- .zip(other.ut_host.iter()) +- .all(|(a,b)| a == b) +- && self +- .__ut_spare +- .iter() +- .zip(other.__ut_spare.iter()) +- .all(|(a,b)| a == b) ++ pub struct ptsstat { ++ #[cfg(any(freebsd12, freebsd13, freebsd14))] ++ pub dev: u64, ++ #[cfg(not(any(freebsd12, freebsd13, freebsd14)))] ++ pub dev: u32, ++ pub devname: [::c_char; SPECNAMELEN as usize + 1], ++ } ++ ++ #[cfg(libc_union)] ++ pub union __c_anonymous_elf32_auxv_union { ++ pub a_val: ::c_int, ++ } ++ ++ pub struct Elf32_Auxinfo { ++ pub a_type: ::c_int, ++ #[cfg(libc_union)] ++ pub a_un: __c_anonymous_elf32_auxv_union, ++ } ++ ++ #[cfg(libc_union)] ++ pub union __c_anonymous_ifi_epoch { ++ pub tt: ::time_t, ++ pub ph: u64, ++ } ++ ++ #[cfg(libc_union)] ++ pub union __c_anonymous_ifi_lastchange { ++ pub tv: ::timeval, ++ pub ph: __c_anonymous_ph, ++ } ++ ++ pub struct if_data { ++ /// ethernet, tokenring, etc ++ pub ifi_type: u8, ++ /// e.g., AUI, Thinnet, 10base-T, etc ++ pub ifi_physical: u8, ++ /// media address length ++ pub ifi_addrlen: u8, ++ /// media header length ++ pub ifi_hdrlen: u8, ++ /// current link state ++ pub ifi_link_state: u8, ++ /// carp vhid ++ pub ifi_vhid: u8, ++ /// length of this data struct ++ pub ifi_datalen: u16, ++ /// maximum transmission unit ++ pub ifi_mtu: u32, ++ /// routing metric (external only) ++ pub ifi_metric: u32, ++ /// linespeed ++ pub ifi_baudrate: u64, ++ /// packets received on interface ++ pub ifi_ipackets: u64, ++ /// input errors on interface ++ pub ifi_ierrors: u64, ++ /// packets sent on interface ++ pub ifi_opackets: u64, ++ /// output errors on interface ++ pub ifi_oerrors: u64, ++ /// collisions on csma interfaces ++ pub ifi_collisions: u64, ++ /// total number of octets received ++ pub ifi_ibytes: u64, ++ /// total number of octets sent ++ pub ifi_obytes: u64, ++ /// packets received via multicast ++ pub ifi_imcasts: u64, ++ /// packets sent via multicast ++ pub ifi_omcasts: u64, ++ /// dropped on input ++ pub ifi_iqdrops: u64, ++ /// dropped on output ++ pub ifi_oqdrops: u64, ++ /// destined for unsupported protocol ++ pub ifi_noproto: u64, ++ /// HW offload capabilities, see IFCAP ++ pub ifi_hwassist: u64, ++ /// uptime at attach or stat reset ++ #[cfg(libc_union)] ++ pub __ifi_epoch: __c_anonymous_ifi_epoch, ++ /// uptime at attach or stat reset ++ #[cfg(not(libc_union))] ++ pub __ifi_epoch: u64, ++ /// time of last administrative change ++ #[cfg(libc_union)] ++ pub __ifi_lastchange: __c_anonymous_ifi_lastchange, ++ /// time of last administrative change ++ #[cfg(not(libc_union))] ++ pub __ifi_lastchange: ::timeval, ++ } ++ ++ #[cfg(libc_union)] ++ pub union __c_anonymous_ifr_ifru { ++ pub ifru_addr: ::sockaddr, ++ pub ifru_dstaddr: ::sockaddr, ++ pub ifru_broadaddr: ::sockaddr, ++ pub ifru_buffer: ifreq_buffer, ++ pub ifru_flags: [::c_short; 2], ++ pub ifru_index: ::c_short, ++ pub ifru_jid: ::c_int, ++ pub ifru_metric: ::c_int, ++ pub ifru_mtu: ::c_int, ++ pub ifru_phys: ::c_int, ++ pub ifru_media: ::c_int, ++ pub ifru_data: ::caddr_t, ++ pub ifru_cap: [::c_int; 2], ++ pub ifru_fib: ::c_uint, ++ pub ifru_vlan_pcp: ::c_uchar, ++ } ++ ++ pub struct ifreq { ++ /// if name, e.g. "en0" ++ pub ifr_name: [::c_char; ::IFNAMSIZ], ++ #[cfg(libc_union)] ++ pub ifr_ifru: __c_anonymous_ifr_ifru, ++ #[cfg(not(libc_union))] ++ pub ifr_ifru: ::sockaddr, ++ } ++ ++ #[cfg(libc_union)] ++ pub union __c_anonymous_ifc_ifcu { ++ pub ifcu_buf: ::caddr_t, ++ pub ifcu_req: *mut ifreq, ++ } ++ ++ pub struct ifstat { ++ /// if name, e.g. "en0" ++ pub ifs_name: [::c_char; ::IFNAMSIZ as usize], ++ pub ascii: [::c_char; ::IFSTATMAX as usize + 1], ++ } ++ ++ pub struct ifrsskey { ++ /// if name, e.g. "en0" ++ pub ifrk_name: [::c_char; ::IFNAMSIZ as usize], ++ /// RSS_FUNC_ ++ pub ifrk_func: u8, ++ pub ifrk_spare0: u8, ++ pub ifrk_keylen: u16, ++ pub ifrk_key: [u8; ::RSS_KEYLEN as usize], ++ } ++ ++ pub struct ifdownreason { ++ pub ifdr_name: [::c_char; ::IFNAMSIZ as usize], ++ pub ifdr_reason: u32, ++ pub ifdr_vendor: u32, ++ pub ifdr_msg: [::c_char; ::IFDR_MSG_SIZE as usize], ++ } ++ ++ #[repr(packed)] ++ pub struct sctphdr { ++ pub src_port: u16, ++ pub dest_port: u16, ++ pub v_tag: u32, ++ pub checksum: u32, ++ } ++ ++ #[repr(packed)] ++ pub struct sctp_chunkhdr { ++ pub chunk_type: u8, ++ pub chunk_flags: u8, ++ pub chunk_length: u16, ++ } ++ ++ #[repr(packed)] ++ pub struct sctp_paramhdr { ++ pub param_type: u16, ++ pub param_length: u16, ++ } ++ ++ #[repr(packed)] ++ pub struct sctp_gen_error_cause { ++ pub code: u16, ++ pub length: u16, ++ pub info: [u8; 0], ++ } ++ ++ #[repr(packed)] ++ pub struct sctp_error_cause { ++ pub code: u16, ++ pub length: u16, ++ } ++ ++ #[repr(packed)] ++ pub struct sctp_error_invalid_stream { ++ pub cause: sctp_error_cause, ++ pub stream_id: u16, ++ __reserved: u16, ++ } ++ ++ #[repr(packed)] ++ pub struct sctp_error_missing_param { ++ pub cause: sctp_error_cause, ++ pub num_missing_params: u32, ++ pub tpe: [u8; 0], ++ } ++ ++ #[repr(packed)] ++ pub struct sctp_error_stale_cookie { ++ pub cause: sctp_error_cause, ++ pub stale_time: u32, ++ } ++ ++ #[repr(packed)] ++ pub struct sctp_error_out_of_resource { ++ pub cause: sctp_error_cause, ++ } ++ ++ #[repr(packed)] ++ pub struct sctp_error_unresolv_addr { ++ pub cause: sctp_error_cause, ++ } ++ ++ #[repr(packed)] ++ pub struct sctp_error_unrecognized_chunk { ++ pub cause: sctp_error_cause, ++ pub ch: sctp_chunkhdr, ++ } ++ ++ #[repr(packed)] ++ pub struct sctp_error_no_user_data { ++ pub cause: sctp_error_cause, ++ pub tsn: u32, ++ } ++ ++ #[repr(packed)] ++ pub struct sctp_error_auth_invalid_hmac { ++ pub cause: sctp_error_cause, ++ pub hmac_id: u16, ++ } ++} ++ ++cfg_if! { ++ if #[cfg(feature = "extra_traits")] { ++ impl PartialEq for utmpx { ++ fn eq(&self, other: &utmpx) -> bool { ++ self.ut_type == other.ut_type ++ && self.ut_tv == other.ut_tv ++ && self.ut_id == other.ut_id ++ && self.ut_pid == other.ut_pid ++ && self.ut_user == other.ut_user ++ && self.ut_line == other.ut_line ++ && self ++ .ut_host ++ .iter() ++ .zip(other.ut_host.iter()) ++ .all(|(a,b)| a == b) ++ && self ++ .__ut_spare ++ .iter() ++ .zip(other.__ut_spare.iter()) ++ .all(|(a,b)| a == b) ++ } ++ } ++ impl Eq for utmpx {} ++ impl ::fmt::Debug for utmpx { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("utmpx") ++ .field("ut_type", &self.ut_type) ++ .field("ut_tv", &self.ut_tv) ++ .field("ut_id", &self.ut_id) ++ .field("ut_pid", &self.ut_pid) ++ .field("ut_user", &self.ut_user) ++ .field("ut_line", &self.ut_line) ++ // FIXME: .field("ut_host", &self.ut_host) ++ // FIXME: .field("__ut_spare", &self.__ut_spare) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for utmpx { ++ fn hash(&self, state: &mut H) { ++ self.ut_type.hash(state); ++ self.ut_tv.hash(state); ++ self.ut_id.hash(state); ++ self.ut_pid.hash(state); ++ self.ut_user.hash(state); ++ self.ut_line.hash(state); ++ self.ut_host.hash(state); ++ self.__ut_spare.hash(state); ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl PartialEq for __c_anonymous_cr_pid { ++ fn eq(&self, other: &__c_anonymous_cr_pid) -> bool { ++ unsafe { self.cr_pid == other.cr_pid} ++ } ++ } ++ #[cfg(libc_union)] ++ impl Eq for __c_anonymous_cr_pid {} ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for __c_anonymous_cr_pid { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("cr_pid") ++ .field("cr_pid", unsafe { &self.cr_pid }) ++ .finish() ++ } ++ } ++ #[cfg(libc_union)] ++ impl ::hash::Hash for __c_anonymous_cr_pid { ++ fn hash(&self, state: &mut H) { ++ unsafe { self.cr_pid.hash(state) }; ++ } ++ } ++ ++ impl PartialEq for xucred { ++ fn eq(&self, other: &xucred) -> bool { ++ #[cfg(libc_union)] ++ let equal_cr_pid = self.cr_pid__c_anonymous_union ++ == other.cr_pid__c_anonymous_union; ++ #[cfg(not(libc_union))] ++ let equal_cr_pid = self.__cr_unused1 == other.__cr_unused1; ++ ++ self.cr_version == other.cr_version ++ && self.cr_uid == other.cr_uid ++ && self.cr_ngroups == other.cr_ngroups ++ && self.cr_groups == other.cr_groups ++ && equal_cr_pid ++ } ++ } ++ impl Eq for xucred {} ++ impl ::fmt::Debug for xucred { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let mut struct_formatter = f.debug_struct("xucred"); ++ struct_formatter.field("cr_version", &self.cr_version); ++ struct_formatter.field("cr_uid", &self.cr_uid); ++ struct_formatter.field("cr_ngroups", &self.cr_ngroups); ++ struct_formatter.field("cr_groups", &self.cr_groups); ++ #[cfg(libc_union)] ++ struct_formatter.field( ++ "cr_pid__c_anonymous_union", ++ &self.cr_pid__c_anonymous_union ++ ); ++ struct_formatter.finish() ++ } ++ } ++ impl ::hash::Hash for xucred { ++ fn hash(&self, state: &mut H) { ++ self.cr_version.hash(state); ++ self.cr_uid.hash(state); ++ self.cr_ngroups.hash(state); ++ self.cr_groups.hash(state); ++ #[cfg(libc_union)] ++ self.cr_pid__c_anonymous_union.hash(state); ++ #[cfg(not(libc_union))] ++ self.__cr_unused1.hash(state); ++ } ++ } ++ ++ impl PartialEq for sockaddr_dl { ++ fn eq(&self, other: &sockaddr_dl) -> bool { ++ self.sdl_len == other.sdl_len ++ && self.sdl_family == other.sdl_family ++ && self.sdl_index == other.sdl_index ++ && self.sdl_type == other.sdl_type ++ && self.sdl_nlen == other.sdl_nlen ++ && self.sdl_alen == other.sdl_alen ++ && self.sdl_slen == other.sdl_slen ++ && self ++ .sdl_data ++ .iter() ++ .zip(other.sdl_data.iter()) ++ .all(|(a,b)| a == b) ++ } ++ } ++ impl Eq for sockaddr_dl {} ++ impl ::fmt::Debug for sockaddr_dl { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("sockaddr_dl") ++ .field("sdl_len", &self.sdl_len) ++ .field("sdl_family", &self.sdl_family) ++ .field("sdl_index", &self.sdl_index) ++ .field("sdl_type", &self.sdl_type) ++ .field("sdl_nlen", &self.sdl_nlen) ++ .field("sdl_alen", &self.sdl_alen) ++ .field("sdl_slen", &self.sdl_slen) ++ // FIXME: .field("sdl_data", &self.sdl_data) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for sockaddr_dl { ++ fn hash(&self, state: &mut H) { ++ self.sdl_len.hash(state); ++ self.sdl_family.hash(state); ++ self.sdl_index.hash(state); ++ self.sdl_type.hash(state); ++ self.sdl_nlen.hash(state); ++ self.sdl_alen.hash(state); ++ self.sdl_slen.hash(state); ++ self.sdl_data.hash(state); ++ } ++ } ++ ++ impl PartialEq for mq_attr { ++ fn eq(&self, other: &mq_attr) -> bool { ++ self.mq_flags == other.mq_flags && ++ self.mq_maxmsg == other.mq_maxmsg && ++ self.mq_msgsize == other.mq_msgsize && ++ self.mq_curmsgs == other.mq_curmsgs ++ } ++ } ++ impl Eq for mq_attr {} ++ impl ::fmt::Debug for mq_attr { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("mq_attr") ++ .field("mq_flags", &self.mq_flags) ++ .field("mq_maxmsg", &self.mq_maxmsg) ++ .field("mq_msgsize", &self.mq_msgsize) ++ .field("mq_curmsgs", &self.mq_curmsgs) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for mq_attr { ++ fn hash(&self, state: &mut H) { ++ self.mq_flags.hash(state); ++ self.mq_maxmsg.hash(state); ++ self.mq_msgsize.hash(state); ++ self.mq_curmsgs.hash(state); ++ } ++ } ++ ++ impl PartialEq for sigevent { ++ fn eq(&self, other: &sigevent) -> bool { ++ self.sigev_notify == other.sigev_notify ++ && self.sigev_signo == other.sigev_signo ++ && self.sigev_value == other.sigev_value ++ && self.sigev_notify_thread_id ++ == other.sigev_notify_thread_id ++ } ++ } ++ impl Eq for sigevent {} ++ impl ::fmt::Debug for sigevent { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("sigevent") ++ .field("sigev_notify", &self.sigev_notify) ++ .field("sigev_signo", &self.sigev_signo) ++ .field("sigev_value", &self.sigev_value) ++ .field("sigev_notify_thread_id", ++ &self.sigev_notify_thread_id) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for sigevent { ++ fn hash(&self, state: &mut H) { ++ self.sigev_notify.hash(state); ++ self.sigev_signo.hash(state); ++ self.sigev_value.hash(state); ++ self.sigev_notify_thread_id.hash(state); ++ } ++ } ++ ++ impl PartialEq for ptsstat { ++ fn eq(&self, other: &ptsstat) -> bool { ++ let self_devname: &[::c_char] = &self.devname; ++ let other_devname: &[::c_char] = &other.devname; ++ ++ self.dev == other.dev && self_devname == other_devname ++ } ++ } ++ impl Eq for ptsstat {} ++ impl ::fmt::Debug for ptsstat { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let self_devname: &[::c_char] = &self.devname; ++ ++ f.debug_struct("ptsstat") ++ .field("dev", &self.dev) ++ .field("devname", &self_devname) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for ptsstat { ++ fn hash(&self, state: &mut H) { ++ let self_devname: &[::c_char] = &self.devname; ++ ++ self.dev.hash(state); ++ self_devname.hash(state); ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl PartialEq for __c_anonymous_elf32_auxv_union { ++ fn eq(&self, other: &__c_anonymous_elf32_auxv_union) -> bool { ++ unsafe { self.a_val == other.a_val} ++ } ++ } ++ #[cfg(libc_union)] ++ impl Eq for __c_anonymous_elf32_auxv_union {} ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for __c_anonymous_elf32_auxv_union { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("a_val") ++ .field("a_val", unsafe { &self.a_val }) ++ .finish() ++ } ++ } ++ #[cfg(not(libc_union))] ++ impl PartialEq for Elf32_Auxinfo { ++ fn eq(&self, other: &Elf32_Auxinfo) -> bool { ++ self.a_type == other.a_type ++ } ++ } ++ #[cfg(libc_union)] ++ impl PartialEq for Elf32_Auxinfo { ++ fn eq(&self, other: &Elf32_Auxinfo) -> bool { ++ self.a_type == other.a_type ++ && self.a_un == other.a_un ++ } ++ } ++ impl Eq for Elf32_Auxinfo {} ++ #[cfg(not(libc_union))] ++ impl ::fmt::Debug for Elf32_Auxinfo { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("Elf32_Auxinfo") ++ .field("a_type", &self.a_type) ++ .finish() ++ } ++ } ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for Elf32_Auxinfo { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("Elf32_Auxinfo") ++ .field("a_type", &self.a_type) ++ .field("a_un", &self.a_un) ++ .finish() ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl PartialEq for __c_anonymous_ifr_ifru { ++ fn eq(&self, other: &__c_anonymous_ifr_ifru) -> bool { ++ unsafe { ++ self.ifru_addr == other.ifru_addr && ++ self.ifru_dstaddr == other.ifru_dstaddr && ++ self.ifru_broadaddr == other.ifru_broadaddr && ++ self.ifru_buffer == other.ifru_buffer && ++ self.ifru_flags == other.ifru_flags && ++ self.ifru_index == other.ifru_index && ++ self.ifru_jid == other.ifru_jid && ++ self.ifru_metric == other.ifru_metric && ++ self.ifru_mtu == other.ifru_mtu && ++ self.ifru_phys == other.ifru_phys && ++ self.ifru_media == other.ifru_media && ++ self.ifru_data == other.ifru_data && ++ self.ifru_cap == other.ifru_cap && ++ self.ifru_fib == other.ifru_fib && ++ self.ifru_vlan_pcp == other.ifru_vlan_pcp ++ } ++ } ++ } ++ #[cfg(libc_union)] ++ impl Eq for __c_anonymous_ifr_ifru {} ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for __c_anonymous_ifr_ifru { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("ifr_ifru") ++ .field("ifru_addr", unsafe { &self.ifru_addr }) ++ .field("ifru_dstaddr", unsafe { &self.ifru_dstaddr }) ++ .field("ifru_broadaddr", unsafe { &self.ifru_broadaddr }) ++ .field("ifru_buffer", unsafe { &self.ifru_buffer }) ++ .field("ifru_flags", unsafe { &self.ifru_flags }) ++ .field("ifru_index", unsafe { &self.ifru_index }) ++ .field("ifru_jid", unsafe { &self.ifru_jid }) ++ .field("ifru_metric", unsafe { &self.ifru_metric }) ++ .field("ifru_mtu", unsafe { &self.ifru_mtu }) ++ .field("ifru_phys", unsafe { &self.ifru_phys }) ++ .field("ifru_media", unsafe { &self.ifru_media }) ++ .field("ifru_data", unsafe { &self.ifru_data }) ++ .field("ifru_cap", unsafe { &self.ifru_cap }) ++ .field("ifru_fib", unsafe { &self.ifru_fib }) ++ .field("ifru_vlan_pcp", unsafe { &self.ifru_vlan_pcp }) ++ .finish() ++ } ++ } ++ #[cfg(libc_union)] ++ impl ::hash::Hash for __c_anonymous_ifr_ifru { ++ fn hash(&self, state: &mut H) { ++ unsafe { self.ifru_addr.hash(state) }; ++ unsafe { self.ifru_dstaddr.hash(state) }; ++ unsafe { self.ifru_broadaddr.hash(state) }; ++ unsafe { self.ifru_buffer.hash(state) }; ++ unsafe { self.ifru_flags.hash(state) }; ++ unsafe { self.ifru_index.hash(state) }; ++ unsafe { self.ifru_jid.hash(state) }; ++ unsafe { self.ifru_metric.hash(state) }; ++ unsafe { self.ifru_mtu.hash(state) }; ++ unsafe { self.ifru_phys.hash(state) }; ++ unsafe { self.ifru_media.hash(state) }; ++ unsafe { self.ifru_data.hash(state) }; ++ unsafe { self.ifru_cap.hash(state) }; ++ unsafe { self.ifru_fib.hash(state) }; ++ unsafe { self.ifru_vlan_pcp.hash(state) }; ++ } ++ } ++ ++ impl PartialEq for ifreq { ++ fn eq(&self, other: &ifreq) -> bool { ++ self.ifr_name == other.ifr_name && self.ifr_ifru == other.ifr_ifru ++ } ++ } ++ impl Eq for ifreq {} ++ impl ::fmt::Debug for ifreq { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("ifreq") ++ .field("ifr_name", &self.ifr_name) ++ .field("ifr_ifru", &self.ifr_ifru) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for ifreq { ++ fn hash(&self, state: &mut H) { ++ self.ifr_name.hash(state); ++ self.ifr_ifru.hash(state); ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl Eq for __c_anonymous_ifc_ifcu {} ++ ++ #[cfg(libc_union)] ++ impl PartialEq for __c_anonymous_ifc_ifcu { ++ fn eq(&self, other: &__c_anonymous_ifc_ifcu) -> bool { ++ unsafe { ++ self.ifcu_buf == other.ifcu_buf && ++ self.ifcu_req == other.ifcu_req ++ } ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for __c_anonymous_ifc_ifcu { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("ifc_ifcu") ++ .field("ifcu_buf", unsafe { &self.ifcu_buf }) ++ .field("ifcu_req", unsafe { &self.ifcu_req }) ++ .finish() ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl ::hash::Hash for __c_anonymous_ifc_ifcu { ++ fn hash(&self, state: &mut H) { ++ unsafe { self.ifcu_buf.hash(state) }; ++ unsafe { self.ifcu_req.hash(state) }; ++ } ++ } ++ ++ impl PartialEq for ifstat { ++ fn eq(&self, other: &ifstat) -> bool { ++ let self_ascii: &[::c_char] = &self.ascii; ++ let other_ascii: &[::c_char] = &other.ascii; ++ ++ self.ifs_name == other.ifs_name && self_ascii == other_ascii ++ } ++ } ++ impl Eq for ifstat {} ++ impl ::fmt::Debug for ifstat { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let ascii: &[::c_char] = &self.ascii; ++ ++ f.debug_struct("ifstat") ++ .field("ifs_name", &self.ifs_name) ++ .field("ascii", &ascii) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for ifstat { ++ fn hash(&self, state: &mut H) { ++ self.ifs_name.hash(state); ++ self.ascii.hash(state); ++ } ++ } ++ ++ impl PartialEq for ifrsskey { ++ fn eq(&self, other: &ifrsskey) -> bool { ++ let self_ifrk_key: &[u8] = &self.ifrk_key; ++ let other_ifrk_key: &[u8] = &other.ifrk_key; ++ ++ self.ifrk_name == other.ifrk_name && ++ self.ifrk_func == other.ifrk_func && ++ self.ifrk_spare0 == other.ifrk_spare0 && ++ self.ifrk_keylen == other.ifrk_keylen && ++ self_ifrk_key == other_ifrk_key ++ } ++ } ++ impl Eq for ifrsskey {} ++ impl ::fmt::Debug for ifrsskey { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let ifrk_key: &[u8] = &self.ifrk_key; ++ ++ f.debug_struct("ifrsskey") ++ .field("ifrk_name", &self.ifrk_name) ++ .field("ifrk_func", &self.ifrk_func) ++ .field("ifrk_spare0", &self.ifrk_spare0) ++ .field("ifrk_keylen", &self.ifrk_keylen) ++ .field("ifrk_key", &ifrk_key) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for ifrsskey { ++ fn hash(&self, state: &mut H) { ++ self.ifrk_name.hash(state); ++ self.ifrk_func.hash(state); ++ self.ifrk_spare0.hash(state); ++ self.ifrk_keylen.hash(state); ++ self.ifrk_key.hash(state); ++ } ++ } ++ ++ impl PartialEq for ifdownreason { ++ fn eq(&self, other: &ifdownreason) -> bool { ++ let self_ifdr_msg: &[::c_char] = &self.ifdr_msg; ++ let other_ifdr_msg: &[::c_char] = &other.ifdr_msg; ++ ++ self.ifdr_name == other.ifdr_name && ++ self.ifdr_reason == other.ifdr_reason && ++ self.ifdr_vendor == other.ifdr_vendor && ++ self_ifdr_msg == other_ifdr_msg ++ } ++ } ++ impl Eq for ifdownreason {} ++ impl ::fmt::Debug for ifdownreason { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ let ifdr_msg: &[::c_char] = &self.ifdr_msg; ++ ++ f.debug_struct("ifdownreason") ++ .field("ifdr_name", &self.ifdr_name) ++ .field("ifdr_reason", &self.ifdr_reason) ++ .field("ifdr_vendor", &self.ifdr_vendor) ++ .field("ifdr_msg", &ifdr_msg) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for ifdownreason { ++ fn hash(&self, state: &mut H) { ++ self.ifdr_name.hash(state); ++ self.ifdr_reason.hash(state); ++ self.ifdr_vendor.hash(state); ++ self.ifdr_msg.hash(state); ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl PartialEq for __c_anonymous_ifi_epoch { ++ fn eq(&self, other: &__c_anonymous_ifi_epoch) -> bool { ++ unsafe { ++ self.tt == other.tt && ++ self.ph == other.ph ++ } ++ } ++ } ++ #[cfg(libc_union)] ++ impl Eq for __c_anonymous_ifi_epoch {} ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for __c_anonymous_ifi_epoch { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("__c_anonymous_ifi_epoch") ++ .field("tt", unsafe { &self.tt }) ++ .field("ph", unsafe { &self.ph }) ++ .finish() ++ } ++ } ++ #[cfg(libc_union)] ++ impl ::hash::Hash for __c_anonymous_ifi_epoch { ++ fn hash(&self, state: &mut H) { ++ unsafe { ++ self.tt.hash(state); ++ self.ph.hash(state); ++ } ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl PartialEq for __c_anonymous_ifi_lastchange { ++ fn eq(&self, other: &__c_anonymous_ifi_lastchange) -> bool { ++ unsafe { ++ self.tv == other.tv && ++ self.ph == other.ph ++ } ++ } ++ } ++ #[cfg(libc_union)] ++ impl Eq for __c_anonymous_ifi_lastchange {} ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for __c_anonymous_ifi_lastchange { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("__c_anonymous_ifi_lastchange") ++ .field("tv", unsafe { &self.tv }) ++ .field("ph", unsafe { &self.ph }) ++ .finish() ++ } ++ } ++ #[cfg(libc_union)] ++ impl ::hash::Hash for __c_anonymous_ifi_lastchange { ++ fn hash(&self, state: &mut H) { ++ unsafe { ++ self.tv.hash(state); ++ self.ph.hash(state); ++ } ++ } ++ } ++ ++ impl PartialEq for if_data { ++ fn eq(&self, other: &if_data) -> bool { ++ self.ifi_type == other.ifi_type && ++ self.ifi_physical == other.ifi_physical && ++ self.ifi_addrlen == other.ifi_addrlen && ++ self.ifi_hdrlen == other.ifi_hdrlen && ++ self.ifi_link_state == other.ifi_link_state && ++ self.ifi_vhid == other.ifi_vhid && ++ self.ifi_datalen == other.ifi_datalen && ++ self.ifi_mtu == other.ifi_mtu && ++ self.ifi_metric == other.ifi_metric && ++ self.ifi_baudrate == other.ifi_baudrate && ++ self.ifi_ipackets == other.ifi_ipackets && ++ self.ifi_ierrors == other.ifi_ierrors && ++ self.ifi_opackets == other.ifi_opackets && ++ self.ifi_oerrors == other.ifi_oerrors && ++ self.ifi_collisions == other.ifi_collisions && ++ self.ifi_ibytes == other.ifi_ibytes && ++ self.ifi_obytes == other.ifi_obytes && ++ self.ifi_imcasts == other.ifi_imcasts && ++ self.ifi_omcasts == other.ifi_omcasts && ++ self.ifi_iqdrops == other.ifi_iqdrops && ++ self.ifi_oqdrops == other.ifi_oqdrops && ++ self.ifi_noproto == other.ifi_noproto && ++ self.ifi_hwassist == other.ifi_hwassist && ++ self.__ifi_epoch == other.__ifi_epoch && ++ self.__ifi_lastchange == other.__ifi_lastchange ++ } ++ } ++ impl Eq for if_data {} ++ impl ::fmt::Debug for if_data { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("if_data") ++ .field("ifi_type", &self.ifi_type) ++ .field("ifi_physical", &self.ifi_physical) ++ .field("ifi_addrlen", &self.ifi_addrlen) ++ .field("ifi_hdrlen", &self.ifi_hdrlen) ++ .field("ifi_link_state", &self.ifi_link_state) ++ .field("ifi_vhid", &self.ifi_vhid) ++ .field("ifi_datalen", &self.ifi_datalen) ++ .field("ifi_mtu", &self.ifi_mtu) ++ .field("ifi_metric", &self.ifi_metric) ++ .field("ifi_baudrate", &self.ifi_baudrate) ++ .field("ifi_ipackets", &self.ifi_ipackets) ++ .field("ifi_ierrors", &self.ifi_ierrors) ++ .field("ifi_opackets", &self.ifi_opackets) ++ .field("ifi_oerrors", &self.ifi_oerrors) ++ .field("ifi_collisions", &self.ifi_collisions) ++ .field("ifi_ibytes", &self.ifi_ibytes) ++ .field("ifi_obytes", &self.ifi_obytes) ++ .field("ifi_imcasts", &self.ifi_imcasts) ++ .field("ifi_omcasts", &self.ifi_omcasts) ++ .field("ifi_iqdrops", &self.ifi_iqdrops) ++ .field("ifi_oqdrops", &self.ifi_oqdrops) ++ .field("ifi_noproto", &self.ifi_noproto) ++ .field("ifi_hwassist", &self.ifi_hwassist) ++ .field("__ifi_epoch", &self.__ifi_epoch) ++ .field("__ifi_lastchange", &self.__ifi_lastchange) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for if_data { ++ fn hash(&self, state: &mut H) { ++ self.ifi_type.hash(state); ++ self.ifi_physical.hash(state); ++ self.ifi_addrlen.hash(state); ++ self.ifi_hdrlen.hash(state); ++ self.ifi_link_state.hash(state); ++ self.ifi_vhid.hash(state); ++ self.ifi_datalen.hash(state); ++ self.ifi_mtu.hash(state); ++ self.ifi_metric.hash(state); ++ self.ifi_baudrate.hash(state); ++ self.ifi_ipackets.hash(state); ++ self.ifi_ierrors.hash(state); ++ self.ifi_opackets.hash(state); ++ self.ifi_oerrors.hash(state); ++ self.ifi_collisions.hash(state); ++ self.ifi_ibytes.hash(state); ++ self.ifi_obytes.hash(state); ++ self.ifi_imcasts.hash(state); ++ self.ifi_omcasts.hash(state); ++ self.ifi_iqdrops.hash(state); ++ self.ifi_oqdrops.hash(state); ++ self.ifi_noproto.hash(state); ++ self.ifi_hwassist.hash(state); ++ self.__ifi_epoch.hash(state); ++ self.__ifi_lastchange.hash(state); ++ } ++ } ++ ++ impl PartialEq for sctphdr { ++ fn eq(&self, other: &sctphdr) -> bool { ++ return {self.src_port} == {other.src_port} && ++ {self.dest_port} == {other.dest_port} && ++ {self.v_tag} == {other.v_tag} && ++ {self.checksum} == {other.checksum} ++ } ++ } ++ impl Eq for sctphdr {} ++ impl ::fmt::Debug for sctphdr { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("sctphdr") ++ .field("src_port", &{self.src_port}) ++ .field("dest_port", &{self.dest_port}) ++ .field("v_tag", &{self.v_tag}) ++ .field("checksum", &{self.checksum}) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for sctphdr { ++ fn hash(&self, state: &mut H) { ++ {self.src_port}.hash(state); ++ {self.dest_port}.hash(state); ++ {self.v_tag}.hash(state); ++ {self.checksum}.hash(state); ++ } ++ } ++ ++ impl PartialEq for sctp_chunkhdr { ++ fn eq(&self, other: &sctp_chunkhdr) -> bool { ++ return {self.chunk_type} == {other.chunk_type} && ++ {self.chunk_flags} == {other.chunk_flags} && ++ {self.chunk_length} == {other.chunk_length} ++ } ++ } ++ impl Eq for sctp_chunkhdr {} ++ impl ::fmt::Debug for sctp_chunkhdr { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("sctp_chunkhdr") ++ .field("chunk_type", &{self.chunk_type}) ++ .field("chunk_flags", &{self.chunk_flags}) ++ .field("chunk_length", &{self.chunk_length}) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for sctp_chunkhdr { ++ fn hash(&self, state: &mut H) { ++ {self.chunk_type}.hash(state); ++ {self.chunk_flags}.hash(state); ++ {self.chunk_length}.hash(state); ++ } ++ } ++ ++ impl PartialEq for sctp_paramhdr { ++ fn eq(&self, other: &sctp_paramhdr) -> bool { ++ return {self.param_type} == {other.param_type} && ++ {self.param_length} == {other.param_length} ++ } ++ } ++ impl Eq for sctp_paramhdr {} ++ impl ::fmt::Debug for sctp_paramhdr { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("sctp_paramhdr") ++ .field("param_type", &{self.param_type}) ++ .field("param_length", &{self.param_length}) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for sctp_paramhdr { ++ fn hash(&self, state: &mut H) { ++ {self.param_type}.hash(state); ++ {self.param_length}.hash(state); ++ } ++ } ++ ++ impl PartialEq for sctp_gen_error_cause { ++ fn eq(&self, other: &sctp_gen_error_cause) -> bool { ++ return {self.code} == {other.code} && ++ {self.length} == {other.length} && ++ {self.info}.iter().zip({other.info}.iter()).all(|(a,b)| a == b) ++ } ++ } ++ impl Eq for sctp_gen_error_cause {} ++ impl ::fmt::Debug for sctp_gen_error_cause { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("sctp_gen_error_cause") ++ .field("code", &{self.code}) ++ .field("length", &{self.length}) ++ // FIXME: .field("info", &{self.info}) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for sctp_gen_error_cause { ++ fn hash(&self, state: &mut H) { ++ {self.code}.hash(state); ++ {self.length}.hash(state); ++ {self.info}.hash(state); ++ } ++ } ++ ++ impl PartialEq for sctp_error_cause { ++ fn eq(&self, other: &sctp_error_cause) -> bool { ++ return {self.code} == {other.code} && ++ {self.length} == {other.length} ++ } ++ } ++ impl Eq for sctp_error_cause {} ++ impl ::fmt::Debug for sctp_error_cause { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("sctp_error_cause") ++ .field("code", &{self.code}) ++ .field("length", &{self.length}) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for sctp_error_cause { ++ fn hash(&self, state: &mut H) { ++ {self.code}.hash(state); ++ {self.length}.hash(state); ++ } ++ } ++ ++ impl PartialEq for sctp_error_invalid_stream { ++ fn eq(&self, other: &sctp_error_invalid_stream) -> bool { ++ return {self.cause} == {other.cause} && ++ {self.stream_id} == {other.stream_id} ++ } ++ } ++ impl Eq for sctp_error_invalid_stream {} ++ impl ::fmt::Debug for sctp_error_invalid_stream { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("sctp_error_invalid_stream") ++ .field("cause", &{self.cause}) ++ .field("stream_id", &{self.stream_id}) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for sctp_error_invalid_stream { ++ fn hash(&self, state: &mut H) { ++ {self.cause}.hash(state); ++ {self.stream_id}.hash(state); ++ } ++ } ++ ++ impl PartialEq for sctp_error_missing_param { ++ fn eq(&self, other: &sctp_error_missing_param) -> bool { ++ return {self.cause} == {other.cause} && ++ {self.num_missing_params} == {other.num_missing_params} && ++ {self.tpe}.iter().zip({other.tpe}.iter()).all(|(a,b)| a == b) + } + } +- impl Eq for utmpx {} +- impl ::fmt::Debug for utmpx { ++ impl Eq for sctp_error_missing_param {} ++ impl ::fmt::Debug for sctp_error_missing_param { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { +- f.debug_struct("utmpx") +- .field("ut_type", &self.ut_type) +- .field("ut_tv", &self.ut_tv) +- .field("ut_id", &self.ut_id) +- .field("ut_pid", &self.ut_pid) +- .field("ut_user", &self.ut_user) +- .field("ut_line", &self.ut_line) +- // FIXME: .field("ut_host", &self.ut_host) +- // FIXME: .field("__ut_spare", &self.__ut_spare) ++ f.debug_struct("sctp_error_missing_param") ++ .field("cause", &{self.cause}) ++ .field("num_missing_params", &{self.num_missing_params}) ++ // FIXME: .field("tpe", &{self.tpe}) + .finish() + } + } +- impl ::hash::Hash for utmpx { ++ impl ::hash::Hash for sctp_error_missing_param { + fn hash(&self, state: &mut H) { +- self.ut_type.hash(state); +- self.ut_tv.hash(state); +- self.ut_id.hash(state); +- self.ut_pid.hash(state); +- self.ut_user.hash(state); +- self.ut_line.hash(state); +- self.ut_host.hash(state); +- self.__ut_spare.hash(state); ++ {self.cause}.hash(state); ++ {self.num_missing_params}.hash(state); ++ {self.tpe}.hash(state); + } + } + +- #[cfg(libc_union)] +- impl PartialEq for __c_anonymous_cr_pid { +- fn eq(&self, other: &__c_anonymous_cr_pid) -> bool { +- unsafe { self.cr_pid == other.cr_pid} ++ impl PartialEq for sctp_error_stale_cookie { ++ fn eq(&self, other: &sctp_error_stale_cookie) -> bool { ++ return {self.cause} == {other.cause} && ++ {self.stale_time} == {other.stale_time} + } + } +- #[cfg(libc_union)] +- impl Eq for __c_anonymous_cr_pid {} +- #[cfg(libc_union)] +- impl ::fmt::Debug for __c_anonymous_cr_pid { ++ impl Eq for sctp_error_stale_cookie {} ++ impl ::fmt::Debug for sctp_error_stale_cookie { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { +- f.debug_struct("cr_pid") +- .field("cr_pid", unsafe { &self.cr_pid }) ++ f.debug_struct("sctp_error_stale_cookie") ++ .field("cause", &{self.cause}) ++ .field("stale_time", &{self.stale_time}) + .finish() + } + } +- #[cfg(libc_union)] +- impl ::hash::Hash for __c_anonymous_cr_pid { ++ impl ::hash::Hash for sctp_error_stale_cookie { + fn hash(&self, state: &mut H) { +- unsafe { self.cr_pid.hash(state) }; ++ {self.cause}.hash(state); ++ {self.stale_time}.hash(state); + } + } + +- impl PartialEq for xucred { +- fn eq(&self, other: &xucred) -> bool { +- #[cfg(libc_union)] +- let equal_cr_pid = self.cr_pid__c_anonymous_union +- == other.cr_pid__c_anonymous_union; +- #[cfg(not(libc_union))] +- let equal_cr_pid = self.__cr_unused1 == other.__cr_unused1; ++ impl PartialEq for sctp_error_out_of_resource { ++ fn eq(&self, other: &sctp_error_out_of_resource) -> bool { ++ return {self.cause} == {other.cause} ++ } ++ } ++ impl Eq for sctp_error_out_of_resource {} ++ impl ::fmt::Debug for sctp_error_out_of_resource { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("sctp_error_out_of_resource") ++ .field("cause", &{self.cause}) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for sctp_error_out_of_resource { ++ fn hash(&self, state: &mut H) { ++ {self.cause}.hash(state); ++ } ++ } + +- self.cr_version == other.cr_version +- && self.cr_uid == other.cr_uid +- && self.cr_ngroups == other.cr_ngroups +- && self.cr_groups == other.cr_groups +- && equal_cr_pid ++ impl PartialEq for sctp_error_unresolv_addr { ++ fn eq(&self, other: &sctp_error_unresolv_addr) -> bool { ++ return {self.cause} == {other.cause} + } + } +- impl Eq for xucred {} +- impl ::fmt::Debug for xucred { ++ impl Eq for sctp_error_unresolv_addr {} ++ impl ::fmt::Debug for sctp_error_unresolv_addr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { +- let mut struct_formatter = f.debug_struct("xucred"); +- struct_formatter.field("cr_version", &self.cr_version); +- struct_formatter.field("cr_uid", &self.cr_uid); +- struct_formatter.field("cr_ngroups", &self.cr_ngroups); +- struct_formatter.field("cr_groups", &self.cr_groups); +- #[cfg(libc_union)] +- struct_formatter.field( +- "cr_pid__c_anonymous_union", +- &self.cr_pid__c_anonymous_union +- ); +- struct_formatter.finish() ++ f.debug_struct("sctp_error_unresolv_addr") ++ .field("cause", &{self.cause}) ++ .finish() + } + } +- impl ::hash::Hash for xucred { ++ impl ::hash::Hash for sctp_error_unresolv_addr { + fn hash(&self, state: &mut H) { +- self.cr_version.hash(state); +- self.cr_uid.hash(state); +- self.cr_ngroups.hash(state); +- self.cr_groups.hash(state); +- #[cfg(libc_union)] +- self.cr_pid__c_anonymous_union.hash(state); +- #[cfg(not(libc_union))] +- self.__cr_unused1.hash(state); ++ {self.cause}.hash(state); + } + } + +- impl PartialEq for sockaddr_dl { +- fn eq(&self, other: &sockaddr_dl) -> bool { +- self.sdl_len == other.sdl_len +- && self.sdl_family == other.sdl_family +- && self.sdl_index == other.sdl_index +- && self.sdl_type == other.sdl_type +- && self.sdl_nlen == other.sdl_nlen +- && self.sdl_alen == other.sdl_alen +- && self.sdl_slen == other.sdl_slen +- && self +- .sdl_data +- .iter() +- .zip(other.sdl_data.iter()) +- .all(|(a,b)| a == b) ++ impl PartialEq for sctp_error_unrecognized_chunk { ++ fn eq(&self, other: &sctp_error_unrecognized_chunk) -> bool { ++ return {self.cause} == {other.cause} && ++ {self.ch} == {other.ch} + } + } +- impl Eq for sockaddr_dl {} +- impl ::fmt::Debug for sockaddr_dl { ++ impl Eq for sctp_error_unrecognized_chunk {} ++ impl ::fmt::Debug for sctp_error_unrecognized_chunk { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { +- f.debug_struct("sockaddr_dl") +- .field("sdl_len", &self.sdl_len) +- .field("sdl_family", &self.sdl_family) +- .field("sdl_index", &self.sdl_index) +- .field("sdl_type", &self.sdl_type) +- .field("sdl_nlen", &self.sdl_nlen) +- .field("sdl_alen", &self.sdl_alen) +- .field("sdl_slen", &self.sdl_slen) +- // FIXME: .field("sdl_data", &self.sdl_data) ++ f.debug_struct("sctp_error_unrecognized_chunk") ++ .field("cause", &{self.cause}) ++ .field("ch", &{self.ch}) + .finish() + } + } +- impl ::hash::Hash for sockaddr_dl { ++ impl ::hash::Hash for sctp_error_unrecognized_chunk { + fn hash(&self, state: &mut H) { +- self.sdl_len.hash(state); +- self.sdl_family.hash(state); +- self.sdl_index.hash(state); +- self.sdl_type.hash(state); +- self.sdl_nlen.hash(state); +- self.sdl_alen.hash(state); +- self.sdl_slen.hash(state); +- self.sdl_data.hash(state); ++ {self.cause}.hash(state); ++ {self.ch}.hash(state); + } + } + +- impl PartialEq for mq_attr { +- fn eq(&self, other: &mq_attr) -> bool { +- self.mq_flags == other.mq_flags && +- self.mq_maxmsg == other.mq_maxmsg && +- self.mq_msgsize == other.mq_msgsize && +- self.mq_curmsgs == other.mq_curmsgs ++ impl PartialEq for sctp_error_no_user_data { ++ fn eq(&self, other: &sctp_error_no_user_data) -> bool { ++ return {self.cause} == {other.cause} && ++ {self.tsn} == {other.tsn} + } + } +- impl Eq for mq_attr {} +- impl ::fmt::Debug for mq_attr { ++ impl Eq for sctp_error_no_user_data {} ++ impl ::fmt::Debug for sctp_error_no_user_data { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { +- f.debug_struct("mq_attr") +- .field("mq_flags", &self.mq_flags) +- .field("mq_maxmsg", &self.mq_maxmsg) +- .field("mq_msgsize", &self.mq_msgsize) +- .field("mq_curmsgs", &self.mq_curmsgs) ++ f.debug_struct("sctp_error_no_user_data") ++ .field("cause", &{self.cause}) ++ .field("tsn", &{self.tsn}) + .finish() + } + } +- impl ::hash::Hash for mq_attr { ++ impl ::hash::Hash for sctp_error_no_user_data { + fn hash(&self, state: &mut H) { +- self.mq_flags.hash(state); +- self.mq_maxmsg.hash(state); +- self.mq_msgsize.hash(state); +- self.mq_curmsgs.hash(state); ++ {self.cause}.hash(state); ++ {self.tsn}.hash(state); + } + } + +- impl PartialEq for sigevent { +- fn eq(&self, other: &sigevent) -> bool { +- self.sigev_notify == other.sigev_notify +- && self.sigev_signo == other.sigev_signo +- && self.sigev_value == other.sigev_value +- && self.sigev_notify_thread_id +- == other.sigev_notify_thread_id ++ impl PartialEq for sctp_error_auth_invalid_hmac { ++ fn eq(&self, other: &sctp_error_auth_invalid_hmac) -> bool { ++ return {self.cause} == {other.cause} && ++ {self.hmac_id} == {other.hmac_id} + } + } +- impl Eq for sigevent {} +- impl ::fmt::Debug for sigevent { ++ impl Eq for sctp_error_auth_invalid_hmac {} ++ impl ::fmt::Debug for sctp_error_auth_invalid_hmac { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { +- f.debug_struct("sigevent") +- .field("sigev_notify", &self.sigev_notify) +- .field("sigev_signo", &self.sigev_signo) +- .field("sigev_value", &self.sigev_value) +- .field("sigev_notify_thread_id", +- &self.sigev_notify_thread_id) ++ f.debug_struct("sctp_error_invalid_hmac") ++ .field("cause", &{self.cause}) ++ .field("hmac_id", &{self.hmac_id}) + .finish() + } + } +- impl ::hash::Hash for sigevent { ++ impl ::hash::Hash for sctp_error_auth_invalid_hmac { + fn hash(&self, state: &mut H) { +- self.sigev_notify.hash(state); +- self.sigev_signo.hash(state); +- self.sigev_value.hash(state); +- self.sigev_notify_thread_id.hash(state); ++ {self.cause}.hash(state); ++ {self.hmac_id}.hash(state); + } + } + } + } + ++#[cfg_attr(feature = "extra_traits", derive(Debug))] ++#[repr(u32)] ++pub enum dot3Vendors { ++ dot3VendorAMD = 1, ++ dot3VendorIntel = 2, ++ dot3VendorNational = 4, ++ dot3VendorFujitsu = 5, ++ dot3VendorDigital = 6, ++ dot3VendorWesternDigital = 7, ++} ++impl ::Copy for dot3Vendors {} ++impl ::Clone for dot3Vendors { ++ fn clone(&self) -> dot3Vendors { ++ *self ++ } ++} ++ ++// aio.h ++pub const LIO_VECTORED: ::c_int = 4; ++pub const LIO_WRITEV: ::c_int = 5; ++pub const LIO_READV: ::c_int = 6; ++ ++// sys/devicestat.h ++pub const DEVSTAT_N_TRANS_FLAGS: ::c_int = 4; ++pub const DEVSTAT_NAME_LEN: ::c_int = 16; ++ ++// sys/cpuset.h ++pub const CPU_SETSIZE: ::c_int = 256; ++ + pub const SIGEV_THREAD_ID: ::c_int = 4; + + pub const EXTATTR_NAMESPACE_EMPTY: ::c_int = 0; +@@ -432,6 +2607,8 @@ pub const EXTATTR_NAMESPACE_SYSTEM: ::c_int = 2; + + pub const PTHREAD_STACK_MIN: ::size_t = MINSIGSTKSZ; + pub const PTHREAD_MUTEX_ADAPTIVE_NP: ::c_int = 4; ++pub const PTHREAD_MUTEX_STALLED: ::c_int = 0; ++pub const PTHREAD_MUTEX_ROBUST: ::c_int = 1; + pub const SIGSTKSZ: ::size_t = MINSIGSTKSZ + 32768; + pub const SF_NODISKIO: ::c_int = 0x00000001; + pub const SF_MNOWAIT: ::c_int = 0x00000002; +@@ -440,8 +2617,14 @@ pub const SF_USER_READAHEAD: ::c_int = 0x00000008; + pub const SF_NOCACHE: ::c_int = 0x00000010; + pub const O_CLOEXEC: ::c_int = 0x00100000; + pub const O_DIRECTORY: ::c_int = 0x00020000; ++pub const O_DSYNC: ::c_int = 0x01000000; ++pub const O_EMPTY_PATH: ::c_int = 0x02000000; + pub const O_EXEC: ::c_int = 0x00040000; ++pub const O_PATH: ::c_int = 0x00400000; ++pub const O_RESOLVE_BENEATH: ::c_int = 0x00800000; ++pub const O_SEARCH: ::c_int = O_EXEC; + pub const O_TTY_INIT: ::c_int = 0x00080000; ++pub const O_VERIFY: ::c_int = 0x00200000; + pub const F_GETLK: ::c_int = 11; + pub const F_SETLK: ::c_int = 12; + pub const F_SETLKW: ::c_int = 13; +@@ -449,12 +2632,22 @@ pub const ENOTCAPABLE: ::c_int = 93; + pub const ECAPMODE: ::c_int = 94; + pub const ENOTRECOVERABLE: ::c_int = 95; + pub const EOWNERDEAD: ::c_int = 96; ++pub const EINTEGRITY: ::c_int = 97; + pub const RLIMIT_NPTS: ::c_int = 11; + pub const RLIMIT_SWAP: ::c_int = 12; + pub const RLIMIT_KQUEUES: ::c_int = 13; + pub const RLIMIT_UMTXP: ::c_int = 14; + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIM_NLIMITS: ::rlim_t = 15; ++pub const RLIM_SAVED_MAX: ::rlim_t = ::RLIM_INFINITY; ++pub const RLIM_SAVED_CUR: ::rlim_t = ::RLIM_INFINITY; ++ ++pub const CP_USER: ::c_int = 0; ++pub const CP_NICE: ::c_int = 1; ++pub const CP_SYS: ::c_int = 2; ++pub const CP_INTR: ::c_int = 3; ++pub const CP_IDLE: ::c_int = 4; ++pub const CPUSTATES: ::c_int = 5; + + pub const NI_NOFQDN: ::c_int = 0x00000001; + pub const NI_NUMERICHOST: ::c_int = 0x00000002; +@@ -463,10 +2656,14 @@ pub const NI_NUMERICSERV: ::c_int = 0x00000008; + pub const NI_DGRAM: ::c_int = 0x00000010; + pub const NI_NUMERICSCOPE: ::c_int = 0x00000020; + ++pub const XU_NGROUPS: ::c_int = 16; ++ + pub const Q_GETQUOTA: ::c_int = 0x700; + pub const Q_SETQUOTA: ::c_int = 0x800; + + pub const MAP_GUARD: ::c_int = 0x00002000; ++pub const MAP_EXCL: ::c_int = 0x00004000; ++pub const MAP_PREFAULT_READ: ::c_int = 0x00040000; + pub const MAP_ALIGNED_SUPER: ::c_int = 1 << 24; + + pub const POSIX_FADV_NORMAL: ::c_int = 0; +@@ -496,15 +2693,20 @@ pub const EV_ADD: u16 = 0x1; + pub const EV_DELETE: u16 = 0x2; + pub const EV_ENABLE: u16 = 0x4; + pub const EV_DISABLE: u16 = 0x8; ++pub const EV_FORCEONESHOT: u16 = 0x100; ++pub const EV_KEEPUDATA: u16 = 0x200; ++ + pub const EV_ONESHOT: u16 = 0x10; + pub const EV_CLEAR: u16 = 0x20; + pub const EV_RECEIPT: u16 = 0x40; + pub const EV_DISPATCH: u16 = 0x80; ++pub const EV_SYSFLAGS: u16 = 0xf000; + pub const EV_DROP: u16 = 0x1000; + pub const EV_FLAG1: u16 = 0x2000; +-pub const EV_ERROR: u16 = 0x4000; ++pub const EV_FLAG2: u16 = 0x4000; ++ + pub const EV_EOF: u16 = 0x8000; +-pub const EV_SYSFLAGS: u16 = 0xf000; ++pub const EV_ERROR: u16 = 0x4000; + + pub const NOTE_TRIGGER: u32 = 0x01000000; + pub const NOTE_FFNOP: u32 = 0x00000000; +@@ -514,6 +2716,7 @@ pub const NOTE_FFCOPY: u32 = 0xc0000000; + pub const NOTE_FFCTRLMASK: u32 = 0xc0000000; + pub const NOTE_FFLAGSMASK: u32 = 0x00ffffff; + pub const NOTE_LOWAT: u32 = 0x00000001; ++pub const NOTE_FILE_POLL: u32 = 0x00000002; + pub const NOTE_DELETE: u32 = 0x00000001; + pub const NOTE_WRITE: u32 = 0x00000002; + pub const NOTE_EXTEND: u32 = 0x00000004; +@@ -521,6 +2724,10 @@ pub const NOTE_ATTRIB: u32 = 0x00000008; + pub const NOTE_LINK: u32 = 0x00000010; + pub const NOTE_RENAME: u32 = 0x00000020; + pub const NOTE_REVOKE: u32 = 0x00000040; ++pub const NOTE_OPEN: u32 = 0x00000080; ++pub const NOTE_CLOSE: u32 = 0x00000100; ++pub const NOTE_CLOSE_WRITE: u32 = 0x00000200; ++pub const NOTE_READ: u32 = 0x00000400; + pub const NOTE_EXIT: u32 = 0x80000000; + pub const NOTE_FORK: u32 = 0x40000000; + pub const NOTE_EXEC: u32 = 0x20000000; +@@ -533,9 +2740,9 @@ pub const NOTE_SECONDS: u32 = 0x00000001; + pub const NOTE_MSECONDS: u32 = 0x00000002; + pub const NOTE_USECONDS: u32 = 0x00000004; + pub const NOTE_NSECONDS: u32 = 0x00000008; ++pub const NOTE_ABSTIME: u32 = 0x00000010; + + pub const MADV_PROTECT: ::c_int = 10; +-pub const RUSAGE_THREAD: ::c_int = 1; + + #[doc(hidden)] + #[deprecated( +@@ -553,6 +2760,58 @@ pub const CTL_HW: ::c_int = 6; + pub const CTL_MACHDEP: ::c_int = 7; + pub const CTL_USER: ::c_int = 8; + pub const CTL_P1003_1B: ::c_int = 9; ++ ++// sys/sysctl.h ++pub const CTL_MAXNAME: ::c_int = 24; ++ ++pub const CTLTYPE: ::c_int = 0xf; ++pub const CTLTYPE_NODE: ::c_int = 1; ++pub const CTLTYPE_INT: ::c_int = 2; ++pub const CTLTYPE_STRING: ::c_int = 3; ++pub const CTLTYPE_S64: ::c_int = 4; ++pub const CTLTYPE_OPAQUE: ::c_int = 5; ++pub const CTLTYPE_STRUCT: ::c_int = CTLTYPE_OPAQUE; ++pub const CTLTYPE_UINT: ::c_int = 6; ++pub const CTLTYPE_LONG: ::c_int = 7; ++pub const CTLTYPE_ULONG: ::c_int = 8; ++pub const CTLTYPE_U64: ::c_int = 9; ++pub const CTLTYPE_U8: ::c_int = 0xa; ++pub const CTLTYPE_U16: ::c_int = 0xb; ++pub const CTLTYPE_S8: ::c_int = 0xc; ++pub const CTLTYPE_S16: ::c_int = 0xd; ++pub const CTLTYPE_S32: ::c_int = 0xe; ++pub const CTLTYPE_U32: ::c_int = 0xf; ++ ++pub const CTLFLAG_RD: ::c_int = 0x80000000; ++pub const CTLFLAG_WR: ::c_int = 0x40000000; ++pub const CTLFLAG_RW: ::c_int = CTLFLAG_RD | CTLFLAG_WR; ++pub const CTLFLAG_DORMANT: ::c_int = 0x20000000; ++pub const CTLFLAG_ANYBODY: ::c_int = 0x10000000; ++pub const CTLFLAG_SECURE: ::c_int = 0x08000000; ++pub const CTLFLAG_PRISON: ::c_int = 0x04000000; ++pub const CTLFLAG_DYN: ::c_int = 0x02000000; ++pub const CTLFLAG_SKIP: ::c_int = 0x01000000; ++pub const CTLMASK_SECURE: ::c_int = 0x00F00000; ++pub const CTLFLAG_TUN: ::c_int = 0x00080000; ++pub const CTLFLAG_RDTUN: ::c_int = CTLFLAG_RD | CTLFLAG_TUN; ++pub const CTLFLAG_RWTUN: ::c_int = CTLFLAG_RW | CTLFLAG_TUN; ++pub const CTLFLAG_MPSAFE: ::c_int = 0x00040000; ++pub const CTLFLAG_VNET: ::c_int = 0x00020000; ++pub const CTLFLAG_DYING: ::c_int = 0x00010000; ++pub const CTLFLAG_CAPRD: ::c_int = 0x00008000; ++pub const CTLFLAG_CAPWR: ::c_int = 0x00004000; ++pub const CTLFLAG_STATS: ::c_int = 0x00002000; ++pub const CTLFLAG_NOFETCH: ::c_int = 0x00001000; ++pub const CTLFLAG_CAPRW: ::c_int = CTLFLAG_CAPRD | CTLFLAG_CAPWR; ++pub const CTLFLAG_NEEDGIANT: ::c_int = 0x00000800; ++ ++pub const CTLSHIFT_SECURE: ::c_int = 20; ++pub const CTLFLAG_SECURE1: ::c_int = CTLFLAG_SECURE | (0 << CTLSHIFT_SECURE); ++pub const CTLFLAG_SECURE2: ::c_int = CTLFLAG_SECURE | (1 << CTLSHIFT_SECURE); ++pub const CTLFLAG_SECURE3: ::c_int = CTLFLAG_SECURE | (2 << CTLSHIFT_SECURE); ++ ++pub const OID_AUTO: ::c_int = -1; ++ + pub const CTL_SYSCTL_DEBUG: ::c_int = 0; + pub const CTL_SYSCTL_NAME: ::c_int = 1; + pub const CTL_SYSCTL_NEXT: ::c_int = 2; +@@ -560,6 +2819,8 @@ pub const CTL_SYSCTL_NAME2OID: ::c_int = 3; + pub const CTL_SYSCTL_OIDFMT: ::c_int = 4; + pub const CTL_SYSCTL_OIDDESCR: ::c_int = 5; + pub const CTL_SYSCTL_OIDLABEL: ::c_int = 6; ++pub const CTL_SYSCTL_NEXTNOSKIP: ::c_int = 7; ++ + pub const KERN_OSTYPE: ::c_int = 1; + pub const KERN_OSRELEASE: ::c_int = 2; + pub const KERN_OSREV: ::c_int = 3; +@@ -597,6 +2858,8 @@ pub const KERN_LOGSIGEXIT: ::c_int = 34; + pub const KERN_IOV_MAX: ::c_int = 35; + pub const KERN_HOSTUUID: ::c_int = 36; + pub const KERN_ARND: ::c_int = 37; ++pub const KERN_MAXPHYS: ::c_int = 38; ++ + pub const KERN_PROC_ALL: ::c_int = 0; + pub const KERN_PROC_PID: ::c_int = 1; + pub const KERN_PROC_PGRP: ::c_int = 2; +@@ -624,6 +2887,10 @@ pub const KERN_PROC_PS_STRINGS: ::c_int = 38; + pub const KERN_PROC_UMASK: ::c_int = 39; + pub const KERN_PROC_OSREL: ::c_int = 40; + pub const KERN_PROC_SIGTRAMP: ::c_int = 41; ++pub const KERN_PROC_CWD: ::c_int = 42; ++pub const KERN_PROC_NFDS: ::c_int = 43; ++pub const KERN_PROC_SIGFASTBLK: ::c_int = 44; ++ + pub const KIPC_MAXSOCKBUF: ::c_int = 1; + pub const KIPC_SOCKBUF_WASTE: ::c_int = 2; + pub const KIPC_SOMAXCONN: ::c_int = 3; +@@ -631,6 +2898,7 @@ pub const KIPC_MAX_LINKHDR: ::c_int = 4; + pub const KIPC_MAX_PROTOHDR: ::c_int = 5; + pub const KIPC_MAX_HDR: ::c_int = 6; + pub const KIPC_MAX_DATALEN: ::c_int = 7; ++ + pub const HW_MACHINE: ::c_int = 1; + pub const HW_MODEL: ::c_int = 2; + pub const HW_NCPU: ::c_int = 3; +@@ -643,6 +2911,7 @@ pub const HW_DISKSTATS: ::c_int = 9; + pub const HW_FLOATINGPT: ::c_int = 10; + pub const HW_MACHINE_ARCH: ::c_int = 11; + pub const HW_REALMEM: ::c_int = 12; ++ + pub const USER_CS_PATH: ::c_int = 1; + pub const USER_BC_BASE_MAX: ::c_int = 2; + pub const USER_BC_DIM_MAX: ::c_int = 3; +@@ -663,6 +2932,8 @@ pub const USER_POSIX2_SW_DEV: ::c_int = 17; + pub const USER_POSIX2_UPE: ::c_int = 18; + pub const USER_STREAM_MAX: ::c_int = 19; + pub const USER_TZNAME_MAX: ::c_int = 20; ++pub const USER_LOCALBASE: ::c_int = 21; ++ + pub const CTL_P1003_1B_ASYNCHRONOUS_IO: ::c_int = 1; + pub const CTL_P1003_1B_MAPPED_FILES: ::c_int = 2; + pub const CTL_P1003_1B_MEMLOCK: ::c_int = 3; +@@ -688,18 +2959,23 @@ pub const CTL_P1003_1B_SEM_NSEMS_MAX: ::c_int = 22; + pub const CTL_P1003_1B_SEM_VALUE_MAX: ::c_int = 23; + pub const CTL_P1003_1B_SIGQUEUE_MAX: ::c_int = 24; + pub const CTL_P1003_1B_TIMER_MAX: ::c_int = 25; +-pub const TIOCGPTN: ::c_uint = 0x4004740f; +-pub const TIOCPTMASTER: ::c_uint = 0x2000741c; +-pub const TIOCSIG: ::c_uint = 0x2004745f; ++ ++pub const TIOCGPTN: ::c_ulong = 0x4004740f; ++pub const TIOCPTMASTER: ::c_ulong = 0x2000741c; ++pub const TIOCSIG: ::c_ulong = 0x2004745f; + pub const TIOCM_DCD: ::c_int = 0x40; + pub const H4DISC: ::c_int = 0x7; + ++pub const VM_TOTAL: ::c_int = 1; ++ + pub const BIOCSETFNR: ::c_ulong = 0x80104282; + ++pub const FIODGNAME: ::c_ulong = 0x80106678; + pub const FIONWRITE: ::c_ulong = 0x40046677; + pub const FIONSPACE: ::c_ulong = 0x40046676; + pub const FIOSEEKDATA: ::c_ulong = 0xc0086661; + pub const FIOSEEKHOLE: ::c_ulong = 0xc0086662; ++pub const FIOSSHMLPGCNF: ::c_ulong = 0x80306664; + + pub const JAIL_API_VERSION: u32 = 2; + pub const JAIL_CREATE: ::c_int = 0x01; +@@ -712,6 +2988,17 @@ pub const JAIL_SYS_DISABLE: ::c_int = 0; + pub const JAIL_SYS_NEW: ::c_int = 1; + pub const JAIL_SYS_INHERIT: ::c_int = 2; + ++pub const MNT_ACLS: ::c_int = 0x08000000; ++pub const MNT_BYFSID: ::c_int = 0x08000000; ++pub const MNT_GJOURNAL: ::c_int = 0x02000000; ++pub const MNT_MULTILABEL: ::c_int = 0x04000000; ++pub const MNT_NFS4ACLS: ::c_int = 0x00000010; ++pub const MNT_SNAPSHOT: ::c_int = 0x01000000; ++pub const MNT_UNION: ::c_int = 0x00000020; ++pub const MNT_NONBUSY: ::c_int = 0x04000000; ++ ++pub const SCM_CREDS2: ::c_int = 0x08; ++ + pub const SO_BINTIME: ::c_int = 0x2000; + pub const SO_NO_OFFLOAD: ::c_int = 0x4000; + pub const SO_NO_DDP: ::c_int = 0x8000; +@@ -725,12 +3012,37 @@ pub const SO_SETFIB: ::c_int = 0x1014; + pub const SO_USER_COOKIE: ::c_int = 0x1015; + pub const SO_PROTOCOL: ::c_int = 0x1016; + pub const SO_PROTOTYPE: ::c_int = SO_PROTOCOL; ++pub const SO_TS_CLOCK: ::c_int = 0x1017; ++pub const SO_DOMAIN: ::c_int = 0x1019; + pub const SO_VENDOR: ::c_int = 0x80000000; + ++pub const SO_TS_REALTIME_MICRO: ::c_int = 0; ++pub const SO_TS_BINTIME: ::c_int = 1; ++pub const SO_TS_REALTIME: ::c_int = 2; ++pub const SO_TS_MONOTONIC: ::c_int = 3; ++pub const SO_TS_DEFAULT: ::c_int = SO_TS_REALTIME_MICRO; ++pub const SO_TS_CLOCK_MAX: ::c_int = SO_TS_MONOTONIC; ++ + pub const LOCAL_CREDS: ::c_int = 2; ++pub const LOCAL_CREDS_PERSISTENT: ::c_int = 3; + pub const LOCAL_CONNWAIT: ::c_int = 4; + pub const LOCAL_VENDOR: ::c_int = SO_VENDOR; + ++pub const PL_EVENT_NONE: ::c_int = 0; ++pub const PL_EVENT_SIGNAL: ::c_int = 1; ++pub const PL_FLAG_SA: ::c_int = 0x01; ++pub const PL_FLAG_BOUND: ::c_int = 0x02; ++pub const PL_FLAG_SCE: ::c_int = 0x04; ++pub const PL_FLAG_SCX: ::c_int = 0x08; ++pub const PL_FLAG_EXEC: ::c_int = 0x10; ++pub const PL_FLAG_SI: ::c_int = 0x20; ++pub const PL_FLAG_FORKED: ::c_int = 0x40; ++pub const PL_FLAG_CHILD: ::c_int = 0x80; ++pub const PL_FLAG_BORN: ::c_int = 0x100; ++pub const PL_FLAG_EXITED: ::c_int = 0x200; ++pub const PL_FLAG_VFORKED: ::c_int = 0x400; ++pub const PL_FLAG_VFORK_DONE: ::c_int = 0x800; ++ + pub const PT_LWPINFO: ::c_int = 13; + pub const PT_GETNUMLWPS: ::c_int = 14; + pub const PT_GETLWPLIST: ::c_int = 15; +@@ -745,6 +3057,9 @@ pub const PT_FOLLOW_FORK: ::c_int = 23; + pub const PT_LWP_EVENTS: ::c_int = 24; + pub const PT_GET_EVENT_MASK: ::c_int = 25; + pub const PT_SET_EVENT_MASK: ::c_int = 26; ++pub const PT_GET_SC_ARGS: ::c_int = 27; ++pub const PT_GET_SC_RET: ::c_int = 28; ++pub const PT_COREDUMP: ::c_int = 29; + pub const PT_GETREGS: ::c_int = 33; + pub const PT_SETREGS: ::c_int = 34; + pub const PT_GETFPREGS: ::c_int = 35; +@@ -753,6 +3068,9 @@ pub const PT_GETDBREGS: ::c_int = 37; + pub const PT_SETDBREGS: ::c_int = 38; + pub const PT_VM_TIMESTAMP: ::c_int = 40; + pub const PT_VM_ENTRY: ::c_int = 41; ++pub const PT_GETREGSET: ::c_int = 42; ++pub const PT_SETREGSET: ::c_int = 43; ++pub const PT_SC_REMOTE: ::c_int = 44; + pub const PT_FIRSTMACH: ::c_int = 64; + + pub const PTRACE_EXEC: ::c_int = 0x0001; +@@ -764,48 +3082,289 @@ pub const PTRACE_LWP: ::c_int = 0x0010; + pub const PTRACE_VFORK: ::c_int = 0x0020; + pub const PTRACE_DEFAULT: ::c_int = PTRACE_EXEC; + +-pub const AF_SLOW: ::c_int = 33; +-pub const AF_SCLUSTER: ::c_int = 34; +-pub const AF_ARP: ::c_int = 35; +-pub const AF_BLUETOOTH: ::c_int = 36; +-pub const AF_IEEE80211: ::c_int = 37; +-pub const AF_INET_SDP: ::c_int = 40; +-pub const AF_INET6_SDP: ::c_int = 42; ++pub const PC_COMPRESS: u32 = 0x00000001; ++pub const PC_ALL: u32 = 0x00000002; ++ ++pub const PROC_SPROTECT: ::c_int = 1; ++pub const PROC_REAP_ACQUIRE: ::c_int = 2; ++pub const PROC_REAP_RELEASE: ::c_int = 3; ++pub const PROC_REAP_STATUS: ::c_int = 4; ++pub const PROC_REAP_GETPIDS: ::c_int = 5; ++pub const PROC_REAP_KILL: ::c_int = 6; ++pub const PROC_TRACE_CTL: ::c_int = 7; ++pub const PROC_TRACE_STATUS: ::c_int = 8; ++pub const PROC_TRAPCAP_CTL: ::c_int = 9; ++pub const PROC_TRAPCAP_STATUS: ::c_int = 10; ++pub const PROC_PDEATHSIG_CTL: ::c_int = 11; ++pub const PROC_PDEATHSIG_STATUS: ::c_int = 12; ++pub const PROC_ASLR_CTL: ::c_int = 13; ++pub const PROC_ASLR_STATUS: ::c_int = 14; ++pub const PROC_PROTMAX_CTL: ::c_int = 15; ++pub const PROC_PROTMAX_STATUS: ::c_int = 16; ++pub const PROC_STACKGAP_CTL: ::c_int = 17; ++pub const PROC_STACKGAP_STATUS: ::c_int = 18; ++pub const PROC_NO_NEW_PRIVS_CTL: ::c_int = 19; ++pub const PROC_NO_NEW_PRIVS_STATUS: ::c_int = 20; ++pub const PROC_WXMAP_CTL: ::c_int = 21; ++pub const PROC_WXMAP_STATUS: ::c_int = 22; ++pub const PROC_PROCCTL_MD_MIN: ::c_int = 0x10000000; ++ ++pub const PPROT_SET: ::c_int = 1; ++pub const PPROT_CLEAR: ::c_int = 2; ++pub const PPROT_DESCEND: ::c_int = 0x10; ++pub const PPROT_INHERIT: ::c_int = 0x20; ++ ++pub const PROC_TRACE_CTL_ENABLE: ::c_int = 1; ++pub const PROC_TRACE_CTL_DISABLE: ::c_int = 2; ++pub const PROC_TRACE_CTL_DISABLE_EXEC: ::c_int = 3; ++ ++pub const PROC_TRAPCAP_CTL_ENABLE: ::c_int = 1; ++pub const PROC_TRAPCAP_CTL_DISABLE: ::c_int = 2; ++ ++pub const PROC_ASLR_FORCE_ENABLE: ::c_int = 1; ++pub const PROC_ASLR_FORCE_DISABLE: ::c_int = 2; ++pub const PROC_ASLR_NOFORCE: ::c_int = 3; ++pub const PROC_ASLR_ACTIVE: ::c_int = 0x80000000; ++ ++pub const PROC_PROTMAX_FORCE_ENABLE: ::c_int = 1; ++pub const PROC_PROTMAX_FORCE_DISABLE: ::c_int = 2; ++pub const PROC_PROTMAX_NOFORCE: ::c_int = 3; ++pub const PROC_PROTMAX_ACTIVE: ::c_int = 0x80000000; ++ ++pub const PROC_STACKGAP_ENABLE: ::c_int = 0x0001; ++pub const PROC_STACKGAP_DISABLE: ::c_int = 0x0002; ++pub const PROC_STACKGAP_ENABLE_EXEC: ::c_int = 0x0004; ++pub const PROC_STACKGAP_DISABLE_EXEC: ::c_int = 0x0008; ++ ++pub const PROC_NO_NEW_PRIVS_ENABLE: ::c_int = 1; ++pub const PROC_NO_NEW_PRIVS_DISABLE: ::c_int = 2; ++ ++pub const PROC_WX_MAPPINGS_PERMIT: ::c_int = 0x0001; ++pub const PROC_WX_MAPPINGS_DISALLOW_EXEC: ::c_int = 0x0002; ++pub const PROC_WXORX_ENFORCE: ::c_int = 0x80000000; ++ ++pub const AF_SLOW: ::c_int = 33; ++pub const AF_SCLUSTER: ::c_int = 34; ++pub const AF_ARP: ::c_int = 35; ++pub const AF_BLUETOOTH: ::c_int = 36; ++pub const AF_IEEE80211: ::c_int = 37; ++pub const AF_INET_SDP: ::c_int = 40; ++pub const AF_INET6_SDP: ::c_int = 42; ++ ++// sys/net/if.h ++pub const IF_MAXUNIT: ::c_int = 0x7fff; ++/// (n) interface is up ++pub const IFF_UP: ::c_int = 0x1; ++/// (i) broadcast address valid ++pub const IFF_BROADCAST: ::c_int = 0x2; ++/// (n) turn on debugging ++pub const IFF_DEBUG: ::c_int = 0x4; ++/// (i) is a loopback net ++pub const IFF_LOOPBACK: ::c_int = 0x8; ++/// (i) is a point-to-point link ++pub const IFF_POINTOPOINT: ::c_int = 0x10; ++/// (i) calls if_input in net epoch ++pub const IFF_KNOWSEPOCH: ::c_int = 0x20; ++/// (d) resources allocated ++pub const IFF_RUNNING: ::c_int = 0x40; ++#[doc(hidden)] ++#[deprecated( ++ since = "0.2.54", ++ note = "IFF_DRV_RUNNING is deprecated. Use the portable IFF_RUNNING instead" ++)] ++/// (d) resources allocate ++pub const IFF_DRV_RUNNING: ::c_int = 0x40; ++/// (n) no address resolution protocol ++pub const IFF_NOARP: ::c_int = 0x80; ++/// (n) receive all packets ++pub const IFF_PROMISC: ::c_int = 0x100; ++/// (n) receive all multicast packets ++pub const IFF_ALLMULTI: ::c_int = 0x200; ++/// (d) tx hardware queue is full ++pub const IFF_OACTIVE: ::c_int = 0x400; ++#[doc(hidden)] ++#[deprecated(since = "0.2.54", note = "Use the portable `IFF_OACTIVE` instead")] ++/// (d) tx hardware queue is full ++pub const IFF_DRV_OACTIVE: ::c_int = 0x400; ++/// (i) can't hear own transmissions ++pub const IFF_SIMPLEX: ::c_int = 0x800; ++/// per link layer defined bit ++pub const IFF_LINK0: ::c_int = 0x1000; ++/// per link layer defined bit ++pub const IFF_LINK1: ::c_int = 0x2000; ++/// per link layer defined bit ++pub const IFF_LINK2: ::c_int = 0x4000; ++/// use alternate physical connection ++pub const IFF_ALTPHYS: ::c_int = IFF_LINK2; ++/// (i) supports multicast ++pub const IFF_MULTICAST: ::c_int = 0x8000; ++/// (i) unconfigurable using ioctl(2) ++pub const IFF_CANTCONFIG: ::c_int = 0x10000; ++/// (n) user-requested promisc mode ++pub const IFF_PPROMISC: ::c_int = 0x20000; ++/// (n) user-requested monitor mode ++pub const IFF_MONITOR: ::c_int = 0x40000; ++/// (n) static ARP ++pub const IFF_STATICARP: ::c_int = 0x80000; ++/// (n) interface is winding down ++pub const IFF_DYING: ::c_int = 0x200000; ++/// (n) interface is being renamed ++pub const IFF_RENAMING: ::c_int = 0x400000; ++/// interface is not part of any groups ++pub const IFF_NOGROUP: ::c_int = 0x800000; ++ ++/// link invalid/unknown ++pub const LINK_STATE_UNKNOWN: ::c_int = 0; ++/// link is down ++pub const LINK_STATE_DOWN: ::c_int = 1; ++/// link is up ++pub const LINK_STATE_UP: ::c_int = 2; ++ ++/// can offload checksum on RX ++pub const IFCAP_RXCSUM: ::c_int = 0x00001; ++/// can offload checksum on TX ++pub const IFCAP_TXCSUM: ::c_int = 0x00002; ++/// can be a network console ++pub const IFCAP_NETCONS: ::c_int = 0x00004; ++/// VLAN-compatible MTU ++pub const IFCAP_VLAN_MTU: ::c_int = 0x00008; ++/// hardware VLAN tag support ++pub const IFCAP_VLAN_HWTAGGING: ::c_int = 0x00010; ++/// 9000 byte MTU supported ++pub const IFCAP_JUMBO_MTU: ::c_int = 0x00020; ++/// driver supports polling ++pub const IFCAP_POLLING: ::c_int = 0x00040; ++/// can do IFCAP_HWCSUM on VLANs ++pub const IFCAP_VLAN_HWCSUM: ::c_int = 0x00080; ++/// can do TCP Segmentation Offload ++pub const IFCAP_TSO4: ::c_int = 0x00100; ++/// can do TCP6 Segmentation Offload ++pub const IFCAP_TSO6: ::c_int = 0x00200; ++/// can do Large Receive Offload ++pub const IFCAP_LRO: ::c_int = 0x00400; ++/// wake on any unicast frame ++pub const IFCAP_WOL_UCAST: ::c_int = 0x00800; ++/// wake on any multicast frame ++pub const IFCAP_WOL_MCAST: ::c_int = 0x01000; ++/// wake on any Magic Packet ++pub const IFCAP_WOL_MAGIC: ::c_int = 0x02000; ++/// interface can offload TCP ++pub const IFCAP_TOE4: ::c_int = 0x04000; ++/// interface can offload TCP6 ++pub const IFCAP_TOE6: ::c_int = 0x08000; ++/// interface hw can filter vlan tag ++pub const IFCAP_VLAN_HWFILTER: ::c_int = 0x10000; ++/// can do SIOCGIFCAPNV/SIOCSIFCAPNV ++pub const IFCAP_NV: ::c_int = 0x20000; ++/// can do IFCAP_TSO on VLANs ++pub const IFCAP_VLAN_HWTSO: ::c_int = 0x40000; ++/// the runtime link state is dynamic ++pub const IFCAP_LINKSTATE: ::c_int = 0x80000; ++/// netmap mode supported/enabled ++pub const IFCAP_NETMAP: ::c_int = 0x100000; ++/// can offload checksum on IPv6 RX ++pub const IFCAP_RXCSUM_IPV6: ::c_int = 0x200000; ++/// can offload checksum on IPv6 TX ++pub const IFCAP_TXCSUM_IPV6: ::c_int = 0x400000; ++/// manages counters internally ++pub const IFCAP_HWSTATS: ::c_int = 0x800000; ++/// hardware supports TX rate limiting ++pub const IFCAP_TXRTLMT: ::c_int = 0x1000000; ++/// hardware rx timestamping ++pub const IFCAP_HWRXTSTMP: ::c_int = 0x2000000; ++/// understands M_EXTPG mbufs ++pub const IFCAP_MEXTPG: ::c_int = 0x4000000; ++/// can do TLS encryption and segmentation for TCP ++pub const IFCAP_TXTLS4: ::c_int = 0x8000000; ++/// can do TLS encryption and segmentation for TCP6 ++pub const IFCAP_TXTLS6: ::c_int = 0x10000000; ++/// can do IFCAN_HWCSUM on VXLANs ++pub const IFCAP_VXLAN_HWCSUM: ::c_int = 0x20000000; ++/// can do IFCAP_TSO on VXLANs ++pub const IFCAP_VXLAN_HWTSO: ::c_int = 0x40000000; ++/// can do TLS with rate limiting ++pub const IFCAP_TXTLS_RTLMT: ::c_int = 0x80000000; ++ ++pub const IFCAP_HWCSUM_IPV6: ::c_int = IFCAP_RXCSUM_IPV6 | IFCAP_TXCSUM_IPV6; ++pub const IFCAP_HWCSUM: ::c_int = IFCAP_RXCSUM | IFCAP_TXCSUM; ++pub const IFCAP_TSO: ::c_int = IFCAP_TSO4 | IFCAP_TSO6; ++pub const IFCAP_WOL: ::c_int = IFCAP_WOL_UCAST | IFCAP_WOL_MCAST | IFCAP_WOL_MAGIC; ++pub const IFCAP_TOE: ::c_int = IFCAP_TOE4 | IFCAP_TOE6; ++pub const IFCAP_TXTLS: ::c_int = IFCAP_TXTLS4 | IFCAP_TXTLS6; ++pub const IFCAP_CANTCHANGE: ::c_int = IFCAP_NETMAP | IFCAP_NV; ++ ++pub const IFQ_MAXLEN: ::c_int = 50; ++pub const IFNET_SLOWHZ: ::c_int = 1; ++ ++pub const IFAN_ARRIVAL: ::c_int = 0; ++pub const IFAN_DEPARTURE: ::c_int = 1; ++ ++pub const IFSTATMAX: ::c_int = 800; ++ ++pub const RSS_FUNC_NONE: ::c_int = 0; ++pub const RSS_FUNC_PRIVATE: ::c_int = 1; ++pub const RSS_FUNC_TOEPLITZ: ::c_int = 2; ++ ++pub const RSS_TYPE_IPV4: ::c_int = 0x00000001; ++pub const RSS_TYPE_TCP_IPV4: ::c_int = 0x00000002; ++pub const RSS_TYPE_IPV6: ::c_int = 0x00000004; ++pub const RSS_TYPE_IPV6_EX: ::c_int = 0x00000008; ++pub const RSS_TYPE_TCP_IPV6: ::c_int = 0x00000010; ++pub const RSS_TYPE_TCP_IPV6_EX: ::c_int = 0x00000020; ++pub const RSS_TYPE_UDP_IPV4: ::c_int = 0x00000040; ++pub const RSS_TYPE_UDP_IPV6: ::c_int = 0x00000080; ++pub const RSS_TYPE_UDP_IPV6_EX: ::c_int = 0x00000100; ++pub const RSS_KEYLEN: ::c_int = 128; ++ ++pub const IFNET_PCP_NONE: ::c_int = 0xff; ++pub const IFDR_MSG_SIZE: ::c_int = 64; ++pub const IFDR_REASON_MSG: ::c_int = 1; ++pub const IFDR_REASON_VENDOR: ::c_int = 2; ++ ++// sys/net/if_mib.h ++ ++/// non-interface-specific ++pub const IFMIB_SYSTEM: ::c_int = 1; ++/// per-interface data table ++pub const IFMIB_IFDATA: ::c_int = 2; ++ ++/// generic stats for all kinds of ifaces ++pub const IFDATA_GENERAL: ::c_int = 1; ++/// specific to the type of interface ++pub const IFDATA_LINKSPECIFIC: ::c_int = 2; ++/// driver name and unit ++pub const IFDATA_DRIVERNAME: ::c_int = 3; ++ ++/// number of interfaces configured ++pub const IFMIB_IFCOUNT: ::c_int = 1; ++ ++/// functions not specific to a type of iface ++pub const NETLINK_GENERIC: ::c_int = 0; ++ ++pub const DOT3COMPLIANCE_STATS: ::c_int = 1; ++pub const DOT3COMPLIANCE_COLLS: ::c_int = 2; ++ ++pub const dot3ChipSetAMD7990: ::c_int = 1; ++pub const dot3ChipSetAMD79900: ::c_int = 2; ++pub const dot3ChipSetAMD79C940: ::c_int = 3; ++ ++pub const dot3ChipSetIntel82586: ::c_int = 1; ++pub const dot3ChipSetIntel82596: ::c_int = 2; ++pub const dot3ChipSetIntel82557: ::c_int = 3; ++ ++pub const dot3ChipSetNational8390: ::c_int = 1; ++pub const dot3ChipSetNationalSonic: ::c_int = 2; ++ ++pub const dot3ChipSetFujitsu86950: ::c_int = 1; ++ ++pub const dot3ChipSetDigitalDC21040: ::c_int = 1; ++pub const dot3ChipSetDigitalDC21140: ::c_int = 2; ++pub const dot3ChipSetDigitalDC21041: ::c_int = 3; ++pub const dot3ChipSetDigitalDC21140A: ::c_int = 4; ++pub const dot3ChipSetDigitalDC21142: ::c_int = 5; + +-// https://github.com/freebsd/freebsd/blob/master/sys/net/if.h#L140 +-pub const IFF_UP: ::c_int = 0x1; // (n) interface is up +-pub const IFF_BROADCAST: ::c_int = 0x2; // (i) broadcast address valid +-pub const IFF_DEBUG: ::c_int = 0x4; // (n) turn on debugging +-pub const IFF_LOOPBACK: ::c_int = 0x8; // (i) is a loopback net +-pub const IFF_POINTOPOINT: ::c_int = 0x10; // (i) is a point-to-point link +- // 0x20 was IFF_SMART +-pub const IFF_RUNNING: ::c_int = 0x40; // (d) resources allocated +-#[doc(hidden)] +-#[deprecated( +- since = "0.2.54", +- note = "IFF_DRV_RUNNING is deprecated. Use the portable IFF_RUNNING instead" +-)] +-pub const IFF_DRV_RUNNING: ::c_int = 0x40; +-pub const IFF_NOARP: ::c_int = 0x80; // (n) no address resolution protocol +-pub const IFF_PROMISC: ::c_int = 0x100; // (n) receive all packets +-pub const IFF_ALLMULTI: ::c_int = 0x200; // (n) receive all multicast packets +-pub const IFF_OACTIVE: ::c_int = 0x400; // (d) tx hardware queue is full +-#[doc(hidden)] +-#[deprecated(since = "0.2.54", note = "Use the portable `IFF_OACTIVE` instead")] +-pub const IFF_DRV_OACTIVE: ::c_int = 0x400; +-pub const IFF_SIMPLEX: ::c_int = 0x800; // (i) can't hear own transmissions +-pub const IFF_LINK0: ::c_int = 0x1000; // per link layer defined bit +-pub const IFF_LINK1: ::c_int = 0x2000; // per link layer defined bit +-pub const IFF_LINK2: ::c_int = 0x4000; // per link layer defined bit +-pub const IFF_ALTPHYS: ::c_int = IFF_LINK2; // use alternate physical connection +-pub const IFF_MULTICAST: ::c_int = 0x8000; // (i) supports multicast +- // (i) unconfigurable using ioctl(2) +-pub const IFF_CANTCONFIG: ::c_int = 0x10000; +-pub const IFF_PPROMISC: ::c_int = 0x20000; // (n) user-requested promisc mode +-pub const IFF_MONITOR: ::c_int = 0x40000; // (n) user-requested monitor mode +-pub const IFF_STATICARP: ::c_int = 0x80000; // (n) static ARP +-pub const IFF_DYING: ::c_int = 0x200000; // (n) interface is winding down +-pub const IFF_RENAMING: ::c_int = 0x400000; // (n) interface is being renamed ++pub const dot3ChipSetWesternDigital83C690: ::c_int = 1; ++pub const dot3ChipSetWesternDigital83C790: ::c_int = 2; + + // sys/netinet/in.h + // Protocols (RFC 1700) +@@ -1057,10 +3616,24 @@ pub const TCP_MD5SIG: ::c_int = 16; + pub const TCP_INFO: ::c_int = 32; + pub const TCP_CONGESTION: ::c_int = 64; + pub const TCP_CCALGOOPT: ::c_int = 65; ++pub const TCP_MAXUNACKTIME: ::c_int = 68; ++pub const TCP_MAXPEAKRATE: ::c_int = 69; ++pub const TCP_IDLE_REDUCE: ::c_int = 70; ++pub const TCP_REMOTE_UDP_ENCAPS_PORT: ::c_int = 71; ++pub const TCP_DELACK: ::c_int = 72; ++pub const TCP_FIN_IS_RST: ::c_int = 73; ++pub const TCP_LOG_LIMIT: ::c_int = 74; ++pub const TCP_SHARED_CWND_ALLOWED: ::c_int = 75; ++pub const TCP_PROC_ACCOUNTING: ::c_int = 76; ++pub const TCP_USE_CMP_ACKS: ::c_int = 77; ++pub const TCP_PERF_INFO: ::c_int = 78; ++pub const TCP_LRD: ::c_int = 79; + pub const TCP_KEEPINIT: ::c_int = 128; + pub const TCP_FASTOPEN: ::c_int = 1025; + pub const TCP_PCAP_OUT: ::c_int = 2048; + pub const TCP_PCAP_IN: ::c_int = 4096; ++pub const TCP_FASTOPEN_PSK_LEN: ::c_int = 16; ++pub const TCP_FUNCTION_NAME_LEN_MAX: ::c_int = 32; + + pub const IP_BINDANY: ::c_int = 24; + pub const IP_BINDMULTI: ::c_int = 25; +@@ -1068,6 +3641,7 @@ pub const IP_RSS_LISTEN_BUCKET: ::c_int = 26; + pub const IP_ORIGDSTADDR: ::c_int = 27; + pub const IP_RECVORIGDSTADDR: ::c_int = IP_ORIGDSTADDR; + ++pub const IP_DONTFRAG: ::c_int = 67; + pub const IP_RECVTOS: ::c_int = 68; + + pub const IPV6_BINDANY: ::c_int = 64; +@@ -1089,22 +3663,8 @@ pub const NET_RT_IFMALIST: ::c_int = 4; + pub const NET_RT_IFLISTL: ::c_int = 5; + + // System V IPC +-pub const IPC_PRIVATE: ::key_t = 0; +-pub const IPC_CREAT: ::c_int = 0o1000; +-pub const IPC_EXCL: ::c_int = 0o2000; +-pub const IPC_NOWAIT: ::c_int = 0o4000; +-pub const IPC_RMID: ::c_int = 0; +-pub const IPC_SET: ::c_int = 1; +-pub const IPC_STAT: ::c_int = 2; + pub const IPC_INFO: ::c_int = 3; +-pub const IPC_R: ::c_int = 0o400; +-pub const IPC_W: ::c_int = 0o200; +-pub const IPC_M: ::c_int = 0o10000; + pub const MSG_NOERROR: ::c_int = 0o10000; +-pub const SHM_RDONLY: ::c_int = 0o10000; +-pub const SHM_RND: ::c_int = 0o20000; +-pub const SHM_R: ::c_int = 0o400; +-pub const SHM_W: ::c_int = 0o200; + pub const SHM_LOCK: ::c_int = 11; + pub const SHM_UNLOCK: ::c_int = 12; + pub const SHM_STAT: ::c_int = 13; +@@ -1188,6 +3748,25 @@ pub const AT_EACCESS: ::c_int = 0x100; + pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x200; + pub const AT_SYMLINK_FOLLOW: ::c_int = 0x400; + pub const AT_REMOVEDIR: ::c_int = 0x800; ++pub const AT_RESOLVE_BENEATH: ::c_int = 0x2000; ++pub const AT_EMPTY_PATH: ::c_int = 0x4000; ++ ++pub const AT_NULL: ::c_int = 0; ++pub const AT_IGNORE: ::c_int = 1; ++pub const AT_EXECFD: ::c_int = 2; ++pub const AT_PHDR: ::c_int = 3; ++pub const AT_PHENT: ::c_int = 4; ++pub const AT_PHNUM: ::c_int = 5; ++pub const AT_PAGESZ: ::c_int = 6; ++pub const AT_BASE: ::c_int = 7; ++pub const AT_FLAGS: ::c_int = 8; ++pub const AT_ENTRY: ::c_int = 9; ++pub const AT_NOTELF: ::c_int = 10; ++pub const AT_UID: ::c_int = 11; ++pub const AT_EUID: ::c_int = 12; ++pub const AT_GID: ::c_int = 13; ++pub const AT_EGID: ::c_int = 14; ++pub const AT_EXECPATH: ::c_int = 15; + + pub const TABDLY: ::tcflag_t = 0x00000004; + pub const TAB0: ::tcflag_t = 0x00000000; +@@ -1197,6 +3776,8 @@ pub const _PC_ACL_NFS4: ::c_int = 64; + + pub const _SC_CPUSET_SIZE: ::c_int = 122; + ++pub const _UUID_NODE_LEN: usize = 6; ++ + // Flags which can be passed to pdfork(2) + pub const PD_DAEMON: ::c_int = 0x00000001; + pub const PD_CLOEXEC: ::c_int = 0x00000002; +@@ -1224,14 +3805,30 @@ pub const UF_READONLY: ::c_ulong = 0x00001000; + pub const UF_HIDDEN: ::c_ulong = 0x00008000; + pub const SF_SNAPSHOT: ::c_ulong = 0x00200000; + ++// fcntl commands ++pub const F_ADD_SEALS: ::c_int = 19; ++pub const F_GET_SEALS: ::c_int = 20; + pub const F_OGETLK: ::c_int = 7; + pub const F_OSETLK: ::c_int = 8; + pub const F_OSETLKW: ::c_int = 9; +-pub const F_DUP2FD: ::c_int = 10; +-pub const F_SETLK_REMOTE: ::c_int = 14; +-pub const F_READAHEAD: ::c_int = 15; + pub const F_RDAHEAD: ::c_int = 16; +-pub const F_DUP2FD_CLOEXEC: ::c_int = 18; ++pub const F_READAHEAD: ::c_int = 15; ++pub const F_SETLK_REMOTE: ::c_int = 14; ++pub const F_KINFO: ::c_int = 22; ++ ++// for use with F_ADD_SEALS ++pub const F_SEAL_GROW: ::c_int = 4; ++pub const F_SEAL_SEAL: ::c_int = 1; ++pub const F_SEAL_SHRINK: ::c_int = 2; ++pub const F_SEAL_WRITE: ::c_int = 8; ++ ++// for use with fspacectl ++pub const SPACECTL_DEALLOC: ::c_int = 1; ++ ++// For getrandom() ++pub const GRND_NONBLOCK: ::c_uint = 0x1; ++pub const GRND_RANDOM: ::c_uint = 0x2; ++pub const GRND_INSECURE: ::c_uint = 0x4; + + // For realhostname* api + pub const HOSTNAME_FOUND: ::c_int = 0; +@@ -1250,6 +3847,841 @@ pub const RFLINUXTHPN: ::c_int = 65536; + pub const RFTSIGZMB: ::c_int = 524288; + pub const RFSPAWN: ::c_int = 2147483648; + ++// For eventfd ++pub const EFD_SEMAPHORE: ::c_int = 0x1; ++pub const EFD_NONBLOCK: ::c_int = 0x4; ++pub const EFD_CLOEXEC: ::c_int = 0x100000; ++ ++pub const MALLOCX_ZERO: ::c_int = 0x40; ++ ++/// size of returned wchan message ++pub const WMESGLEN: usize = 8; ++/// size of returned lock name ++pub const LOCKNAMELEN: usize = 8; ++/// size of returned thread name ++pub const TDNAMLEN: usize = 16; ++/// size of returned ki_comm name ++pub const COMMLEN: usize = 19; ++/// size of returned ki_emul ++pub const KI_EMULNAMELEN: usize = 16; ++/// number of groups in ki_groups ++pub const KI_NGROUPS: usize = 16; ++cfg_if! { ++ if #[cfg(freebsd11)] { ++ pub const KI_NSPARE_INT: usize = 4; ++ } else { ++ pub const KI_NSPARE_INT: usize = 2; ++ } ++} ++pub const KI_NSPARE_LONG: usize = 12; ++/// Flags for the process credential. ++pub const KI_CRF_CAPABILITY_MODE: usize = 0x00000001; ++/// Steal a bit from ki_cr_flags to indicate that the cred had more than ++/// KI_NGROUPS groups. ++pub const KI_CRF_GRP_OVERFLOW: usize = 0x80000000; ++/// controlling tty vnode active ++pub const KI_CTTY: usize = 0x00000001; ++/// session leader ++pub const KI_SLEADER: usize = 0x00000002; ++/// proc blocked on lock ki_lockname ++pub const KI_LOCKBLOCK: usize = 0x00000004; ++/// size of returned ki_login ++pub const LOGNAMELEN: usize = 17; ++/// size of returned ki_loginclass ++pub const LOGINCLASSLEN: usize = 17; ++ ++pub const KF_ATTR_VALID: ::c_int = 0x0001; ++pub const KF_TYPE_NONE: ::c_int = 0; ++pub const KF_TYPE_VNODE: ::c_int = 1; ++pub const KF_TYPE_SOCKET: ::c_int = 2; ++pub const KF_TYPE_PIPE: ::c_int = 3; ++pub const KF_TYPE_FIFO: ::c_int = 4; ++pub const KF_TYPE_KQUEUE: ::c_int = 5; ++pub const KF_TYPE_MQUEUE: ::c_int = 7; ++pub const KF_TYPE_SHM: ::c_int = 8; ++pub const KF_TYPE_SEM: ::c_int = 9; ++pub const KF_TYPE_PTS: ::c_int = 10; ++pub const KF_TYPE_PROCDESC: ::c_int = 11; ++pub const KF_TYPE_DEV: ::c_int = 12; ++pub const KF_TYPE_UNKNOWN: ::c_int = 255; ++ ++pub const KF_VTYPE_VNON: ::c_int = 0; ++pub const KF_VTYPE_VREG: ::c_int = 1; ++pub const KF_VTYPE_VDIR: ::c_int = 2; ++pub const KF_VTYPE_VBLK: ::c_int = 3; ++pub const KF_VTYPE_VCHR: ::c_int = 4; ++pub const KF_VTYPE_VLNK: ::c_int = 5; ++pub const KF_VTYPE_VSOCK: ::c_int = 6; ++pub const KF_VTYPE_VFIFO: ::c_int = 7; ++pub const KF_VTYPE_VBAD: ::c_int = 8; ++pub const KF_VTYPE_UNKNOWN: ::c_int = 255; ++ ++/// Current working directory ++pub const KF_FD_TYPE_CWD: ::c_int = -1; ++/// Root directory ++pub const KF_FD_TYPE_ROOT: ::c_int = -2; ++/// Jail directory ++pub const KF_FD_TYPE_JAIL: ::c_int = -3; ++/// Ktrace vnode ++pub const KF_FD_TYPE_TRACE: ::c_int = -4; ++pub const KF_FD_TYPE_TEXT: ::c_int = -5; ++/// Controlling terminal ++pub const KF_FD_TYPE_CTTY: ::c_int = -6; ++pub const KF_FLAG_READ: ::c_int = 0x00000001; ++pub const KF_FLAG_WRITE: ::c_int = 0x00000002; ++pub const KF_FLAG_APPEND: ::c_int = 0x00000004; ++pub const KF_FLAG_ASYNC: ::c_int = 0x00000008; ++pub const KF_FLAG_FSYNC: ::c_int = 0x00000010; ++pub const KF_FLAG_NONBLOCK: ::c_int = 0x00000020; ++pub const KF_FLAG_DIRECT: ::c_int = 0x00000040; ++pub const KF_FLAG_HASLOCK: ::c_int = 0x00000080; ++pub const KF_FLAG_SHLOCK: ::c_int = 0x00000100; ++pub const KF_FLAG_EXLOCK: ::c_int = 0x00000200; ++pub const KF_FLAG_NOFOLLOW: ::c_int = 0x00000400; ++pub const KF_FLAG_CREAT: ::c_int = 0x00000800; ++pub const KF_FLAG_TRUNC: ::c_int = 0x00001000; ++pub const KF_FLAG_EXCL: ::c_int = 0x00002000; ++pub const KF_FLAG_EXEC: ::c_int = 0x00004000; ++ ++pub const KVME_TYPE_NONE: ::c_int = 0; ++pub const KVME_TYPE_DEFAULT: ::c_int = 1; ++pub const KVME_TYPE_VNODE: ::c_int = 2; ++pub const KVME_TYPE_SWAP: ::c_int = 3; ++pub const KVME_TYPE_DEVICE: ::c_int = 4; ++pub const KVME_TYPE_PHYS: ::c_int = 5; ++pub const KVME_TYPE_DEAD: ::c_int = 6; ++pub const KVME_TYPE_SG: ::c_int = 7; ++pub const KVME_TYPE_MGTDEVICE: ::c_int = 8; ++// Present in `sys/user.h` but is undefined for whatever reason... ++// pub const KVME_TYPE_GUARD: ::c_int = 9; ++pub const KVME_TYPE_UNKNOWN: ::c_int = 255; ++pub const KVME_PROT_READ: ::c_int = 0x00000001; ++pub const KVME_PROT_WRITE: ::c_int = 0x00000002; ++pub const KVME_PROT_EXEC: ::c_int = 0x00000004; ++pub const KVME_FLAG_COW: ::c_int = 0x00000001; ++pub const KVME_FLAG_NEEDS_COPY: ::c_int = 0x00000002; ++pub const KVME_FLAG_NOCOREDUMP: ::c_int = 0x00000004; ++pub const KVME_FLAG_SUPER: ::c_int = 0x00000008; ++pub const KVME_FLAG_GROWS_UP: ::c_int = 0x00000010; ++pub const KVME_FLAG_GROWS_DOWN: ::c_int = 0x00000020; ++pub const KVME_FLAG_USER_WIRED: ::c_int = 0x00000040; ++ ++pub const KKST_MAXLEN: ::c_int = 1024; ++/// Stack is valid. ++pub const KKST_STATE_STACKOK: ::c_int = 0; ++/// Stack swapped out. ++pub const KKST_STATE_SWAPPED: ::c_int = 1; ++pub const KKST_STATE_RUNNING: ::c_int = 2; ++ ++// Constants about priority. ++pub const PRI_MIN: ::c_int = 0; ++pub const PRI_MAX: ::c_int = 255; ++pub const PRI_MIN_ITHD: ::c_int = PRI_MIN; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++#[allow(deprecated)] ++pub const PRI_MAX_ITHD: ::c_int = PRI_MIN_REALTIME - 1; ++pub const PI_REALTIME: ::c_int = PRI_MIN_ITHD + 0; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++pub const PI_AV: ::c_int = PRI_MIN_ITHD + 4; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++pub const PI_NET: ::c_int = PRI_MIN_ITHD + 8; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++pub const PI_DISK: ::c_int = PRI_MIN_ITHD + 12; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++pub const PI_TTY: ::c_int = PRI_MIN_ITHD + 16; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++pub const PI_DULL: ::c_int = PRI_MIN_ITHD + 20; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++pub const PI_SOFT: ::c_int = PRI_MIN_ITHD + 24; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++pub const PRI_MIN_REALTIME: ::c_int = 48; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++#[allow(deprecated)] ++pub const PRI_MAX_REALTIME: ::c_int = PRI_MIN_KERN - 1; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++pub const PRI_MIN_KERN: ::c_int = 80; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++#[allow(deprecated)] ++pub const PRI_MAX_KERN: ::c_int = PRI_MIN_TIMESHARE - 1; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++#[allow(deprecated)] ++pub const PSWP: ::c_int = PRI_MIN_KERN + 0; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++#[allow(deprecated)] ++pub const PVM: ::c_int = PRI_MIN_KERN + 4; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++#[allow(deprecated)] ++pub const PINOD: ::c_int = PRI_MIN_KERN + 8; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++#[allow(deprecated)] ++pub const PRIBIO: ::c_int = PRI_MIN_KERN + 12; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++#[allow(deprecated)] ++pub const PVFS: ::c_int = PRI_MIN_KERN + 16; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++#[allow(deprecated)] ++pub const PZERO: ::c_int = PRI_MIN_KERN + 20; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++#[allow(deprecated)] ++pub const PSOCK: ::c_int = PRI_MIN_KERN + 24; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++#[allow(deprecated)] ++pub const PWAIT: ::c_int = PRI_MIN_KERN + 28; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++#[allow(deprecated)] ++pub const PLOCK: ::c_int = PRI_MIN_KERN + 32; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++#[allow(deprecated)] ++pub const PPAUSE: ::c_int = PRI_MIN_KERN + 36; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++pub const PRI_MIN_TIMESHARE: ::c_int = 120; ++pub const PRI_MAX_TIMESHARE: ::c_int = PRI_MIN_IDLE - 1; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++#[allow(deprecated)] ++pub const PUSER: ::c_int = PRI_MIN_TIMESHARE; ++pub const PRI_MIN_IDLE: ::c_int = 224; ++pub const PRI_MAX_IDLE: ::c_int = PRI_MAX; ++ ++pub const NZERO: ::c_int = 0; ++ ++// Resource utilization information. ++pub const RUSAGE_THREAD: ::c_int = 1; ++ ++cfg_if! { ++ if #[cfg(any(freebsd11, target_pointer_width = "32"))] { ++ pub const ARG_MAX: ::c_int = 256 * 1024; ++ } else { ++ pub const ARG_MAX: ::c_int = 2 * 256 * 1024; ++ } ++} ++pub const CHILD_MAX: ::c_int = 40; ++/// max command name remembered ++pub const MAXCOMLEN: usize = 19; ++/// max interpreter file name length ++pub const MAXINTERP: ::c_int = ::PATH_MAX; ++/// max login name length (incl. NUL) ++pub const MAXLOGNAME: ::c_int = 33; ++/// max simultaneous processes ++pub const MAXUPRC: ::c_int = CHILD_MAX; ++/// max bytes for an exec function ++pub const NCARGS: ::c_int = ARG_MAX; ++/// /* max number groups ++pub const NGROUPS: ::c_int = NGROUPS_MAX + 1; ++/// max open files per process ++pub const NOFILE: ::c_int = OPEN_MAX; ++/// marker for empty group set member ++pub const NOGROUP: ::c_int = 65535; ++/// max hostname size ++pub const MAXHOSTNAMELEN: ::c_int = 256; ++/// max bytes in term canon input line ++pub const MAX_CANON: ::c_int = 255; ++/// max bytes in terminal input ++pub const MAX_INPUT: ::c_int = 255; ++/// max bytes in a file name ++pub const NAME_MAX: ::c_int = 255; ++pub const MAXSYMLINKS: ::c_int = 32; ++/// max supplemental group id's ++pub const NGROUPS_MAX: ::c_int = 1023; ++/// max open files per process ++pub const OPEN_MAX: ::c_int = 64; ++ ++pub const _POSIX_ARG_MAX: ::c_int = 4096; ++pub const _POSIX_LINK_MAX: ::c_int = 8; ++pub const _POSIX_MAX_CANON: ::c_int = 255; ++pub const _POSIX_MAX_INPUT: ::c_int = 255; ++pub const _POSIX_NAME_MAX: ::c_int = 14; ++pub const _POSIX_PIPE_BUF: ::c_int = 512; ++pub const _POSIX_SSIZE_MAX: ::c_int = 32767; ++pub const _POSIX_STREAM_MAX: ::c_int = 8; ++ ++/// max ibase/obase values in bc(1) ++pub const BC_BASE_MAX: ::c_int = 99; ++/// max array elements in bc(1) ++pub const BC_DIM_MAX: ::c_int = 2048; ++/// max scale value in bc(1) ++pub const BC_SCALE_MAX: ::c_int = 99; ++/// max const string length in bc(1) ++pub const BC_STRING_MAX: ::c_int = 1000; ++/// max character class name size ++pub const CHARCLASS_NAME_MAX: ::c_int = 14; ++/// max weights for order keyword ++pub const COLL_WEIGHTS_MAX: ::c_int = 10; ++/// max expressions nested in expr(1) ++pub const EXPR_NEST_MAX: ::c_int = 32; ++/// max bytes in an input line ++pub const LINE_MAX: ::c_int = 2048; ++/// max RE's in interval notation ++pub const RE_DUP_MAX: ::c_int = 255; ++ ++pub const _POSIX2_BC_BASE_MAX: ::c_int = 99; ++pub const _POSIX2_BC_DIM_MAX: ::c_int = 2048; ++pub const _POSIX2_BC_SCALE_MAX: ::c_int = 99; ++pub const _POSIX2_BC_STRING_MAX: ::c_int = 1000; ++pub const _POSIX2_CHARCLASS_NAME_MAX: ::c_int = 14; ++pub const _POSIX2_COLL_WEIGHTS_MAX: ::c_int = 2; ++pub const _POSIX2_EQUIV_CLASS_MAX: ::c_int = 2; ++pub const _POSIX2_EXPR_NEST_MAX: ::c_int = 32; ++pub const _POSIX2_LINE_MAX: ::c_int = 2048; ++pub const _POSIX2_RE_DUP_MAX: ::c_int = 255; ++ ++// sys/proc.h ++pub const TDF_BORROWING: ::c_int = 0x00000001; ++pub const TDF_INPANIC: ::c_int = 0x00000002; ++pub const TDF_INMEM: ::c_int = 0x00000004; ++pub const TDF_SINTR: ::c_int = 0x00000008; ++pub const TDF_TIMEOUT: ::c_int = 0x00000010; ++pub const TDF_IDLETD: ::c_int = 0x00000020; ++pub const TDF_CANSWAP: ::c_int = 0x00000040; ++pub const TDF_KTH_SUSP: ::c_int = 0x00000100; ++pub const TDF_ALLPROCSUSP: ::c_int = 0x00000200; ++pub const TDF_BOUNDARY: ::c_int = 0x00000400; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++pub const TDF_ASTPENDING: ::c_int = 0x00000800; ++pub const TDF_SBDRY: ::c_int = 0x00002000; ++pub const TDF_UPIBLOCKED: ::c_int = 0x00004000; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++pub const TDF_NEEDSUSPCHK: ::c_int = 0x00008000; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++pub const TDF_NEEDRESCHED: ::c_int = 0x00010000; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++pub const TDF_NEEDSIGCHK: ::c_int = 0x00020000; ++pub const TDF_NOLOAD: ::c_int = 0x00040000; ++pub const TDF_SERESTART: ::c_int = 0x00080000; ++pub const TDF_THRWAKEUP: ::c_int = 0x00100000; ++pub const TDF_SEINTR: ::c_int = 0x00200000; ++pub const TDF_SWAPINREQ: ::c_int = 0x00400000; ++#[deprecated(since = "0.2.133", note = "Removed in FreeBSD 14")] ++pub const TDF_UNUSED23: ::c_int = 0x00800000; ++pub const TDF_SCHED0: ::c_int = 0x01000000; ++pub const TDF_SCHED1: ::c_int = 0x02000000; ++pub const TDF_SCHED2: ::c_int = 0x04000000; ++pub const TDF_SCHED3: ::c_int = 0x08000000; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++pub const TDF_ALRMPEND: ::c_int = 0x10000000; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++pub const TDF_PROFPEND: ::c_int = 0x20000000; ++#[deprecated(since = "0.2.133", note = "Not stable across OS versions")] ++pub const TDF_MACPEND: ::c_int = 0x40000000; ++ ++pub const TDB_SUSPEND: ::c_int = 0x00000001; ++pub const TDB_XSIG: ::c_int = 0x00000002; ++pub const TDB_USERWR: ::c_int = 0x00000004; ++pub const TDB_SCE: ::c_int = 0x00000008; ++pub const TDB_SCX: ::c_int = 0x00000010; ++pub const TDB_EXEC: ::c_int = 0x00000020; ++pub const TDB_FORK: ::c_int = 0x00000040; ++pub const TDB_STOPATFORK: ::c_int = 0x00000080; ++pub const TDB_CHILD: ::c_int = 0x00000100; ++pub const TDB_BORN: ::c_int = 0x00000200; ++pub const TDB_EXIT: ::c_int = 0x00000400; ++pub const TDB_VFORK: ::c_int = 0x00000800; ++pub const TDB_FSTP: ::c_int = 0x00001000; ++pub const TDB_STEP: ::c_int = 0x00002000; ++ ++pub const TDP_OLDMASK: ::c_int = 0x00000001; ++pub const TDP_INKTR: ::c_int = 0x00000002; ++pub const TDP_INKTRACE: ::c_int = 0x00000004; ++pub const TDP_BUFNEED: ::c_int = 0x00000008; ++pub const TDP_COWINPROGRESS: ::c_int = 0x00000010; ++pub const TDP_ALTSTACK: ::c_int = 0x00000020; ++pub const TDP_DEADLKTREAT: ::c_int = 0x00000040; ++pub const TDP_NOFAULTING: ::c_int = 0x00000080; ++pub const TDP_OWEUPC: ::c_int = 0x00000200; ++pub const TDP_ITHREAD: ::c_int = 0x00000400; ++pub const TDP_SYNCIO: ::c_int = 0x00000800; ++pub const TDP_SCHED1: ::c_int = 0x00001000; ++pub const TDP_SCHED2: ::c_int = 0x00002000; ++pub const TDP_SCHED3: ::c_int = 0x00004000; ++pub const TDP_SCHED4: ::c_int = 0x00008000; ++pub const TDP_GEOM: ::c_int = 0x00010000; ++pub const TDP_SOFTDEP: ::c_int = 0x00020000; ++pub const TDP_NORUNNINGBUF: ::c_int = 0x00040000; ++pub const TDP_WAKEUP: ::c_int = 0x00080000; ++pub const TDP_INBDFLUSH: ::c_int = 0x00100000; ++pub const TDP_KTHREAD: ::c_int = 0x00200000; ++pub const TDP_CALLCHAIN: ::c_int = 0x00400000; ++pub const TDP_IGNSUSP: ::c_int = 0x00800000; ++pub const TDP_AUDITREC: ::c_int = 0x01000000; ++pub const TDP_RFPPWAIT: ::c_int = 0x02000000; ++pub const TDP_RESETSPUR: ::c_int = 0x04000000; ++pub const TDP_NERRNO: ::c_int = 0x08000000; ++pub const TDP_EXECVMSPC: ::c_int = 0x40000000; ++ ++pub const TDI_SUSPENDED: ::c_int = 0x0001; ++pub const TDI_SLEEPING: ::c_int = 0x0002; ++pub const TDI_SWAPPED: ::c_int = 0x0004; ++pub const TDI_LOCK: ::c_int = 0x0008; ++pub const TDI_IWAIT: ::c_int = 0x0010; ++ ++pub const P_ADVLOCK: ::c_int = 0x00000001; ++pub const P_CONTROLT: ::c_int = 0x00000002; ++pub const P_KPROC: ::c_int = 0x00000004; ++pub const P_UNUSED3: ::c_int = 0x00000008; ++pub const P_PPWAIT: ::c_int = 0x00000010; ++pub const P_PROFIL: ::c_int = 0x00000020; ++pub const P_STOPPROF: ::c_int = 0x00000040; ++pub const P_HADTHREADS: ::c_int = 0x00000080; ++pub const P_SUGID: ::c_int = 0x00000100; ++pub const P_SYSTEM: ::c_int = 0x00000200; ++pub const P_SINGLE_EXIT: ::c_int = 0x00000400; ++pub const P_TRACED: ::c_int = 0x00000800; ++pub const P_WAITED: ::c_int = 0x00001000; ++pub const P_WEXIT: ::c_int = 0x00002000; ++pub const P_EXEC: ::c_int = 0x00004000; ++pub const P_WKILLED: ::c_int = 0x00008000; ++pub const P_CONTINUED: ::c_int = 0x00010000; ++pub const P_STOPPED_SIG: ::c_int = 0x00020000; ++pub const P_STOPPED_TRACE: ::c_int = 0x00040000; ++pub const P_STOPPED_SINGLE: ::c_int = 0x00080000; ++pub const P_PROTECTED: ::c_int = 0x00100000; ++pub const P_SIGEVENT: ::c_int = 0x00200000; ++pub const P_SINGLE_BOUNDARY: ::c_int = 0x00400000; ++pub const P_HWPMC: ::c_int = 0x00800000; ++pub const P_JAILED: ::c_int = 0x01000000; ++pub const P_TOTAL_STOP: ::c_int = 0x02000000; ++pub const P_INEXEC: ::c_int = 0x04000000; ++pub const P_STATCHILD: ::c_int = 0x08000000; ++pub const P_INMEM: ::c_int = 0x10000000; ++pub const P_SWAPPINGOUT: ::c_int = 0x20000000; ++pub const P_SWAPPINGIN: ::c_int = 0x40000000; ++pub const P_PPTRACE: ::c_int = 0x80000000; ++pub const P_STOPPED: ::c_int = P_STOPPED_SIG | P_STOPPED_SINGLE | P_STOPPED_TRACE; ++ ++pub const P2_INHERIT_PROTECTED: ::c_int = 0x00000001; ++pub const P2_NOTRACE: ::c_int = 0x00000002; ++pub const P2_NOTRACE_EXEC: ::c_int = 0x00000004; ++pub const P2_AST_SU: ::c_int = 0x00000008; ++pub const P2_PTRACE_FSTP: ::c_int = 0x00000010; ++pub const P2_TRAPCAP: ::c_int = 0x00000020; ++pub const P2_STKGAP_DISABLE: ::c_int = 0x00000800; ++pub const P2_STKGAP_DISABLE_EXEC: ::c_int = 0x00001000; ++ ++pub const P_TREE_ORPHANED: ::c_int = 0x00000001; ++pub const P_TREE_FIRST_ORPHAN: ::c_int = 0x00000002; ++pub const P_TREE_REAPER: ::c_int = 0x00000004; ++ ++pub const SIDL: ::c_char = 1; ++pub const SRUN: ::c_char = 2; ++pub const SSLEEP: ::c_char = 3; ++pub const SSTOP: ::c_char = 4; ++pub const SZOMB: ::c_char = 5; ++pub const SWAIT: ::c_char = 6; ++pub const SLOCK: ::c_char = 7; ++ ++pub const P_MAGIC: ::c_int = 0xbeefface; ++ ++pub const TDP_SIGFASTBLOCK: ::c_int = 0x00000100; ++pub const TDP_UIOHELD: ::c_int = 0x10000000; ++pub const TDP_SIGFASTPENDING: ::c_int = 0x80000000; ++pub const TDP2_COMPAT32RB: ::c_int = 0x00000002; ++pub const P2_PROTMAX_ENABLE: ::c_int = 0x00000200; ++pub const P2_PROTMAX_DISABLE: ::c_int = 0x00000400; ++pub const TDP2_SBPAGES: ::c_int = 0x00000001; ++pub const P2_ASLR_ENABLE: ::c_int = 0x00000040; ++pub const P2_ASLR_DISABLE: ::c_int = 0x00000080; ++pub const P2_ASLR_IGNSTART: ::c_int = 0x00000100; ++pub const P_TREE_GRPEXITED: ::c_int = 0x00000008; ++ ++// libprocstat.h ++pub const PS_FST_VTYPE_VNON: ::c_int = 1; ++pub const PS_FST_VTYPE_VREG: ::c_int = 2; ++pub const PS_FST_VTYPE_VDIR: ::c_int = 3; ++pub const PS_FST_VTYPE_VBLK: ::c_int = 4; ++pub const PS_FST_VTYPE_VCHR: ::c_int = 5; ++pub const PS_FST_VTYPE_VLNK: ::c_int = 6; ++pub const PS_FST_VTYPE_VSOCK: ::c_int = 7; ++pub const PS_FST_VTYPE_VFIFO: ::c_int = 8; ++pub const PS_FST_VTYPE_VBAD: ::c_int = 9; ++pub const PS_FST_VTYPE_UNKNOWN: ::c_int = 255; ++ ++pub const PS_FST_TYPE_VNODE: ::c_int = 1; ++pub const PS_FST_TYPE_FIFO: ::c_int = 2; ++pub const PS_FST_TYPE_SOCKET: ::c_int = 3; ++pub const PS_FST_TYPE_PIPE: ::c_int = 4; ++pub const PS_FST_TYPE_PTS: ::c_int = 5; ++pub const PS_FST_TYPE_KQUEUE: ::c_int = 6; ++pub const PS_FST_TYPE_MQUEUE: ::c_int = 8; ++pub const PS_FST_TYPE_SHM: ::c_int = 9; ++pub const PS_FST_TYPE_SEM: ::c_int = 10; ++pub const PS_FST_TYPE_UNKNOWN: ::c_int = 11; ++pub const PS_FST_TYPE_NONE: ::c_int = 12; ++pub const PS_FST_TYPE_PROCDESC: ::c_int = 13; ++pub const PS_FST_TYPE_DEV: ::c_int = 14; ++pub const PS_FST_TYPE_EVENTFD: ::c_int = 15; ++ ++pub const PS_FST_UFLAG_RDIR: ::c_int = 0x0001; ++pub const PS_FST_UFLAG_CDIR: ::c_int = 0x0002; ++pub const PS_FST_UFLAG_JAIL: ::c_int = 0x0004; ++pub const PS_FST_UFLAG_TRACE: ::c_int = 0x0008; ++pub const PS_FST_UFLAG_TEXT: ::c_int = 0x0010; ++pub const PS_FST_UFLAG_MMAP: ::c_int = 0x0020; ++pub const PS_FST_UFLAG_CTTY: ::c_int = 0x0040; ++ ++pub const PS_FST_FFLAG_READ: ::c_int = 0x0001; ++pub const PS_FST_FFLAG_WRITE: ::c_int = 0x0002; ++pub const PS_FST_FFLAG_NONBLOCK: ::c_int = 0x0004; ++pub const PS_FST_FFLAG_APPEND: ::c_int = 0x0008; ++pub const PS_FST_FFLAG_SHLOCK: ::c_int = 0x0010; ++pub const PS_FST_FFLAG_EXLOCK: ::c_int = 0x0020; ++pub const PS_FST_FFLAG_ASYNC: ::c_int = 0x0040; ++pub const PS_FST_FFLAG_SYNC: ::c_int = 0x0080; ++pub const PS_FST_FFLAG_NOFOLLOW: ::c_int = 0x0100; ++pub const PS_FST_FFLAG_CREAT: ::c_int = 0x0200; ++pub const PS_FST_FFLAG_TRUNC: ::c_int = 0x0400; ++pub const PS_FST_FFLAG_EXCL: ::c_int = 0x0800; ++pub const PS_FST_FFLAG_DIRECT: ::c_int = 0x1000; ++pub const PS_FST_FFLAG_EXEC: ::c_int = 0x2000; ++pub const PS_FST_FFLAG_HASLOCK: ::c_int = 0x4000; ++ ++// sys/mount.h ++ ++/// File identifier. ++/// These are unique per filesystem on a single machine. ++/// ++/// Note that the offset of fid_data is 4 bytes, so care must be taken to avoid ++/// undefined behavior accessing unaligned fields within an embedded struct. ++pub const MAXFIDSZ: ::c_int = 16; ++/// Length of type name including null. ++pub const MFSNAMELEN: ::c_int = 16; ++cfg_if! { ++ if #[cfg(any(freebsd10, freebsd11))] { ++ /// Size of on/from name bufs. ++ pub const MNAMELEN: ::c_int = 88; ++ } else { ++ /// Size of on/from name bufs. ++ pub const MNAMELEN: ::c_int = 1024; ++ } ++} ++ ++/// Using journaled soft updates. ++pub const MNT_SUJ: u64 = 0x100000000; ++/// Mounted by automountd(8). ++pub const MNT_AUTOMOUNTED: u64 = 0x200000000; ++/// Filesys metadata untrusted. ++pub const MNT_UNTRUSTED: u64 = 0x800000000; ++ ++/// Require TLS. ++pub const MNT_EXTLS: u64 = 0x4000000000; ++/// Require TLS with client cert. ++pub const MNT_EXTLSCERT: u64 = 0x8000000000; ++/// Require TLS with user cert. ++pub const MNT_EXTLSCERTUSER: u64 = 0x10000000000; ++ ++/// Filesystem is stored locally. ++pub const MNT_LOCAL: u64 = 0x000001000; ++/// Quotas are enabled on fs. ++pub const MNT_QUOTA: u64 = 0x000002000; ++/// Identifies the root fs. ++pub const MNT_ROOTFS: u64 = 0x000004000; ++/// Mounted by a user. ++pub const MNT_USER: u64 = 0x000008000; ++/// Do not show entry in df. ++pub const MNT_IGNORE: u64 = 0x000800000; ++/// Filesystem is verified. ++pub const MNT_VERIFIED: u64 = 0x400000000; ++ ++/// Do not cover a mount point. ++pub const MNT_NOCOVER: u64 = 0x001000000000; ++/// Only mount on empty dir. ++pub const MNT_EMPTYDIR: u64 = 0x002000000000; ++/// Recursively unmount uppers. ++pub const MNT_RECURSE: u64 = 0x100000000000; ++/// Unmount in async context. ++pub const MNT_DEFERRED: u64 = 0x200000000000; ++ ++/// Get configured filesystems. ++pub const VFS_VFSCONF: ::c_int = 0; ++/// Generic filesystem information. ++pub const VFS_GENERIC: ::c_int = 0; ++ ++/// int: highest defined filesystem type. ++pub const VFS_MAXTYPENUM: ::c_int = 1; ++/// struct: vfsconf for filesystem given as next argument. ++pub const VFS_CONF: ::c_int = 2; ++ ++/// Synchronously wait for I/O to complete. ++pub const MNT_WAIT: ::c_int = 1; ++/// Start all I/O, but do not wait for it. ++pub const MNT_NOWAIT: ::c_int = 2; ++/// Push data not written by filesystem syncer. ++pub const MNT_LAZY: ::c_int = 3; ++/// Suspend file system after sync. ++pub const MNT_SUSPEND: ::c_int = 4; ++ ++pub const MAXSECFLAVORS: ::c_int = 5; ++ ++/// Statically compiled into kernel. ++pub const VFCF_STATIC: ::c_int = 0x00010000; ++/// May get data over the network. ++pub const VFCF_NETWORK: ::c_int = 0x00020000; ++/// Writes are not implemented. ++pub const VFCF_READONLY: ::c_int = 0x00040000; ++/// Data does not represent real files. ++pub const VFCF_SYNTHETIC: ::c_int = 0x00080000; ++/// Aliases some other mounted FS. ++pub const VFCF_LOOPBACK: ::c_int = 0x00100000; ++/// Stores file names as Unicode. ++pub const VFCF_UNICODE: ::c_int = 0x00200000; ++/// Can be mounted from within a jail. ++pub const VFCF_JAIL: ::c_int = 0x00400000; ++/// Supports delegated administration. ++pub const VFCF_DELEGADMIN: ::c_int = 0x00800000; ++/// Stop at Boundary: defer stop requests to kernel->user (AST) transition. ++pub const VFCF_SBDRY: ::c_int = 0x01000000; ++ ++// time.h ++ ++/// not on dst ++pub const DST_NONE: ::c_int = 0; ++/// USA style dst ++pub const DST_USA: ::c_int = 1; ++/// Australian style dst ++pub const DST_AUST: ::c_int = 2; ++/// Western European dst ++pub const DST_WET: ::c_int = 3; ++/// Middle European dst ++pub const DST_MET: ::c_int = 4; ++/// Eastern European dst ++pub const DST_EET: ::c_int = 5; ++/// Canada ++pub const DST_CAN: ::c_int = 6; ++ ++pub const CPUCLOCK_WHICH_PID: ::c_int = 0; ++pub const CPUCLOCK_WHICH_TID: ::c_int = 1; ++ ++pub const MFD_CLOEXEC: ::c_uint = 0x00000001; ++pub const MFD_ALLOW_SEALING: ::c_uint = 0x00000002; ++pub const MFD_HUGETLB: ::c_uint = 0x00000004; ++pub const MFD_HUGE_MASK: ::c_uint = 0xFC000000; ++pub const MFD_HUGE_64KB: ::c_uint = 16 << 26; ++pub const MFD_HUGE_512KB: ::c_uint = 19 << 26; ++pub const MFD_HUGE_1MB: ::c_uint = 20 << 26; ++pub const MFD_HUGE_2MB: ::c_uint = 21 << 26; ++pub const MFD_HUGE_8MB: ::c_uint = 23 << 26; ++pub const MFD_HUGE_16MB: ::c_uint = 24 << 26; ++pub const MFD_HUGE_32MB: ::c_uint = 25 << 26; ++pub const MFD_HUGE_256MB: ::c_uint = 28 << 26; ++pub const MFD_HUGE_512MB: ::c_uint = 29 << 26; ++pub const MFD_HUGE_1GB: ::c_uint = 30 << 26; ++pub const MFD_HUGE_2GB: ::c_uint = 31 << 26; ++pub const MFD_HUGE_16GB: ::c_uint = 34 << 26; ++ ++pub const SHM_LARGEPAGE_ALLOC_DEFAULT: ::c_int = 0; ++pub const SHM_LARGEPAGE_ALLOC_NOWAIT: ::c_int = 1; ++pub const SHM_LARGEPAGE_ALLOC_HARD: ::c_int = 2; ++pub const SHM_RENAME_NOREPLACE: ::c_int = 1 << 0; ++pub const SHM_RENAME_EXCHANGE: ::c_int = 1 << 1; ++ ++// sys/umtx.h ++ ++pub const UMTX_OP_WAIT: ::c_int = 2; ++pub const UMTX_OP_WAKE: ::c_int = 3; ++pub const UMTX_OP_MUTEX_TRYLOCK: ::c_int = 4; ++pub const UMTX_OP_MUTEX_LOCK: ::c_int = 5; ++pub const UMTX_OP_MUTEX_UNLOCK: ::c_int = 6; ++pub const UMTX_OP_SET_CEILING: ::c_int = 7; ++pub const UMTX_OP_CV_WAIT: ::c_int = 8; ++pub const UMTX_OP_CV_SIGNAL: ::c_int = 9; ++pub const UMTX_OP_CV_BROADCAST: ::c_int = 10; ++pub const UMTX_OP_WAIT_UINT: ::c_int = 11; ++pub const UMTX_OP_RW_RDLOCK: ::c_int = 12; ++pub const UMTX_OP_RW_WRLOCK: ::c_int = 13; ++pub const UMTX_OP_RW_UNLOCK: ::c_int = 14; ++pub const UMTX_OP_WAIT_UINT_PRIVATE: ::c_int = 15; ++pub const UMTX_OP_WAKE_PRIVATE: ::c_int = 16; ++pub const UMTX_OP_MUTEX_WAIT: ::c_int = 17; ++pub const UMTX_OP_NWAKE_PRIVATE: ::c_int = 21; ++pub const UMTX_OP_MUTEX_WAKE2: ::c_int = 22; ++pub const UMTX_OP_SEM2_WAIT: ::c_int = 23; ++pub const UMTX_OP_SEM2_WAKE: ::c_int = 24; ++pub const UMTX_OP_SHM: ::c_int = 25; ++pub const UMTX_OP_ROBUST_LISTS: ::c_int = 26; ++ ++pub const UMTX_ABSTIME: u32 = 1; ++ ++pub const CPU_LEVEL_ROOT: ::c_int = 1; ++pub const CPU_LEVEL_CPUSET: ::c_int = 2; ++pub const CPU_LEVEL_WHICH: ::c_int = 3; ++ ++pub const CPU_WHICH_TID: ::c_int = 1; ++pub const CPU_WHICH_PID: ::c_int = 2; ++pub const CPU_WHICH_CPUSET: ::c_int = 3; ++pub const CPU_WHICH_IRQ: ::c_int = 4; ++pub const CPU_WHICH_JAIL: ::c_int = 5; ++ ++// sys/signal.h ++pub const SIGTHR: ::c_int = 32; ++pub const SIGLWP: ::c_int = SIGTHR; ++pub const SIGLIBRT: ::c_int = 33; ++ ++// netinet/sctp.h ++pub const SCTP_FUTURE_ASSOC: ::c_int = 0; ++pub const SCTP_CURRENT_ASSOC: ::c_int = 1; ++pub const SCTP_ALL_ASSOC: ::c_int = 2; ++ ++pub const SCTP_NO_NEXT_MSG: ::c_int = 0x0000; ++pub const SCTP_NEXT_MSG_AVAIL: ::c_int = 0x0001; ++pub const SCTP_NEXT_MSG_ISCOMPLETE: ::c_int = 0x0002; ++pub const SCTP_NEXT_MSG_IS_UNORDERED: ::c_int = 0x0004; ++pub const SCTP_NEXT_MSG_IS_NOTIFICATION: ::c_int = 0x0008; ++ ++pub const SCTP_RECVV_NOINFO: ::c_int = 0; ++pub const SCTP_RECVV_RCVINFO: ::c_int = 1; ++pub const SCTP_RECVV_NXTINFO: ::c_int = 2; ++pub const SCTP_RECVV_RN: ::c_int = 3; ++ ++pub const SCTP_SENDV_NOINFO: ::c_int = 0; ++pub const SCTP_SENDV_SNDINFO: ::c_int = 1; ++pub const SCTP_SENDV_PRINFO: ::c_int = 2; ++pub const SCTP_SENDV_AUTHINFO: ::c_int = 3; ++pub const SCTP_SENDV_SPA: ::c_int = 4; ++ ++pub const SCTP_SEND_SNDINFO_VALID: ::c_int = 0x00000001; ++pub const SCTP_SEND_PRINFO_VALID: ::c_int = 0x00000002; ++pub const SCTP_SEND_AUTHINFO_VALID: ::c_int = 0x00000004; ++ ++pub const SCTP_NOTIFICATION: ::c_int = 0x0010; ++pub const SCTP_COMPLETE: ::c_int = 0x0020; ++pub const SCTP_EOF: ::c_int = 0x0100; ++pub const SCTP_ABORT: ::c_int = 0x0200; ++pub const SCTP_UNORDERED: ::c_int = 0x0400; ++pub const SCTP_ADDR_OVER: ::c_int = 0x0800; ++pub const SCTP_SENDALL: ::c_int = 0x1000; ++pub const SCTP_EOR: ::c_int = 0x2000; ++pub const SCTP_SACK_IMMEDIATELY: ::c_int = 0x4000; ++pub const SCTP_PR_SCTP_NONE: ::c_int = 0x0000; ++pub const SCTP_PR_SCTP_TTL: ::c_int = 0x0001; ++pub const SCTP_PR_SCTP_PRIO: ::c_int = 0x0002; ++pub const SCTP_PR_SCTP_BUF: ::c_int = SCTP_PR_SCTP_PRIO; ++pub const SCTP_PR_SCTP_RTX: ::c_int = 0x0003; ++pub const SCTP_PR_SCTP_MAX: ::c_int = SCTP_PR_SCTP_RTX; ++pub const SCTP_PR_SCTP_ALL: ::c_int = 0x000f; ++ ++pub const SCTP_INIT: ::c_int = 0x0001; ++pub const SCTP_SNDRCV: ::c_int = 0x0002; ++pub const SCTP_EXTRCV: ::c_int = 0x0003; ++pub const SCTP_SNDINFO: ::c_int = 0x0004; ++pub const SCTP_RCVINFO: ::c_int = 0x0005; ++pub const SCTP_NXTINFO: ::c_int = 0x0006; ++pub const SCTP_PRINFO: ::c_int = 0x0007; ++pub const SCTP_AUTHINFO: ::c_int = 0x0008; ++pub const SCTP_DSTADDRV4: ::c_int = 0x0009; ++pub const SCTP_DSTADDRV6: ::c_int = 0x000a; ++ ++pub const SCTP_RTOINFO: ::c_int = 0x00000001; ++pub const SCTP_ASSOCINFO: ::c_int = 0x00000002; ++pub const SCTP_INITMSG: ::c_int = 0x00000003; ++pub const SCTP_NODELAY: ::c_int = 0x00000004; ++pub const SCTP_AUTOCLOSE: ::c_int = 0x00000005; ++pub const SCTP_SET_PEER_PRIMARY_ADDR: ::c_int = 0x00000006; ++pub const SCTP_PRIMARY_ADDR: ::c_int = 0x00000007; ++pub const SCTP_ADAPTATION_LAYER: ::c_int = 0x00000008; ++pub const SCTP_ADAPTION_LAYER: ::c_int = 0x00000008; ++pub const SCTP_DISABLE_FRAGMENTS: ::c_int = 0x00000009; ++pub const SCTP_PEER_ADDR_PARAMS: ::c_int = 0x0000000a; ++pub const SCTP_DEFAULT_SEND_PARAM: ::c_int = 0x0000000b; ++pub const SCTP_EVENTS: ::c_int = 0x0000000c; ++pub const SCTP_I_WANT_MAPPED_V4_ADDR: ::c_int = 0x0000000d; ++pub const SCTP_MAXSEG: ::c_int = 0x0000000e; ++pub const SCTP_DELAYED_SACK: ::c_int = 0x0000000f; ++pub const SCTP_FRAGMENT_INTERLEAVE: ::c_int = 0x00000010; ++pub const SCTP_PARTIAL_DELIVERY_POINT: ::c_int = 0x00000011; ++pub const SCTP_AUTH_CHUNK: ::c_int = 0x00000012; ++pub const SCTP_AUTH_KEY: ::c_int = 0x00000013; ++pub const SCTP_HMAC_IDENT: ::c_int = 0x00000014; ++pub const SCTP_AUTH_ACTIVE_KEY: ::c_int = 0x00000015; ++pub const SCTP_AUTH_DELETE_KEY: ::c_int = 0x00000016; ++pub const SCTP_USE_EXT_RCVINFO: ::c_int = 0x00000017; ++pub const SCTP_AUTO_ASCONF: ::c_int = 0x00000018; ++pub const SCTP_MAXBURST: ::c_int = 0x00000019; ++pub const SCTP_MAX_BURST: ::c_int = 0x00000019; ++pub const SCTP_CONTEXT: ::c_int = 0x0000001a; ++pub const SCTP_EXPLICIT_EOR: ::c_int = 0x00000001b; ++pub const SCTP_REUSE_PORT: ::c_int = 0x00000001c; ++pub const SCTP_AUTH_DEACTIVATE_KEY: ::c_int = 0x00000001d; ++pub const SCTP_EVENT: ::c_int = 0x0000001e; ++pub const SCTP_RECVRCVINFO: ::c_int = 0x0000001f; ++pub const SCTP_RECVNXTINFO: ::c_int = 0x00000020; ++pub const SCTP_DEFAULT_SNDINFO: ::c_int = 0x00000021; ++pub const SCTP_DEFAULT_PRINFO: ::c_int = 0x00000022; ++pub const SCTP_PEER_ADDR_THLDS: ::c_int = 0x00000023; ++pub const SCTP_REMOTE_UDP_ENCAPS_PORT: ::c_int = 0x00000024; ++pub const SCTP_ECN_SUPPORTED: ::c_int = 0x00000025; ++pub const SCTP_AUTH_SUPPORTED: ::c_int = 0x00000027; ++pub const SCTP_ASCONF_SUPPORTED: ::c_int = 0x00000028; ++pub const SCTP_RECONFIG_SUPPORTED: ::c_int = 0x00000029; ++pub const SCTP_NRSACK_SUPPORTED: ::c_int = 0x00000030; ++pub const SCTP_PKTDROP_SUPPORTED: ::c_int = 0x00000031; ++pub const SCTP_MAX_CWND: ::c_int = 0x00000032; ++ ++pub const SCTP_STATUS: ::c_int = 0x00000100; ++pub const SCTP_GET_PEER_ADDR_INFO: ::c_int = 0x00000101; ++pub const SCTP_PEER_AUTH_CHUNKS: ::c_int = 0x00000102; ++pub const SCTP_LOCAL_AUTH_CHUNKS: ::c_int = 0x00000103; ++pub const SCTP_GET_ASSOC_NUMBER: ::c_int = 0x00000104; ++pub const SCTP_GET_ASSOC_ID_LIST: ::c_int = 0x00000105; ++pub const SCTP_TIMEOUTS: ::c_int = 0x00000106; ++pub const SCTP_PR_STREAM_STATUS: ::c_int = 0x00000107; ++pub const SCTP_PR_ASSOC_STATUS: ::c_int = 0x00000108; ++ ++pub const SCTP_COMM_UP: ::c_int = 0x0001; ++pub const SCTP_COMM_LOST: ::c_int = 0x0002; ++pub const SCTP_RESTART: ::c_int = 0x0003; ++pub const SCTP_SHUTDOWN_COMP: ::c_int = 0x0004; ++pub const SCTP_CANT_STR_ASSOC: ::c_int = 0x0005; ++ ++pub const SCTP_ASSOC_SUPPORTS_PR: ::c_int = 0x01; ++pub const SCTP_ASSOC_SUPPORTS_AUTH: ::c_int = 0x02; ++pub const SCTP_ASSOC_SUPPORTS_ASCONF: ::c_int = 0x03; ++pub const SCTP_ASSOC_SUPPORTS_MULTIBUF: ::c_int = 0x04; ++pub const SCTP_ASSOC_SUPPORTS_RE_CONFIG: ::c_int = 0x05; ++pub const SCTP_ASSOC_SUPPORTS_INTERLEAVING: ::c_int = 0x06; ++pub const SCTP_ASSOC_SUPPORTS_MAX: ::c_int = 0x06; ++ ++pub const SCTP_ADDR_AVAILABLE: ::c_int = 0x0001; ++pub const SCTP_ADDR_UNREACHABLE: ::c_int = 0x0002; ++pub const SCTP_ADDR_REMOVED: ::c_int = 0x0003; ++pub const SCTP_ADDR_ADDED: ::c_int = 0x0004; ++pub const SCTP_ADDR_MADE_PRIM: ::c_int = 0x0005; ++pub const SCTP_ADDR_CONFIRMED: ::c_int = 0x0006; ++ ++pub const SCTP_ACTIVE: ::c_int = 0x0001; ++pub const SCTP_INACTIVE: ::c_int = 0x0002; ++pub const SCTP_UNCONFIRMED: ::c_int = 0x0200; ++ ++pub const SCTP_DATA_UNSENT: ::c_int = 0x0001; ++pub const SCTP_DATA_SENT: ::c_int = 0x0002; ++ ++pub const SCTP_PARTIAL_DELIVERY_ABORTED: ::c_int = 0x0001; ++ ++pub const SCTP_AUTH_NEW_KEY: ::c_int = 0x0001; ++pub const SCTP_AUTH_NEWKEY: ::c_int = SCTP_AUTH_NEW_KEY; ++pub const SCTP_AUTH_NO_AUTH: ::c_int = 0x0002; ++pub const SCTP_AUTH_FREE_KEY: ::c_int = 0x0003; ++ ++pub const SCTP_STREAM_RESET_INCOMING_SSN: ::c_int = 0x0001; ++pub const SCTP_STREAM_RESET_OUTGOING_SSN: ::c_int = 0x0002; ++pub const SCTP_STREAM_RESET_DENIED: ::c_int = 0x0004; ++pub const SCTP_STREAM_RESET_FAILED: ::c_int = 0x0008; ++ ++pub const SCTP_ASSOC_RESET_DENIED: ::c_int = 0x0004; ++pub const SCTP_ASSOC_RESET_FAILED: ::c_int = 0x0008; ++ ++pub const SCTP_STREAM_CHANGE_DENIED: ::c_int = 0x0004; ++pub const SCTP_STREAM_CHANGE_FAILED: ::c_int = 0x0008; ++ ++cfg_if! { ++ if #[cfg(libc_const_extern_fn)] { ++ pub const fn MAP_ALIGNED(a: ::c_int) -> ::c_int { ++ a << 24 ++ } ++ } else { ++ pub fn MAP_ALIGNED(a: ::c_int) -> ::c_int { ++ a << 24 ++ } ++ } ++} ++ + const_fn! { + {const} fn _ALIGN(p: usize) -> usize { + (p + _ALIGNBYTES) & !_ALIGNBYTES +@@ -1289,6 +4721,18 @@ f! { + as ::c_uint + } + ++ pub fn MALLOCX_ALIGN(lg: ::c_uint) -> ::c_int { ++ ffsl(lg as ::c_long - 1) ++ } ++ ++ pub {const} fn MALLOCX_TCACHE(tc: ::c_int) -> ::c_int { ++ (tc + 2) << 8 as ::c_int ++ } ++ ++ pub {const} fn MALLOCX_ARENA(a: ::c_int) -> ::c_int { ++ (a + 1) << 20 as ::c_int ++ } ++ + pub fn SOCKCREDSIZE(ngrps: usize) -> usize { + let ngrps = if ngrps > 0 { + ngrps - 1 +@@ -1315,39 +4759,115 @@ f! { + } + + pub fn CPU_SET(cpu: usize, cpuset: &mut cpuset_t) -> () { +- let bitset_bits = ::mem::size_of::<::c_long>(); ++ let bitset_bits = 8 * ::mem::size_of::<::c_long>(); + let (idx, offset) = (cpu / bitset_bits, cpu % bitset_bits); + cpuset.__bits[idx] |= 1 << offset; + () + } + + pub fn CPU_CLR(cpu: usize, cpuset: &mut cpuset_t) -> () { +- let bitset_bits = ::mem::size_of::<::c_long>(); ++ let bitset_bits = 8 * ::mem::size_of::<::c_long>(); + let (idx, offset) = (cpu / bitset_bits, cpu % bitset_bits); + cpuset.__bits[idx] &= !(1 << offset); + () + } + +- pub fn CPU_ISSET(cpu: usize, cpuset: &mut cpuset_t) -> bool { +- let bitset_bits = ::mem::size_of::<::c_long>(); ++ pub fn CPU_ISSET(cpu: usize, cpuset: &cpuset_t) -> bool { ++ let bitset_bits = 8 * ::mem::size_of::<::c_long>(); + let (idx, offset) = (cpu / bitset_bits, cpu % bitset_bits); + 0 != cpuset.__bits[idx] & (1 << offset) + } ++ ++ pub fn CPU_COUNT(cpuset: &cpuset_t) -> ::c_int { ++ let mut s: u32 = 0; ++ let cpuset_size = ::mem::size_of::(); ++ let bitset_size = ::mem::size_of::<::c_long>(); ++ ++ for i in cpuset.__bits[..(cpuset_size / bitset_size)].iter() { ++ s += i.count_ones(); ++ }; ++ s as ::c_int ++ } ++ ++ pub fn SOCKCRED2SIZE(ngrps: usize) -> usize { ++ let ngrps = if ngrps > 0 { ++ ngrps - 1 ++ } else { ++ 0 ++ }; ++ ::mem::size_of::() + ::mem::size_of::<::gid_t>() * ngrps ++ } + } + + safe_f! { + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + (status & 0o177) != 0o177 && (status & 0o177) != 0 && status != 0x13 + } ++ ++ pub {const} fn INVALID_SINFO_FLAG(x: ::c_int) -> bool { ++ (x) & 0xfffffff0 & !(SCTP_EOF | SCTP_ABORT | SCTP_UNORDERED | ++ SCTP_ADDR_OVER | SCTP_SENDALL | SCTP_EOR | SCTP_SACK_IMMEDIATELY) != 0 ++ } ++ ++ pub {const} fn PR_SCTP_POLICY(x: ::c_int) -> ::c_int { ++ x & 0x0f ++ } ++ ++ pub {const} fn PR_SCTP_ENABLED(x: ::c_int) -> bool { ++ PR_SCTP_POLICY(x) != SCTP_PR_SCTP_NONE && PR_SCTP_POLICY(x) != SCTP_PR_SCTP_ALL ++ } ++ ++ pub {const} fn PR_SCTP_TTL_ENABLED(x: ::c_int) -> bool { ++ PR_SCTP_POLICY(x) == SCTP_PR_SCTP_TTL ++ } ++ ++ pub {const} fn PR_SCTP_BUF_ENABLED(x: ::c_int) -> bool { ++ PR_SCTP_POLICY(x) == SCTP_PR_SCTP_BUF ++ } ++ ++ pub {const} fn PR_SCTP_RTX_ENABLED(x: ::c_int) -> bool { ++ PR_SCTP_POLICY(x) == SCTP_PR_SCTP_RTX ++ } ++ ++ pub {const} fn PR_SCTP_INVALID_POLICY(x: ::c_int) -> bool { ++ PR_SCTP_POLICY(x) > SCTP_PR_SCTP_MAX ++ } ++ ++ pub {const} fn PR_SCTP_VALID_POLICY(x: ::c_int) -> bool { ++ PR_SCTP_POLICY(x) <= SCTP_PR_SCTP_MAX ++ } ++} ++ ++cfg_if! { ++ if #[cfg(not(any(freebsd10, freebsd11)))] { ++ extern "C" { ++ pub fn fhlink(fhp: *mut fhandle_t, to: *const ::c_char) -> ::c_int; ++ pub fn fhlinkat(fhp: *mut fhandle_t, tofd: ::c_int, to: *const ::c_char) -> ::c_int; ++ pub fn fhreadlink( ++ fhp: *mut fhandle_t, ++ buf: *mut ::c_char, ++ bufsize: ::size_t, ++ ) -> ::c_int; ++ pub fn getfhat( ++ fd: ::c_int, ++ path: *mut ::c_char, ++ fhp: *mut fhandle, ++ flag: ::c_int, ++ ) -> ::c_int; ++ } ++ } + } + + extern "C" { ++ #[cfg_attr(doc, doc(alias = "__errno_location"))] ++ #[cfg_attr(doc, doc(alias = "errno"))] + pub fn __error() -> *mut ::c_int; + + pub fn aio_cancel(fd: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_error(aiocbp: *const aiocb) -> ::c_int; + pub fn aio_fsync(op: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_read(aiocbp: *mut aiocb) -> ::c_int; ++ pub fn aio_readv(aiocbp: *mut ::aiocb) -> ::c_int; + pub fn aio_return(aiocbp: *mut aiocb) -> ::ssize_t; + pub fn aio_suspend( + aiocb_list: *const *const aiocb, +@@ -1355,6 +4875,23 @@ extern "C" { + timeout: *const ::timespec, + ) -> ::c_int; + pub fn aio_write(aiocbp: *mut aiocb) -> ::c_int; ++ pub fn aio_writev(aiocbp: *mut ::aiocb) -> ::c_int; ++ ++ pub fn copy_file_range( ++ infd: ::c_int, ++ inoffp: *mut ::off_t, ++ outfd: ::c_int, ++ outoffp: *mut ::off_t, ++ len: ::size_t, ++ flags: ::c_uint, ++ ) -> ::ssize_t; ++ ++ pub fn devname_r( ++ dev: ::dev_t, ++ mode: ::mode_t, ++ buf: *mut ::c_char, ++ len: ::c_int, ++ ) -> *mut ::c_char; + + pub fn extattr_delete_fd( + fd: ::c_int, +@@ -1432,6 +4969,14 @@ extern "C" { + nbytes: ::size_t, + ) -> ::ssize_t; + ++ pub fn fspacectl( ++ fd: ::c_int, ++ cmd: ::c_int, ++ rqsr: *const spacectl_range, ++ flags: ::c_int, ++ rmsr: *mut spacectl_range, ++ ) -> ::c_int; ++ + pub fn jail(jail: *mut ::jail) -> ::c_int; + pub fn jail_attach(jid: ::c_int) -> ::c_int; + pub fn jail_remove(jid: ::c_int) -> ::c_int; +@@ -1445,8 +4990,6 @@ extern "C" { + sevp: *mut sigevent, + ) -> ::c_int; + +- pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; +- pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, advise: ::c_int) -> ::c_int; + pub fn mkostemp(template: *mut ::c_char, flags: ::c_int) -> ::c_int; + pub fn mkostemps(template: *mut ::c_char, suffixlen: ::c_int, flags: ::c_int) -> ::c_int; + +@@ -1462,12 +5005,16 @@ extern "C" { + infop: *mut ::siginfo_t, + options: ::c_int, + ) -> ::c_int; ++ pub fn ptsname_r(fd: ::c_int, buf: *mut ::c_char, buflen: ::size_t) -> ::c_int; + + pub fn ftok(pathname: *const ::c_char, proj_id: ::c_int) -> ::key_t; + pub fn shmget(key: ::key_t, size: ::size_t, shmflg: ::c_int) -> ::c_int; + pub fn shmat(shmid: ::c_int, shmaddr: *const ::c_void, shmflg: ::c_int) -> *mut ::c_void; + pub fn shmdt(shmaddr: *const ::c_void) -> ::c_int; + pub fn shmctl(shmid: ::c_int, cmd: ::c_int, buf: *mut ::shmid_ds) -> ::c_int; ++ pub fn semget(key: ::key_t, nsems: ::c_int, semflg: ::c_int) -> ::c_int; ++ pub fn semctl(semid: ::c_int, semnum: ::c_int, cmd: ::c_int, ...) -> ::c_int; ++ pub fn semop(semid: ::c_int, sops: *mut sembuf, nsops: ::size_t) -> ::c_int; + pub fn msgctl(msqid: ::c_int, cmd: ::c_int, buf: *mut ::msqid_ds) -> ::c_int; + pub fn msgget(key: ::key_t, msgflg: ::c_int) -> ::c_int; + pub fn msgsnd( +@@ -1477,11 +5024,6 @@ extern "C" { + msgflg: ::c_int, + ) -> ::c_int; + pub fn cfmakesane(termios: *mut ::termios); +- pub fn fexecve( +- fd: ::c_int, +- argv: *const *const ::c_char, +- envp: *const *const ::c_char, +- ) -> ::c_int; + + pub fn pdfork(fdp: *mut ::c_int, flags: ::c_int) -> ::pid_t; + pub fn pdgetpid(fd: ::c_int, pidp: *mut ::pid_t) -> ::c_int; +@@ -1566,7 +5108,48 @@ extern "C" { + newfd: ::c_int, + ) -> ::c_int; + ++ pub fn uuidgen(store: *mut uuid, count: ::c_int) -> ::c_int; ++ ++ pub fn thr_kill(id: ::c_long, sig: ::c_int) -> ::c_int; ++ pub fn thr_kill2(pid: ::pid_t, id: ::c_long, sig: ::c_int) -> ::c_int; ++ pub fn thr_self(tid: *mut ::c_long) -> ::c_int; + pub fn pthread_getthreadid_np() -> ::c_int; ++ pub fn pthread_getaffinity_np( ++ td: ::pthread_t, ++ cpusetsize: ::size_t, ++ cpusetp: *mut cpuset_t, ++ ) -> ::c_int; ++ pub fn pthread_setaffinity_np( ++ td: ::pthread_t, ++ cpusetsize: ::size_t, ++ cpusetp: *const cpuset_t, ++ ) -> ::c_int; ++ ++ // sched.h linux compatibility api ++ pub fn sched_getaffinity(pid: ::pid_t, cpusetsz: ::size_t, cpuset: *mut ::cpuset_t) -> ::c_int; ++ pub fn sched_setaffinity( ++ pid: ::pid_t, ++ cpusetsz: ::size_t, ++ cpuset: *const ::cpuset_t, ++ ) -> ::c_int; ++ pub fn sched_getcpu() -> ::c_int; ++ ++ pub fn pthread_mutex_consistent(mutex: *mut ::pthread_mutex_t) -> ::c_int; ++ ++ pub fn pthread_mutexattr_getrobust( ++ attr: *mut ::pthread_mutexattr_t, ++ robust: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_mutexattr_setrobust( ++ attr: *mut ::pthread_mutexattr_t, ++ robust: ::c_int, ++ ) -> ::c_int; ++ ++ pub fn pthread_spin_init(lock: *mut pthread_spinlock_t, pshared: ::c_int) -> ::c_int; ++ pub fn pthread_spin_destroy(lock: *mut pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_lock(lock: *mut pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_trylock(lock: *mut pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_unlock(lock: *mut pthread_spinlock_t) -> ::c_int; + + #[cfg_attr(all(target_os = "freebsd", freebsd11), link_name = "statfs@FBSD_1.0")] + pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int; +@@ -1596,7 +5179,25 @@ extern "C" { + needlelen: ::size_t, + ) -> *mut ::c_void; + ++ pub fn fhopen(fhp: *const fhandle_t, flags: ::c_int) -> ::c_int; ++ pub fn fhstat(fhp: *const fhandle, buf: *mut ::stat) -> ::c_int; ++ pub fn fhstatfs(fhp: *const fhandle_t, buf: *mut ::statfs) -> ::c_int; ++ pub fn getfh(path: *const ::c_char, fhp: *mut fhandle_t) -> ::c_int; ++ pub fn lgetfh(path: *const ::c_char, fhp: *mut fhandle_t) -> ::c_int; ++ pub fn getfsstat(buf: *mut ::statfs, bufsize: ::c_long, mode: ::c_int) -> ::c_int; ++ #[cfg_attr( ++ all(target_os = "freebsd", freebsd11), ++ link_name = "getmntinfo@FBSD_1.0" ++ )] ++ pub fn getmntinfo(mntbufp: *mut *mut ::statfs, mode: ::c_int) -> ::c_int; ++ pub fn mount( ++ type_: *const ::c_char, ++ dir: *const ::c_char, ++ flags: ::c_int, ++ data: *mut ::c_void, ++ ) -> ::c_int; + pub fn nmount(iov: *mut ::iovec, niov: ::c_uint, flags: ::c_int) -> ::c_int; ++ + pub fn setproctitle(fmt: *const ::c_char, ...); + pub fn rfork(flags: ::c_int) -> ::c_int; + pub fn cpuset_getaffinity( +@@ -1613,10 +5214,23 @@ extern "C" { + setsize: ::size_t, + mask: *const cpuset_t, + ) -> ::c_int; ++ pub fn cpuset(setid: *mut ::cpusetid_t) -> ::c_int; ++ pub fn cpuset_getid( ++ level: cpulevel_t, ++ which: cpuwhich_t, ++ id: ::id_t, ++ setid: *mut ::cpusetid_t, ++ ) -> ::c_int; ++ pub fn cpuset_setid(which: cpuwhich_t, id: ::id_t, setid: ::cpusetid_t) -> ::c_int; + pub fn cap_enter() -> ::c_int; + pub fn cap_getmode(modep: *mut ::c_uint) -> ::c_int; ++ pub fn cap_fcntls_get(fd: ::c_int, fcntlrightsp: *mut u32) -> ::c_int; ++ pub fn cap_fcntls_limit(fd: ::c_int, fcntlrights: u32) -> ::c_int; ++ pub fn cap_ioctls_get(fd: ::c_int, cmds: *mut u_long, maxcmds: usize) -> isize; ++ pub fn cap_ioctls_limit(fd: ::c_int, cmds: *const u_long, ncmds: usize) -> ::c_int; + pub fn __cap_rights_init(version: ::c_int, rights: *mut cap_rights_t, ...) + -> *mut cap_rights_t; ++ pub fn __cap_rights_get(version: ::c_int, fd: ::c_int, rightsp: *mut cap_rights_t) -> ::c_int; + pub fn __cap_rights_set(rights: *mut cap_rights_t, ...) -> *mut cap_rights_t; + pub fn __cap_rights_clear(rights: *mut cap_rights_t, ...) -> *mut cap_rights_t; + pub fn __cap_rights_is_set(rights: *const cap_rights_t, ...) -> bool; +@@ -1626,6 +5240,203 @@ extern "C" { + pub fn cap_rights_remove(dst: *mut cap_rights_t, src: *const cap_rights_t) + -> *mut cap_rights_t; + pub fn cap_rights_contains(big: *const cap_rights_t, little: *const cap_rights_t) -> bool; ++ pub fn cap_sandboxed() -> bool; ++ ++ pub fn reallocarray(ptr: *mut ::c_void, nmemb: ::size_t, size: ::size_t) -> *mut ::c_void; ++ ++ pub fn ffs(value: ::c_int) -> ::c_int; ++ pub fn ffsl(value: ::c_long) -> ::c_int; ++ pub fn ffsll(value: ::c_longlong) -> ::c_int; ++ pub fn fls(value: ::c_int) -> ::c_int; ++ pub fn flsl(value: ::c_long) -> ::c_int; ++ pub fn flsll(value: ::c_longlong) -> ::c_int; ++ pub fn malloc_usable_size(ptr: *const ::c_void) -> ::size_t; ++ pub fn malloc_stats_print( ++ write_cb: unsafe extern "C" fn(*mut ::c_void, *const ::c_char), ++ cbopaque: *mut ::c_void, ++ opt: *const ::c_char, ++ ); ++ pub fn mallctl( ++ name: *const ::c_char, ++ oldp: *mut ::c_void, ++ oldlenp: *mut ::size_t, ++ newp: *mut ::c_void, ++ newlen: ::size_t, ++ ) -> ::c_int; ++ pub fn mallctlnametomib( ++ name: *const ::c_char, ++ mibp: *mut ::size_t, ++ miplen: *mut ::size_t, ++ ) -> ::c_int; ++ pub fn mallctlbymib( ++ mib: *const ::size_t, ++ mible: ::size_t, ++ oldp: *mut ::c_void, ++ oldlenp: *mut ::size_t, ++ newp: *mut ::c_void, ++ newlen: ::size_t, ++ ) -> ::c_int; ++ pub fn mallocx(size: ::size_t, flags: ::c_int) -> *mut ::c_void; ++ pub fn rallocx(ptr: *mut ::c_void, size: ::size_t, flags: ::c_int) -> *mut ::c_void; ++ pub fn xallocx(ptr: *mut ::c_void, size: ::size_t, extra: ::size_t, flags: ::c_int) ++ -> ::size_t; ++ pub fn sallocx(ptr: *const ::c_void, flags: ::c_int) -> ::size_t; ++ pub fn dallocx(ptr: *mut ::c_void, flags: ::c_int); ++ pub fn sdallocx(ptr: *mut ::c_void, size: ::size_t, flags: ::c_int); ++ pub fn nallocx(size: ::size_t, flags: ::c_int) -> ::size_t; ++ ++ pub fn procctl(idtype: ::idtype_t, id: ::id_t, cmd: ::c_int, data: *mut ::c_void) -> ::c_int; ++ ++ pub fn getpagesize() -> ::c_int; ++ pub fn getpagesizes(pagesize: *mut ::size_t, nelem: ::c_int) -> ::c_int; ++ ++ pub fn clock_getcpuclockid2(arg1: ::id_t, arg2: ::c_int, arg3: *mut clockid_t) -> ::c_int; ++ pub fn clock_nanosleep( ++ clk_id: ::clockid_t, ++ flags: ::c_int, ++ rqtp: *const ::timespec, ++ rmtp: *mut ::timespec, ++ ) -> ::c_int; ++ ++ pub fn strchrnul(s: *const ::c_char, c: ::c_int) -> *mut ::c_char; ++ ++ pub fn shm_create_largepage( ++ path: *const ::c_char, ++ flags: ::c_int, ++ psind: ::c_int, ++ alloc_policy: ::c_int, ++ mode: ::mode_t, ++ ) -> ::c_int; ++ pub fn shm_rename( ++ path_from: *const ::c_char, ++ path_to: *const ::c_char, ++ flags: ::c_int, ++ ) -> ::c_int; ++ pub fn memfd_create(name: *const ::c_char, flags: ::c_uint) -> ::c_int; ++ pub fn setaudit(auditinfo: *const auditinfo_t) -> ::c_int; ++ ++ pub fn eventfd(init: ::c_uint, flags: ::c_int) -> ::c_int; ++ ++ pub fn fdatasync(fd: ::c_int) -> ::c_int; ++ ++ pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; ++ pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; ++ pub fn elf_aux_info(aux: ::c_int, buf: *mut ::c_void, buflen: ::c_int) -> ::c_int; ++ pub fn setproctitle_fast(fmt: *const ::c_char, ...); ++ pub fn timingsafe_bcmp(a: *const ::c_void, b: *const ::c_void, len: ::size_t) -> ::c_int; ++ pub fn timingsafe_memcmp(a: *const ::c_void, b: *const ::c_void, len: ::size_t) -> ::c_int; ++ ++ pub fn _umtx_op( ++ obj: *mut ::c_void, ++ op: ::c_int, ++ val: ::c_ulong, ++ uaddr: *mut ::c_void, ++ uaddr2: *mut ::c_void, ++ ) -> ::c_int; ++ ++ pub fn sctp_peeloff(s: ::c_int, id: ::sctp_assoc_t) -> ::c_int; ++ pub fn sctp_bindx(s: ::c_int, addrs: *mut ::sockaddr, num: ::c_int, tpe: ::c_int) -> ::c_int; ++ pub fn sctp_connectx( ++ s: ::c_int, ++ addrs: *const ::sockaddr, ++ addrcnt: ::c_int, ++ id: *mut ::sctp_assoc_t, ++ ) -> ::c_int; ++ pub fn sctp_getaddrlen(family: ::sa_family_t) -> ::c_int; ++ pub fn sctp_getpaddrs( ++ s: ::c_int, ++ asocid: ::sctp_assoc_t, ++ addrs: *mut *mut ::sockaddr, ++ ) -> ::c_int; ++ pub fn sctp_freepaddrs(addrs: *mut ::sockaddr); ++ pub fn sctp_getladdrs( ++ s: ::c_int, ++ asocid: ::sctp_assoc_t, ++ addrs: *mut *mut ::sockaddr, ++ ) -> ::c_int; ++ pub fn sctp_freeladdrs(addrs: *mut ::sockaddr); ++ pub fn sctp_opt_info( ++ s: ::c_int, ++ id: ::sctp_assoc_t, ++ opt: ::c_int, ++ arg: *mut ::c_void, ++ size: *mut ::socklen_t, ++ ) -> ::c_int; ++ pub fn sctp_sendv( ++ sd: ::c_int, ++ iov: *const ::iovec, ++ iovcnt: ::c_int, ++ addrs: *mut ::sockaddr, ++ addrcnt: ::c_int, ++ info: *mut ::c_void, ++ infolen: ::socklen_t, ++ infotype: ::c_uint, ++ flags: ::c_int, ++ ) -> ::ssize_t; ++ pub fn sctp_recvv( ++ sd: ::c_int, ++ iov: *const ::iovec, ++ iovcnt: ::c_int, ++ from: *mut ::sockaddr, ++ fromlen: *mut ::socklen_t, ++ info: *mut ::c_void, ++ infolen: *mut ::socklen_t, ++ infotype: *mut ::c_uint, ++ flags: *mut ::c_int, ++ ) -> ::ssize_t; ++} ++ ++#[link(name = "memstat")] ++extern "C" { ++ pub fn memstat_strerror(error: ::c_int) -> *const ::c_char; ++ pub fn memstat_mtl_alloc() -> *mut memory_type_list; ++ pub fn memstat_mtl_first(list: *mut memory_type_list) -> *mut memory_type; ++ pub fn memstat_mtl_next(mtp: *mut memory_type) -> *mut memory_type; ++ pub fn memstat_mtl_find( ++ list: *mut memory_type_list, ++ allocator: ::c_int, ++ name: *const ::c_char, ++ ) -> *mut memory_type; ++ pub fn memstat_mtl_free(list: *mut memory_type_list); ++ pub fn memstat_mtl_geterror(list: *mut memory_type_list) -> ::c_int; ++ pub fn memstat_get_name(mtp: *const memory_type) -> *const ::c_char; ++} ++ ++#[link(name = "kvm")] ++extern "C" { ++ pub fn kvm_dpcpu_setcpu(kd: *mut ::kvm_t, cpu: ::c_uint) -> ::c_int; ++ pub fn kvm_getargv(kd: *mut ::kvm_t, p: *const kinfo_proc, nchr: ::c_int) ++ -> *mut *mut ::c_char; ++ pub fn kvm_getcptime(kd: *mut ::kvm_t, cp_time: *mut ::c_long) -> ::c_int; ++ pub fn kvm_getenvv(kd: *mut ::kvm_t, p: *const kinfo_proc, nchr: ::c_int) ++ -> *mut *mut ::c_char; ++ pub fn kvm_geterr(kd: *mut ::kvm_t) -> *mut ::c_char; ++ pub fn kvm_getmaxcpu(kd: *mut ::kvm_t) -> ::c_int; ++ pub fn kvm_getncpus(kd: *mut ::kvm_t) -> ::c_int; ++ pub fn kvm_getpcpu(kd: *mut ::kvm_t, cpu: ::c_int) -> *mut ::c_void; ++ pub fn kvm_counter_u64_fetch(kd: *mut ::kvm_t, base: ::c_ulong) -> u64; ++ pub fn kvm_getswapinfo( ++ kd: *mut ::kvm_t, ++ info: *mut kvm_swap, ++ maxswap: ::c_int, ++ flags: ::c_int, ++ ) -> ::c_int; ++ pub fn kvm_native(kd: *mut ::kvm_t) -> ::c_int; ++ pub fn kvm_nlist(kd: *mut ::kvm_t, nl: *mut nlist) -> ::c_int; ++ pub fn kvm_nlist2(kd: *mut ::kvm_t, nl: *mut kvm_nlist) -> ::c_int; ++ pub fn kvm_read_zpcpu( ++ kd: *mut ::kvm_t, ++ base: ::c_ulong, ++ buf: *mut ::c_void, ++ size: ::size_t, ++ cpu: ::c_int, ++ ) -> ::ssize_t; ++ pub fn kvm_read2( ++ kd: *mut ::kvm_t, ++ addr: kvaddr_t, ++ buf: *mut ::c_void, ++ nbytes: ::size_t, ++ ) -> ::ssize_t; + } + + #[link(name = "util")] +@@ -1645,10 +5456,179 @@ extern "C" { + addr: *mut ::sockaddr, + addrlen: ::c_int, + ) -> ::c_int; ++ ++ pub fn kld_isloaded(name: *const ::c_char) -> ::c_int; ++ pub fn kld_load(name: *const ::c_char) -> ::c_int; ++ ++ pub fn kinfo_getvmmap(pid: ::pid_t, cntp: *mut ::c_int) -> *mut kinfo_vmentry; ++ ++ pub fn hexdump(ptr: *const ::c_void, length: ::c_int, hdr: *const ::c_char, flags: ::c_int); ++ pub fn humanize_number( ++ buf: *mut ::c_char, ++ len: ::size_t, ++ number: i64, ++ suffix: *const ::c_char, ++ scale: ::c_int, ++ flags: ::c_int, ++ ) -> ::c_int; ++ ++ pub fn flopen(path: *const ::c_char, flags: ::c_int, ...) -> ::c_int; ++ pub fn flopenat(fd: ::c_int, path: *const ::c_char, flags: ::c_int, ...) -> ::c_int; ++ ++ pub fn getlocalbase() -> *const ::c_char; ++ ++ pub fn pidfile_open( ++ path: *const ::c_char, ++ mode: ::mode_t, ++ pidptr: *mut ::pid_t, ++ ) -> *mut ::pidfh; ++ pub fn pidfile_write(path: *mut ::pidfh) -> ::c_int; ++ pub fn pidfile_close(path: *mut ::pidfh) -> ::c_int; ++ pub fn pidfile_remove(path: *mut ::pidfh) -> ::c_int; ++ pub fn pidfile_fileno(path: *const ::pidfh) -> ::c_int; ++ // FIXME: pidfile_signal in due time (both manpage present and updated image snapshot) ++} ++ ++#[link(name = "procstat")] ++extern "C" { ++ pub fn procstat_open_sysctl() -> *mut procstat; ++ pub fn procstat_getfiles( ++ procstat: *mut procstat, ++ kp: *mut kinfo_proc, ++ mmapped: ::c_int, ++ ) -> *mut filestat_list; ++ pub fn procstat_freefiles(procstat: *mut procstat, head: *mut filestat_list); ++ pub fn procstat_getprocs( ++ procstat: *mut procstat, ++ what: ::c_int, ++ arg: ::c_int, ++ count: *mut ::c_uint, ++ ) -> *mut kinfo_proc; ++ pub fn procstat_freeprocs(procstat: *mut procstat, p: *mut kinfo_proc); ++ pub fn procstat_getvmmap( ++ procstat: *mut procstat, ++ kp: *mut kinfo_proc, ++ count: *mut ::c_uint, ++ ) -> *mut kinfo_vmentry; ++ pub fn procstat_freevmmap(procstat: *mut procstat, vmmap: *mut kinfo_vmentry); ++ pub fn procstat_close(procstat: *mut procstat); ++ pub fn procstat_freeargv(procstat: *mut procstat); ++ pub fn procstat_freeenvv(procstat: *mut procstat); ++ pub fn procstat_freegroups(procstat: *mut procstat, groups: *mut ::gid_t); ++ pub fn procstat_freeptlwpinfo(procstat: *mut procstat, pl: *mut ptrace_lwpinfo); ++ pub fn procstat_getargv( ++ procstat: *mut procstat, ++ kp: *mut kinfo_proc, ++ nchr: ::size_t, ++ ) -> *mut *mut ::c_char; ++ pub fn procstat_getenvv( ++ procstat: *mut procstat, ++ kp: *mut kinfo_proc, ++ nchr: ::size_t, ++ ) -> *mut *mut ::c_char; ++ pub fn procstat_getgroups( ++ procstat: *mut procstat, ++ kp: *mut kinfo_proc, ++ count: *mut ::c_uint, ++ ) -> *mut ::gid_t; ++ pub fn procstat_getosrel( ++ procstat: *mut procstat, ++ kp: *mut kinfo_proc, ++ osrelp: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn procstat_getpathname( ++ procstat: *mut procstat, ++ kp: *mut kinfo_proc, ++ pathname: *mut ::c_char, ++ maxlen: ::size_t, ++ ) -> ::c_int; ++ pub fn procstat_getrlimit( ++ procstat: *mut procstat, ++ kp: *mut kinfo_proc, ++ which: ::c_int, ++ rlimit: *mut ::rlimit, ++ ) -> ::c_int; ++ pub fn procstat_getumask( ++ procstat: *mut procstat, ++ kp: *mut kinfo_proc, ++ maskp: *mut ::c_ushort, ++ ) -> ::c_int; ++ pub fn procstat_open_core(filename: *const ::c_char) -> *mut procstat; ++ pub fn procstat_open_kvm(nlistf: *const ::c_char, memf: *const ::c_char) -> *mut procstat; ++ pub fn procstat_get_socket_info( ++ proc_: *mut procstat, ++ fst: *mut filestat, ++ sock: *mut sockstat, ++ errbuf: *mut ::c_char, ++ ) -> ::c_int; ++ pub fn procstat_get_vnode_info( ++ proc_: *mut procstat, ++ fst: *mut filestat, ++ vn: *mut vnstat, ++ errbuf: *mut ::c_char, ++ ) -> ::c_int; ++ pub fn procstat_get_pts_info( ++ proc_: *mut procstat, ++ fst: *mut filestat, ++ pts: *mut ptsstat, ++ errbuf: *mut ::c_char, ++ ) -> ::c_int; ++ pub fn procstat_get_shm_info( ++ proc_: *mut procstat, ++ fst: *mut filestat, ++ shm: *mut shmstat, ++ errbuf: *mut ::c_char, ++ ) -> ::c_int; ++} ++ ++#[link(name = "rt")] ++extern "C" { ++ pub fn timer_create(clock_id: clockid_t, evp: *mut sigevent, timerid: *mut timer_t) -> ::c_int; ++ pub fn timer_delete(timerid: timer_t) -> ::c_int; ++ pub fn timer_getoverrun(timerid: timer_t) -> ::c_int; ++ pub fn timer_gettime(timerid: timer_t, value: *mut itimerspec) -> ::c_int; ++ pub fn timer_settime( ++ timerid: timer_t, ++ flags: ::c_int, ++ value: *const itimerspec, ++ ovalue: *mut itimerspec, ++ ) -> ::c_int; ++} ++ ++#[link(name = "devstat")] ++extern "C" { ++ pub fn devstat_getnumdevs(kd: *mut ::kvm_t) -> ::c_int; ++ pub fn devstat_getgeneration(kd: *mut ::kvm_t) -> ::c_long; ++ pub fn devstat_getversion(kd: *mut ::kvm_t) -> ::c_int; ++ pub fn devstat_checkversion(kd: *mut ::kvm_t) -> ::c_int; ++ pub fn devstat_selectdevs( ++ dev_select: *mut *mut device_selection, ++ num_selected: *mut ::c_int, ++ num_selections: *mut ::c_int, ++ select_generation: *mut ::c_long, ++ current_generation: ::c_long, ++ devices: *mut devstat, ++ numdevs: ::c_int, ++ matches: *mut devstat_match, ++ num_matches: ::c_int, ++ dev_selections: *mut *mut ::c_char, ++ num_dev_selections: ::c_int, ++ select_mode: devstat_select_mode, ++ maxshowdevs: ::c_int, ++ perf_select: ::c_int, ++ ) -> ::c_int; ++ pub fn devstat_buildmatch( ++ match_str: *mut ::c_char, ++ matches: *mut *mut devstat_match, ++ num_matches: *mut ::c_int, ++ ) -> ::c_int; + } + + cfg_if! { +- if #[cfg(freebsd13)] { ++ if #[cfg(freebsd14)] { ++ mod freebsd14; ++ pub use self::freebsd14::*; ++ } else if #[cfg(freebsd13)] { + mod freebsd13; + pub use self::freebsd13::*; + } else if #[cfg(freebsd12)] { +@@ -1678,6 +5658,12 @@ cfg_if! { + } else if #[cfg(target_arch = "powerpc64")] { + mod powerpc64; + pub use self::powerpc64::*; ++ } else if #[cfg(target_arch = "powerpc")] { ++ mod powerpc; ++ pub use self::powerpc::*; ++ } else if #[cfg(target_arch = "riscv64")] { ++ mod riscv64; ++ pub use self::riscv64::*; + } else { + // Unknown target_arch + } +diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc.rs +new file mode 100644 +index 0000000..a0120c3 +--- /dev/null ++++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc.rs +@@ -0,0 +1,47 @@ ++pub type c_char = u8; ++pub type c_long = i32; ++pub type c_ulong = u32; ++pub type wchar_t = i32; ++pub type time_t = i64; ++pub type suseconds_t = i32; ++pub type register_t = i32; ++ ++s! { ++ pub struct stat { ++ pub st_dev: ::dev_t, ++ pub st_ino: ::ino_t, ++ pub st_mode: ::mode_t, ++ pub st_nlink: ::nlink_t, ++ pub st_uid: ::uid_t, ++ pub st_gid: ::gid_t, ++ pub st_rdev: ::dev_t, ++ pub st_atime: ::time_t, ++ pub st_atime_nsec: ::c_long, ++ pub st_mtime: ::time_t, ++ pub st_mtime_nsec: ::c_long, ++ pub st_ctime: ::time_t, ++ pub st_ctime_nsec: ::c_long, ++ pub st_size: ::off_t, ++ pub st_blocks: ::blkcnt_t, ++ pub st_blksize: ::blksize_t, ++ pub st_flags: ::fflags_t, ++ pub st_gen: u32, ++ pub st_lspare: i32, ++ pub st_birthtime: ::time_t, ++ pub st_birthtime_nsec: ::c_long, ++ } ++} ++ ++// should be pub(crate), but that requires Rust 1.18.0 ++cfg_if! { ++ if #[cfg(libc_const_size_of)] { ++ #[doc(hidden)] ++ pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_int>() - 1; ++ } else { ++ #[doc(hidden)] ++ pub const _ALIGNBYTES: usize = 4 - 1; ++ } ++} ++ ++pub const MAP_32BIT: ::c_int = 0x00080000; ++pub const MINSIGSTKSZ: ::size_t = 2048; // 512 * 4 +diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/riscv64.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/riscv64.rs +new file mode 100644 +index 0000000..f9fa1c2 +--- /dev/null ++++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/riscv64.rs +@@ -0,0 +1,154 @@ ++pub type c_char = u8; ++pub type c_long = i64; ++pub type c_ulong = u64; ++pub type wchar_t = ::c_int; ++pub type time_t = i64; ++pub type suseconds_t = ::c_long; ++pub type register_t = i64; ++ ++s_no_extra_traits! { ++ pub struct gpregs { ++ pub gp_ra: ::register_t, ++ pub gp_sp: ::register_t, ++ pub gp_gp: ::register_t, ++ pub gp_tp: ::register_t, ++ pub gp_t: [::register_t; 7], ++ pub gp_s: [::register_t; 12], ++ pub gp_a: [::register_t; 8], ++ pub gp_sepc: ::register_t, ++ pub gp_sstatus: ::register_t, ++ } ++ ++ pub struct fpregs { ++ pub fp_x: [[::register_t; 2]; 32], ++ pub fp_fcsr: ::register_t, ++ pub fp_flags: ::c_int, ++ pub fp_pad: ::c_int, ++ } ++ ++ pub struct mcontext_t { ++ pub mc_gpregs: gpregs, ++ pub mc_fpregs: fpregs, ++ pub mc_flags: ::c_int, ++ pub mc_pad: ::c_int, ++ pub mc_spare: [u64; 8], ++ } ++} ++ ++// should be pub(crate), but that requires Rust 1.18.0 ++cfg_if! { ++ if #[cfg(libc_const_size_of)] { ++ #[doc(hidden)] ++ pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_longlong>() - 1; ++ } else { ++ #[doc(hidden)] ++ pub const _ALIGNBYTES: usize = 8 - 1; ++ } ++} ++ ++cfg_if! { ++ if #[cfg(feature = "extra_traits")] { ++ impl PartialEq for gpregs { ++ fn eq(&self, other: &gpregs) -> bool { ++ self.gp_ra == other.gp_ra && ++ self.gp_sp == other.gp_sp && ++ self.gp_gp == other.gp_gp && ++ self.gp_tp == other.gp_tp && ++ self.gp_t.iter().zip(other.gp_t.iter()).all(|(a, b)| a == b) && ++ self.gp_s.iter().zip(other.gp_s.iter()).all(|(a, b)| a == b) && ++ self.gp_a.iter().zip(other.gp_a.iter()).all(|(a, b)| a == b) && ++ self.gp_sepc == other.gp_sepc && ++ self.gp_sstatus == other.gp_sstatus ++ } ++ } ++ impl Eq for gpregs {} ++ impl ::fmt::Debug for gpregs { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("gpregs") ++ .field("gp_ra", &self.gp_ra) ++ .field("gp_sp", &self.gp_sp) ++ .field("gp_gp", &self.gp_gp) ++ .field("gp_tp", &self.gp_tp) ++ .field("gp_t", &self.gp_t) ++ .field("gp_s", &self.gp_s) ++ .field("gp_a", &self.gp_a) ++ .field("gp_sepc", &self.gp_sepc) ++ .field("gp_sstatus", &self.gp_sstatus) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for gpregs { ++ fn hash(&self, state: &mut H) { ++ self.gp_ra.hash(state); ++ self.gp_sp.hash(state); ++ self.gp_gp.hash(state); ++ self.gp_tp.hash(state); ++ self.gp_t.hash(state); ++ self.gp_s.hash(state); ++ self.gp_a.hash(state); ++ self.gp_sepc.hash(state); ++ self.gp_sstatus.hash(state); ++ } ++ } ++ impl PartialEq for fpregs { ++ fn eq(&self, other: &fpregs) -> bool { ++ self.fp_x == other.fp_x && ++ self.fp_fcsr == other.fp_fcsr && ++ self.fp_flags == other.fp_flags && ++ self.fp_pad == other.fp_pad ++ } ++ } ++ impl Eq for fpregs {} ++ impl ::fmt::Debug for fpregs { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("fpregs") ++ .field("fp_x", &self.fp_x) ++ .field("fp_fcsr", &self.fp_fcsr) ++ .field("fp_flags", &self.fp_flags) ++ .field("fp_pad", &self.fp_pad) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for fpregs { ++ fn hash(&self, state: &mut H) { ++ self.fp_x.hash(state); ++ self.fp_fcsr.hash(state); ++ self.fp_flags.hash(state); ++ self.fp_pad.hash(state); ++ } ++ } ++ impl PartialEq for mcontext_t { ++ fn eq(&self, other: &mcontext_t) -> bool { ++ self.mc_gpregs == other.mc_gpregs && ++ self.mc_fpregs == other.mc_fpregs && ++ self.mc_flags == other.mc_flags && ++ self.mc_pad == other.mc_pad && ++ self.mc_spare.iter().zip(other.mc_spare.iter()).all(|(a, b)| a == b) ++ } ++ } ++ impl Eq for mcontext_t {} ++ impl ::fmt::Debug for mcontext_t { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("mcontext_t") ++ .field("mc_gpregs", &self.mc_gpregs) ++ .field("mc_fpregs", &self.mc_fpregs) ++ .field("mc_flags", &self.mc_flags) ++ .field("mc_pad", &self.mc_pad) ++ .field("mc_spare", &self.mc_spare) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for mcontext_t { ++ fn hash(&self, state: &mut H) { ++ self.mc_gpregs.hash(state); ++ self.mc_fpregs.hash(state); ++ self.mc_flags.hash(state); ++ self.mc_pad.hash(state); ++ self.mc_spare.hash(state); ++ } ++ } ++ } ++} ++ ++pub const MAP_32BIT: ::c_int = 0x00080000; ++pub const MINSIGSTKSZ: ::size_t = 4096; // 1024 * 4 +diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86.rs +index d3a3f34..4046ec3 100644 +--- a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86.rs ++++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86.rs +@@ -6,6 +6,41 @@ pub type time_t = i32; + pub type suseconds_t = i32; + pub type register_t = i32; + ++s_no_extra_traits! { ++ pub struct mcontext_t { ++ pub mc_onstack: register_t, ++ pub mc_gs: register_t, ++ pub mc_fs: register_t, ++ pub mc_es: register_t, ++ pub mc_ds: register_t, ++ pub mc_edi: register_t, ++ pub mc_esi: register_t, ++ pub mc_ebp: register_t, ++ pub mc_isp: register_t, ++ pub mc_ebx: register_t, ++ pub mc_edx: register_t, ++ pub mc_ecx: register_t, ++ pub mc_eax: register_t, ++ pub mc_trapno: register_t, ++ pub mc_err: register_t, ++ pub mc_eip: register_t, ++ pub mc_cs: register_t, ++ pub mc_eflags: register_t, ++ pub mc_esp: register_t, ++ pub mc_ss: register_t, ++ pub mc_len: ::c_int, ++ pub mc_fpformat: ::c_int, ++ pub mc_ownedfp: ::c_int, ++ pub mc_flags: register_t, ++ pub mc_fpstate: [[::c_int; 32]; 4], ++ pub mc_fsbase: register_t, ++ pub mc_gsbase: register_t, ++ pub mc_xfpustate: register_t, ++ pub mc_xfpustate_len: register_t, ++ pub mc_spare2: [::c_int; 4], ++ } ++} ++ + s! { + pub struct stat { + pub st_dev: ::dev_t, +@@ -31,6 +66,15 @@ s! { + pub st_birthtime_nsec: ::c_long, + __unused: [u8; 8], + } ++ ++ pub struct ucontext_t { ++ pub uc_sigmask: ::sigset_t, ++ pub uc_mcontext: ::mcontext_t, ++ pub uc_link: *mut ::ucontext_t, ++ pub uc_stack: ::stack_t, ++ pub uc_flags: ::c_int, ++ __spare__: [::c_int; 4], ++ } + } + + // should be pub(crate), but that requires Rust 1.18.0 +@@ -43,4 +87,115 @@ cfg_if! { + pub const _ALIGNBYTES: usize = 4 - 1; + } + } ++ ++cfg_if! { ++ if #[cfg(feature = "extra_traits")] { ++ impl PartialEq for mcontext_t { ++ fn eq(&self, other: &mcontext_t) -> bool { ++ self.mc_onstack == other.mc_onstack && ++ self.mc_gs == other.mc_gs && ++ self.mc_fs == other.mc_fs && ++ self.mc_es == other.mc_es && ++ self.mc_ds == other.mc_ds && ++ self.mc_edi == other.mc_edi && ++ self.mc_esi == other.mc_esi && ++ self.mc_ebp == other.mc_ebp && ++ self.mc_isp == other.mc_isp && ++ self.mc_ebx == other.mc_ebx && ++ self.mc_edx == other.mc_edx && ++ self.mc_ecx == other.mc_ecx && ++ self.mc_eax == other.mc_eax && ++ self.mc_trapno == other.mc_trapno && ++ self.mc_err == other.mc_err && ++ self.mc_eip == other.mc_eip && ++ self.mc_cs == other.mc_cs && ++ self.mc_eflags == other.mc_eflags && ++ self.mc_esp == other.mc_esp && ++ self.mc_ss == other.mc_ss && ++ self.mc_len == other.mc_len && ++ self.mc_fpformat == other.mc_fpformat && ++ self.mc_ownedfp == other.mc_ownedfp && ++ self.mc_flags == other.mc_flags && ++ self.mc_fpstate.iter().zip(other.mc_fpstate.iter()).all(|(a, b)| a == b) && ++ self.mc_fsbase == other.mc_fsbase && ++ self.mc_gsbase == other.mc_gsbase && ++ self.mc_xfpustate == other.mc_xfpustate && ++ self.mc_xfpustate_len == other.mc_xfpustate_len && ++ self.mc_spare2.iter().zip(other.mc_spare2.iter()).all(|(a, b)| a == b) ++ } ++ } ++ impl Eq for mcontext_t {} ++ impl ::fmt::Debug for mcontext_t { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("mcontext_t") ++ .field("mc_onstack", &self.mc_onstack) ++ .field("mc_gs", &self.mc_gs) ++ .field("mc_fs", &self.mc_fs) ++ .field("mc_es", &self.mc_es) ++ .field("mc_ds", &self.mc_ds) ++ .field("mc_edi", &self.mc_edi) ++ .field("mc_esi", &self.mc_esi) ++ .field("mc_ebp", &self.mc_ebp) ++ .field("mc_isp", &self.mc_isp) ++ .field("mc_ebx", &self.mc_ebx) ++ .field("mc_edx", &self.mc_edx) ++ .field("mc_ecx", &self.mc_ecx) ++ .field("mc_eax", &self.mc_eax) ++ .field("mc_trapno", &self.mc_trapno) ++ .field("mc_err", &self.mc_err) ++ .field("mc_eip", &self.mc_eip) ++ .field("mc_cs", &self.mc_cs) ++ .field("mc_eflags", &self.mc_eflags) ++ .field("mc_esp", &self.mc_esp) ++ .field("mc_ss", &self.mc_ss) ++ .field("mc_len", &self.mc_len) ++ .field("mc_fpformat", &self.mc_fpformat) ++ .field("mc_ownedfp", &self.mc_ownedfp) ++ .field("mc_flags", &self.mc_flags) ++ .field("mc_fpstate", &self.mc_fpstate) ++ .field("mc_fsbase", &self.mc_fsbase) ++ .field("mc_gsbase", &self.mc_gsbase) ++ .field("mc_xfpustate", &self.mc_xfpustate) ++ .field("mc_xfpustate_len", &self.mc_xfpustate_len) ++ .field("mc_spare2", &self.mc_spare2) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for mcontext_t { ++ fn hash(&self, state: &mut H) { ++ self.mc_onstack.hash(state); ++ self.mc_gs.hash(state); ++ self.mc_fs.hash(state); ++ self.mc_es.hash(state); ++ self.mc_ds.hash(state); ++ self.mc_edi.hash(state); ++ self.mc_esi.hash(state); ++ self.mc_ebp.hash(state); ++ self.mc_isp.hash(state); ++ self.mc_ebx.hash(state); ++ self.mc_edx.hash(state); ++ self.mc_ecx.hash(state); ++ self.mc_eax.hash(state); ++ self.mc_trapno.hash(state); ++ self.mc_err.hash(state); ++ self.mc_eip.hash(state); ++ self.mc_cs.hash(state); ++ self.mc_eflags.hash(state); ++ self.mc_esp.hash(state); ++ self.mc_ss.hash(state); ++ self.mc_len.hash(state); ++ self.mc_fpformat.hash(state); ++ self.mc_ownedfp.hash(state); ++ self.mc_flags.hash(state); ++ self.mc_fpstate.hash(state); ++ self.mc_fsbase.hash(state); ++ self.mc_gsbase.hash(state); ++ self.mc_xfpustate.hash(state); ++ self.mc_xfpustate_len.hash(state); ++ self.mc_spare2.hash(state); ++ } ++ } ++ } ++} ++ + pub const MINSIGSTKSZ: ::size_t = 2048; // 512 * 4 +diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs +index d3333c8..ae1fcf7 100644 +--- a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs ++++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs +@@ -80,6 +80,36 @@ s_no_extra_traits! { + pub xmm_reg: [[u8; 16]; 8], + pub xmm_pad: [u8; 224], + } ++ ++ #[cfg(libc_union)] ++ pub union __c_anonymous_elf64_auxv_union { ++ pub a_val: ::c_long, ++ pub a_ptr: *mut ::c_void, ++ pub a_fcn: extern "C" fn(), ++ } ++ ++ pub struct Elf64_Auxinfo { ++ pub a_type: ::c_long, ++ #[cfg(libc_union)] ++ pub a_un: __c_anonymous_elf64_auxv_union, ++ } ++ ++ pub struct kinfo_file { ++ pub kf_structsize: ::c_int, ++ pub kf_type: ::c_int, ++ pub kf_fd: ::c_int, ++ pub kf_ref_count: ::c_int, ++ pub kf_flags: ::c_int, ++ _kf_pad0: ::c_int, ++ pub kf_offset: i64, ++ _priv: [::uintptr_t; 38], // FIXME if needed ++ pub kf_status: u16, ++ _kf_pad1: u16, ++ _kf_ispare0: ::c_int, ++ pub kf_cap_rights: ::cap_rights_t, ++ _kf_cap_spare: u64, ++ pub kf_path: [::c_char; ::PATH_MAX as usize], ++ } + } + + cfg_if! { +@@ -173,6 +203,102 @@ cfg_if! { + self.xmm_pad.hash(state); + } + } ++ ++ #[cfg(libc_union)] ++ impl PartialEq for __c_anonymous_elf64_auxv_union { ++ fn eq(&self, other: &__c_anonymous_elf64_auxv_union) -> bool { ++ unsafe { self.a_val == other.a_val ++ || self.a_ptr == other.a_ptr ++ || self.a_fcn == other.a_fcn } ++ } ++ } ++ #[cfg(libc_union)] ++ impl Eq for __c_anonymous_elf64_auxv_union {} ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for __c_anonymous_elf64_auxv_union { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("a_val") ++ .field("a_val", unsafe { &self.a_val }) ++ .finish() ++ } ++ } ++ #[cfg(not(libc_union))] ++ impl PartialEq for Elf64_Auxinfo { ++ fn eq(&self, other: &Elf64_Auxinfo) -> bool { ++ self.a_type == other.a_type ++ } ++ } ++ #[cfg(libc_union)] ++ impl PartialEq for Elf64_Auxinfo { ++ fn eq(&self, other: &Elf64_Auxinfo) -> bool { ++ self.a_type == other.a_type ++ && self.a_un == other.a_un ++ } ++ } ++ impl Eq for Elf64_Auxinfo {} ++ #[cfg(not(libc_union))] ++ impl ::fmt::Debug for Elf64_Auxinfo { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("Elf64_Auxinfo") ++ .field("a_type", &self.a_type) ++ .finish() ++ } ++ } ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for Elf64_Auxinfo { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("Elf64_Auxinfo") ++ .field("a_type", &self.a_type) ++ .field("a_un", &self.a_un) ++ .finish() ++ } ++ } ++ ++ impl PartialEq for kinfo_file { ++ fn eq(&self, other: &kinfo_file) -> bool { ++ self.kf_structsize == other.kf_structsize && ++ self.kf_type == other.kf_type && ++ self.kf_fd == other.kf_fd && ++ self.kf_ref_count == other.kf_ref_count && ++ self.kf_flags == other.kf_flags && ++ self.kf_offset == other.kf_offset && ++ self.kf_status == other.kf_status && ++ self.kf_cap_rights == other.kf_cap_rights && ++ self.kf_path ++ .iter() ++ .zip(other.kf_path.iter()) ++ .all(|(a,b)| a == b) ++ } ++ } ++ impl Eq for kinfo_file {} ++ impl ::fmt::Debug for kinfo_file { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("kinfo_file") ++ .field("kf_structsize", &self.kf_structsize) ++ .field("kf_type", &self.kf_type) ++ .field("kf_fd", &self.kf_fd) ++ .field("kf_ref_count", &self.kf_ref_count) ++ .field("kf_flags", &self.kf_flags) ++ .field("kf_offset", &self.kf_offset) ++ .field("kf_status", &self.kf_status) ++ .field("kf_cap_rights", &self.kf_cap_rights) ++ .field("kf_path", &&self.kf_path[..]) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for kinfo_file { ++ fn hash(&self, state: &mut H) { ++ self.kf_structsize.hash(state); ++ self.kf_type.hash(state); ++ self.kf_fd.hash(state); ++ self.kf_ref_count.hash(state); ++ self.kf_flags.hash(state); ++ self.kf_offset.hash(state); ++ self.kf_status.hash(state); ++ self.kf_cap_rights.hash(state); ++ self.kf_path.hash(state); ++ } ++ } + } + } + +diff --git a/vendor/libc/src/unix/bsd/freebsdlike/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/mod.rs +index b0400c3..6a0f383 100644 +--- a/vendor/libc/src/unix/bsd/freebsdlike/mod.rs ++++ b/vendor/libc/src/unix/bsd/freebsdlike/mod.rs +@@ -13,6 +13,7 @@ pub type speed_t = ::c_uint; + pub type nl_item = ::c_int; + pub type id_t = i64; + pub type vm_size_t = ::uintptr_t; ++pub type key_t = ::c_long; + + // elf.h + +@@ -34,6 +35,10 @@ pub type Elf64_Xword = u64; + + pub type iconv_t = *mut ::c_void; + ++// It's an alias over "struct __kvm_t". However, its fields aren't supposed to be used directly, ++// making the type definition system dependent. Better not bind it exactly. ++pub type kvm_t = ::c_void; ++ + cfg_if! { + if #[cfg(target_pointer_width = "64")] { + type Elf_Addr = Elf64_Addr; +@@ -89,6 +94,18 @@ s! { + pub imr_interface: in_addr, + } + ++ pub struct ip_mreqn { ++ pub imr_multiaddr: in_addr, ++ pub imr_address: in_addr, ++ pub imr_ifindex: ::c_int, ++ } ++ ++ pub struct ip_mreq_source { ++ pub imr_multiaddr: in_addr, ++ pub imr_sourceaddr: in_addr, ++ pub imr_interface: in_addr, ++ } ++ + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_matchc: ::size_t, +@@ -265,6 +282,11 @@ s! { + pub time_state: ::c_int, + } + ++ pub struct accept_filter_arg { ++ pub af_name: [::c_char; 16], ++ af_arg: [[::c_char; 10]; 24], ++ } ++ + pub struct ptrace_io_desc { + pub piod_op: ::c_int, + pub piod_offs: *mut ::c_void, +@@ -344,6 +366,20 @@ s! { + pub dlpi_tls_modid: usize, + pub dlpi_tls_data: *mut ::c_void, + } ++ ++ pub struct ipc_perm { ++ pub cuid: ::uid_t, ++ pub cgid: ::gid_t, ++ pub uid: ::uid_t, ++ pub gid: ::gid_t, ++ pub mode: ::mode_t, ++ pub seq: ::c_ushort, ++ pub key: ::key_t, ++ } ++ ++ pub struct eui64 { ++ pub octet: [u8; EUI64_LEN], ++ } + } + + s_no_extra_traits! { +@@ -562,6 +598,8 @@ pub const F_TEST: ::c_int = 3; + pub const F_TLOCK: ::c_int = 2; + pub const F_ULOCK: ::c_int = 0; + pub const F_DUPFD_CLOEXEC: ::c_int = 17; ++pub const F_DUP2FD: ::c_int = 10; ++pub const F_DUP2FD_CLOEXEC: ::c_int = 18; + pub const SIGHUP: ::c_int = 1; + pub const SIGINT: ::c_int = 2; + pub const SIGQUIT: ::c_int = 3; +@@ -592,6 +630,19 @@ pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; + pub const MCL_CURRENT: ::c_int = 0x0001; + pub const MCL_FUTURE: ::c_int = 0x0002; + ++pub const MNT_EXPUBLIC: ::c_int = 0x20000000; ++pub const MNT_NOATIME: ::c_int = 0x10000000; ++pub const MNT_NOCLUSTERR: ::c_int = 0x40000000; ++pub const MNT_NOCLUSTERW: ::c_int = 0x80000000; ++pub const MNT_NOSYMFOLLOW: ::c_int = 0x00400000; ++pub const MNT_SOFTDEP: ::c_int = 0x00200000; ++pub const MNT_SUIDDIR: ::c_int = 0x00100000; ++pub const MNT_EXRDONLY: ::c_int = 0x00000080; ++pub const MNT_DEFEXPORTED: ::c_int = 0x00000200; ++pub const MNT_EXPORTANON: ::c_int = 0x00000400; ++pub const MNT_EXKERB: ::c_int = 0x00000800; ++pub const MNT_DELEXPORT: ::c_int = 0x00020000; ++ + pub const MS_SYNC: ::c_int = 0x0000; + pub const MS_ASYNC: ::c_int = 0x0001; + pub const MS_INVALIDATE: ::c_int = 0x0002; +@@ -701,6 +752,14 @@ pub const POLLSTANDARD: ::c_short = ::POLLIN + | ::POLLHUP + | ::POLLNVAL; + ++pub const AI_PASSIVE: ::c_int = 0x00000001; ++pub const AI_CANONNAME: ::c_int = 0x00000002; ++pub const AI_NUMERICHOST: ::c_int = 0x00000004; ++pub const AI_NUMERICSERV: ::c_int = 0x00000008; ++pub const AI_ALL: ::c_int = 0x00000100; ++pub const AI_ADDRCONFIG: ::c_int = 0x00000400; ++pub const AI_V4MAPPED: ::c_int = 0x00000800; ++ + pub const EAI_AGAIN: ::c_int = 2; + pub const EAI_BADFLAGS: ::c_int = 3; + pub const EAI_FAIL: ::c_int = 4; +@@ -765,12 +824,15 @@ pub const CLOCK_VIRTUAL: ::clockid_t = 1; + pub const CLOCK_PROF: ::clockid_t = 2; + pub const CLOCK_MONOTONIC: ::clockid_t = 4; + pub const CLOCK_UPTIME: ::clockid_t = 5; ++pub const CLOCK_BOOTTIME: ::clockid_t = CLOCK_UPTIME; + pub const CLOCK_UPTIME_PRECISE: ::clockid_t = 7; + pub const CLOCK_UPTIME_FAST: ::clockid_t = 8; + pub const CLOCK_REALTIME_PRECISE: ::clockid_t = 9; + pub const CLOCK_REALTIME_FAST: ::clockid_t = 10; ++pub const CLOCK_REALTIME_COARSE: ::clockid_t = CLOCK_REALTIME_FAST; + pub const CLOCK_MONOTONIC_PRECISE: ::clockid_t = 11; + pub const CLOCK_MONOTONIC_FAST: ::clockid_t = 12; ++pub const CLOCK_MONOTONIC_COARSE: ::clockid_t = CLOCK_MONOTONIC_FAST; + pub const CLOCK_SECOND: ::clockid_t = 13; + pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 14; + pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 15; +@@ -791,7 +853,6 @@ pub const MINCORE_REFERENCED: ::c_int = 0x2; + pub const MINCORE_MODIFIED: ::c_int = 0x4; + pub const MINCORE_REFERENCED_OTHER: ::c_int = 0x8; + pub const MINCORE_MODIFIED_OTHER: ::c_int = 0x10; +-pub const MINCORE_SUPER: ::c_int = 0x20; + + pub const AF_UNSPEC: ::c_int = 0; + pub const AF_LOCAL: ::c_int = 1; +@@ -920,6 +981,11 @@ pub const IPV6_PKTINFO: ::c_int = 46; + pub const IPV6_HOPLIMIT: ::c_int = 47; + pub const IPV6_RECVTCLASS: ::c_int = 57; + pub const IPV6_TCLASS: ::c_int = 61; ++pub const IPV6_DONTFRAG: ::c_int = 62; ++pub const IP_ADD_SOURCE_MEMBERSHIP: ::c_int = 70; ++pub const IP_DROP_SOURCE_MEMBERSHIP: ::c_int = 71; ++pub const IP_BLOCK_SOURCE: ::c_int = 72; ++pub const IP_UNBLOCK_SOURCE: ::c_int = 73; + + pub const TCP_NOPUSH: ::c_int = 4; + pub const TCP_NOOPT: ::c_int = 8; +@@ -963,10 +1029,16 @@ pub const LOCK_UN: ::c_int = 8; + + pub const MAP_COPY: ::c_int = 0x0002; + #[doc(hidden)] +-#[deprecated(since = "0.2.54", note = "Removed in FreeBSD 11")] ++#[deprecated( ++ since = "0.2.54", ++ note = "Removed in FreeBSD 11, unused in DragonFlyBSD" ++)] + pub const MAP_RENAME: ::c_int = 0x0020; + #[doc(hidden)] +-#[deprecated(since = "0.2.54", note = "Removed in FreeBSD 11")] ++#[deprecated( ++ since = "0.2.54", ++ note = "Removed in FreeBSD 11, unused in DragonFlyBSD" ++)] + pub const MAP_NORESERVE: ::c_int = 0x0040; + pub const MAP_HASSEMAPHORE: ::c_int = 0x0200; + pub const MAP_STACK: ::c_int = 0x0400; +@@ -1138,7 +1210,6 @@ pub const ST_NOSUID: ::c_ulong = 2; + + pub const NI_MAXHOST: ::size_t = 1025; + +-pub const XU_NGROUPS: ::c_int = 16; + pub const XUCRED_VERSION: ::c_uint = 0; + + pub const RTLD_LOCAL: ::c_int = 0; +@@ -1151,30 +1222,30 @@ pub const LOG_SECURITY: ::c_int = 13 << 3; + pub const LOG_CONSOLE: ::c_int = 14 << 3; + pub const LOG_NFACILITIES: ::c_int = 24; + +-pub const TIOCEXCL: ::c_uint = 0x2000740d; +-pub const TIOCNXCL: ::c_uint = 0x2000740e; ++pub const TIOCEXCL: ::c_ulong = 0x2000740d; ++pub const TIOCNXCL: ::c_ulong = 0x2000740e; + pub const TIOCFLUSH: ::c_ulong = 0x80047410; +-pub const TIOCGETA: ::c_uint = 0x402c7413; ++pub const TIOCGETA: ::c_ulong = 0x402c7413; + pub const TIOCSETA: ::c_ulong = 0x802c7414; + pub const TIOCSETAW: ::c_ulong = 0x802c7415; + pub const TIOCSETAF: ::c_ulong = 0x802c7416; +-pub const TIOCGETD: ::c_uint = 0x4004741a; ++pub const TIOCGETD: ::c_ulong = 0x4004741a; + pub const TIOCSETD: ::c_ulong = 0x8004741b; +-pub const TIOCGDRAINWAIT: ::c_uint = 0x40047456; ++pub const TIOCGDRAINWAIT: ::c_ulong = 0x40047456; + pub const TIOCSDRAINWAIT: ::c_ulong = 0x80047457; +-pub const TIOCTIMESTAMP: ::c_uint = 0x40107459; +-pub const TIOCMGDTRWAIT: ::c_uint = 0x4004745a; ++pub const TIOCTIMESTAMP: ::c_ulong = 0x40107459; ++pub const TIOCMGDTRWAIT: ::c_ulong = 0x4004745a; + pub const TIOCMSDTRWAIT: ::c_ulong = 0x8004745b; +-pub const TIOCDRAIN: ::c_uint = 0x2000745e; ++pub const TIOCDRAIN: ::c_ulong = 0x2000745e; + pub const TIOCEXT: ::c_ulong = 0x80047460; +-pub const TIOCSCTTY: ::c_uint = 0x20007461; ++pub const TIOCSCTTY: ::c_ulong = 0x20007461; + pub const TIOCCONS: ::c_ulong = 0x80047462; +-pub const TIOCGSID: ::c_uint = 0x40047463; +-pub const TIOCSTAT: ::c_uint = 0x20007465; ++pub const TIOCGSID: ::c_ulong = 0x40047463; ++pub const TIOCSTAT: ::c_ulong = 0x20007465; + pub const TIOCUCNTL: ::c_ulong = 0x80047466; + pub const TIOCSWINSZ: ::c_ulong = 0x80087467; +-pub const TIOCGWINSZ: ::c_uint = 0x40087468; +-pub const TIOCMGET: ::c_uint = 0x4004746a; ++pub const TIOCGWINSZ: ::c_ulong = 0x40087468; ++pub const TIOCMGET: ::c_ulong = 0x4004746a; + pub const TIOCM_LE: ::c_int = 0x1; + pub const TIOCM_DTR: ::c_int = 0x2; + pub const TIOCM_RTS: ::c_int = 0x4; +@@ -1189,8 +1260,8 @@ pub const TIOCM_RNG: ::c_int = 0x80; + pub const TIOCMBIC: ::c_ulong = 0x8004746b; + pub const TIOCMBIS: ::c_ulong = 0x8004746c; + pub const TIOCMSET: ::c_ulong = 0x8004746d; +-pub const TIOCSTART: ::c_uint = 0x2000746e; +-pub const TIOCSTOP: ::c_uint = 0x2000746f; ++pub const TIOCSTART: ::c_ulong = 0x2000746e; ++pub const TIOCSTOP: ::c_ulong = 0x2000746f; + pub const TIOCPKT: ::c_ulong = 0x80047470; + pub const TIOCPKT_DATA: ::c_int = 0x0; + pub const TIOCPKT_FLUSHREAD: ::c_int = 0x1; +@@ -1200,13 +1271,13 @@ pub const TIOCPKT_START: ::c_int = 0x8; + pub const TIOCPKT_NOSTOP: ::c_int = 0x10; + pub const TIOCPKT_DOSTOP: ::c_int = 0x20; + pub const TIOCPKT_IOCTL: ::c_int = 0x40; +-pub const TIOCNOTTY: ::c_uint = 0x20007471; ++pub const TIOCNOTTY: ::c_ulong = 0x20007471; + pub const TIOCSTI: ::c_ulong = 0x80017472; +-pub const TIOCOUTQ: ::c_uint = 0x40047473; ++pub const TIOCOUTQ: ::c_ulong = 0x40047473; + pub const TIOCSPGRP: ::c_ulong = 0x80047476; +-pub const TIOCGPGRP: ::c_uint = 0x40047477; +-pub const TIOCCDTR: ::c_uint = 0x20007478; +-pub const TIOCSDTR: ::c_uint = 0x20007479; ++pub const TIOCGPGRP: ::c_ulong = 0x40047477; ++pub const TIOCCDTR: ::c_ulong = 0x20007478; ++pub const TIOCSDTR: ::c_ulong = 0x20007479; + pub const TTYDISC: ::c_int = 0x0; + pub const SLIPDISC: ::c_int = 0x4; + pub const PPPDISC: ::c_int = 0x5; +@@ -1224,7 +1295,6 @@ pub const BIOCGRTIMEOUT: ::c_ulong = 0x4010426e; + + pub const FIODTYPE: ::c_ulong = 0x4004667a; + pub const FIOGETLBA: ::c_ulong = 0x40046679; +-pub const FIODGNAME: ::c_ulong = 0x80106678; + + pub const B0: speed_t = 0; + pub const B50: speed_t = 50; +@@ -1267,6 +1337,8 @@ pub const ONLRET: ::tcflag_t = 0x40; + + pub const CMGROUP_MAX: usize = 16; + ++pub const EUI64_LEN: usize = 8; ++ + // https://github.com/freebsd/freebsd/blob/master/sys/net/bpf.h + pub const BPF_ALIGNMENT: usize = SIZEOF_LONG; + +@@ -1346,6 +1418,22 @@ pub const TIME_ERROR: ::c_int = 5; + pub const REG_ENOSYS: ::c_int = -1; + pub const REG_ILLSEQ: ::c_int = 17; + ++pub const IPC_PRIVATE: ::key_t = 0; ++pub const IPC_CREAT: ::c_int = 0o1000; ++pub const IPC_EXCL: ::c_int = 0o2000; ++pub const IPC_NOWAIT: ::c_int = 0o4000; ++pub const IPC_RMID: ::c_int = 0; ++pub const IPC_SET: ::c_int = 1; ++pub const IPC_STAT: ::c_int = 2; ++pub const IPC_R: ::c_int = 0o400; ++pub const IPC_W: ::c_int = 0o200; ++pub const IPC_M: ::c_int = 0o10000; ++ ++pub const SHM_RDONLY: ::c_int = 0o10000; ++pub const SHM_RND: ::c_int = 0o20000; ++pub const SHM_R: ::c_int = 0o400; ++pub const SHM_W: ::c_int = 0o200; ++ + safe_f! { + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + status == 0x13 +@@ -1385,10 +1473,17 @@ extern "C" { + pub fn clock_settime(clk_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; + pub fn clock_getcpuclockid(pid: ::pid_t, clk_id: *mut ::clockid_t) -> ::c_int; + ++ pub fn pthread_getcpuclockid(thread: ::pthread_t, clk_id: *mut ::clockid_t) -> ::c_int; ++ + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; + pub fn duplocale(base: ::locale_t) -> ::locale_t; + pub fn endutxent(); + pub fn fchflags(fd: ::c_int, flags: ::c_ulong) -> ::c_int; ++ pub fn fexecve( ++ fd: ::c_int, ++ argv: *const *const ::c_char, ++ envp: *const *const ::c_char, ++ ) -> ::c_int; + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; + pub fn getdomainname(name: *mut ::c_char, len: ::c_int) -> ::c_int; + pub fn getgrent_r( +@@ -1419,6 +1514,8 @@ extern "C" { + flags: ::c_int, + ) -> ::c_int; + pub fn getpriority(which: ::c_int, who: ::c_int) -> ::c_int; ++ pub fn getresgid(rgid: *mut ::gid_t, egid: *mut ::gid_t, sgid: *mut ::gid_t) -> ::c_int; ++ pub fn getresuid(ruid: *mut ::uid_t, euid: *mut ::uid_t, suid: *mut ::uid_t) -> ::c_int; + pub fn getutxent() -> *mut utmpx; + pub fn getutxid(ut: *const utmpx) -> *mut utmpx; + pub fn getutxline(ut: *const utmpx) -> *mut utmpx; +@@ -1453,6 +1550,8 @@ extern "C" { + pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t; + pub fn nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char; + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; ++ pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; ++ pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, advise: ::c_int) -> ::c_int; + pub fn ppoll( + fds: *mut ::pollfd, + nfds: ::nfds_t, +@@ -1501,13 +1600,45 @@ extern "C" { + val: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_rwlockattr_setpshared(attr: *mut pthread_rwlockattr_t, val: ::c_int) -> ::c_int; ++ pub fn pthread_barrierattr_init(attr: *mut ::pthread_barrierattr_t) -> ::c_int; ++ pub fn pthread_barrierattr_destroy(attr: *mut ::pthread_barrierattr_t) -> ::c_int; ++ pub fn pthread_barrierattr_getpshared( ++ attr: *const ::pthread_barrierattr_t, ++ shared: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_barrierattr_setpshared( ++ attr: *mut ::pthread_barrierattr_t, ++ shared: ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_barrier_init( ++ barrier: *mut pthread_barrier_t, ++ attr: *const ::pthread_barrierattr_t, ++ count: ::c_uint, ++ ) -> ::c_int; ++ pub fn pthread_barrier_destroy(barrier: *mut pthread_barrier_t) -> ::c_int; ++ pub fn pthread_barrier_wait(barrier: *mut pthread_barrier_t) -> ::c_int; ++ pub fn pthread_get_name_np(tid: ::pthread_t, name: *mut ::c_char, len: ::size_t); + pub fn pthread_set_name_np(tid: ::pthread_t, name: *const ::c_char); ++ pub fn pthread_setschedparam( ++ native: ::pthread_t, ++ policy: ::c_int, ++ param: *const sched_param, ++ ) -> ::c_int; ++ pub fn pthread_getschedparam( ++ native: ::pthread_t, ++ policy: *mut ::c_int, ++ param: *mut sched_param, ++ ) -> ::c_int; + pub fn ptrace(request: ::c_int, pid: ::pid_t, addr: *mut ::c_char, data: ::c_int) -> ::c_int; ++ pub fn utrace(addr: *const ::c_void, len: ::size_t) -> ::c_int; + pub fn pututxline(ut: *const utmpx) -> *mut utmpx; + pub fn pwritev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) + -> ::ssize_t; + pub fn querylocale(mask: ::c_int, loc: ::locale_t) -> *const ::c_char; + pub fn rtprio(function: ::c_int, pid: ::pid_t, rtp: *mut rtprio) -> ::c_int; ++ pub fn sched_rr_get_interval(pid: ::pid_t, t: *mut ::timespec) -> ::c_int; ++ pub fn sched_getparam(pid: ::pid_t, param: *mut sched_param) -> ::c_int; ++ pub fn sched_setparam(pid: ::pid_t, param: *const sched_param) -> ::c_int; + pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int; + pub fn sched_setscheduler( + pid: ::pid_t, +@@ -1597,6 +1728,15 @@ extern "C" { + pub fn explicit_bzero(s: *mut ::c_void, len: ::size_t); + // ISO/IEC 9899:2011 ("ISO C11") K.3.7.4.1 + pub fn memset_s(s: *mut ::c_void, smax: ::size_t, c: ::c_int, n: ::size_t) -> ::c_int; ++ pub fn gethostid() -> ::c_long; ++ pub fn sethostid(hostid: ::c_long); ++ ++ pub fn eui64_aton(a: *const ::c_char, e: *mut eui64) -> ::c_int; ++ pub fn eui64_ntoa(id: *const eui64, a: *mut ::c_char, len: ::size_t) -> ::c_int; ++ pub fn eui64_ntohost(hostname: *mut ::c_char, len: ::size_t, id: *const eui64) -> ::c_int; ++ pub fn eui64_hostton(hostname: *const ::c_char, id: *mut eui64) -> ::c_int; ++ ++ pub fn eaccess(path: *const ::c_char, mode: ::c_int) -> ::c_int; + } + + #[link(name = "rt")] +@@ -1651,6 +1791,62 @@ extern "C" { + winp: *mut ::winsize, + ) -> ::pid_t; + pub fn login_tty(fd: ::c_int) -> ::c_int; ++ pub fn fparseln( ++ stream: *mut ::FILE, ++ len: *mut ::size_t, ++ lineno: *mut ::size_t, ++ delim: *const ::c_char, ++ flags: ::c_int, ++ ) -> *mut ::c_char; ++} ++ ++#[link(name = "execinfo")] ++extern "C" { ++ pub fn backtrace(addrlist: *mut *mut ::c_void, len: ::size_t) -> ::size_t; ++ pub fn backtrace_symbols(addrlist: *const *mut ::c_void, len: ::size_t) -> *mut *mut ::c_char; ++ pub fn backtrace_symbols_fd( ++ addrlist: *const *mut ::c_void, ++ len: ::size_t, ++ fd: ::c_int, ++ ) -> ::c_int; ++} ++ ++#[link(name = "kvm")] ++extern "C" { ++ pub fn kvm_open( ++ execfile: *const ::c_char, ++ corefile: *const ::c_char, ++ swapfile: *const ::c_char, ++ flags: ::c_int, ++ errstr: *const ::c_char, ++ ) -> *mut ::kvm_t; ++ pub fn kvm_close(kd: *mut ::kvm_t) -> ::c_int; ++ pub fn kvm_getprocs( ++ kd: *mut ::kvm_t, ++ op: ::c_int, ++ arg: ::c_int, ++ cnt: *mut ::c_int, ++ ) -> *mut ::kinfo_proc; ++ pub fn kvm_getloadavg(kd: *mut kvm_t, loadavg: *mut ::c_double, nelem: ::c_int) -> ::c_int; ++ pub fn kvm_openfiles( ++ execfile: *const ::c_char, ++ corefile: *const ::c_char, ++ swapfile: *const ::c_char, ++ flags: ::c_int, ++ errbuf: *mut ::c_char, ++ ) -> *mut ::kvm_t; ++ pub fn kvm_read( ++ kd: *mut ::kvm_t, ++ addr: ::c_ulong, ++ buf: *mut ::c_void, ++ nbytes: ::size_t, ++ ) -> ::ssize_t; ++ pub fn kvm_write( ++ kd: *mut ::kvm_t, ++ addr: ::c_ulong, ++ buf: *const ::c_void, ++ nbytes: ::size_t, ++ ) -> ::ssize_t; + } + + cfg_if! { +diff --git a/vendor/libc/src/unix/bsd/mod.rs b/vendor/libc/src/unix/bsd/mod.rs +index f86a008..84e572e 100644 +--- a/vendor/libc/src/unix/bsd/mod.rs ++++ b/vendor/libc/src/unix/bsd/mod.rs +@@ -37,6 +37,8 @@ s! { + + #[cfg(not(any(target_os = "macos", + target_os = "ios", ++ target_os = "tvos", ++ target_os = "watchos", + target_os = "netbsd", + target_os = "openbsd")))] + pub pw_fields: ::c_int, +@@ -113,6 +115,13 @@ s! { + pub rm_so: regoff_t, + pub rm_eo: regoff_t, + } ++ ++ pub struct option { ++ pub name: *const ::c_char, ++ pub has_arg: ::c_int, ++ pub flag: *mut ::c_int, ++ pub val: ::c_int, ++ } + } + + s_no_extra_traits! { +@@ -253,6 +262,7 @@ pub const FIOSETOWN: ::c_ulong = 0x8004667c; + pub const FIOGETOWN: ::c_ulong = 0x4004667b; + + pub const PATH_MAX: ::c_int = 1024; ++pub const MAXPATHLEN: ::c_int = PATH_MAX; + + pub const IOV_MAX: ::c_int = 1024; + +@@ -337,7 +347,15 @@ pub const F_RDLCK: ::c_short = 1; + pub const F_UNLCK: ::c_short = 2; + pub const F_WRLCK: ::c_short = 3; + +-pub const MNT_FORCE: ::c_int = 0x80000; ++pub const MNT_RDONLY: ::c_int = 0x00000001; ++pub const MNT_SYNCHRONOUS: ::c_int = 0x00000002; ++pub const MNT_NOEXEC: ::c_int = 0x00000004; ++pub const MNT_NOSUID: ::c_int = 0x00000008; ++pub const MNT_ASYNC: ::c_int = 0x00000040; ++pub const MNT_EXPORTED: ::c_int = 0x00000100; ++pub const MNT_UPDATE: ::c_int = 0x00010000; ++pub const MNT_RELOAD: ::c_int = 0x00040000; ++pub const MNT_FORCE: ::c_int = 0x00080000; + + pub const Q_SYNC: ::c_int = 0x600; + pub const Q_QUOTAON: ::c_int = 0x100; +@@ -439,6 +457,12 @@ pub const TCP_MAXSEG: ::c_int = 2; + + pub const PIPE_BUF: usize = 512; + ++// si_code values for SIGBUS signal ++pub const BUS_ADRALN: ::c_int = 1; ++pub const BUS_ADRERR: ::c_int = 2; ++pub const BUS_OBJERR: ::c_int = 3; ++ ++// si_code values for SIGCHLD signal + pub const CLD_EXITED: ::c_int = 1; + pub const CLD_KILLED: ::c_int = 2; + pub const CLD_DUMPED: ::c_int = 3; +@@ -533,7 +557,7 @@ f! { + return + } + +- pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool { ++ pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0 +@@ -589,7 +613,6 @@ extern "C" { + + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + pub fn abs(i: ::c_int) -> ::c_int; +- pub fn atof(s: *const ::c_char) -> ::c_double; + pub fn labs(i: ::c_long) -> ::c_long; + #[cfg_attr( + all(target_os = "freebsd", any(freebsd12, freebsd11, freebsd10)), +@@ -759,6 +782,8 @@ extern "C" { + )] + pub fn pthread_cancel(thread: ::pthread_t) -> ::c_int; + pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; ++ pub fn sched_get_priority_min(policy: ::c_int) -> ::c_int; ++ pub fn sched_get_priority_max(policy: ::c_int) -> ::c_int; + pub fn sem_unlink(name: *const ::c_char) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__getpwnam_r50")] + pub fn getpwnam_r( +@@ -852,10 +877,31 @@ extern "C" { + ) -> ::size_t; + + pub fn regfree(preg: *mut regex_t); ++ ++ pub fn arc4random() -> u32; ++ pub fn arc4random_buf(buf: *mut ::c_void, size: ::size_t); ++ pub fn arc4random_uniform(l: u32) -> u32; ++ ++ pub fn drand48() -> ::c_double; ++ pub fn erand48(xseed: *mut ::c_ushort) -> ::c_double; ++ pub fn lrand48() -> ::c_long; ++ pub fn nrand48(xseed: *mut ::c_ushort) -> ::c_long; ++ pub fn mrand48() -> ::c_long; ++ pub fn jrand48(xseed: *mut ::c_ushort) -> ::c_long; ++ pub fn srand48(seed: ::c_long); ++ pub fn seed48(xseed: *mut ::c_ushort) -> *mut ::c_ushort; ++ pub fn lcong48(p: *mut ::c_ushort); ++ pub fn getopt_long( ++ argc: ::c_int, ++ argv: *const *mut c_char, ++ optstring: *const c_char, ++ longopts: *const option, ++ longindex: *mut ::c_int, ++ ) -> ::c_int; + } + + cfg_if! { +- if #[cfg(any(target_os = "macos", target_os = "ios"))] { ++ if #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] { + mod apple; + pub use self::apple::*; + } else if #[cfg(any(target_os = "openbsd", target_os = "netbsd"))] { +diff --git a/vendor/libc/src/unix/bsd/netbsdlike/mod.rs b/vendor/libc/src/unix/bsd/netbsdlike/mod.rs +index 7e7269f..c43a4b9 100644 +--- a/vendor/libc/src/unix/bsd/netbsdlike/mod.rs ++++ b/vendor/libc/src/unix/bsd/netbsdlike/mod.rs +@@ -31,6 +31,10 @@ impl ::Clone for sem { + } + + s! { ++ pub struct sched_param { ++ pub sched_priority: ::c_int, ++ } ++ + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, +@@ -238,6 +242,13 @@ pub const IPC_RMID: ::c_int = 0; + pub const IPC_SET: ::c_int = 1; + pub const IPC_STAT: ::c_int = 2; + ++pub const IPC_R: ::c_int = 0o000400; ++pub const IPC_W: ::c_int = 0o000200; ++pub const IPC_M: ::c_int = 0o010000; ++ ++pub const SHM_R: ::c_int = IPC_R; ++pub const SHM_W: ::c_int = IPC_W; ++ + pub const MCL_CURRENT: ::c_int = 0x0001; + pub const MCL_FUTURE: ::c_int = 0x0002; + +@@ -408,6 +419,11 @@ pub const MADV_WILLNEED: ::c_int = 3; + pub const MADV_DONTNEED: ::c_int = 4; + pub const MADV_FREE: ::c_int = 6; + ++// sys/fstypes.h in NetBSD, or sys/mount.h in OpenBSD ++pub const MNT_NODEV: ::c_int = 0x00000010; ++pub const MNT_LOCAL: ::c_int = 0x00001000; ++pub const MNT_QUOTA: ::c_int = 0x00002000; ++ + pub const AF_UNSPEC: ::c_int = 0; + pub const AF_LOCAL: ::c_int = 1; + pub const AF_UNIX: ::c_int = AF_LOCAL; +@@ -628,17 +644,6 @@ pub const TIOCM_DSR: ::c_int = 0o0400; + pub const TIOCM_CD: ::c_int = TIOCM_CAR; + pub const TIOCM_RI: ::c_int = TIOCM_RNG; + +-// Flags for chflags(2) +-pub const UF_SETTABLE: ::c_ulong = 0x0000ffff; +-pub const UF_NODUMP: ::c_ulong = 0x00000001; +-pub const UF_IMMUTABLE: ::c_ulong = 0x00000002; +-pub const UF_APPEND: ::c_ulong = 0x00000004; +-pub const UF_OPAQUE: ::c_ulong = 0x00000008; +-pub const SF_SETTABLE: ::c_ulong = 0xffff0000; +-pub const SF_ARCHIVED: ::c_ulong = 0x00010000; +-pub const SF_IMMUTABLE: ::c_ulong = 0x00020000; +-pub const SF_APPEND: ::c_ulong = 0x00040000; +- + pub const TIMER_ABSTIME: ::c_int = 1; + + #[link(name = "util")] +@@ -677,19 +682,6 @@ extern "C" { + flag: ::c_int, + ) -> ::c_int; + pub fn fdatasync(fd: ::c_int) -> ::c_int; +- pub fn openpty( +- amaster: *mut ::c_int, +- aslave: *mut ::c_int, +- name: *mut ::c_char, +- termp: *mut termios, +- winp: *mut ::winsize, +- ) -> ::c_int; +- pub fn forkpty( +- amaster: *mut ::c_int, +- name: *mut ::c_char, +- termp: *mut termios, +- winp: *mut ::winsize, +- ) -> ::pid_t; + pub fn login_tty(fd: ::c_int) -> ::c_int; + pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int; + pub fn setpriority(which: ::c_int, who: ::id_t, prio: ::c_int) -> ::c_int; +@@ -712,6 +704,21 @@ extern "C" { + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; ++ pub fn pthread_spin_init(lock: *mut pthread_spinlock_t, pshared: ::c_int) -> ::c_int; ++ pub fn pthread_spin_destroy(lock: *mut pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_lock(lock: *mut pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_trylock(lock: *mut pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_unlock(lock: *mut pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_setschedparam( ++ native: ::pthread_t, ++ policy: ::c_int, ++ param: *const sched_param, ++ ) -> ::c_int; ++ pub fn pthread_getschedparam( ++ native: ::pthread_t, ++ policy: *mut ::c_int, ++ param: *mut sched_param, ++ ) -> ::c_int; + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; + + pub fn getgrouplist( +@@ -731,6 +738,17 @@ extern "C" { + pub fn shmctl(shmid: ::c_int, cmd: ::c_int, buf: *mut ::shmid_ds) -> ::c_int; + } + ++extern "C" { ++ pub fn reallocarray(ptr: *mut ::c_void, nmemb: ::size_t, size: ::size_t) -> *mut ::c_void; ++ pub fn gethostid() -> ::c_long; ++ pub fn sethostid(hostid: ::c_long) -> ::c_int; ++ pub fn ftok(path: *const ::c_char, id: ::c_int) -> ::key_t; ++ ++ pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; ++ pub fn basename(path: *mut ::c_char) -> *mut ::c_char; ++ pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; ++} ++ + cfg_if! { + if #[cfg(target_os = "netbsd")] { + mod netbsd; +diff --git a/vendor/libc/src/unix/bsd/netbsdlike/netbsd/aarch64.rs b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/aarch64.rs +index 58c4cf7..7b895f6 100644 +--- a/vendor/libc/src/unix/bsd/netbsdlike/netbsd/aarch64.rs ++++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/aarch64.rs +@@ -3,8 +3,89 @@ use PT_FIRSTMACH; + pub type c_long = i64; + pub type c_ulong = u64; + pub type c_char = u8; ++pub type greg_t = u64; + pub type __cpu_simple_lock_nv_t = ::c_uchar; + ++s! { ++ pub struct __fregset { ++ #[cfg(libc_union)] ++ pub __qregs: [__c_anonymous__freg; 32], ++ pub __fpcr: u32, ++ pub __fpsr: u32, ++ } ++ ++ pub struct mcontext_t { ++ pub __gregs: [::greg_t; 32], ++ pub __fregs: __fregset, ++ __spare: [::greg_t; 8], ++ } ++ ++ pub struct ucontext_t { ++ pub uc_flags: ::c_uint, ++ pub uc_link: *mut ucontext_t, ++ pub uc_sigmask: ::sigset_t, ++ pub uc_stack: ::stack_t, ++ pub uc_mcontext: mcontext_t, ++ } ++} ++ ++s_no_extra_traits! { ++ #[cfg(libc_union)] ++ #[repr(align(16))] ++ pub union __c_anonymous__freg { ++ pub __b8: [u8; 16], ++ pub __h16: [u16; 8], ++ pub __s32: [u32; 4], ++ pub __d64: [u64; 2], ++ pub __q128: [u128; 1], ++ } ++} ++ ++cfg_if! { ++ if #[cfg(feature = "extra_traits")] { ++ #[cfg(libc_union)] ++ impl PartialEq for __c_anonymous__freg { ++ fn eq(&self, other: &__c_anonymous__freg) -> bool { ++ unsafe { ++ self.__b8 == other.__b8 ++ || self.__h16 == other.__h16 ++ || self.__s32 == other.__s32 ++ || self.__d64 == other.__d64 ++ || self.__q128 == other.__q128 ++ } ++ } ++ } ++ #[cfg(libc_union)] ++ impl Eq for __c_anonymous__freg {} ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for __c_anonymous__freg { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ unsafe { ++ f.debug_struct("__c_anonymous__freg") ++ .field("__b8", &self.__b8) ++ .field("__h16", &self.__h16) ++ .field("__s32", &self.__s32) ++ .field("__d64", &self.__d64) ++ .field("__q128", &self.__q128) ++ .finish() ++ } ++ } ++ } ++ #[cfg(libc_union)] ++ impl ::hash::Hash for __c_anonymous__freg { ++ fn hash(&self, state: &mut H) { ++ unsafe { ++ self.__b8.hash(state); ++ self.__h16.hash(state); ++ self.__s32.hash(state); ++ self.__d64.hash(state); ++ self.__q128.hash(state); ++ } ++ } ++ } ++ } ++} ++ + // should be pub(crate), but that requires Rust 1.18.0 + cfg_if! { + if #[cfg(libc_const_size_of)] { +diff --git a/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs +index 0aee1ec..402257f 100644 +--- a/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs ++++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs +@@ -12,6 +12,8 @@ pub type lwpid_t = ::c_uint; + pub type shmatt_t = ::c_uint; + pub type cpuid_t = u64; + pub type cpuset_t = _cpuset; ++pub type pthread_spin_t = ::c_uchar; ++pub type timer_t = ::c_int; + + // elf.h + +@@ -33,6 +35,14 @@ pub type Elf64_Xword = u64; + + pub type iconv_t = *mut ::c_void; + ++e! { ++ pub enum fae_action { ++ FAE_OPEN, ++ FAE_DUP2, ++ FAE_CLOSE, ++ } ++} ++ + cfg_if! { + if #[cfg(target_pointer_width = "64")] { + type Elf_Addr = Elf64_Addr; +@@ -63,6 +73,23 @@ impl siginfo_t { + } + (*(self as *const siginfo_t as *const siginfo_timer)).value + } ++ ++ pub unsafe fn si_status(&self) -> ::c_int { ++ #[repr(C)] ++ struct siginfo_timer { ++ _si_signo: ::c_int, ++ _si_errno: ::c_int, ++ _si_code: ::c_int, ++ __pad1: ::c_int, ++ _pid: ::pid_t, ++ _uid: ::uid_t, ++ _value: ::sigval, ++ _cpid: ::pid_t, ++ _cuid: ::uid_t, ++ status: ::c_int, ++ } ++ (*(self as *const siginfo_t as *const siginfo_timer)).status ++ } + } + + s! { +@@ -102,6 +129,11 @@ s! { + pub mq_curmsgs: ::c_long, + } + ++ pub struct itimerspec { ++ pub it_interval: ::timespec, ++ pub it_value: ::timespec, ++ } ++ + pub struct sigset_t { + __bits: [u32; 4], + } +@@ -209,6 +241,12 @@ s! { + ptr_private: *mut ::c_void, + } + ++ pub struct pthread_spinlock_t { ++ pts_magic: ::c_uint, ++ pts_spin: ::pthread_spin_t, ++ pts_flags: ::c_int, ++ } ++ + pub struct kevent { + pub ident: ::uintptr_t, + pub filter: u32, +@@ -305,6 +343,14 @@ s! { + pub sc_groups: [::gid_t; 1], + } + ++ pub struct uucred { ++ pub cr_unused: ::c_ushort, ++ pub cr_uid: ::uid_t, ++ pub cr_gid: ::gid_t, ++ pub cr_ngroups: ::c_int, ++ pub cr_groups: [::gid_t; NGROUPS_MAX as usize], ++ } ++ + pub struct unpcbid { + pub unp_pid: ::pid_t, + pub unp_euid: ::uid_t, +@@ -440,6 +486,272 @@ s! { + pub af_name: [::c_char; 16], + af_arg: [[::c_char; 10]; 24], + } ++ ++ pub struct ki_sigset_t { ++ pub __bits: [u32; 4], ++ } ++ ++ pub struct kinfo_proc2 { ++ pub p_forw: u64, ++ pub p_back: u64, ++ pub p_paddr: u64, ++ pub p_addr: u64, ++ pub p_fd: u64, ++ pub p_cwdi: u64, ++ pub p_stats: u64, ++ pub p_limit: u64, ++ pub p_vmspace: u64, ++ pub p_sigacts: u64, ++ pub p_sess: u64, ++ pub p_tsess: u64, ++ pub p_ru: u64, ++ pub p_eflag: i32, ++ pub p_exitsig: i32, ++ pub p_flag: i32, ++ pub p_pid: i32, ++ pub p_ppid: i32, ++ pub p_sid: i32, ++ pub p__pgid: i32, ++ pub p_tpgid: i32, ++ pub p_uid: u32, ++ pub p_ruid: u32, ++ pub p_gid: u32, ++ pub p_rgid: u32, ++ pub p_groups: [u32; KI_NGROUPS as usize], ++ pub p_ngroups: i16, ++ pub p_jobc: i16, ++ pub p_tdev: u32, ++ pub p_estcpu: u32, ++ pub p_rtime_sec: u32, ++ pub p_rtime_usec: u32, ++ pub p_cpticks: i32, ++ pub p_pctcpu: u32, ++ pub p_swtime: u32, ++ pub p_slptime: u32, ++ pub p_schedflags: i32, ++ pub p_uticks: u64, ++ pub p_sticks: u64, ++ pub p_iticks: u64, ++ pub p_tracep: u64, ++ pub p_traceflag: i32, ++ pub p_holdcnt: i32, ++ pub p_siglist: ki_sigset_t, ++ pub p_sigmask: ki_sigset_t, ++ pub p_sigignore: ki_sigset_t, ++ pub p_sigcatch: ki_sigset_t, ++ pub p_stat: i8, ++ pub p_priority: u8, ++ pub p_usrpri: u8, ++ pub p_nice: u8, ++ pub p_xstat: u16, ++ pub p_acflag: u16, ++ pub p_comm: [::c_char; KI_MAXCOMLEN as usize], ++ pub p_wmesg: [::c_char; KI_WMESGLEN as usize], ++ pub p_wchan: u64, ++ pub p_login: [::c_char; KI_MAXLOGNAME as usize], ++ pub p_vm_rssize: i32, ++ pub p_vm_tsize: i32, ++ pub p_vm_dsize: i32, ++ pub p_vm_ssize: i32, ++ pub p_uvalid: i64, ++ pub p_ustart_sec: u32, ++ pub p_ustart_usec: u32, ++ pub p_uutime_sec: u32, ++ pub p_uutime_usec: u32, ++ pub p_ustime_sec: u32, ++ pub p_ustime_usec: u32, ++ pub p_uru_maxrss: u64, ++ pub p_uru_ixrss: u64, ++ pub p_uru_idrss: u64, ++ pub p_uru_isrss: u64, ++ pub p_uru_minflt: u64, ++ pub p_uru_majflt: u64, ++ pub p_uru_nswap: u64, ++ pub p_uru_inblock: u64, ++ pub p_uru_oublock: u64, ++ pub p_uru_msgsnd: u64, ++ pub p_uru_msgrcv: u64, ++ pub p_uru_nsignals: u64, ++ pub p_uru_nvcsw: u64, ++ pub p_uru_nivcsw: u64, ++ pub p_uctime_sec: u32, ++ pub p_uctime_usec: u32, ++ pub p_cpuid: u64, ++ pub p_realflag: u64, ++ pub p_nlwps: u64, ++ pub p_nrlwps: u64, ++ pub p_realstat: u64, ++ pub p_svuid: u32, ++ pub p_svgid: u32, ++ pub p_ename: [::c_char; KI_MAXEMULLEN as usize], ++ pub p_vm_vsize: i64, ++ pub p_vm_msize: i64, ++ } ++ ++ pub struct kinfo_lwp { ++ pub l_forw: u64, ++ pub l_back: u64, ++ pub l_laddr: u64, ++ pub l_addr: u64, ++ pub l_lid: i32, ++ pub l_flag: i32, ++ pub l_swtime: u32, ++ pub l_slptime: u32, ++ pub l_schedflags: i32, ++ pub l_holdcnt: i32, ++ pub l_priority: u8, ++ pub l_usrpri: u8, ++ pub l_stat: i8, ++ l_pad1: i8, ++ l_pad2: i32, ++ pub l_wmesg: [::c_char; KI_WMESGLEN as usize], ++ pub l_wchan: u64, ++ pub l_cpuid: u64, ++ pub l_rtime_sec: u32, ++ pub l_rtime_usec: u32, ++ pub l_cpticks: u32, ++ pub l_pctcpu: u32, ++ pub l_pid: u32, ++ pub l_name: [::c_char; KI_LNAMELEN as usize], ++ } ++ ++ pub struct kinfo_vmentry { ++ pub kve_start: u64, ++ pub kve_end: u64, ++ pub kve_offset: u64, ++ pub kve_type: u32, ++ pub kve_flags: u32, ++ pub kve_count: u32, ++ pub kve_wired_count: u32, ++ pub kve_advice: u32, ++ pub kve_attributes: u32, ++ pub kve_protection: u32, ++ pub kve_max_protection: u32, ++ pub kve_ref_count: u32, ++ pub kve_inheritance: u32, ++ pub kve_vn_fileid: u64, ++ pub kve_vn_size: u64, ++ pub kve_vn_fsid: u64, ++ pub kve_vn_rdev: u64, ++ pub kve_vn_type: u32, ++ pub kve_vn_mode: u32, ++ pub kve_path: [[::c_char; 32]; 32], ++ } ++ ++ pub struct __c_anonymous_posix_spawn_fae_open { ++ pub path: *mut ::c_char, ++ pub oflag: ::c_int, ++ pub mode: ::mode_t, ++ } ++ ++ pub struct __c_anonymous_posix_spawn_fae_dup2 { ++ pub newfildes: ::c_int, ++ } ++ ++ pub struct posix_spawnattr_t { ++ pub sa_flags: ::c_short, ++ pub sa_pgroup: ::pid_t, ++ pub sa_schedparam: ::sched_param, ++ pub sa_schedpolicy: ::c_int, ++ pub sa_sigdefault: sigset_t, ++ pub sa_sigmask: sigset_t, ++ } ++ ++ pub struct posix_spawn_file_actions_entry_t { ++ pub fae_action: fae_action, ++ pub fae_fildes: ::c_int, ++ #[cfg(libc_union)] ++ pub fae_data: __c_anonymous_posix_spawn_fae, ++ } ++ ++ pub struct posix_spawn_file_actions_t { ++ pub size: ::c_uint, ++ pub len: ::c_uint, ++ #[cfg(libc_union)] ++ pub fae: *mut posix_spawn_file_actions_entry_t, ++ } ++ ++ pub struct ptrace_lwpinfo { ++ pub pl_lwpid: lwpid_t, ++ pub pl_event: ::c_int, ++ } ++ ++ pub struct ptrace_lwpstatus { ++ pub pl_lwpid: lwpid_t, ++ pub pl_sigpend: sigset_t, ++ pub pl_sigmask: sigset_t, ++ pub pl_name: [::c_char; 20], ++ pub pl_private: *mut ::c_void, ++ } ++ ++ pub struct ptrace_siginfo { ++ pub psi_siginfo: siginfo_t, ++ pub psi_lwpid: lwpid_t, ++ } ++ ++ pub struct ptrace_event { ++ pub pe_set_event: ::c_int, ++ } ++ ++ pub struct sysctldesc { ++ pub descr_num: i32, ++ pub descr_ver: u32, ++ pub descr_len: u32, ++ pub descr_str: [::c_char; 1], ++ } ++ ++ pub struct ifreq { ++ pub _priv: [[::c_char; 6]; 24], ++ } ++ ++ pub struct ifconf { ++ pub ifc_len: ::c_int, ++ #[cfg(libc_union)] ++ pub ifc_ifcu: __c_anonymous_ifc_ifcu, ++ } ++ ++ pub struct tcp_info { ++ pub tcpi_state: u8, ++ pub __tcpi_ca_state: u8, ++ pub __tcpi_retransmits: u8, ++ pub __tcpi_probes: u8, ++ pub __tcpi_backoff: u8, ++ pub tcpi_options: u8, ++ pub tcp_snd_wscale: u8, ++ pub tcp_rcv_wscale: u8, ++ pub tcpi_rto: u32, ++ pub __tcpi_ato: u32, ++ pub tcpi_snd_mss: u32, ++ pub tcpi_rcv_mss: u32, ++ pub __tcpi_unacked: u32, ++ pub __tcpi_sacked: u32, ++ pub __tcpi_lost: u32, ++ pub __tcpi_retrans: u32, ++ pub __tcpi_fackets: u32, ++ pub __tcpi_last_data_sent: u32, ++ pub __tcpi_last_ack_sent: u32, ++ pub tcpi_last_data_recv: u32, ++ pub __tcpi_last_ack_recv: u32, ++ pub __tcpi_pmtu: u32, ++ pub __tcpi_rcv_ssthresh: u32, ++ pub tcpi_rtt: u32, ++ pub tcpi_rttvar: u32, ++ pub tcpi_snd_ssthresh: u32, ++ pub tcpi_snd_cwnd: u32, ++ pub __tcpi_advmss: u32, ++ pub __tcpi_reordering: u32, ++ pub __tcpi_rcv_rtt: u32, ++ pub tcpi_rcv_space: u32, ++ pub tcpi_snd_wnd: u32, ++ pub tcpi_snd_bwnd: u32, ++ pub tcpi_snd_nxt: u32, ++ pub tcpi_rcv_nxt: u32, ++ pub tcpi_toe_tid: u32, ++ pub tcpi_snd_rexmitpack: u32, ++ pub tcpi_rcv_ooopack: u32, ++ pub tcpi_snd_zerowin: u32, ++ pub __tcpi_pad: [u32; 26], ++ } + } + + s_no_extra_traits! { +@@ -552,6 +864,18 @@ s_no_extra_traits! { + __unused1: *mut ::c_void, //actually a function pointer + pub sigev_notify_attributes: *mut ::c_void + } ++ ++ #[cfg(libc_union)] ++ pub union __c_anonymous_posix_spawn_fae { ++ pub open: __c_anonymous_posix_spawn_fae_open, ++ pub dup2: __c_anonymous_posix_spawn_fae_dup2, ++ } ++ ++ #[cfg(libc_union)] ++ pub union __c_anonymous_ifc_ifcu { ++ pub ifcu_buf: *mut ::c_void, ++ pub ifcu_req: *mut ifreq, ++ } + } + + cfg_if! { +@@ -979,6 +1303,76 @@ cfg_if! { + self.sigev_notify_attributes.hash(state); + } + } ++ ++ #[cfg(libc_union)] ++ impl Eq for __c_anonymous_posix_spawn_fae {} ++ ++ #[cfg(libc_union)] ++ impl PartialEq for __c_anonymous_posix_spawn_fae { ++ fn eq(&self, other: &__c_anonymous_posix_spawn_fae) -> bool { ++ unsafe { ++ self.open == other.open ++ || self.dup2 == other.dup2 ++ } ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for __c_anonymous_posix_spawn_fae { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ unsafe { ++ f.debug_struct("__c_anonymous_posix_fae") ++ .field("open", &self.open) ++ .field("dup2", &self.dup2) ++ .finish() ++ } ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl ::hash::Hash for __c_anonymous_posix_spawn_fae { ++ fn hash(&self, state: &mut H) { ++ unsafe { ++ self.open.hash(state); ++ self.dup2.hash(state); ++ } ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl Eq for __c_anonymous_ifc_ifcu {} ++ ++ #[cfg(libc_union)] ++ impl PartialEq for __c_anonymous_ifc_ifcu { ++ fn eq(&self, other: &__c_anonymous_ifc_ifcu) -> bool { ++ unsafe { ++ self.ifcu_buf == other.ifcu_buf ++ || self.ifcu_req == other.ifcu_req ++ } ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for __c_anonymous_ifc_ifcu { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ unsafe { ++ f.debug_struct("__c_anonymous_ifc_ifcu") ++ .field("ifcu_buf", &self.ifcu_buf) ++ .field("ifcu_req", &self.ifcu_req) ++ .finish() ++ } ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl ::hash::Hash for __c_anonymous_ifc_ifcu { ++ fn hash(&self, state: &mut H) { ++ unsafe { ++ self.ifcu_buf.hash(state); ++ self.ifcu_req.hash(state); ++ } ++ } ++ } + } + } + +@@ -988,6 +1382,36 @@ pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x200; + pub const AT_SYMLINK_FOLLOW: ::c_int = 0x400; + pub const AT_REMOVEDIR: ::c_int = 0x800; + ++pub const AT_NULL: ::c_int = 0; ++pub const AT_IGNORE: ::c_int = 1; ++pub const AT_EXECFD: ::c_int = 2; ++pub const AT_PHDR: ::c_int = 3; ++pub const AT_PHENT: ::c_int = 4; ++pub const AT_PHNUM: ::c_int = 5; ++pub const AT_PAGESZ: ::c_int = 6; ++pub const AT_BASE: ::c_int = 7; ++pub const AT_FLAGS: ::c_int = 8; ++pub const AT_ENTRY: ::c_int = 9; ++pub const AT_DCACHEBSIZE: ::c_int = 10; ++pub const AT_ICACHEBSIZE: ::c_int = 11; ++pub const AT_UCACHEBSIZE: ::c_int = 12; ++pub const AT_STACKBASE: ::c_int = 13; ++pub const AT_EUID: ::c_int = 2000; ++pub const AT_RUID: ::c_int = 2001; ++pub const AT_EGID: ::c_int = 2002; ++pub const AT_RGID: ::c_int = 2003; ++pub const AT_SUN_LDELF: ::c_int = 2004; ++pub const AT_SUN_LDSHDR: ::c_int = 2005; ++pub const AT_SUN_LDNAME: ::c_int = 2006; ++pub const AT_SUN_LDPGSIZE: ::c_int = 2007; ++pub const AT_SUN_PLATFORM: ::c_int = 2008; ++pub const AT_SUN_HWCAP: ::c_int = 2009; ++pub const AT_SUN_IFLUSH: ::c_int = 2010; ++pub const AT_SUN_CPU: ::c_int = 2011; ++pub const AT_SUN_EMUL_ENTRY: ::c_int = 2012; ++pub const AT_SUN_EMUL_EXECFD: ::c_int = 2013; ++pub const AT_SUN_EXECNAME: ::c_int = 2014; ++ + pub const EXTATTR_NAMESPACE_USER: ::c_int = 1; + pub const EXTATTR_NAMESPACE_SYSTEM: ::c_int = 2; + +@@ -1047,6 +1471,30 @@ pub const F_CLOSEM: ::c_int = 10; + pub const F_GETNOSIGPIPE: ::c_int = 13; + pub const F_SETNOSIGPIPE: ::c_int = 14; + pub const F_MAXFD: ::c_int = 11; ++pub const F_GETPATH: ::c_int = 15; ++ ++pub const FUTEX_WAIT: ::c_int = 0; ++pub const FUTEX_WAKE: ::c_int = 1; ++pub const FUTEX_FD: ::c_int = 2; ++pub const FUTEX_REQUEUE: ::c_int = 3; ++pub const FUTEX_CMP_REQUEUE: ::c_int = 4; ++pub const FUTEX_WAKE_OP: ::c_int = 5; ++pub const FUTEX_LOCK_PI: ::c_int = 6; ++pub const FUTEX_UNLOCK_PI: ::c_int = 7; ++pub const FUTEX_TRYLOCK_PI: ::c_int = 8; ++pub const FUTEX_WAIT_BITSET: ::c_int = 9; ++pub const FUTEX_WAKE_BITSET: ::c_int = 10; ++pub const FUTEX_WAIT_REQUEUE_PI: ::c_int = 11; ++pub const FUTEX_CMP_REQUEUE_PI: ::c_int = 12; ++pub const FUTEX_PRIVATE_FLAG: ::c_int = 1 << 7; ++pub const FUTEX_CLOCK_REALTIME: ::c_int = 1 << 8; ++pub const FUTEX_CMD_MASK: ::c_int = !(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME); ++pub const FUTEX_WAITERS: u32 = 1 << 31; ++pub const FUTEX_OWNER_DIED: u32 = 1 << 30; ++pub const FUTEX_SYNCOBJ_1: u32 = 1 << 29; ++pub const FUTEX_SYNCOBJ_0: u32 = 1 << 28; ++pub const FUTEX_TID_MASK: u32 = (1 << 28) - 1; ++pub const FUTEX_BITSET_MATCH_ANY: u32 = !0; + + pub const IP_RECVDSTADDR: ::c_int = 7; + pub const IP_SENDSRCADDR: ::c_int = IP_RECVDSTADDR; +@@ -1163,10 +1611,7 @@ pub const IPPROTO_VRRP: ::c_int = 112; + /// Common Address Resolution Protocol + pub const IPPROTO_CARP: ::c_int = 112; + /// L2TPv3 +-// TEMP: Disabled for now; this constant was added to NetBSD on 2017-02-16, +-// but isn't yet supported by the NetBSD rumprun kernel image used for +-// libc testing. +-//pub const IPPROTO_L2TP: ::c_int = 115; ++pub const IPPROTO_L2TP: ::c_int = 115; + /// SCTP + pub const IPPROTO_SCTP: ::c_int = 132; + /// PFSYNC +@@ -1215,6 +1660,16 @@ pub const MAP_RENAME: ::c_int = 0x20; + pub const MAP_NORESERVE: ::c_int = 0x40; + pub const MAP_HASSEMAPHORE: ::c_int = 0x200; + pub const MAP_WIRED: ::c_int = 0x800; ++pub const MAP_STACK: ::c_int = 0x2000; ++// map alignment aliases for MAP_ALIGNED ++pub const MAP_ALIGNMENT_SHIFT: ::c_int = 24; ++pub const MAP_ALIGNMENT_MASK: ::c_int = 0xff << MAP_ALIGNMENT_SHIFT; ++pub const MAP_ALIGNMENT_64KB: ::c_int = 16 << MAP_ALIGNMENT_SHIFT; ++pub const MAP_ALIGNMENT_16MB: ::c_int = 24 << MAP_ALIGNMENT_SHIFT; ++pub const MAP_ALIGNMENT_4GB: ::c_int = 32 << MAP_ALIGNMENT_SHIFT; ++pub const MAP_ALIGNMENT_1TB: ::c_int = 40 << MAP_ALIGNMENT_SHIFT; ++pub const MAP_ALIGNMENT_256TB: ::c_int = 48 << MAP_ALIGNMENT_SHIFT; ++pub const MAP_ALIGNMENT_64PB: ::c_int = 56 << MAP_ALIGNMENT_SHIFT; + // mremap flag + pub const MAP_REMAPDUP: ::c_int = 0x004; + +@@ -1373,6 +1828,23 @@ pub const BIOCSDLT: ::c_ulong = 0x80044278; + pub const BIOCGSEESENT: ::c_ulong = 0x40044276; + pub const BIOCSSEESENT: ::c_ulong = 0x80044277; + ++// ++pub const MNT_UNION: ::c_int = 0x00000020; ++pub const MNT_NOCOREDUMP: ::c_int = 0x00008000; ++pub const MNT_RELATIME: ::c_int = 0x00020000; ++pub const MNT_IGNORE: ::c_int = 0x00100000; ++pub const MNT_NFS4ACLS: ::c_int = 0x00200000; ++pub const MNT_DISCARD: ::c_int = 0x00800000; ++pub const MNT_EXTATTR: ::c_int = 0x01000000; ++pub const MNT_LOG: ::c_int = 0x02000000; ++pub const MNT_NOATIME: ::c_int = 0x04000000; ++pub const MNT_AUTOMOUNTED: ::c_int = 0x10000000; ++pub const MNT_SYMPERM: ::c_int = 0x20000000; ++pub const MNT_NODEVMTIME: ::c_int = 0x40000000; ++pub const MNT_SOFTDEP: ::c_int = 0x80000000; ++pub const MNT_POSIX1EACLS: ::c_int = 0x00000800; ++pub const MNT_ACLS: ::c_int = MNT_POSIX1EACLS; ++ + // + pub const NTP_API: ::c_int = 4; + pub const MAXPHASE: ::c_long = 500000000; +@@ -1425,6 +1897,13 @@ pub const TIME_OOP: ::c_int = 3; + pub const TIME_WAIT: ::c_int = 4; + pub const TIME_ERROR: ::c_int = 5; + ++pub const LITTLE_ENDIAN: ::c_int = 1234; ++pub const BIG_ENDIAN: ::c_int = 4321; ++ ++pub const PL_EVENT_NONE: ::c_int = 0; ++pub const PL_EVENT_SIGNAL: ::c_int = 1; ++pub const PL_EVENT_SUSPENDED: ::c_int = 2; ++ + cfg_if! { + if #[cfg(any(target_arch = "sparc", target_arch = "sparc64", + target_arch = "x86", target_arch = "x86_64"))] { +@@ -1478,6 +1957,11 @@ pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 1; + pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 2; + pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; + ++pub const SCHED_NONE: ::c_int = -1; ++pub const SCHED_OTHER: ::c_int = 0; ++pub const SCHED_FIFO: ::c_int = 1; ++pub const SCHED_RR: ::c_int = 2; ++ + pub const EVFILT_AIO: u32 = 2; + pub const EVFILT_PROC: u32 = 4; + pub const EVFILT_READ: u32 = 0; +@@ -1485,6 +1969,9 @@ pub const EVFILT_SIGNAL: u32 = 5; + pub const EVFILT_TIMER: u32 = 6; + pub const EVFILT_VNODE: u32 = 3; + pub const EVFILT_WRITE: u32 = 1; ++pub const EVFILT_FS: u32 = 7; ++pub const EVFILT_USER: u32 = 8; ++pub const EVFILT_EMPTY: u32 = 9; + + pub const EV_ADD: u32 = 0x1; + pub const EV_DELETE: u32 = 0x2; +@@ -1499,6 +1986,13 @@ pub const EV_ERROR: u32 = 0x4000; + pub const EV_EOF: u32 = 0x8000; + pub const EV_SYSFLAGS: u32 = 0xf000; + ++pub const NOTE_TRIGGER: u32 = 0x01000000; ++pub const NOTE_FFNOP: u32 = 0x00000000; ++pub const NOTE_FFAND: u32 = 0x40000000; ++pub const NOTE_FFOR: u32 = 0x80000000; ++pub const NOTE_FFCOPY: u32 = 0xc0000000; ++pub const NOTE_FFCTRLMASK: u32 = 0xc0000000; ++pub const NOTE_FFLAGSMASK: u32 = 0x00ffffff; + pub const NOTE_LOWAT: u32 = 0x00000001; + pub const NOTE_DELETE: u32 = 0x00000001; + pub const NOTE_WRITE: u32 = 0x00000002; +@@ -1515,9 +2009,21 @@ pub const NOTE_PCTRLMASK: u32 = 0xf0000000; + pub const NOTE_TRACK: u32 = 0x00000001; + pub const NOTE_TRACKERR: u32 = 0x00000002; + pub const NOTE_CHILD: u32 = 0x00000004; ++pub const NOTE_MSECONDS: u32 = 0x00000000; ++pub const NOTE_SECONDS: u32 = 0x00000001; ++pub const NOTE_USECONDS: u32 = 0x00000002; ++pub const NOTE_NSECONDS: u32 = 0x00000003; ++pub const NOTE_ABSTIME: u32 = 0x000000010; + + pub const TMP_MAX: ::c_uint = 308915776; + ++pub const AI_PASSIVE: ::c_int = 0x00000001; ++pub const AI_CANONNAME: ::c_int = 0x00000002; ++pub const AI_NUMERICHOST: ::c_int = 0x00000004; ++pub const AI_NUMERICSERV: ::c_int = 0x00000008; ++pub const AI_ADDRCONFIG: ::c_int = 0x00000400; ++pub const AI_SRV: ::c_int = 0x00000800; ++ + pub const NI_MAXHOST: ::socklen_t = 1025; + pub const NI_MAXSERV: ::socklen_t = 32; + +@@ -1681,6 +2187,8 @@ pub const KERN_PROC_NARGV: ::c_int = 2; + pub const KERN_PROC_ENV: ::c_int = 3; + pub const KERN_PROC_NENV: ::c_int = 4; + pub const KERN_PROC_PATHNAME: ::c_int = 5; ++pub const VM_PROC: ::c_int = 16; ++pub const VM_PROC_MAP: ::c_int = 1; + + pub const EAI_AGAIN: ::c_int = 2; + pub const EAI_BADFLAGS: ::c_int = 3; +@@ -1712,6 +2220,11 @@ pub const WCONTINUED: ::c_int = 0x00000010; + pub const WEXITED: ::c_int = 0x000000020; + pub const WNOWAIT: ::c_int = 0x00010000; + ++pub const WALTSIG: ::c_int = 0x00000004; ++pub const WALLSIG: ::c_int = 0x00000008; ++pub const WTRAPPED: ::c_int = 0x00000040; ++pub const WNOZOMBIE: ::c_int = 0x00020000; ++ + pub const P_ALL: idtype_t = 0; + pub const P_PID: idtype_t = 1; + pub const P_PGID: idtype_t = 4; +@@ -1775,12 +2288,119 @@ pub const PT_SYSCALLEMU: ::c_int = 15; + pub const PT_SET_EVENT_MASK: ::c_int = 16; + pub const PT_GET_EVENT_MASK: ::c_int = 17; + pub const PT_GET_PROCESS_STATE: ::c_int = 18; ++pub const PT_SET_SIGINFO: ::c_int = 19; ++pub const PT_GET_SIGINFO: ::c_int = 20; ++pub const PT_RESUME: ::c_int = 21; ++pub const PT_SUSPEND: ::c_int = 23; ++pub const PT_STOP: ::c_int = 23; ++pub const PT_LWPSTATUS: ::c_int = 24; ++pub const PT_LWPNEXT: ::c_int = 25; ++pub const PT_SET_SIGPASS: ::c_int = 26; ++pub const PT_GET_SIGPASS: ::c_int = 27; + pub const PT_FIRSTMACH: ::c_int = 32; + ++pub const POSIX_SPAWN_RESETIDS: ::c_int = 0x01; ++pub const POSIX_SPAWN_SETPGROUP: ::c_int = 0x02; ++pub const POSIX_SPAWN_SETSCHEDPARAM: ::c_int = 0x04; ++pub const POSIX_SPAWN_SETSCHEDULER: ::c_int = 0x08; ++pub const POSIX_SPAWN_SETSIGDEF: ::c_int = 0x10; ++pub const POSIX_SPAWN_SETSIGMASK: ::c_int = 0x20; ++pub const POSIX_SPAWN_RETURNERROR: ::c_int = 0x40; ++ + // Flags for chflags(2) +-pub const SF_SNAPSHOT: ::c_ulong = 0x00200000; ++pub const SF_APPEND: ::c_ulong = 0x00040000; ++pub const SF_ARCHIVED: ::c_ulong = 0x00010000; ++pub const SF_IMMUTABLE: ::c_ulong = 0x00020000; + pub const SF_LOG: ::c_ulong = 0x00400000; ++pub const SF_SETTABLE: ::c_ulong = 0xffff0000; + pub const SF_SNAPINVAL: ::c_ulong = 0x00800000; ++pub const SF_SNAPSHOT: ::c_ulong = 0x00200000; ++pub const UF_APPEND: ::c_ulong = 0x00000004; ++pub const UF_IMMUTABLE: ::c_ulong = 0x00000002; ++pub const UF_NODUMP: ::c_ulong = 0x00000001; ++pub const UF_OPAQUE: ::c_ulong = 0x00000008; ++pub const UF_SETTABLE: ::c_ulong = 0x0000ffff; ++ ++// sys/sysctl.h ++pub const KVME_PROT_READ: ::c_int = 0x00000001; ++pub const KVME_PROT_WRITE: ::c_int = 0x00000002; ++pub const KVME_PROT_EXEC: ::c_int = 0x00000004; ++ ++pub const KVME_FLAG_COW: ::c_int = 0x00000001; ++pub const KVME_FLAG_NEEDS_COPY: ::c_int = 0x00000002; ++pub const KVME_FLAG_NOCOREDUMP: ::c_int = 0x000000004; ++pub const KVME_FLAG_PAGEABLE: ::c_int = 0x000000008; ++pub const KVME_FLAG_GROWS_UP: ::c_int = 0x000000010; ++pub const KVME_FLAG_GROWS_DOWN: ::c_int = 0x000000020; ++ ++pub const NGROUPS_MAX: ::c_int = 16; ++ ++pub const KI_NGROUPS: ::c_int = 16; ++pub const KI_MAXCOMLEN: ::c_int = 24; ++pub const KI_WMESGLEN: ::c_int = 8; ++pub const KI_MAXLOGNAME: ::c_int = 24; ++pub const KI_MAXEMULLEN: ::c_int = 16; ++pub const KI_LNAMELEN: ::c_int = 20; ++ ++// sys/lwp.h ++pub const LSIDL: ::c_int = 1; ++pub const LSRUN: ::c_int = 2; ++pub const LSSLEEP: ::c_int = 3; ++pub const LSSTOP: ::c_int = 4; ++pub const LSZOMB: ::c_int = 5; ++pub const LSONPROC: ::c_int = 7; ++pub const LSSUSPENDED: ::c_int = 8; ++ ++pub const _REG_RDI: ::c_int = 0; ++pub const _REG_RSI: ::c_int = 1; ++pub const _REG_RDX: ::c_int = 2; ++pub const _REG_RCX: ::c_int = 3; ++pub const _REG_R8: ::c_int = 4; ++pub const _REG_R9: ::c_int = 5; ++pub const _REG_R10: ::c_int = 6; ++pub const _REG_R11: ::c_int = 7; ++pub const _REG_R12: ::c_int = 8; ++pub const _REG_R13: ::c_int = 9; ++pub const _REG_R14: ::c_int = 10; ++pub const _REG_R15: ::c_int = 11; ++pub const _REG_RBP: ::c_int = 12; ++pub const _REG_RBX: ::c_int = 13; ++pub const _REG_RAX: ::c_int = 14; ++pub const _REG_GS: ::c_int = 15; ++pub const _REG_FS: ::c_int = 16; ++pub const _REG_ES: ::c_int = 17; ++pub const _REG_DS: ::c_int = 18; ++pub const _REG_TRAPNO: ::c_int = 19; ++pub const _REG_ERR: ::c_int = 20; ++pub const _REG_RIP: ::c_int = 21; ++pub const _REG_CS: ::c_int = 22; ++pub const _REG_RFLAGS: ::c_int = 23; ++pub const _REG_RSP: ::c_int = 24; ++pub const _REG_SS: ::c_int = 25; ++ ++// sys/xattr.h ++pub const XATTR_CREATE: ::c_int = 0x01; ++pub const XATTR_REPLACE: ::c_int = 0x02; ++// sys/extattr.h ++pub const EXTATTR_NAMESPACE_EMPTY: ::c_int = 0; ++ ++// For getrandom() ++pub const GRND_NONBLOCK: ::c_uint = 0x1; ++pub const GRND_RANDOM: ::c_uint = 0x2; ++pub const GRND_INSECURE: ::c_uint = 0x4; ++ ++cfg_if! { ++ ++ if #[cfg(libc_const_extern_fn)] { ++ pub const fn MAP_ALIGNED(alignment: ::c_int) -> ::c_int { ++ alignment << MAP_ALIGNMENT_SHIFT ++ } ++ } else { ++ pub fn MAP_ALIGNED(alignment: ::c_int) -> ::c_int { ++ alignment << MAP_ALIGNMENT_SHIFT ++ } ++ } ++} + + const_fn! { + {const} fn _ALIGN(p: usize) -> usize { +@@ -1836,6 +2456,14 @@ f! { + }; + ::mem::size_of::() + ::mem::size_of::<::gid_t>() * ngrps + } ++ ++ pub fn PROT_MPROTECT(x: ::c_int) -> ::c_int { ++ x << 3 ++ } ++ ++ pub fn PROT_MPROTECT_EXTRACT(x: ::c_int) -> ::c_int { ++ (x >> 3) & 0x7 ++ } + } + + safe_f! { +@@ -1854,6 +2482,16 @@ safe_f! { + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + status == 0xffff + } ++ ++ pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { ++ let major = major as ::dev_t; ++ let minor = minor as ::dev_t; ++ let mut dev = 0; ++ dev |= (major << 8) & 0x000ff00; ++ dev |= (minor << 12) & 0xfff00000; ++ dev |= minor & 0xff; ++ dev ++ } + } + + extern "C" { +@@ -1865,6 +2503,8 @@ extern "C" { + rqtp: *const ::timespec, + rmtp: *mut ::timespec, + ) -> ::c_int; ++ ++ pub fn reallocarr(ptr: *mut ::c_void, number: ::size_t, size: ::size_t) -> ::c_int; + } + + #[link(name = "rt")] +@@ -1894,6 +2534,30 @@ extern "C" { + pub fn fchflags(fd: ::c_int, flags: ::c_ulong) -> ::c_int; + pub fn lchflags(path: *const ::c_char, flags: ::c_ulong) -> ::c_int; + ++ pub fn execvpe( ++ file: *const ::c_char, ++ argv: *const *const ::c_char, ++ envp: *const *const ::c_char, ++ ) -> ::c_int; ++ ++ pub fn extattr_list_fd( ++ fd: ::c_int, ++ attrnamespace: ::c_int, ++ data: *mut ::c_void, ++ nbytes: ::size_t, ++ ) -> ::ssize_t; ++ pub fn extattr_list_file( ++ path: *const ::c_char, ++ attrnamespace: ::c_int, ++ data: *mut ::c_void, ++ nbytes: ::size_t, ++ ) -> ::ssize_t; ++ pub fn extattr_list_link( ++ path: *const ::c_char, ++ attrnamespace: ::c_int, ++ data: *mut ::c_void, ++ nbytes: ::size_t, ++ ) -> ::ssize_t; + pub fn extattr_delete_fd( + fd: ::c_int, + attrnamespace: ::c_int, +@@ -1960,6 +2624,20 @@ extern "C" { + attrnamespace: *mut ::c_int, + ) -> ::c_int; + ++ pub fn openpty( ++ amaster: *mut ::c_int, ++ aslave: *mut ::c_int, ++ name: *mut ::c_char, ++ termp: *mut ::termios, ++ winp: *mut ::winsize, ++ ) -> ::c_int; ++ pub fn forkpty( ++ amaster: *mut ::c_int, ++ name: *mut ::c_char, ++ termp: *mut ::termios, ++ winp: *mut ::winsize, ++ ) -> ::pid_t; ++ + #[link_name = "__lutimes50"] + pub fn lutimes(file: *const ::c_char, times: *const ::timeval) -> ::c_int; + #[link_name = "__gettimeofday50"] +@@ -2041,6 +2719,8 @@ extern "C" { + ) -> ::c_int; + pub fn mq_unlink(name: *const ::c_char) -> ::c_int; + pub fn ptrace(request: ::c_int, pid: ::pid_t, addr: *mut ::c_void, data: ::c_int) -> ::c_int; ++ pub fn utrace(label: *const ::c_char, addr: *mut ::c_void, len: ::size_t) -> ::c_int; ++ pub fn pthread_getname_np(t: ::pthread_t, name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn pthread_setname_np( + t: ::pthread_t, + name: *const ::c_char, +@@ -2067,6 +2747,7 @@ extern "C" { + size: ::size_t, + set: *mut cpuset_t, + ) -> ::c_int; ++ + pub fn _cpuset_create() -> *mut cpuset_t; + pub fn _cpuset_destroy(set: *mut cpuset_t); + pub fn _cpuset_clr(cpu: cpuid_t, set: *mut cpuset_t) -> ::c_int; +@@ -2081,6 +2762,13 @@ extern "C" { + timeout: *const ::timespec, + ) -> ::c_int; + pub fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> ::c_int; ++ pub fn waitid( ++ idtype: idtype_t, ++ id: ::id_t, ++ infop: *mut ::siginfo_t, ++ options: ::c_int, ++ ) -> ::c_int; ++ + pub fn duplocale(base: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t); + pub fn localeconv_l(loc: ::locale_t) -> *mut lconv; +@@ -2141,6 +2829,21 @@ extern "C" { + ) -> ::size_t; + pub fn iconv_close(cd: iconv_t) -> ::c_int; + ++ pub fn timer_create( ++ clockid: ::clockid_t, ++ sevp: *mut ::sigevent, ++ timerid: *mut ::timer_t, ++ ) -> ::c_int; ++ pub fn timer_delete(timerid: ::timer_t) -> ::c_int; ++ pub fn timer_getoverrun(timerid: ::timer_t) -> ::c_int; ++ pub fn timer_gettime(timerid: ::timer_t, curr_value: *mut ::itimerspec) -> ::c_int; ++ pub fn timer_settime( ++ timerid: ::timer_t, ++ flags: ::c_int, ++ new_value: *const ::itimerspec, ++ old_value: *mut ::itimerspec, ++ ) -> ::c_int; ++ + // Added in `NetBSD` 7.0 + pub fn explicit_memset(b: *mut ::c_void, c: ::c_int, len: ::size_t); + pub fn consttime_memequal(a: *const ::c_void, b: *const ::c_void, len: ::size_t) -> ::c_int; +@@ -2153,6 +2856,107 @@ extern "C" { + newsize: ::size_t, + flags: ::c_int, + ) -> *mut ::c_void; ++ ++ pub fn sched_rr_get_interval(pid: ::pid_t, t: *mut ::timespec) -> ::c_int; ++ pub fn sched_setparam(pid: ::pid_t, param: *const ::sched_param) -> ::c_int; ++ pub fn sched_getparam(pid: ::pid_t, param: *mut ::sched_param) -> ::c_int; ++ pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int; ++ pub fn sched_setscheduler( ++ pid: ::pid_t, ++ policy: ::c_int, ++ param: *const ::sched_param, ++ ) -> ::c_int; ++ ++ #[link_name = "__pollts50"] ++ pub fn pollts( ++ fds: *mut ::pollfd, ++ nfds: ::nfds_t, ++ ts: *const ::timespec, ++ sigmask: *const ::sigset_t, ++ ) -> ::c_int; ++ pub fn ppoll( ++ fds: *mut ::pollfd, ++ nfds: ::nfds_t, ++ ts: *const ::timespec, ++ sigmask: *const ::sigset_t, ++ ) -> ::c_int; ++ pub fn posix_spawn( ++ pid: *mut ::pid_t, ++ path: *const ::c_char, ++ file_actions: *const ::posix_spawn_file_actions_t, ++ attrp: *const ::posix_spawnattr_t, ++ argv: *const *mut ::c_char, ++ envp: *const *mut ::c_char, ++ ) -> ::c_int; ++ pub fn posix_spawnp( ++ pid: *mut ::pid_t, ++ file: *const ::c_char, ++ file_actions: *const ::posix_spawn_file_actions_t, ++ attrp: *const ::posix_spawnattr_t, ++ argv: *const *mut ::c_char, ++ envp: *const *mut ::c_char, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_init(attr: *mut posix_spawnattr_t) -> ::c_int; ++ pub fn posix_spawnattr_destroy(attr: *mut posix_spawnattr_t) -> ::c_int; ++ pub fn posix_spawnattr_getsigdefault( ++ attr: *const posix_spawnattr_t, ++ default: *mut ::sigset_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setsigdefault( ++ attr: *mut posix_spawnattr_t, ++ default: *const ::sigset_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_getsigmask( ++ attr: *const posix_spawnattr_t, ++ default: *mut ::sigset_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setsigmask( ++ attr: *mut posix_spawnattr_t, ++ default: *const ::sigset_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_getflags( ++ attr: *const posix_spawnattr_t, ++ flags: *mut ::c_short, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setflags(attr: *mut posix_spawnattr_t, flags: ::c_short) -> ::c_int; ++ pub fn posix_spawnattr_getpgroup( ++ attr: *const posix_spawnattr_t, ++ flags: *mut ::pid_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: ::pid_t) -> ::c_int; ++ pub fn posix_spawnattr_getschedpolicy( ++ attr: *const posix_spawnattr_t, ++ flags: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setschedpolicy(attr: *mut posix_spawnattr_t, flags: ::c_int) -> ::c_int; ++ pub fn posix_spawnattr_getschedparam( ++ attr: *const posix_spawnattr_t, ++ param: *mut ::sched_param, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setschedparam( ++ attr: *mut posix_spawnattr_t, ++ param: *const ::sched_param, ++ ) -> ::c_int; ++ ++ pub fn posix_spawn_file_actions_init(actions: *mut posix_spawn_file_actions_t) -> ::c_int; ++ pub fn posix_spawn_file_actions_destroy(actions: *mut posix_spawn_file_actions_t) -> ::c_int; ++ pub fn posix_spawn_file_actions_addopen( ++ actions: *mut posix_spawn_file_actions_t, ++ fd: ::c_int, ++ path: *const ::c_char, ++ oflag: ::c_int, ++ mode: ::mode_t, ++ ) -> ::c_int; ++ pub fn posix_spawn_file_actions_addclose( ++ actions: *mut posix_spawn_file_actions_t, ++ fd: ::c_int, ++ ) -> ::c_int; ++ pub fn posix_spawn_file_actions_adddup2( ++ actions: *mut posix_spawn_file_actions_t, ++ fd: ::c_int, ++ newfd: ::c_int, ++ ) -> ::c_int; ++ pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; + } + + #[link(name = "util")] +@@ -2194,15 +2998,142 @@ extern "C" { + pub fn emalloc(n: ::size_t) -> *mut ::c_void; + pub fn ecalloc(n: ::size_t, c: ::size_t) -> *mut ::c_void; + pub fn erealloc(p: *mut ::c_void, n: ::size_t) -> *mut ::c_void; ++ pub fn ereallocarr(p: *mut ::c_void, n: ::size_t, s: ::size_t); + pub fn estrdup(s: *const ::c_char) -> *mut ::c_char; + pub fn estrndup(s: *const ::c_char, len: ::size_t) -> *mut ::c_char; + pub fn estrlcpy(dst: *mut ::c_char, src: *const ::c_char, len: ::size_t) -> ::size_t; + pub fn estrlcat(dst: *mut ::c_char, src: *const ::c_char, len: ::size_t) -> ::size_t; ++ pub fn estrtoi( ++ nptr: *const ::c_char, ++ base: ::c_int, ++ lo: ::intmax_t, ++ hi: ::intmax_t, ++ ) -> ::intmax_t; ++ pub fn estrtou( ++ nptr: *const ::c_char, ++ base: ::c_int, ++ lo: ::uintmax_t, ++ hi: ::uintmax_t, ++ ) -> ::uintmax_t; + pub fn easprintf(string: *mut *mut ::c_char, fmt: *const ::c_char, ...) -> ::c_int; + pub fn evasprintf(string: *mut *mut ::c_char, fmt: *const ::c_char, ...) -> ::c_int; + pub fn esetfunc( + cb: ::Option, + ) -> ::Option; ++ pub fn secure_path(path: *const ::c_char) -> ::c_int; ++ pub fn snprintb( ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ fmt: *const ::c_char, ++ val: u64, ++ ) -> ::c_int; ++ pub fn snprintb_m( ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ fmt: *const ::c_char, ++ val: u64, ++ max: ::size_t, ++ ) -> ::c_int; ++ ++ pub fn getbootfile() -> *const ::c_char; ++ pub fn getbyteorder() -> ::c_int; ++ pub fn getdiskrawname( ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ name: *const ::c_char, ++ ) -> *const ::c_char; ++ pub fn getdiskcookedname( ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ name: *const ::c_char, ++ ) -> *const ::c_char; ++ pub fn getfsspecname( ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ spec: *const ::c_char, ++ ) -> *const ::c_char; ++ ++ pub fn strpct( ++ buf: *mut ::c_char, ++ bufsiz: ::size_t, ++ numerator: ::uintmax_t, ++ denominator: ::uintmax_t, ++ precision: ::size_t, ++ ) -> *mut ::c_char; ++ pub fn strspct( ++ buf: *mut ::c_char, ++ bufsiz: ::size_t, ++ numerator: ::intmax_t, ++ denominator: ::intmax_t, ++ precision: ::size_t, ++ ) -> *mut ::c_char; ++ #[link_name = "__login50"] ++ pub fn login(ut: *const utmp); ++ #[link_name = "__loginx50"] ++ pub fn loginx(ut: *const utmpx); ++ pub fn logout(line: *const ::c_char); ++ pub fn logoutx(line: *const ::c_char, status: ::c_int, tpe: ::c_int); ++ pub fn logwtmp(line: *const ::c_char, name: *const ::c_char, host: *const ::c_char); ++ pub fn logwtmpx( ++ line: *const ::c_char, ++ name: *const ::c_char, ++ host: *const ::c_char, ++ status: ::c_int, ++ tpe: ::c_int, ++ ); ++ ++ pub fn getxattr( ++ path: *const ::c_char, ++ name: *const ::c_char, ++ value: *mut ::c_void, ++ size: ::size_t, ++ ) -> ::ssize_t; ++ pub fn lgetxattr( ++ path: *const ::c_char, ++ name: *const ::c_char, ++ value: *mut ::c_void, ++ size: ::size_t, ++ ) -> ::ssize_t; ++ pub fn fgetxattr( ++ filedes: ::c_int, ++ name: *const ::c_char, ++ value: *mut ::c_void, ++ size: ::size_t, ++ ) -> ::ssize_t; ++ pub fn setxattr( ++ path: *const ::c_char, ++ name: *const ::c_char, ++ value: *const ::c_void, ++ size: ::size_t, ++ ) -> ::c_int; ++ pub fn lsetxattr( ++ path: *const ::c_char, ++ name: *const ::c_char, ++ value: *const ::c_void, ++ size: ::size_t, ++ ) -> ::c_int; ++ pub fn fsetxattr( ++ filedes: ::c_int, ++ name: *const ::c_char, ++ value: *const ::c_void, ++ size: ::size_t, ++ flags: ::c_int, ++ ) -> ::c_int; ++ pub fn listxattr(path: *const ::c_char, list: *mut ::c_char, size: ::size_t) -> ::ssize_t; ++ pub fn llistxattr(path: *const ::c_char, list: *mut ::c_char, size: ::size_t) -> ::ssize_t; ++ pub fn flistxattr(filedes: ::c_int, list: *mut ::c_char, size: ::size_t) -> ::ssize_t; ++ pub fn removexattr(path: *const ::c_char, name: *const ::c_char) -> ::c_int; ++ pub fn lremovexattr(path: *const ::c_char, name: *const ::c_char) -> ::c_int; ++ pub fn fremovexattr(fd: ::c_int, path: *const ::c_char, name: *const ::c_char) -> ::c_int; ++ ++ pub fn string_to_flags( ++ string_p: *mut *mut ::c_char, ++ setp: *mut ::c_ulong, ++ clrp: *mut ::c_ulong, ++ ) -> ::c_int; ++ pub fn flags_to_string(flags: ::c_ulong, def: *const ::c_char) -> ::c_int; ++ ++ pub fn kinfo_getvmmap(pid: ::pid_t, cntp: *mut ::size_t) -> *mut kinfo_vmentry; + } + + cfg_if! { +diff --git a/vendor/libc/src/unix/bsd/netbsdlike/openbsd/aarch64.rs b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/aarch64.rs +index 99350ec..2bc82e4 100644 +--- a/vendor/libc/src/unix/bsd/netbsdlike/openbsd/aarch64.rs ++++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/aarch64.rs +@@ -1,6 +1,20 @@ + pub type c_long = i64; + pub type c_ulong = u64; + pub type c_char = u8; ++pub type ucontext_t = sigcontext; ++ ++s! { ++ pub struct sigcontext { ++ __sc_unused: ::c_int, ++ pub sc_mask: ::c_int, ++ pub sc_sp: ::c_ulong, ++ pub sc_lr: ::c_ulong, ++ pub sc_elr: ::c_ulong, ++ pub sc_spsr: ::c_ulong, ++ pub sc_x: [::c_ulong; 30], ++ pub sc_cookie: ::c_long, ++ } ++} + + // should be pub(crate), but that requires Rust 1.18.0 + cfg_if! { +diff --git a/vendor/libc/src/unix/bsd/netbsdlike/openbsd/arm.rs b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/arm.rs +new file mode 100644 +index 0000000..f1ab365 +--- /dev/null ++++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/arm.rs +@@ -0,0 +1,16 @@ ++pub type c_long = i32; ++pub type c_ulong = u32; ++pub type c_char = u8; ++ ++// should be pub(crate), but that requires Rust 1.18.0 ++cfg_if! { ++ if #[cfg(libc_const_size_of)] { ++ #[doc(hidden)] ++ pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_double>() - 1; ++ } else { ++ #[doc(hidden)] ++ pub const _ALIGNBYTES: usize = 8 - 1; ++ } ++} ++ ++pub const _MAX_PAGE_SHIFT: u32 = 12; +diff --git a/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mips64.rs b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mips64.rs +new file mode 100644 +index 0000000..15803ce +--- /dev/null ++++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mips64.rs +@@ -0,0 +1,8 @@ ++pub type c_long = i64; ++pub type c_ulong = u64; ++pub type c_char = i8; ++ ++#[doc(hidden)] ++pub const _ALIGNBYTES: usize = 7; ++ ++pub const _MAX_PAGE_SHIFT: u32 = 14; +diff --git a/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs +index c5d45b4..8099bad 100644 +--- a/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs ++++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs +@@ -7,6 +7,7 @@ pub type sigset_t = ::c_uint; + pub type blksize_t = i32; + pub type fsblkcnt_t = u64; + pub type fsfilcnt_t = u64; ++pub type idtype_t = ::c_uint; + pub type pthread_attr_t = *mut ::c_void; + pub type pthread_mutex_t = *mut ::c_void; + pub type pthread_mutexattr_t = *mut ::c_void; +@@ -14,6 +15,7 @@ pub type pthread_cond_t = *mut ::c_void; + pub type pthread_condattr_t = *mut ::c_void; + pub type pthread_rwlock_t = *mut ::c_void; + pub type pthread_rwlockattr_t = *mut ::c_void; ++pub type pthread_spinlock_t = ::uintptr_t; + pub type caddr_t = *mut ::c_char; + + // elf.h +@@ -34,6 +36,11 @@ pub type Elf64_Sxword = i64; + pub type Elf64_Word = u32; + pub type Elf64_Xword = u64; + ++// search.h ++ ++pub type ENTRY = entry; ++pub type ACTION = ::c_uint; ++ + cfg_if! { + if #[cfg(target_pointer_width = "64")] { + type Elf_Addr = Elf64_Addr; +@@ -47,6 +54,12 @@ cfg_if! { + } + + s! { ++ pub struct ip_mreqn { ++ pub imr_multiaddr: in_addr, ++ pub imr_address: in_addr, ++ pub imr_ifindex: ::c_int, ++ } ++ + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_matchc: ::size_t, +@@ -208,6 +221,12 @@ s! { + pub sin_zero: [i8; 8], + } + ++ pub struct splice { ++ pub sp_fd: ::c_int, ++ pub sp_max: ::off_t, ++ pub sp_idle: ::timeval, ++ } ++ + pub struct kevent { + pub ident: ::uintptr_t, + pub filter: ::c_short, +@@ -383,6 +402,137 @@ s! { + pub dlpi_phdr: *const Elf_Phdr, + pub dlpi_phnum: Elf_Half, + } ++ ++ // sys/sysctl.h ++ pub struct kinfo_proc { ++ pub p_forw: u64, ++ pub p_back: u64, ++ pub p_paddr: u64, ++ pub p_addr: u64, ++ pub p_fd: u64, ++ pub p_stats: u64, ++ pub p_limit: u64, ++ pub p_vmspace: u64, ++ pub p_sigacts: u64, ++ pub p_sess: u64, ++ pub p_tsess: u64, ++ pub p_ru: u64, ++ pub p_eflag: i32, ++ pub p_exitsig: i32, ++ pub p_flag: i32, ++ pub p_pid: i32, ++ pub p_ppid: i32, ++ pub p_sid: i32, ++ pub p__pgid: i32, ++ pub p_tpgid: i32, ++ pub p_uid: u32, ++ pub p_ruid: u32, ++ pub p_gid: u32, ++ pub p_rgid: u32, ++ pub p_groups: [u32; KI_NGROUPS as usize], ++ pub p_ngroups: i16, ++ pub p_jobc: i16, ++ pub p_tdev: u32, ++ pub p_estcpu: u32, ++ pub p_rtime_sec: u32, ++ pub p_rtime_usec: u32, ++ pub p_cpticks: i32, ++ pub p_pctcpu: u32, ++ pub p_swtime: u32, ++ pub p_slptime: u32, ++ pub p_schedflags: i32, ++ pub p_uticks: u64, ++ pub p_sticks: u64, ++ pub p_iticks: u64, ++ pub p_tracep: u64, ++ pub p_traceflag: i32, ++ pub p_holdcnt: i32, ++ pub p_siglist: i32, ++ pub p_sigmask: u32, ++ pub p_sigignore: u32, ++ pub p_sigcatch: u32, ++ pub p_stat: i8, ++ pub p_priority: u8, ++ pub p_usrpri: u8, ++ pub p_nice: u8, ++ pub p_xstat: u16, ++ pub p_spare: u16, ++ pub p_comm: [::c_char; KI_MAXCOMLEN as usize], ++ pub p_wmesg: [::c_char; KI_WMESGLEN as usize], ++ pub p_wchan: u64, ++ pub p_login: [::c_char; KI_MAXLOGNAME as usize], ++ pub p_vm_rssize: i32, ++ pub p_vm_tsize: i32, ++ pub p_vm_dsize: i32, ++ pub p_vm_ssize: i32, ++ pub p_uvalid: i64, ++ pub p_ustart_sec: u64, ++ pub p_ustart_usec: u32, ++ pub p_uutime_sec: u32, ++ pub p_uutime_usec: u32, ++ pub p_ustime_sec: u32, ++ pub p_ustime_usec: u32, ++ pub p_uru_maxrss: u64, ++ pub p_uru_ixrss: u64, ++ pub p_uru_idrss: u64, ++ pub p_uru_isrss: u64, ++ pub p_uru_minflt: u64, ++ pub p_uru_majflt: u64, ++ pub p_uru_nswap: u64, ++ pub p_uru_inblock: u64, ++ pub p_uru_oublock: u64, ++ pub p_uru_msgsnd: u64, ++ pub p_uru_msgrcv: u64, ++ pub p_uru_nsignals: u64, ++ pub p_uru_nvcsw: u64, ++ pub p_uru_nivcsw: u64, ++ pub p_uctime_sec: u32, ++ pub p_uctime_usec: u32, ++ pub p_psflags: u32, ++ pub p_acflag: u32, ++ pub p_svuid: u32, ++ pub p_svgid: u32, ++ pub p_emul: [::c_char; KI_EMULNAMELEN as usize], ++ pub p_rlim_rss_cur: u64, ++ pub p_cpuid: u64, ++ pub p_vm_map_size: u64, ++ pub p_tid: i32, ++ pub p_rtableid: u32, ++ pub p_pledge: u64, ++ pub p_name: [::c_char; KI_MAXCOMLEN as usize], ++ } ++ ++ pub struct kinfo_vmentry { ++ pub kve_start: ::c_ulong, ++ pub kve_end: ::c_ulong, ++ pub kve_guard: ::c_ulong, ++ pub kve_fspace: ::c_ulong, ++ pub kve_fspace_augment: ::c_ulong, ++ pub kve_offset: u64, ++ pub kve_wired_count: ::c_int, ++ pub kve_etype: ::c_int, ++ pub kve_protection: ::c_int, ++ pub kve_max_protection: ::c_int, ++ pub kve_advice: ::c_int, ++ pub kve_inheritance: ::c_int, ++ pub kve_flags: u8, ++ } ++ ++ pub struct ptrace_state { ++ pub pe_report_event: ::c_int, ++ pub pe_other_pid: ::pid_t, ++ pub pe_tid: ::pid_t, ++ } ++ ++ pub struct ptrace_thread_state { ++ pub pts_tid: ::pid_t, ++ } ++ ++ // search.h ++ pub struct entry { ++ pub key: *mut ::c_char, ++ pub data: *mut ::c_void, ++ } + } + + impl siginfo_t { +@@ -1114,6 +1264,10 @@ pub const _SC_NPROCESSORS_ONLN: ::c_int = 503; + + pub const FD_SETSIZE: usize = 1024; + ++pub const SCHED_FIFO: ::c_int = 1; ++pub const SCHED_OTHER: ::c_int = 2; ++pub const SCHED_RR: ::c_int = 3; ++ + pub const ST_NOSUID: ::c_ulong = 2; + + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = 0 as *mut _; +@@ -1126,13 +1280,15 @@ pub const PTHREAD_MUTEX_NORMAL: ::c_int = 3; + pub const PTHREAD_MUTEX_STRICT_NP: ::c_int = 4; + pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_STRICT_NP; + ++pub const EVFILT_READ: i16 = -1; ++pub const EVFILT_WRITE: i16 = -2; + pub const EVFILT_AIO: i16 = -3; ++pub const EVFILT_VNODE: i16 = -4; + pub const EVFILT_PROC: i16 = -5; +-pub const EVFILT_READ: i16 = -1; + pub const EVFILT_SIGNAL: i16 = -6; + pub const EVFILT_TIMER: i16 = -7; +-pub const EVFILT_VNODE: i16 = -4; +-pub const EVFILT_WRITE: i16 = -2; ++pub const EVFILT_DEVICE: i16 = -8; ++pub const EVFILT_EXCEPT: i16 = -9; + + pub const EV_ADD: u16 = 0x1; + pub const EV_DELETE: u16 = 0x2; +@@ -1145,10 +1301,13 @@ pub const EV_DISPATCH: u16 = 0x80; + pub const EV_FLAG1: u16 = 0x2000; + pub const EV_ERROR: u16 = 0x4000; + pub const EV_EOF: u16 = 0x8000; +-pub const EV_SYSFLAGS: u16 = 0xf000; ++ ++#[deprecated(since = "0.2.113", note = "Not stable across OS versions")] ++pub const EV_SYSFLAGS: u16 = 0xf800; + + pub const NOTE_LOWAT: u32 = 0x00000001; + pub const NOTE_EOF: u32 = 0x00000002; ++pub const NOTE_OOB: u32 = 0x00000004; + pub const NOTE_DELETE: u32 = 0x00000001; + pub const NOTE_WRITE: u32 = 0x00000002; + pub const NOTE_EXTEND: u32 = 0x00000004; +@@ -1165,9 +1324,18 @@ pub const NOTE_PCTRLMASK: u32 = 0xf0000000; + pub const NOTE_TRACK: u32 = 0x00000001; + pub const NOTE_TRACKERR: u32 = 0x00000002; + pub const NOTE_CHILD: u32 = 0x00000004; ++pub const NOTE_CHANGE: u32 = 0x00000001; + + pub const TMP_MAX: ::c_uint = 0x7fffffff; + ++pub const AI_PASSIVE: ::c_int = 1; ++pub const AI_CANONNAME: ::c_int = 2; ++pub const AI_NUMERICHOST: ::c_int = 4; ++pub const AI_EXT: ::c_int = 8; ++pub const AI_NUMERICSERV: ::c_int = 16; ++pub const AI_FQDN: ::c_int = 32; ++pub const AI_ADDRCONFIG: ::c_int = 64; ++ + pub const NI_NUMERICHOST: ::c_int = 1; + pub const NI_NUMERICSERV: ::c_int = 2; + pub const NI_NOFQDN: ::c_int = 4; +@@ -1311,6 +1479,35 @@ pub const KI_WMESGLEN: ::c_int = 8; + pub const KI_MAXLOGNAME: ::c_int = 32; + pub const KI_EMULNAMELEN: ::c_int = 8; + ++pub const KVE_ET_OBJ: ::c_int = 0x00000001; ++pub const KVE_ET_SUBMAP: ::c_int = 0x00000002; ++pub const KVE_ET_COPYONWRITE: ::c_int = 0x00000004; ++pub const KVE_ET_NEEDSCOPY: ::c_int = 0x00000008; ++pub const KVE_ET_HOLE: ::c_int = 0x00000010; ++pub const KVE_ET_NOFAULT: ::c_int = 0x00000020; ++pub const KVE_ET_STACK: ::c_int = 0x00000040; ++pub const KVE_ET_WC: ::c_int = 0x000000080; ++pub const KVE_ET_CONCEAL: ::c_int = 0x000000100; ++pub const KVE_ET_SYSCALL: ::c_int = 0x000000200; ++pub const KVE_ET_FREEMAPPED: ::c_int = 0x000000800; ++ ++pub const KVE_PROT_NONE: ::c_int = 0x00000000; ++pub const KVE_PROT_READ: ::c_int = 0x00000001; ++pub const KVE_PROT_WRITE: ::c_int = 0x00000002; ++pub const KVE_PROT_EXEC: ::c_int = 0x00000004; ++ ++pub const KVE_ADV_NORMAL: ::c_int = 0x00000000; ++pub const KVE_ADV_RANDOM: ::c_int = 0x00000001; ++pub const KVE_ADV_SEQUENTIAL: ::c_int = 0x00000002; ++ ++pub const KVE_INH_SHARE: ::c_int = 0x00000000; ++pub const KVE_INH_COPY: ::c_int = 0x00000010; ++pub const KVE_INH_NONE: ::c_int = 0x00000020; ++pub const KVE_INH_ZERO: ::c_int = 0x00000030; ++ ++pub const KVE_F_STATIC: ::c_int = 0x1; ++pub const KVE_F_KMEM: ::c_int = 0x2; ++ + pub const CHWFLOW: ::tcflag_t = ::MDMBUF | ::CRTSCTS; + pub const OLCUC: ::tcflag_t = 0x20; + pub const ONOCR: ::tcflag_t = 0x40; +@@ -1402,6 +1599,11 @@ pub const PTHREAD_STACK_MIN: ::size_t = 1_usize << _MAX_PAGE_SHIFT; + pub const MINSIGSTKSZ: ::size_t = 3_usize << _MAX_PAGE_SHIFT; + pub const SIGSTKSZ: ::size_t = MINSIGSTKSZ + (1_usize << _MAX_PAGE_SHIFT) * 4; + ++pub const PT_SET_EVENT_MASK: ::c_int = 12; ++pub const PT_GET_EVENT_MASK: ::c_int = 13; ++pub const PT_GET_PROCESS_STATE: ::c_int = 14; ++pub const PT_GET_THREAD_FIRST: ::c_int = 15; ++pub const PT_GET_THREAD_NEXT: ::c_int = 16; + pub const PT_FIRSTMACH: ::c_int = 32; + + pub const SOCK_CLOEXEC: ::c_int = 0x8000; +@@ -1414,7 +1616,80 @@ pub const BIOCSDLT: ::c_ulong = 0x8004427a; + + pub const PTRACE_FORK: ::c_int = 0x0002; + +-pub const WCONTINUED: ::c_int = 8; ++pub const WCONTINUED: ::c_int = 0x08; ++pub const WEXITED: ::c_int = 0x04; ++pub const WSTOPPED: ::c_int = 0x02; // same as WUNTRACED ++pub const WNOWAIT: ::c_int = 0x10; ++pub const WTRAPPED: ::c_int = 0x20; ++ ++pub const P_ALL: ::idtype_t = 0; ++pub const P_PGID: ::idtype_t = 1; ++pub const P_PID: ::idtype_t = 2; ++ ++// search.h ++pub const FIND: ::ACTION = 0; ++pub const ENTER: ::ACTION = 1; ++ ++// futex.h ++pub const FUTEX_WAIT: ::c_int = 1; ++pub const FUTEX_WAKE: ::c_int = 2; ++pub const FUTEX_REQUEUE: ::c_int = 3; ++pub const FUTEX_PRIVATE_FLAG: ::c_int = 128; ++ ++// sysctl.h, kinfo_proc p_eflag constants ++pub const EPROC_CTTY: i32 = 0x01; // controlling tty vnode active ++pub const EPROC_SLEADER: i32 = 0x02; // session leader ++pub const EPROC_UNVEIL: i32 = 0x04; // has unveil settings ++pub const EPROC_LKUNVEIL: i32 = 0x08; // unveil is locked ++ ++// Flags for chflags(2) ++pub const UF_SETTABLE: ::c_uint = 0x0000ffff; ++pub const UF_NODUMP: ::c_uint = 0x00000001; ++pub const UF_IMMUTABLE: ::c_uint = 0x00000002; ++pub const UF_APPEND: ::c_uint = 0x00000004; ++pub const UF_OPAQUE: ::c_uint = 0x00000008; ++pub const SF_SETTABLE: ::c_uint = 0xffff0000; ++pub const SF_ARCHIVED: ::c_uint = 0x00010000; ++pub const SF_IMMUTABLE: ::c_uint = 0x00020000; ++pub const SF_APPEND: ::c_uint = 0x00040000; ++ ++// sys/mount.h ++pub const MNT_NOPERM: ::c_int = 0x00000020; ++pub const MNT_WXALLOWED: ::c_int = 0x00000800; ++pub const MNT_EXRDONLY: ::c_int = 0x00000080; ++pub const MNT_DEFEXPORTED: ::c_int = 0x00000200; ++pub const MNT_EXPORTANON: ::c_int = 0x00000400; ++pub const MNT_ROOTFS: ::c_int = 0x00004000; ++pub const MNT_NOATIME: ::c_int = 0x00008000; ++pub const MNT_DELEXPORT: ::c_int = 0x00020000; ++pub const MNT_STALLED: ::c_int = 0x00100000; ++pub const MNT_SWAPPABLE: ::c_int = 0x00200000; ++pub const MNT_WANTRDWR: ::c_int = 0x02000000; ++pub const MNT_SOFTDEP: ::c_int = 0x04000000; ++pub const MNT_DOOMED: ::c_int = 0x08000000; ++ ++// For use with vfs_fsync and getfsstat ++pub const MNT_WAIT: ::c_int = 1; ++pub const MNT_NOWAIT: ::c_int = 2; ++pub const MNT_LAZY: ::c_int = 3; ++ ++// sys/_time.h ++pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 2; ++pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 4; ++pub const CLOCK_UPTIME: ::clockid_t = 5; ++pub const CLOCK_BOOTTIME: ::clockid_t = 6; ++ ++pub const LC_COLLATE_MASK: ::c_int = 1 << ::LC_COLLATE; ++pub const LC_CTYPE_MASK: ::c_int = 1 << ::LC_CTYPE; ++pub const LC_MONETARY_MASK: ::c_int = 1 << ::LC_MONETARY; ++pub const LC_NUMERIC_MASK: ::c_int = 1 << ::LC_NUMERIC; ++pub const LC_TIME_MASK: ::c_int = 1 << ::LC_TIME; ++pub const LC_MESSAGES_MASK: ::c_int = 1 << ::LC_MESSAGES; ++ ++const _LC_LAST: ::c_int = 7; ++pub const LC_ALL_MASK: ::c_int = (1 << _LC_LAST) - 2; ++ ++pub const LC_GLOBAL_LOCALE: ::locale_t = -1isize as ::locale_t; + + const_fn! { + {const} fn _ALIGN(p: usize) -> usize { +@@ -1472,6 +1747,16 @@ safe_f! { + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + (status & 0o177777) == 0o177777 + } ++ ++ pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { ++ let major = major as ::dev_t; ++ let minor = minor as ::dev_t; ++ let mut dev = 0; ++ dev |= (major & 0xff) << 8; ++ dev |= minor & 0xff; ++ dev |= (minor & 0xffff00) << 8; ++ dev ++ } + } + + extern "C" { +@@ -1509,6 +1794,8 @@ extern "C" { + servlen: ::size_t, + flags: ::c_int, + ) -> ::c_int; ++ pub fn getresgid(rgid: *mut ::gid_t, egid: *mut ::gid_t, sgid: *mut ::gid_t) -> ::c_int; ++ pub fn getresuid(ruid: *mut ::uid_t, euid: *mut ::uid_t, suid: *mut ::uid_t) -> ::c_int; + pub fn kevent( + kq: ::c_int, + changelist: *const ::kevent, +@@ -1518,6 +1805,7 @@ extern "C" { + timeout: *const ::timespec, + ) -> ::c_int; + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; ++ pub fn getthrid() -> ::pid_t; + pub fn pthread_attr_getguardsize( + attr: *const ::pthread_attr_t, + guardsize: *mut ::size_t, +@@ -1528,8 +1816,24 @@ extern "C" { + stacksize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_main_np() -> ::c_int; ++ pub fn pthread_get_name_np(tid: ::pthread_t, name: *mut ::c_char, len: ::size_t); + pub fn pthread_set_name_np(tid: ::pthread_t, name: *const ::c_char); + pub fn pthread_stackseg_np(thread: ::pthread_t, sinfo: *mut ::stack_t) -> ::c_int; ++ ++ pub fn openpty( ++ amaster: *mut ::c_int, ++ aslave: *mut ::c_int, ++ name: *mut ::c_char, ++ termp: *const ::termios, ++ winp: *const ::winsize, ++ ) -> ::c_int; ++ pub fn forkpty( ++ amaster: *mut ::c_int, ++ name: *mut ::c_char, ++ termp: *const ::termios, ++ winp: *const ::winsize, ++ ) -> ::pid_t; ++ + pub fn sysctl( + name: *const ::c_int, + namelen: ::c_uint, +@@ -1538,10 +1842,10 @@ extern "C" { + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; +- pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; + pub fn setresgid(rgid: ::gid_t, egid: ::gid_t, sgid: ::gid_t) -> ::c_int; + pub fn setresuid(ruid: ::uid_t, euid: ::uid_t, suid: ::uid_t) -> ::c_int; + pub fn ptrace(request: ::c_int, pid: ::pid_t, addr: caddr_t, data: ::c_int) -> ::c_int; ++ pub fn utrace(label: *const ::c_char, addr: *const ::c_void, len: ::size_t) -> ::c_int; + pub fn memmem( + haystack: *const ::c_void, + haystacklen: ::size_t, +@@ -1568,6 +1872,59 @@ extern "C" { + pub fn explicit_bzero(s: *mut ::c_void, len: ::size_t); + + pub fn setproctitle(fmt: *const ::c_char, ...); ++ ++ pub fn freezero(ptr: *mut ::c_void, size: ::size_t); ++ pub fn malloc_conceal(size: ::size_t) -> *mut ::c_void; ++ pub fn calloc_conceal(nmemb: ::size_t, size: ::size_t) -> *mut ::c_void; ++ ++ pub fn srand48_deterministic(seed: ::c_long); ++ pub fn seed48_deterministic(xseed: *mut ::c_ushort) -> *mut ::c_ushort; ++ pub fn lcong48_deterministic(p: *mut ::c_ushort); ++ ++ pub fn lsearch( ++ key: *const ::c_void, ++ base: *mut ::c_void, ++ nelp: *mut ::size_t, ++ width: ::size_t, ++ compar: ::Option ::c_int>, ++ ) -> *mut ::c_void; ++ pub fn lfind( ++ key: *const ::c_void, ++ base: *const ::c_void, ++ nelp: *mut ::size_t, ++ width: ::size_t, ++ compar: ::Option ::c_int>, ++ ) -> *mut ::c_void; ++ pub fn hcreate(nelt: ::size_t) -> ::c_int; ++ pub fn hdestroy(); ++ pub fn hsearch(entry: ::ENTRY, action: ::ACTION) -> *mut ::ENTRY; ++ ++ // futex.h ++ pub fn futex( ++ uaddr: *mut u32, ++ op: ::c_int, ++ val: ::c_int, ++ timeout: *const ::timespec, ++ uaddr2: *mut u32, ++ ) -> ::c_int; ++ ++ pub fn mimmutable(addr: *mut ::c_void, len: ::size_t) -> ::c_int; ++} ++ ++#[link(name = "execinfo")] ++extern "C" { ++ pub fn backtrace(addrlist: *mut *mut ::c_void, len: ::size_t) -> ::size_t; ++ pub fn backtrace_symbols(addrlist: *const *mut ::c_void, len: ::size_t) -> *mut *mut ::c_char; ++ pub fn backtrace_symbols_fd( ++ addrlist: *const *mut ::c_void, ++ len: ::size_t, ++ fd: ::c_int, ++ ) -> ::c_int; ++ pub fn backtrace_symbols_fmt( ++ addrlist: *const *mut ::c_void, ++ len: ::size_t, ++ fmt: *const ::c_char, ++ ) -> *mut *mut ::c_char; + } + + cfg_if! { +@@ -1576,23 +1933,40 @@ cfg_if! { + // these functions use statfs which uses the union mount_info: + pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int; + pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int; ++ pub fn getmntinfo(mntbufp: *mut *mut ::statfs, flags: ::c_int) -> ::c_int; ++ pub fn getfsstat(buf: *mut statfs, bufsize: ::size_t, flags: ::c_int) -> ::c_int; + } + } + } + + cfg_if! { +- if #[cfg(target_arch = "x86")] { +- mod x86; +- pub use self::x86::*; +- } else if #[cfg(target_arch = "x86_64")] { +- mod x86_64; +- pub use self::x86_64::*; +- } else if #[cfg(target_arch = "aarch64")] { ++ if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; ++ } else if #[cfg(target_arch = "arm")] { ++ mod arm; ++ pub use self::arm::*; ++ } else if #[cfg(target_arch = "mips64")] { ++ mod mips64; ++ pub use self::mips64::*; ++ } else if #[cfg(target_arch = "powerpc")] { ++ mod powerpc; ++ pub use self::powerpc::*; ++ } else if #[cfg(target_arch = "powerpc64")] { ++ mod powerpc64; ++ pub use self::powerpc64::*; ++ } else if #[cfg(target_arch = "riscv64")] { ++ mod riscv64; ++ pub use self::riscv64::*; + } else if #[cfg(target_arch = "sparc64")] { + mod sparc64; + pub use self::sparc64::*; ++ } else if #[cfg(target_arch = "x86")] { ++ mod x86; ++ pub use self::x86::*; ++ } else if #[cfg(target_arch = "x86_64")] { ++ mod x86_64; ++ pub use self::x86_64::*; + } else { + // Unknown target_arch + } +diff --git a/vendor/libc/src/unix/bsd/netbsdlike/openbsd/powerpc.rs b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/powerpc.rs +new file mode 100644 +index 0000000..f1ab365 +--- /dev/null ++++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/powerpc.rs +@@ -0,0 +1,16 @@ ++pub type c_long = i32; ++pub type c_ulong = u32; ++pub type c_char = u8; ++ ++// should be pub(crate), but that requires Rust 1.18.0 ++cfg_if! { ++ if #[cfg(libc_const_size_of)] { ++ #[doc(hidden)] ++ pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_double>() - 1; ++ } else { ++ #[doc(hidden)] ++ pub const _ALIGNBYTES: usize = 8 - 1; ++ } ++} ++ ++pub const _MAX_PAGE_SHIFT: u32 = 12; +diff --git a/vendor/libc/src/unix/bsd/netbsdlike/openbsd/powerpc64.rs b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/powerpc64.rs +new file mode 100644 +index 0000000..99350ec +--- /dev/null ++++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/powerpc64.rs +@@ -0,0 +1,16 @@ ++pub type c_long = i64; ++pub type c_ulong = u64; ++pub type c_char = u8; ++ ++// should be pub(crate), but that requires Rust 1.18.0 ++cfg_if! { ++ if #[cfg(libc_const_size_of)] { ++ #[doc(hidden)] ++ pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; ++ } else { ++ #[doc(hidden)] ++ pub const _ALIGNBYTES: usize = 8 - 1; ++ } ++} ++ ++pub const _MAX_PAGE_SHIFT: u32 = 12; +diff --git a/vendor/libc/src/unix/bsd/netbsdlike/openbsd/riscv64.rs b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/riscv64.rs +new file mode 100644 +index 0000000..99350ec +--- /dev/null ++++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/riscv64.rs +@@ -0,0 +1,16 @@ ++pub type c_long = i64; ++pub type c_ulong = u64; ++pub type c_char = u8; ++ ++// should be pub(crate), but that requires Rust 1.18.0 ++cfg_if! { ++ if #[cfg(libc_const_size_of)] { ++ #[doc(hidden)] ++ pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; ++ } else { ++ #[doc(hidden)] ++ pub const _ALIGNBYTES: usize = 8 - 1; ++ } ++} ++ ++pub const _MAX_PAGE_SHIFT: u32 = 12; +diff --git a/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86_64.rs b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86_64.rs +index 263b6e1..60dab00 100644 +--- a/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86_64.rs ++++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86_64.rs +@@ -3,6 +3,112 @@ use PT_FIRSTMACH; + pub type c_long = i64; + pub type c_ulong = u64; + pub type c_char = i8; ++pub type ucontext_t = sigcontext; ++ ++s! { ++ pub struct sigcontext { ++ pub sc_rdi: ::c_long, ++ pub sc_rsi: ::c_long, ++ pub sc_rdx: ::c_long, ++ pub sc_rcx: ::c_long, ++ pub sc_r8: ::c_long, ++ pub sc_r9: ::c_long, ++ pub sc_r10: ::c_long, ++ pub sc_r11: ::c_long, ++ pub sc_r12: ::c_long, ++ pub sc_r13: ::c_long, ++ pub sc_r14: ::c_long, ++ pub sc_r15: ::c_long, ++ pub sc_rbp: ::c_long, ++ pub sc_rbx: ::c_long, ++ pub sc_rax: ::c_long, ++ pub sc_gs: ::c_long, ++ pub sc_fs: ::c_long, ++ pub sc_es: ::c_long, ++ pub sc_ds: ::c_long, ++ pub sc_trapno: ::c_long, ++ pub sc_err: ::c_long, ++ pub sc_rip: ::c_long, ++ pub sc_cs: ::c_long, ++ pub sc_rflags: ::c_long, ++ pub sc_rsp: ::c_long, ++ pub sc_ss: ::c_long, ++ pub sc_fpstate: *mut fxsave64, ++ __sc_unused: ::c_int, ++ pub sc_mask: ::c_int, ++ pub sc_cookie: ::c_long, ++ } ++} ++ ++s_no_extra_traits! { ++ #[repr(packed)] ++ pub struct fxsave64 { ++ pub fx_fcw: u16, ++ pub fx_fsw: u16, ++ pub fx_ftw: u8, ++ __fx_unused1: u8, ++ pub fx_fop: u16, ++ pub fx_rip: u64, ++ pub fx_rdp: u64, ++ pub fx_mxcsr: u32, ++ pub fx_mxcsr_mask: u32, ++ pub fx_st: [[u64; 2]; 8], ++ pub fx_xmm: [[u64; 2]; 16], ++ __fx_unused3: [u8; 96], ++ } ++} ++ ++cfg_if! { ++ if #[cfg(feature = "extra_traits")] { ++ // `fxsave64` is packed, so field access is unaligned. ++ // use {x} to create temporary storage, copy field to it, and do aligned access. ++ impl PartialEq for fxsave64 { ++ fn eq(&self, other: &fxsave64) -> bool { ++ return {self.fx_fcw} == {other.fx_fcw} && ++ {self.fx_fsw} == {other.fx_fsw} && ++ {self.fx_ftw} == {other.fx_ftw} && ++ {self.fx_fop} == {other.fx_fop} && ++ {self.fx_rip} == {other.fx_rip} && ++ {self.fx_rdp} == {other.fx_rdp} && ++ {self.fx_mxcsr} == {other.fx_mxcsr} && ++ {self.fx_mxcsr_mask} == {other.fx_mxcsr_mask} && ++ {self.fx_st}.iter().zip({other.fx_st}.iter()).all(|(a,b)| a == b) && ++ {self.fx_xmm}.iter().zip({other.fx_xmm}.iter()).all(|(a,b)| a == b) ++ } ++ } ++ impl Eq for fxsave64 {} ++ impl ::fmt::Debug for fxsave64 { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("fxsave64") ++ .field("fx_fcw", &{self.fx_fcw}) ++ .field("fx_fsw", &{self.fx_fsw}) ++ .field("fx_ftw", &{self.fx_ftw}) ++ .field("fx_fop", &{self.fx_fop}) ++ .field("fx_rip", &{self.fx_rip}) ++ .field("fx_rdp", &{self.fx_rdp}) ++ .field("fx_mxcsr", &{self.fx_mxcsr}) ++ .field("fx_mxcsr_mask", &{self.fx_mxcsr_mask}) ++ // FIXME: .field("fx_st", &{self.fx_st}) ++ // FIXME: .field("fx_xmm", &{self.fx_xmm}) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for fxsave64 { ++ fn hash(&self, state: &mut H) { ++ {self.fx_fcw}.hash(state); ++ {self.fx_fsw}.hash(state); ++ {self.fx_ftw}.hash(state); ++ {self.fx_fop}.hash(state); ++ {self.fx_rip}.hash(state); ++ {self.fx_rdp}.hash(state); ++ {self.fx_mxcsr}.hash(state); ++ {self.fx_mxcsr_mask}.hash(state); ++ {self.fx_st}.hash(state); ++ {self.fx_xmm}.hash(state); ++ } ++ } ++ } ++} + + // should be pub(crate), but that requires Rust 1.18.0 + cfg_if! { +diff --git a/vendor/libc/src/unix/haiku/b32.rs b/vendor/libc/src/unix/haiku/b32.rs +index cce8864..073ae9d 100644 +--- a/vendor/libc/src/unix/haiku/b32.rs ++++ b/vendor/libc/src/unix/haiku/b32.rs +@@ -1,3 +1,20 @@ + pub type c_long = i32; + pub type c_ulong = u32; + pub type time_t = i32; ++ ++pub type Elf_Addr = ::Elf32_Addr; ++pub type Elf_Half = ::Elf32_Half; ++pub type Elf_Phdr = ::Elf32_Phdr; ++ ++s! { ++ pub struct Elf32_Phdr { ++ pub p_type: ::Elf32_Word, ++ pub p_offset: ::Elf32_Off, ++ pub p_vaddr: ::Elf32_Addr, ++ pub p_paddr: ::Elf32_Addr, ++ pub p_filesz: ::Elf32_Word, ++ pub p_memsz: ::Elf32_Word, ++ pub p_flags: ::Elf32_Word, ++ pub p_align: ::Elf32_Word, ++ } ++} +diff --git a/vendor/libc/src/unix/haiku/b64.rs b/vendor/libc/src/unix/haiku/b64.rs +index 3e66f14..4569180 100644 +--- a/vendor/libc/src/unix/haiku/b64.rs ++++ b/vendor/libc/src/unix/haiku/b64.rs +@@ -1,3 +1,20 @@ + pub type c_ulong = u64; + pub type c_long = i64; + pub type time_t = i64; ++ ++pub type Elf_Addr = ::Elf64_Addr; ++pub type Elf_Half = ::Elf64_Half; ++pub type Elf_Phdr = ::Elf64_Phdr; ++ ++s! { ++ pub struct Elf64_Phdr { ++ pub p_type: ::Elf64_Word, ++ pub p_flags: ::Elf64_Word, ++ pub p_offset: ::Elf64_Off, ++ pub p_vaddr: ::Elf64_Addr, ++ pub p_paddr: ::Elf64_Addr, ++ pub p_filesz: ::Elf64_Xword, ++ pub p_memsz: ::Elf64_Xword, ++ pub p_align: ::Elf64_Xword, ++ } ++} +diff --git a/vendor/libc/src/unix/haiku/mod.rs b/vendor/libc/src/unix/haiku/mod.rs +index d88baec..2fa3327 100644 +--- a/vendor/libc/src/unix/haiku/mod.rs ++++ b/vendor/libc/src/unix/haiku/mod.rs +@@ -28,8 +28,34 @@ pub type fsfilcnt_t = i64; + pub type pthread_attr_t = *mut ::c_void; + pub type nl_item = ::c_int; + pub type id_t = i32; +-pub type idtype_t = ::c_uint; ++pub type idtype_t = ::c_int; + pub type fd_mask = u32; ++pub type regoff_t = ::c_int; ++pub type key_t = i32; ++pub type msgqnum_t = u32; ++pub type msglen_t = u32; ++ ++pub type Elf32_Addr = u32; ++pub type Elf32_Half = u16; ++pub type Elf32_Off = u32; ++pub type Elf32_Sword = i32; ++pub type Elf32_Word = u32; ++ ++pub type Elf64_Addr = u64; ++pub type Elf64_Half = u16; ++pub type Elf64_Off = u64; ++pub type Elf64_Sword = i32; ++pub type Elf64_Sxword = i64; ++pub type Elf64_Word = u32; ++pub type Elf64_Xword = u64; ++ ++pub type ENTRY = entry; ++pub type ACTION = ::c_int; ++ ++pub type posix_spawnattr_t = *mut ::c_void; ++pub type posix_spawn_file_actions_t = *mut ::c_void; ++ ++pub type StringList = _stringlist; + + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub enum timezone {} +@@ -102,6 +128,16 @@ s! { + pub ai_next: *mut addrinfo, + } + ++ pub struct ifaddrs { ++ pub ifa_next: *mut ifaddrs, ++ pub ifa_name: *const ::c_char, ++ pub ifa_flags: ::c_uint, ++ pub ifa_addr: *mut ::sockaddr, ++ pub ifa_netmask: *mut ::sockaddr, ++ pub ifa_dstaddr: *mut ::sockaddr, ++ pub ifa_data: *mut ::c_void, ++ } ++ + pub struct fd_set { + // size for 1024 bits, and a fd_mask with size u32 + fds_bits: [fd_mask; 32], +@@ -261,6 +297,10 @@ s! { + waiters: [*mut ::c_void; 2], + } + ++ pub struct pthread_spinlock_t { ++ lock: u32, ++ } ++ + pub struct passwd { + pub pw_name: *mut ::c_char, + pub pw_passwd: *mut ::c_char, +@@ -315,6 +355,103 @@ s! { + pub named_sem_id: i32, // actually a union with unnamed_sem (i32) + pub padding: [i32; 2], + } ++ ++ pub struct ucred { ++ pub pid: ::pid_t, ++ pub uid: ::uid_t, ++ pub gid: ::gid_t, ++ } ++ ++ pub struct sockaddr_dl { ++ pub sdl_len: u8, ++ pub sdl_family: u8, ++ pub sdl_e_type: u16, ++ pub sdl_index: u32, ++ pub sdl_type: u8, ++ pub sdl_nlen: u8, ++ pub sdl_alen: u8, ++ pub sdl_slen: u8, ++ pub sdl_data: [u8; 46], ++ } ++ ++ pub struct spwd { ++ pub sp_namp: *mut ::c_char, ++ pub sp_pwdp: *mut ::c_char, ++ pub sp_lstchg: ::c_int, ++ pub sp_min: ::c_int, ++ pub sp_max: ::c_int, ++ pub sp_warn: ::c_int, ++ pub sp_inact: ::c_int, ++ pub sp_expire: ::c_int, ++ pub sp_flag: ::c_int, ++ } ++ ++ pub struct regex_t { ++ __buffer: *mut ::c_void, ++ __allocated: ::size_t, ++ __used: ::size_t, ++ __syntax: ::c_ulong, ++ __fastmap: *mut ::c_char, ++ __translate: *mut ::c_char, ++ __re_nsub: ::size_t, ++ __bitfield: u8, ++ } ++ ++ pub struct regmatch_t { ++ pub rm_so: regoff_t, ++ pub rm_eo: regoff_t, ++ } ++ ++ pub struct msqid_ds { ++ pub msg_perm: ::ipc_perm, ++ pub msg_qnum: ::msgqnum_t, ++ pub msg_qbytes: ::msglen_t, ++ pub msg_lspid: ::pid_t, ++ pub msg_lrpid: ::pid_t, ++ pub msg_stime: ::time_t, ++ pub msg_rtime: ::time_t, ++ pub msg_ctime: ::time_t, ++ } ++ ++ pub struct ipc_perm { ++ pub key: ::key_t, ++ pub uid: ::uid_t, ++ pub gid: ::gid_t, ++ pub cuid: ::uid_t, ++ pub cgid: ::gid_t, ++ pub mode: ::mode_t, ++ } ++ ++ pub struct sembuf { ++ pub sem_num: ::c_ushort, ++ pub sem_op: ::c_short, ++ pub sem_flg: ::c_short, ++ } ++ ++ pub struct entry { ++ pub key: *mut ::c_char, ++ pub data: *mut ::c_void, ++ } ++ ++ pub struct option { ++ pub name: *const ::c_char, ++ pub has_arg: ::c_int, ++ pub flag: *mut ::c_int, ++ pub val: ::c_int, ++ } ++ ++ pub struct _stringlist { ++ pub sl_str: *mut *mut ::c_char, ++ pub sl_max: ::size_t, ++ pub sl_cur: ::size_t, ++ } ++ ++ pub struct dl_phdr_info { ++ pub dlpi_addr: ::Elf_Addr, ++ pub dlpi_name: *const ::c_char, ++ pub dlpi_phdr: *const ::Elf_Phdr, ++ pub dlpi_phnum: ::Elf_Half, ++ } + } + + s_no_extra_traits! { +@@ -346,10 +483,63 @@ s_no_extra_traits! { + __unused1: *mut ::c_void, // actually a function pointer + pub sigev_notify_attributes: *mut ::pthread_attr_t, + } ++ ++ pub struct utmpx { ++ pub ut_type: ::c_short, ++ pub ut_tv: ::timeval, ++ pub ut_id: [::c_char; 8], ++ pub ut_pid: ::pid_t, ++ pub ut_user: [::c_char; 32], ++ pub ut_line: [::c_char; 16], ++ pub ut_host: [::c_char; 128], ++ __ut_reserved: [::c_char; 64], ++ } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { ++ impl PartialEq for utmpx { ++ fn eq(&self, other: &utmpx) -> bool { ++ self.ut_type == other.ut_type ++ && self.ut_tv == other.ut_tv ++ && self.ut_id == other.ut_id ++ && self.ut_pid == other.ut_pid ++ && self.ut_user == other.ut_user ++ && self.ut_line == other.ut_line ++ && self.ut_host.iter().zip(other.ut_host.iter()).all(|(a,b)| a == b) ++ && self.__ut_reserved == other.__ut_reserved ++ } ++ } ++ ++ impl Eq for utmpx {} ++ ++ impl ::fmt::Debug for utmpx { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("utmpx") ++ .field("ut_type", &self.ut_type) ++ .field("ut_tv", &self.ut_tv) ++ .field("ut_id", &self.ut_id) ++ .field("ut_pid", &self.ut_pid) ++ .field("ut_user", &self.ut_user) ++ .field("ut_line", &self.ut_line) ++ .field("ut_host", &self.ut_host) ++ .field("__ut_reserved", &self.__ut_reserved) ++ .finish() ++ } ++ } ++ ++ impl ::hash::Hash for utmpx { ++ fn hash(&self, state: &mut H) { ++ self.ut_type.hash(state); ++ self.ut_tv.hash(state); ++ self.ut_id.hash(state); ++ self.ut_pid.hash(state); ++ self.ut_user.hash(state); ++ self.ut_line.hash(state); ++ self.ut_host.hash(state); ++ self.__ut_reserved.hash(state); ++ } ++ } + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_len == other.sun_len +@@ -495,6 +685,9 @@ pub const EOF: ::c_int = -1; + pub const SEEK_SET: ::c_int = 0; + pub const SEEK_CUR: ::c_int = 1; + pub const SEEK_END: ::c_int = 2; ++pub const L_SET: ::c_int = SEEK_SET; ++pub const L_INCR: ::c_int = SEEK_CUR; ++pub const L_XTND: ::c_int = SEEK_END; + pub const _IOFBF: ::c_int = 0; + pub const _IONBF: ::c_int = 2; + pub const _IOLBF: ::c_int = 1; +@@ -535,6 +728,8 @@ pub const PTHREAD_CREATE_DETACHED: ::c_int = 1; + + pub const CLOCK_REALTIME: ::c_int = -1; + pub const CLOCK_MONOTONIC: ::c_int = 0; ++pub const CLOCK_PROCESS_CPUTIME_ID: ::c_int = -2; ++pub const CLOCK_THREAD_CPUTIME_ID: ::c_int = -3; + + pub const RLIMIT_CORE: ::c_int = 0; + pub const RLIMIT_CPU: ::c_int = 1; +@@ -543,6 +738,7 @@ pub const RLIMIT_FSIZE: ::c_int = 3; + pub const RLIMIT_NOFILE: ::c_int = 4; + pub const RLIMIT_STACK: ::c_int = 5; + pub const RLIMIT_AS: ::c_int = 6; ++pub const RLIM_INFINITY: ::rlim_t = 0xffffffff; + // Haiku specific + pub const RLIMIT_NOVMON: ::c_int = 7; + pub const RLIM_NLIMITS: ::c_int = 8; +@@ -674,6 +870,7 @@ pub const MAP_SHARED: ::c_int = 0x01; + pub const MAP_PRIVATE: ::c_int = 0x02; + pub const MAP_FIXED: ::c_int = 0x04; + pub const MAP_ANONYMOUS: ::c_int = 0x08; ++pub const MAP_NORESERVE: ::c_int = 0x10; + pub const MAP_ANON: ::c_int = MAP_ANONYMOUS; + + pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; +@@ -780,6 +977,7 @@ pub const MADV_SEQUENTIAL: ::c_int = 2; + pub const MADV_RANDOM: ::c_int = 3; + pub const MADV_WILLNEED: ::c_int = 4; + pub const MADV_DONTNEED: ::c_int = 5; ++pub const MADV_FREE: ::c_int = 6; + + // https://github.com/haiku/haiku/blob/master/headers/posix/net/if.h#L80 + pub const IFF_UP: ::c_int = 0x0001; +@@ -809,6 +1007,15 @@ pub const AF_LOCAL: ::c_int = 9; + pub const AF_UNIX: ::c_int = AF_LOCAL; + pub const AF_BLUETOOTH: ::c_int = 10; + ++pub const PF_UNSPEC: ::c_int = AF_UNSPEC; ++pub const PF_INET: ::c_int = AF_INET; ++pub const PF_ROUTE: ::c_int = AF_ROUTE; ++pub const PF_LINK: ::c_int = AF_LINK; ++pub const PF_INET6: ::c_int = AF_INET6; ++pub const PF_LOCAL: ::c_int = AF_LOCAL; ++pub const PF_UNIX: ::c_int = AF_UNIX; ++pub const PF_BLUETOOTH: ::c_int = AF_BLUETOOTH; ++ + pub const IP_OPTIONS: ::c_int = 1; + pub const IP_HDRINCL: ::c_int = 2; + pub const IP_TOS: ::c_int = 3; +@@ -872,6 +1079,7 @@ pub const LOCK_EX: ::c_int = 0x02; + pub const LOCK_NB: ::c_int = 0x04; + pub const LOCK_UN: ::c_int = 0x08; + ++pub const MINSIGSTKSZ: ::size_t = 8192; + pub const SIGSTKSZ: ::size_t = 16384; + + pub const IOV_MAX: ::c_int = 1024; +@@ -888,6 +1096,9 @@ pub const SA_NOMASK: ::c_int = SA_NODEFER; + pub const SA_STACK: ::c_int = SA_ONSTACK; + pub const SA_ONESHOT: ::c_int = SA_RESETHAND; + ++pub const SS_ONSTACK: ::c_int = 0x1; ++pub const SS_DISABLE: ::c_int = 0x2; ++ + pub const FD_SETSIZE: usize = 1024; + + pub const RTLD_LOCAL: ::c_int = 0x0; +@@ -979,6 +1190,7 @@ pub const _SC_HOST_NAME_MAX: ::c_int = 61; + pub const _SC_REGEXP: ::c_int = 62; + pub const _SC_SYMLOOP_MAX: ::c_int = 63; + pub const _SC_SHELL: ::c_int = 64; ++pub const _SC_TTY_NAME_MAX: ::c_int = 65; + + pub const PTHREAD_STACK_MIN: ::size_t = 8192; + +@@ -1045,6 +1257,8 @@ pub const SO_PEERCRED: ::c_int = 0x4000000b; + + pub const SCM_RIGHTS: ::c_int = 0x01; + ++pub const SOMAXCONN: ::c_int = 32; ++ + pub const NI_MAXHOST: ::size_t = 1025; + + pub const WNOHANG: ::c_int = 0x01; +@@ -1054,6 +1268,12 @@ pub const WEXITED: ::c_int = 0x08; + pub const WSTOPPED: ::c_int = 0x10; + pub const WNOWAIT: ::c_int = 0x20; + ++// si_code values for SIGBUS signal ++pub const BUS_ADRALN: ::c_int = 40; ++pub const BUS_ADRERR: ::c_int = 41; ++pub const BUS_OBJERR: ::c_int = 42; ++ ++// si_code values for SIGCHLD signal + pub const CLD_EXITED: ::c_int = 60; + pub const CLD_KILLED: ::c_int = 61; + pub const CLD_DUMPED: ::c_int = 62; +@@ -1234,6 +1454,16 @@ pub const PRIO_PROCESS: ::c_int = 0; + pub const PRIO_PGRP: ::c_int = 1; + pub const PRIO_USER: ::c_int = 2; + ++// utmpx entry types ++pub const EMPTY: ::c_short = 0; ++pub const BOOT_TIME: ::c_short = 1; ++pub const OLD_TIME: ::c_short = 2; ++pub const NEW_TIME: ::c_short = 3; ++pub const USER_PROCESS: ::c_short = 4; ++pub const INIT_PROCESS: ::c_short = 5; ++pub const LOGIN_PROCESS: ::c_short = 6; ++pub const DEAD_PROCESS: ::c_short = 7; ++ + pub const LOG_PID: ::c_int = 1 << 12; + pub const LOG_CONS: ::c_int = 2 << 12; + pub const LOG_ODELAY: ::c_int = 4 << 12; +@@ -1242,6 +1472,13 @@ pub const LOG_SERIAL: ::c_int = 16 << 12; + pub const LOG_PERROR: ::c_int = 32 << 12; + pub const LOG_NOWAIT: ::c_int = 64 << 12; + ++// spawn.h ++pub const POSIX_SPAWN_RESETIDS: ::c_int = 0x01; ++pub const POSIX_SPAWN_SETPGROUP: ::c_int = 0x02; ++pub const POSIX_SPAWN_SETSIGDEF: ::c_int = 0x10; ++pub const POSIX_SPAWN_SETSIGMASK: ::c_int = 0x20; ++pub const POSIX_SPAWN_SETSID: ::c_int = 0x40; ++ + const_fn! { + {const} fn CMSG_ALIGN(len: usize) -> usize { + len + ::mem::size_of::() - 1 & !(::mem::size_of::() - 1) +@@ -1295,7 +1532,7 @@ f! { + return + } + +- pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool { ++ pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0 +@@ -1356,6 +1593,12 @@ extern "C" { + pub fn getpriority(which: ::c_int, who: id_t) -> ::c_int; + pub fn setpriority(which: ::c_int, who: id_t, priority: ::c_int) -> ::c_int; + ++ pub fn endusershell(); ++ pub fn getpass(prompt: *const ::c_char) -> *mut ::c_char; ++ pub fn getusershell() -> *mut ::c_char; ++ pub fn issetugid() -> ::c_int; ++ pub fn setusershell(); ++ + pub fn utimensat( + fd: ::c_int, + path: *const ::c_char, +@@ -1367,19 +1610,65 @@ extern "C" { + pub fn _errnop() -> *mut ::c_int; + + pub fn abs(i: ::c_int) -> ::c_int; +- pub fn atof(s: *const ::c_char) -> ::c_double; + pub fn labs(i: ::c_long) -> ::c_long; + pub fn rand() -> ::c_int; + pub fn srand(seed: ::c_uint); +-} ++ pub fn getifaddrs(ifap: *mut *mut ::ifaddrs) -> ::c_int; ++ pub fn freeifaddrs(ifa: *mut ::ifaddrs); ++ pub fn ppoll( ++ fds: *mut ::pollfd, ++ numfds: ::nfds_t, ++ timeout: *const ::timespec, ++ sigMask: *const sigset_t, ++ ) -> ::c_int; + +-#[link(name = "bsd")] +-extern "C" { ++ pub fn getspent() -> *mut spwd; ++ pub fn getspent_r( ++ pwd: *mut spwd, ++ buf: *mut ::c_char, ++ bufferSize: ::size_t, ++ res: *mut *mut spwd, ++ ) -> ::c_int; ++ pub fn setspent(); ++ pub fn endspent(); ++ pub fn getspnam(name: *const ::c_char) -> *mut spwd; ++ pub fn getspnam_r( ++ name: *const ::c_char, ++ spwd: *mut spwd, ++ buffer: *mut ::c_char, ++ bufferSize: ::size_t, ++ res: *mut *mut spwd, ++ ) -> ::c_int; ++ pub fn sgetspent(line: *const ::c_char) -> *mut spwd; ++ pub fn sgetspent_r( ++ line: *const ::c_char, ++ spwd: *mut spwd, ++ buffer: *mut ::c_char, ++ bufferSize: ::size_t, ++ res: *mut *mut spwd, ++ ) -> ::c_int; ++ pub fn fgetspent(file: *mut ::FILE) -> *mut spwd; ++ pub fn fgetspent_r( ++ file: *mut ::FILE, ++ spwd: *mut spwd, ++ buffer: *mut ::c_char, ++ bufferSize: ::size_t, ++ res: *mut *mut spwd, ++ ) -> ::c_int; ++ pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; ++ pub fn mknodat( ++ dirfd: ::c_int, ++ pathname: *const ::c_char, ++ mode: ::mode_t, ++ dev: dev_t, ++ ) -> ::c_int; + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + +- pub fn clock_gettime(clk_id: ::c_int, tp: *mut ::timespec) -> ::c_int; +- pub fn clock_settime(clk_id: ::c_int, tp: *const ::timespec) -> ::c_int; ++ pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; ++ pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; ++ pub fn clock_settime(clk_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; ++ pub fn clock_getcpuclockid(pid: ::pid_t, clk_id: *mut ::clockid_t) -> ::c_int; + pub fn pthread_create( + thread: *mut ::pthread_t, + attr: *const ::pthread_attr_t, +@@ -1403,8 +1692,11 @@ extern "C" { + attr: *mut pthread_condattr_t, + clock_id: ::clockid_t, + ) -> ::c_int; ++ pub fn valloc(numBytes: ::size_t) -> *mut ::c_void; ++ pub fn malloc_usable_size(ptr: *mut ::c_void) -> ::size_t; + pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; + pub fn setgroups(ngroups: ::c_int, ptr: *const ::gid_t) -> ::c_int; ++ pub fn initgroups(name: *const ::c_char, basegid: ::gid_t) -> ::c_int; + pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; +@@ -1421,6 +1713,11 @@ extern "C" { + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; ++ pub fn pthread_spin_init(lock: *mut ::pthread_spinlock_t, pshared: ::c_int) -> ::c_int; ++ pub fn pthread_spin_destroy(lock: *mut ::pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_lock(lock: *mut ::pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_trylock(lock: *mut ::pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_unlock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t, options: ::c_int) + -> ::c_int; + +@@ -1433,6 +1730,8 @@ extern "C" { + pub fn globfree(pglob: *mut ::glob_t); + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; ++ pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, advice: ::c_int) -> ::c_int; ++ pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + + pub fn shm_open(name: *const ::c_char, oflag: ::c_int, mode: ::mode_t) -> ::c_int; + pub fn shm_unlink(name: *const ::c_char) -> ::c_int; +@@ -1453,7 +1752,6 @@ extern "C" { + addrlen: *mut ::socklen_t, + ) -> ::ssize_t; + pub fn mkstemps(template: *mut ::c_char, suffixlen: ::c_int) -> ::c_int; +- pub fn lutimes(file: *const ::c_char, times: *const ::timeval) -> ::c_int; + pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; + + pub fn bind(socket: ::c_int, address: *const ::sockaddr, address_len: ::socklen_t) -> ::c_int; +@@ -1475,6 +1773,12 @@ extern "C" { + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; ++ pub fn getgrouplist( ++ user: *const ::c_char, ++ basegroup: ::gid_t, ++ grouplist: *mut ::gid_t, ++ groupcount: *mut ::c_int, ++ ) -> ::c_int; + pub fn sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> ::c_int; + pub fn sem_close(sem: *mut sem_t) -> ::c_int; + pub fn getdtablesize() -> ::c_int; +@@ -1490,7 +1794,6 @@ extern "C" { + pub fn getgrnam(name: *const ::c_char) -> *mut ::group; + pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; + pub fn sem_unlink(name: *const ::c_char) -> ::c_int; +- pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + pub fn getpwnam_r( + name: *const ::c_char, + pwd: *mut passwd, +@@ -1505,6 +1808,12 @@ extern "C" { + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; ++ pub fn getpwent() -> *mut passwd; ++ pub fn setpwent(); ++ pub fn endpwent(); ++ pub fn endgrent(); ++ pub fn getgrent() -> *mut ::group; ++ pub fn setgrent(); + pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; + pub fn pthread_atfork( + prepare: ::Option, +@@ -1513,21 +1822,247 @@ extern "C" { + ) -> ::c_int; + pub fn getgrgid(gid: ::gid_t) -> *mut ::group; + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; +- pub fn openpty( ++ pub fn sethostname(name: *const ::c_char, len: ::size_t) -> ::c_int; ++ pub fn uname(buf: *mut ::utsname) -> ::c_int; ++ pub fn getutxent() -> *mut utmpx; ++ pub fn getutxid(ut: *const utmpx) -> *mut utmpx; ++ pub fn getutxline(ut: *const utmpx) -> *mut utmpx; ++ pub fn pututxline(ut: *const utmpx) -> *mut utmpx; ++ pub fn setutxent(); ++ pub fn endutxent(); ++ pub fn faccessat( ++ dirfd: ::c_int, ++ pathname: *const ::c_char, ++ mode: ::c_int, ++ flags: ::c_int, ++ ) -> ::c_int; ++ ++ pub fn sigtimedwait( ++ set: *const sigset_t, ++ info: *mut siginfo_t, ++ timeout: *const ::timespec, ++ ) -> ::c_int; ++ pub fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> ::c_int; ++ ++ pub fn getitimer(which: ::c_int, curr_value: *mut ::itimerval) -> ::c_int; ++ pub fn setitimer( ++ which: ::c_int, ++ new_value: *const ::itimerval, ++ old_value: *mut ::itimerval, ++ ) -> ::c_int; ++ ++ pub fn regcomp(preg: *mut regex_t, pattern: *const ::c_char, cflags: ::c_int) -> ::c_int; ++ ++ pub fn regexec( ++ preg: *const regex_t, ++ input: *const ::c_char, ++ nmatch: ::size_t, ++ pmatch: *mut regmatch_t, ++ eflags: ::c_int, ++ ) -> ::c_int; ++ ++ pub fn regerror( ++ errcode: ::c_int, ++ preg: *const regex_t, ++ errbuf: *mut ::c_char, ++ errbuf_size: ::size_t, ++ ) -> ::size_t; ++ ++ pub fn regfree(preg: *mut regex_t); ++ ++ pub fn msgctl(msqid: ::c_int, cmd: ::c_int, buf: *mut msqid_ds) -> ::c_int; ++ pub fn msgget(key: ::key_t, msgflg: ::c_int) -> ::c_int; ++ pub fn msgrcv( ++ msqid: ::c_int, ++ msgp: *mut ::c_void, ++ msgsz: ::size_t, ++ msgtype: ::c_long, ++ msgflg: ::c_int, ++ ) -> ::ssize_t; ++ pub fn msgsnd( ++ msqid: ::c_int, ++ msgp: *const ::c_void, ++ msgsz: ::size_t, ++ msgflg: ::c_int, ++ ) -> ::c_int; ++ pub fn semget(key: ::key_t, nsems: ::c_int, semflg: ::c_int) -> ::c_int; ++ pub fn semctl(semid: ::c_int, semnum: ::c_int, cmd: ::c_int, ...) -> ::c_int; ++ pub fn semop(semid: ::c_int, sops: *mut sembuf, nsops: ::size_t) -> ::c_int; ++ pub fn ftok(pathname: *const ::c_char, proj_id: ::c_int) -> ::key_t; ++ ++ pub fn memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void; ++ ++ pub fn lsearch( ++ key: *const ::c_void, ++ base: *mut ::c_void, ++ nelp: *mut ::size_t, ++ width: ::size_t, ++ compar: ::Option ::c_int>, ++ ) -> *mut ::c_void; ++ pub fn lfind( ++ key: *const ::c_void, ++ base: *const ::c_void, ++ nelp: *mut ::size_t, ++ width: ::size_t, ++ compar: ::Option ::c_int>, ++ ) -> *mut ::c_void; ++ pub fn hcreate(nelt: ::size_t) -> ::c_int; ++ pub fn hdestroy(); ++ pub fn hsearch(entry: ::ENTRY, action: ::ACTION) -> *mut ::ENTRY; ++ ++ pub fn drand48() -> ::c_double; ++ pub fn erand48(xseed: *mut ::c_ushort) -> ::c_double; ++ pub fn lrand48() -> ::c_long; ++ pub fn nrand48(xseed: *mut ::c_ushort) -> ::c_long; ++ pub fn mrand48() -> ::c_long; ++ pub fn jrand48(xseed: *mut ::c_ushort) -> ::c_long; ++ pub fn srand48(seed: ::c_long); ++ pub fn seed48(xseed: *mut ::c_ushort) -> *mut ::c_ushort; ++ pub fn lcong48(p: *mut ::c_ushort); ++ ++ pub fn clearenv() -> ::c_int; ++ pub fn ctermid(s: *mut ::c_char) -> *mut ::c_char; ++ ++ pub fn sync(); ++ pub fn getpagesize() -> ::c_int; ++ ++ pub fn brk(addr: *mut ::c_void) -> ::c_int; ++ pub fn sbrk(increment: ::intptr_t) -> *mut ::c_void; ++ ++ pub fn posix_spawn( ++ pid: *mut ::pid_t, ++ path: *const ::c_char, ++ file_actions: *const ::posix_spawn_file_actions_t, ++ attrp: *const ::posix_spawnattr_t, ++ argv: *const *mut ::c_char, ++ envp: *const *mut ::c_char, ++ ) -> ::c_int; ++ pub fn posix_spawnp( ++ pid: *mut ::pid_t, ++ file: *const ::c_char, ++ file_actions: *const ::posix_spawn_file_actions_t, ++ attrp: *const ::posix_spawnattr_t, ++ argv: *const *mut ::c_char, ++ envp: *const *mut ::c_char, ++ ) -> ::c_int; ++ ++ pub fn posix_spawn_file_actions_init(file_actions: *mut posix_spawn_file_actions_t) -> ::c_int; ++ pub fn posix_spawn_file_actions_destroy( ++ file_actions: *mut posix_spawn_file_actions_t, ++ ) -> ::c_int; ++ pub fn posix_spawn_file_actions_addopen( ++ file_actions: *mut posix_spawn_file_actions_t, ++ fildes: ::c_int, ++ path: *const ::c_char, ++ oflag: ::c_int, ++ mode: ::mode_t, ++ ) -> ::c_int; ++ pub fn posix_spawn_file_actions_addclose( ++ file_actions: *mut posix_spawn_file_actions_t, ++ fildes: ::c_int, ++ ) -> ::c_int; ++ pub fn posix_spawn_file_actions_adddup2( ++ file_actions: *mut posix_spawn_file_actions_t, ++ fildes: ::c_int, ++ newfildes: ::c_int, ++ ) -> ::c_int; ++ ++ pub fn posix_spawnattr_init(attr: *mut posix_spawnattr_t) -> ::c_int; ++ pub fn posix_spawnattr_destroy(attr: *mut posix_spawnattr_t) -> ::c_int; ++ pub fn posix_spawnattr_getflags( ++ attr: *const posix_spawnattr_t, ++ _flags: *mut ::c_short, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setflags(attr: *mut posix_spawnattr_t, flags: ::c_short) -> ::c_int; ++ pub fn posix_spawnattr_getpgroup( ++ attr: *const posix_spawnattr_t, ++ _pgroup: *mut ::pid_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, pgroup: ::pid_t) -> ::c_int; ++ pub fn posix_spawnattr_getsigdefault( ++ attr: *const posix_spawnattr_t, ++ sigdefault: *mut ::sigset_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setsigdefault( ++ attr: *mut posix_spawnattr_t, ++ sigdefault: *const ::sigset_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_getsigmask( ++ attr: *const posix_spawnattr_t, ++ _sigmask: *mut ::sigset_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setsigmask( ++ attr: *mut posix_spawnattr_t, ++ sigmask: *const ::sigset_t, ++ ) -> ::c_int; ++ pub fn getopt_long( ++ argc: ::c_int, ++ argv: *const *mut c_char, ++ optstring: *const c_char, ++ longopts: *const option, ++ longindex: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn strcasecmp_l( ++ string1: *const ::c_char, ++ string2: *const ::c_char, ++ locale: ::locale_t, ++ ) -> ::c_int; ++ pub fn strncasecmp_l( ++ string1: *const ::c_char, ++ string2: *const ::c_char, ++ length: ::size_t, ++ locale: ::locale_t, ++ ) -> ::c_int; ++} ++ ++#[link(name = "bsd")] ++extern "C" { ++ pub fn lutimes(file: *const ::c_char, times: *const ::timeval) -> ::c_int; ++ pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; ++ pub fn forkpty( + amaster: *mut ::c_int, +- aslave: *mut ::c_int, + name: *mut ::c_char, + termp: *mut termios, + winp: *mut ::winsize, +- ) -> ::c_int; +- pub fn forkpty( ++ ) -> ::pid_t; ++ pub fn openpty( + amaster: *mut ::c_int, ++ aslave: *mut ::c_int, + name: *mut ::c_char, + termp: *mut termios, + winp: *mut ::winsize, +- ) -> ::pid_t; +- pub fn sethostname(name: *const ::c_char, len: ::size_t) -> ::c_int; +- pub fn uname(buf: *mut ::utsname) -> ::c_int; ++ ) -> ::c_int; ++ pub fn strsep(string: *mut *mut ::c_char, delimiters: *const ::c_char) -> *mut ::c_char; ++ pub fn explicit_bzero(buf: *mut ::c_void, len: ::size_t); ++ pub fn login_tty(_fd: ::c_int) -> ::c_int; ++ ++ pub fn sl_init() -> *mut StringList; ++ pub fn sl_add(sl: *mut StringList, n: *mut ::c_char) -> ::c_int; ++ pub fn sl_free(sl: *mut StringList, i: ::c_int); ++ pub fn sl_find(sl: *mut StringList, n: *mut ::c_char) -> *mut ::c_char; ++ ++ pub fn getprogname() -> *const ::c_char; ++ pub fn setprogname(progname: *const ::c_char); ++ pub fn dl_iterate_phdr( ++ callback: ::Option< ++ unsafe extern "C" fn( ++ info: *mut dl_phdr_info, ++ size: usize, ++ data: *mut ::c_void, ++ ) -> ::c_int, ++ >, ++ data: *mut ::c_void, ++ ) -> ::c_int; ++} ++ ++#[link(name = "unix")] ++extern "C" { ++ pub fn memmem( ++ source: *const ::c_void, ++ sourceLength: ::size_t, ++ search: *const ::c_void, ++ searchLength: ::size_t, ++ ) -> *mut ::c_void; + } + + cfg_if! { +@@ -1540,5 +2075,20 @@ cfg_if! { + } + } + ++cfg_if! { ++ if #[cfg(target_arch = "x86")] { ++ // TODO ++ // mod x86; ++ // pub use self::x86::*; ++ } else if #[cfg(target_arch = "x86_64")] { ++ mod x86_64; ++ pub use self::x86_64::*; ++ } else if #[cfg(target_arch = "aarch64")] { ++ // TODO ++ // mod aarch64; ++ // pub use self::aarch64::*; ++ } ++} ++ + mod native; + pub use self::native::*; +diff --git a/vendor/libc/src/unix/haiku/native.rs b/vendor/libc/src/unix/haiku/native.rs +index 5a37c68..44bcc1e 100644 +--- a/vendor/libc/src/unix/haiku/native.rs ++++ b/vendor/libc/src/unix/haiku/native.rs +@@ -63,10 +63,140 @@ e! { + } + + // kernel/scheduler.h ++ ++ pub enum be_task_flags { ++ B_DEFAULT_MEDIA_PRIORITY = 0x000, ++ B_OFFLINE_PROCESSING = 0x001, ++ B_STATUS_RENDERING = 0x002, ++ B_USER_INPUT_HANDLING = 0x004, ++ B_LIVE_VIDEO_MANIPULATION = 0x008, ++ B_VIDEO_PLAYBACK = 0x010, ++ B_VIDEO_RECORDING = 0x020, ++ B_LIVE_AUDIO_MANIPULATION = 0x040, ++ B_AUDIO_PLAYBACK = 0x080, ++ B_AUDIO_RECORDING = 0x100, ++ B_LIVE_3D_RENDERING = 0x200, ++ B_NUMBER_CRUNCHING = 0x400, ++ B_MIDI_PROCESSING = 0x800, ++ } ++ + pub enum schduler_mode { + SCHEDULER_MODE_LOW_LATENCY, + SCHEDULER_MODE_POWER_SAVING, + } ++ ++ // FindDirectory.h ++ pub enum path_base_directory { ++ B_FIND_PATH_INSTALLATION_LOCATION_DIRECTORY, ++ B_FIND_PATH_ADD_ONS_DIRECTORY, ++ B_FIND_PATH_APPS_DIRECTORY, ++ B_FIND_PATH_BIN_DIRECTORY, ++ B_FIND_PATH_BOOT_DIRECTORY, ++ B_FIND_PATH_CACHE_DIRECTORY, ++ B_FIND_PATH_DATA_DIRECTORY, ++ B_FIND_PATH_DEVELOP_DIRECTORY, ++ B_FIND_PATH_DEVELOP_LIB_DIRECTORY, ++ B_FIND_PATH_DOCUMENTATION_DIRECTORY, ++ B_FIND_PATH_ETC_DIRECTORY, ++ B_FIND_PATH_FONTS_DIRECTORY, ++ B_FIND_PATH_HEADERS_DIRECTORY, ++ B_FIND_PATH_LIB_DIRECTORY, ++ B_FIND_PATH_LOG_DIRECTORY, ++ B_FIND_PATH_MEDIA_NODES_DIRECTORY, ++ B_FIND_PATH_PACKAGES_DIRECTORY, ++ B_FIND_PATH_PREFERENCES_DIRECTORY, ++ B_FIND_PATH_SERVERS_DIRECTORY, ++ B_FIND_PATH_SETTINGS_DIRECTORY, ++ B_FIND_PATH_SOUNDS_DIRECTORY, ++ B_FIND_PATH_SPOOL_DIRECTORY, ++ B_FIND_PATH_TRANSLATORS_DIRECTORY, ++ B_FIND_PATH_VAR_DIRECTORY, ++ B_FIND_PATH_IMAGE_PATH = 1000, ++ B_FIND_PATH_PACKAGE_PATH, ++ } ++ ++ pub enum directory_which { ++ B_DESKTOP_DIRECTORY = 0, ++ B_TRASH_DIRECTORY, ++ B_SYSTEM_DIRECTORY = 1000, ++ B_SYSTEM_ADDONS_DIRECTORY = 1002, ++ B_SYSTEM_BOOT_DIRECTORY, ++ B_SYSTEM_FONTS_DIRECTORY, ++ B_SYSTEM_LIB_DIRECTORY, ++ B_SYSTEM_SERVERS_DIRECTORY, ++ B_SYSTEM_APPS_DIRECTORY, ++ B_SYSTEM_BIN_DIRECTORY, ++ B_SYSTEM_DOCUMENTATION_DIRECTORY = 1010, ++ B_SYSTEM_PREFERENCES_DIRECTORY, ++ B_SYSTEM_TRANSLATORS_DIRECTORY, ++ B_SYSTEM_MEDIA_NODES_DIRECTORY, ++ B_SYSTEM_SOUNDS_DIRECTORY, ++ B_SYSTEM_DATA_DIRECTORY, ++ B_SYSTEM_DEVELOP_DIRECTORY, ++ B_SYSTEM_PACKAGES_DIRECTORY, ++ B_SYSTEM_HEADERS_DIRECTORY, ++ B_SYSTEM_ETC_DIRECTORY = 2008, ++ B_SYSTEM_SETTINGS_DIRECTORY = 2010, ++ B_SYSTEM_LOG_DIRECTORY = 2012, ++ B_SYSTEM_SPOOL_DIRECTORY, ++ B_SYSTEM_TEMP_DIRECTORY, ++ B_SYSTEM_VAR_DIRECTORY, ++ B_SYSTEM_CACHE_DIRECTORY = 2020, ++ B_SYSTEM_NONPACKAGED_DIRECTORY = 2023, ++ B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY, ++ B_SYSTEM_NONPACKAGED_TRANSLATORS_DIRECTORY, ++ B_SYSTEM_NONPACKAGED_MEDIA_NODES_DIRECTORY, ++ B_SYSTEM_NONPACKAGED_BIN_DIRECTORY, ++ B_SYSTEM_NONPACKAGED_DATA_DIRECTORY, ++ B_SYSTEM_NONPACKAGED_FONTS_DIRECTORY, ++ B_SYSTEM_NONPACKAGED_SOUNDS_DIRECTORY, ++ B_SYSTEM_NONPACKAGED_DOCUMENTATION_DIRECTORY, ++ B_SYSTEM_NONPACKAGED_LIB_DIRECTORY, ++ B_SYSTEM_NONPACKAGED_HEADERS_DIRECTORY, ++ B_SYSTEM_NONPACKAGED_DEVELOP_DIRECTORY, ++ B_USER_DIRECTORY = 3000, ++ B_USER_CONFIG_DIRECTORY, ++ B_USER_ADDONS_DIRECTORY, ++ B_USER_BOOT_DIRECTORY, ++ B_USER_FONTS_DIRECTORY, ++ B_USER_LIB_DIRECTORY, ++ B_USER_SETTINGS_DIRECTORY, ++ B_USER_DESKBAR_DIRECTORY, ++ B_USER_PRINTERS_DIRECTORY, ++ B_USER_TRANSLATORS_DIRECTORY, ++ B_USER_MEDIA_NODES_DIRECTORY, ++ B_USER_SOUNDS_DIRECTORY, ++ B_USER_DATA_DIRECTORY, ++ B_USER_CACHE_DIRECTORY, ++ B_USER_PACKAGES_DIRECTORY, ++ B_USER_HEADERS_DIRECTORY, ++ B_USER_NONPACKAGED_DIRECTORY, ++ B_USER_NONPACKAGED_ADDONS_DIRECTORY, ++ B_USER_NONPACKAGED_TRANSLATORS_DIRECTORY, ++ B_USER_NONPACKAGED_MEDIA_NODES_DIRECTORY, ++ B_USER_NONPACKAGED_BIN_DIRECTORY, ++ B_USER_NONPACKAGED_DATA_DIRECTORY, ++ B_USER_NONPACKAGED_FONTS_DIRECTORY, ++ B_USER_NONPACKAGED_SOUNDS_DIRECTORY, ++ B_USER_NONPACKAGED_DOCUMENTATION_DIRECTORY, ++ B_USER_NONPACKAGED_LIB_DIRECTORY, ++ B_USER_NONPACKAGED_HEADERS_DIRECTORY, ++ B_USER_NONPACKAGED_DEVELOP_DIRECTORY, ++ B_USER_DEVELOP_DIRECTORY, ++ B_USER_DOCUMENTATION_DIRECTORY, ++ B_USER_SERVERS_DIRECTORY, ++ B_USER_APPS_DIRECTORY, ++ B_USER_BIN_DIRECTORY, ++ B_USER_PREFERENCES_DIRECTORY, ++ B_USER_ETC_DIRECTORY, ++ B_USER_LOG_DIRECTORY, ++ B_USER_SPOOL_DIRECTORY, ++ B_USER_VAR_DIRECTORY, ++ B_APPS_DIRECTORY = 4000, ++ B_PREFERENCES_DIRECTORY, ++ B_UTILITIES_DIRECTORY, ++ B_PACKAGE_LINKS_DIRECTORY, ++ } + } + + s! { +@@ -142,7 +272,8 @@ s! { + + pub struct cpu_info { + pub active_time: bigtime_t, +- pub enabled: bool ++ pub enabled: bool, ++ pub current_frequency: u64 + } + + pub struct system_info { +@@ -229,6 +360,93 @@ s! { + pub api_version: i32, + pub abi: i32 + } ++ ++ pub struct __c_anonymous_eax_0 { ++ pub max_eax: u32, ++ pub vendor_id: [::c_char; 12], ++ } ++ ++ pub struct __c_anonymous_eax_1 { ++ pub stepping: u32, ++ pub model: u32, ++ pub family: u32, ++ pub tpe: u32, ++ __reserved_0: u32, ++ pub extended_model: u32, ++ pub extended_family: u32, ++ __reserved_1: u32, ++ pub brand_index: u32, ++ pub clflush: u32, ++ pub logical_cpus: u32, ++ pub apic_id: u32, ++ pub features: u32, ++ pub extended_features: u32, ++ } ++ ++ pub struct __c_anonymous_eax_2 { ++ pub call_num: u8, ++ pub cache_descriptors: [u8; 15], ++ } ++ ++ pub struct __c_anonymous_eax_3 { ++ __reserved: [u32; 2], ++ pub serial_number_high: u32, ++ pub serial_number_low: u32, ++ } ++ ++ pub struct __c_anonymous_regs { ++ pub eax: u32, ++ pub ebx: u32, ++ pub edx: u32, ++ pub ecx: u32, ++ } ++} ++ ++s_no_extra_traits! { ++ #[cfg(libc_union)] ++ pub union cpuid_info { ++ pub eax_0: __c_anonymous_eax_0, ++ pub eax_1: __c_anonymous_eax_1, ++ pub eax_2: __c_anonymous_eax_2, ++ pub eax_3: __c_anonymous_eax_3, ++ pub as_chars: [::c_char; 16], ++ pub regs: __c_anonymous_regs, ++ } ++} ++ ++cfg_if! { ++ if #[cfg(feature = "extra_traits")] { ++ #[cfg(libc_union)] ++ impl PartialEq for cpuid_info { ++ fn eq(&self, other: &cpuid_info) -> bool { ++ unsafe { ++ self.eax_0 == other.eax_0 ++ || self.eax_1 == other.eax_1 ++ || self.eax_2 == other.eax_2 ++ || self.eax_3 == other.eax_3 ++ || self.as_chars == other.as_chars ++ || self.regs == other.regs ++ } ++ } ++ } ++ #[cfg(libc_union)] ++ impl Eq for cpuid_info {} ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for cpuid_info { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ unsafe { ++ f.debug_struct("cpuid_info") ++ .field("eax_0", &self.eax_0) ++ .field("eax_1", &self.eax_1) ++ .field("eax_2", &self.eax_2) ++ .field("eax_3", &self.eax_3) ++ .field("as_chars", &self.as_chars) ++ .field("regs", &self.regs) ++ .finish() ++ } ++ } ++ } ++ } + } + + // kernel/OS.h +@@ -450,7 +668,6 @@ pub const B_SHUTTING_DOWN: status_t = B_APP_ERROR_BASE + 18; + + // Storage kit errors + pub const B_FILE_ERROR: status_t = B_STORAGE_ERROR_BASE + 0; +-pub const B_FILE_NOT_FOUND: status_t = B_STORAGE_ERROR_BASE + 1; + pub const B_FILE_EXISTS: status_t = B_STORAGE_ERROR_BASE + 2; + pub const B_ENTRY_NOT_FOUND: status_t = B_STORAGE_ERROR_BASE + 3; + pub const B_NAME_TOO_LONG: status_t = B_STORAGE_ERROR_BASE + 4; +@@ -744,6 +961,13 @@ extern "C" { + + pub fn rename_thread(thread: thread_id, newName: *const ::c_char) -> status_t; + pub fn set_thread_priority(thread: thread_id, newPriority: i32) -> status_t; ++ pub fn suggest_thread_priority( ++ what: u32, ++ period: i32, ++ jitter: ::bigtime_t, ++ length: ::bigtime_t, ++ ) -> i32; ++ pub fn estimate_max_scheduling_latency(th: ::thread_id) -> ::bigtime_t; + pub fn exit_thread(status: status_t); + pub fn wait_for_thread(thread: thread_id, returnValue: *mut status_t) -> status_t; + pub fn on_exit_thread(callback: extern "C" fn(*mut ::c_void), data: *mut ::c_void) -> status_t; +@@ -795,10 +1019,13 @@ extern "C" { + pub fn debugger(message: *const ::c_char); + pub fn disable_debugger(state: ::c_int) -> ::c_int; + +- // TODO: cpuid_info struct and the get_cpuid() function +- + pub fn get_system_info(info: *mut system_info) -> status_t; +- pub fn get_cpu_info(firstCPU: u32, cpuCount: u32, info: *mut cpu_info) -> status_t; ++ pub fn _get_cpu_info_etc( ++ firstCPU: u32, ++ cpuCount: u32, ++ info: *mut cpu_info, ++ size: ::size_t, ++ ) -> status_t; + pub fn is_computer_on() -> i32; + pub fn is_computer_on_fire() -> ::c_double; + pub fn send_signal(threadID: thread_id, signal: ::c_uint) -> ::c_int; +@@ -934,13 +1161,88 @@ extern "C" { + info: *mut image_info, + size: ::size_t, + ) -> status_t; ++ pub fn find_path( ++ codePointer: *const ::c_void, ++ baseDirectory: path_base_directory, ++ subPath: *const ::c_char, ++ pathBuffer: *mut ::c_char, ++ bufferSize: usize, ++ ) -> status_t; ++ pub fn find_path_etc( ++ codePointer: *const ::c_void, ++ dependency: *const ::c_char, ++ architecture: *const ::c_char, ++ baseDirectory: path_base_directory, ++ subPath: *const ::c_char, ++ flags: u32, ++ pathBuffer: *mut ::c_char, ++ bufferSize: ::size_t, ++ ) -> status_t; ++ pub fn find_path_for_path( ++ path: *const ::c_char, ++ baseDirectory: path_base_directory, ++ subPath: *const ::c_char, ++ pathBuffer: *mut ::c_char, ++ bufferSize: ::size_t, ++ ) -> status_t; ++ pub fn find_path_for_path_etc( ++ path: *const ::c_char, ++ dependency: *const ::c_char, ++ architectur: *const ::c_char, ++ baseDirectory: path_base_directory, ++ subPath: *const ::c_char, ++ flags: u32, ++ pathBuffer: *mut ::c_char, ++ bufferSize: ::size_t, ++ ) -> status_t; ++ pub fn find_paths( ++ baseDirectory: path_base_directory, ++ subPath: *const ::c_char, ++ _paths: *mut *mut *mut ::c_char, ++ pathCount: *mut ::size_t, ++ ) -> status_t; ++ pub fn find_paths_etc( ++ architecture: *const ::c_char, ++ baseDirectory: path_base_directory, ++ subPath: *const ::c_char, ++ flags: u32, ++ _paths: *mut *mut *mut ::c_char, ++ pathCount: *mut ::size_t, ++ ) -> status_t; ++ pub fn find_directory( ++ which: directory_which, ++ volume: ::dev_t, ++ createIt: bool, ++ pathString: *mut ::c_char, ++ length: i32, ++ ) -> status_t; ++} ++ ++cfg_if! { ++ if #[cfg(libc_union)] { ++ extern "C" { ++ pub fn get_cpuid(info: *mut cpuid_info, eaxRegister: u32, cpuNum: u32) -> status_t; ++ } ++ } + } + + // The following functions are defined as macros in C/C++ ++#[inline] ++pub unsafe fn get_cpu_info(firstCPU: u32, cpuCount: u32, info: *mut cpu_info) -> status_t { ++ _get_cpu_info_etc( ++ firstCPU, ++ cpuCount, ++ info, ++ core::mem::size_of::() as ::size_t, ++ ) ++} ++ ++#[inline] + pub unsafe fn get_area_info(id: area_id, info: *mut area_info) -> status_t { + _get_area_info(id, info, core::mem::size_of::() as usize) + } + ++#[inline] + pub unsafe fn get_next_area_info( + team: team_id, + cookie: *mut isize, +@@ -954,10 +1256,12 @@ pub unsafe fn get_next_area_info( + ) + } + ++#[inline] + pub unsafe fn get_port_info(port: port_id, buf: *mut port_info) -> status_t { + _get_port_info(port, buf, core::mem::size_of::() as ::size_t) + } + ++#[inline] + pub unsafe fn get_next_port_info( + port: port_id, + cookie: *mut i32, +@@ -971,6 +1275,7 @@ pub unsafe fn get_next_port_info( + ) + } + ++#[inline] + pub unsafe fn get_port_message_info_etc( + port: port_id, + info: *mut port_message_info, +@@ -986,10 +1291,12 @@ pub unsafe fn get_port_message_info_etc( + ) + } + ++#[inline] + pub unsafe fn get_sem_info(id: sem_id, info: *mut sem_info) -> status_t { + _get_sem_info(id, info, core::mem::size_of::() as ::size_t) + } + ++#[inline] + pub unsafe fn get_next_sem_info(team: team_id, cookie: *mut i32, info: *mut sem_info) -> status_t { + _get_next_sem_info( + team, +@@ -999,14 +1306,17 @@ pub unsafe fn get_next_sem_info(team: team_id, cookie: *mut i32, info: *mut sem_ + ) + } + ++#[inline] + pub unsafe fn get_team_info(team: team_id, info: *mut team_info) -> status_t { + _get_team_info(team, info, core::mem::size_of::() as ::size_t) + } + ++#[inline] + pub unsafe fn get_next_team_info(cookie: *mut i32, info: *mut team_info) -> status_t { + _get_next_team_info(cookie, info, core::mem::size_of::() as ::size_t) + } + ++#[inline] + pub unsafe fn get_team_usage_info(team: team_id, who: i32, info: *mut team_usage_info) -> status_t { + _get_team_usage_info( + team, +@@ -1016,10 +1326,12 @@ pub unsafe fn get_team_usage_info(team: team_id, who: i32, info: *mut team_usage + ) + } + ++#[inline] + pub unsafe fn get_thread_info(id: thread_id, info: *mut thread_info) -> status_t { + _get_thread_info(id, info, core::mem::size_of::() as ::size_t) + } + ++#[inline] + pub unsafe fn get_next_thread_info( + team: team_id, + cookie: *mut i32, +@@ -1034,10 +1346,12 @@ pub unsafe fn get_next_thread_info( + } + + // kernel/image.h ++#[inline] + pub unsafe fn get_image_info(image: image_id, info: *mut image_info) -> status_t { + _get_image_info(image, info, core::mem::size_of::() as ::size_t) + } + ++#[inline] + pub unsafe fn get_next_image_info( + team: team_id, + cookie: *mut i32, +diff --git a/vendor/libc/src/unix/haiku/x86_64.rs b/vendor/libc/src/unix/haiku/x86_64.rs +new file mode 100644 +index 0000000..1b0462f +--- /dev/null ++++ b/vendor/libc/src/unix/haiku/x86_64.rs +@@ -0,0 +1,264 @@ ++s_no_extra_traits! { ++ pub struct fpu_state { ++ pub control: ::c_ushort, ++ pub status: ::c_ushort, ++ pub tag: ::c_ushort, ++ pub opcode: ::c_ushort, ++ pub rip: ::c_ulong, ++ pub rdp: ::c_ulong, ++ pub mxcsr: ::c_uint, ++ pub mscsr_mask: ::c_uint, ++ pub _fpreg: [[::c_uchar; 8]; 16], ++ pub _xmm: [[::c_uchar; 16]; 16], ++ pub _reserved_416_511: [::c_uchar; 96], ++ } ++ ++ pub struct xstate_hdr { ++ pub bv: ::c_ulong, ++ pub xcomp_bv: ::c_ulong, ++ pub _reserved: [::c_uchar; 48], ++ } ++ ++ pub struct savefpu { ++ pub fp_fxsave: fpu_state, ++ pub fp_xstate: xstate_hdr, ++ pub _fp_ymm: [[::c_uchar; 16]; 16], ++ } ++ ++ pub struct mcontext_t { ++ pub rax: ::c_ulong, ++ pub rbx: ::c_ulong, ++ pub rcx: ::c_ulong, ++ pub rdx: ::c_ulong, ++ pub rdi: ::c_ulong, ++ pub rsi: ::c_ulong, ++ pub rbp: ::c_ulong, ++ pub r8: ::c_ulong, ++ pub r9: ::c_ulong, ++ pub r10: ::c_ulong, ++ pub r11: ::c_ulong, ++ pub r12: ::c_ulong, ++ pub r13: ::c_ulong, ++ pub r14: ::c_ulong, ++ pub r15: ::c_ulong, ++ pub rsp: ::c_ulong, ++ pub rip: ::c_ulong, ++ pub rflags: ::c_ulong, ++ pub fpu: savefpu, ++ } ++ ++ pub struct ucontext_t { ++ pub uc_link: *mut ucontext_t, ++ pub uc_sigmask: ::sigset_t, ++ pub uc_stack: ::stack_t, ++ pub uc_mcontext: mcontext_t, ++ } ++} ++ ++cfg_if! { ++ if #[cfg(feature = "extra_traits")] { ++ impl PartialEq for fpu_state { ++ fn eq(&self, other: &fpu_state) -> bool { ++ self.control == other.control ++ && self.status == other.status ++ && self.tag == other.tag ++ && self.opcode == other.opcode ++ && self.rip == other.rip ++ && self.rdp == other.rdp ++ && self.mxcsr == other.mxcsr ++ && self.mscsr_mask == other.mscsr_mask ++ && self._fpreg.iter().zip(other._fpreg.iter()).all(|(a, b)| a == b) ++ && self._xmm.iter().zip(other._xmm.iter()).all(|(a, b)| a == b) ++ && self._reserved_416_511. ++ iter(). ++ zip(other._reserved_416_511.iter()). ++ all(|(a, b)| a == b) ++ } ++ } ++ impl Eq for fpu_state {} ++ impl ::fmt::Debug for fpu_state { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("fpu_state") ++ .field("control", &self.control) ++ .field("status", &self.status) ++ .field("tag", &self.tag) ++ .field("opcode", &self.opcode) ++ .field("rip", &self.rip) ++ .field("rdp", &self.rdp) ++ .field("mxcsr", &self.mxcsr) ++ .field("mscsr_mask", &self.mscsr_mask) ++ // FIXME: .field("_fpreg", &self._fpreg) ++ // FIXME: .field("_xmm", &self._xmm) ++ // FIXME: .field("_reserved_416_511", &self._reserved_416_511) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for fpu_state { ++ fn hash(&self, state: &mut H) { ++ self.control.hash(state); ++ self.status.hash(state); ++ self.tag.hash(state); ++ self.opcode.hash(state); ++ self.rip.hash(state); ++ self.rdp.hash(state); ++ self.mxcsr.hash(state); ++ self.mscsr_mask.hash(state); ++ self._fpreg.hash(state); ++ self._xmm.hash(state); ++ self._reserved_416_511.hash(state); ++ } ++ } ++ ++ impl PartialEq for xstate_hdr { ++ fn eq(&self, other: &xstate_hdr) -> bool { ++ self.bv == other.bv ++ && self.xcomp_bv == other.xcomp_bv ++ && self._reserved.iter().zip(other._reserved.iter()).all(|(a, b)| a == b) ++ } ++ } ++ impl Eq for xstate_hdr {} ++ impl ::fmt::Debug for xstate_hdr { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("xstate_hdr") ++ .field("bv", &self.bv) ++ .field("xcomp_bv", &self.xcomp_bv) ++ // FIXME: .field("_reserved", &field._reserved) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for xstate_hdr { ++ fn hash(&self, state: &mut H) { ++ self.bv.hash(state); ++ self.xcomp_bv.hash(state); ++ self._reserved.hash(state); ++ } ++ } ++ ++ impl PartialEq for savefpu { ++ fn eq(&self, other: &savefpu) -> bool { ++ self.fp_fxsave == other.fp_fxsave ++ && self.fp_xstate == other.fp_xstate ++ && self._fp_ymm.iter().zip(other._fp_ymm.iter()).all(|(a, b)| a == b) ++ } ++ } ++ impl Eq for savefpu {} ++ impl ::fmt::Debug for savefpu { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("savefpu") ++ .field("fp_fxsave", &self.fp_fxsave) ++ .field("fp_xstate", &self.fp_xstate) ++ // FIXME: .field("_fp_ymm", &field._fp_ymm) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for savefpu { ++ fn hash(&self, state: &mut H) { ++ self.fp_fxsave.hash(state); ++ self.fp_xstate.hash(state); ++ self._fp_ymm.hash(state); ++ } ++ } ++ ++ impl PartialEq for mcontext_t { ++ fn eq(&self, other: &mcontext_t) -> bool { ++ self.rax == other.rax ++ && self.rbx == other.rbx ++ && self.rbx == other.rbx ++ && self.rcx == other.rcx ++ && self.rdx == other.rdx ++ && self.rdi == other.rdi ++ && self.rsi == other.rsi ++ && self.r8 == other.r8 ++ && self.r9 == other.r9 ++ && self.r10 == other.r10 ++ && self.r11 == other.r11 ++ && self.r12 == other.r12 ++ && self.r13 == other.r13 ++ && self.r14 == other.r14 ++ && self.r15 == other.r15 ++ && self.rsp == other.rsp ++ && self.rip == other.rip ++ && self.rflags == other.rflags ++ && self.fpu == other.fpu ++ } ++ } ++ impl Eq for mcontext_t {} ++ impl ::fmt::Debug for mcontext_t { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("mcontext_t") ++ .field("rax", &self.rax) ++ .field("rbx", &self.rbx) ++ .field("rcx", &self.rcx) ++ .field("rdx", &self.rdx) ++ .field("rdi", &self.rdi) ++ .field("rsi", &self.rsi) ++ .field("rbp", &self.rbp) ++ .field("r8", &self.r8) ++ .field("r9", &self.r9) ++ .field("r10", &self.r10) ++ .field("r11", &self.r11) ++ .field("r12", &self.r12) ++ .field("r13", &self.r13) ++ .field("r14", &self.r14) ++ .field("r15", &self.r15) ++ .field("rsp", &self.rsp) ++ .field("rip", &self.rip) ++ .field("rflags", &self.rflags) ++ .field("fpu", &self.fpu) ++ .finish() ++ ++ } ++ } ++ impl ::hash::Hash for mcontext_t { ++ fn hash(&self, state: &mut H) { ++ self.rax.hash(state); ++ self.rbx.hash(state); ++ self.rcx.hash(state); ++ self.rdx.hash(state); ++ self.rdi.hash(state); ++ self.rsi.hash(state); ++ self.rbp.hash(state); ++ self.r8.hash(state); ++ self.r9.hash(state); ++ self.r10.hash(state); ++ self.r11.hash(state); ++ self.r12.hash(state); ++ self.r13.hash(state); ++ self.r14.hash(state); ++ self.r15.hash(state); ++ self.rsp.hash(state); ++ self.rip.hash(state); ++ self.rflags.hash(state); ++ self.fpu.hash(state); ++ } ++ } ++ ++ impl PartialEq for ucontext_t { ++ fn eq(&self, other: &ucontext_t) -> bool { ++ self.uc_link == other.uc_link ++ && self.uc_sigmask == other.uc_sigmask ++ && self.uc_stack == other.uc_stack ++ && self.uc_mcontext == other.uc_mcontext ++ } ++ } ++ impl Eq for ucontext_t {} ++ impl ::fmt::Debug for ucontext_t { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("ucontext_t") ++ .field("uc_link", &self.uc_link) ++ .field("uc_sigmask", &self.uc_sigmask) ++ .field("uc_stack", &self.uc_stack) ++ .field("uc_mcontext", &self.uc_mcontext) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for ucontext_t { ++ fn hash(&self, state: &mut H) { ++ self.uc_link.hash(state); ++ self.uc_sigmask.hash(state); ++ self.uc_stack.hash(state); ++ self.uc_mcontext.hash(state); ++ } ++ } ++ } ++} +diff --git a/vendor/libc/src/unix/hermit/mod.rs b/vendor/libc/src/unix/hermit/mod.rs +index eedfd28..6a656a8 100644 +--- a/vendor/libc/src/unix/hermit/mod.rs ++++ b/vendor/libc/src/unix/hermit/mod.rs +@@ -966,7 +966,6 @@ extern "C" { + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + + pub fn abs(i: ::c_int) -> ::c_int; +- pub fn atof(s: *const ::c_char) -> ::c_double; + pub fn labs(i: ::c_long) -> ::c_long; + pub fn rand() -> ::c_int; + pub fn srand(seed: ::c_uint); +diff --git a/vendor/libc/src/unix/linux_like/android/b32/arm.rs b/vendor/libc/src/unix/linux_like/android/b32/arm.rs +index 8a53e53..a062175 100644 +--- a/vendor/libc/src/unix/linux_like/android/b32/arm.rs ++++ b/vendor/libc/src/unix/linux_like/android/b32/arm.rs +@@ -138,7 +138,7 @@ cfg_if! { + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + self.uc_sigmask__c_anonymous_union.hash(state); +- &self.uc_regspace[..].hash(state); ++ self.uc_regspace[..].hash(state); + // Ignore padding field + } + } +@@ -501,6 +501,17 @@ pub const SYS_pwritev2: ::c_long = 393; + pub const SYS_pkey_mprotect: ::c_long = 394; + pub const SYS_pkey_alloc: ::c_long = 395; + pub const SYS_pkey_free: ::c_long = 396; ++pub const SYS_statx: ::c_long = 397; ++pub const SYS_pidfd_send_signal: ::c_long = 424; ++pub const SYS_io_uring_setup: ::c_long = 425; ++pub const SYS_io_uring_enter: ::c_long = 426; ++pub const SYS_io_uring_register: ::c_long = 427; ++pub const SYS_open_tree: ::c_long = 428; ++pub const SYS_move_mount: ::c_long = 429; ++pub const SYS_fsopen: ::c_long = 430; ++pub const SYS_fsconfig: ::c_long = 431; ++pub const SYS_fsmount: ::c_long = 432; ++pub const SYS_fspick: ::c_long = 433; + + // offsets in mcontext_t.gregs from sys/ucontext.h + pub const REG_R0: ::c_int = 0; +diff --git a/vendor/libc/src/unix/linux_like/android/b32/mod.rs b/vendor/libc/src/unix/linux_like/android/b32/mod.rs +index fc4b3f1..1f4f796 100644 +--- a/vendor/libc/src/unix/linux_like/android/b32/mod.rs ++++ b/vendor/libc/src/unix/linux_like/android/b32/mod.rs +@@ -8,6 +8,7 @@ pub type off64_t = ::c_longlong; + pub type sigset_t = ::c_ulong; + pub type socklen_t = i32; + pub type time64_t = i64; ++pub type __u64 = ::c_ulonglong; + + s! { + pub struct sigaction { +@@ -119,6 +120,14 @@ s! { + __reserved: [::c_char; 12], + } + ++ pub struct pthread_barrier_t { ++ __private: [i32; 8], ++ } ++ ++ pub struct pthread_spinlock_t { ++ __private: [i32; 2], ++ } ++ + pub struct passwd { + pub pw_name: *mut ::c_char, + pub pw_passwd: *mut ::c_char, +@@ -194,8 +203,6 @@ pub const RTLD_DEFAULT: *mut ::c_void = -1isize as *mut ::c_void; + + pub const PTRACE_GETFPREGS: ::c_int = 14; + pub const PTRACE_SETFPREGS: ::c_int = 15; +-pub const PTRACE_GETREGS: ::c_int = 12; +-pub const PTRACE_SETREGS: ::c_int = 13; + + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { value: 0 }; + pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { value: 0 }; +diff --git a/vendor/libc/src/unix/linux_like/android/b32/x86/mod.rs b/vendor/libc/src/unix/linux_like/android/b32/x86/mod.rs +index 6507cb4..e549f3b 100644 +--- a/vendor/libc/src/unix/linux_like/android/b32/x86/mod.rs ++++ b/vendor/libc/src/unix/linux_like/android/b32/x86/mod.rs +@@ -533,6 +533,17 @@ pub const SYS_pwritev2: ::c_long = 379; + pub const SYS_pkey_mprotect: ::c_long = 380; + pub const SYS_pkey_alloc: ::c_long = 381; + pub const SYS_pkey_free: ::c_long = 382; ++pub const SYS_statx: ::c_long = 383; ++pub const SYS_pidfd_send_signal: ::c_long = 424; ++pub const SYS_io_uring_setup: ::c_long = 425; ++pub const SYS_io_uring_enter: ::c_long = 426; ++pub const SYS_io_uring_register: ::c_long = 427; ++pub const SYS_open_tree: ::c_long = 428; ++pub const SYS_move_mount: ::c_long = 429; ++pub const SYS_fsopen: ::c_long = 430; ++pub const SYS_fsconfig: ::c_long = 431; ++pub const SYS_fsmount: ::c_long = 432; ++pub const SYS_fspick: ::c_long = 433; + + // offsets in user_regs_structs, from sys/reg.h + pub const EBX: ::c_int = 0; +diff --git a/vendor/libc/src/unix/linux_like/android/b64/aarch64/int128.rs b/vendor/libc/src/unix/linux_like/android/b64/aarch64/int128.rs +new file mode 100644 +index 0000000..4535e73 +--- /dev/null ++++ b/vendor/libc/src/unix/linux_like/android/b64/aarch64/int128.rs +@@ -0,0 +1,7 @@ ++s! { ++ pub struct user_fpsimd_struct { ++ pub vregs: [::__uint128_t; 32], ++ pub fpsr: u32, ++ pub fpcr: u32, ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/android/b64/aarch64/mod.rs b/vendor/libc/src/unix/linux_like/android/b64/aarch64/mod.rs +index 4912ff5..e7247fb 100644 +--- a/vendor/libc/src/unix/linux_like/android/b64/aarch64/mod.rs ++++ b/vendor/libc/src/unix/linux_like/android/b64/aarch64/mod.rs +@@ -1,5 +1,6 @@ + pub type c_char = u8; + pub type wchar_t = u32; ++pub type __u64 = ::c_ulonglong; + + s! { + pub struct stat { +@@ -47,6 +48,13 @@ s! { + __unused4: ::c_uint, + __unused5: ::c_uint, + } ++ ++ pub struct user_regs_struct { ++ pub regs: [u64; 31], ++ pub sp: u64, ++ pub pc: u64, ++ pub pstate: u64, ++ } + } + + pub const O_DIRECT: ::c_int = 0x10000; +@@ -99,6 +107,31 @@ pub const HWCAP2_SVESHA3: ::c_ulong = 1 << 5; + pub const HWCAP2_SVESM4: ::c_ulong = 1 << 6; + pub const HWCAP2_FLAGM2: ::c_ulong = 1 << 7; + pub const HWCAP2_FRINT: ::c_ulong = 1 << 8; ++pub const HWCAP2_SVEI8MM: ::c_ulong = 1 << 9; ++pub const HWCAP2_SVEF32MM: ::c_ulong = 1 << 10; ++pub const HWCAP2_SVEF64MM: ::c_ulong = 1 << 11; ++pub const HWCAP2_SVEBF16: ::c_ulong = 1 << 12; ++pub const HWCAP2_I8MM: ::c_ulong = 1 << 13; ++pub const HWCAP2_BF16: ::c_ulong = 1 << 14; ++pub const HWCAP2_DGH: ::c_ulong = 1 << 15; ++pub const HWCAP2_RNG: ::c_ulong = 1 << 16; ++pub const HWCAP2_BTI: ::c_ulong = 1 << 17; ++pub const HWCAP2_MTE: ::c_ulong = 1 << 18; ++pub const HWCAP2_ECV: ::c_ulong = 1 << 19; ++pub const HWCAP2_AFP: ::c_ulong = 1 << 20; ++pub const HWCAP2_RPRES: ::c_ulong = 1 << 21; ++pub const HWCAP2_MTE3: ::c_ulong = 1 << 22; ++pub const HWCAP2_SME: ::c_ulong = 1 << 23; ++pub const HWCAP2_SME_I16I64: ::c_ulong = 1 << 24; ++pub const HWCAP2_SME_F64F64: ::c_ulong = 1 << 25; ++pub const HWCAP2_SME_I8I32: ::c_ulong = 1 << 26; ++pub const HWCAP2_SME_F16F32: ::c_ulong = 1 << 27; ++pub const HWCAP2_SME_B16F32: ::c_ulong = 1 << 28; ++pub const HWCAP2_SME_F32F32: ::c_ulong = 1 << 29; ++pub const HWCAP2_SME_FA64: ::c_ulong = 1 << 30; ++pub const HWCAP2_WFXT: ::c_ulong = 1 << 31; ++pub const HWCAP2_EBF16: ::c_ulong = 1 << 32; ++pub const HWCAP2_SVE_EBF16: ::c_ulong = 1 << 33; + + pub const SYS_io_setup: ::c_long = 0; + pub const SYS_io_destroy: ::c_long = 1; +@@ -125,6 +158,7 @@ pub const SYS_epoll_ctl: ::c_long = 21; + pub const SYS_epoll_pwait: ::c_long = 22; + pub const SYS_dup: ::c_long = 23; + pub const SYS_dup3: ::c_long = 24; ++pub const SYS_fcntl: ::c_long = 25; + pub const SYS_inotify_init1: ::c_long = 26; + pub const SYS_inotify_add_watch: ::c_long = 27; + pub const SYS_inotify_rm_watch: ::c_long = 28; +@@ -365,6 +399,17 @@ pub const SYS_pwritev2: ::c_long = 287; + pub const SYS_pkey_mprotect: ::c_long = 288; + pub const SYS_pkey_alloc: ::c_long = 289; + pub const SYS_pkey_free: ::c_long = 290; ++pub const SYS_statx: ::c_long = 291; ++pub const SYS_pidfd_send_signal: ::c_long = 424; ++pub const SYS_io_uring_setup: ::c_long = 425; ++pub const SYS_io_uring_enter: ::c_long = 426; ++pub const SYS_io_uring_register: ::c_long = 427; ++pub const SYS_open_tree: ::c_long = 428; ++pub const SYS_move_mount: ::c_long = 429; ++pub const SYS_fsopen: ::c_long = 430; ++pub const SYS_fsconfig: ::c_long = 431; ++pub const SYS_fsmount: ::c_long = 432; ++pub const SYS_fspick: ::c_long = 433; + pub const SYS_syscalls: ::c_long = 436; + + cfg_if! { +@@ -373,3 +418,10 @@ cfg_if! { + pub use self::align::*; + } + } ++ ++cfg_if! { ++ if #[cfg(libc_int128)] { ++ mod int128; ++ pub use self::int128::*; ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/android/b64/mod.rs b/vendor/libc/src/unix/linux_like/android/b64/mod.rs +index c23e2db..67d0dac 100644 +--- a/vendor/libc/src/unix/linux_like/android/b64/mod.rs ++++ b/vendor/libc/src/unix/linux_like/android/b64/mod.rs +@@ -105,6 +105,14 @@ s! { + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } ++ ++ pub struct pthread_barrier_t { ++ __private: [i64; 4], ++ } ++ ++ pub struct pthread_spinlock_t { ++ __private: i64, ++ } + } + + s_no_extra_traits! { +@@ -323,6 +331,12 @@ f! { + + extern "C" { + pub fn getauxval(type_: ::c_ulong) -> ::c_ulong; ++ pub fn __system_property_wait( ++ pi: *const ::prop_info, ++ __old_serial: u32, ++ __new_serial_ptr: *mut u32, ++ __relative_timeout: *const ::timespec, ++ ) -> bool; + } + + cfg_if! { +@@ -332,6 +346,9 @@ cfg_if! { + } else if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; ++ } else if #[cfg(target_arch = "riscv64")] { ++ mod riscv64; ++ pub use self::riscv64::*; + } else { + // Unknown target_arch + } +diff --git a/vendor/libc/src/unix/linux_like/android/b64/riscv64/align.rs b/vendor/libc/src/unix/linux_like/android/b64/riscv64/align.rs +new file mode 100644 +index 0000000..8e94996 +--- /dev/null ++++ b/vendor/libc/src/unix/linux_like/android/b64/riscv64/align.rs +@@ -0,0 +1,7 @@ ++s_no_extra_traits! { ++ #[allow(missing_debug_implementations)] ++ #[repr(align(16))] ++ pub struct max_align_t { ++ priv_: [f32; 8] ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/android/b64/riscv64/mod.rs b/vendor/libc/src/unix/linux_like/android/b64/riscv64/mod.rs +new file mode 100644 +index 0000000..9d414dc +--- /dev/null ++++ b/vendor/libc/src/unix/linux_like/android/b64/riscv64/mod.rs +@@ -0,0 +1,353 @@ ++pub type c_char = i8; ++pub type wchar_t = u32; ++pub type greg_t = i64; ++pub type __u64 = ::c_ulonglong; ++ ++s! { ++ pub struct stat { ++ pub st_dev: ::dev_t, ++ pub st_ino: ::ino_t, ++ pub st_mode: ::c_uint, ++ pub st_nlink: ::c_uint, ++ pub st_uid: ::uid_t, ++ pub st_gid: ::gid_t, ++ pub st_rdev: ::dev_t, ++ __pad1: ::c_ulong, ++ pub st_size: ::off64_t, ++ pub st_blksize: ::c_int, ++ __pad2: ::c_int, ++ pub st_blocks: ::c_long, ++ pub st_atime: ::time_t, ++ pub st_atime_nsec: ::c_long, ++ pub st_mtime: ::time_t, ++ pub st_mtime_nsec: ::c_long, ++ pub st_ctime: ::time_t, ++ pub st_ctime_nsec: ::c_long, ++ __unused4: ::c_uint, ++ __unused5: ::c_uint, ++ } ++ ++ pub struct stat64 { ++ pub st_dev: ::dev_t, ++ pub st_ino: ::ino_t, ++ pub st_mode: ::c_uint, ++ pub st_nlink: ::c_uint, ++ pub st_uid: ::uid_t, ++ pub st_gid: ::gid_t, ++ pub st_rdev: ::dev_t, ++ __pad1: ::c_ulong, ++ pub st_size: ::off64_t, ++ pub st_blksize: ::c_int, ++ __pad2: ::c_int, ++ pub st_blocks: ::c_long, ++ pub st_atime: ::time_t, ++ pub st_atime_nsec: ::c_long, ++ pub st_mtime: ::time_t, ++ pub st_mtime_nsec: ::c_long, ++ pub st_ctime: ::time_t, ++ pub st_ctime_nsec: ::c_long, ++ __unused4: ::c_uint, ++ __unused5: ::c_uint, ++ } ++} ++ ++pub const O_DIRECT: ::c_int = 0x40000; ++pub const O_DIRECTORY: ::c_int = 0x200000; ++pub const O_NOFOLLOW: ::c_int = 0x400000; ++pub const O_LARGEFILE: ::c_int = 0x100000; ++ ++pub const SIGSTKSZ: ::size_t = 8192; ++pub const MINSIGSTKSZ: ::size_t = 2048; ++ ++// From NDK's asm/hwcap.h ++pub const COMPAT_HWCAP_ISA_I: ::c_ulong = 1 << (b'I' - b'A'); ++pub const COMPAT_HWCAP_ISA_M: ::c_ulong = 1 << (b'M' - b'A'); ++pub const COMPAT_HWCAP_ISA_A: ::c_ulong = 1 << (b'A' - b'A'); ++pub const COMPAT_HWCAP_ISA_F: ::c_ulong = 1 << (b'F' - b'A'); ++pub const COMPAT_HWCAP_ISA_D: ::c_ulong = 1 << (b'D' - b'A'); ++pub const COMPAT_HWCAP_ISA_C: ::c_ulong = 1 << (b'C' - b'A'); ++ ++pub const SYS_io_setup: ::c_long = 0; ++pub const SYS_io_destroy: ::c_long = 1; ++pub const SYS_io_submit: ::c_long = 2; ++pub const SYS_io_cancel: ::c_long = 3; ++pub const SYS_io_getevents: ::c_long = 4; ++pub const SYS_setxattr: ::c_long = 5; ++pub const SYS_lsetxattr: ::c_long = 6; ++pub const SYS_fsetxattr: ::c_long = 7; ++pub const SYS_getxattr: ::c_long = 8; ++pub const SYS_lgetxattr: ::c_long = 9; ++pub const SYS_fgetxattr: ::c_long = 10; ++pub const SYS_listxattr: ::c_long = 11; ++pub const SYS_llistxattr: ::c_long = 12; ++pub const SYS_flistxattr: ::c_long = 13; ++pub const SYS_removexattr: ::c_long = 14; ++pub const SYS_lremovexattr: ::c_long = 15; ++pub const SYS_fremovexattr: ::c_long = 16; ++pub const SYS_getcwd: ::c_long = 17; ++pub const SYS_lookup_dcookie: ::c_long = 18; ++pub const SYS_eventfd2: ::c_long = 19; ++pub const SYS_epoll_create1: ::c_long = 20; ++pub const SYS_epoll_ctl: ::c_long = 21; ++pub const SYS_epoll_pwait: ::c_long = 22; ++pub const SYS_dup: ::c_long = 23; ++pub const SYS_dup3: ::c_long = 24; ++pub const SYS_inotify_init1: ::c_long = 26; ++pub const SYS_inotify_add_watch: ::c_long = 27; ++pub const SYS_inotify_rm_watch: ::c_long = 28; ++pub const SYS_ioctl: ::c_long = 29; ++pub const SYS_ioprio_set: ::c_long = 30; ++pub const SYS_ioprio_get: ::c_long = 31; ++pub const SYS_flock: ::c_long = 32; ++pub const SYS_mknodat: ::c_long = 33; ++pub const SYS_mkdirat: ::c_long = 34; ++pub const SYS_unlinkat: ::c_long = 35; ++pub const SYS_symlinkat: ::c_long = 36; ++pub const SYS_linkat: ::c_long = 37; ++pub const SYS_renameat: ::c_long = 38; ++pub const SYS_umount2: ::c_long = 39; ++pub const SYS_mount: ::c_long = 40; ++pub const SYS_pivot_root: ::c_long = 41; ++pub const SYS_nfsservctl: ::c_long = 42; ++pub const SYS_fallocate: ::c_long = 47; ++pub const SYS_faccessat: ::c_long = 48; ++pub const SYS_chdir: ::c_long = 49; ++pub const SYS_fchdir: ::c_long = 50; ++pub const SYS_chroot: ::c_long = 51; ++pub const SYS_fchmod: ::c_long = 52; ++pub const SYS_fchmodat: ::c_long = 53; ++pub const SYS_fchownat: ::c_long = 54; ++pub const SYS_fchown: ::c_long = 55; ++pub const SYS_openat: ::c_long = 56; ++pub const SYS_close: ::c_long = 57; ++pub const SYS_vhangup: ::c_long = 58; ++pub const SYS_pipe2: ::c_long = 59; ++pub const SYS_quotactl: ::c_long = 60; ++pub const SYS_getdents64: ::c_long = 61; ++pub const SYS_read: ::c_long = 63; ++pub const SYS_write: ::c_long = 64; ++pub const SYS_readv: ::c_long = 65; ++pub const SYS_writev: ::c_long = 66; ++pub const SYS_pread64: ::c_long = 67; ++pub const SYS_pwrite64: ::c_long = 68; ++pub const SYS_preadv: ::c_long = 69; ++pub const SYS_pwritev: ::c_long = 70; ++pub const SYS_pselect6: ::c_long = 72; ++pub const SYS_ppoll: ::c_long = 73; ++pub const SYS_signalfd4: ::c_long = 74; ++pub const SYS_vmsplice: ::c_long = 75; ++pub const SYS_splice: ::c_long = 76; ++pub const SYS_tee: ::c_long = 77; ++pub const SYS_readlinkat: ::c_long = 78; ++pub const SYS_sync: ::c_long = 81; ++pub const SYS_fsync: ::c_long = 82; ++pub const SYS_fdatasync: ::c_long = 83; ++pub const SYS_sync_file_range: ::c_long = 84; ++pub const SYS_timerfd_create: ::c_long = 85; ++pub const SYS_timerfd_settime: ::c_long = 86; ++pub const SYS_timerfd_gettime: ::c_long = 87; ++pub const SYS_utimensat: ::c_long = 88; ++pub const SYS_acct: ::c_long = 89; ++pub const SYS_capget: ::c_long = 90; ++pub const SYS_capset: ::c_long = 91; ++pub const SYS_personality: ::c_long = 92; ++pub const SYS_exit: ::c_long = 93; ++pub const SYS_exit_group: ::c_long = 94; ++pub const SYS_waitid: ::c_long = 95; ++pub const SYS_set_tid_address: ::c_long = 96; ++pub const SYS_unshare: ::c_long = 97; ++pub const SYS_futex: ::c_long = 98; ++pub const SYS_set_robust_list: ::c_long = 99; ++pub const SYS_get_robust_list: ::c_long = 100; ++pub const SYS_nanosleep: ::c_long = 101; ++pub const SYS_getitimer: ::c_long = 102; ++pub const SYS_setitimer: ::c_long = 103; ++pub const SYS_kexec_load: ::c_long = 104; ++pub const SYS_init_module: ::c_long = 105; ++pub const SYS_delete_module: ::c_long = 106; ++pub const SYS_timer_create: ::c_long = 107; ++pub const SYS_timer_gettime: ::c_long = 108; ++pub const SYS_timer_getoverrun: ::c_long = 109; ++pub const SYS_timer_settime: ::c_long = 110; ++pub const SYS_timer_delete: ::c_long = 111; ++pub const SYS_clock_settime: ::c_long = 112; ++pub const SYS_clock_gettime: ::c_long = 113; ++pub const SYS_clock_getres: ::c_long = 114; ++pub const SYS_clock_nanosleep: ::c_long = 115; ++pub const SYS_syslog: ::c_long = 116; ++pub const SYS_ptrace: ::c_long = 117; ++pub const SYS_sched_setparam: ::c_long = 118; ++pub const SYS_sched_setscheduler: ::c_long = 119; ++pub const SYS_sched_getscheduler: ::c_long = 120; ++pub const SYS_sched_getparam: ::c_long = 121; ++pub const SYS_sched_setaffinity: ::c_long = 122; ++pub const SYS_sched_getaffinity: ::c_long = 123; ++pub const SYS_sched_yield: ::c_long = 124; ++pub const SYS_sched_get_priority_max: ::c_long = 125; ++pub const SYS_sched_get_priority_min: ::c_long = 126; ++pub const SYS_sched_rr_get_interval: ::c_long = 127; ++pub const SYS_restart_syscall: ::c_long = 128; ++pub const SYS_kill: ::c_long = 129; ++pub const SYS_tkill: ::c_long = 130; ++pub const SYS_tgkill: ::c_long = 131; ++pub const SYS_sigaltstack: ::c_long = 132; ++pub const SYS_rt_sigsuspend: ::c_long = 133; ++pub const SYS_rt_sigaction: ::c_long = 134; ++pub const SYS_rt_sigprocmask: ::c_long = 135; ++pub const SYS_rt_sigpending: ::c_long = 136; ++pub const SYS_rt_sigtimedwait: ::c_long = 137; ++pub const SYS_rt_sigqueueinfo: ::c_long = 138; ++pub const SYS_rt_sigreturn: ::c_long = 139; ++pub const SYS_setpriority: ::c_long = 140; ++pub const SYS_getpriority: ::c_long = 141; ++pub const SYS_reboot: ::c_long = 142; ++pub const SYS_setregid: ::c_long = 143; ++pub const SYS_setgid: ::c_long = 144; ++pub const SYS_setreuid: ::c_long = 145; ++pub const SYS_setuid: ::c_long = 146; ++pub const SYS_setresuid: ::c_long = 147; ++pub const SYS_getresuid: ::c_long = 148; ++pub const SYS_setresgid: ::c_long = 149; ++pub const SYS_getresgid: ::c_long = 150; ++pub const SYS_setfsuid: ::c_long = 151; ++pub const SYS_setfsgid: ::c_long = 152; ++pub const SYS_times: ::c_long = 153; ++pub const SYS_setpgid: ::c_long = 154; ++pub const SYS_getpgid: ::c_long = 155; ++pub const SYS_getsid: ::c_long = 156; ++pub const SYS_setsid: ::c_long = 157; ++pub const SYS_getgroups: ::c_long = 158; ++pub const SYS_setgroups: ::c_long = 159; ++pub const SYS_uname: ::c_long = 160; ++pub const SYS_sethostname: ::c_long = 161; ++pub const SYS_setdomainname: ::c_long = 162; ++pub const SYS_getrlimit: ::c_long = 163; ++pub const SYS_setrlimit: ::c_long = 164; ++pub const SYS_getrusage: ::c_long = 165; ++pub const SYS_umask: ::c_long = 166; ++pub const SYS_prctl: ::c_long = 167; ++pub const SYS_getcpu: ::c_long = 168; ++pub const SYS_gettimeofday: ::c_long = 169; ++pub const SYS_settimeofday: ::c_long = 170; ++pub const SYS_adjtimex: ::c_long = 171; ++pub const SYS_getpid: ::c_long = 172; ++pub const SYS_getppid: ::c_long = 173; ++pub const SYS_getuid: ::c_long = 174; ++pub const SYS_geteuid: ::c_long = 175; ++pub const SYS_getgid: ::c_long = 176; ++pub const SYS_getegid: ::c_long = 177; ++pub const SYS_gettid: ::c_long = 178; ++pub const SYS_sysinfo: ::c_long = 179; ++pub const SYS_mq_open: ::c_long = 180; ++pub const SYS_mq_unlink: ::c_long = 181; ++pub const SYS_mq_timedsend: ::c_long = 182; ++pub const SYS_mq_timedreceive: ::c_long = 183; ++pub const SYS_mq_notify: ::c_long = 184; ++pub const SYS_mq_getsetattr: ::c_long = 185; ++pub const SYS_msgget: ::c_long = 186; ++pub const SYS_msgctl: ::c_long = 187; ++pub const SYS_msgrcv: ::c_long = 188; ++pub const SYS_msgsnd: ::c_long = 189; ++pub const SYS_semget: ::c_long = 190; ++pub const SYS_semctl: ::c_long = 191; ++pub const SYS_semtimedop: ::c_long = 192; ++pub const SYS_semop: ::c_long = 193; ++pub const SYS_shmget: ::c_long = 194; ++pub const SYS_shmctl: ::c_long = 195; ++pub const SYS_shmat: ::c_long = 196; ++pub const SYS_shmdt: ::c_long = 197; ++pub const SYS_socket: ::c_long = 198; ++pub const SYS_socketpair: ::c_long = 199; ++pub const SYS_bind: ::c_long = 200; ++pub const SYS_listen: ::c_long = 201; ++pub const SYS_accept: ::c_long = 202; ++pub const SYS_connect: ::c_long = 203; ++pub const SYS_getsockname: ::c_long = 204; ++pub const SYS_getpeername: ::c_long = 205; ++pub const SYS_sendto: ::c_long = 206; ++pub const SYS_recvfrom: ::c_long = 207; ++pub const SYS_setsockopt: ::c_long = 208; ++pub const SYS_getsockopt: ::c_long = 209; ++pub const SYS_shutdown: ::c_long = 210; ++pub const SYS_sendmsg: ::c_long = 211; ++pub const SYS_recvmsg: ::c_long = 212; ++pub const SYS_readahead: ::c_long = 213; ++pub const SYS_brk: ::c_long = 214; ++pub const SYS_munmap: ::c_long = 215; ++pub const SYS_mremap: ::c_long = 216; ++pub const SYS_add_key: ::c_long = 217; ++pub const SYS_request_key: ::c_long = 218; ++pub const SYS_keyctl: ::c_long = 219; ++pub const SYS_clone: ::c_long = 220; ++pub const SYS_execve: ::c_long = 221; ++pub const SYS_swapon: ::c_long = 224; ++pub const SYS_swapoff: ::c_long = 225; ++pub const SYS_mprotect: ::c_long = 226; ++pub const SYS_msync: ::c_long = 227; ++pub const SYS_mlock: ::c_long = 228; ++pub const SYS_munlock: ::c_long = 229; ++pub const SYS_mlockall: ::c_long = 230; ++pub const SYS_munlockall: ::c_long = 231; ++pub const SYS_mincore: ::c_long = 232; ++pub const SYS_madvise: ::c_long = 233; ++pub const SYS_remap_file_pages: ::c_long = 234; ++pub const SYS_mbind: ::c_long = 235; ++pub const SYS_get_mempolicy: ::c_long = 236; ++pub const SYS_set_mempolicy: ::c_long = 237; ++pub const SYS_migrate_pages: ::c_long = 238; ++pub const SYS_move_pages: ::c_long = 239; ++pub const SYS_rt_tgsigqueueinfo: ::c_long = 240; ++pub const SYS_perf_event_open: ::c_long = 241; ++pub const SYS_accept4: ::c_long = 242; ++pub const SYS_recvmmsg: ::c_long = 243; ++pub const SYS_arch_specific_syscall: ::c_long = 244; ++pub const SYS_wait4: ::c_long = 260; ++pub const SYS_prlimit64: ::c_long = 261; ++pub const SYS_fanotify_init: ::c_long = 262; ++pub const SYS_fanotify_mark: ::c_long = 263; ++pub const SYS_name_to_handle_at: ::c_long = 264; ++pub const SYS_open_by_handle_at: ::c_long = 265; ++pub const SYS_clock_adjtime: ::c_long = 266; ++pub const SYS_syncfs: ::c_long = 267; ++pub const SYS_setns: ::c_long = 268; ++pub const SYS_sendmmsg: ::c_long = 269; ++pub const SYS_process_vm_readv: ::c_long = 270; ++pub const SYS_process_vm_writev: ::c_long = 271; ++pub const SYS_kcmp: ::c_long = 272; ++pub const SYS_finit_module: ::c_long = 273; ++pub const SYS_sched_setattr: ::c_long = 274; ++pub const SYS_sched_getattr: ::c_long = 275; ++pub const SYS_renameat2: ::c_long = 276; ++pub const SYS_seccomp: ::c_long = 277; ++pub const SYS_getrandom: ::c_long = 278; ++pub const SYS_memfd_create: ::c_long = 279; ++pub const SYS_bpf: ::c_long = 280; ++pub const SYS_execveat: ::c_long = 281; ++pub const SYS_userfaultfd: ::c_long = 282; ++pub const SYS_membarrier: ::c_long = 283; ++pub const SYS_mlock2: ::c_long = 284; ++pub const SYS_copy_file_range: ::c_long = 285; ++pub const SYS_preadv2: ::c_long = 286; ++pub const SYS_pwritev2: ::c_long = 287; ++pub const SYS_pkey_mprotect: ::c_long = 288; ++pub const SYS_pkey_alloc: ::c_long = 289; ++pub const SYS_pkey_free: ::c_long = 290; ++pub const SYS_statx: ::c_long = 291; ++pub const SYS_pidfd_send_signal: ::c_long = 424; ++pub const SYS_io_uring_setup: ::c_long = 425; ++pub const SYS_io_uring_enter: ::c_long = 426; ++pub const SYS_io_uring_register: ::c_long = 427; ++pub const SYS_open_tree: ::c_long = 428; ++pub const SYS_move_mount: ::c_long = 429; ++pub const SYS_fsopen: ::c_long = 430; ++pub const SYS_fsconfig: ::c_long = 431; ++pub const SYS_fsmount: ::c_long = 432; ++pub const SYS_fspick: ::c_long = 433; ++pub const SYS_syscalls: ::c_long = 436; ++ ++cfg_if! { ++ if #[cfg(libc_align)] { ++ mod align; ++ pub use self::align::*; ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/android/b64/x86_64/mod.rs b/vendor/libc/src/unix/linux_like/android/b64/x86_64/mod.rs +index 27fd17b..be6b501 100644 +--- a/vendor/libc/src/unix/linux_like/android/b64/x86_64/mod.rs ++++ b/vendor/libc/src/unix/linux_like/android/b64/x86_64/mod.rs +@@ -1,6 +1,7 @@ + pub type c_char = i8; + pub type wchar_t = i32; + pub type greg_t = i64; ++pub type __u64 = ::c_ulonglong; + + s! { + pub struct stat { +@@ -46,6 +47,61 @@ s! { + pub struct _libc_xmmreg { + pub element: [u32; 4], + } ++ ++ pub struct user_regs_struct { ++ pub r15: ::c_ulong, ++ pub r14: ::c_ulong, ++ pub r13: ::c_ulong, ++ pub r12: ::c_ulong, ++ pub rbp: ::c_ulong, ++ pub rbx: ::c_ulong, ++ pub r11: ::c_ulong, ++ pub r10: ::c_ulong, ++ pub r9: ::c_ulong, ++ pub r8: ::c_ulong, ++ pub rax: ::c_ulong, ++ pub rcx: ::c_ulong, ++ pub rdx: ::c_ulong, ++ pub rsi: ::c_ulong, ++ pub rdi: ::c_ulong, ++ pub orig_rax: ::c_ulong, ++ pub rip: ::c_ulong, ++ pub cs: ::c_ulong, ++ pub eflags: ::c_ulong, ++ pub rsp: ::c_ulong, ++ pub ss: ::c_ulong, ++ pub fs_base: ::c_ulong, ++ pub gs_base: ::c_ulong, ++ pub ds: ::c_ulong, ++ pub es: ::c_ulong, ++ pub fs: ::c_ulong, ++ pub gs: ::c_ulong, ++ } ++ ++ pub struct user { ++ pub regs: user_regs_struct, ++ pub u_fpvalid: ::c_int, ++ pub i387: user_fpregs_struct, ++ pub u_tsize: ::c_ulong, ++ pub u_dsize: ::c_ulong, ++ pub u_ssize: ::c_ulong, ++ pub start_code: ::c_ulong, ++ pub start_stack: ::c_ulong, ++ pub signal: ::c_long, ++ __reserved: ::c_int, ++ #[cfg(target_pointer_width = "32")] ++ __pad1: u32, ++ pub u_ar0: *mut user_regs_struct, ++ #[cfg(target_pointer_width = "32")] ++ __pad2: u32, ++ pub u_fpstate: *mut user_fpregs_struct, ++ pub magic: ::c_ulong, ++ pub u_comm: [::c_char; 32], ++ pub u_debugreg: [::c_ulong; 8], ++ pub error_code: ::c_ulong, ++ pub fault_address: ::c_ulong, ++ } ++ + } + + cfg_if! { +@@ -117,6 +173,20 @@ s_no_extra_traits! { + pub uc_sigmask64: __c_anonymous_uc_sigmask, + __fpregs_mem: _libc_fpstate, + } ++ ++ pub struct user_fpregs_struct { ++ pub cwd: ::c_ushort, ++ pub swd: ::c_ushort, ++ pub ftw: ::c_ushort, ++ pub fop: ::c_ushort, ++ pub rip: ::c_ulong, ++ pub rdp: ::c_ulong, ++ pub mxcsr: ::c_uint, ++ pub mxcr_mask: ::c_uint, ++ pub st_space: [::c_uint; 32], ++ pub xmm_space: [::c_uint; 64], ++ padding: [::c_uint; 24], ++ } + } + + cfg_if! { +@@ -253,6 +323,62 @@ cfg_if! { + // Ignore padding field + } + } ++ ++ impl PartialEq for user_fpregs_struct { ++ fn eq(&self, other: &user_fpregs_struct) -> bool { ++ self.cwd == other.cwd ++ && self.swd == other.swd ++ && self.ftw == other.ftw ++ && self.fop == other.fop ++ && self.rip == other.rip ++ && self.rdp == other.rdp ++ && self.mxcsr == other.mxcsr ++ && self.mxcr_mask == other.mxcr_mask ++ && self.st_space == other.st_space ++ && self ++ .xmm_space ++ .iter() ++ .zip(other.xmm_space.iter()) ++ .all(|(a,b)| a == b) ++ // Ignore padding field ++ } ++ } ++ ++ impl Eq for user_fpregs_struct {} ++ ++ impl ::fmt::Debug for user_fpregs_struct { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("user_fpregs_struct") ++ .field("cwd", &self.cwd) ++ .field("swd", &self.swd) ++ .field("ftw", &self.ftw) ++ .field("fop", &self.fop) ++ .field("rip", &self.rip) ++ .field("rdp", &self.rdp) ++ .field("mxcsr", &self.mxcsr) ++ .field("mxcr_mask", &self.mxcr_mask) ++ .field("st_space", &self.st_space) ++ // FIXME: .field("xmm_space", &self.xmm_space) ++ // Ignore padding field ++ .finish() ++ } ++ } ++ ++ impl ::hash::Hash for user_fpregs_struct { ++ fn hash(&self, state: &mut H) { ++ self.cwd.hash(state); ++ self.swd.hash(state); ++ self.ftw.hash(state); ++ self.fop.hash(state); ++ self.rip.hash(state); ++ self.rdp.hash(state); ++ self.mxcsr.hash(state); ++ self.mxcr_mask.hash(state); ++ self.st_space.hash(state); ++ self.xmm_space.hash(state); ++ // Ignore padding field ++ } ++ } + } + } + +@@ -602,6 +728,17 @@ pub const SYS_pwritev2: ::c_long = 328; + pub const SYS_pkey_mprotect: ::c_long = 329; + pub const SYS_pkey_alloc: ::c_long = 330; + pub const SYS_pkey_free: ::c_long = 331; ++pub const SYS_statx: ::c_long = 332; ++pub const SYS_pidfd_send_signal: ::c_long = 424; ++pub const SYS_io_uring_setup: ::c_long = 425; ++pub const SYS_io_uring_enter: ::c_long = 426; ++pub const SYS_io_uring_register: ::c_long = 427; ++pub const SYS_open_tree: ::c_long = 428; ++pub const SYS_move_mount: ::c_long = 429; ++pub const SYS_fsopen: ::c_long = 430; ++pub const SYS_fsconfig: ::c_long = 431; ++pub const SYS_fsmount: ::c_long = 432; ++pub const SYS_fspick: ::c_long = 433; + + // offsets in user_regs_structs, from sys/reg.h + pub const R15: ::c_int = 0; +diff --git a/vendor/libc/src/unix/linux_like/android/mod.rs b/vendor/libc/src/unix/linux_like/android/mod.rs +index d2b04dc..fd4b059 100644 +--- a/vendor/libc/src/unix/linux_like/android/mod.rs ++++ b/vendor/libc/src/unix/linux_like/android/mod.rs +@@ -11,6 +11,7 @@ pub type useconds_t = u32; + pub type pthread_t = ::c_long; + pub type pthread_mutexattr_t = ::c_long; + pub type pthread_rwlockattr_t = ::c_long; ++pub type pthread_barrierattr_t = ::c_int; + pub type pthread_condattr_t = ::c_long; + pub type pthread_key_t = ::c_int; + pub type fsfilcnt_t = ::c_ulong; +@@ -26,6 +27,12 @@ pub type loff_t = ::c_longlong; + pub type __kernel_loff_t = ::c_longlong; + pub type __kernel_pid_t = ::c_int; + ++pub type __u8 = ::c_uchar; ++pub type __u16 = ::c_ushort; ++pub type __s16 = ::c_short; ++pub type __u32 = ::c_uint; ++pub type __s32 = ::c_int; ++ + // linux/elf.h + + pub type Elf32_Addr = u32; +@@ -86,6 +93,19 @@ s! { + pub c_ospeed: ::speed_t, + } + ++ pub struct mallinfo { ++ pub arena: ::size_t, ++ pub ordblks: ::size_t, ++ pub smblks: ::size_t, ++ pub hblks: ::size_t, ++ pub hblkhd: ::size_t, ++ pub usmblks: ::size_t, ++ pub fsmblks: ::size_t, ++ pub uordblks: ::size_t, ++ pub fordblks: ::size_t, ++ pub keepcost: ::size_t, ++ } ++ + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, +@@ -308,6 +328,167 @@ s! { + pub dlpi_tls_modid: ::size_t, + pub dlpi_tls_data: *mut ::c_void, + } ++ ++ // linux/filter.h ++ pub struct sock_filter { ++ pub code: ::__u16, ++ pub jt: ::__u8, ++ pub jf: ::__u8, ++ pub k: ::__u32, ++ } ++ ++ pub struct sock_fprog { ++ pub len: ::c_ushort, ++ pub filter: *mut sock_filter, ++ } ++ ++ // linux/seccomp.h ++ pub struct seccomp_data { ++ pub nr: ::c_int, ++ pub arch: ::__u32, ++ pub instruction_pointer: ::__u64, ++ pub args: [::__u64; 6], ++ } ++ ++ pub struct ptrace_peeksiginfo_args { ++ pub off: ::__u64, ++ pub flags: ::__u32, ++ pub nr: ::__s32, ++ } ++ ++ // linux/input.h ++ pub struct input_event { ++ pub time: ::timeval, ++ pub type_: ::__u16, ++ pub code: ::__u16, ++ pub value: ::__s32, ++ } ++ ++ pub struct input_id { ++ pub bustype: ::__u16, ++ pub vendor: ::__u16, ++ pub product: ::__u16, ++ pub version: ::__u16, ++ } ++ ++ pub struct input_absinfo { ++ pub value: ::__s32, ++ pub minimum: ::__s32, ++ pub maximum: ::__s32, ++ pub fuzz: ::__s32, ++ pub flat: ::__s32, ++ pub resolution: ::__s32, ++ } ++ ++ pub struct input_keymap_entry { ++ pub flags: ::__u8, ++ pub len: ::__u8, ++ pub index: ::__u16, ++ pub keycode: ::__u32, ++ pub scancode: [::__u8; 32], ++ } ++ ++ pub struct input_mask { ++ pub type_: ::__u32, ++ pub codes_size: ::__u32, ++ pub codes_ptr: ::__u64, ++ } ++ ++ pub struct ff_replay { ++ pub length: ::__u16, ++ pub delay: ::__u16, ++ } ++ ++ pub struct ff_trigger { ++ pub button: ::__u16, ++ pub interval: ::__u16, ++ } ++ ++ pub struct ff_envelope { ++ pub attack_length: ::__u16, ++ pub attack_level: ::__u16, ++ pub fade_length: ::__u16, ++ pub fade_level: ::__u16, ++ } ++ ++ pub struct ff_constant_effect { ++ pub level: ::__s16, ++ pub envelope: ff_envelope, ++ } ++ ++ pub struct ff_ramp_effect { ++ pub start_level: ::__s16, ++ pub end_level: ::__s16, ++ pub envelope: ff_envelope, ++ } ++ ++ pub struct ff_condition_effect { ++ pub right_saturation: ::__u16, ++ pub left_saturation: ::__u16, ++ ++ pub right_coeff: ::__s16, ++ pub left_coeff: ::__s16, ++ ++ pub deadband: ::__u16, ++ pub center: ::__s16, ++ } ++ ++ pub struct ff_periodic_effect { ++ pub waveform: ::__u16, ++ pub period: ::__u16, ++ pub magnitude: ::__s16, ++ pub offset: ::__s16, ++ pub phase: ::__u16, ++ ++ pub envelope: ff_envelope, ++ ++ pub custom_len: ::__u32, ++ pub custom_data: *mut ::__s16, ++ } ++ ++ pub struct ff_rumble_effect { ++ pub strong_magnitude: ::__u16, ++ pub weak_magnitude: ::__u16, ++ } ++ ++ pub struct ff_effect { ++ pub type_: ::__u16, ++ pub id: ::__s16, ++ pub direction: ::__u16, ++ pub trigger: ff_trigger, ++ pub replay: ff_replay, ++ // FIXME this is actually a union ++ #[cfg(target_pointer_width = "64")] ++ pub u: [u64; 4], ++ #[cfg(target_pointer_width = "32")] ++ pub u: [u32; 7], ++ } ++ ++ // linux/uinput.h ++ pub struct uinput_ff_upload { ++ pub request_id: ::__u32, ++ pub retval: ::__s32, ++ pub effect: ff_effect, ++ pub old: ff_effect, ++ } ++ ++ pub struct uinput_ff_erase { ++ pub request_id: ::__u32, ++ pub retval: ::__s32, ++ pub effect_id: ::__u32, ++ } ++ ++ pub struct uinput_abs_setup { ++ pub code: ::__u16, ++ pub absinfo: input_absinfo, ++ } ++ ++ pub struct option { ++ pub name: *const ::c_char, ++ pub has_arg: ::c_int, ++ pub flag: *mut ::c_int, ++ pub val: ::c_int, ++ } + } + + s_no_extra_traits! { +@@ -370,6 +551,22 @@ s_no_extra_traits! { + pub salg_name: [::c_uchar; 64], + } + ++ pub struct uinput_setup { ++ pub id: input_id, ++ pub name: [::c_char; UINPUT_MAX_NAME_SIZE], ++ pub ff_effects_max: ::__u32, ++ } ++ ++ pub struct uinput_user_dev { ++ pub name: [::c_char; UINPUT_MAX_NAME_SIZE], ++ pub id: input_id, ++ pub ff_effects_max: ::__u32, ++ pub absmax: [::__s32; ABS_CNT], ++ pub absmin: [::__s32; ABS_CNT], ++ pub absfuzz: [::__s32; ABS_CNT], ++ pub absflat: [::__s32; ABS_CNT], ++ } ++ + /// WARNING: The `PartialEq`, `Eq` and `Hash` implementations of this + /// type are unsound and will be removed in the future. + #[deprecated( +@@ -381,6 +578,12 @@ s_no_extra_traits! { + pub ivlen: u32, + pub iv: [::c_uchar; 0], + } ++ ++ pub struct prop_info { ++ __name: [::c_char; 32], ++ __serial: ::c_uint, ++ __value: [[::c_char; 4]; 23], ++ } + } + + cfg_if! { +@@ -662,6 +865,72 @@ cfg_if! { + } + } + ++ impl PartialEq for uinput_setup { ++ fn eq(&self, other: &uinput_setup) -> bool { ++ self.id == other.id ++ && self.name[..] == other.name[..] ++ && self.ff_effects_max == other.ff_effects_max ++ } ++ } ++ impl Eq for uinput_setup {} ++ ++ impl ::fmt::Debug for uinput_setup { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("uinput_setup") ++ .field("id", &self.id) ++ .field("name", &&self.name[..]) ++ .field("ff_effects_max", &self.ff_effects_max) ++ .finish() ++ } ++ } ++ ++ impl ::hash::Hash for uinput_setup { ++ fn hash(&self, state: &mut H) { ++ self.id.hash(state); ++ self.name.hash(state); ++ self.ff_effects_max.hash(state); ++ } ++ } ++ ++ impl PartialEq for uinput_user_dev { ++ fn eq(&self, other: &uinput_user_dev) -> bool { ++ self.name[..] == other.name[..] ++ && self.id == other.id ++ && self.ff_effects_max == other.ff_effects_max ++ && self.absmax[..] == other.absmax[..] ++ && self.absmin[..] == other.absmin[..] ++ && self.absfuzz[..] == other.absfuzz[..] ++ && self.absflat[..] == other.absflat[..] ++ } ++ } ++ impl Eq for uinput_user_dev {} ++ ++ impl ::fmt::Debug for uinput_user_dev { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("uinput_setup") ++ .field("name", &&self.name[..]) ++ .field("id", &self.id) ++ .field("ff_effects_max", &self.ff_effects_max) ++ .field("absmax", &&self.absmax[..]) ++ .field("absmin", &&self.absmin[..]) ++ .field("absfuzz", &&self.absfuzz[..]) ++ .field("absflat", &&self.absflat[..]) ++ .finish() ++ } ++ } ++ ++ impl ::hash::Hash for uinput_user_dev { ++ fn hash(&self, state: &mut H) { ++ self.name.hash(state); ++ self.id.hash(state); ++ self.ff_effects_max.hash(state); ++ self.absmax.hash(state); ++ self.absmin.hash(state); ++ self.absfuzz.hash(state); ++ self.absflat.hash(state); ++ } ++ } ++ + #[allow(deprecated)] + impl af_alg_iv { + fn as_slice(&self) -> &[u8] { +@@ -699,6 +968,24 @@ cfg_if! { + self.as_slice().hash(state); + } + } ++ ++ impl PartialEq for prop_info { ++ fn eq(&self, other: &prop_info) -> bool { ++ self.__name == other.__name && ++ self.__serial == other.__serial && ++ self.__value == other.__value ++ } ++ } ++ impl Eq for prop_info {} ++ impl ::fmt::Debug for prop_info { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("prop_info") ++ .field("__name", &self.__name) ++ .field("__serial", &self.__serial) ++ .field("__value", &self.__value) ++ .finish() ++ } ++ } + } + } + +@@ -727,9 +1014,6 @@ pub const EPROTO: ::c_int = 71; + pub const EDOTDOT: ::c_int = 73; + + pub const EPOLL_CLOEXEC: ::c_int = 0x80000; +-pub const EPOLLONESHOT: ::c_int = 0x40000000; +-pub const EPOLLRDHUP: ::c_int = 0x00002000; +-pub const EPOLLWAKEUP: ::c_int = 0x20000000; + + // sys/eventfd.h + pub const EFD_SEMAPHORE: ::c_int = 0x1; +@@ -744,6 +1028,8 @@ pub const TFD_TIMER_CANCEL_ON_SET: ::c_int = 2; + + pub const USER_PROCESS: ::c_short = 7; + ++pub const _POSIX_VDISABLE: ::cc_t = 0; ++ + // linux/falloc.h + pub const FALLOC_FL_KEEP_SIZE: ::c_int = 0x01; + pub const FALLOC_FL_PUNCH_HOLE: ::c_int = 0x02; +@@ -922,6 +1208,12 @@ pub const F_TEST: ::c_int = 3; + pub const F_TLOCK: ::c_int = 2; + pub const F_ULOCK: ::c_int = 0; + ++pub const F_SEAL_FUTURE_WRITE: ::c_int = 0x0010; ++ ++pub const IFF_LOWER_UP: ::c_int = 0x10000; ++pub const IFF_DORMANT: ::c_int = 0x20000; ++pub const IFF_ECHO: ::c_int = 0x40000; ++ + pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; + pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1; + pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2; +@@ -1140,6 +1432,9 @@ pub const SO_SNDLOWAT: ::c_int = 19; + pub const SO_RCVTIMEO: ::c_int = 20; + pub const SO_SNDTIMEO: ::c_int = 21; + pub const SO_BINDTODEVICE: ::c_int = 25; ++pub const SO_ATTACH_FILTER: ::c_int = 26; ++pub const SO_DETACH_FILTER: ::c_int = 27; ++pub const SO_GET_FILTER: ::c_int = SO_ATTACH_FILTER; + pub const SO_TIMESTAMP: ::c_int = 29; + pub const SO_ACCEPTCONN: ::c_int = 30; + pub const SO_PEERSEC: ::c_int = 31; +@@ -1190,33 +1485,6 @@ pub const TOSTOP: ::tcflag_t = 0x00000100; + pub const FLUSHO: ::tcflag_t = 0x00001000; + pub const EXTPROC: ::tcflag_t = 0o200000; + +-pub const ADFS_SUPER_MAGIC: ::c_long = 0x0000adf5; +-pub const AFFS_SUPER_MAGIC: ::c_long = 0x0000adff; +-pub const CODA_SUPER_MAGIC: ::c_long = 0x73757245; +-pub const CRAMFS_MAGIC: ::c_long = 0x28cd3d45; +-pub const EFS_SUPER_MAGIC: ::c_long = 0x00414a53; +-pub const EXT2_SUPER_MAGIC: ::c_long = 0x0000ef53; +-pub const EXT3_SUPER_MAGIC: ::c_long = 0x0000ef53; +-pub const EXT4_SUPER_MAGIC: ::c_long = 0x0000ef53; +-pub const HPFS_SUPER_MAGIC: ::c_long = 0xf995e849; +-pub const HUGETLBFS_MAGIC: ::c_long = 0x958458f6; +-pub const ISOFS_SUPER_MAGIC: ::c_long = 0x00009660; +-pub const JFFS2_SUPER_MAGIC: ::c_long = 0x000072b6; +-pub const MINIX_SUPER_MAGIC: ::c_long = 0x0000137f; +-pub const MINIX_SUPER_MAGIC2: ::c_long = 0x0000138f; +-pub const MINIX2_SUPER_MAGIC: ::c_long = 0x00002468; +-pub const MINIX2_SUPER_MAGIC2: ::c_long = 0x00002478; +-pub const MSDOS_SUPER_MAGIC: ::c_long = 0x00004d44; +-pub const NCP_SUPER_MAGIC: ::c_long = 0x0000564c; +-pub const NFS_SUPER_MAGIC: ::c_long = 0x00006969; +-pub const OPENPROM_SUPER_MAGIC: ::c_long = 0x00009fa1; +-pub const PROC_SUPER_MAGIC: ::c_long = 0x00009fa0; +-pub const QNX4_SUPER_MAGIC: ::c_long = 0x0000002f; +-pub const REISERFS_SUPER_MAGIC: ::c_long = 0x52654973; +-pub const SMB_SUPER_MAGIC: ::c_long = 0x0000517b; +-pub const TMPFS_MAGIC: ::c_long = 0x01021994; +-pub const USBDEVICE_SUPER_MAGIC: ::c_long = 0x00009fa2; +- + pub const MAP_HUGETLB: ::c_int = 0x040000; + + pub const PTRACE_TRACEME: ::c_int = 0; +@@ -1229,6 +1497,8 @@ pub const PTRACE_POKEUSER: ::c_int = 6; + pub const PTRACE_CONT: ::c_int = 7; + pub const PTRACE_KILL: ::c_int = 8; + pub const PTRACE_SINGLESTEP: ::c_int = 9; ++pub const PTRACE_GETREGS: ::c_int = 12; ++pub const PTRACE_SETREGS: ::c_int = 13; + pub const PTRACE_ATTACH: ::c_int = 16; + pub const PTRACE_DETACH: ::c_int = 17; + pub const PTRACE_SYSCALL: ::c_int = 24; +@@ -1236,6 +1506,8 @@ pub const PTRACE_SETOPTIONS: ::c_int = 0x4200; + pub const PTRACE_GETEVENTMSG: ::c_int = 0x4201; + pub const PTRACE_GETSIGINFO: ::c_int = 0x4202; + pub const PTRACE_SETSIGINFO: ::c_int = 0x4203; ++pub const PTRACE_GETREGSET: ::c_int = 0x4204; ++pub const PTRACE_SETREGSET: ::c_int = 0x4205; + + pub const PTRACE_EVENT_STOP: ::c_int = 128; + +@@ -1274,6 +1546,10 @@ pub const TCGETS: ::c_int = 0x5401; + pub const TCSETS: ::c_int = 0x5402; + pub const TCSETSW: ::c_int = 0x5403; + pub const TCSETSF: ::c_int = 0x5404; ++pub const TCGETS2: ::c_int = 0x802c542a; ++pub const TCSETS2: ::c_int = 0x402c542b; ++pub const TCSETSW2: ::c_int = 0x402c542c; ++pub const TCSETSF2: ::c_int = 0x402c542d; + pub const TCGETA: ::c_int = 0x5405; + pub const TCSETA: ::c_int = 0x5406; + pub const TCSETAW: ::c_int = 0x5407; +@@ -1303,6 +1579,23 @@ pub const FIONREAD: ::c_int = 0x541B; + pub const TIOCCONS: ::c_int = 0x541D; + pub const TIOCSBRK: ::c_int = 0x5427; + pub const TIOCCBRK: ::c_int = 0x5428; ++cfg_if! { ++ if #[cfg(any(target_arch = "x86", ++ target_arch = "x86_64", ++ target_arch = "arm", ++ target_arch = "aarch64", ++ target_arch = "riscv64", ++ target_arch = "s390x"))] { ++ pub const FICLONE: ::c_int = 0x40049409; ++ pub const FICLONERANGE: ::c_int = 0x4020940D; ++ } else if #[cfg(any(target_arch = "mips", ++ target_arch = "mips64", ++ target_arch = "powerpc", ++ target_arch = "powerpc64"))] { ++ pub const FICLONE: ::c_int = 0x80049409; ++ pub const FICLONERANGE: ::c_int = 0x8020940D; ++ } ++} + + pub const ST_RDONLY: ::c_ulong = 1; + pub const ST_NOSUID: ::c_ulong = 2; +@@ -1330,6 +1623,14 @@ pub const AI_ADDRCONFIG: ::c_int = 0x00000400; + pub const AI_V4MAPPED: ::c_int = 0x00000800; + pub const AI_DEFAULT: ::c_int = AI_V4MAPPED_CFG | AI_ADDRCONFIG; + ++// linux/kexec.h ++pub const KEXEC_ON_CRASH: ::c_int = 0x00000001; ++pub const KEXEC_PRESERVE_CONTEXT: ::c_int = 0x00000002; ++pub const KEXEC_ARCH_MASK: ::c_int = 0xffff0000; ++pub const KEXEC_FILE_UNLOAD: ::c_int = 0x00000001; ++pub const KEXEC_FILE_ON_CRASH: ::c_int = 0x00000002; ++pub const KEXEC_FILE_NO_INITRAMFS: ::c_int = 0x00000004; ++ + pub const LINUX_REBOOT_MAGIC1: ::c_int = 0xfee1dead; + pub const LINUX_REBOOT_MAGIC2: ::c_int = 672274793; + pub const LINUX_REBOOT_MAGIC2A: ::c_int = 85072278; +@@ -1467,6 +1768,12 @@ pub const B2500000: ::speed_t = 0o010014; + pub const B3000000: ::speed_t = 0o010015; + pub const B3500000: ::speed_t = 0o010016; + pub const B4000000: ::speed_t = 0o010017; ++pub const IBSHIFT: ::tcflag_t = 16; ++ ++pub const BLKIOMIN: ::c_int = 0x1278; ++pub const BLKIOOPT: ::c_int = 0x1279; ++pub const BLKSSZGET: ::c_int = 0x1268; ++pub const BLKPBSZGET: ::c_int = 0x127B; + + pub const EAI_AGAIN: ::c_int = 2; + pub const EAI_BADFLAGS: ::c_int = 3; +@@ -1720,14 +2027,39 @@ pub const NETLINK_BROADCAST_ERROR: ::c_int = 4; + pub const NETLINK_NO_ENOBUFS: ::c_int = 5; + pub const NETLINK_RX_RING: ::c_int = 6; + pub const NETLINK_TX_RING: ::c_int = 7; ++pub const NETLINK_LISTEN_ALL_NSID: ::c_int = 8; ++pub const NETLINK_LIST_MEMBERSHIPS: ::c_int = 9; ++pub const NETLINK_CAP_ACK: ::c_int = 10; ++pub const NETLINK_EXT_ACK: ::c_int = 11; ++pub const NETLINK_GET_STRICT_CHK: ::c_int = 12; + + pub const GRND_NONBLOCK: ::c_uint = 0x0001; + pub const GRND_RANDOM: ::c_uint = 0x0002; ++pub const GRND_INSECURE: ::c_uint = 0x0004; + + pub const SECCOMP_MODE_DISABLED: ::c_uint = 0; + pub const SECCOMP_MODE_STRICT: ::c_uint = 1; + pub const SECCOMP_MODE_FILTER: ::c_uint = 2; + ++pub const SECCOMP_FILTER_FLAG_TSYNC: ::c_ulong = 1; ++pub const SECCOMP_FILTER_FLAG_LOG: ::c_ulong = 2; ++pub const SECCOMP_FILTER_FLAG_SPEC_ALLOW: ::c_ulong = 4; ++pub const SECCOMP_FILTER_FLAG_NEW_LISTENER: ::c_ulong = 8; ++ ++pub const SECCOMP_RET_ACTION_FULL: ::c_uint = 0xffff0000; ++pub const SECCOMP_RET_ACTION: ::c_uint = 0x7fff0000; ++pub const SECCOMP_RET_DATA: ::c_uint = 0x0000ffff; ++ ++pub const SECCOMP_RET_KILL_PROCESS: ::c_uint = 0x80000000; ++pub const SECCOMP_RET_KILL_THREAD: ::c_uint = 0x00000000; ++pub const SECCOMP_RET_KILL: ::c_uint = SECCOMP_RET_KILL_THREAD; ++pub const SECCOMP_RET_TRAP: ::c_uint = 0x00030000; ++pub const SECCOMP_RET_ERRNO: ::c_uint = 0x00050000; ++pub const SECCOMP_RET_USER_NOTIF: ::c_uint = 0x7fc00000; ++pub const SECCOMP_RET_TRACE: ::c_uint = 0x7ff00000; ++pub const SECCOMP_RET_LOG: ::c_uint = 0x7ffc0000; ++pub const SECCOMP_RET_ALLOW: ::c_uint = 0x7fff0000; ++ + pub const NLA_F_NESTED: ::c_int = 1 << 15; + pub const NLA_F_NET_BYTEORDER: ::c_int = 1 << 14; + pub const NLA_TYPE_MASK: ::c_int = !(NLA_F_NESTED | NLA_F_NET_BYTEORDER); +@@ -1780,6 +2112,43 @@ pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; + pub const MFD_CLOEXEC: ::c_uint = 0x0001; + pub const MFD_ALLOW_SEALING: ::c_uint = 0x0002; + pub const MFD_HUGETLB: ::c_uint = 0x0004; ++pub const MFD_HUGE_64KB: ::c_uint = 0x40000000; ++pub const MFD_HUGE_512KB: ::c_uint = 0x4c000000; ++pub const MFD_HUGE_1MB: ::c_uint = 0x50000000; ++pub const MFD_HUGE_2MB: ::c_uint = 0x54000000; ++pub const MFD_HUGE_8MB: ::c_uint = 0x5c000000; ++pub const MFD_HUGE_16MB: ::c_uint = 0x60000000; ++pub const MFD_HUGE_32MB: ::c_uint = 0x64000000; ++pub const MFD_HUGE_256MB: ::c_uint = 0x70000000; ++pub const MFD_HUGE_512MB: ::c_uint = 0x74000000; ++pub const MFD_HUGE_1GB: ::c_uint = 0x78000000; ++pub const MFD_HUGE_2GB: ::c_uint = 0x7c000000; ++pub const MFD_HUGE_16GB: ::c_uint = 0x88000000; ++pub const MFD_HUGE_MASK: ::c_uint = 63; ++pub const MFD_HUGE_SHIFT: ::c_uint = 26; ++ ++// these are used in the p_type field of Elf32_Phdr and Elf64_Phdr, which has ++// the type Elf32Word and Elf64Word respectively. Luckily, both of those are u32 ++// so we can use that type here to avoid having to cast. ++pub const PT_NULL: u32 = 0; ++pub const PT_LOAD: u32 = 1; ++pub const PT_DYNAMIC: u32 = 2; ++pub const PT_INTERP: u32 = 3; ++pub const PT_NOTE: u32 = 4; ++pub const PT_SHLIB: u32 = 5; ++pub const PT_PHDR: u32 = 6; ++pub const PT_TLS: u32 = 7; ++pub const PT_LOOS: u32 = 0x60000000; ++pub const PT_GNU_EH_FRAME: u32 = 0x6474e550; ++pub const PT_GNU_STACK: u32 = 0x6474e551; ++pub const PT_GNU_RELRO: u32 = 0x6474e552; ++pub const PT_HIOS: u32 = 0x6fffffff; ++pub const PT_LOPROC: u32 = 0x70000000; ++pub const PT_HIPROC: u32 = 0x7fffffff; ++ ++// uapi/linux/mount.h ++pub const OPEN_TREE_CLONE: ::c_uint = 0x01; ++pub const OPEN_TREE_CLOEXEC: ::c_uint = O_CLOEXEC as ::c_uint; + + // linux/netfilter.h + pub const NF_DROP: ::c_int = 0; +@@ -2049,9 +2418,52 @@ pub const NFT_TRACETYPE_RULE: ::c_int = 3; + pub const NFT_NG_INCREMENTAL: ::c_int = 0; + pub const NFT_NG_RANDOM: ::c_int = 1; + ++// linux/input.h ++pub const FF_MAX: ::__u16 = 0x7f; ++pub const FF_CNT: usize = FF_MAX as usize + 1; ++ ++// linux/input-event-codes.h ++pub const INPUT_PROP_MAX: ::__u16 = 0x1f; ++pub const INPUT_PROP_CNT: usize = INPUT_PROP_MAX as usize + 1; ++pub const EV_MAX: ::__u16 = 0x1f; ++pub const EV_CNT: usize = EV_MAX as usize + 1; ++pub const SYN_MAX: ::__u16 = 0xf; ++pub const SYN_CNT: usize = SYN_MAX as usize + 1; ++pub const KEY_MAX: ::__u16 = 0x2ff; ++pub const KEY_CNT: usize = KEY_MAX as usize + 1; ++pub const REL_MAX: ::__u16 = 0x0f; ++pub const REL_CNT: usize = REL_MAX as usize + 1; ++pub const ABS_MAX: ::__u16 = 0x3f; ++pub const ABS_CNT: usize = ABS_MAX as usize + 1; ++pub const SW_MAX: ::__u16 = 0x0f; ++pub const SW_CNT: usize = SW_MAX as usize + 1; ++pub const MSC_MAX: ::__u16 = 0x07; ++pub const MSC_CNT: usize = MSC_MAX as usize + 1; ++pub const LED_MAX: ::__u16 = 0x0f; ++pub const LED_CNT: usize = LED_MAX as usize + 1; ++pub const REP_MAX: ::__u16 = 0x01; ++pub const REP_CNT: usize = REP_MAX as usize + 1; ++pub const SND_MAX: ::__u16 = 0x07; ++pub const SND_CNT: usize = SND_MAX as usize + 1; ++ ++// linux/uinput.h ++pub const UINPUT_VERSION: ::c_uint = 5; ++pub const UINPUT_MAX_NAME_SIZE: usize = 80; ++ ++// bionic/libc/kernel/uapi/linux/if_tun.h + pub const IFF_TUN: ::c_int = 0x0001; + pub const IFF_TAP: ::c_int = 0x0002; ++pub const IFF_NAPI: ::c_int = 0x0010; ++pub const IFF_NAPI_FRAGS: ::c_int = 0x0020; + pub const IFF_NO_PI: ::c_int = 0x1000; ++pub const IFF_ONE_QUEUE: ::c_int = 0x2000; ++pub const IFF_VNET_HDR: ::c_int = 0x4000; ++pub const IFF_TUN_EXCL: ::c_int = 0x8000; ++pub const IFF_MULTI_QUEUE: ::c_int = 0x0100; ++pub const IFF_ATTACH_QUEUE: ::c_int = 0x0200; ++pub const IFF_DETACH_QUEUE: ::c_int = 0x0400; ++pub const IFF_PERSIST: ::c_int = 0x0800; ++pub const IFF_NOFILTER: ::c_int = 0x1000; + + // start android/platform/bionic/libc/kernel/uapi/linux/if_ether.h + // from https://android.googlesource.com/ +@@ -2213,6 +2625,9 @@ pub const ALG_SET_AEAD_AUTHSIZE: ::c_int = 5; + pub const ALG_OP_DECRYPT: ::c_int = 0; + pub const ALG_OP_ENCRYPT: ::c_int = 1; + ++// sys/mman.h ++pub const MLOCK_ONFAULT: ::c_int = 0x01; ++ + // uapi/linux/vm_sockets.h + pub const VMADDR_CID_ANY: ::c_uint = 0xFFFFFFFF; + pub const VMADDR_CID_HYPERVISOR: ::c_uint = 0; +@@ -2240,10 +2655,10 @@ pub const IN_Q_OVERFLOW: u32 = 0x0000_4000; + pub const IN_IGNORED: u32 = 0x0000_8000; + pub const IN_ONLYDIR: u32 = 0x0100_0000; + pub const IN_DONT_FOLLOW: u32 = 0x0200_0000; +-// pub const IN_EXCL_UNLINK: u32 = 0x0400_0000; ++pub const IN_EXCL_UNLINK: u32 = 0x0400_0000; + +-// pub const IN_MASK_CREATE: u32 = 0x1000_0000; +-// pub const IN_MASK_ADD: u32 = 0x2000_0000; ++pub const IN_MASK_CREATE: u32 = 0x1000_0000; ++pub const IN_MASK_ADD: u32 = 0x2000_0000; + pub const IN_ISDIR: u32 = 0x4000_0000; + pub const IN_ONESHOT: u32 = 0x8000_0000; + +@@ -2338,6 +2753,32 @@ pub const SCHED_BATCH: ::c_int = 3; + pub const SCHED_IDLE: ::c_int = 5; + pub const SCHED_DEADLINE: ::c_int = 6; + ++pub const SCHED_RESET_ON_FORK: ::c_int = 0x40000000; ++ ++pub const CLONE_PIDFD: ::c_int = 0x1000; ++ ++// linux/membarrier.h ++pub const MEMBARRIER_CMD_QUERY: ::c_int = 0; ++pub const MEMBARRIER_CMD_GLOBAL: ::c_int = 1 << 0; ++pub const MEMBARRIER_CMD_GLOBAL_EXPEDITED: ::c_int = 1 << 1; ++pub const MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED: ::c_int = 1 << 2; ++pub const MEMBARRIER_CMD_PRIVATE_EXPEDITED: ::c_int = 1 << 3; ++pub const MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED: ::c_int = 1 << 4; ++pub const MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE: ::c_int = 1 << 5; ++pub const MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE: ::c_int = 1 << 6; ++pub const MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ: ::c_int = 1 << 7; ++pub const MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ: ::c_int = 1 << 8; ++ ++// linux/mempolicy.h ++pub const MPOL_DEFAULT: ::c_int = 0; ++pub const MPOL_PREFERRED: ::c_int = 1; ++pub const MPOL_BIND: ::c_int = 2; ++pub const MPOL_INTERLEAVE: ::c_int = 3; ++pub const MPOL_LOCAL: ::c_int = 4; ++pub const MPOL_F_NUMA_BALANCING: ::c_int = 1 << 13; ++pub const MPOL_F_RELATIVE_NODES: ::c_int = 1 << 14; ++pub const MPOL_F_STATIC_NODES: ::c_int = 1 << 15; ++ + // bits/seek_constants.h + pub const SEEK_DATA: ::c_int = 3; + pub const SEEK_HOLE: ::c_int = 4; +@@ -2348,8 +2789,242 @@ pub const AF_VSOCK: ::c_int = 40; + pub const PF_NFC: ::c_int = AF_NFC; + pub const PF_VSOCK: ::c_int = AF_VSOCK; + ++pub const SOMAXCONN: ::c_int = 128; ++ ++// sys/prctl.h ++pub const PR_SET_PDEATHSIG: ::c_int = 1; ++pub const PR_GET_PDEATHSIG: ::c_int = 2; ++pub const PR_GET_SECUREBITS: ::c_int = 27; ++pub const PR_SET_SECUREBITS: ::c_int = 28; ++ + // sys/system_properties.h + pub const PROP_VALUE_MAX: ::c_int = 92; ++pub const PROP_NAME_MAX: ::c_int = 32; ++ ++// sys/prctl.h ++pub const PR_SET_VMA: ::c_int = 0x53564d41; ++pub const PR_SET_VMA_ANON_NAME: ::c_int = 0; ++pub const PR_SET_NO_NEW_PRIVS: ::c_int = 38; ++pub const PR_GET_NO_NEW_PRIVS: ::c_int = 39; ++pub const PR_GET_SECCOMP: ::c_int = 21; ++pub const PR_SET_SECCOMP: ::c_int = 22; ++pub const PR_GET_TIMING: ::c_int = 13; ++pub const PR_SET_TIMING: ::c_int = 14; ++pub const PR_TIMING_STATISTICAL: ::c_int = 0; ++pub const PR_TIMING_TIMESTAMP: ::c_int = 1; ++ ++// linux/if_addr.h ++pub const IFA_UNSPEC: ::c_ushort = 0; ++pub const IFA_ADDRESS: ::c_ushort = 1; ++pub const IFA_LOCAL: ::c_ushort = 2; ++pub const IFA_LABEL: ::c_ushort = 3; ++pub const IFA_BROADCAST: ::c_ushort = 4; ++pub const IFA_ANYCAST: ::c_ushort = 5; ++pub const IFA_CACHEINFO: ::c_ushort = 6; ++pub const IFA_MULTICAST: ::c_ushort = 7; ++ ++pub const IFA_F_SECONDARY: u32 = 0x01; ++pub const IFA_F_TEMPORARY: u32 = 0x01; ++pub const IFA_F_NODAD: u32 = 0x02; ++pub const IFA_F_OPTIMISTIC: u32 = 0x04; ++pub const IFA_F_DADFAILED: u32 = 0x08; ++pub const IFA_F_HOMEADDRESS: u32 = 0x10; ++pub const IFA_F_DEPRECATED: u32 = 0x20; ++pub const IFA_F_TENTATIVE: u32 = 0x40; ++pub const IFA_F_PERMANENT: u32 = 0x80; ++ ++// linux/if_link.h ++pub const IFLA_UNSPEC: ::c_ushort = 0; ++pub const IFLA_ADDRESS: ::c_ushort = 1; ++pub const IFLA_BROADCAST: ::c_ushort = 2; ++pub const IFLA_IFNAME: ::c_ushort = 3; ++pub const IFLA_MTU: ::c_ushort = 4; ++pub const IFLA_LINK: ::c_ushort = 5; ++pub const IFLA_QDISC: ::c_ushort = 6; ++pub const IFLA_STATS: ::c_ushort = 7; ++pub const IFLA_COST: ::c_ushort = 8; ++pub const IFLA_PRIORITY: ::c_ushort = 9; ++pub const IFLA_MASTER: ::c_ushort = 10; ++pub const IFLA_WIRELESS: ::c_ushort = 11; ++pub const IFLA_PROTINFO: ::c_ushort = 12; ++pub const IFLA_TXQLEN: ::c_ushort = 13; ++pub const IFLA_MAP: ::c_ushort = 14; ++pub const IFLA_WEIGHT: ::c_ushort = 15; ++pub const IFLA_OPERSTATE: ::c_ushort = 16; ++pub const IFLA_LINKMODE: ::c_ushort = 17; ++pub const IFLA_LINKINFO: ::c_ushort = 18; ++pub const IFLA_NET_NS_PID: ::c_ushort = 19; ++pub const IFLA_IFALIAS: ::c_ushort = 20; ++pub const IFLA_NUM_VF: ::c_ushort = 21; ++pub const IFLA_VFINFO_LIST: ::c_ushort = 22; ++pub const IFLA_STATS64: ::c_ushort = 23; ++pub const IFLA_VF_PORTS: ::c_ushort = 24; ++pub const IFLA_PORT_SELF: ::c_ushort = 25; ++pub const IFLA_AF_SPEC: ::c_ushort = 26; ++pub const IFLA_GROUP: ::c_ushort = 27; ++pub const IFLA_NET_NS_FD: ::c_ushort = 28; ++pub const IFLA_EXT_MASK: ::c_ushort = 29; ++pub const IFLA_PROMISCUITY: ::c_ushort = 30; ++pub const IFLA_NUM_TX_QUEUES: ::c_ushort = 31; ++pub const IFLA_NUM_RX_QUEUES: ::c_ushort = 32; ++pub const IFLA_CARRIER: ::c_ushort = 33; ++pub const IFLA_PHYS_PORT_ID: ::c_ushort = 34; ++pub const IFLA_CARRIER_CHANGES: ::c_ushort = 35; ++pub const IFLA_PHYS_SWITCH_ID: ::c_ushort = 36; ++pub const IFLA_LINK_NETNSID: ::c_ushort = 37; ++pub const IFLA_PHYS_PORT_NAME: ::c_ushort = 38; ++pub const IFLA_PROTO_DOWN: ::c_ushort = 39; ++pub const IFLA_GSO_MAX_SEGS: ::c_ushort = 40; ++pub const IFLA_GSO_MAX_SIZE: ::c_ushort = 41; ++pub const IFLA_PAD: ::c_ushort = 42; ++pub const IFLA_XDP: ::c_ushort = 43; ++pub const IFLA_EVENT: ::c_ushort = 44; ++pub const IFLA_NEW_NETNSID: ::c_ushort = 45; ++pub const IFLA_IF_NETNSID: ::c_ushort = 46; ++pub const IFLA_TARGET_NETNSID: ::c_ushort = IFLA_IF_NETNSID; ++pub const IFLA_CARRIER_UP_COUNT: ::c_ushort = 47; ++pub const IFLA_CARRIER_DOWN_COUNT: ::c_ushort = 48; ++pub const IFLA_NEW_IFINDEX: ::c_ushort = 49; ++pub const IFLA_MIN_MTU: ::c_ushort = 50; ++pub const IFLA_MAX_MTU: ::c_ushort = 51; ++ ++pub const IFLA_INFO_UNSPEC: ::c_ushort = 0; ++pub const IFLA_INFO_KIND: ::c_ushort = 1; ++pub const IFLA_INFO_DATA: ::c_ushort = 2; ++pub const IFLA_INFO_XSTATS: ::c_ushort = 3; ++pub const IFLA_INFO_SLAVE_KIND: ::c_ushort = 4; ++pub const IFLA_INFO_SLAVE_DATA: ::c_ushort = 5; ++ ++// linux/rtnetlink.h ++pub const TCA_UNSPEC: ::c_ushort = 0; ++pub const TCA_KIND: ::c_ushort = 1; ++pub const TCA_OPTIONS: ::c_ushort = 2; ++pub const TCA_STATS: ::c_ushort = 3; ++pub const TCA_XSTATS: ::c_ushort = 4; ++pub const TCA_RATE: ::c_ushort = 5; ++pub const TCA_FCNT: ::c_ushort = 6; ++pub const TCA_STATS2: ::c_ushort = 7; ++pub const TCA_STAB: ::c_ushort = 8; ++ ++pub const RTM_NEWLINK: u16 = 16; ++pub const RTM_DELLINK: u16 = 17; ++pub const RTM_GETLINK: u16 = 18; ++pub const RTM_SETLINK: u16 = 19; ++pub const RTM_NEWADDR: u16 = 20; ++pub const RTM_DELADDR: u16 = 21; ++pub const RTM_GETADDR: u16 = 22; ++pub const RTM_NEWROUTE: u16 = 24; ++pub const RTM_DELROUTE: u16 = 25; ++pub const RTM_GETROUTE: u16 = 26; ++pub const RTM_NEWNEIGH: u16 = 28; ++pub const RTM_DELNEIGH: u16 = 29; ++pub const RTM_GETNEIGH: u16 = 30; ++pub const RTM_NEWRULE: u16 = 32; ++pub const RTM_DELRULE: u16 = 33; ++pub const RTM_GETRULE: u16 = 34; ++pub const RTM_NEWQDISC: u16 = 36; ++pub const RTM_DELQDISC: u16 = 37; ++pub const RTM_GETQDISC: u16 = 38; ++pub const RTM_NEWTCLASS: u16 = 40; ++pub const RTM_DELTCLASS: u16 = 41; ++pub const RTM_GETTCLASS: u16 = 42; ++pub const RTM_NEWTFILTER: u16 = 44; ++pub const RTM_DELTFILTER: u16 = 45; ++pub const RTM_GETTFILTER: u16 = 46; ++pub const RTM_NEWACTION: u16 = 48; ++pub const RTM_DELACTION: u16 = 49; ++pub const RTM_GETACTION: u16 = 50; ++pub const RTM_NEWPREFIX: u16 = 52; ++pub const RTM_GETMULTICAST: u16 = 58; ++pub const RTM_GETANYCAST: u16 = 62; ++pub const RTM_NEWNEIGHTBL: u16 = 64; ++pub const RTM_GETNEIGHTBL: u16 = 66; ++pub const RTM_SETNEIGHTBL: u16 = 67; ++pub const RTM_NEWNDUSEROPT: u16 = 68; ++pub const RTM_NEWADDRLABEL: u16 = 72; ++pub const RTM_DELADDRLABEL: u16 = 73; ++pub const RTM_GETADDRLABEL: u16 = 74; ++pub const RTM_GETDCB: u16 = 78; ++pub const RTM_SETDCB: u16 = 79; ++pub const RTM_NEWNETCONF: u16 = 80; ++pub const RTM_GETNETCONF: u16 = 82; ++pub const RTM_NEWMDB: u16 = 84; ++pub const RTM_DELMDB: u16 = 85; ++pub const RTM_GETMDB: u16 = 86; ++pub const RTM_NEWNSID: u16 = 88; ++pub const RTM_DELNSID: u16 = 89; ++pub const RTM_GETNSID: u16 = 90; ++ ++pub const RTM_F_NOTIFY: ::c_uint = 0x100; ++pub const RTM_F_CLONED: ::c_uint = 0x200; ++pub const RTM_F_EQUALIZE: ::c_uint = 0x400; ++pub const RTM_F_PREFIX: ::c_uint = 0x800; ++ ++pub const RTA_UNSPEC: ::c_ushort = 0; ++pub const RTA_DST: ::c_ushort = 1; ++pub const RTA_SRC: ::c_ushort = 2; ++pub const RTA_IIF: ::c_ushort = 3; ++pub const RTA_OIF: ::c_ushort = 4; ++pub const RTA_GATEWAY: ::c_ushort = 5; ++pub const RTA_PRIORITY: ::c_ushort = 6; ++pub const RTA_PREFSRC: ::c_ushort = 7; ++pub const RTA_METRICS: ::c_ushort = 8; ++pub const RTA_MULTIPATH: ::c_ushort = 9; ++pub const RTA_PROTOINFO: ::c_ushort = 10; // No longer used ++pub const RTA_FLOW: ::c_ushort = 11; ++pub const RTA_CACHEINFO: ::c_ushort = 12; ++pub const RTA_SESSION: ::c_ushort = 13; // No longer used ++pub const RTA_MP_ALGO: ::c_ushort = 14; // No longer used ++pub const RTA_TABLE: ::c_ushort = 15; ++pub const RTA_MARK: ::c_ushort = 16; ++pub const RTA_MFC_STATS: ::c_ushort = 17; ++ ++pub const RTN_UNSPEC: ::c_uchar = 0; ++pub const RTN_UNICAST: ::c_uchar = 1; ++pub const RTN_LOCAL: ::c_uchar = 2; ++pub const RTN_BROADCAST: ::c_uchar = 3; ++pub const RTN_ANYCAST: ::c_uchar = 4; ++pub const RTN_MULTICAST: ::c_uchar = 5; ++pub const RTN_BLACKHOLE: ::c_uchar = 6; ++pub const RTN_UNREACHABLE: ::c_uchar = 7; ++pub const RTN_PROHIBIT: ::c_uchar = 8; ++pub const RTN_THROW: ::c_uchar = 9; ++pub const RTN_NAT: ::c_uchar = 10; ++pub const RTN_XRESOLVE: ::c_uchar = 11; ++ ++pub const RTPROT_UNSPEC: ::c_uchar = 0; ++pub const RTPROT_REDIRECT: ::c_uchar = 1; ++pub const RTPROT_KERNEL: ::c_uchar = 2; ++pub const RTPROT_BOOT: ::c_uchar = 3; ++pub const RTPROT_STATIC: ::c_uchar = 4; ++ ++pub const RT_SCOPE_UNIVERSE: ::c_uchar = 0; ++pub const RT_SCOPE_SITE: ::c_uchar = 200; ++pub const RT_SCOPE_LINK: ::c_uchar = 253; ++pub const RT_SCOPE_HOST: ::c_uchar = 254; ++pub const RT_SCOPE_NOWHERE: ::c_uchar = 255; ++ ++pub const RT_TABLE_UNSPEC: ::c_uchar = 0; ++pub const RT_TABLE_COMPAT: ::c_uchar = 252; ++pub const RT_TABLE_DEFAULT: ::c_uchar = 253; ++pub const RT_TABLE_MAIN: ::c_uchar = 254; ++pub const RT_TABLE_LOCAL: ::c_uchar = 255; ++ ++pub const RTMSG_NEWDEVICE: u32 = 0x11; ++pub const RTMSG_DELDEVICE: u32 = 0x12; ++pub const RTMSG_NEWROUTE: u32 = 0x21; ++pub const RTMSG_DELROUTE: u32 = 0x22; ++ ++// Most `*_SUPER_MAGIC` constants are defined at the `linux_like` level; the ++// following are only available on newer Linux versions than the versions ++// currently used in CI in some configurations, so we define them here. ++cfg_if! { ++ if #[cfg(not(target_arch = "s390x"))] { ++ pub const XFS_SUPER_MAGIC: ::c_long = 0x58465342; ++ } else if #[cfg(target_arch = "s390x")] { ++ pub const XFS_SUPER_MAGIC: ::c_uint = 0x58465342; ++ } ++} + + f! { + pub fn CMSG_NXTHDR(mhdr: *const msghdr, +@@ -2366,6 +3041,12 @@ f! { + } + } + ++ pub fn CPU_ALLOC_SIZE(count: ::c_int) -> ::size_t { ++ let _dummy: cpu_set_t = ::mem::zeroed(); ++ let size_in_bits = 8 * ::mem::size_of_val(&_dummy.__bits[0]); ++ ((count as ::size_t + size_in_bits - 1) / 8) as ::size_t ++ } ++ + pub fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + for slot in cpuset.__bits.iter_mut() { + *slot = 0; +@@ -2373,40 +3054,50 @@ f! { + } + + pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { +- let size_in___bits = 8 * ::mem::size_of_val(&cpuset.__bits[0]); +- let (idx, offset) = (cpu / size_in___bits, cpu % size_in___bits); ++ let size_in_bits ++ = 8 * ::mem::size_of_val(&cpuset.__bits[0]); // 32, 64 etc ++ let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.__bits[idx] |= 1 << offset; + () + } + + pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { +- let size_in___bits = 8 * ::mem::size_of_val(&cpuset.__bits[0]); +- let (idx, offset) = (cpu / size_in___bits, cpu % size_in___bits); ++ let size_in_bits ++ = 8 * ::mem::size_of_val(&cpuset.__bits[0]); // 32, 64 etc ++ let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.__bits[idx] &= !(1 << offset); + () + } + + pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { +- let size_in___bits = 8 * ::mem::size_of_val(&cpuset.__bits[0]); +- let (idx, offset) = (cpu / size_in___bits, cpu % size_in___bits); ++ let size_in_bits = 8 * ::mem::size_of_val(&cpuset.__bits[0]); ++ let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + 0 != (cpuset.__bits[idx] & (1 << offset)) + } + ++ pub fn CPU_COUNT_S(size: usize, cpuset: &cpu_set_t) -> ::c_int { ++ let mut s: u32 = 0; ++ let size_of_mask = ::mem::size_of_val(&cpuset.__bits[0]); ++ for i in cpuset.__bits[..(size / size_of_mask)].iter() { ++ s += i.count_ones(); ++ }; ++ s as ::c_int ++ } ++ ++ pub fn CPU_COUNT(cpuset: &cpu_set_t) -> ::c_int { ++ CPU_COUNT_S(::mem::size_of::(), cpuset) ++ } ++ + pub fn CPU_EQUAL(set1: &cpu_set_t, set2: &cpu_set_t) -> bool { + set1.__bits == set2.__bits + } ++ + pub fn major(dev: ::dev_t) -> ::c_int { + ((dev >> 8) & 0xfff) as ::c_int + } + pub fn minor(dev: ::dev_t) -> ::c_int { + ((dev & 0xff) | ((dev >> 12) & 0xfff00)) as ::c_int + } +- pub fn makedev(ma: ::c_int, mi: ::c_int) -> ::dev_t { +- let ma = ma as ::dev_t; +- let mi = mi as ::dev_t; +- ((ma & 0xfff) << 8) | (mi & 0xff) | ((mi & 0xfff00) << 12) +- } +- + pub fn NLA_ALIGN(len: ::c_int) -> ::c_int { + return ((len) + NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1) + } +@@ -2416,6 +3107,15 @@ f! { + } + } + ++safe_f! { ++ pub {const} fn makedev(ma: ::c_uint, mi: ::c_uint) -> ::dev_t { ++ let ma = ma as ::dev_t; ++ let mi = mi as ::dev_t; ++ ((ma & 0xfff) << 8) | (mi & 0xff) | ((mi & 0xfff00) << 12) ++ } ++ ++} ++ + extern "C" { + pub fn getrlimit64(resource: ::c_int, rlim: *mut rlimit64) -> ::c_int; + pub fn setrlimit64(resource: ::c_int, rlim: *const rlimit64) -> ::c_int; +@@ -2436,6 +3136,7 @@ extern "C" { + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::timezone) -> ::c_int; ++ pub fn mlock2(addr: *const ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; + pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; + pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; +@@ -2482,6 +3183,11 @@ extern "C" { + pub fn __sched_cpufree(set: *mut ::cpu_set_t); + pub fn __sched_cpucount(setsize: ::size_t, set: *const cpu_set_t) -> ::c_int; + pub fn sched_getcpu() -> ::c_int; ++ pub fn mallinfo() -> ::mallinfo; ++ // available from API 23 ++ pub fn malloc_info(options: ::c_int, stream: *mut ::FILE) -> ::c_int; ++ ++ pub fn malloc_usable_size(ptr: *const ::c_void) -> ::size_t; + + pub fn utmpname(name: *const ::c_char) -> ::c_int; + pub fn setutent(); +@@ -2616,6 +3322,28 @@ extern "C" { + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; ++ pub fn pthread_barrierattr_init(attr: *mut ::pthread_barrierattr_t) -> ::c_int; ++ pub fn pthread_barrierattr_destroy(attr: *mut ::pthread_barrierattr_t) -> ::c_int; ++ pub fn pthread_barrierattr_getpshared( ++ attr: *const ::pthread_barrierattr_t, ++ shared: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_barrierattr_setpshared( ++ attr: *mut ::pthread_barrierattr_t, ++ shared: ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_barrier_init( ++ barrier: *mut pthread_barrier_t, ++ attr: *const ::pthread_barrierattr_t, ++ count: ::c_uint, ++ ) -> ::c_int; ++ pub fn pthread_barrier_destroy(barrier: *mut pthread_barrier_t) -> ::c_int; ++ pub fn pthread_barrier_wait(barrier: *mut pthread_barrier_t) -> ::c_int; ++ pub fn pthread_spin_init(lock: *mut ::pthread_spinlock_t, pshared: ::c_int) -> ::c_int; ++ pub fn pthread_spin_destroy(lock: *mut ::pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_lock(lock: *mut ::pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_trylock(lock: *mut ::pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_unlock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn clone( + cb: extern "C" fn(*mut ::c_void) -> ::c_int, + child_stack: *mut ::c_void, +@@ -2776,8 +3504,18 @@ extern "C" { + + pub fn gettid() -> ::pid_t; + ++ pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; ++ ++ pub fn pthread_setname_np(thread: ::pthread_t, name: *const ::c_char) -> ::c_int; ++ + pub fn __system_property_set(__name: *const ::c_char, __value: *const ::c_char) -> ::c_int; + pub fn __system_property_get(__name: *const ::c_char, __value: *mut ::c_char) -> ::c_int; ++ pub fn __system_property_find(__name: *const ::c_char) -> *const prop_info; ++ pub fn __system_property_find_nth(__n: ::c_uint) -> *const prop_info; ++ pub fn __system_property_foreach( ++ __callback: unsafe extern "C" fn(__pi: *const prop_info, __cookie: *mut ::c_void), ++ __cookie: *mut ::c_void, ++ ) -> ::c_int; + + // #include + /// Only available in API Version 21+ +@@ -2791,6 +3529,27 @@ extern "C" { + >, + data: *mut ::c_void, + ) -> ::c_int; ++ ++ pub fn arc4random() -> u32; ++ pub fn arc4random_uniform(__upper_bound: u32) -> u32; ++ pub fn arc4random_buf(__buf: *mut ::c_void, __n: ::size_t); ++ ++ pub fn reallocarray(ptr: *mut ::c_void, nmemb: ::size_t, size: ::size_t) -> *mut ::c_void; ++ ++ pub fn pthread_getcpuclockid(thread: ::pthread_t, clk_id: *mut ::clockid_t) -> ::c_int; ++ ++ pub fn dirname(path: *const ::c_char) -> *mut ::c_char; ++ pub fn basename(path: *const ::c_char) -> *mut ::c_char; ++ pub fn getopt_long( ++ argc: ::c_int, ++ argv: *const *mut c_char, ++ optstring: *const c_char, ++ longopts: *const option, ++ longindex: *mut ::c_int, ++ ) -> ::c_int; ++ ++ pub fn sync(); ++ pub fn syncfs(fd: ::c_int) -> ::c_int; + } + + cfg_if! { +diff --git a/vendor/libc/src/unix/linux_like/emscripten/mod.rs b/vendor/libc/src/unix/linux_like/emscripten/mod.rs +index b83415a..5b947b6 100644 +--- a/vendor/libc/src/unix/linux_like/emscripten/mod.rs ++++ b/vendor/libc/src/unix/linux_like/emscripten/mod.rs +@@ -965,10 +965,6 @@ pub const SHM_UNLOCK: ::c_int = 12; + pub const SHM_HUGETLB: ::c_int = 0o4000; + pub const SHM_NORESERVE: ::c_int = 0o10000; + +-pub const EPOLLRDHUP: ::c_int = 0x2000; +-pub const EPOLLEXCLUSIVE: ::c_int = 0x10000000; +-pub const EPOLLONESHOT: ::c_int = 0x40000000; +- + pub const QFMT_VFS_OLD: ::c_int = 1; + pub const QFMT_VFS_V0: ::c_int = 2; + +@@ -1123,6 +1119,7 @@ pub const PR_SET_MM_MAP: ::c_int = 14; + pub const PR_SET_MM_MAP_SIZE: ::c_int = 15; + + pub const PR_SET_PTRACER: ::c_int = 0x59616d61; ++pub const PR_SET_PTRACER_ANY: ::c_ulong = 0xffffffffffffffff; + + pub const PR_SET_CHILD_SUBREAPER: ::c_int = 36; + pub const PR_GET_CHILD_SUBREAPER: ::c_int = 37; +@@ -1372,8 +1369,6 @@ pub const PTRACE_INTERRUPT: ::c_int = 0x4207; + pub const PTRACE_LISTEN: ::c_int = 0x4208; + pub const PTRACE_PEEKSIGINFO: ::c_int = 0x4209; + +-pub const EPOLLWAKEUP: ::c_int = 0x20000000; +- + pub const PTRACE_GETFPREGS: ::c_uint = 14; + pub const PTRACE_SETFPREGS: ::c_uint = 15; + pub const PTRACE_GETFPXREGS: ::c_uint = 18; +@@ -1675,6 +1670,8 @@ pub const PRIO_PROCESS: ::c_int = 0; + pub const PRIO_PGRP: ::c_int = 1; + pub const PRIO_USER: ::c_int = 2; + ++pub const SOMAXCONN: ::c_int = 128; ++ + f! { + pub fn CMSG_NXTHDR(mhdr: *const msghdr, + cmsg: *const cmsghdr) -> *mut cmsghdr { +@@ -1728,7 +1725,7 @@ f! { + pub fn major(dev: ::dev_t) -> ::c_uint { + // see + // https://github.com/emscripten-core/emscripten/blob/ +- // master/system/include/libc/sys/sysmacros.h ++ // main/system/lib/libc/musl/include/sys/sysmacros.h + let mut major = 0; + major |= (dev & 0x00000fff) >> 8; + major |= (dev & 0xfffff000) >> 31 >> 1; +@@ -1738,14 +1735,16 @@ f! { + pub fn minor(dev: ::dev_t) -> ::c_uint { + // see + // https://github.com/emscripten-core/emscripten/blob/ +- // master/system/include/libc/sys/sysmacros.h ++ // main/system/lib/libc/musl/include/sys/sysmacros.h + let mut minor = 0; + minor |= (dev & 0x000000ff) >> 0; + minor |= (dev & 0xffffff00) >> 12; + minor as ::c_uint + } ++} + +- pub fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { ++safe_f! { ++ pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; +@@ -1765,7 +1764,6 @@ extern "C" { + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + pub fn abs(i: ::c_int) -> ::c_int; +- pub fn atof(s: *const ::c_char) -> ::c_double; + pub fn labs(i: ::c_long) -> ::c_long; + pub fn rand() -> ::c_int; + pub fn srand(seed: ::c_uint); +@@ -1817,7 +1815,6 @@ extern "C" { + ) -> ::c_int; + pub fn getloadavg(loadavg: *mut ::c_double, nelem: ::c_int) -> ::c_int; + +- // Not available now on Android + pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; + pub fn if_nameindex() -> *mut if_nameindex; + pub fn if_freenameindex(ptr: *mut if_nameindex); +@@ -1885,6 +1882,8 @@ extern "C" { + f: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; ++ ++ pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; + } + + cfg_if! { +diff --git a/vendor/libc/src/unix/linux_like/linux/align.rs b/vendor/libc/src/unix/linux_like/linux/align.rs +index 11f5504..cd4bbc7 100644 +--- a/vendor/libc/src/unix/linux_like/linux/align.rs ++++ b/vendor/libc/src/unix/linux_like/linux/align.rs +@@ -9,7 +9,8 @@ macro_rules! expand_align { + target_arch = "sparc64", + target_arch = "aarch64", + target_arch = "riscv64", +- target_arch = "riscv32"), ++ target_arch = "riscv32", ++ target_arch = "loongarch64"), + repr(align(4)))] + #[cfg_attr(not(any(target_pointer_width = "32", + target_arch = "x86_64", +@@ -19,16 +20,18 @@ macro_rules! expand_align { + target_arch = "sparc64", + target_arch = "aarch64", + target_arch = "riscv64", +- target_arch = "riscv32")), ++ target_arch = "riscv32", ++ target_arch = "loongarch64")), + repr(align(8)))] + pub struct pthread_mutexattr_t { + #[doc(hidden)] + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + +- #[cfg_attr(any(target_env = "musl", target_pointer_width = "32"), ++ #[cfg_attr(any(target_env = "musl", target_env = "ohos", target_pointer_width = "32"), + repr(align(4)))] + #[cfg_attr(all(not(target_env = "musl"), ++ not(target_env = "ohos"), + target_pointer_width = "64"), + repr(align(8)))] + pub struct pthread_rwlockattr_t { +@@ -42,6 +45,12 @@ macro_rules! expand_align { + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + ++ #[repr(align(4))] ++ pub struct pthread_barrierattr_t { ++ #[doc(hidden)] ++ size: [u8; ::__SIZEOF_PTHREAD_BARRIERATTR_T], ++ } ++ + #[repr(align(8))] + pub struct fanotify_event_metadata { + pub event_len: __u32, +@@ -55,16 +64,16 @@ macro_rules! expand_align { + } + + s_no_extra_traits! { +- #[cfg_attr(all(target_env = "musl", ++ #[cfg_attr(all(any(target_env = "musl", target_env = "ohos"), + target_pointer_width = "32"), + repr(align(4)))] +- #[cfg_attr(all(target_env = "musl", ++ #[cfg_attr(all(any(target_env = "musl", target_env = "ohos"), + target_pointer_width = "64"), + repr(align(8)))] +- #[cfg_attr(all(not(target_env = "musl"), ++ #[cfg_attr(all(not(any(target_env = "musl", target_env = "ohos")), + target_arch = "x86"), + repr(align(4)))] +- #[cfg_attr(all(not(target_env = "musl"), ++ #[cfg_attr(all(not(any(target_env = "musl", target_env = "ohos")), + not(target_arch = "x86")), + repr(align(8)))] + pub struct pthread_cond_t { +@@ -76,6 +85,7 @@ macro_rules! expand_align { + any(target_arch = "mips", + target_arch = "arm", + target_arch = "hexagon", ++ target_arch = "m68k", + target_arch = "powerpc", + target_arch = "sparc", + target_arch = "x86_64", +@@ -85,6 +95,7 @@ macro_rules! expand_align { + not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "hexagon", ++ target_arch = "m68k", + target_arch = "powerpc", + target_arch = "sparc", + target_arch = "x86_64", +@@ -99,6 +110,7 @@ macro_rules! expand_align { + any(target_arch = "mips", + target_arch = "arm", + target_arch = "hexagon", ++ target_arch = "m68k", + target_arch = "powerpc", + target_arch = "sparc", + target_arch = "x86_64", +@@ -108,6 +120,7 @@ macro_rules! expand_align { + not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "hexagon", ++ target_arch = "m68k", + target_arch = "powerpc", + target_arch = "sparc", + target_arch = "x86_64", +@@ -117,6 +130,30 @@ macro_rules! expand_align { + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + ++ #[cfg_attr(all(target_pointer_width = "32", ++ any(target_arch = "mips", ++ target_arch = "arm", ++ target_arch = "hexagon", ++ target_arch = "m68k", ++ target_arch = "powerpc", ++ target_arch = "sparc", ++ target_arch = "x86_64", ++ target_arch = "x86")), ++ repr(align(4)))] ++ #[cfg_attr(any(target_pointer_width = "64", ++ not(any(target_arch = "mips", ++ target_arch = "arm", ++ target_arch = "hexagon", ++ target_arch = "m68k", ++ target_arch = "powerpc", ++ target_arch = "sparc", ++ target_arch = "x86_64", ++ target_arch = "x86"))), ++ repr(align(8)))] ++ pub struct pthread_barrier_t { ++ size: [u8; ::__SIZEOF_PTHREAD_BARRIER_T], ++ } ++ + // linux/can.h + #[repr(align(8))] + #[allow(missing_debug_implementations)] +diff --git a/vendor/libc/src/unix/linux_like/linux/arch/generic/mod.rs b/vendor/libc/src/unix/linux_like/linux/arch/generic/mod.rs +index e3401d4..4693978 100644 +--- a/vendor/libc/src/unix/linux_like/linux/arch/generic/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/arch/generic/mod.rs +@@ -1,3 +1,16 @@ ++s! { ++ pub struct termios2 { ++ pub c_iflag: ::tcflag_t, ++ pub c_oflag: ::tcflag_t, ++ pub c_cflag: ::tcflag_t, ++ pub c_lflag: ::tcflag_t, ++ pub c_line: ::cc_t, ++ pub c_cc: [::cc_t; 19], ++ pub c_ispeed: ::speed_t, ++ pub c_ospeed: ::speed_t, ++ } ++} ++ + // include/uapi/asm-generic/socket.h + // arch/alpha/include/uapi/asm/socket.h + // tools/include/uapi/asm-generic/socket.h +@@ -82,7 +95,7 @@ cfg_if! { + if #[cfg(all(any(target_arch = "x86", + target_arch = "x86_64", + target_arch = "aarch64"), +- not(target_env = "musl")))] { ++ not(any(target_env = "musl", target_env = "ohos"))))] { + pub const SO_TIMESTAMP_NEW: ::c_int = 63; + pub const SO_TIMESTAMPNS_NEW: ::c_int = 64; + pub const SO_TIMESTAMPING_NEW: ::c_int = 65; +@@ -91,6 +104,24 @@ cfg_if! { + pub const SO_DETACH_REUSEPORT_BPF: ::c_int = 68; + } + } ++ ++cfg_if! { ++ if #[cfg(any(target_arch = "x86", ++ target_arch = "x86_64", ++ target_arch = "arm", ++ target_arch = "aarch64", ++ target_arch = "riscv64", ++ target_arch = "s390x"))] { ++ pub const FICLONE: ::c_ulong = 0x40049409; ++ pub const FICLONERANGE: ::c_ulong = 0x4020940D; ++ } else if #[cfg(any(target_arch = "mips", ++ target_arch = "mips64", ++ target_arch = "powerpc", ++ target_arch = "powerpc64"))] { ++ pub const FICLONE: ::c_ulong = 0x80049409; ++ pub const FICLONERANGE: ::c_ulong = 0x8020940D; ++ } ++} + // pub const SO_PREFER_BUSY_POLL: ::c_int = 69; + // pub const SO_BUSY_POLL_BUDGET: ::c_int = 70; + +@@ -98,3 +129,168 @@ cfg_if! { + // pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP; + pub const SCM_TIMESTAMPNS: ::c_int = SO_TIMESTAMPNS; + pub const SCM_TIMESTAMPING: ::c_int = SO_TIMESTAMPING; ++ ++// Ioctl Constants ++ ++pub const TCGETS: ::Ioctl = 0x5401; ++pub const TCSETS: ::Ioctl = 0x5402; ++pub const TCSETSW: ::Ioctl = 0x5403; ++pub const TCSETSF: ::Ioctl = 0x5404; ++pub const TCGETA: ::Ioctl = 0x5405; ++pub const TCSETA: ::Ioctl = 0x5406; ++pub const TCSETAW: ::Ioctl = 0x5407; ++pub const TCSETAF: ::Ioctl = 0x5408; ++pub const TCSBRK: ::Ioctl = 0x5409; ++pub const TCXONC: ::Ioctl = 0x540A; ++pub const TCFLSH: ::Ioctl = 0x540B; ++pub const TIOCEXCL: ::Ioctl = 0x540C; ++pub const TIOCNXCL: ::Ioctl = 0x540D; ++pub const TIOCSCTTY: ::Ioctl = 0x540E; ++pub const TIOCGPGRP: ::Ioctl = 0x540F; ++pub const TIOCSPGRP: ::Ioctl = 0x5410; ++pub const TIOCOUTQ: ::Ioctl = 0x5411; ++pub const TIOCSTI: ::Ioctl = 0x5412; ++pub const TIOCGWINSZ: ::Ioctl = 0x5413; ++pub const TIOCSWINSZ: ::Ioctl = 0x5414; ++pub const TIOCMGET: ::Ioctl = 0x5415; ++pub const TIOCMBIS: ::Ioctl = 0x5416; ++pub const TIOCMBIC: ::Ioctl = 0x5417; ++pub const TIOCMSET: ::Ioctl = 0x5418; ++pub const TIOCGSOFTCAR: ::Ioctl = 0x5419; ++pub const TIOCSSOFTCAR: ::Ioctl = 0x541A; ++pub const FIONREAD: ::Ioctl = 0x541B; ++pub const TIOCINQ: ::Ioctl = FIONREAD; ++pub const TIOCLINUX: ::Ioctl = 0x541C; ++pub const TIOCCONS: ::Ioctl = 0x541D; ++pub const TIOCGSERIAL: ::Ioctl = 0x541E; ++pub const TIOCSSERIAL: ::Ioctl = 0x541F; ++pub const TIOCPKT: ::Ioctl = 0x5420; ++pub const FIONBIO: ::Ioctl = 0x5421; ++pub const TIOCNOTTY: ::Ioctl = 0x5422; ++pub const TIOCSETD: ::Ioctl = 0x5423; ++pub const TIOCGETD: ::Ioctl = 0x5424; ++pub const TCSBRKP: ::Ioctl = 0x5425; ++pub const TIOCSBRK: ::Ioctl = 0x5427; ++pub const TIOCCBRK: ::Ioctl = 0x5428; ++pub const TIOCGSID: ::Ioctl = 0x5429; ++pub const TCGETS2: ::Ioctl = 0x802c542a; ++pub const TCSETS2: ::Ioctl = 0x402c542b; ++pub const TCSETSW2: ::Ioctl = 0x402c542c; ++pub const TCSETSF2: ::Ioctl = 0x402c542d; ++pub const TIOCGRS485: ::Ioctl = 0x542E; ++pub const TIOCSRS485: ::Ioctl = 0x542F; ++pub const TIOCGPTN: ::Ioctl = 0x80045430; ++pub const TIOCSPTLCK: ::Ioctl = 0x40045431; ++pub const TIOCGDEV: ::Ioctl = 0x80045432; ++pub const TCGETX: ::Ioctl = 0x5432; ++pub const TCSETX: ::Ioctl = 0x5433; ++pub const TCSETXF: ::Ioctl = 0x5434; ++pub const TCSETXW: ::Ioctl = 0x5435; ++pub const TIOCSIG: ::Ioctl = 0x40045436; ++pub const TIOCVHANGUP: ::Ioctl = 0x5437; ++pub const TIOCGPKT: ::Ioctl = 0x80045438; ++pub const TIOCGPTLCK: ::Ioctl = 0x80045439; ++pub const TIOCGEXCL: ::Ioctl = 0x80045440; ++pub const TIOCGPTPEER: ::Ioctl = 0x5441; ++// pub const TIOCGISO7816: ::Ioctl = 0x80285442; ++// pub const TIOCSISO7816: ::Ioctl = 0xc0285443; ++pub const FIONCLEX: ::Ioctl = 0x5450; ++pub const FIOCLEX: ::Ioctl = 0x5451; ++pub const FIOASYNC: ::Ioctl = 0x5452; ++pub const TIOCSERCONFIG: ::Ioctl = 0x5453; ++pub const TIOCSERGWILD: ::Ioctl = 0x5454; ++pub const TIOCSERSWILD: ::Ioctl = 0x5455; ++pub const TIOCGLCKTRMIOS: ::Ioctl = 0x5456; ++pub const TIOCSLCKTRMIOS: ::Ioctl = 0x5457; ++pub const TIOCSERGSTRUCT: ::Ioctl = 0x5458; ++pub const TIOCSERGETLSR: ::Ioctl = 0x5459; ++pub const TIOCSERGETMULTI: ::Ioctl = 0x545A; ++pub const TIOCSERSETMULTI: ::Ioctl = 0x545B; ++pub const TIOCMIWAIT: ::Ioctl = 0x545C; ++pub const TIOCGICOUNT: ::Ioctl = 0x545D; ++pub const BLKIOMIN: ::Ioctl = 0x1278; ++pub const BLKIOOPT: ::Ioctl = 0x1279; ++pub const BLKSSZGET: ::Ioctl = 0x1268; ++pub const BLKPBSZGET: ::Ioctl = 0x127B; ++ ++cfg_if! { ++ if #[cfg(any(target_arch = "arm", ++ target_arch = "s390x"))] { ++ pub const FIOQSIZE: ::Ioctl = 0x545E; ++ } else { ++ pub const FIOQSIZE: ::Ioctl = 0x5460; ++ } ++} ++ ++pub const TIOCM_LE: ::c_int = 0x001; ++pub const TIOCM_DTR: ::c_int = 0x002; ++pub const TIOCM_RTS: ::c_int = 0x004; ++pub const TIOCM_ST: ::c_int = 0x008; ++pub const TIOCM_SR: ::c_int = 0x010; ++pub const TIOCM_CTS: ::c_int = 0x020; ++pub const TIOCM_CAR: ::c_int = 0x040; ++pub const TIOCM_CD: ::c_int = TIOCM_CAR; ++pub const TIOCM_RNG: ::c_int = 0x080; ++pub const TIOCM_RI: ::c_int = TIOCM_RNG; ++pub const TIOCM_DSR: ::c_int = 0x100; ++ ++pub const BOTHER: ::speed_t = 0o010000; ++pub const IBSHIFT: ::tcflag_t = 16; ++ ++// RLIMIT Constants ++ ++cfg_if! { ++ if #[cfg(any(target_env = "gnu", ++ target_env = "uclibc"))] { ++ ++ pub const RLIMIT_CPU: ::__rlimit_resource_t = 0; ++ pub const RLIMIT_FSIZE: ::__rlimit_resource_t = 1; ++ pub const RLIMIT_DATA: ::__rlimit_resource_t = 2; ++ pub const RLIMIT_STACK: ::__rlimit_resource_t = 3; ++ pub const RLIMIT_CORE: ::__rlimit_resource_t = 4; ++ pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; ++ pub const RLIMIT_NPROC: ::__rlimit_resource_t = 6; ++ pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 7; ++ pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; ++ pub const RLIMIT_AS: ::__rlimit_resource_t = 9; ++ pub const RLIMIT_LOCKS: ::__rlimit_resource_t = 10; ++ pub const RLIMIT_SIGPENDING: ::__rlimit_resource_t = 11; ++ pub const RLIMIT_MSGQUEUE: ::__rlimit_resource_t = 12; ++ pub const RLIMIT_NICE: ::__rlimit_resource_t = 13; ++ pub const RLIMIT_RTPRIO: ::__rlimit_resource_t = 14; ++ pub const RLIMIT_RTTIME: ::__rlimit_resource_t = 15; ++ pub const RLIMIT_NLIMITS: ::__rlimit_resource_t = RLIM_NLIMITS; ++ ++ } else if #[cfg(any(target_env = "musl", target_env = "ohos"))] { ++ ++ pub const RLIMIT_CPU: ::c_int = 0; ++ pub const RLIMIT_FSIZE: ::c_int = 1; ++ pub const RLIMIT_DATA: ::c_int = 2; ++ pub const RLIMIT_STACK: ::c_int = 3; ++ pub const RLIMIT_CORE: ::c_int = 4; ++ pub const RLIMIT_RSS: ::c_int = 5; ++ pub const RLIMIT_NPROC: ::c_int = 6; ++ pub const RLIMIT_NOFILE: ::c_int = 7; ++ pub const RLIMIT_MEMLOCK: ::c_int = 8; ++ pub const RLIMIT_AS: ::c_int = 9; ++ pub const RLIMIT_LOCKS: ::c_int = 10; ++ pub const RLIMIT_SIGPENDING: ::c_int = 11; ++ pub const RLIMIT_MSGQUEUE: ::c_int = 12; ++ pub const RLIMIT_NICE: ::c_int = 13; ++ pub const RLIMIT_RTPRIO: ::c_int = 14; ++ pub const RLIMIT_RTTIME: ::c_int = 15; ++ pub const RLIM_NLIMITS: ::c_int = 15; ++ pub const RLIMIT_NLIMITS: ::c_int = RLIM_NLIMITS; ++ } ++} ++ ++cfg_if! { ++ if #[cfg(target_env = "gnu")] { ++ pub const RLIM_NLIMITS: ::__rlimit_resource_t = 16; ++ } ++ else if #[cfg(target_env = "uclibc")] { ++ pub const RLIM_NLIMITS: ::__rlimit_resource_t = 15; ++ } ++} ++ ++pub const RLIM_INFINITY: ::rlim_t = !0; +diff --git a/vendor/libc/src/unix/linux_like/linux/arch/mips/mod.rs b/vendor/libc/src/unix/linux_like/linux/arch/mips/mod.rs +index cdbdca2..077417d 100644 +--- a/vendor/libc/src/unix/linux_like/linux/arch/mips/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/arch/mips/mod.rs +@@ -1,3 +1,16 @@ ++s! { ++ pub struct termios2 { ++ pub c_iflag: ::tcflag_t, ++ pub c_oflag: ::tcflag_t, ++ pub c_cflag: ::tcflag_t, ++ pub c_lflag: ::tcflag_t, ++ pub c_line: ::cc_t, ++ pub c_cc: [::cc_t; 23], ++ pub c_ispeed: ::speed_t, ++ pub c_ospeed: ::speed_t, ++ } ++} ++ + // arch/mips/include/uapi/asm/socket.h + pub const SOL_SOCKET: ::c_int = 0xffff; + +@@ -94,3 +107,179 @@ pub const SO_TIMESTAMPING: ::c_int = 37; + // pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP; + pub const SCM_TIMESTAMPNS: ::c_int = SO_TIMESTAMPNS; + pub const SCM_TIMESTAMPING: ::c_int = SO_TIMESTAMPING; ++ ++// Ioctl Constants ++ ++pub const TCGETS: ::Ioctl = 0x540d; ++pub const TCSETS: ::Ioctl = 0x540e; ++pub const TCSETSW: ::Ioctl = 0x540f; ++pub const TCSETSF: ::Ioctl = 0x5410; ++pub const TCGETA: ::Ioctl = 0x5401; ++pub const TCSETA: ::Ioctl = 0x5402; ++pub const TCSETAW: ::Ioctl = 0x5403; ++pub const TCSETAF: ::Ioctl = 0x5404; ++pub const TCSBRK: ::Ioctl = 0x5405; ++pub const TCXONC: ::Ioctl = 0x5406; ++pub const TCFLSH: ::Ioctl = 0x5407; ++pub const TIOCEXCL: ::Ioctl = 0x740d; ++pub const TIOCNXCL: ::Ioctl = 0x740e; ++pub const TIOCSCTTY: ::Ioctl = 0x5480; ++pub const TIOCGPGRP: ::Ioctl = 0x40047477; ++pub const TIOCSPGRP: ::Ioctl = 0x80047476; ++pub const TIOCOUTQ: ::Ioctl = 0x7472; ++pub const TIOCSTI: ::Ioctl = 0x5472; ++pub const TIOCGWINSZ: ::Ioctl = 0x40087468; ++pub const TIOCSWINSZ: ::Ioctl = 0x80087467; ++pub const TIOCMGET: ::Ioctl = 0x741d; ++pub const TIOCMBIS: ::Ioctl = 0x741b; ++pub const TIOCMBIC: ::Ioctl = 0x741c; ++pub const TIOCMSET: ::Ioctl = 0x741a; ++pub const TIOCGSOFTCAR: ::Ioctl = 0x5481; ++pub const TIOCSSOFTCAR: ::Ioctl = 0x5482; ++pub const FIONREAD: ::Ioctl = 0x467f; ++pub const TIOCINQ: ::Ioctl = FIONREAD; ++pub const TIOCLINUX: ::Ioctl = 0x5483; ++pub const TIOCCONS: ::Ioctl = 0x80047478; ++pub const TIOCGSERIAL: ::Ioctl = 0x5484; ++pub const TIOCSSERIAL: ::Ioctl = 0x5485; ++pub const TIOCPKT: ::Ioctl = 0x5470; ++pub const FIONBIO: ::Ioctl = 0x667e; ++pub const TIOCNOTTY: ::Ioctl = 0x5471; ++pub const TIOCSETD: ::Ioctl = 0x7401; ++pub const TIOCGETD: ::Ioctl = 0x7400; ++pub const TCSBRKP: ::Ioctl = 0x5486; ++pub const TIOCSBRK: ::Ioctl = 0x5427; ++pub const TIOCCBRK: ::Ioctl = 0x5428; ++pub const TIOCGSID: ::Ioctl = 0x7416; ++pub const TCGETS2: ::Ioctl = 0x4030542a; ++pub const TCSETS2: ::Ioctl = 0x8030542b; ++pub const TCSETSW2: ::Ioctl = 0x8030542c; ++pub const TCSETSF2: ::Ioctl = 0x8030542d; ++pub const TIOCGPTN: ::Ioctl = 0x40045430; ++pub const TIOCSPTLCK: ::Ioctl = 0x80045431; ++pub const TIOCGDEV: ::Ioctl = 0x40045432; ++pub const TIOCSIG: ::Ioctl = 0x80045436; ++pub const TIOCVHANGUP: ::Ioctl = 0x5437; ++pub const TIOCGPKT: ::Ioctl = 0x40045438; ++pub const TIOCGPTLCK: ::Ioctl = 0x40045439; ++pub const TIOCGEXCL: ::Ioctl = 0x40045440; ++pub const TIOCGPTPEER: ::Ioctl = 0x20005441; ++//pub const TIOCGISO7816: ::Ioctl = 0x40285442; ++//pub const TIOCSISO7816: ::Ioctl = 0xc0285443; ++pub const FIONCLEX: ::Ioctl = 0x6602; ++pub const FIOCLEX: ::Ioctl = 0x6601; ++pub const FIOASYNC: ::Ioctl = 0x667d; ++pub const TIOCSERCONFIG: ::Ioctl = 0x5488; ++pub const TIOCSERGWILD: ::Ioctl = 0x5489; ++pub const TIOCSERSWILD: ::Ioctl = 0x548a; ++pub const TIOCGLCKTRMIOS: ::Ioctl = 0x548b; ++pub const TIOCSLCKTRMIOS: ::Ioctl = 0x548c; ++pub const TIOCSERGSTRUCT: ::Ioctl = 0x548d; ++pub const TIOCSERGETLSR: ::Ioctl = 0x548e; ++pub const TIOCSERGETMULTI: ::Ioctl = 0x548f; ++pub const TIOCSERSETMULTI: ::Ioctl = 0x5490; ++pub const TIOCMIWAIT: ::Ioctl = 0x5491; ++pub const TIOCGICOUNT: ::Ioctl = 0x5492; ++pub const FIOQSIZE: ::Ioctl = 0x667f; ++pub const TIOCSLTC: ::Ioctl = 0x7475; ++pub const TIOCGETP: ::Ioctl = 0x7408; ++pub const TIOCSETP: ::Ioctl = 0x7409; ++pub const TIOCSETN: ::Ioctl = 0x740a; ++pub const BLKIOMIN: ::Ioctl = 0x20001278; ++pub const BLKIOOPT: ::Ioctl = 0x20001279; ++pub const BLKSSZGET: ::Ioctl = 0x20001268; ++pub const BLKPBSZGET: ::Ioctl = 0x2000127B; ++ ++cfg_if! { ++ if #[cfg(target_env = "musl")] { ++ pub const TIOCGRS485: ::Ioctl = 0x4020542e; ++ pub const TIOCSRS485: ::Ioctl = 0xc020542f; ++ } ++} ++ ++pub const TIOCM_LE: ::c_int = 0x001; ++pub const TIOCM_DTR: ::c_int = 0x002; ++pub const TIOCM_RTS: ::c_int = 0x004; ++pub const TIOCM_ST: ::c_int = 0x010; ++pub const TIOCM_SR: ::c_int = 0x020; ++pub const TIOCM_CTS: ::c_int = 0x040; ++pub const TIOCM_CAR: ::c_int = 0x100; ++pub const TIOCM_CD: ::c_int = TIOCM_CAR; ++pub const TIOCM_RNG: ::c_int = 0x200; ++pub const TIOCM_RI: ::c_int = TIOCM_RNG; ++pub const TIOCM_DSR: ::c_int = 0x400; ++ ++pub const BOTHER: ::speed_t = 0o010000; ++pub const IBSHIFT: ::tcflag_t = 16; ++ ++// RLIMIT Constants ++ ++cfg_if! { ++ if #[cfg(any(target_env = "gnu", ++ target_env = "uclibc"))] { ++ ++ pub const RLIMIT_CPU: ::__rlimit_resource_t = 0; ++ pub const RLIMIT_FSIZE: ::__rlimit_resource_t = 1; ++ pub const RLIMIT_DATA: ::__rlimit_resource_t = 2; ++ pub const RLIMIT_STACK: ::__rlimit_resource_t = 3; ++ pub const RLIMIT_CORE: ::__rlimit_resource_t = 4; ++ pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 5; ++ pub const RLIMIT_AS: ::__rlimit_resource_t = 6; ++ pub const RLIMIT_RSS: ::__rlimit_resource_t = 7; ++ pub const RLIMIT_NPROC: ::__rlimit_resource_t = 8; ++ pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 9; ++ pub const RLIMIT_LOCKS: ::__rlimit_resource_t = 10; ++ pub const RLIMIT_SIGPENDING: ::__rlimit_resource_t = 11; ++ pub const RLIMIT_MSGQUEUE: ::__rlimit_resource_t = 12; ++ pub const RLIMIT_NICE: ::__rlimit_resource_t = 13; ++ pub const RLIMIT_RTPRIO: ::__rlimit_resource_t = 14; ++ pub const RLIMIT_RTTIME: ::__rlimit_resource_t = 15; ++ pub const RLIMIT_NLIMITS: ::__rlimit_resource_t = RLIM_NLIMITS; ++ ++ } else if #[cfg(target_env = "musl")] { ++ ++ pub const RLIMIT_CPU: ::c_int = 0; ++ pub const RLIMIT_FSIZE: ::c_int = 1; ++ pub const RLIMIT_DATA: ::c_int = 2; ++ pub const RLIMIT_STACK: ::c_int = 3; ++ pub const RLIMIT_CORE: ::c_int = 4; ++ pub const RLIMIT_NOFILE: ::c_int = 5; ++ pub const RLIMIT_AS: ::c_int = 6; ++ pub const RLIMIT_RSS: ::c_int = 7; ++ pub const RLIMIT_NPROC: ::c_int = 8; ++ pub const RLIMIT_MEMLOCK: ::c_int = 9; ++ pub const RLIMIT_LOCKS: ::c_int = 10; ++ pub const RLIMIT_SIGPENDING: ::c_int = 11; ++ pub const RLIMIT_MSGQUEUE: ::c_int = 12; ++ pub const RLIMIT_NICE: ::c_int = 13; ++ pub const RLIMIT_RTPRIO: ::c_int = 14; ++ pub const RLIMIT_RTTIME: ::c_int = 15; ++ pub const RLIM_NLIMITS: ::c_int = 15; ++ pub const RLIMIT_NLIMITS: ::c_int = RLIM_NLIMITS; ++ pub const RLIM_INFINITY: ::rlim_t = !0; ++ } ++} ++ ++cfg_if! { ++ if #[cfg(target_env = "gnu")] { ++ pub const RLIM_NLIMITS: ::__rlimit_resource_t = 16; ++ } else if #[cfg(target_env = "uclibc")] { ++ pub const RLIM_NLIMITS: ::__rlimit_resource_t = 15; ++ } ++} ++ ++cfg_if! { ++ if #[cfg(target_arch = "mips64", ++ any(target_env = "gnu", ++ target_env = "uclibc"))] { ++ pub const RLIM_INFINITY: ::rlim_t = !0; ++ } ++} ++ ++cfg_if! { ++ if #[cfg(target_arch = "mips", ++ any(target_env = "gnu", ++ target_env = "uclibc"))] { ++ pub const RLIM_INFINITY: ::rlim_t = 0x7fffffff; ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/arch/powerpc/mod.rs b/vendor/libc/src/unix/linux_like/linux/arch/powerpc/mod.rs +index 89cc09e..637b7a1 100644 +--- a/vendor/libc/src/unix/linux_like/linux/arch/powerpc/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/arch/powerpc/mod.rs +@@ -89,3 +89,152 @@ pub const SO_BINDTOIFINDEX: ::c_int = 62; + // pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP; + pub const SCM_TIMESTAMPNS: ::c_int = SO_TIMESTAMPNS; + pub const SCM_TIMESTAMPING: ::c_int = SO_TIMESTAMPING; ++ ++// Ioctl Constants ++ ++cfg_if! { ++ if #[cfg(target_env = "gnu")] { ++ pub const TCGETS: ::Ioctl = 0x403c7413; ++ pub const TCSETS: ::Ioctl = 0x803c7414; ++ pub const TCSETSW: ::Ioctl = 0x803c7415; ++ pub const TCSETSF: ::Ioctl = 0x803c7416; ++ } else if #[cfg(target_env = "musl")] { ++ pub const TCGETS: ::Ioctl = 0x402c7413; ++ pub const TCSETS: ::Ioctl = 0x802c7414; ++ pub const TCSETSW: ::Ioctl = 0x802c7415; ++ pub const TCSETSF: ::Ioctl = 0x802c7416; ++ } ++} ++ ++pub const TCGETA: ::Ioctl = 0x40147417; ++pub const TCSETA: ::Ioctl = 0x80147418; ++pub const TCSETAW: ::Ioctl = 0x80147419; ++pub const TCSETAF: ::Ioctl = 0x8014741C; ++pub const TCSBRK: ::Ioctl = 0x2000741D; ++pub const TCXONC: ::Ioctl = 0x2000741E; ++pub const TCFLSH: ::Ioctl = 0x2000741F; ++pub const TIOCEXCL: ::Ioctl = 0x540C; ++pub const TIOCNXCL: ::Ioctl = 0x540D; ++pub const TIOCSCTTY: ::Ioctl = 0x540E; ++pub const TIOCGPGRP: ::Ioctl = 0x40047477; ++pub const TIOCSPGRP: ::Ioctl = 0x80047476; ++pub const TIOCOUTQ: ::Ioctl = 0x40047473; ++pub const TIOCSTI: ::Ioctl = 0x5412; ++pub const TIOCGWINSZ: ::Ioctl = 0x40087468; ++pub const TIOCSWINSZ: ::Ioctl = 0x80087467; ++pub const TIOCMGET: ::Ioctl = 0x5415; ++pub const TIOCMBIS: ::Ioctl = 0x5416; ++pub const TIOCMBIC: ::Ioctl = 0x5417; ++pub const TIOCMSET: ::Ioctl = 0x5418; ++pub const TIOCGSOFTCAR: ::Ioctl = 0x5419; ++pub const TIOCSSOFTCAR: ::Ioctl = 0x541A; ++pub const FIONREAD: ::Ioctl = 0x4004667F; ++pub const TIOCINQ: ::Ioctl = FIONREAD; ++pub const TIOCLINUX: ::Ioctl = 0x541C; ++pub const TIOCCONS: ::Ioctl = 0x541D; ++pub const TIOCGSERIAL: ::Ioctl = 0x541E; ++pub const TIOCSSERIAL: ::Ioctl = 0x541F; ++pub const TIOCPKT: ::Ioctl = 0x5420; ++pub const FIONBIO: ::Ioctl = 0x8004667e; ++pub const TIOCNOTTY: ::Ioctl = 0x5422; ++pub const TIOCSETD: ::Ioctl = 0x5423; ++pub const TIOCGETD: ::Ioctl = 0x5424; ++pub const TCSBRKP: ::Ioctl = 0x5425; ++pub const TIOCSBRK: ::Ioctl = 0x5427; ++pub const TIOCCBRK: ::Ioctl = 0x5428; ++pub const TIOCGSID: ::Ioctl = 0x5429; ++pub const TIOCGRS485: ::Ioctl = 0x542e; ++pub const TIOCSRS485: ::Ioctl = 0x542f; ++pub const TIOCGPTN: ::Ioctl = 0x40045430; ++pub const TIOCSPTLCK: ::Ioctl = 0x80045431; ++pub const TIOCGDEV: ::Ioctl = 0x40045432; ++pub const TIOCSIG: ::Ioctl = 0x80045436; ++pub const TIOCVHANGUP: ::Ioctl = 0x5437; ++pub const TIOCGPKT: ::Ioctl = 0x40045438; ++pub const TIOCGPTLCK: ::Ioctl = 0x40045439; ++pub const TIOCGEXCL: ::Ioctl = 0x40045440; ++pub const TIOCGPTPEER: ::Ioctl = 0x20005441; ++//pub const TIOCGISO7816: ::Ioctl = 0x40285442; ++//pub const TIOCSISO7816: ::Ioctl = 0xc0285443; ++pub const FIONCLEX: ::Ioctl = 0x20006602; ++pub const FIOCLEX: ::Ioctl = 0x20006601; ++pub const FIOASYNC: ::Ioctl = 0x8004667d; ++pub const TIOCSERCONFIG: ::Ioctl = 0x5453; ++pub const TIOCSERGWILD: ::Ioctl = 0x5454; ++pub const TIOCSERSWILD: ::Ioctl = 0x5455; ++pub const TIOCGLCKTRMIOS: ::Ioctl = 0x5456; ++pub const TIOCSLCKTRMIOS: ::Ioctl = 0x5457; ++pub const TIOCSERGSTRUCT: ::Ioctl = 0x5458; ++pub const TIOCSERGETLSR: ::Ioctl = 0x5459; ++pub const TIOCSERGETMULTI: ::Ioctl = 0x545A; ++pub const TIOCSERSETMULTI: ::Ioctl = 0x545B; ++pub const TIOCMIWAIT: ::Ioctl = 0x545C; ++pub const TIOCGICOUNT: ::Ioctl = 0x545D; ++pub const BLKIOMIN: ::Ioctl = 0x20001278; ++pub const BLKIOOPT: ::Ioctl = 0x20001279; ++pub const BLKSSZGET: ::Ioctl = 0x20001268; ++pub const BLKPBSZGET: ::Ioctl = 0x2000127B; ++//pub const FIOQSIZE: ::Ioctl = 0x40086680; ++ ++pub const TIOCM_LE: ::c_int = 0x001; ++pub const TIOCM_DTR: ::c_int = 0x002; ++pub const TIOCM_RTS: ::c_int = 0x004; ++pub const TIOCM_ST: ::c_int = 0x008; ++pub const TIOCM_SR: ::c_int = 0x010; ++pub const TIOCM_CTS: ::c_int = 0x020; ++pub const TIOCM_CAR: ::c_int = 0x040; ++pub const TIOCM_CD: ::c_int = TIOCM_CAR; ++pub const TIOCM_RNG: ::c_int = 0x080; ++pub const TIOCM_RI: ::c_int = TIOCM_RNG; ++pub const TIOCM_DSR: ::c_int = 0x100; ++ ++pub const BOTHER: ::speed_t = 0o0037; ++pub const IBSHIFT: ::tcflag_t = 16; ++ ++// RLIMIT Constants ++ ++cfg_if! { ++ if #[cfg(target_env = "gnu")] { ++ ++ pub const RLIMIT_CPU: ::__rlimit_resource_t = 0; ++ pub const RLIMIT_FSIZE: ::__rlimit_resource_t = 1; ++ pub const RLIMIT_DATA: ::__rlimit_resource_t = 2; ++ pub const RLIMIT_STACK: ::__rlimit_resource_t = 3; ++ pub const RLIMIT_CORE: ::__rlimit_resource_t = 4; ++ pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; ++ pub const RLIMIT_NPROC: ::__rlimit_resource_t = 6; ++ pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 7; ++ pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; ++ pub const RLIMIT_AS: ::__rlimit_resource_t = 9; ++ pub const RLIMIT_LOCKS: ::__rlimit_resource_t = 10; ++ pub const RLIMIT_SIGPENDING: ::__rlimit_resource_t = 11; ++ pub const RLIMIT_MSGQUEUE: ::__rlimit_resource_t = 12; ++ pub const RLIMIT_NICE: ::__rlimit_resource_t = 13; ++ pub const RLIMIT_RTPRIO: ::__rlimit_resource_t = 14; ++ pub const RLIMIT_RTTIME: ::__rlimit_resource_t = 15; ++ pub const RLIM_NLIMITS: ::__rlimit_resource_t = 16; ++ pub const RLIMIT_NLIMITS: ::__rlimit_resource_t = RLIM_NLIMITS; ++ ++ } else if #[cfg(target_env = "musl")] { ++ ++ pub const RLIMIT_CPU: ::c_int = 0; ++ pub const RLIMIT_FSIZE: ::c_int = 1; ++ pub const RLIMIT_DATA: ::c_int = 2; ++ pub const RLIMIT_STACK: ::c_int = 3; ++ pub const RLIMIT_CORE: ::c_int = 4; ++ pub const RLIMIT_RSS: ::c_int = 5; ++ pub const RLIMIT_NPROC: ::c_int = 6; ++ pub const RLIMIT_NOFILE: ::c_int = 7; ++ pub const RLIMIT_MEMLOCK: ::c_int = 8; ++ pub const RLIMIT_AS: ::c_int = 9; ++ pub const RLIMIT_LOCKS: ::c_int = 10; ++ pub const RLIMIT_SIGPENDING: ::c_int = 11; ++ pub const RLIMIT_MSGQUEUE: ::c_int = 12; ++ pub const RLIMIT_NICE: ::c_int = 13; ++ pub const RLIMIT_RTPRIO: ::c_int = 14; ++ pub const RLIMIT_RTTIME: ::c_int = 15; ++ pub const RLIM_NLIMITS: ::c_int = 15; ++ pub const RLIMIT_NLIMITS: ::c_int = RLIM_NLIMITS; ++ } ++} ++pub const RLIM_INFINITY: ::rlim_t = !0; +diff --git a/vendor/libc/src/unix/linux_like/linux/arch/sparc/mod.rs b/vendor/libc/src/unix/linux_like/linux/arch/sparc/mod.rs +index d4f9bb0..da3e388 100644 +--- a/vendor/libc/src/unix/linux_like/linux/arch/sparc/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/arch/sparc/mod.rs +@@ -1,3 +1,16 @@ ++s! { ++ pub struct termios2 { ++ pub c_iflag: ::tcflag_t, ++ pub c_oflag: ::tcflag_t, ++ pub c_cflag: ::tcflag_t, ++ pub c_lflag: ::tcflag_t, ++ pub c_line: ::cc_t, ++ pub c_cc: [::cc_t; 19], ++ pub c_ispeed: ::speed_t, ++ pub c_ospeed: ::speed_t, ++ } ++} ++ + // arch/sparc/include/uapi/asm/socket.h + pub const SOL_SOCKET: ::c_int = 0xffff; + +@@ -86,3 +99,130 @@ pub const SO_TIMESTAMPING: ::c_int = 0x0023; + // pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP; + pub const SCM_TIMESTAMPNS: ::c_int = SO_TIMESTAMPNS; + pub const SCM_TIMESTAMPING: ::c_int = SO_TIMESTAMPING; ++ ++// Ioctl Constants ++ ++pub const TCGETS: ::Ioctl = 0x40245408; ++pub const TCSETS: ::Ioctl = 0x80245409; ++pub const TCSETSW: ::Ioctl = 0x8024540a; ++pub const TCSETSF: ::Ioctl = 0x8024540b; ++pub const TCGETA: ::Ioctl = 0x40125401; ++pub const TCSETA: ::Ioctl = 0x80125402; ++pub const TCSETAW: ::Ioctl = 0x80125403; ++pub const TCSETAF: ::Ioctl = 0x80125404; ++pub const TCSBRK: ::Ioctl = 0x20005405; ++pub const TCXONC: ::Ioctl = 0x20005406; ++pub const TCFLSH: ::Ioctl = 0x20005407; ++pub const TIOCEXCL: ::Ioctl = 0x2000740d; ++pub const TIOCNXCL: ::Ioctl = 0x2000740e; ++pub const TIOCSCTTY: ::Ioctl = 0x20007484; ++pub const TIOCGPGRP: ::Ioctl = 0x40047483; ++pub const TIOCSPGRP: ::Ioctl = 0x80047482; ++pub const TIOCOUTQ: ::Ioctl = 0x40047473; ++pub const TIOCSTI: ::Ioctl = 0x80017472; ++pub const TIOCGWINSZ: ::Ioctl = 0x40087468; ++pub const TIOCSWINSZ: ::Ioctl = 0x80087467; ++pub const TIOCMGET: ::Ioctl = 0x4004746a; ++pub const TIOCMBIS: ::Ioctl = 0x8004746c; ++pub const TIOCMBIC: ::Ioctl = 0x8004746b; ++pub const TIOCMSET: ::Ioctl = 0x8004746d; ++pub const TIOCGSOFTCAR: ::Ioctl = 0x40047464; ++pub const TIOCSSOFTCAR: ::Ioctl = 0x80047465; ++pub const FIONREAD: ::Ioctl = 0x4004667f; ++pub const TIOCINQ: ::Ioctl = FIONREAD; ++pub const TIOCLINUX: ::Ioctl = 0x541C; ++pub const TIOCCONS: ::Ioctl = 0x20007424; ++pub const TIOCGSERIAL: ::Ioctl = 0x541E; ++pub const TIOCSSERIAL: ::Ioctl = 0x541F; ++pub const TIOCPKT: ::Ioctl = 0x80047470; ++pub const FIONBIO: ::Ioctl = 0x8004667e; ++pub const TIOCNOTTY: ::Ioctl = 0x20007471; ++pub const TIOCSETD: ::Ioctl = 0x80047401; ++pub const TIOCGETD: ::Ioctl = 0x40047400; ++pub const TCSBRKP: ::Ioctl = 0x5425; ++pub const TIOCSBRK: ::Ioctl = 0x2000747b; ++pub const TIOCCBRK: ::Ioctl = 0x2000747a; ++pub const TIOCGSID: ::Ioctl = 0x40047485; ++pub const TCGETS2: ::Ioctl = 0x402c540c; ++pub const TCSETS2: ::Ioctl = 0x802c540d; ++pub const TCSETSW2: ::Ioctl = 0x802c540e; ++pub const TCSETSF2: ::Ioctl = 0x802c540f; ++pub const TIOCGPTN: ::Ioctl = 0x40047486; ++pub const TIOCSPTLCK: ::Ioctl = 0x80047487; ++pub const TIOCGDEV: ::Ioctl = 0x40045432; ++pub const TIOCSIG: ::Ioctl = 0x80047488; ++pub const TIOCVHANGUP: ::Ioctl = 0x20005437; ++pub const TIOCGPKT: ::Ioctl = 0x40045438; ++pub const TIOCGPTLCK: ::Ioctl = 0x40045439; ++pub const TIOCGEXCL: ::Ioctl = 0x40045440; ++pub const TIOCGPTPEER: ::Ioctl = 0x20007489; ++pub const FIONCLEX: ::Ioctl = 0x20006602; ++pub const FIOCLEX: ::Ioctl = 0x20006601; ++pub const TIOCSERCONFIG: ::Ioctl = 0x5453; ++pub const TIOCSERGWILD: ::Ioctl = 0x5454; ++pub const TIOCSERSWILD: ::Ioctl = 0x5455; ++pub const TIOCGLCKTRMIOS: ::Ioctl = 0x5456; ++pub const TIOCSLCKTRMIOS: ::Ioctl = 0x5457; ++pub const TIOCSERGSTRUCT: ::Ioctl = 0x5458; ++pub const TIOCSERGETLSR: ::Ioctl = 0x5459; ++pub const TIOCSERGETMULTI: ::Ioctl = 0x545A; ++pub const TIOCSERSETMULTI: ::Ioctl = 0x545B; ++pub const TIOCMIWAIT: ::Ioctl = 0x545C; ++pub const TIOCGICOUNT: ::Ioctl = 0x545D; ++pub const TIOCSTART: ::Ioctl = 0x2000746e; ++pub const TIOCSTOP: ::Ioctl = 0x2000746f; ++pub const BLKIOMIN: ::Ioctl = 0x20001278; ++pub const BLKIOOPT: ::Ioctl = 0x20001279; ++pub const BLKSSZGET: ::Ioctl = 0x20001268; ++pub const BLKPBSZGET: ::Ioctl = 0x2000127B; ++ ++//pub const FIOASYNC: ::Ioctl = 0x4004667d; ++//pub const FIOQSIZE: ::Ioctl = ; ++//pub const TIOCGISO7816: ::Ioctl = 0x40285443; ++//pub const TIOCSISO7816: ::Ioctl = 0xc0285444; ++//pub const TIOCGRS485: ::Ioctl = 0x40205441; ++//pub const TIOCSRS485: ::Ioctl = 0xc0205442; ++ ++pub const TIOCM_LE: ::c_int = 0x001; ++pub const TIOCM_DTR: ::c_int = 0x002; ++pub const TIOCM_RTS: ::c_int = 0x004; ++pub const TIOCM_ST: ::c_int = 0x008; ++pub const TIOCM_SR: ::c_int = 0x010; ++pub const TIOCM_CTS: ::c_int = 0x020; ++pub const TIOCM_CAR: ::c_int = 0x040; ++pub const TIOCM_CD: ::c_int = TIOCM_CAR; ++pub const TIOCM_RNG: ::c_int = 0x080; ++pub const TIOCM_RI: ::c_int = TIOCM_RNG; ++pub const TIOCM_DSR: ::c_int = 0x100; ++ ++pub const BOTHER: ::speed_t = 0x1000; ++pub const IBSHIFT: ::tcflag_t = 16; ++ ++// RLIMIT Constants ++ ++pub const RLIMIT_CPU: ::__rlimit_resource_t = 0; ++pub const RLIMIT_FSIZE: ::__rlimit_resource_t = 1; ++pub const RLIMIT_DATA: ::__rlimit_resource_t = 2; ++pub const RLIMIT_STACK: ::__rlimit_resource_t = 3; ++pub const RLIMIT_CORE: ::__rlimit_resource_t = 4; ++pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; ++pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 6; ++pub const RLIMIT_NPROC: ::__rlimit_resource_t = 7; ++pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; ++pub const RLIMIT_AS: ::__rlimit_resource_t = 9; ++pub const RLIMIT_LOCKS: ::__rlimit_resource_t = 10; ++pub const RLIMIT_SIGPENDING: ::__rlimit_resource_t = 11; ++pub const RLIMIT_MSGQUEUE: ::__rlimit_resource_t = 12; ++pub const RLIMIT_NICE: ::__rlimit_resource_t = 13; ++pub const RLIMIT_RTPRIO: ::__rlimit_resource_t = 14; ++pub const RLIMIT_RTTIME: ::__rlimit_resource_t = 15; ++pub const RLIM_NLIMITS: ::__rlimit_resource_t = 16; ++pub const RLIMIT_NLIMITS: ::__rlimit_resource_t = RLIM_NLIMITS; ++ ++cfg_if! { ++ if #[cfg(target_arch = "sparc64")] { ++ pub const RLIM_INFINITY: ::rlim_t = !0; ++ } else if #[cfg(target_arch = "sparc")] { ++ pub const RLIM_INFINITY: ::rlim_t = 0x7fffffff; ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/align.rs +index 825546b..2645ec4 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/align.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/align.rs +@@ -4,4 +4,50 @@ s_no_extra_traits! { + pub struct max_align_t { + priv_: [i64; 2] + } ++ ++ #[allow(missing_debug_implementations)] ++ #[repr(align(8))] ++ pub struct ucontext_t { ++ pub uc_flags: ::c_ulong, ++ pub uc_link: *mut ucontext_t, ++ pub uc_stack: ::stack_t, ++ pub uc_mcontext: ::mcontext_t, ++ pub uc_sigmask: ::sigset_t, ++ pub uc_regspace: [::c_ulong; 128], ++ } ++} ++ ++cfg_if! { ++ if #[cfg(feature = "extra_traits")] { ++ impl PartialEq for ucontext_t { ++ fn eq(&self, other: &ucontext_t) -> bool { ++ self.uc_flags == other.uc_flags ++ && self.uc_link == other.uc_link ++ && self.uc_stack == other.uc_stack ++ && self.uc_mcontext == other.uc_mcontext ++ && self.uc_sigmask == other.uc_sigmask ++ } ++ } ++ impl Eq for ucontext_t {} ++ impl ::fmt::Debug for ucontext_t { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("ucontext_t") ++ .field("uc_flags", &self.uc_link) ++ .field("uc_link", &self.uc_link) ++ .field("uc_stack", &self.uc_stack) ++ .field("uc_mcontext", &self.uc_mcontext) ++ .field("uc_sigmask", &self.uc_sigmask) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for ucontext_t { ++ fn hash(&self, state: &mut H) { ++ self.uc_flags.hash(state); ++ self.uc_link.hash(state); ++ self.uc_stack.hash(state); ++ self.uc_mcontext.hash(state); ++ self.uc_sigmask.hash(state); ++ } ++ } ++ } + } +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/mod.rs +index 0e7fb70..fd690a1 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/mod.rs +@@ -141,17 +141,6 @@ s! { + __glibc_reserved5: ::c_ulong, + } + +- pub struct termios2 { +- pub c_iflag: ::tcflag_t, +- pub c_oflag: ::tcflag_t, +- pub c_cflag: ::tcflag_t, +- pub c_lflag: ::tcflag_t, +- pub c_line: ::cc_t, +- pub c_cc: [::cc_t; 19], +- pub c_ispeed: ::speed_t, +- pub c_ospeed: ::speed_t, +- } +- + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, +@@ -172,9 +161,59 @@ s! { + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } ++ ++ pub struct seccomp_notif_sizes { ++ pub seccomp_notif: ::__u16, ++ pub seccomp_notif_resp: ::__u16, ++ pub seccomp_data: ::__u16, ++ } ++ ++ pub struct mcontext_t { ++ pub trap_no: ::c_ulong, ++ pub error_code: ::c_ulong, ++ pub oldmask: ::c_ulong, ++ pub arm_r0: ::c_ulong, ++ pub arm_r1: ::c_ulong, ++ pub arm_r2: ::c_ulong, ++ pub arm_r3: ::c_ulong, ++ pub arm_r4: ::c_ulong, ++ pub arm_r5: ::c_ulong, ++ pub arm_r6: ::c_ulong, ++ pub arm_r7: ::c_ulong, ++ pub arm_r8: ::c_ulong, ++ pub arm_r9: ::c_ulong, ++ pub arm_r10: ::c_ulong, ++ pub arm_fp: ::c_ulong, ++ pub arm_ip: ::c_ulong, ++ pub arm_sp: ::c_ulong, ++ pub arm_lr: ::c_ulong, ++ pub arm_pc: ::c_ulong, ++ pub arm_cpsr: ::c_ulong, ++ pub fault_address: ::c_ulong, ++ } ++ ++ pub struct user_regs { ++ pub arm_r0: ::c_ulong, ++ pub arm_r1: ::c_ulong, ++ pub arm_r2: ::c_ulong, ++ pub arm_r3: ::c_ulong, ++ pub arm_r4: ::c_ulong, ++ pub arm_r5: ::c_ulong, ++ pub arm_r6: ::c_ulong, ++ pub arm_r7: ::c_ulong, ++ pub arm_r8: ::c_ulong, ++ pub arm_r9: ::c_ulong, ++ pub arm_r10: ::c_ulong, ++ pub arm_fp: ::c_ulong, ++ pub arm_ip: ::c_ulong, ++ pub arm_sp: ::c_ulong, ++ pub arm_lr: ::c_ulong, ++ pub arm_pc: ::c_ulong, ++ pub arm_cpsr: ::c_ulong, ++ pub arm_orig_r0: ::c_ulong, ++ } + } + +-pub const RLIM_INFINITY: ::rlim_t = !0; + pub const VEOF: usize = 4; + pub const RTLD_DEEPBIND: ::c_int = 0x8; + pub const RTLD_GLOBAL: ::c_int = 0x100; +@@ -194,11 +233,6 @@ pub const O_DSYNC: ::c_int = 4096; + pub const O_FSYNC: ::c_int = 0x101000; + pub const O_ASYNC: ::c_int = 0x2000; + pub const O_NDELAY: ::c_int = 0x800; +-pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 7; +-pub const RLIMIT_NPROC: ::__rlimit_resource_t = 6; +-pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; +-pub const RLIMIT_AS: ::__rlimit_resource_t = 9; +-pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; + + pub const MADV_SOFT_OFFLINE: ::c_int = 101; + pub const MAP_LOCKED: ::c_int = 0x02000; +@@ -305,10 +339,6 @@ pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + pub const SOCK_STREAM: ::c_int = 1; + pub const SOCK_DGRAM: ::c_int = 2; + +-pub const FIOCLEX: ::c_ulong = 0x5451; +-pub const FIONCLEX: ::c_ulong = 0x5450; +-pub const FIONBIO: ::c_ulong = 0x5421; +- + pub const MCL_CURRENT: ::c_int = 0x0001; + pub const MCL_FUTURE: ::c_int = 0x0002; + +@@ -419,7 +449,6 @@ pub const B19200: ::speed_t = 0o000016; + pub const B38400: ::speed_t = 0o000017; + pub const EXTA: ::speed_t = B19200; + pub const EXTB: ::speed_t = B38400; +-pub const BOTHER: ::speed_t = 0o010000; + pub const B57600: ::speed_t = 0o010001; + pub const B115200: ::speed_t = 0o010002; + pub const B230400: ::speed_t = 0o010003; +@@ -436,6 +465,11 @@ pub const B3000000: ::speed_t = 0o010015; + pub const B3500000: ::speed_t = 0o010016; + pub const B4000000: ::speed_t = 0o010017; + ++pub const SECCOMP_SET_MODE_STRICT: ::c_uint = 0; ++pub const SECCOMP_SET_MODE_FILTER: ::c_uint = 1; ++pub const SECCOMP_GET_ACTION_AVAIL: ::c_uint = 2; ++pub const SECCOMP_GET_NOTIF_SIZES: ::c_uint = 3; ++ + pub const VEOL: usize = 11; + pub const VEOL2: usize = 16; + pub const VMIN: usize = 6; +@@ -443,52 +477,11 @@ pub const IEXTEN: ::tcflag_t = 0x00008000; + pub const TOSTOP: ::tcflag_t = 0x00000100; + pub const FLUSHO: ::tcflag_t = 0x00001000; + pub const EXTPROC: ::tcflag_t = 0x00010000; +-pub const TCGETS: ::c_ulong = 0x5401; +-pub const TCSETS: ::c_ulong = 0x5402; +-pub const TCSETSW: ::c_ulong = 0x5403; +-pub const TCSETSF: ::c_ulong = 0x5404; +-pub const TCGETA: ::c_ulong = 0x5405; +-pub const TCSETA: ::c_ulong = 0x5406; +-pub const TCSETAW: ::c_ulong = 0x5407; +-pub const TCSETAF: ::c_ulong = 0x5408; +-pub const TCSBRK: ::c_ulong = 0x5409; +-pub const TCXONC: ::c_ulong = 0x540A; +-pub const TCFLSH: ::c_ulong = 0x540B; +-pub const TIOCINQ: ::c_ulong = 0x541B; +-pub const TIOCGPGRP: ::c_ulong = 0x540F; +-pub const TIOCSPGRP: ::c_ulong = 0x5410; +-pub const TIOCOUTQ: ::c_ulong = 0x5411; +-pub const TIOCGWINSZ: ::c_ulong = 0x5413; +-pub const TIOCSWINSZ: ::c_ulong = 0x5414; +-pub const TIOCGRS485: ::c_int = 0x542E; +-pub const TIOCSRS485: ::c_int = 0x542F; +-pub const FIONREAD: ::c_ulong = 0x541B; +- +-pub const TIOCGSOFTCAR: ::c_ulong = 0x5419; +-pub const TIOCSSOFTCAR: ::c_ulong = 0x541A; +-pub const TIOCEXCL: ::c_ulong = 0x540C; +-pub const TIOCNXCL: ::c_ulong = 0x540D; +-pub const TIOCSCTTY: ::c_ulong = 0x540E; +-pub const TIOCSTI: ::c_ulong = 0x5412; +-pub const TIOCMGET: ::c_ulong = 0x5415; +-pub const TIOCMBIS: ::c_ulong = 0x5416; +-pub const TIOCMBIC: ::c_ulong = 0x5417; +-pub const TIOCMSET: ::c_ulong = 0x5418; +-pub const TIOCCONS: ::c_ulong = 0x541D; + + pub const TCSANOW: ::c_int = 0; + pub const TCSADRAIN: ::c_int = 1; + pub const TCSAFLUSH: ::c_int = 2; + +-pub const TIOCLINUX: ::c_ulong = 0x541C; +-pub const TIOCGSERIAL: ::c_ulong = 0x541E; +-pub const TIOCM_ST: ::c_int = 0x008; +-pub const TIOCM_SR: ::c_int = 0x010; +-pub const TIOCM_CTS: ::c_int = 0x020; +-pub const TIOCM_CAR: ::c_int = 0x040; +-pub const TIOCM_RNG: ::c_int = 0x080; +-pub const TIOCM_DSR: ::c_int = 0x100; +- + // Syscall table + pub const SYS_restart_syscall: ::c_long = 0; + pub const SYS_exit: ::c_long = 1; +@@ -843,6 +836,8 @@ pub const SYS_pkey_mprotect: ::c_long = 394; + pub const SYS_pkey_alloc: ::c_long = 395; + pub const SYS_pkey_free: ::c_long = 396; + pub const SYS_statx: ::c_long = 397; ++pub const SYS_rseq: ::c_long = 398; ++pub const SYS_kexec_file_load: ::c_long = 401; + pub const SYS_pidfd_send_signal: ::c_long = 424; + pub const SYS_io_uring_setup: ::c_long = 425; + pub const SYS_io_uring_enter: ::c_long = 426; +@@ -862,6 +857,14 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; + + cfg_if! { + if #[cfg(libc_align)] { +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/m68k/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/m68k/align.rs +new file mode 100644 +index 0000000..639394a +--- /dev/null ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/m68k/align.rs +@@ -0,0 +1,7 @@ ++s_no_extra_traits! { ++ #[allow(missing_debug_implementations)] ++ #[repr(align(2))] ++ pub struct max_align_t { ++ priv_: [i8; 20] ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/m68k/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/m68k/mod.rs +new file mode 100644 +index 0000000..69725ee +--- /dev/null ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/m68k/mod.rs +@@ -0,0 +1,849 @@ ++pub type c_char = i8; ++pub type wchar_t = i32; ++ ++s! { ++ pub struct sigaction { ++ pub sa_sigaction: ::sighandler_t, ++ pub sa_mask: ::sigset_t, ++ pub sa_flags: ::c_int, ++ pub sa_restorer: ::Option, ++ } ++ ++ pub struct statfs { ++ pub f_type: ::__fsword_t, ++ pub f_bsize: ::__fsword_t, ++ pub f_blocks: ::fsblkcnt_t, ++ pub f_bfree: ::fsblkcnt_t, ++ pub f_bavail: ::fsblkcnt_t, ++ ++ pub f_files: ::fsfilcnt_t, ++ pub f_ffree: ::fsfilcnt_t, ++ pub f_fsid: ::fsid_t, ++ ++ pub f_namelen: ::__fsword_t, ++ pub f_frsize: ::__fsword_t, ++ pub f_flags: ::__fsword_t, ++ f_spare: [::__fsword_t; 4], ++ } ++ ++ pub struct flock { ++ pub l_type: ::c_short, ++ pub l_whence: ::c_short, ++ pub l_start: ::off_t, ++ pub l_len: ::off_t, ++ pub l_pid: ::pid_t, ++ } ++ ++ pub struct flock64 { ++ pub l_type: ::c_short, ++ pub l_whence: ::c_short, ++ pub l_start: ::off64_t, ++ pub l_len: ::off64_t, ++ pub l_pid: ::pid_t, ++ } ++ ++ pub struct ipc_perm { ++ __key: ::key_t, ++ pub uid: ::uid_t, ++ pub gid: ::gid_t, ++ pub cuid: ::uid_t, ++ pub cgid: ::gid_t, ++ pub mode: ::mode_t, ++ __seq: ::c_ushort, ++ __pad1: ::c_ushort, ++ __glibc_reserved1: ::c_ulong, ++ __glibc_reserved2: ::c_ulong, ++ } ++ ++ pub struct stat64 { ++ pub st_dev: ::dev_t, ++ __pad1: ::c_ushort, ++ pub __st_ino: ::ino_t, ++ pub st_mode: ::mode_t, ++ pub st_nlink: ::nlink_t, ++ pub st_uid: ::uid_t, ++ pub st_gid: ::gid_t, ++ pub st_rdev: ::dev_t, ++ __pad2: ::c_ushort, ++ pub st_size: ::off64_t, ++ pub st_blksize: ::blksize_t, ++ pub st_blocks: ::blkcnt64_t, ++ pub st_atime: ::time_t, ++ pub st_atime_nsec: ::c_ulong, ++ pub st_mtime: ::time_t, ++ pub st_mtime_nsec: ::c_ulong, ++ pub st_ctime: ::time_t, ++ pub st_ctime_nsec: ::c_ulong, ++ pub st_ino: ::ino64_t, ++ } ++ ++ pub struct statfs64 { ++ pub f_type: ::__fsword_t, ++ pub f_bsize: ::__fsword_t, ++ pub f_blocks: ::fsblkcnt64_t, ++ pub f_bfree: ::fsblkcnt64_t, ++ pub f_bavail: ::fsblkcnt64_t, ++ pub f_files: ::fsblkcnt64_t, ++ pub f_ffree: ::fsblkcnt64_t, ++ pub f_fsid: ::fsid_t, ++ pub f_namelen: ::__fsword_t, ++ pub f_frsize: ::__fsword_t, ++ pub f_flags: ::__fsword_t, ++ pub f_spare: [::__fsword_t; 4], ++ } ++ ++ pub struct statvfs64 { ++ pub f_bsize: ::c_ulong, ++ pub f_frsize: ::c_ulong, ++ pub f_blocks: ::fsblkcnt64_t, ++ pub f_bfree: ::fsblkcnt64_t, ++ pub f_bavail: ::fsblkcnt64_t, ++ pub f_files: ::fsblkcnt64_t, ++ pub f_ffree: ::fsblkcnt64_t, ++ pub f_favail: ::fsblkcnt64_t, ++ pub f_fsid: ::c_ulong, ++ __f_unused: ::c_int, ++ pub f_flag: ::c_ulong, ++ pub f_namemax: ::c_ulong, ++ __f_spare: [::c_int; 6], ++ } ++ ++ pub struct shmid_ds { ++ pub shm_perm: ::ipc_perm, ++ pub shm_segsz: ::size_t, ++ pub shm_atime: ::time_t, ++ __glibc_reserved1: ::c_long, ++ pub shm_dtime: ::time_t, ++ __glibc_reserved2: ::c_long, ++ pub shm_ctime: ::time_t, ++ __glibc_reserved3: ::c_long, ++ pub shm_cpid: ::pid_t, ++ pub shm_lpid: ::pid_t, ++ pub shm_nattch: ::shmatt_t, ++ __glibc_reserved5: ::c_ulong, ++ __glibc_reserved6: ::c_ulong, ++ } ++ ++ pub struct msqid_ds { ++ pub msg_perm: ::ipc_perm, ++ pub msg_stime: ::time_t, ++ __glibc_reserved1: ::c_uint, ++ pub msg_rtime: ::time_t, ++ __glibc_reserved2: ::c_uint, ++ pub msg_ctime: ::time_t, ++ __glibc_reserved3: ::c_uint, ++ __msg_cbytes: ::c_ulong, ++ pub msg_qnum: ::msgqnum_t, ++ pub msg_qbytes: ::msglen_t, ++ pub msg_lspid: ::pid_t, ++ pub msg_lrpid: ::pid_t, ++ __glibc_reserved4: ::c_ulong, ++ __glibc_reserved5: ::c_ulong, ++ } ++ ++ pub struct siginfo_t { ++ pub si_signo: ::c_int, ++ pub si_code: ::c_int, ++ pub si_errno: ::c_int, ++ _pad: [::c_int; 29], ++ _align: [usize; 0], ++ } ++ ++ pub struct stack_t { ++ pub ss_sp: *mut ::c_void, ++ pub ss_flags: ::c_int, ++ pub ss_size: ::size_t ++ } ++} ++ ++pub const VEOF: usize = 4; ++pub const RTLD_DEEPBIND: ::c_int = 0x8; ++pub const RTLD_GLOBAL: ::c_int = 0x100; ++pub const RTLD_NOLOAD: ::c_int = 0x4; ++pub const O_DIRECT: ::c_int = 0x10000; ++pub const O_DIRECTORY: ::c_int = 0x4000; ++pub const O_NOFOLLOW: ::c_int = 0x8000; ++pub const O_LARGEFILE: ::c_int = 0x20000; ++pub const O_APPEND: ::c_int = 1024; ++pub const O_CREAT: ::c_int = 64; ++pub const O_EXCL: ::c_int = 128; ++pub const O_NOCTTY: ::c_int = 256; ++pub const O_NONBLOCK: ::c_int = 2048; ++pub const O_SYNC: ::c_int = 1052672; ++pub const O_RSYNC: ::c_int = 1052672; ++pub const O_DSYNC: ::c_int = 4096; ++pub const O_FSYNC: ::c_int = 0x101000; ++pub const O_ASYNC: ::c_int = 0x2000; ++pub const O_NDELAY: ::c_int = 0x800; ++ ++pub const MADV_SOFT_OFFLINE: ::c_int = 101; ++pub const MAP_LOCKED: ::c_int = 0x02000; ++pub const MAP_NORESERVE: ::c_int = 0x04000; ++pub const MAP_32BIT: ::c_int = 0x0040; ++pub const MAP_ANON: ::c_int = 0x0020; ++pub const MAP_ANONYMOUS: ::c_int = 0x0020; ++pub const MAP_DENYWRITE: ::c_int = 0x0800; ++pub const MAP_EXECUTABLE: ::c_int = 0x01000; ++pub const MAP_POPULATE: ::c_int = 0x08000; ++pub const MAP_NONBLOCK: ::c_int = 0x010000; ++pub const MAP_STACK: ::c_int = 0x020000; ++pub const MAP_HUGETLB: ::c_int = 0x040000; ++pub const MAP_GROWSDOWN: ::c_int = 0x0100; ++pub const MAP_SYNC: ::c_int = 0x080000; ++ ++pub const EDEADLOCK: ::c_int = 35; ++pub const EUCLEAN: ::c_int = 117; ++pub const ENOTNAM: ::c_int = 118; ++pub const ENAVAIL: ::c_int = 119; ++pub const EISNAM: ::c_int = 120; ++pub const EREMOTEIO: ::c_int = 121; ++pub const EDEADLK: ::c_int = 35; ++pub const ENAMETOOLONG: ::c_int = 36; ++pub const ENOLCK: ::c_int = 37; ++pub const ENOSYS: ::c_int = 38; ++pub const ENOTEMPTY: ::c_int = 39; ++pub const ELOOP: ::c_int = 40; ++pub const ENOMSG: ::c_int = 42; ++pub const EIDRM: ::c_int = 43; ++pub const ECHRNG: ::c_int = 44; ++pub const EL2NSYNC: ::c_int = 45; ++pub const EL3HLT: ::c_int = 46; ++pub const EL3RST: ::c_int = 47; ++pub const ELNRNG: ::c_int = 48; ++pub const EUNATCH: ::c_int = 49; ++pub const ENOCSI: ::c_int = 50; ++pub const EL2HLT: ::c_int = 51; ++pub const EBADE: ::c_int = 52; ++pub const EBADR: ::c_int = 53; ++pub const EXFULL: ::c_int = 54; ++pub const ENOANO: ::c_int = 55; ++pub const EBADRQC: ::c_int = 56; ++pub const EBADSLT: ::c_int = 57; ++pub const EMULTIHOP: ::c_int = 72; ++pub const EOVERFLOW: ::c_int = 75; ++pub const ENOTUNIQ: ::c_int = 76; ++pub const EBADFD: ::c_int = 77; ++pub const EBADMSG: ::c_int = 74; ++pub const EREMCHG: ::c_int = 78; ++pub const ELIBACC: ::c_int = 79; ++pub const ELIBBAD: ::c_int = 80; ++pub const ELIBSCN: ::c_int = 81; ++pub const ELIBMAX: ::c_int = 82; ++pub const ELIBEXEC: ::c_int = 83; ++pub const EILSEQ: ::c_int = 84; ++pub const ERESTART: ::c_int = 85; ++pub const ESTRPIPE: ::c_int = 86; ++pub const EUSERS: ::c_int = 87; ++pub const ENOTSOCK: ::c_int = 88; ++pub const EDESTADDRREQ: ::c_int = 89; ++pub const EMSGSIZE: ::c_int = 90; ++pub const EPROTOTYPE: ::c_int = 91; ++pub const ENOPROTOOPT: ::c_int = 92; ++pub const EPROTONOSUPPORT: ::c_int = 93; ++pub const ESOCKTNOSUPPORT: ::c_int = 94; ++pub const EOPNOTSUPP: ::c_int = 95; ++pub const EPFNOSUPPORT: ::c_int = 96; ++pub const EAFNOSUPPORT: ::c_int = 97; ++pub const EADDRINUSE: ::c_int = 98; ++pub const EADDRNOTAVAIL: ::c_int = 99; ++pub const ENETDOWN: ::c_int = 100; ++pub const ENETUNREACH: ::c_int = 101; ++pub const ENETRESET: ::c_int = 102; ++pub const ECONNABORTED: ::c_int = 103; ++pub const ECONNRESET: ::c_int = 104; ++pub const ENOBUFS: ::c_int = 105; ++pub const EISCONN: ::c_int = 106; ++pub const ENOTCONN: ::c_int = 107; ++pub const ESHUTDOWN: ::c_int = 108; ++pub const ETOOMANYREFS: ::c_int = 109; ++pub const ETIMEDOUT: ::c_int = 110; ++pub const ECONNREFUSED: ::c_int = 111; ++pub const EHOSTDOWN: ::c_int = 112; ++pub const EHOSTUNREACH: ::c_int = 113; ++pub const EALREADY: ::c_int = 114; ++pub const EINPROGRESS: ::c_int = 115; ++pub const ESTALE: ::c_int = 116; ++pub const EDQUOT: ::c_int = 122; ++pub const ENOMEDIUM: ::c_int = 123; ++pub const EMEDIUMTYPE: ::c_int = 124; ++pub const ECANCELED: ::c_int = 125; ++pub const ENOKEY: ::c_int = 126; ++pub const EKEYEXPIRED: ::c_int = 127; ++pub const EKEYREVOKED: ::c_int = 128; ++pub const EKEYREJECTED: ::c_int = 129; ++pub const EOWNERDEAD: ::c_int = 130; ++pub const ENOTRECOVERABLE: ::c_int = 131; ++pub const EHWPOISON: ::c_int = 133; ++pub const ERFKILL: ::c_int = 132; ++ ++pub const SA_SIGINFO: ::c_int = 0x00000004; ++pub const SA_NOCLDWAIT: ::c_int = 0x00000002; ++ ++pub const SOCK_STREAM: ::c_int = 1; ++pub const SOCK_DGRAM: ::c_int = 2; ++ ++pub const F_GETLK: ::c_int = 5; ++pub const F_GETOWN: ::c_int = 9; ++pub const F_SETOWN: ::c_int = 8; ++ ++pub const PTRACE_GETFPXREGS: ::c_uint = 18; ++pub const PTRACE_SETFPXREGS: ::c_uint = 19; ++pub const PTRACE_SYSEMU: ::c_uint = 31; ++pub const PTRACE_SYSEMU_SINGLESTEP: ::c_uint = 32; ++ ++pub const MCL_CURRENT: ::c_int = 0x0001; ++pub const MCL_FUTURE: ::c_int = 0x0002; ++ ++pub const POLLWRNORM: ::c_short = 0x100; ++pub const POLLWRBAND: ::c_short = 0x200; ++ ++pub const EFD_NONBLOCK: ::c_int = 0x800; ++pub const SFD_NONBLOCK: ::c_int = 0x0800; ++ ++pub const SIGCHLD: ::c_int = 17; ++pub const SIGBUS: ::c_int = 7; ++pub const SIGUSR1: ::c_int = 10; ++pub const SIGUSR2: ::c_int = 12; ++pub const SIGCONT: ::c_int = 18; ++pub const SIGSTOP: ::c_int = 19; ++pub const SIGTSTP: ::c_int = 20; ++pub const SIGURG: ::c_int = 23; ++pub const SIGIO: ::c_int = 29; ++pub const SIGSYS: ::c_int = 31; ++pub const SIGSTKFLT: ::c_int = 16; ++#[deprecated(since = "0.2.55", note = "Use SIGSYS instead")] ++pub const SIGUNUSED: ::c_int = 31; ++pub const SIGPOLL: ::c_int = 29; ++pub const SIGPWR: ::c_int = 30; ++pub const SIG_SETMASK: ::c_int = 2; ++pub const SIG_BLOCK: ::c_int = 0x000000; ++pub const SIG_UNBLOCK: ::c_int = 0x01; ++pub const SIGTTIN: ::c_int = 21; ++pub const SIGTTOU: ::c_int = 22; ++pub const SIGXCPU: ::c_int = 24; ++pub const SIGXFSZ: ::c_int = 25; ++pub const SIGVTALRM: ::c_int = 26; ++pub const SIGPROF: ::c_int = 27; ++pub const SIGWINCH: ::c_int = 28; ++pub const SIGSTKSZ: ::size_t = 8192; ++pub const MINSIGSTKSZ: ::size_t = 2048; ++pub const CBAUD: ::tcflag_t = 0o0010017; ++pub const TAB1: ::tcflag_t = 0x00000800; ++pub const TAB2: ::tcflag_t = 0x00001000; ++pub const TAB3: ::tcflag_t = 0x00001800; ++pub const CR1: ::tcflag_t = 0x00000200; ++pub const CR2: ::tcflag_t = 0x00000400; ++pub const CR3: ::tcflag_t = 0x00000600; ++pub const FF1: ::tcflag_t = 0x00008000; ++pub const BS1: ::tcflag_t = 0x00002000; ++pub const VT1: ::tcflag_t = 0x00004000; ++pub const VWERASE: usize = 14; ++pub const VREPRINT: usize = 12; ++pub const VSUSP: usize = 10; ++pub const VSTART: usize = 8; ++pub const VSTOP: usize = 9; ++pub const VDISCARD: usize = 13; ++pub const VTIME: usize = 5; ++pub const IXON: ::tcflag_t = 0x00000400; ++pub const IXOFF: ::tcflag_t = 0x00001000; ++pub const ONLCR: ::tcflag_t = 0x4; ++pub const CSIZE: ::tcflag_t = 0x00000030; ++pub const CS6: ::tcflag_t = 0x00000010; ++pub const CS7: ::tcflag_t = 0x00000020; ++pub const CS8: ::tcflag_t = 0x00000030; ++pub const CSTOPB: ::tcflag_t = 0x00000040; ++pub const CREAD: ::tcflag_t = 0x00000080; ++pub const PARENB: ::tcflag_t = 0x00000100; ++pub const PARODD: ::tcflag_t = 0x00000200; ++pub const HUPCL: ::tcflag_t = 0x00000400; ++pub const CLOCAL: ::tcflag_t = 0x00000800; ++pub const ECHOKE: ::tcflag_t = 0x00000800; ++pub const ECHOE: ::tcflag_t = 0x00000010; ++pub const ECHOK: ::tcflag_t = 0x00000020; ++pub const ECHONL: ::tcflag_t = 0x00000040; ++pub const ECHOPRT: ::tcflag_t = 0x00000400; ++pub const ECHOCTL: ::tcflag_t = 0x00000200; ++pub const ISIG: ::tcflag_t = 0x00000001; ++pub const ICANON: ::tcflag_t = 0x00000002; ++pub const PENDIN: ::tcflag_t = 0x00004000; ++pub const NOFLSH: ::tcflag_t = 0x00000080; ++pub const CIBAUD: ::tcflag_t = 0o02003600000; ++pub const CBAUDEX: ::tcflag_t = 0o010000; ++pub const VSWTC: usize = 7; ++pub const OLCUC: ::tcflag_t = 0o000002; ++pub const NLDLY: ::tcflag_t = 0o000400; ++pub const CRDLY: ::tcflag_t = 0o003000; ++pub const TABDLY: ::tcflag_t = 0o014000; ++pub const BSDLY: ::tcflag_t = 0o020000; ++pub const FFDLY: ::tcflag_t = 0o100000; ++pub const VTDLY: ::tcflag_t = 0o040000; ++pub const XTABS: ::tcflag_t = 0o014000; ++ ++pub const B0: ::speed_t = 0o000000; ++pub const B50: ::speed_t = 0o000001; ++pub const B75: ::speed_t = 0o000002; ++pub const B110: ::speed_t = 0o000003; ++pub const B134: ::speed_t = 0o000004; ++pub const B150: ::speed_t = 0o000005; ++pub const B200: ::speed_t = 0o000006; ++pub const B300: ::speed_t = 0o000007; ++pub const B600: ::speed_t = 0o000010; ++pub const B1200: ::speed_t = 0o000011; ++pub const B1800: ::speed_t = 0o000012; ++pub const B2400: ::speed_t = 0o000013; ++pub const B4800: ::speed_t = 0o000014; ++pub const B9600: ::speed_t = 0o000015; ++pub const B19200: ::speed_t = 0o000016; ++pub const B38400: ::speed_t = 0o000017; ++pub const EXTA: ::speed_t = B19200; ++pub const EXTB: ::speed_t = B38400; ++pub const B57600: ::speed_t = 0o010001; ++pub const B115200: ::speed_t = 0o010002; ++pub const B230400: ::speed_t = 0o010003; ++pub const B460800: ::speed_t = 0o010004; ++pub const B500000: ::speed_t = 0o010005; ++pub const B576000: ::speed_t = 0o010006; ++pub const B921600: ::speed_t = 0o010007; ++pub const B1000000: ::speed_t = 0o010010; ++pub const B1152000: ::speed_t = 0o010011; ++pub const B1500000: ::speed_t = 0o010012; ++pub const B2000000: ::speed_t = 0o010013; ++pub const B2500000: ::speed_t = 0o010014; ++pub const B3000000: ::speed_t = 0o010015; ++pub const B3500000: ::speed_t = 0o010016; ++pub const B4000000: ::speed_t = 0o010017; ++ ++pub const VEOL: usize = 11; ++pub const VEOL2: usize = 16; ++pub const VMIN: usize = 6; ++pub const IEXTEN: ::tcflag_t = 0x00008000; ++pub const TOSTOP: ::tcflag_t = 0x00000100; ++pub const FLUSHO: ::tcflag_t = 0x00001000; ++pub const EXTPROC: ::tcflag_t = 0x00010000; ++ ++pub const TCSANOW: ::c_int = 0; ++pub const TCSADRAIN: ::c_int = 1; ++pub const TCSAFLUSH: ::c_int = 2; ++ ++pub const SYS_restart_syscall: ::c_long = 0; ++pub const SYS_exit: ::c_long = 1; ++pub const SYS_fork: ::c_long = 2; ++pub const SYS_read: ::c_long = 3; ++pub const SYS_write: ::c_long = 4; ++pub const SYS_open: ::c_long = 5; ++pub const SYS_close: ::c_long = 6; ++pub const SYS_waitpid: ::c_long = 7; ++pub const SYS_creat: ::c_long = 8; ++pub const SYS_link: ::c_long = 9; ++pub const SYS_unlink: ::c_long = 10; ++pub const SYS_execve: ::c_long = 11; ++pub const SYS_chdir: ::c_long = 12; ++pub const SYS_time32: ::c_long = 13; ++pub const SYS_mknod: ::c_long = 14; ++pub const SYS_chmod: ::c_long = 15; ++pub const SYS_chown16: ::c_long = 16; ++pub const SYS_stat: ::c_long = 18; ++pub const SYS_lseek: ::c_long = 19; ++pub const SYS_getpid: ::c_long = 20; ++pub const SYS_mount: ::c_long = 21; ++pub const SYS_oldumount: ::c_long = 22; ++pub const SYS_setuid16: ::c_long = 23; ++pub const SYS_getuid16: ::c_long = 24; ++pub const SYS_stime32: ::c_long = 25; ++pub const SYS_ptrace: ::c_long = 26; ++pub const SYS_alarm: ::c_long = 27; ++pub const SYS_fstat: ::c_long = 28; ++pub const SYS_pause: ::c_long = 29; ++pub const SYS_utime32: ::c_long = 30; ++pub const SYS_access: ::c_long = 33; ++pub const SYS_nice: ::c_long = 34; ++pub const SYS_sync: ::c_long = 36; ++pub const SYS_kill: ::c_long = 37; ++pub const SYS_rename: ::c_long = 38; ++pub const SYS_mkdir: ::c_long = 39; ++pub const SYS_rmdir: ::c_long = 40; ++pub const SYS_dup: ::c_long = 41; ++pub const SYS_pipe: ::c_long = 42; ++pub const SYS_times: ::c_long = 43; ++pub const SYS_brk: ::c_long = 45; ++pub const SYS_setgid16: ::c_long = 46; ++pub const SYS_getgid16: ::c_long = 47; ++pub const SYS_signal: ::c_long = 48; ++pub const SYS_geteuid16: ::c_long = 49; ++pub const SYS_getegid16: ::c_long = 50; ++pub const SYS_acct: ::c_long = 51; ++pub const SYS_umount: ::c_long = 52; ++pub const SYS_ioctl: ::c_long = 54; ++pub const SYS_fcntl: ::c_long = 55; ++pub const SYS_setpgid: ::c_long = 57; ++pub const SYS_umask: ::c_long = 60; ++pub const SYS_chroot: ::c_long = 61; ++pub const SYS_ustat: ::c_long = 62; ++pub const SYS_dup2: ::c_long = 63; ++pub const SYS_getppid: ::c_long = 64; ++pub const SYS_getpgrp: ::c_long = 65; ++pub const SYS_setsid: ::c_long = 66; ++pub const SYS_sigaction: ::c_long = 67; ++pub const SYS_sgetmask: ::c_long = 68; ++pub const SYS_ssetmask: ::c_long = 69; ++pub const SYS_setreuid16: ::c_long = 70; ++pub const SYS_setregid16: ::c_long = 71; ++pub const SYS_sigsuspend: ::c_long = 72; ++pub const SYS_sigpending: ::c_long = 73; ++pub const SYS_sethostname: ::c_long = 74; ++pub const SYS_setrlimit: ::c_long = 75; ++pub const SYS_old_getrlimit: ::c_long = 76; ++pub const SYS_getrusage: ::c_long = 77; ++pub const SYS_gettimeofday: ::c_long = 78; ++pub const SYS_settimeofday: ::c_long = 79; ++pub const SYS_getgroups16: ::c_long = 80; ++pub const SYS_setgroups16: ::c_long = 81; ++pub const SYS_old_select: ::c_long = 82; ++pub const SYS_symlink: ::c_long = 83; ++pub const SYS_lstat: ::c_long = 84; ++pub const SYS_readlink: ::c_long = 85; ++pub const SYS_uselib: ::c_long = 86; ++pub const SYS_swapon: ::c_long = 87; ++pub const SYS_reboot: ::c_long = 88; ++pub const SYS_old_readdir: ::c_long = 89; ++pub const SYS_old_mmap: ::c_long = 90; ++pub const SYS_munmap: ::c_long = 91; ++pub const SYS_truncate: ::c_long = 92; ++pub const SYS_ftruncate: ::c_long = 93; ++pub const SYS_fchmod: ::c_long = 94; ++pub const SYS_fchown16: ::c_long = 95; ++pub const SYS_getpriority: ::c_long = 96; ++pub const SYS_setpriority: ::c_long = 97; ++pub const SYS_statfs: ::c_long = 99; ++pub const SYS_fstatfs: ::c_long = 100; ++pub const SYS_socketcall: ::c_long = 102; ++pub const SYS_syslog: ::c_long = 103; ++pub const SYS_setitimer: ::c_long = 104; ++pub const SYS_getitimer: ::c_long = 105; ++pub const SYS_newstat: ::c_long = 106; ++pub const SYS_newlstat: ::c_long = 107; ++pub const SYS_newfstat: ::c_long = 108; ++pub const SYS_vhangup: ::c_long = 111; ++pub const SYS_wait4: ::c_long = 114; ++pub const SYS_swapoff: ::c_long = 115; ++pub const SYS_sysinfo: ::c_long = 116; ++pub const SYS_ipc: ::c_long = 117; ++pub const SYS_fsync: ::c_long = 118; ++pub const SYS_sigreturn: ::c_long = 119; ++pub const SYS_clone: ::c_long = 120; ++pub const SYS_setdomainname: ::c_long = 121; ++pub const SYS_newuname: ::c_long = 122; ++pub const SYS_cacheflush: ::c_long = 123; ++pub const SYS_adjtimex_time32: ::c_long = 124; ++pub const SYS_mprotect: ::c_long = 125; ++pub const SYS_sigprocmask: ::c_long = 126; ++pub const SYS_create_module: ::c_long = 127; ++pub const SYS_init_module: ::c_long = 128; ++pub const SYS_delete_module: ::c_long = 129; ++pub const SYS_get_kernel_syms: ::c_long = 130; ++pub const SYS_quotactl: ::c_long = 131; ++pub const SYS_getpgid: ::c_long = 132; ++pub const SYS_fchdir: ::c_long = 133; ++pub const SYS_bdflush: ::c_long = 134; ++pub const SYS_sysfs: ::c_long = 135; ++pub const SYS_personality: ::c_long = 136; ++pub const SYS_setfsuid16: ::c_long = 138; ++pub const SYS_setfsgid16: ::c_long = 139; ++pub const SYS_llseek: ::c_long = 140; ++pub const SYS_getdents: ::c_long = 141; ++pub const SYS_select: ::c_long = 142; ++pub const SYS_flock: ::c_long = 143; ++pub const SYS_msync: ::c_long = 144; ++pub const SYS_readv: ::c_long = 145; ++pub const SYS_writev: ::c_long = 146; ++pub const SYS_getsid: ::c_long = 147; ++pub const SYS_fdatasync: ::c_long = 148; ++pub const SYS__sysctl: ::c_long = 149; ++pub const SYS_mlock: ::c_long = 150; ++pub const SYS_munlock: ::c_long = 151; ++pub const SYS_mlockall: ::c_long = 152; ++pub const SYS_munlockall: ::c_long = 153; ++pub const SYS_sched_setparam: ::c_long = 154; ++pub const SYS_sched_getparam: ::c_long = 155; ++pub const SYS_sched_setscheduler: ::c_long = 156; ++pub const SYS_sched_getscheduler: ::c_long = 157; ++pub const SYS_sched_yield: ::c_long = 158; ++pub const SYS_sched_get_priority_max: ::c_long = 159; ++pub const SYS_sched_get_priority_min: ::c_long = 160; ++pub const SYS_sched_rr_get_interval_time32: ::c_long = 161; ++pub const SYS_nanosleep_time32: ::c_long = 162; ++pub const SYS_mremap: ::c_long = 163; ++pub const SYS_setresuid16: ::c_long = 164; ++pub const SYS_getresuid16: ::c_long = 165; ++pub const SYS_getpagesize: ::c_long = 166; ++pub const SYS_query_module: ::c_long = 167; ++pub const SYS_poll: ::c_long = 168; ++pub const SYS_nfsservctl: ::c_long = 169; ++pub const SYS_setresgid16: ::c_long = 170; ++pub const SYS_getresgid16: ::c_long = 171; ++pub const SYS_prctl: ::c_long = 172; ++pub const SYS_rt_sigreturn: ::c_long = 173; ++pub const SYS_rt_sigaction: ::c_long = 174; ++pub const SYS_rt_sigprocmask: ::c_long = 175; ++pub const SYS_rt_sigpending: ::c_long = 176; ++pub const SYS_rt_sigtimedwait_time32: ::c_long = 177; ++pub const SYS_rt_sigqueueinfo: ::c_long = 178; ++pub const SYS_rt_sigsuspend: ::c_long = 179; ++pub const SYS_pread64: ::c_long = 180; ++pub const SYS_pwrite64: ::c_long = 181; ++pub const SYS_lchown16: ::c_long = 182; ++pub const SYS_getcwd: ::c_long = 183; ++pub const SYS_capget: ::c_long = 184; ++pub const SYS_capset: ::c_long = 185; ++pub const SYS_sigaltstack: ::c_long = 186; ++pub const SYS_sendfile: ::c_long = 187; ++pub const SYS_getpmsg: ::c_long = 188; ++pub const SYS_putpmsg: ::c_long = 189; ++pub const SYS_vfork: ::c_long = 190; ++pub const SYS_getrlimit: ::c_long = 191; ++pub const SYS_mmap2: ::c_long = 192; ++pub const SYS_truncate64: ::c_long = 193; ++pub const SYS_ftruncate64: ::c_long = 194; ++pub const SYS_stat64: ::c_long = 195; ++pub const SYS_lstat64: ::c_long = 196; ++pub const SYS_fstat64: ::c_long = 197; ++pub const SYS_chown: ::c_long = 198; ++pub const SYS_getuid: ::c_long = 199; ++pub const SYS_getgid: ::c_long = 200; ++pub const SYS_geteuid: ::c_long = 201; ++pub const SYS_getegid: ::c_long = 202; ++pub const SYS_setreuid: ::c_long = 203; ++pub const SYS_setregid: ::c_long = 204; ++pub const SYS_getgroups: ::c_long = 205; ++pub const SYS_setgroups: ::c_long = 206; ++pub const SYS_fchown: ::c_long = 207; ++pub const SYS_setresuid: ::c_long = 208; ++pub const SYS_getresuid: ::c_long = 209; ++pub const SYS_setresgid: ::c_long = 210; ++pub const SYS_getresgid: ::c_long = 211; ++pub const SYS_lchown: ::c_long = 212; ++pub const SYS_setuid: ::c_long = 213; ++pub const SYS_setgid: ::c_long = 214; ++pub const SYS_setfsuid: ::c_long = 215; ++pub const SYS_setfsgid: ::c_long = 216; ++pub const SYS_pivot_root: ::c_long = 217; ++pub const SYS_getdents64: ::c_long = 220; ++pub const SYS_gettid: ::c_long = 221; ++pub const SYS_tkill: ::c_long = 222; ++pub const SYS_setxattr: ::c_long = 223; ++pub const SYS_lsetxattr: ::c_long = 224; ++pub const SYS_fsetxattr: ::c_long = 225; ++pub const SYS_getxattr: ::c_long = 226; ++pub const SYS_lgetxattr: ::c_long = 227; ++pub const SYS_fgetxattr: ::c_long = 228; ++pub const SYS_listxattr: ::c_long = 229; ++pub const SYS_llistxattr: ::c_long = 230; ++pub const SYS_flistxattr: ::c_long = 231; ++pub const SYS_removexattr: ::c_long = 232; ++pub const SYS_lremovexattr: ::c_long = 233; ++pub const SYS_fremovexattr: ::c_long = 234; ++pub const SYS_futex_time32: ::c_long = 235; ++pub const SYS_sendfile64: ::c_long = 236; ++pub const SYS_mincore: ::c_long = 237; ++pub const SYS_madvise: ::c_long = 238; ++pub const SYS_fcntl64: ::c_long = 239; ++pub const SYS_readahead: ::c_long = 240; ++pub const SYS_io_setup: ::c_long = 241; ++pub const SYS_io_destroy: ::c_long = 242; ++pub const SYS_io_getevents_time32: ::c_long = 243; ++pub const SYS_io_submit: ::c_long = 244; ++pub const SYS_io_cancel: ::c_long = 245; ++pub const SYS_fadvise64: ::c_long = 246; ++pub const SYS_exit_group: ::c_long = 247; ++pub const SYS_lookup_dcookie: ::c_long = 248; ++pub const SYS_epoll_create: ::c_long = 249; ++pub const SYS_epoll_ctl: ::c_long = 250; ++pub const SYS_epoll_wait: ::c_long = 251; ++pub const SYS_remap_file_pages: ::c_long = 252; ++pub const SYS_set_tid_address: ::c_long = 253; ++pub const SYS_timer_create: ::c_long = 254; ++pub const SYS_timer_settime32: ::c_long = 255; ++pub const SYS_timer_gettime32: ::c_long = 256; ++pub const SYS_timer_getoverrun: ::c_long = 257; ++pub const SYS_timer_delete: ::c_long = 258; ++pub const SYS_clock_settime32: ::c_long = 259; ++pub const SYS_clock_gettime32: ::c_long = 260; ++pub const SYS_clock_getres_time32: ::c_long = 261; ++pub const SYS_clock_nanosleep_time32: ::c_long = 262; ++pub const SYS_statfs64: ::c_long = 263; ++pub const SYS_fstatfs64: ::c_long = 264; ++pub const SYS_tgkill: ::c_long = 265; ++pub const SYS_utimes_time32: ::c_long = 266; ++pub const SYS_fadvise64_64: ::c_long = 267; ++pub const SYS_mbind: ::c_long = 268; ++pub const SYS_get_mempolicy: ::c_long = 269; ++pub const SYS_set_mempolicy: ::c_long = 270; ++pub const SYS_mq_open: ::c_long = 271; ++pub const SYS_mq_unlink: ::c_long = 272; ++pub const SYS_mq_timedsend_time32: ::c_long = 273; ++pub const SYS_mq_timedreceive_time32: ::c_long = 274; ++pub const SYS_mq_notify: ::c_long = 275; ++pub const SYS_mq_getsetattr: ::c_long = 276; ++pub const SYS_waitid: ::c_long = 277; ++pub const SYS_add_key: ::c_long = 279; ++pub const SYS_request_key: ::c_long = 280; ++pub const SYS_keyctl: ::c_long = 281; ++pub const SYS_ioprio_set: ::c_long = 282; ++pub const SYS_ioprio_get: ::c_long = 283; ++pub const SYS_inotify_init: ::c_long = 284; ++pub const SYS_inotify_add_watch: ::c_long = 285; ++pub const SYS_inotify_rm_watch: ::c_long = 286; ++pub const SYS_migrate_pages: ::c_long = 287; ++pub const SYS_openat: ::c_long = 288; ++pub const SYS_mkdirat: ::c_long = 289; ++pub const SYS_mknodat: ::c_long = 290; ++pub const SYS_fchownat: ::c_long = 291; ++pub const SYS_futimesat_time32: ::c_long = 292; ++pub const SYS_fstatat64: ::c_long = 293; ++pub const SYS_unlinkat: ::c_long = 294; ++pub const SYS_renameat: ::c_long = 295; ++pub const SYS_linkat: ::c_long = 296; ++pub const SYS_symlinkat: ::c_long = 297; ++pub const SYS_readlinkat: ::c_long = 298; ++pub const SYS_fchmodat: ::c_long = 299; ++pub const SYS_faccessat: ::c_long = 300; ++pub const SYS_pselect6_time32: ::c_long = 301; ++pub const SYS_ppoll_time32: ::c_long = 302; ++pub const SYS_unshare: ::c_long = 303; ++pub const SYS_set_robust_list: ::c_long = 304; ++pub const SYS_get_robust_list: ::c_long = 305; ++pub const SYS_splice: ::c_long = 306; ++pub const SYS_sync_file_range: ::c_long = 307; ++pub const SYS_tee: ::c_long = 308; ++pub const SYS_vmsplice: ::c_long = 309; ++pub const SYS_move_pages: ::c_long = 310; ++pub const SYS_sched_setaffinity: ::c_long = 311; ++pub const SYS_sched_getaffinity: ::c_long = 312; ++pub const SYS_kexec_load: ::c_long = 313; ++pub const SYS_getcpu: ::c_long = 314; ++pub const SYS_epoll_pwait: ::c_long = 315; ++pub const SYS_utimensat_time32: ::c_long = 316; ++pub const SYS_signalfd: ::c_long = 317; ++pub const SYS_timerfd_create: ::c_long = 318; ++pub const SYS_eventfd: ::c_long = 319; ++pub const SYS_fallocate: ::c_long = 320; ++pub const SYS_timerfd_settime32: ::c_long = 321; ++pub const SYS_timerfd_gettime32: ::c_long = 322; ++pub const SYS_signalfd4: ::c_long = 323; ++pub const SYS_eventfd2: ::c_long = 324; ++pub const SYS_epoll_create1: ::c_long = 325; ++pub const SYS_dup3: ::c_long = 326; ++pub const SYS_pipe2: ::c_long = 327; ++pub const SYS_inotify_init1: ::c_long = 328; ++pub const SYS_preadv: ::c_long = 329; ++pub const SYS_pwritev: ::c_long = 330; ++pub const SYS_rt_tgsigqueueinfo: ::c_long = 331; ++pub const SYS_perf_event_open: ::c_long = 332; ++pub const SYS_get_thread_area: ::c_long = 333; ++pub const SYS_set_thread_area: ::c_long = 334; ++pub const SYS_atomic_cmpxchg_32: ::c_long = 335; ++pub const SYS_atomic_barrier: ::c_long = 336; ++pub const SYS_fanotify_init: ::c_long = 337; ++pub const SYS_fanotify_mark: ::c_long = 338; ++pub const SYS_prlimit64: ::c_long = 339; ++pub const SYS_name_to_handle_at: ::c_long = 340; ++pub const SYS_open_by_handle_at: ::c_long = 341; ++pub const SYS_clock_adjtime32: ::c_long = 342; ++pub const SYS_syncfs: ::c_long = 343; ++pub const SYS_setns: ::c_long = 344; ++pub const SYS_process_vm_readv: ::c_long = 345; ++pub const SYS_process_vm_writev: ::c_long = 346; ++pub const SYS_kcmp: ::c_long = 347; ++pub const SYS_finit_module: ::c_long = 348; ++pub const SYS_sched_setattr: ::c_long = 349; ++pub const SYS_sched_getattr: ::c_long = 350; ++pub const SYS_renameat2: ::c_long = 351; ++pub const SYS_getrandom: ::c_long = 352; ++pub const SYS_memfd_create: ::c_long = 353; ++pub const SYS_bpf: ::c_long = 354; ++pub const SYS_execveat: ::c_long = 355; ++pub const SYS_socket: ::c_long = 356; ++pub const SYS_socketpair: ::c_long = 357; ++pub const SYS_bind: ::c_long = 358; ++pub const SYS_connect: ::c_long = 359; ++pub const SYS_listen: ::c_long = 360; ++pub const SYS_accept4: ::c_long = 361; ++pub const SYS_getsockopt: ::c_long = 362; ++pub const SYS_setsockopt: ::c_long = 363; ++pub const SYS_getsockname: ::c_long = 364; ++pub const SYS_getpeername: ::c_long = 365; ++pub const SYS_sendto: ::c_long = 366; ++pub const SYS_sendmsg: ::c_long = 367; ++pub const SYS_recvfrom: ::c_long = 368; ++pub const SYS_recvmsg: ::c_long = 369; ++pub const SYS_shutdown: ::c_long = 370; ++pub const SYS_recvmmsg_time32: ::c_long = 371; ++pub const SYS_sendmmsg: ::c_long = 372; ++pub const SYS_userfaultfd: ::c_long = 373; ++pub const SYS_membarrier: ::c_long = 374; ++pub const SYS_mlock2: ::c_long = 375; ++pub const SYS_copy_file_range: ::c_long = 376; ++pub const SYS_preadv2: ::c_long = 377; ++pub const SYS_pwritev2: ::c_long = 378; ++pub const SYS_statx: ::c_long = 379; ++pub const SYS_seccomp: ::c_long = 380; ++pub const SYS_pkey_mprotect: ::c_long = 381; ++pub const SYS_pkey_alloc: ::c_long = 382; ++pub const SYS_pkey_free: ::c_long = 383; ++pub const SYS_rseq: ::c_long = 384; ++pub const SYS_semget: ::c_long = 393; ++pub const SYS_semctl: ::c_long = 394; ++pub const SYS_shmget: ::c_long = 395; ++pub const SYS_shmctl: ::c_long = 396; ++pub const SYS_shmat: ::c_long = 397; ++pub const SYS_shmdt: ::c_long = 398; ++pub const SYS_msgget: ::c_long = 399; ++pub const SYS_msgsnd: ::c_long = 400; ++pub const SYS_msgrcv: ::c_long = 401; ++pub const SYS_msgctl: ::c_long = 402; ++pub const SYS_clock_gettime: ::c_long = 403; ++pub const SYS_clock_settime: ::c_long = 404; ++pub const SYS_clock_adjtime: ::c_long = 405; ++pub const SYS_clock_getres: ::c_long = 406; ++pub const SYS_clock_nanosleep: ::c_long = 407; ++pub const SYS_timer_gettime: ::c_long = 408; ++pub const SYS_timer_settime: ::c_long = 409; ++pub const SYS_timerfd_gettime: ::c_long = 410; ++pub const SYS_timerfd_settime: ::c_long = 411; ++pub const SYS_utimensat: ::c_long = 412; ++pub const SYS_pselect6: ::c_long = 413; ++pub const SYS_ppoll: ::c_long = 414; ++pub const SYS_io_pgetevents: ::c_long = 416; ++pub const SYS_recvmmsg: ::c_long = 417; ++pub const SYS_mq_timedsend: ::c_long = 418; ++pub const SYS_mq_timedreceive: ::c_long = 419; ++pub const SYS_semtimedop: ::c_long = 420; ++pub const SYS_rt_sigtimedwait: ::c_long = 421; ++pub const SYS_futex: ::c_long = 422; ++pub const SYS_sched_rr_get_interval: ::c_long = 423; ++pub const SYS_pidfd_send_signal: ::c_long = 424; ++pub const SYS_io_uring_setup: ::c_long = 425; ++pub const SYS_io_uring_enter: ::c_long = 426; ++pub const SYS_io_uring_register: ::c_long = 427; ++pub const SYS_open_tree: ::c_long = 428; ++pub const SYS_move_mount: ::c_long = 429; ++pub const SYS_fsopen: ::c_long = 430; ++pub const SYS_fsconfig: ::c_long = 431; ++pub const SYS_fsmount: ::c_long = 432; ++pub const SYS_fspick: ::c_long = 433; ++pub const SYS_pidfd_open: ::c_long = 434; ++pub const SYS_clone3: ::c_long = 435; ++pub const SYS_close_range: ::c_long = 436; ++pub const SYS_openat2: ::c_long = 437; ++pub const SYS_pidfd_getfd: ::c_long = 438; ++pub const SYS_faccessat2: ::c_long = 439; ++pub const SYS_process_madvise: ::c_long = 440; ++pub const SYS_epoll_pwait2: ::c_long = 441; ++pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/mod.rs +index 4ded201..6a03f0b 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/mod.rs +@@ -153,17 +153,6 @@ s! { + pub l_pid: ::pid_t, + pad: [::c_long; 4], + } +- +- pub struct termios2 { +- pub c_iflag: ::tcflag_t, +- pub c_oflag: ::tcflag_t, +- pub c_cflag: ::tcflag_t, +- pub c_lflag: ::tcflag_t, +- pub c_line: ::cc_t, +- pub c_cc: [::cc_t; 23], +- pub c_ispeed: ::speed_t, +- pub c_ospeed: ::speed_t, +- } + } + + pub const O_LARGEFILE: ::c_int = 0x2000; +@@ -527,6 +516,7 @@ pub const SYS_pkey_mprotect: ::c_long = 4000 + 363; + pub const SYS_pkey_alloc: ::c_long = 4000 + 364; + pub const SYS_pkey_free: ::c_long = 4000 + 365; + pub const SYS_statx: ::c_long = 4000 + 366; ++pub const SYS_rseq: ::c_long = 4000 + 367; + pub const SYS_pidfd_send_signal: ::c_long = 4000 + 424; + pub const SYS_io_uring_setup: ::c_long = 4000 + 425; + pub const SYS_io_uring_enter: ::c_long = 4000 + 426; +@@ -546,18 +536,19 @@ pub const SYS_faccessat2: ::c_long = 4000 + 439; + pub const SYS_process_madvise: ::c_long = 4000 + 440; + pub const SYS_epoll_pwait2: ::c_long = 4000 + 441; + pub const SYS_mount_setattr: ::c_long = 4000 + 442; ++pub const SYS_quotactl_fd: ::c_long = 4000 + 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 4000 + 444; ++pub const SYS_landlock_add_rule: ::c_long = 4000 + 445; ++pub const SYS_landlock_restrict_self: ::c_long = 4000 + 446; ++pub const SYS_memfd_secret: ::c_long = 4000 + 447; ++pub const SYS_process_mrelease: ::c_long = 4000 + 448; ++pub const SYS_futex_waitv: ::c_long = 4000 + 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 4000 + 450; + + pub const O_DIRECT: ::c_int = 0x8000; + pub const O_DIRECTORY: ::c_int = 0x10000; + pub const O_NOFOLLOW: ::c_int = 0x20000; + +-pub const RLIM_INFINITY: ::rlim_t = 0x7fffffff; +-pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 5; +-pub const RLIMIT_AS: ::__rlimit_resource_t = 6; +-pub const RLIMIT_RSS: ::__rlimit_resource_t = 7; +-pub const RLIMIT_NPROC: ::__rlimit_resource_t = 8; +-pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 9; +- + pub const O_APPEND: ::c_int = 8; + pub const O_CREAT: ::c_int = 256; + pub const O_EXCL: ::c_int = 1024; +@@ -668,10 +659,6 @@ pub const MAP_STACK: ::c_int = 0x40000; + pub const SOCK_STREAM: ::c_int = 2; + pub const SOCK_DGRAM: ::c_int = 1; + +-pub const FIOCLEX: ::c_ulong = 0x6601; +-pub const FIONCLEX: ::c_ulong = 0x6602; +-pub const FIONBIO: ::c_ulong = 0x667e; +- + pub const SA_SIGINFO: ::c_int = 0x00000008; + pub const SA_NOCLDWAIT: ::c_int = 0x00010000; + +@@ -726,38 +713,6 @@ pub const F_SETOWN: ::c_int = 24; + + pub const SFD_NONBLOCK: ::c_int = 0x80; + +-pub const TCGETS: ::c_ulong = 0x540d; +-pub const TCSETS: ::c_ulong = 0x540e; +-pub const TCSETSW: ::c_ulong = 0x540f; +-pub const TCSETSF: ::c_ulong = 0x5410; +-pub const TCGETA: ::c_ulong = 0x5401; +-pub const TCSETA: ::c_ulong = 0x5402; +-pub const TCSETAW: ::c_ulong = 0x5403; +-pub const TCSETAF: ::c_ulong = 0x5404; +-pub const TCSBRK: ::c_ulong = 0x5405; +-pub const TCXONC: ::c_ulong = 0x5406; +-pub const TCFLSH: ::c_ulong = 0x5407; +-pub const TIOCGSOFTCAR: ::c_ulong = 0x5481; +-pub const TIOCSSOFTCAR: ::c_ulong = 0x5482; +-pub const TIOCINQ: ::c_ulong = 0x467f; +-pub const TIOCLINUX: ::c_ulong = 0x5483; +-pub const TIOCGSERIAL: ::c_ulong = 0x5484; +-pub const TIOCEXCL: ::c_ulong = 0x740d; +-pub const TIOCNXCL: ::c_ulong = 0x740e; +-pub const TIOCSCTTY: ::c_ulong = 0x5480; +-pub const TIOCGPGRP: ::c_ulong = 0x40047477; +-pub const TIOCSPGRP: ::c_ulong = 0x80047476; +-pub const TIOCOUTQ: ::c_ulong = 0x7472; +-pub const TIOCSTI: ::c_ulong = 0x5472; +-pub const TIOCGWINSZ: ::c_ulong = 0x40087468; +-pub const TIOCSWINSZ: ::c_ulong = 0x80087467; +-pub const TIOCMGET: ::c_ulong = 0x741d; +-pub const TIOCMBIS: ::c_ulong = 0x741b; +-pub const TIOCMBIC: ::c_ulong = 0x741c; +-pub const TIOCMSET: ::c_ulong = 0x741a; +-pub const FIONREAD: ::c_ulong = 0x467f; +-pub const TIOCCONS: ::c_ulong = 0x80047478; +- + pub const RTLD_DEEPBIND: ::c_int = 0x10; + pub const RTLD_GLOBAL: ::c_int = 0x4; + pub const RTLD_NOLOAD: ::c_int = 0x8; +@@ -837,7 +792,6 @@ pub const B19200: ::speed_t = 0o000016; + pub const B38400: ::speed_t = 0o000017; + pub const EXTA: ::speed_t = B19200; + pub const EXTB: ::speed_t = B38400; +-pub const BOTHER: ::speed_t = 0o010000; + pub const B57600: ::speed_t = 0o010001; + pub const B115200: ::speed_t = 0o010002; + pub const B230400: ::speed_t = 0o010003; +@@ -854,13 +808,6 @@ pub const B3000000: ::speed_t = 0o010015; + pub const B3500000: ::speed_t = 0o010016; + pub const B4000000: ::speed_t = 0o010017; + +-pub const TIOCM_ST: ::c_int = 0x010; +-pub const TIOCM_SR: ::c_int = 0x020; +-pub const TIOCM_CTS: ::c_int = 0x040; +-pub const TIOCM_CAR: ::c_int = 0x100; +-pub const TIOCM_RNG: ::c_int = 0x200; +-pub const TIOCM_DSR: ::c_int = 0x400; +- + pub const EHWPOISON: ::c_int = 168; + + cfg_if! { +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/mod.rs +index 239492b..66d1d01 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b32/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/mod.rs +@@ -11,9 +11,11 @@ pub type msgqnum_t = ::c_ulong; + pub type msglen_t = ::c_ulong; + pub type nlink_t = u32; + pub type __u64 = ::c_ulonglong; ++pub type __s64 = ::c_longlong; + pub type __fsword_t = i32; + pub type fsblkcnt64_t = u64; + pub type fsfilcnt64_t = u64; ++pub type __syscall_ulong_t = ::c_ulong; + + cfg_if! { + if #[cfg(target_arch = "riscv32")] { +@@ -133,10 +135,21 @@ s! { + pub _f: [::c_char; 8], + } + +- pub struct ip_mreqn { +- pub imr_multiaddr: ::in_addr, +- pub imr_address: ::in_addr, +- pub imr_ifindex: ::c_int, ++ pub struct semid_ds { ++ pub sem_perm: ipc_perm, ++ #[cfg(target_arch = "powerpc")] ++ __reserved: ::__syscall_ulong_t, ++ pub sem_otime: ::time_t, ++ #[cfg(not(any(target_arch = "mips", target_arch = "powerpc")))] ++ __reserved: ::__syscall_ulong_t, ++ #[cfg(target_arch = "powerpc")] ++ __reserved2: ::__syscall_ulong_t, ++ pub sem_ctime: ::time_t, ++ #[cfg(not(any(target_arch = "mips", target_arch = "powerpc")))] ++ __reserved2: ::__syscall_ulong_t, ++ pub sem_nsems: ::__syscall_ulong_t, ++ __glibc_reserved3: ::__syscall_ulong_t, ++ __glibc_reserved4: ::__syscall_ulong_t, + } + } + +@@ -150,8 +163,10 @@ pub const F_OFD_SETLKW: ::c_int = 38; + pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 24; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; ++pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 20; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; ++pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + + cfg_if! { + if #[cfg(target_arch = "sparc")] { +@@ -304,9 +319,6 @@ pub const PTRACE_SETFPREGS: ::c_uint = 15; + pub const PTRACE_GETREGS: ::c_uint = 12; + pub const PTRACE_SETREGS: ::c_uint = 13; + +-pub const TIOCSBRK: ::c_int = 0x5427; +-pub const TIOCCBRK: ::c_int = 0x5428; +- + extern "C" { + pub fn sysctl( + name: *mut ::c_int, +@@ -328,6 +340,9 @@ cfg_if! { + } else if #[cfg(target_arch = "mips")] { + mod mips; + pub use self::mips::*; ++ } else if #[cfg(target_arch = "m68k")] { ++ mod m68k; ++ pub use self::m68k::*; + } else if #[cfg(target_arch = "powerpc")] { + mod powerpc; + pub use self::powerpc::*; +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/powerpc.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/powerpc.rs +index 59c1e1c..e70b216 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b32/powerpc.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/powerpc.rs +@@ -163,7 +163,6 @@ s! { + } + } + +-pub const RLIM_INFINITY: ::rlim_t = !0; + pub const VEOF: usize = 4; + pub const RTLD_DEEPBIND: ::c_int = 0x8; + pub const RTLD_GLOBAL: ::c_int = 0x100; +@@ -183,24 +182,10 @@ pub const O_DSYNC: ::c_int = 4096; + pub const O_FSYNC: ::c_int = 0x101000; + pub const O_ASYNC: ::c_int = 0x2000; + pub const O_NDELAY: ::c_int = 0x800; +-pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 7; +-pub const RLIMIT_NPROC: ::__rlimit_resource_t = 6; +-pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; +-pub const RLIMIT_AS: ::__rlimit_resource_t = 9; +-pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; + pub const TCSANOW: ::c_int = 0; + pub const TCSADRAIN: ::c_int = 1; + pub const TCSAFLUSH: ::c_int = 2; + +-pub const TIOCLINUX: ::c_ulong = 0x541C; +-pub const TIOCGSERIAL: ::c_ulong = 0x541E; +-pub const TIOCM_ST: ::c_int = 0x008; +-pub const TIOCM_SR: ::c_int = 0x010; +-pub const TIOCM_CTS: ::c_int = 0x020; +-pub const TIOCM_CAR: ::c_int = 0x040; +-pub const TIOCM_RNG: ::c_int = 0x080; +-pub const TIOCM_DSR: ::c_int = 0x100; +- + pub const MADV_SOFT_OFFLINE: ::c_int = 101; + pub const MAP_LOCKED: ::c_int = 0x00080; + pub const MAP_NORESERVE: ::c_int = 0x00040; +@@ -306,10 +291,6 @@ pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + pub const SOCK_STREAM: ::c_int = 1; + pub const SOCK_DGRAM: ::c_int = 2; + +-pub const FIOCLEX: ::c_ulong = 0x20006601; +-pub const FIONCLEX: ::c_ulong = 0x20006602; +-pub const FIONBIO: ::c_ulong = 0x8004667e; +- + pub const MCL_CURRENT: ::c_int = 0x2000; + pub const MCL_FUTURE: ::c_int = 0x4000; + +@@ -323,18 +304,6 @@ pub const F_SETOWN: ::c_int = 8; + pub const EFD_NONBLOCK: ::c_int = 0x800; + pub const SFD_NONBLOCK: ::c_int = 0x0800; + +-pub const TIOCGSOFTCAR: ::c_ulong = 0x5419; +-pub const TIOCSSOFTCAR: ::c_ulong = 0x541A; +-pub const TIOCEXCL: ::c_ulong = 0x540C; +-pub const TIOCNXCL: ::c_ulong = 0x540D; +-pub const TIOCSCTTY: ::c_ulong = 0x540E; +-pub const TIOCSTI: ::c_ulong = 0x5412; +-pub const TIOCMGET: ::c_ulong = 0x5415; +-pub const TIOCMBIS: ::c_ulong = 0x5416; +-pub const TIOCMBIC: ::c_ulong = 0x5417; +-pub const TIOCMSET: ::c_ulong = 0x5418; +-pub const TIOCCONS: ::c_ulong = 0x541D; +- + pub const SIGCHLD: ::c_int = 17; + pub const SIGBUS: ::c_int = 7; + pub const SIGUSR1: ::c_int = 10; +@@ -446,7 +415,6 @@ pub const B2500000: ::speed_t = 0o0033; + pub const B3000000: ::speed_t = 0o0034; + pub const B3500000: ::speed_t = 0o0035; + pub const B4000000: ::speed_t = 0o0036; +-pub const BOTHER: ::speed_t = 0o0037; + + pub const VEOL: usize = 6; + pub const VEOL2: usize = 8; +@@ -455,26 +423,6 @@ pub const IEXTEN: ::tcflag_t = 0x400; + pub const TOSTOP: ::tcflag_t = 0x400000; + pub const FLUSHO: ::tcflag_t = 0x800000; + pub const EXTPROC: ::tcflag_t = 0x10000000; +-pub const TCGETS: ::c_ulong = 0x403c7413; +-pub const TCSETS: ::c_ulong = 0x803c7414; +-pub const TCSETSW: ::c_ulong = 0x803c7415; +-pub const TCSETSF: ::c_ulong = 0x803c7416; +-pub const TCGETA: ::c_ulong = 0x40147417; +-pub const TCSETA: ::c_ulong = 0x80147418; +-pub const TCSETAW: ::c_ulong = 0x80147419; +-pub const TCSETAF: ::c_ulong = 0x8014741c; +-pub const TCSBRK: ::c_ulong = 0x2000741d; +-pub const TCXONC: ::c_ulong = 0x2000741e; +-pub const TCFLSH: ::c_ulong = 0x2000741f; +-pub const TIOCINQ: ::c_ulong = 0x4004667f; +-pub const TIOCGPGRP: ::c_ulong = 0x40047477; +-pub const TIOCSPGRP: ::c_ulong = 0x80047476; +-pub const TIOCOUTQ: ::c_ulong = 0x40047473; +-pub const TIOCGWINSZ: ::c_ulong = 0x40087468; +-pub const TIOCSWINSZ: ::c_ulong = 0x80087467; +-pub const TIOCGRS485: ::c_int = 0x542e; +-pub const TIOCSRS485: ::c_int = 0x542f; +-pub const FIONREAD: ::c_ulong = 0x4004667f; + + pub const SYS_restart_syscall: ::c_long = 0; + pub const SYS_exit: ::c_long = 1; +@@ -846,6 +794,7 @@ pub const SYS_preadv2: ::c_long = 380; + pub const SYS_pwritev2: ::c_long = 381; + pub const SYS_kexec_file_load: ::c_long = 382; + pub const SYS_statx: ::c_long = 383; ++pub const SYS_rseq: ::c_long = 387; + pub const SYS_pidfd_send_signal: ::c_long = 424; + pub const SYS_io_uring_setup: ::c_long = 425; + pub const SYS_io_uring_enter: ::c_long = 426; +@@ -865,3 +814,11 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/align.rs +new file mode 100644 +index 0000000..48d152a +--- /dev/null ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/align.rs +@@ -0,0 +1,44 @@ ++s_no_extra_traits! { ++ #[allow(missing_debug_implementations)] ++ pub struct ucontext_t { ++ pub __uc_flags: ::c_ulong, ++ pub uc_link: *mut ucontext_t, ++ pub uc_stack: ::stack_t, ++ pub uc_sigmask: ::sigset_t, ++ pub uc_mcontext: mcontext_t, ++ } ++ ++ #[allow(missing_debug_implementations)] ++ #[repr(align(16))] ++ pub struct mcontext_t { ++ pub __gregs: [::c_ulong; 32], ++ pub __fpregs: __riscv_mc_fp_state, ++ } ++ ++ #[allow(missing_debug_implementations)] ++ pub union __riscv_mc_fp_state { ++ pub __f: __riscv_mc_f_ext_state, ++ pub __d: __riscv_mc_d_ext_state, ++ pub __q: __riscv_mc_q_ext_state, ++ } ++ ++ #[allow(missing_debug_implementations)] ++ pub struct __riscv_mc_f_ext_state { ++ pub __f: [::c_uint; 32], ++ pub __fcsr: ::c_uint, ++ } ++ ++ #[allow(missing_debug_implementations)] ++ pub struct __riscv_mc_d_ext_state { ++ pub __f: [::c_ulonglong; 32], ++ pub __fcsr: ::c_uint, ++ } ++ ++ #[allow(missing_debug_implementations)] ++ #[repr(align(16))] ++ pub struct __riscv_mc_q_ext_state { ++ pub __f: [::c_ulonglong; 64], ++ pub __fcsr: ::c_uint, ++ pub __glibc_reserved: [::c_uint; 3], ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs +index 96ee5a3..f3b130c 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs +@@ -196,22 +196,48 @@ s! { + pub l_len: ::off64_t, + pub l_pid: ::pid_t, + } ++ ++ pub struct user_regs_struct { ++ pub pc: ::c_ulong, ++ pub ra: ::c_ulong, ++ pub sp: ::c_ulong, ++ pub gp: ::c_ulong, ++ pub tp: ::c_ulong, ++ pub t0: ::c_ulong, ++ pub t1: ::c_ulong, ++ pub t2: ::c_ulong, ++ pub s0: ::c_ulong, ++ pub s1: ::c_ulong, ++ pub a0: ::c_ulong, ++ pub a1: ::c_ulong, ++ pub a2: ::c_ulong, ++ pub a3: ::c_ulong, ++ pub a4: ::c_ulong, ++ pub a5: ::c_ulong, ++ pub a6: ::c_ulong, ++ pub a7: ::c_ulong, ++ pub s2: ::c_ulong, ++ pub s3: ::c_ulong, ++ pub s4: ::c_ulong, ++ pub s5: ::c_ulong, ++ pub s6: ::c_ulong, ++ pub s7: ::c_ulong, ++ pub s8: ::c_ulong, ++ pub s9: ::c_ulong, ++ pub s10: ::c_ulong, ++ pub s11: ::c_ulong, ++ pub t3: ::c_ulong, ++ pub t4: ::c_ulong, ++ pub t5: ::c_ulong, ++ pub t6: ::c_ulong, ++ } + } + +-pub const RLIM_INFINITY: ::rlim_t = !0; ++pub const O_LARGEFILE: ::c_int = 0; + pub const VEOF: usize = 4; + pub const RTLD_DEEPBIND: ::c_int = 0x8; + pub const RTLD_GLOBAL: ::c_int = 0x100; + pub const RTLD_NOLOAD: ::c_int = 0x4; +-pub const TIOCGSOFTCAR: ::c_ulong = 21529; +-pub const TIOCSSOFTCAR: ::c_ulong = 21530; +-pub const TIOCGRS485: ::c_int = 21550; +-pub const TIOCSRS485: ::c_int = 21551; +-pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; +-pub const RLIMIT_AS: ::__rlimit_resource_t = 9; +-pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; +-pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 7; +-pub const RLIMIT_NPROC: ::__rlimit_resource_t = 6; + pub const O_APPEND: ::c_int = 1024; + pub const O_CREAT: ::c_int = 64; + pub const O_EXCL: ::c_int = 128; +@@ -221,6 +247,7 @@ pub const O_SYNC: ::c_int = 1052672; + pub const O_RSYNC: ::c_int = 1052672; + pub const O_DSYNC: ::c_int = 4096; + pub const O_FSYNC: ::c_int = 1052672; ++pub const MADV_SOFT_OFFLINE: ::c_int = 101; + pub const MAP_GROWSDOWN: ::c_int = 256; + pub const EDEADLK: ::c_int = 35; + pub const ENAMETOOLONG: ::c_int = 36; +@@ -340,26 +367,10 @@ pub const SFD_NONBLOCK: ::c_int = 2048; + pub const TCSANOW: ::c_int = 0; + pub const TCSADRAIN: ::c_int = 1; + pub const TCSAFLUSH: ::c_int = 2; +-pub const TIOCLINUX: ::c_ulong = 21532; +-pub const TIOCGSERIAL: ::c_ulong = 21534; +-pub const TIOCEXCL: ::c_ulong = 21516; +-pub const TIOCNXCL: ::c_ulong = 21517; +-pub const TIOCSCTTY: ::c_ulong = 21518; +-pub const TIOCSTI: ::c_ulong = 21522; +-pub const TIOCMGET: ::c_ulong = 21525; +-pub const TIOCMBIS: ::c_ulong = 21526; +-pub const TIOCMBIC: ::c_ulong = 21527; +-pub const TIOCMSET: ::c_ulong = 21528; +-pub const TIOCCONS: ::c_ulong = 21533; +-pub const TIOCM_ST: ::c_int = 8; +-pub const TIOCM_SR: ::c_int = 16; +-pub const TIOCM_CTS: ::c_int = 32; +-pub const TIOCM_CAR: ::c_int = 64; +-pub const TIOCM_RNG: ::c_int = 128; +-pub const TIOCM_DSR: ::c_int = 256; + + pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; ++pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + pub const O_DIRECT: ::c_int = 16384; + pub const O_DIRECTORY: ::c_int = 65536; + pub const O_NOFOLLOW: ::c_int = 131072; +@@ -380,9 +391,6 @@ pub const ENOTNAM: ::c_int = 118; + pub const ENAVAIL: ::c_int = 119; + pub const EISNAM: ::c_int = 120; + pub const EREMOTEIO: ::c_int = 121; +-pub const FIOCLEX: ::c_ulong = 21585; +-pub const FIONCLEX: ::c_ulong = 21584; +-pub const FIONBIO: ::c_ulong = 21537; + pub const MCL_CURRENT: ::c_int = 1; + pub const MCL_FUTURE: ::c_int = 2; + pub const SIGSTKSZ: ::size_t = 8192; +@@ -478,26 +486,19 @@ pub const IEXTEN: ::tcflag_t = 32768; + pub const TOSTOP: ::tcflag_t = 256; + pub const FLUSHO: ::tcflag_t = 4096; + pub const EXTPROC: ::tcflag_t = 65536; +-pub const TCGETS: ::c_ulong = 21505; +-pub const TCSETS: ::c_ulong = 21506; +-pub const TCSETSW: ::c_ulong = 21507; +-pub const TCSETSF: ::c_ulong = 21508; +-pub const TCGETA: ::c_ulong = 21509; +-pub const TCSETA: ::c_ulong = 21510; +-pub const TCSETAW: ::c_ulong = 21511; +-pub const TCSETAF: ::c_ulong = 21512; +-pub const TCSBRK: ::c_ulong = 21513; +-pub const TCXONC: ::c_ulong = 21514; +-pub const TCFLSH: ::c_ulong = 21515; +-pub const TIOCINQ: ::c_ulong = 21531; +-pub const TIOCGPGRP: ::c_ulong = 21519; +-pub const TIOCSPGRP: ::c_ulong = 21520; +-pub const TIOCOUTQ: ::c_ulong = 21521; +-pub const TIOCGWINSZ: ::c_ulong = 21523; +-pub const TIOCSWINSZ: ::c_ulong = 21524; +-pub const FIONREAD: ::c_ulong = 21531; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; ++pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; ++pub const NGREG: usize = 32; ++pub const REG_PC: usize = 0; ++pub const REG_RA: usize = 1; ++pub const REG_SP: usize = 2; ++pub const REG_TP: usize = 4; ++pub const REG_S0: usize = 8; ++pub const REG_S1: usize = 9; ++pub const REG_A0: usize = 10; ++pub const REG_S2: usize = 18; ++pub const REG_NARGS: usize = 8; + + pub const SYS_read: ::c_long = 63; + pub const SYS_write: ::c_long = 64; +@@ -774,6 +775,7 @@ pub const SYS_pkey_mprotect: ::c_long = 288; + pub const SYS_pkey_alloc: ::c_long = 289; + pub const SYS_pkey_free: ::c_long = 290; + pub const SYS_statx: ::c_long = 291; ++pub const SYS_rseq: ::c_long = 293; + pub const SYS_pidfd_send_signal: ::c_long = 424; + pub const SYS_io_uring_setup: ::c_long = 425; + pub const SYS_io_uring_enter: ::c_long = 426; +@@ -793,3 +795,18 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; ++ ++cfg_if! { ++ if #[cfg(libc_align)] { ++ mod align; ++ pub use self::align::*; ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/mod.rs +index 4364814..57ad9fe 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/mod.rs +@@ -191,34 +191,13 @@ s! { + __glibc_reserved1: ::c_ulong, + __glibc_reserved2: ::c_ulong, + } +- +- pub struct termios2 { +- pub c_iflag: ::tcflag_t, +- pub c_oflag: ::tcflag_t, +- pub c_cflag: ::tcflag_t, +- pub c_lflag: ::tcflag_t, +- pub c_line: ::cc_t, +- pub c_cc: [::cc_t; 19], +- pub c_ispeed: ::speed_t, +- pub c_ospeed: ::speed_t, +- } + } + +-pub const RLIM_INFINITY: ::rlim_t = !0; + pub const VEOF: usize = 4; + pub const RTLD_DEEPBIND: ::c_int = 0x8; + pub const RTLD_GLOBAL: ::c_int = 0x100; + pub const RTLD_NOLOAD: ::c_int = 0x4; + +-pub const TIOCGSOFTCAR: ::c_ulong = 0x40047464; +-pub const TIOCSSOFTCAR: ::c_ulong = 0x80047465; +- +-pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; +-pub const RLIMIT_AS: ::__rlimit_resource_t = 9; +-pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; +-pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 6; +-pub const RLIMIT_NPROC: ::__rlimit_resource_t = 7; +- + pub const O_APPEND: ::c_int = 0x8; + pub const O_CREAT: ::c_int = 0x200; + pub const O_EXCL: ::c_int = 0x800; +@@ -367,25 +346,6 @@ pub const TCSANOW: ::c_int = 0; + pub const TCSADRAIN: ::c_int = 1; + pub const TCSAFLUSH: ::c_int = 2; + +-pub const TIOCLINUX: ::c_ulong = 0x541C; +-pub const TIOCGSERIAL: ::c_ulong = 0x541E; +-pub const TIOCEXCL: ::c_ulong = 0x2000740d; +-pub const TIOCNXCL: ::c_ulong = 0x2000740e; +-pub const TIOCSCTTY: ::c_ulong = 0x20007484; +-pub const TIOCSTI: ::c_ulong = 0x80017472; +-pub const TIOCMGET: ::c_ulong = 0x4004746a; +-pub const TIOCMBIS: ::c_ulong = 0x8004746c; +-pub const TIOCMBIC: ::c_ulong = 0x8004746b; +-pub const TIOCMSET: ::c_ulong = 0x8004746d; +-pub const TIOCCONS: ::c_ulong = 0x20007424; +- +-pub const TIOCM_ST: ::c_int = 0x008; +-pub const TIOCM_SR: ::c_int = 0x010; +-pub const TIOCM_CTS: ::c_int = 0x020; +-pub const TIOCM_CAR: ::c_int = 0x040; +-pub const TIOCM_RNG: ::c_int = 0x080; +-pub const TIOCM_DSR: ::c_int = 0x100; +- + pub const O_DIRECTORY: ::c_int = 0o200000; + pub const O_NOFOLLOW: ::c_int = 0o400000; + pub const O_LARGEFILE: ::c_int = 0x40000; +@@ -401,10 +361,6 @@ pub const ENAVAIL: ::c_int = 119; + pub const EISNAM: ::c_int = 120; + pub const EREMOTEIO: ::c_int = 121; + +-pub const FIOCLEX: ::c_ulong = 0x20006601; +-pub const FIONCLEX: ::c_ulong = 0x20006602; +-pub const FIONBIO: ::c_ulong = 0x8004667e; +- + pub const MCL_CURRENT: ::c_int = 0x2000; + pub const MCL_FUTURE: ::c_int = 0x4000; + +@@ -480,7 +436,6 @@ pub const B19200: ::speed_t = 0o000016; + pub const B38400: ::speed_t = 0o000017; + pub const EXTA: ::speed_t = B19200; + pub const EXTB: ::speed_t = B38400; +-pub const BOTHER: ::speed_t = 0x1000; + pub const B57600: ::speed_t = 0x1001; + pub const B115200: ::speed_t = 0x1002; + pub const B230400: ::speed_t = 0x1003; +@@ -504,24 +459,6 @@ pub const IEXTEN: ::tcflag_t = 0x8000; + pub const TOSTOP: ::tcflag_t = 0x100; + pub const FLUSHO: ::tcflag_t = 0x1000; + pub const EXTPROC: ::tcflag_t = 0x10000; +-pub const TCGETS: ::c_ulong = 0x40245408; +-pub const TCSETS: ::c_ulong = 0x80245409; +-pub const TCSETSW: ::c_ulong = 0x8024540a; +-pub const TCSETSF: ::c_ulong = 0x8024540b; +-pub const TCGETA: ::c_ulong = 0x40125401; +-pub const TCSETA: ::c_ulong = 0x80125402; +-pub const TCSETAW: ::c_ulong = 0x80125403; +-pub const TCSETAF: ::c_ulong = 0x80125404; +-pub const TCSBRK: ::c_ulong = 0x20005405; +-pub const TCXONC: ::c_ulong = 0x20005406; +-pub const TCFLSH: ::c_ulong = 0x20005407; +-pub const TIOCINQ: ::c_ulong = 0x4004667f; +-pub const TIOCGPGRP: ::c_ulong = 0x40047483; +-pub const TIOCSPGRP: ::c_ulong = 0x80047482; +-pub const TIOCOUTQ: ::c_ulong = 0x40047473; +-pub const TIOCGWINSZ: ::c_ulong = 0x40087468; +-pub const TIOCSWINSZ: ::c_ulong = 0x80087467; +-pub const FIONREAD: ::c_ulong = 0x4004667f; + + pub const SYS_restart_syscall: ::c_long = 0; + pub const SYS_exit: ::c_long = 1; +@@ -881,6 +818,7 @@ pub const SYS_copy_file_range: ::c_long = 357; + pub const SYS_preadv2: ::c_long = 358; + pub const SYS_pwritev2: ::c_long = 359; + pub const SYS_statx: ::c_long = 360; ++pub const SYS_rseq: ::c_long = 365; + pub const SYS_pidfd_send_signal: ::c_long = 424; + pub const SYS_io_uring_setup: ::c_long = 425; + pub const SYS_io_uring_enter: ::c_long = 426; +@@ -901,6 +839,14 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; + + cfg_if! { + if #[cfg(libc_align)] { +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/mod.rs +index 75edd27..9362238 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/mod.rs +@@ -215,17 +215,6 @@ s! { + __glibc_reserved5: ::c_ulong, + } + +- pub struct termios2 { +- pub c_iflag: ::tcflag_t, +- pub c_oflag: ::tcflag_t, +- pub c_cflag: ::tcflag_t, +- pub c_lflag: ::tcflag_t, +- pub c_line: ::cc_t, +- pub c_cc: [::cc_t; 19], +- pub c_ispeed: ::speed_t, +- pub c_ospeed: ::speed_t, +- } +- + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, +@@ -246,6 +235,12 @@ s! { + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } ++ ++ pub struct seccomp_notif_sizes { ++ pub seccomp_notif: ::__u16, ++ pub seccomp_notif_resp: ::__u16, ++ pub seccomp_data: ::__u16, ++ } + } + + s_no_extra_traits! { +@@ -375,7 +370,6 @@ cfg_if! { + } + } + +-pub const RLIM_INFINITY: ::rlim_t = !0; + pub const VEOF: usize = 4; + pub const RTLD_DEEPBIND: ::c_int = 0x8; + pub const RTLD_GLOBAL: ::c_int = 0x100; +@@ -395,11 +389,6 @@ pub const O_DSYNC: ::c_int = 4096; + pub const O_FSYNC: ::c_int = 0x101000; + pub const O_ASYNC: ::c_int = 0x2000; + pub const O_NDELAY: ::c_int = 0x800; +-pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 7; +-pub const RLIMIT_NPROC: ::__rlimit_resource_t = 6; +-pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; +-pub const RLIMIT_AS: ::__rlimit_resource_t = 9; +-pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; + + pub const MADV_SOFT_OFFLINE: ::c_int = 101; + pub const MAP_LOCKED: ::c_int = 0x02000; +@@ -511,10 +500,6 @@ pub const F_GETLK: ::c_int = 5; + pub const F_GETOWN: ::c_int = 9; + pub const F_SETOWN: ::c_int = 8; + +-pub const FIOCLEX: ::c_ulong = 0x5451; +-pub const FIONCLEX: ::c_ulong = 0x5450; +-pub const FIONBIO: ::c_ulong = 0x5421; +- + pub const PTRACE_GETFPXREGS: ::c_uint = 18; + pub const PTRACE_SETFPXREGS: ::c_uint = 19; + pub const PTRACE_SYSEMU: ::c_uint = 31; +@@ -608,18 +593,6 @@ pub const FFDLY: ::tcflag_t = 0o100000; + pub const VTDLY: ::tcflag_t = 0o040000; + pub const XTABS: ::tcflag_t = 0o014000; + +-pub const TIOCGSOFTCAR: ::c_ulong = 0x5419; +-pub const TIOCSSOFTCAR: ::c_ulong = 0x541A; +-pub const TIOCEXCL: ::c_ulong = 0x540C; +-pub const TIOCNXCL: ::c_ulong = 0x540D; +-pub const TIOCSCTTY: ::c_ulong = 0x540E; +-pub const TIOCSTI: ::c_ulong = 0x5412; +-pub const TIOCMGET: ::c_ulong = 0x5415; +-pub const TIOCMBIS: ::c_ulong = 0x5416; +-pub const TIOCMBIC: ::c_ulong = 0x5417; +-pub const TIOCMSET: ::c_ulong = 0x5418; +-pub const TIOCCONS: ::c_ulong = 0x541D; +- + pub const B0: ::speed_t = 0o000000; + pub const B50: ::speed_t = 0o000001; + pub const B75: ::speed_t = 0o000002; +@@ -638,7 +611,6 @@ pub const B19200: ::speed_t = 0o000016; + pub const B38400: ::speed_t = 0o000017; + pub const EXTA: ::speed_t = B19200; + pub const EXTB: ::speed_t = B38400; +-pub const BOTHER: ::speed_t = 0o010000; + pub const B57600: ::speed_t = 0o010001; + pub const B115200: ::speed_t = 0o010002; + pub const B230400: ::speed_t = 0o010003; +@@ -662,40 +634,11 @@ pub const IEXTEN: ::tcflag_t = 0x00008000; + pub const TOSTOP: ::tcflag_t = 0x00000100; + pub const FLUSHO: ::tcflag_t = 0x00001000; + pub const EXTPROC: ::tcflag_t = 0x00010000; +-pub const TCGETS: ::c_ulong = 0x5401; +-pub const TCSETS: ::c_ulong = 0x5402; +-pub const TCSETSW: ::c_ulong = 0x5403; +-pub const TCSETSF: ::c_ulong = 0x5404; +-pub const TCGETA: ::c_ulong = 0x5405; +-pub const TCSETA: ::c_ulong = 0x5406; +-pub const TCSETAW: ::c_ulong = 0x5407; +-pub const TCSETAF: ::c_ulong = 0x5408; +-pub const TCSBRK: ::c_ulong = 0x5409; +-pub const TCXONC: ::c_ulong = 0x540A; +-pub const TCFLSH: ::c_ulong = 0x540B; +-pub const TIOCINQ: ::c_ulong = 0x541B; +-pub const TIOCGPGRP: ::c_ulong = 0x540F; +-pub const TIOCSPGRP: ::c_ulong = 0x5410; +-pub const TIOCOUTQ: ::c_ulong = 0x5411; +-pub const TIOCGWINSZ: ::c_ulong = 0x5413; +-pub const TIOCSWINSZ: ::c_ulong = 0x5414; +-pub const TIOCGRS485: ::c_int = 0x542E; +-pub const TIOCSRS485: ::c_int = 0x542F; +-pub const FIONREAD: ::c_ulong = 0x541B; + + pub const TCSANOW: ::c_int = 0; + pub const TCSADRAIN: ::c_int = 1; + pub const TCSAFLUSH: ::c_int = 2; + +-pub const TIOCLINUX: ::c_ulong = 0x541C; +-pub const TIOCGSERIAL: ::c_ulong = 0x541E; +-pub const TIOCM_ST: ::c_int = 0x008; +-pub const TIOCM_SR: ::c_int = 0x010; +-pub const TIOCM_CTS: ::c_int = 0x020; +-pub const TIOCM_CAR: ::c_int = 0x040; +-pub const TIOCM_RNG: ::c_int = 0x080; +-pub const TIOCM_DSR: ::c_int = 0x100; +- + // Syscall table + pub const SYS_restart_syscall: ::c_long = 0; + pub const SYS_exit: ::c_long = 1; +@@ -1077,6 +1020,7 @@ pub const SYS_pkey_mprotect: ::c_long = 380; + pub const SYS_pkey_alloc: ::c_long = 381; + pub const SYS_pkey_free: ::c_long = 382; + pub const SYS_statx: ::c_long = 383; ++pub const SYS_rseq: ::c_long = 386; + pub const SYS_pidfd_send_signal: ::c_long = 424; + pub const SYS_io_uring_setup: ::c_long = 425; + pub const SYS_io_uring_enter: ::c_long = 426; +@@ -1096,6 +1040,14 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; + + // offsets in user_regs_structs, from sys/reg.h + pub const EBX: ::c_int = 0; +@@ -1137,6 +1089,11 @@ pub const REG_EFL: ::c_int = 16; + pub const REG_UESP: ::c_int = 17; + pub const REG_SS: ::c_int = 18; + ++pub const SECCOMP_SET_MODE_STRICT: ::c_uint = 0; ++pub const SECCOMP_SET_MODE_FILTER: ::c_uint = 1; ++pub const SECCOMP_GET_ACTION_AVAIL: ::c_uint = 2; ++pub const SECCOMP_GET_NOTIF_SIZES: ::c_uint = 3; ++ + extern "C" { + pub fn getcontext(ucp: *mut ucontext_t) -> ::c_int; + pub fn setcontext(ucp: *const ucontext_t) -> ::c_int; +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/align.rs +index 154c2c5..06173be 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/align.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/align.rs +@@ -26,4 +26,33 @@ s! { + // auto-derive traits like Debug + __reserved: [[u64; 32]; 16], + } ++ ++ #[repr(align(16))] ++ pub struct user_fpsimd_struct { ++ pub vregs: [[u64; 2]; 32], ++ pub fpsr: ::c_uint, ++ pub fpcr: ::c_uint, ++ } ++ ++ #[repr(align(8))] ++ pub struct clone_args { ++ pub flags: ::c_ulonglong, ++ pub pidfd: ::c_ulonglong, ++ pub child_tid: ::c_ulonglong, ++ pub parent_tid: ::c_ulonglong, ++ pub exit_signal: ::c_ulonglong, ++ pub stack: ::c_ulonglong, ++ pub stack_size: ::c_ulonglong, ++ pub tls: ::c_ulonglong, ++ pub set_tid: ::c_ulonglong, ++ pub set_tid_size: ::c_ulonglong, ++ pub cgroup: ::c_ulonglong, ++ } ++} ++ ++extern "C" { ++ pub fn getcontext(ucp: *mut ucontext_t) -> ::c_int; ++ pub fn setcontext(ucp: *const ucontext_t) -> ::c_int; ++ pub fn makecontext(ucp: *mut ucontext_t, func: extern "C" fn(), argc: ::c_int, ...); ++ pub fn swapcontext(uocp: *mut ucontext_t, ucp: *const ucontext_t) -> ::c_int; + } +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs +index 24b7f4e..0848fb5 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs +@@ -7,6 +7,8 @@ pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 32; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 48; ++pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; ++pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 20; + + align_const! { + #[cfg(target_endian = "little")] +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs +new file mode 100644 +index 0000000..4535e73 +--- /dev/null ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/int128.rs +@@ -0,0 +1,7 @@ ++s! { ++ pub struct user_fpsimd_struct { ++ pub vregs: [::__uint128_t; 32], ++ pub fpsr: u32, ++ pub fpcr: u32, ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs +index 14d39e5..3802caf 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs +@@ -7,6 +7,8 @@ pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 8; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 48; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 8; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; ++pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 8; ++pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + + align_const! { + #[cfg(target_endian = "little")] +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs +index 35fe306..f46ea94 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs +@@ -6,6 +6,7 @@ pub type nlink_t = u32; + pub type blksize_t = i32; + pub type suseconds_t = i64; + pub type __u64 = ::c_ulonglong; ++pub type __s64 = ::c_longlong; + + s! { + pub struct sigaction { +@@ -142,6 +143,13 @@ s! { + __size: [usize; 8] + } + ++ pub struct user_regs_struct { ++ pub regs: [::c_ulonglong; 31], ++ pub sp: ::c_ulonglong, ++ pub pc: ::c_ulonglong, ++ pub pstate: ::c_ulonglong, ++ } ++ + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, +@@ -168,17 +176,6 @@ s! { + __unused5: ::c_ulong + } + +- pub struct termios2 { +- pub c_iflag: ::tcflag_t, +- pub c_oflag: ::tcflag_t, +- pub c_cflag: ::tcflag_t, +- pub c_lflag: ::tcflag_t, +- pub c_line: ::cc_t, +- pub c_cc: [::cc_t; 19], +- pub c_ispeed: ::speed_t, +- pub c_ospeed: ::speed_t, +- } +- + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, +@@ -200,10 +197,10 @@ s! { + pub ss_size: ::size_t + } + +- pub struct ip_mreqn { +- pub imr_multiaddr: ::in_addr, +- pub imr_address: ::in_addr, +- pub imr_ifindex: ::c_int, ++ pub struct seccomp_notif_sizes { ++ pub seccomp_notif: ::__u16, ++ pub seccomp_notif_resp: ::__u16, ++ pub seccomp_data: ::__u16, + } + } + +@@ -213,12 +210,6 @@ pub const RTLD_DEEPBIND: ::c_int = 0x8; + pub const RTLD_GLOBAL: ::c_int = 0x100; + pub const RTLD_NOLOAD: ::c_int = 0x4; + +-pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; +-pub const RLIMIT_AS: ::__rlimit_resource_t = 9; +-pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; +-pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 7; +-pub const RLIMIT_NPROC: ::__rlimit_resource_t = 6; +- + pub const O_APPEND: ::c_int = 1024; + pub const O_CREAT: ::c_int = 64; + pub const O_EXCL: ::c_int = 128; +@@ -380,29 +371,6 @@ pub const F_UNLCK: ::c_int = 2; + + pub const SFD_NONBLOCK: ::c_int = 0x0800; + +-pub const TIOCEXCL: ::c_ulong = 0x540C; +-pub const TIOCNXCL: ::c_ulong = 0x540D; +-pub const TIOCSCTTY: ::c_ulong = 0x540E; +-pub const TIOCSTI: ::c_ulong = 0x5412; +-pub const TIOCMGET: ::c_ulong = 0x5415; +-pub const TIOCMBIS: ::c_ulong = 0x5416; +-pub const TIOCMBIC: ::c_ulong = 0x5417; +-pub const TIOCMSET: ::c_ulong = 0x5418; +-pub const TIOCGSOFTCAR: ::c_ulong = 0x5419; +-pub const TIOCSSOFTCAR: ::c_ulong = 0x541A; +-pub const TIOCCONS: ::c_ulong = 0x541D; +-pub const TIOCSBRK: ::c_ulong = 0x5427; +-pub const TIOCCBRK: ::c_ulong = 0x5428; +-pub const TIOCGRS485: ::c_int = 0x542E; +-pub const TIOCSRS485: ::c_int = 0x542F; +- +-pub const TIOCM_ST: ::c_int = 0x008; +-pub const TIOCM_SR: ::c_int = 0x010; +-pub const TIOCM_CTS: ::c_int = 0x020; +-pub const TIOCM_CAR: ::c_int = 0x040; +-pub const TIOCM_RNG: ::c_int = 0x080; +-pub const TIOCM_DSR: ::c_int = 0x100; +- + pub const SFD_CLOEXEC: ::c_int = 0x080000; + + pub const NCCS: usize = 32; +@@ -453,10 +421,6 @@ pub const MAP_SYNC: ::c_int = 0x080000; + + pub const EDEADLOCK: ::c_int = 35; + +-pub const FIOCLEX: ::c_ulong = 0x5451; +-pub const FIONCLEX: ::c_ulong = 0x5450; +-pub const FIONBIO: ::c_ulong = 0x5421; +- + pub const MCL_CURRENT: ::c_int = 0x0001; + pub const MCL_FUTURE: ::c_int = 0x0002; + +@@ -532,7 +496,6 @@ pub const B19200: ::speed_t = 0o000016; + pub const B38400: ::speed_t = 0o000017; + pub const EXTA: ::speed_t = B19200; + pub const EXTB: ::speed_t = B38400; +-pub const BOTHER: ::speed_t = 0o010000; + pub const B57600: ::speed_t = 0o010001; + pub const B115200: ::speed_t = 0o010002; + pub const B230400: ::speed_t = 0o010003; +@@ -549,6 +512,11 @@ pub const B3000000: ::speed_t = 0o010015; + pub const B3500000: ::speed_t = 0o010016; + pub const B4000000: ::speed_t = 0o010017; + ++pub const SECCOMP_SET_MODE_STRICT: ::c_uint = 0; ++pub const SECCOMP_SET_MODE_FILTER: ::c_uint = 1; ++pub const SECCOMP_GET_ACTION_AVAIL: ::c_uint = 2; ++pub const SECCOMP_GET_NOTIF_SIZES: ::c_uint = 3; ++ + pub const VEOL: usize = 11; + pub const VEOL2: usize = 16; + pub const VMIN: usize = 6; +@@ -556,32 +524,11 @@ pub const IEXTEN: ::tcflag_t = 0x00008000; + pub const TOSTOP: ::tcflag_t = 0x00000100; + pub const FLUSHO: ::tcflag_t = 0x00001000; + pub const EXTPROC: ::tcflag_t = 0x00010000; +-pub const TCGETS: ::c_ulong = 0x5401; +-pub const TCSETS: ::c_ulong = 0x5402; +-pub const TCSETSW: ::c_ulong = 0x5403; +-pub const TCSETSF: ::c_ulong = 0x5404; +-pub const TCGETA: ::c_ulong = 0x5405; +-pub const TCSETA: ::c_ulong = 0x5406; +-pub const TCSETAW: ::c_ulong = 0x5407; +-pub const TCSETAF: ::c_ulong = 0x5408; +-pub const TCSBRK: ::c_ulong = 0x5409; +-pub const TCXONC: ::c_ulong = 0x540A; +-pub const TCFLSH: ::c_ulong = 0x540B; +-pub const TIOCINQ: ::c_ulong = 0x541B; +-pub const TIOCGPGRP: ::c_ulong = 0x540F; +-pub const TIOCSPGRP: ::c_ulong = 0x5410; +-pub const TIOCOUTQ: ::c_ulong = 0x5411; +-pub const TIOCGWINSZ: ::c_ulong = 0x5413; +-pub const TIOCSWINSZ: ::c_ulong = 0x5414; +-pub const FIONREAD: ::c_ulong = 0x541B; + + pub const TCSANOW: ::c_int = 0; + pub const TCSADRAIN: ::c_int = 1; + pub const TCSAFLUSH: ::c_int = 2; + +-pub const TIOCLINUX: ::c_ulong = 0x541C; +-pub const TIOCGSERIAL: ::c_ulong = 0x541E; +- + // sys/auxv.h + pub const HWCAP_FP: ::c_ulong = 1 << 0; + pub const HWCAP_ASIMD: ::c_ulong = 1 << 1; +@@ -626,6 +573,29 @@ pub const HWCAP_PACG: ::c_ulong = 1 << 31; + //pub const HWCAP2_SVESM4: ::c_ulong = 1 << 6; + //pub const HWCAP2_FLAGM2: ::c_ulong = 1 << 7; + //pub const HWCAP2_FRINT: ::c_ulong = 1 << 8; ++//pub const HWCAP2_MTE: ::c_ulong = 1 << 18; ++ ++// linux/prctl.h ++pub const PR_PAC_RESET_KEYS: ::c_int = 54; ++pub const PR_SET_TAGGED_ADDR_CTRL: ::c_int = 55; ++pub const PR_GET_TAGGED_ADDR_CTRL: ::c_int = 56; ++pub const PR_PAC_SET_ENABLED_KEYS: ::c_int = 60; ++pub const PR_PAC_GET_ENABLED_KEYS: ::c_int = 61; ++ ++pub const PR_TAGGED_ADDR_ENABLE: ::c_ulong = 1; ++ ++pub const PR_PAC_APIAKEY: ::c_ulong = 1 << 0; ++pub const PR_PAC_APIBKEY: ::c_ulong = 1 << 1; ++pub const PR_PAC_APDAKEY: ::c_ulong = 1 << 2; ++pub const PR_PAC_APDBKEY: ::c_ulong = 1 << 3; ++pub const PR_PAC_APGAKEY: ::c_ulong = 1 << 4; ++ ++pub const PR_SME_SET_VL: ::c_int = 63; ++pub const PR_SME_GET_VL: ::c_int = 64; ++pub const PR_SME_VL_LEN_MAX: ::c_int = 0xffff; ++ ++pub const PR_SME_SET_VL_INHERIT: ::c_ulong = 1 << 17; ++pub const PR_SME_SET_VL_ONE_EXEC: ::c_ulong = 1 << 18; + + // Syscall table + pub const SYS_io_setup: ::c_long = 0; +@@ -902,6 +872,8 @@ pub const SYS_pkey_mprotect: ::c_long = 288; + pub const SYS_pkey_alloc: ::c_long = 289; + pub const SYS_pkey_free: ::c_long = 290; + pub const SYS_statx: ::c_long = 291; ++pub const SYS_rseq: ::c_long = 293; ++pub const SYS_kexec_file_load: ::c_long = 294; + pub const SYS_pidfd_send_signal: ::c_long = 424; + pub const SYS_io_uring_setup: ::c_long = 425; + pub const SYS_io_uring_enter: ::c_long = 426; +@@ -921,6 +893,14 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; + + extern "C" { + pub fn sysctl( +@@ -949,3 +929,10 @@ cfg_if! { + pub use self::align::*; + } + } ++ ++cfg_if! { ++ if #[cfg(libc_int128)] { ++ mod int128; ++ pub use self::int128::*; ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs +new file mode 100644 +index 0000000..4cae9c1 +--- /dev/null ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs +@@ -0,0 +1,40 @@ ++s_no_extra_traits! { ++ #[allow(missing_debug_implementations)] ++ #[repr(align(16))] ++ pub struct max_align_t { ++ priv_: [f64; 4] ++ } ++} ++ ++s! { ++ pub struct ucontext_t { ++ pub uc_flags: ::c_ulong, ++ pub uc_link: *mut ucontext_t, ++ pub uc_stack: ::stack_t, ++ pub uc_sigmask: ::sigset_t, ++ pub uc_mcontext: mcontext_t, ++ } ++ ++ #[repr(align(16))] ++ pub struct mcontext_t { ++ pub sc_pc: ::c_ulonglong, ++ pub sc_regs: [::c_ulonglong; 32], ++ pub sc_flags: ::c_ulong, ++ pub sc_extcontext: [u64; 0], ++ } ++ ++ #[repr(align(8))] ++ pub struct clone_args { ++ pub flags: ::c_ulonglong, ++ pub pidfd: ::c_ulonglong, ++ pub child_tid: ::c_ulonglong, ++ pub parent_tid: ::c_ulonglong, ++ pub exit_signal: ::c_ulonglong, ++ pub stack: ::c_ulonglong, ++ pub stack_size: ::c_ulonglong, ++ pub tls: ::c_ulonglong, ++ pub set_tid: ::c_ulonglong, ++ pub set_tid_size: ::c_ulonglong, ++ pub cgroup: ::c_ulonglong, ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs +new file mode 100644 +index 0000000..af2825b +--- /dev/null ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs +@@ -0,0 +1,864 @@ ++use pthread_mutex_t; ++ ++pub type c_char = i8; ++pub type c_long = i64; ++pub type c_ulong = u64; ++pub type wchar_t = i32; ++ ++pub type blksize_t = i32; ++pub type nlink_t = u32; ++pub type suseconds_t = i64; ++pub type __u64 = ::c_ulonglong; ++pub type __s64 = ::c_longlong; ++ ++s! { ++ pub struct stat { ++ pub st_dev: ::dev_t, ++ pub st_ino: ::ino_t, ++ pub st_mode: ::mode_t, ++ pub st_nlink: ::nlink_t, ++ pub st_uid: ::uid_t, ++ pub st_gid: ::gid_t, ++ pub st_rdev: ::dev_t, ++ __pad1: ::dev_t, ++ pub st_size: ::off_t, ++ pub st_blksize: ::blksize_t, ++ __pad2: ::c_int, ++ pub st_blocks: ::blkcnt_t, ++ pub st_atime: ::time_t, ++ pub st_atime_nsec: ::c_long, ++ pub st_mtime: ::time_t, ++ pub st_mtime_nsec: ::c_long, ++ pub st_ctime: ::time_t, ++ pub st_ctime_nsec: ::c_long, ++ __unused: [::c_int; 2], ++ } ++ ++ pub struct stat64 { ++ pub st_dev: ::dev_t, ++ pub st_ino: ::ino64_t, ++ pub st_mode: ::mode_t, ++ pub st_nlink: ::nlink_t, ++ pub st_uid: ::uid_t, ++ pub st_gid: ::gid_t, ++ pub st_rdev: ::dev_t, ++ pub __pad1: ::dev_t, ++ pub st_size: ::off64_t, ++ pub st_blksize: ::blksize_t, ++ pub __pad2: ::c_int, ++ pub st_blocks: ::blkcnt_t, ++ pub st_atime: ::time_t, ++ pub st_atime_nsec: ::c_long, ++ pub st_mtime: ::time_t, ++ pub st_mtime_nsec: ::c_long, ++ pub st_ctime: ::time_t, ++ pub st_ctime_nsec: ::c_long, ++ __unused: [::c_int; 2], ++ } ++ ++ pub struct statfs { ++ pub f_type: ::__fsword_t, ++ pub f_bsize: ::__fsword_t, ++ pub f_blocks: ::fsblkcnt_t, ++ pub f_bfree: ::fsblkcnt_t, ++ pub f_bavail: ::fsblkcnt_t, ++ pub f_files: ::fsfilcnt_t, ++ pub f_ffree: ::fsfilcnt_t, ++ pub f_fsid: ::fsid_t, ++ pub f_namelen: ::__fsword_t, ++ pub f_frsize: ::__fsword_t, ++ pub f_flags: ::__fsword_t, ++ pub f_spare: [::__fsword_t; 4], ++ } ++ ++ pub struct statfs64 { ++ pub f_type: ::__fsword_t, ++ pub f_bsize: ::__fsword_t, ++ pub f_blocks: u64, ++ pub f_bfree: u64, ++ pub f_bavail: u64, ++ pub f_files: u64, ++ pub f_ffree: u64, ++ pub f_fsid: ::fsid_t, ++ pub f_namelen: ::__fsword_t, ++ pub f_frsize: ::__fsword_t, ++ pub f_flags: ::__fsword_t, ++ pub f_spare: [::__fsword_t; 4], ++ } ++ ++ pub struct flock { ++ pub l_type: ::c_short, ++ pub l_whence: ::c_short, ++ pub l_start: ::off_t, ++ pub l_len: ::off_t, ++ pub l_pid: ::pid_t, ++ } ++ ++ pub struct flock64 { ++ pub l_type: ::c_short, ++ pub l_whence: ::c_short, ++ pub l_start: ::off64_t, ++ pub l_len: ::off64_t, ++ pub l_pid: ::pid_t, ++ } ++ ++ pub struct statvfs { ++ pub f_bsize: ::c_ulong, ++ pub f_frsize: ::c_ulong, ++ pub f_blocks: ::fsblkcnt_t, ++ pub f_bfree: ::fsblkcnt_t, ++ pub f_bavail: ::fsblkcnt_t, ++ pub f_files: ::fsfilcnt_t, ++ pub f_ffree: ::fsfilcnt_t, ++ pub f_favail: ::fsfilcnt_t, ++ pub f_fsid: ::c_ulong, ++ pub f_flag: ::c_ulong, ++ pub f_namemax: ::c_ulong, ++ __f_spare: [::c_int; 6], ++ } ++ ++ pub struct statvfs64 { ++ pub f_bsize: ::c_ulong, ++ pub f_frsize: ::c_ulong, ++ pub f_blocks: u64, ++ pub f_bfree: u64, ++ pub f_bavail: u64, ++ pub f_files: u64, ++ pub f_ffree: u64, ++ pub f_favail: u64, ++ pub f_fsid: ::c_ulong, ++ pub f_flag: ::c_ulong, ++ pub f_namemax: ::c_ulong, ++ __f_spare: [::c_int; 6], ++ } ++ ++ pub struct pthread_attr_t { ++ __size: [::c_ulong; 7] ++ } ++ ++ pub struct sigaction { ++ pub sa_sigaction: ::sighandler_t, ++ pub sa_mask: ::sigset_t, ++ pub sa_flags: ::c_int, ++ pub sa_restorer: ::Option, ++ } ++ ++ pub struct stack_t { ++ pub ss_sp: *mut ::c_void, ++ pub ss_flags: ::c_int, ++ pub ss_size: ::size_t, ++ } ++ ++ pub struct siginfo_t { ++ pub si_signo: ::c_int, ++ pub si_errno: ::c_int, ++ pub si_code: ::c_int, ++ #[doc(hidden)] ++ #[deprecated( ++ since="0.2.54", ++ note="Please leave a comment on \ ++ https://github.com/rust-lang/libc/pull/1316 if you're using \ ++ this field" ++ )] ++ pub _pad: [::c_int; 29], ++ _align: [u64; 0], ++ } ++ ++ pub struct ipc_perm { ++ pub __key: ::key_t, ++ pub uid: ::uid_t, ++ pub gid: ::gid_t, ++ pub cuid: ::uid_t, ++ pub cgid: ::gid_t, ++ pub mode: ::c_uint, ++ pub __seq: ::c_ushort, ++ __pad2: ::c_ushort, ++ __unused1: ::c_ulong, ++ __unused2: ::c_ulong ++ } ++ ++ pub struct shmid_ds { ++ pub shm_perm: ::ipc_perm, ++ pub shm_segsz: ::size_t, ++ pub shm_atime: ::time_t, ++ pub shm_dtime: ::time_t, ++ pub shm_ctime: ::time_t, ++ pub shm_cpid: ::pid_t, ++ pub shm_lpid: ::pid_t, ++ pub shm_nattch: ::shmatt_t, ++ __unused4: ::c_ulong, ++ __unused5: ::c_ulong ++ } ++} ++ ++pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; ++pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; ++pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; ++pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; ++pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; ++pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; ++ ++align_const! { ++ #[cfg(target_endian = "little")] ++ pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = ++ pthread_mutex_t { ++ size: [ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ ], ++ }; ++ #[cfg(target_endian = "little")] ++ pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = ++ pthread_mutex_t { ++ size: [ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ ], ++ }; ++ #[cfg(target_endian = "little")] ++ pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = ++ pthread_mutex_t { ++ size: [ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ ], ++ }; ++ #[cfg(target_endian = "big")] ++ pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = ++ pthread_mutex_t { ++ size: [ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ ], ++ }; ++ #[cfg(target_endian = "big")] ++ pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = ++ pthread_mutex_t { ++ size: [ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ ], ++ }; ++ #[cfg(target_endian = "big")] ++ pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = ++ pthread_mutex_t { ++ size: [ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ ], ++ }; ++} ++ ++pub const SYS_io_setup: ::c_long = 0; ++pub const SYS_io_destroy: ::c_long = 1; ++pub const SYS_io_submit: ::c_long = 2; ++pub const SYS_io_cancel: ::c_long = 3; ++pub const SYS_io_getevents: ::c_long = 4; ++pub const SYS_setxattr: ::c_long = 5; ++pub const SYS_lsetxattr: ::c_long = 6; ++pub const SYS_fsetxattr: ::c_long = 7; ++pub const SYS_getxattr: ::c_long = 8; ++pub const SYS_lgetxattr: ::c_long = 9; ++pub const SYS_fgetxattr: ::c_long = 10; ++pub const SYS_listxattr: ::c_long = 11; ++pub const SYS_llistxattr: ::c_long = 12; ++pub const SYS_flistxattr: ::c_long = 13; ++pub const SYS_removexattr: ::c_long = 14; ++pub const SYS_lremovexattr: ::c_long = 15; ++pub const SYS_fremovexattr: ::c_long = 16; ++pub const SYS_getcwd: ::c_long = 17; ++pub const SYS_lookup_dcookie: ::c_long = 18; ++pub const SYS_eventfd2: ::c_long = 19; ++pub const SYS_epoll_create1: ::c_long = 20; ++pub const SYS_epoll_ctl: ::c_long = 21; ++pub const SYS_epoll_pwait: ::c_long = 22; ++pub const SYS_dup: ::c_long = 23; ++pub const SYS_dup3: ::c_long = 24; ++pub const SYS_fcntl: ::c_long = 25; ++pub const SYS_inotify_init1: ::c_long = 26; ++pub const SYS_inotify_add_watch: ::c_long = 27; ++pub const SYS_inotify_rm_watch: ::c_long = 28; ++pub const SYS_ioctl: ::c_long = 29; ++pub const SYS_ioprio_set: ::c_long = 30; ++pub const SYS_ioprio_get: ::c_long = 31; ++pub const SYS_flock: ::c_long = 32; ++pub const SYS_mknodat: ::c_long = 33; ++pub const SYS_mkdirat: ::c_long = 34; ++pub const SYS_unlinkat: ::c_long = 35; ++pub const SYS_symlinkat: ::c_long = 36; ++pub const SYS_linkat: ::c_long = 37; ++pub const SYS_umount2: ::c_long = 39; ++pub const SYS_mount: ::c_long = 40; ++pub const SYS_pivot_root: ::c_long = 41; ++pub const SYS_nfsservctl: ::c_long = 42; ++pub const SYS_statfs: ::c_long = 43; ++pub const SYS_fstatfs: ::c_long = 44; ++pub const SYS_truncate: ::c_long = 45; ++pub const SYS_ftruncate: ::c_long = 46; ++pub const SYS_fallocate: ::c_long = 47; ++pub const SYS_faccessat: ::c_long = 48; ++pub const SYS_chdir: ::c_long = 49; ++pub const SYS_fchdir: ::c_long = 50; ++pub const SYS_chroot: ::c_long = 51; ++pub const SYS_fchmod: ::c_long = 52; ++pub const SYS_fchmodat: ::c_long = 53; ++pub const SYS_fchownat: ::c_long = 54; ++pub const SYS_fchown: ::c_long = 55; ++pub const SYS_openat: ::c_long = 56; ++pub const SYS_close: ::c_long = 57; ++pub const SYS_vhangup: ::c_long = 58; ++pub const SYS_pipe2: ::c_long = 59; ++pub const SYS_quotactl: ::c_long = 60; ++pub const SYS_getdents64: ::c_long = 61; ++pub const SYS_lseek: ::c_long = 62; ++pub const SYS_read: ::c_long = 63; ++pub const SYS_write: ::c_long = 64; ++pub const SYS_readv: ::c_long = 65; ++pub const SYS_writev: ::c_long = 66; ++pub const SYS_pread64: ::c_long = 67; ++pub const SYS_pwrite64: ::c_long = 68; ++pub const SYS_preadv: ::c_long = 69; ++pub const SYS_pwritev: ::c_long = 70; ++pub const SYS_sendfile: ::c_long = 71; ++pub const SYS_pselect6: ::c_long = 72; ++pub const SYS_ppoll: ::c_long = 73; ++pub const SYS_signalfd4: ::c_long = 74; ++pub const SYS_vmsplice: ::c_long = 75; ++pub const SYS_splice: ::c_long = 76; ++pub const SYS_tee: ::c_long = 77; ++pub const SYS_readlinkat: ::c_long = 78; ++pub const SYS_sync: ::c_long = 81; ++pub const SYS_fsync: ::c_long = 82; ++pub const SYS_fdatasync: ::c_long = 83; ++pub const SYS_sync_file_range: ::c_long = 84; ++pub const SYS_timerfd_create: ::c_long = 85; ++pub const SYS_timerfd_settime: ::c_long = 86; ++pub const SYS_timerfd_gettime: ::c_long = 87; ++pub const SYS_utimensat: ::c_long = 88; ++pub const SYS_acct: ::c_long = 89; ++pub const SYS_capget: ::c_long = 90; ++pub const SYS_capset: ::c_long = 91; ++pub const SYS_personality: ::c_long = 92; ++pub const SYS_exit: ::c_long = 93; ++pub const SYS_exit_group: ::c_long = 94; ++pub const SYS_waitid: ::c_long = 95; ++pub const SYS_set_tid_address: ::c_long = 96; ++pub const SYS_unshare: ::c_long = 97; ++pub const SYS_futex: ::c_long = 98; ++pub const SYS_set_robust_list: ::c_long = 99; ++pub const SYS_get_robust_list: ::c_long = 100; ++pub const SYS_nanosleep: ::c_long = 101; ++pub const SYS_getitimer: ::c_long = 102; ++pub const SYS_setitimer: ::c_long = 103; ++pub const SYS_kexec_load: ::c_long = 104; ++pub const SYS_init_module: ::c_long = 105; ++pub const SYS_delete_module: ::c_long = 106; ++pub const SYS_timer_create: ::c_long = 107; ++pub const SYS_timer_gettime: ::c_long = 108; ++pub const SYS_timer_getoverrun: ::c_long = 109; ++pub const SYS_timer_settime: ::c_long = 110; ++pub const SYS_timer_delete: ::c_long = 111; ++pub const SYS_clock_settime: ::c_long = 112; ++pub const SYS_clock_gettime: ::c_long = 113; ++pub const SYS_clock_getres: ::c_long = 114; ++pub const SYS_clock_nanosleep: ::c_long = 115; ++pub const SYS_syslog: ::c_long = 116; ++pub const SYS_ptrace: ::c_long = 117; ++pub const SYS_sched_setparam: ::c_long = 118; ++pub const SYS_sched_setscheduler: ::c_long = 119; ++pub const SYS_sched_getscheduler: ::c_long = 120; ++pub const SYS_sched_getparam: ::c_long = 121; ++pub const SYS_sched_setaffinity: ::c_long = 122; ++pub const SYS_sched_getaffinity: ::c_long = 123; ++pub const SYS_sched_yield: ::c_long = 124; ++pub const SYS_sched_get_priority_max: ::c_long = 125; ++pub const SYS_sched_get_priority_min: ::c_long = 126; ++pub const SYS_sched_rr_get_interval: ::c_long = 127; ++pub const SYS_restart_syscall: ::c_long = 128; ++pub const SYS_kill: ::c_long = 129; ++pub const SYS_tkill: ::c_long = 130; ++pub const SYS_tgkill: ::c_long = 131; ++pub const SYS_sigaltstack: ::c_long = 132; ++pub const SYS_rt_sigsuspend: ::c_long = 133; ++pub const SYS_rt_sigaction: ::c_long = 134; ++pub const SYS_rt_sigprocmask: ::c_long = 135; ++pub const SYS_rt_sigpending: ::c_long = 136; ++pub const SYS_rt_sigtimedwait: ::c_long = 137; ++pub const SYS_rt_sigqueueinfo: ::c_long = 138; ++pub const SYS_rt_sigreturn: ::c_long = 139; ++pub const SYS_setpriority: ::c_long = 140; ++pub const SYS_getpriority: ::c_long = 141; ++pub const SYS_reboot: ::c_long = 142; ++pub const SYS_setregid: ::c_long = 143; ++pub const SYS_setgid: ::c_long = 144; ++pub const SYS_setreuid: ::c_long = 145; ++pub const SYS_setuid: ::c_long = 146; ++pub const SYS_setresuid: ::c_long = 147; ++pub const SYS_getresuid: ::c_long = 148; ++pub const SYS_setresgid: ::c_long = 149; ++pub const SYS_getresgid: ::c_long = 150; ++pub const SYS_setfsuid: ::c_long = 151; ++pub const SYS_setfsgid: ::c_long = 152; ++pub const SYS_times: ::c_long = 153; ++pub const SYS_setpgid: ::c_long = 154; ++pub const SYS_getpgid: ::c_long = 155; ++pub const SYS_getsid: ::c_long = 156; ++pub const SYS_setsid: ::c_long = 157; ++pub const SYS_getgroups: ::c_long = 158; ++pub const SYS_setgroups: ::c_long = 159; ++pub const SYS_uname: ::c_long = 160; ++pub const SYS_sethostname: ::c_long = 161; ++pub const SYS_setdomainname: ::c_long = 162; ++pub const SYS_getrusage: ::c_long = 165; ++pub const SYS_umask: ::c_long = 166; ++pub const SYS_prctl: ::c_long = 167; ++pub const SYS_getcpu: ::c_long = 168; ++pub const SYS_gettimeofday: ::c_long = 169; ++pub const SYS_settimeofday: ::c_long = 170; ++pub const SYS_adjtimex: ::c_long = 171; ++pub const SYS_getpid: ::c_long = 172; ++pub const SYS_getppid: ::c_long = 173; ++pub const SYS_getuid: ::c_long = 174; ++pub const SYS_geteuid: ::c_long = 175; ++pub const SYS_getgid: ::c_long = 176; ++pub const SYS_getegid: ::c_long = 177; ++pub const SYS_gettid: ::c_long = 178; ++pub const SYS_sysinfo: ::c_long = 179; ++pub const SYS_mq_open: ::c_long = 180; ++pub const SYS_mq_unlink: ::c_long = 181; ++pub const SYS_mq_timedsend: ::c_long = 182; ++pub const SYS_mq_timedreceive: ::c_long = 183; ++pub const SYS_mq_notify: ::c_long = 184; ++pub const SYS_mq_getsetattr: ::c_long = 185; ++pub const SYS_msgget: ::c_long = 186; ++pub const SYS_msgctl: ::c_long = 187; ++pub const SYS_msgrcv: ::c_long = 188; ++pub const SYS_msgsnd: ::c_long = 189; ++pub const SYS_semget: ::c_long = 190; ++pub const SYS_semctl: ::c_long = 191; ++pub const SYS_semtimedop: ::c_long = 192; ++pub const SYS_semop: ::c_long = 193; ++pub const SYS_shmget: ::c_long = 194; ++pub const SYS_shmctl: ::c_long = 195; ++pub const SYS_shmat: ::c_long = 196; ++pub const SYS_shmdt: ::c_long = 197; ++pub const SYS_socket: ::c_long = 198; ++pub const SYS_socketpair: ::c_long = 199; ++pub const SYS_bind: ::c_long = 200; ++pub const SYS_listen: ::c_long = 201; ++pub const SYS_accept: ::c_long = 202; ++pub const SYS_connect: ::c_long = 203; ++pub const SYS_getsockname: ::c_long = 204; ++pub const SYS_getpeername: ::c_long = 205; ++pub const SYS_sendto: ::c_long = 206; ++pub const SYS_recvfrom: ::c_long = 207; ++pub const SYS_setsockopt: ::c_long = 208; ++pub const SYS_getsockopt: ::c_long = 209; ++pub const SYS_shutdown: ::c_long = 210; ++pub const SYS_sendmsg: ::c_long = 211; ++pub const SYS_recvmsg: ::c_long = 212; ++pub const SYS_readahead: ::c_long = 213; ++pub const SYS_brk: ::c_long = 214; ++pub const SYS_munmap: ::c_long = 215; ++pub const SYS_mremap: ::c_long = 216; ++pub const SYS_add_key: ::c_long = 217; ++pub const SYS_request_key: ::c_long = 218; ++pub const SYS_keyctl: ::c_long = 219; ++pub const SYS_clone: ::c_long = 220; ++pub const SYS_execve: ::c_long = 221; ++pub const SYS_mmap: ::c_long = 222; ++pub const SYS_fadvise64: ::c_long = 223; ++pub const SYS_swapon: ::c_long = 224; ++pub const SYS_swapoff: ::c_long = 225; ++pub const SYS_mprotect: ::c_long = 226; ++pub const SYS_msync: ::c_long = 227; ++pub const SYS_mlock: ::c_long = 228; ++pub const SYS_munlock: ::c_long = 229; ++pub const SYS_mlockall: ::c_long = 230; ++pub const SYS_munlockall: ::c_long = 231; ++pub const SYS_mincore: ::c_long = 232; ++pub const SYS_madvise: ::c_long = 233; ++pub const SYS_remap_file_pages: ::c_long = 234; ++pub const SYS_mbind: ::c_long = 235; ++pub const SYS_get_mempolicy: ::c_long = 236; ++pub const SYS_set_mempolicy: ::c_long = 237; ++pub const SYS_migrate_pages: ::c_long = 238; ++pub const SYS_move_pages: ::c_long = 239; ++pub const SYS_rt_tgsigqueueinfo: ::c_long = 240; ++pub const SYS_perf_event_open: ::c_long = 241; ++pub const SYS_accept4: ::c_long = 242; ++pub const SYS_recvmmsg: ::c_long = 243; ++//pub const SYS_arch_specific_syscall: ::c_long = 244; ++pub const SYS_wait4: ::c_long = 260; ++pub const SYS_prlimit64: ::c_long = 261; ++pub const SYS_fanotify_init: ::c_long = 262; ++pub const SYS_fanotify_mark: ::c_long = 263; ++pub const SYS_name_to_handle_at: ::c_long = 264; ++pub const SYS_open_by_handle_at: ::c_long = 265; ++pub const SYS_clock_adjtime: ::c_long = 266; ++pub const SYS_syncfs: ::c_long = 267; ++pub const SYS_setns: ::c_long = 268; ++pub const SYS_sendmmsg: ::c_long = 269; ++pub const SYS_process_vm_readv: ::c_long = 270; ++pub const SYS_process_vm_writev: ::c_long = 271; ++pub const SYS_kcmp: ::c_long = 272; ++pub const SYS_finit_module: ::c_long = 273; ++pub const SYS_sched_setattr: ::c_long = 274; ++pub const SYS_sched_getattr: ::c_long = 275; ++pub const SYS_renameat2: ::c_long = 276; ++pub const SYS_seccomp: ::c_long = 277; ++pub const SYS_getrandom: ::c_long = 278; ++pub const SYS_memfd_create: ::c_long = 279; ++pub const SYS_bpf: ::c_long = 280; ++pub const SYS_execveat: ::c_long = 281; ++pub const SYS_userfaultfd: ::c_long = 282; ++pub const SYS_membarrier: ::c_long = 283; ++pub const SYS_mlock2: ::c_long = 284; ++pub const SYS_copy_file_range: ::c_long = 285; ++pub const SYS_preadv2: ::c_long = 286; ++pub const SYS_pwritev2: ::c_long = 287; ++pub const SYS_pkey_mprotect: ::c_long = 288; ++pub const SYS_pkey_alloc: ::c_long = 289; ++pub const SYS_pkey_free: ::c_long = 290; ++pub const SYS_statx: ::c_long = 291; ++pub const SYS_io_pgetevents: ::c_long = 292; ++pub const SYS_rseq: ::c_long = 293; ++pub const SYS_kexec_file_load: ::c_long = 294; ++pub const SYS_pidfd_send_signal: ::c_long = 424; ++pub const SYS_io_uring_setup: ::c_long = 425; ++pub const SYS_io_uring_enter: ::c_long = 426; ++pub const SYS_io_uring_register: ::c_long = 427; ++pub const SYS_open_tree: ::c_long = 428; ++pub const SYS_move_mount: ::c_long = 429; ++pub const SYS_fsopen: ::c_long = 430; ++pub const SYS_fsconfig: ::c_long = 431; ++pub const SYS_fsmount: ::c_long = 432; ++pub const SYS_fspick: ::c_long = 433; ++pub const SYS_pidfd_open: ::c_long = 434; ++pub const SYS_clone3: ::c_long = 435; ++pub const SYS_close_range: ::c_long = 436; ++pub const SYS_openat2: ::c_long = 437; ++pub const SYS_pidfd_getfd: ::c_long = 438; ++pub const SYS_faccessat2: ::c_long = 439; ++pub const SYS_process_madvise: ::c_long = 440; ++pub const SYS_epoll_pwait2: ::c_long = 441; ++pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++//pub const SYS_set_mempolicy_home_node: ::c_long = 450; ++ ++pub const POSIX_FADV_DONTNEED: ::c_int = 4; ++pub const POSIX_FADV_NOREUSE: ::c_int = 5; ++pub const O_DIRECT: ::c_int = 0o00040000; ++pub const O_DIRECTORY: ::c_int = 0o00200000; ++pub const O_NOFOLLOW: ::c_int = 0o00400000; ++pub const O_TRUNC: ::c_int = 0o00001000; ++pub const O_NOATIME: ::c_int = 0o1000000; ++pub const O_CLOEXEC: ::c_int = 0o02000000; ++pub const O_PATH: ::c_int = 0o10000000; ++pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; ++pub const O_APPEND: ::c_int = 0o00002000; ++pub const O_CREAT: ::c_int = 0o00000100; ++pub const O_EXCL: ::c_int = 0o00000200; ++pub const O_NOCTTY: ::c_int = 0o00000400; ++pub const O_NONBLOCK: ::c_int = 0o00004000; ++pub const FASYNC: ::c_int = 0o00020000; ++pub const O_SYNC: ::c_int = 0o04010000; ++pub const O_RSYNC: ::c_int = 0o04010000; ++pub const O_FSYNC: ::c_int = O_SYNC; ++pub const O_ASYNC: ::c_int = 0o00020000; ++pub const O_DSYNC: ::c_int = 0o00010000; ++pub const O_NDELAY: ::c_int = O_NONBLOCK; ++pub const F_RDLCK: ::c_int = 0; ++pub const F_WRLCK: ::c_int = 1; ++pub const F_UNLCK: ::c_int = 2; ++pub const F_GETLK: ::c_int = 5; ++pub const F_SETLK: ::c_int = 6; ++pub const F_SETLKW: ::c_int = 7; ++pub const F_SETOWN: ::c_int = 8; ++pub const F_GETOWN: ::c_int = 9; ++pub const F_OFD_GETLK: ::c_int = 36; ++pub const F_OFD_SETLK: ::c_int = 37; ++pub const F_OFD_SETLKW: ::c_int = 38; ++ ++pub const EDEADLK: ::c_int = 35; ++pub const EDEADLOCK: ::c_int = 35; ++pub const ENAMETOOLONG: ::c_int = 36; ++pub const ENOLCK: ::c_int = 37; ++pub const ENOSYS: ::c_int = 38; ++pub const ENOTEMPTY: ::c_int = 39; ++pub const ELOOP: ::c_int = 40; ++pub const ENOMSG: ::c_int = 42; ++pub const EIDRM: ::c_int = 43; ++pub const ECHRNG: ::c_int = 44; ++pub const EL2NSYNC: ::c_int = 45; ++pub const EL3HLT: ::c_int = 46; ++pub const EL3RST: ::c_int = 47; ++pub const ELNRNG: ::c_int = 48; ++pub const EUNATCH: ::c_int = 49; ++pub const ENOCSI: ::c_int = 50; ++pub const EL2HLT: ::c_int = 51; ++pub const EBADE: ::c_int = 52; ++pub const EBADR: ::c_int = 53; ++pub const EXFULL: ::c_int = 54; ++pub const ENOANO: ::c_int = 55; ++pub const EBADRQC: ::c_int = 56; ++pub const EBADSLT: ::c_int = 57; ++pub const EBFONT: ::c_int = 59; ++pub const ENOSTR: ::c_int = 60; ++pub const ENODATA: ::c_int = 61; ++pub const ETIME: ::c_int = 62; ++pub const ENOSR: ::c_int = 63; ++pub const ENONET: ::c_int = 64; ++pub const ENOPKG: ::c_int = 65; ++pub const EREMOTE: ::c_int = 66; ++pub const ENOLINK: ::c_int = 67; ++pub const EADV: ::c_int = 68; ++pub const ESRMNT: ::c_int = 69; ++pub const ECOMM: ::c_int = 70; ++pub const EPROTO: ::c_int = 71; ++pub const EDOTDOT: ::c_int = 73; ++pub const EMULTIHOP: ::c_int = 72; ++pub const EOVERFLOW: ::c_int = 75; ++pub const ENOTUNIQ: ::c_int = 76; ++pub const EBADFD: ::c_int = 77; ++pub const EBADMSG: ::c_int = 74; ++pub const EREMCHG: ::c_int = 78; ++pub const ELIBACC: ::c_int = 79; ++pub const ELIBBAD: ::c_int = 80; ++pub const ELIBSCN: ::c_int = 81; ++pub const ELIBMAX: ::c_int = 82; ++pub const ELIBEXEC: ::c_int = 83; ++pub const EILSEQ: ::c_int = 84; ++pub const ERESTART: ::c_int = 85; ++pub const ESTRPIPE: ::c_int = 86; ++pub const EUSERS: ::c_int = 87; ++pub const ENOTSOCK: ::c_int = 88; ++pub const EDESTADDRREQ: ::c_int = 89; ++pub const EMSGSIZE: ::c_int = 90; ++pub const EPROTOTYPE: ::c_int = 91; ++pub const ENOPROTOOPT: ::c_int = 92; ++pub const EPROTONOSUPPORT: ::c_int = 93; ++pub const ESOCKTNOSUPPORT: ::c_int = 94; ++pub const EOPNOTSUPP: ::c_int = 95; ++pub const EPFNOSUPPORT: ::c_int = 96; ++pub const EAFNOSUPPORT: ::c_int = 97; ++pub const EADDRINUSE: ::c_int = 98; ++pub const EADDRNOTAVAIL: ::c_int = 99; ++pub const ENETDOWN: ::c_int = 100; ++pub const ENETUNREACH: ::c_int = 101; ++pub const ENETRESET: ::c_int = 102; ++pub const ECONNABORTED: ::c_int = 103; ++pub const ECONNRESET: ::c_int = 104; ++pub const ENOBUFS: ::c_int = 105; ++pub const EISCONN: ::c_int = 106; ++pub const ENOTCONN: ::c_int = 107; ++pub const ESHUTDOWN: ::c_int = 108; ++pub const ETOOMANYREFS: ::c_int = 109; ++pub const ETIMEDOUT: ::c_int = 110; ++pub const ECONNREFUSED: ::c_int = 111; ++pub const EHOSTDOWN: ::c_int = 112; ++pub const EHOSTUNREACH: ::c_int = 113; ++pub const EALREADY: ::c_int = 114; ++pub const EINPROGRESS: ::c_int = 115; ++pub const ESTALE: ::c_int = 116; ++pub const EUCLEAN: ::c_int = 117; ++pub const ENOTNAM: ::c_int = 118; ++pub const ENAVAIL: ::c_int = 119; ++pub const EISNAM: ::c_int = 120; ++pub const EREMOTEIO: ::c_int = 121; ++pub const EDQUOT: ::c_int = 122; ++pub const ENOMEDIUM: ::c_int = 123; ++pub const EMEDIUMTYPE: ::c_int = 124; ++pub const ECANCELED: ::c_int = 125; ++pub const ENOKEY: ::c_int = 126; ++pub const EKEYEXPIRED: ::c_int = 127; ++pub const EKEYREVOKED: ::c_int = 128; ++pub const EKEYREJECTED: ::c_int = 129; ++pub const EOWNERDEAD: ::c_int = 130; ++pub const ENOTRECOVERABLE: ::c_int = 131; ++pub const ERFKILL: ::c_int = 132; ++pub const EHWPOISON: ::c_int = 133; ++ ++pub const MAP_NORESERVE: ::c_int = 0x4000; ++pub const MAP_ANONYMOUS: ::c_int = 0x0020; ++pub const MAP_ANON: ::c_int = 0x0020; ++pub const MAP_GROWSDOWN: ::c_int = 0x0100; ++pub const MAP_DENYWRITE: ::c_int = 0x0800; ++pub const MAP_EXECUTABLE: ::c_int = 0x1000; ++pub const MAP_LOCKED: ::c_int = 0x2000; ++pub const MAP_POPULATE: ::c_int = 0x8000; ++pub const MAP_NONBLOCK: ::c_int = 0x10000; ++pub const MAP_STACK: ::c_int = 0x20000; ++pub const MAP_HUGETLB: ::c_int = 0x40000; ++pub const MCL_CURRENT: ::c_int = 0x0001; ++pub const MCL_FUTURE: ::c_int = 0x0002; ++pub const MCL_ONFAULT: ::c_int = 0x0004; ++ ++pub const SOCK_STREAM: ::c_int = 1; ++pub const SOCK_DGRAM: ::c_int = 2; ++ ++pub const SFD_NONBLOCK: ::c_int = 0x800; ++pub const SFD_CLOEXEC: ::c_int = 0x080000; ++pub const SA_NODEFER: ::c_int = 0x40000000; ++pub const SA_RESETHAND: ::c_int = 0x80000000; ++pub const SA_RESTART: ::c_int = 0x10000000; ++pub const SA_NOCLDSTOP: ::c_int = 0x00000001; ++pub const SA_ONSTACK: ::c_int = 0x08000000; ++pub const SA_SIGINFO: ::c_int = 0x00000004; ++pub const SA_NOCLDWAIT: ::c_int = 0x00000002; ++pub const SIG_BLOCK: ::c_int = 0; ++pub const SIG_UNBLOCK: ::c_int = 1; ++pub const SIG_SETMASK: ::c_int = 2; ++pub const SIGBUS: ::c_int = 7; ++pub const SIGUSR1: ::c_int = 10; ++pub const SIGUSR2: ::c_int = 12; ++pub const SIGSTKFLT: ::c_int = 16; ++pub const SIGCHLD: ::c_int = 17; ++pub const SIGCONT: ::c_int = 18; ++pub const SIGSTOP: ::c_int = 19; ++pub const SIGTSTP: ::c_int = 20; ++pub const SIGTTIN: ::c_int = 21; ++pub const SIGTTOU: ::c_int = 22; ++pub const SIGURG: ::c_int = 23; ++pub const SIGXCPU: ::c_int = 24; ++pub const SIGXFSZ: ::c_int = 25; ++pub const SIGVTALRM: ::c_int = 26; ++pub const SIGPROF: ::c_int = 27; ++pub const SIGWINCH: ::c_int = 28; ++pub const SIGIO: ::c_int = 29; ++pub const SIGPOLL: ::c_int = 29; ++pub const SIGPWR: ::c_int = 30; ++pub const SIGSYS: ::c_int = 31; ++pub const SIGUNUSED: ::c_int = 31; ++ ++pub const POLLWRNORM: ::c_short = 0x100; ++pub const POLLWRBAND: ::c_short = 0x200; ++ ++pub const PTRACE_GETFPREGS: ::c_uint = 14; ++pub const PTRACE_SETFPREGS: ::c_uint = 15; ++pub const PTRACE_DETACH: ::c_uint = 17; ++pub const PTRACE_GETFPXREGS: ::c_uint = 18; ++pub const PTRACE_SETFPXREGS: ::c_uint = 19; ++pub const PTRACE_GETREGS: ::c_uint = 12; ++pub const PTRACE_SETREGS: ::c_uint = 13; ++ ++pub const RTLD_DEEPBIND: ::c_int = 0x8; ++pub const RTLD_GLOBAL: ::c_int = 0x100; ++pub const RTLD_NOLOAD: ::c_int = 0x4; ++ ++pub const VEOF: usize = 4; ++pub const VTIME: usize = 5; ++pub const VMIN: usize = 6; ++pub const VSWTC: usize = 7; ++pub const VSTART: usize = 8; ++pub const VSTOP: usize = 9; ++pub const VSUSP: usize = 10; ++pub const VEOL: usize = 11; ++pub const VREPRINT: usize = 12; ++pub const VDISCARD: usize = 13; ++pub const VWERASE: usize = 14; ++pub const VEOL2: usize = 16; ++pub const IEXTEN: ::tcflag_t = 0x00008000; ++pub const TOSTOP: ::tcflag_t = 0x00000100; ++pub const FLUSHO: ::tcflag_t = 0x00001000; ++pub const EXTPROC: ::tcflag_t = 0x00010000; ++pub const TCSANOW: ::c_int = 0; ++pub const TCSADRAIN: ::c_int = 1; ++pub const TCSAFLUSH: ::c_int = 2; ++pub const SIGSTKSZ: ::size_t = 16384; ++pub const MINSIGSTKSZ: ::size_t = 4096; ++pub const CBAUD: ::tcflag_t = 0o0010017; ++pub const CSIZE: ::tcflag_t = 0x00000030; ++pub const CS6: ::tcflag_t = 0x00000010; ++pub const CS7: ::tcflag_t = 0x00000020; ++pub const CS8: ::tcflag_t = 0x00000030; ++pub const CSTOPB: ::tcflag_t = 0x00000040; ++pub const CREAD: ::tcflag_t = 0x00000080; ++pub const PARENB: ::tcflag_t = 0x00000100; ++pub const PARODD: ::tcflag_t = 0x00000200; ++pub const HUPCL: ::tcflag_t = 0x00000400; ++pub const CLOCAL: ::tcflag_t = 0x00000800; ++pub const CIBAUD: ::tcflag_t = 0o02003600000; ++pub const CBAUDEX: ::tcflag_t = 0o010000; ++pub const B0: ::speed_t = 0o000000; ++pub const B50: ::speed_t = 0o000001; ++pub const B75: ::speed_t = 0o000002; ++pub const B110: ::speed_t = 0o000003; ++pub const B134: ::speed_t = 0o000004; ++pub const B150: ::speed_t = 0o000005; ++pub const B200: ::speed_t = 0o000006; ++pub const B300: ::speed_t = 0o000007; ++pub const B600: ::speed_t = 0o000010; ++pub const B1200: ::speed_t = 0o000011; ++pub const B1800: ::speed_t = 0o000012; ++pub const B2400: ::speed_t = 0o000013; ++pub const B4800: ::speed_t = 0o000014; ++pub const B9600: ::speed_t = 0o000015; ++pub const B19200: ::speed_t = 0o000016; ++pub const B38400: ::speed_t = 0o000017; ++pub const EXTA: ::speed_t = B19200; ++pub const EXTB: ::speed_t = B38400; ++pub const B57600: ::speed_t = 0o010001; ++pub const B115200: ::speed_t = 0o010002; ++pub const B230400: ::speed_t = 0o010003; ++pub const B460800: ::speed_t = 0o010004; ++pub const B500000: ::speed_t = 0o010005; ++pub const B576000: ::speed_t = 0o010006; ++pub const B921600: ::speed_t = 0o010007; ++pub const B1000000: ::speed_t = 0o010010; ++pub const B1152000: ::speed_t = 0o010011; ++pub const B1500000: ::speed_t = 0o010012; ++pub const B2000000: ::speed_t = 0o010013; ++pub const B2500000: ::speed_t = 0o010014; ++pub const B3000000: ::speed_t = 0o010015; ++pub const B3500000: ::speed_t = 0o010016; ++pub const B4000000: ::speed_t = 0o010017; ++pub const TAB1: ::tcflag_t = 0x00000800; ++pub const TAB2: ::tcflag_t = 0x00001000; ++pub const TAB3: ::tcflag_t = 0x00001800; ++pub const CR1: ::tcflag_t = 0x00000200; ++pub const CR2: ::tcflag_t = 0x00000400; ++pub const CR3: ::tcflag_t = 0x00000600; ++pub const FF1: ::tcflag_t = 0x00008000; ++pub const BS1: ::tcflag_t = 0x00002000; ++pub const OLCUC: ::tcflag_t = 0o000002; ++pub const NLDLY: ::tcflag_t = 0o000400; ++pub const CRDLY: ::tcflag_t = 0o003000; ++pub const TABDLY: ::tcflag_t = 0o014000; ++pub const BSDLY: ::tcflag_t = 0o020000; ++pub const FFDLY: ::tcflag_t = 0o100000; ++pub const VTDLY: ::tcflag_t = 0o040000; ++pub const XTABS: ::tcflag_t = 0o014000; ++pub const VT1: ::tcflag_t = 0x00004000; ++pub const ONLCR: ::tcflag_t = 0x4; ++pub const IXON: ::tcflag_t = 0x00000400; ++pub const IXOFF: ::tcflag_t = 0x00001000; ++pub const ECHOKE: ::tcflag_t = 0x00000800; ++pub const ECHOE: ::tcflag_t = 0x00000010; ++pub const ECHOK: ::tcflag_t = 0x00000020; ++pub const ECHONL: ::tcflag_t = 0x00000040; ++pub const ECHOPRT: ::tcflag_t = 0x00000400; ++pub const ECHOCTL: ::tcflag_t = 0x00000200; ++pub const ISIG: ::tcflag_t = 0x00000001; ++pub const ICANON: ::tcflag_t = 0x00000002; ++pub const PENDIN: ::tcflag_t = 0x00004000; ++pub const NOFLSH: ::tcflag_t = 0x00000080; ++ ++pub const NCCS: usize = 32; ++ ++pub const EPOLL_CLOEXEC: ::c_int = 0x80000; ++ ++pub const EFD_CLOEXEC: ::c_int = 0x80000; ++pub const EFD_NONBLOCK: ::c_int = 0x800; ++ ++cfg_if! { ++ if #[cfg(libc_align)] { ++ mod align; ++ pub use self::align::*; ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/mod.rs +index 8793956..66b29a8 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/mod.rs +@@ -8,6 +8,7 @@ pub type nlink_t = u64; + pub type suseconds_t = i64; + pub type wchar_t = i32; + pub type __u64 = ::c_ulong; ++pub type __s64 = ::c_long; + + s! { + pub struct stat { +@@ -183,23 +184,14 @@ s! { + __unused4: ::c_ulong, + __unused5: ::c_ulong + } +- +- pub struct termios2 { +- pub c_iflag: ::tcflag_t, +- pub c_oflag: ::tcflag_t, +- pub c_cflag: ::tcflag_t, +- pub c_lflag: ::tcflag_t, +- pub c_line: ::cc_t, +- pub c_cc: [::cc_t; 23], +- pub c_ispeed: ::speed_t, +- pub c_ospeed: ::speed_t, +- } + } + + pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; ++pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; ++pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + + align_const! { + #[cfg(target_endian = "little")] +@@ -577,6 +569,7 @@ pub const SYS_pkey_mprotect: ::c_long = 5000 + 323; + pub const SYS_pkey_alloc: ::c_long = 5000 + 324; + pub const SYS_pkey_free: ::c_long = 5000 + 325; + pub const SYS_statx: ::c_long = 5000 + 326; ++pub const SYS_rseq: ::c_long = 5000 + 327; + pub const SYS_pidfd_send_signal: ::c_long = 5000 + 424; + pub const SYS_io_uring_setup: ::c_long = 5000 + 425; + pub const SYS_io_uring_enter: ::c_long = 5000 + 426; +@@ -596,6 +589,14 @@ pub const SYS_faccessat2: ::c_long = 5000 + 439; + pub const SYS_process_madvise: ::c_long = 5000 + 440; + pub const SYS_epoll_pwait2: ::c_long = 5000 + 441; + pub const SYS_mount_setattr: ::c_long = 5000 + 442; ++pub const SYS_quotactl_fd: ::c_long = 5000 + 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 5000 + 444; ++pub const SYS_landlock_add_rule: ::c_long = 5000 + 445; ++pub const SYS_landlock_restrict_self: ::c_long = 5000 + 446; ++pub const SYS_memfd_secret: ::c_long = 5000 + 447; ++pub const SYS_process_mrelease: ::c_long = 5000 + 448; ++pub const SYS_futex_waitv: ::c_long = 5000 + 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 5000 + 450; + + pub const SFD_CLOEXEC: ::c_int = 0x080000; + +@@ -639,12 +640,6 @@ pub const O_DIRECT: ::c_int = 0x8000; + pub const O_DIRECTORY: ::c_int = 0x10000; + pub const O_NOFOLLOW: ::c_int = 0x20000; + +-pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 5; +-pub const RLIMIT_AS: ::__rlimit_resource_t = 6; +-pub const RLIMIT_RSS: ::__rlimit_resource_t = 7; +-pub const RLIMIT_NPROC: ::__rlimit_resource_t = 8; +-pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 9; +- + pub const O_APPEND: ::c_int = 8; + pub const O_CREAT: ::c_int = 256; + pub const O_EXCL: ::c_int = 1024; +@@ -756,10 +751,6 @@ pub const MAP_HUGETLB: ::c_int = 0x080000; + pub const SOCK_STREAM: ::c_int = 2; + pub const SOCK_DGRAM: ::c_int = 1; + +-pub const FIOCLEX: ::c_ulong = 0x6601; +-pub const FIONCLEX: ::c_ulong = 0x6602; +-pub const FIONBIO: ::c_ulong = 0x667e; +- + pub const SA_ONSTACK: ::c_int = 0x08000000; + pub const SA_SIGINFO: ::c_int = 0x00000008; + pub const SA_NOCLDWAIT: ::c_int = 0x00010000; +@@ -826,40 +817,6 @@ pub const F_OFD_SETLKW: ::c_int = 38; + + pub const SFD_NONBLOCK: ::c_int = 0x80; + +-pub const TCGETS: ::c_ulong = 0x540d; +-pub const TCSETS: ::c_ulong = 0x540e; +-pub const TCSETSW: ::c_ulong = 0x540f; +-pub const TCSETSF: ::c_ulong = 0x5410; +-pub const TCGETA: ::c_ulong = 0x5401; +-pub const TCSETA: ::c_ulong = 0x5402; +-pub const TCSETAW: ::c_ulong = 0x5403; +-pub const TCSETAF: ::c_ulong = 0x5404; +-pub const TCSBRK: ::c_ulong = 0x5405; +-pub const TCXONC: ::c_ulong = 0x5406; +-pub const TCFLSH: ::c_ulong = 0x5407; +-pub const TIOCSBRK: ::c_ulong = 0x5427; +-pub const TIOCCBRK: ::c_ulong = 0x5428; +-pub const TIOCGSOFTCAR: ::c_ulong = 0x5481; +-pub const TIOCSSOFTCAR: ::c_ulong = 0x5482; +-pub const TIOCINQ: ::c_ulong = 0x467f; +-pub const TIOCLINUX: ::c_ulong = 0x5483; +-pub const TIOCGSERIAL: ::c_ulong = 0x5484; +-pub const TIOCEXCL: ::c_ulong = 0x740d; +-pub const TIOCNXCL: ::c_ulong = 0x740e; +-pub const TIOCSCTTY: ::c_ulong = 0x5480; +-pub const TIOCGPGRP: ::c_ulong = 0x40047477; +-pub const TIOCSPGRP: ::c_ulong = 0x80047476; +-pub const TIOCOUTQ: ::c_ulong = 0x7472; +-pub const TIOCSTI: ::c_ulong = 0x5472; +-pub const TIOCGWINSZ: ::c_ulong = 0x40087468; +-pub const TIOCSWINSZ: ::c_ulong = 0x80087467; +-pub const TIOCMGET: ::c_ulong = 0x741d; +-pub const TIOCMBIS: ::c_ulong = 0x741b; +-pub const TIOCMBIC: ::c_ulong = 0x741c; +-pub const TIOCMSET: ::c_ulong = 0x741a; +-pub const FIONREAD: ::c_ulong = 0x467f; +-pub const TIOCCONS: ::c_ulong = 0x80047478; +- + pub const RTLD_DEEPBIND: ::c_int = 0x10; + pub const RTLD_GLOBAL: ::c_int = 0x4; + pub const RTLD_NOLOAD: ::c_int = 0x8; +@@ -939,7 +896,6 @@ pub const B19200: ::speed_t = 0o000016; + pub const B38400: ::speed_t = 0o000017; + pub const EXTA: ::speed_t = B19200; + pub const EXTB: ::speed_t = B38400; +-pub const BOTHER: ::speed_t = 0o010000; + pub const B57600: ::speed_t = 0o010001; + pub const B115200: ::speed_t = 0o010002; + pub const B230400: ::speed_t = 0o010003; +@@ -956,13 +912,6 @@ pub const B3000000: ::speed_t = 0o010015; + pub const B3500000: ::speed_t = 0o010016; + pub const B4000000: ::speed_t = 0o010017; + +-pub const TIOCM_ST: ::c_int = 0x010; +-pub const TIOCM_SR: ::c_int = 0x020; +-pub const TIOCM_CTS: ::c_int = 0x040; +-pub const TIOCM_CAR: ::c_int = 0x100; +-pub const TIOCM_RNG: ::c_int = 0x200; +-pub const TIOCM_DSR: ::c_int = 0x400; +- + pub const EHWPOISON: ::c_int = 168; + + extern "C" { +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/mod.rs +index 138adc9..443958c 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/mod.rs +@@ -9,6 +9,11 @@ pub type msglen_t = u64; + pub type fsblkcnt_t = u64; + pub type fsfilcnt_t = u64; + pub type rlim_t = u64; ++#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] ++pub type __syscall_ulong_t = ::c_ulonglong; ++#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] ++pub type __syscall_ulong_t = ::c_ulong; ++ + cfg_if! { + if #[cfg(all(target_arch = "aarch64", target_pointer_width = "32"))] { + pub type clock_t = i32; +@@ -60,9 +65,32 @@ s! { + __glibc_reserved5: u64, + } + ++ pub struct semid_ds { ++ pub sem_perm: ipc_perm, ++ pub sem_otime: ::time_t, ++ #[cfg(not(any( ++ target_arch = "aarch64", ++ target_arch = "loongarch64", ++ target_arch = "mips64", ++ target_arch = "powerpc64", ++ target_arch = "riscv64", ++ target_arch = "sparc64")))] ++ __reserved: ::__syscall_ulong_t, ++ pub sem_ctime: ::time_t, ++ #[cfg(not(any( ++ target_arch = "aarch64", ++ target_arch = "loongarch64", ++ target_arch = "mips64", ++ target_arch = "powerpc64", ++ target_arch = "riscv64", ++ target_arch = "sparc64")))] ++ __reserved2: ::__syscall_ulong_t, ++ pub sem_nsems: ::__syscall_ulong_t, ++ __glibc_reserved3: ::__syscall_ulong_t, ++ __glibc_reserved4: ::__syscall_ulong_t, ++ } + } + +-pub const RLIM_INFINITY: ::rlim_t = !0; + pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; + + pub const O_LARGEFILE: ::c_int = 0; +@@ -89,6 +117,9 @@ cfg_if! { + } else if #[cfg(any(target_arch = "riscv64"))] { + mod riscv64; + pub use self::riscv64::*; ++ } else if #[cfg(any(target_arch = "loongarch64"))] { ++ mod loongarch64; ++ pub use self::loongarch64::*; + } else { + // Unknown target_arch + } +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs +index dcaeaf5..2b225e4 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs +@@ -10,6 +10,7 @@ pub type nlink_t = u64; + pub type blksize_t = i64; + pub type suseconds_t = i64; + pub type __u64 = ::c_ulong; ++pub type __s64 = ::c_long; + + s! { + pub struct sigaction { +@@ -190,12 +191,6 @@ s! { + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } +- +- pub struct ip_mreqn { +- pub imr_multiaddr: ::in_addr, +- pub imr_address: ::in_addr, +- pub imr_ifindex: ::c_int, +- } + } + + pub const POSIX_FADV_DONTNEED: ::c_int = 4; +@@ -206,15 +201,7 @@ pub const RTLD_GLOBAL: ::c_int = 0x100; + pub const RTLD_NOLOAD: ::c_int = 0x4; + pub const VEOF: usize = 4; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +- +-pub const TIOCGSOFTCAR: ::c_ulong = 0x5419; +-pub const TIOCSSOFTCAR: ::c_ulong = 0x541A; +- +-pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; +-pub const RLIMIT_AS: ::__rlimit_resource_t = 9; +-pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; +-pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 7; +-pub const RLIMIT_NPROC: ::__rlimit_resource_t = 6; ++pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + + pub const O_APPEND: ::c_int = 1024; + pub const O_CREAT: ::c_int = 64; +@@ -381,29 +368,6 @@ pub const TCSANOW: ::c_int = 0; + pub const TCSADRAIN: ::c_int = 1; + pub const TCSAFLUSH: ::c_int = 2; + +-pub const TIOCLINUX: ::c_ulong = 0x541C; +-pub const TIOCGSERIAL: ::c_ulong = 0x541E; +-pub const TIOCEXCL: ::c_ulong = 0x540C; +-pub const TIOCNXCL: ::c_ulong = 0x540D; +-pub const TIOCSCTTY: ::c_ulong = 0x540E; +-pub const TIOCSTI: ::c_ulong = 0x5412; +-pub const TIOCMGET: ::c_ulong = 0x5415; +-pub const TIOCMBIS: ::c_ulong = 0x5416; +-pub const TIOCMBIC: ::c_ulong = 0x5417; +-pub const TIOCMSET: ::c_ulong = 0x5418; +-pub const TIOCCONS: ::c_ulong = 0x541D; +-pub const TIOCSBRK: ::c_ulong = 0x5427; +-pub const TIOCCBRK: ::c_ulong = 0x5428; +-pub const TIOCGRS485: ::c_int = 0x542E; +-pub const TIOCSRS485: ::c_int = 0x542F; +- +-pub const TIOCM_ST: ::c_int = 0x008; +-pub const TIOCM_SR: ::c_int = 0x010; +-pub const TIOCM_CTS: ::c_int = 0x020; +-pub const TIOCM_CAR: ::c_int = 0x040; +-pub const TIOCM_RNG: ::c_int = 0x080; +-pub const TIOCM_DSR: ::c_int = 0x100; +- + pub const SFD_CLOEXEC: ::c_int = 0x080000; + + pub const NCCS: usize = 32; +@@ -439,6 +403,7 @@ pub const EFD_CLOEXEC: ::c_int = 0x80000; + pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; ++pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + + align_const! { + #[cfg(target_endian = "little")] +@@ -506,10 +471,6 @@ pub const ENAVAIL: ::c_int = 119; + pub const EISNAM: ::c_int = 120; + pub const EREMOTEIO: ::c_int = 121; + +-pub const FIOCLEX: ::c_ulong = 0x20006601; +-pub const FIONCLEX: ::c_ulong = 0x20006602; +-pub const FIONBIO: ::c_ulong = 0x8004667e; +- + pub const MCL_CURRENT: ::c_int = 0x2000; + pub const MCL_FUTURE: ::c_int = 0x4000; + +@@ -599,7 +560,6 @@ pub const B2500000: ::speed_t = 0o0033; + pub const B3000000: ::speed_t = 0o0034; + pub const B3500000: ::speed_t = 0o0035; + pub const B4000000: ::speed_t = 0o0036; +-pub const BOTHER: ::speed_t = 0o0037; + + pub const VEOL: usize = 6; + pub const VEOL2: usize = 8; +@@ -608,24 +568,6 @@ pub const IEXTEN: ::tcflag_t = 0x400; + pub const TOSTOP: ::tcflag_t = 0x400000; + pub const FLUSHO: ::tcflag_t = 0x800000; + pub const EXTPROC: ::tcflag_t = 0x10000000; +-pub const TCGETS: ::c_ulong = 0x403c7413; +-pub const TCSETS: ::c_ulong = 0x803c7414; +-pub const TCSETSW: ::c_ulong = 0x803c7415; +-pub const TCSETSF: ::c_ulong = 0x803c7416; +-pub const TCGETA: ::c_ulong = 0x40147417; +-pub const TCSETA: ::c_ulong = 0x80147418; +-pub const TCSETAW: ::c_ulong = 0x80147419; +-pub const TCSETAF: ::c_ulong = 0x8014741c; +-pub const TCSBRK: ::c_ulong = 0x2000741d; +-pub const TCXONC: ::c_ulong = 0x2000741e; +-pub const TCFLSH: ::c_ulong = 0x2000741f; +-pub const TIOCINQ: ::c_ulong = 0x4004667f; +-pub const TIOCGPGRP: ::c_ulong = 0x40047477; +-pub const TIOCSPGRP: ::c_ulong = 0x80047476; +-pub const TIOCOUTQ: ::c_ulong = 0x40047473; +-pub const TIOCGWINSZ: ::c_ulong = 0x40087468; +-pub const TIOCSWINSZ: ::c_ulong = 0x80087467; +-pub const FIONREAD: ::c_ulong = 0x4004667f; + + // Syscall table + pub const SYS_restart_syscall: ::c_long = 0; +@@ -988,6 +930,7 @@ pub const SYS_preadv2: ::c_long = 380; + pub const SYS_pwritev2: ::c_long = 381; + pub const SYS_kexec_file_load: ::c_long = 382; + pub const SYS_statx: ::c_long = 383; ++pub const SYS_rseq: ::c_long = 387; + pub const SYS_pidfd_send_signal: ::c_long = 424; + pub const SYS_io_uring_setup: ::c_long = 425; + pub const SYS_io_uring_enter: ::c_long = 426; +@@ -1007,6 +950,14 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; + + extern "C" { + pub fn sysctl( +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/align.rs +new file mode 100644 +index 0000000..48d152a +--- /dev/null ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/align.rs +@@ -0,0 +1,44 @@ ++s_no_extra_traits! { ++ #[allow(missing_debug_implementations)] ++ pub struct ucontext_t { ++ pub __uc_flags: ::c_ulong, ++ pub uc_link: *mut ucontext_t, ++ pub uc_stack: ::stack_t, ++ pub uc_sigmask: ::sigset_t, ++ pub uc_mcontext: mcontext_t, ++ } ++ ++ #[allow(missing_debug_implementations)] ++ #[repr(align(16))] ++ pub struct mcontext_t { ++ pub __gregs: [::c_ulong; 32], ++ pub __fpregs: __riscv_mc_fp_state, ++ } ++ ++ #[allow(missing_debug_implementations)] ++ pub union __riscv_mc_fp_state { ++ pub __f: __riscv_mc_f_ext_state, ++ pub __d: __riscv_mc_d_ext_state, ++ pub __q: __riscv_mc_q_ext_state, ++ } ++ ++ #[allow(missing_debug_implementations)] ++ pub struct __riscv_mc_f_ext_state { ++ pub __f: [::c_uint; 32], ++ pub __fcsr: ::c_uint, ++ } ++ ++ #[allow(missing_debug_implementations)] ++ pub struct __riscv_mc_d_ext_state { ++ pub __f: [::c_ulonglong; 32], ++ pub __fcsr: ::c_uint, ++ } ++ ++ #[allow(missing_debug_implementations)] ++ #[repr(align(16))] ++ pub struct __riscv_mc_q_ext_state { ++ pub __f: [::c_ulonglong; 64], ++ pub __fcsr: ::c_uint, ++ pub __glibc_reserved: [::c_uint; 3], ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs +index c656189..c65a562 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs +@@ -11,6 +11,7 @@ pub type fsblkcnt64_t = ::c_ulong; + pub type fsfilcnt64_t = ::c_ulong; + pub type suseconds_t = i64; + pub type __u64 = ::c_ulonglong; ++pub type __s64 = ::c_longlong; + + s! { + pub struct pthread_attr_t { +@@ -192,10 +193,39 @@ s! { + pub l_pid: ::pid_t, + } + +- pub struct ip_mreqn { +- pub imr_multiaddr: ::in_addr, +- pub imr_address: ::in_addr, +- pub imr_ifindex: ::c_int, ++ pub struct user_regs_struct { ++ pub pc: ::c_ulong, ++ pub ra: ::c_ulong, ++ pub sp: ::c_ulong, ++ pub gp: ::c_ulong, ++ pub tp: ::c_ulong, ++ pub t0: ::c_ulong, ++ pub t1: ::c_ulong, ++ pub t2: ::c_ulong, ++ pub s0: ::c_ulong, ++ pub s1: ::c_ulong, ++ pub a0: ::c_ulong, ++ pub a1: ::c_ulong, ++ pub a2: ::c_ulong, ++ pub a3: ::c_ulong, ++ pub a4: ::c_ulong, ++ pub a5: ::c_ulong, ++ pub a6: ::c_ulong, ++ pub a7: ::c_ulong, ++ pub s2: ::c_ulong, ++ pub s3: ::c_ulong, ++ pub s4: ::c_ulong, ++ pub s5: ::c_ulong, ++ pub s6: ::c_ulong, ++ pub s7: ::c_ulong, ++ pub s8: ::c_ulong, ++ pub s9: ::c_ulong, ++ pub s10: ::c_ulong, ++ pub s11: ::c_ulong, ++ pub t3: ::c_ulong, ++ pub t4: ::c_ulong, ++ pub t5: ::c_ulong, ++ pub t6: ::c_ulong, + } + } + +@@ -205,15 +235,6 @@ pub const VEOF: usize = 4; + pub const RTLD_DEEPBIND: ::c_int = 0x8; + pub const RTLD_GLOBAL: ::c_int = 0x100; + pub const RTLD_NOLOAD: ::c_int = 0x4; +-pub const TIOCGSOFTCAR: ::c_ulong = 21529; +-pub const TIOCSSOFTCAR: ::c_ulong = 21530; +-pub const TIOCGRS485: ::c_int = 21550; +-pub const TIOCSRS485: ::c_int = 21551; +-pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; +-pub const RLIMIT_AS: ::__rlimit_resource_t = 9; +-pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; +-pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 7; +-pub const RLIMIT_NPROC: ::__rlimit_resource_t = 6; + pub const O_APPEND: ::c_int = 1024; + pub const O_CREAT: ::c_int = 64; + pub const O_EXCL: ::c_int = 128; +@@ -226,6 +247,7 @@ pub const O_FSYNC: ::c_int = 1052672; + pub const O_NOATIME: ::c_int = 262144; + pub const O_PATH: ::c_int = 2097152; + pub const O_TMPFILE: ::c_int = 4259840; ++pub const MADV_SOFT_OFFLINE: ::c_int = 101; + pub const MAP_GROWSDOWN: ::c_int = 256; + pub const EDEADLK: ::c_int = 35; + pub const ENAMETOOLONG: ::c_int = 36; +@@ -355,23 +377,6 @@ pub const SFD_NONBLOCK: ::c_int = 2048; + pub const TCSANOW: ::c_int = 0; + pub const TCSADRAIN: ::c_int = 1; + pub const TCSAFLUSH: ::c_int = 2; +-pub const TIOCLINUX: ::c_ulong = 21532; +-pub const TIOCGSERIAL: ::c_ulong = 21534; +-pub const TIOCEXCL: ::c_ulong = 21516; +-pub const TIOCNXCL: ::c_ulong = 21517; +-pub const TIOCSCTTY: ::c_ulong = 21518; +-pub const TIOCSTI: ::c_ulong = 21522; +-pub const TIOCMGET: ::c_ulong = 21525; +-pub const TIOCMBIS: ::c_ulong = 21526; +-pub const TIOCMBIC: ::c_ulong = 21527; +-pub const TIOCMSET: ::c_ulong = 21528; +-pub const TIOCCONS: ::c_ulong = 21533; +-pub const TIOCM_ST: ::c_int = 8; +-pub const TIOCM_SR: ::c_int = 16; +-pub const TIOCM_CTS: ::c_int = 32; +-pub const TIOCM_CAR: ::c_int = 64; +-pub const TIOCM_RNG: ::c_int = 128; +-pub const TIOCM_DSR: ::c_int = 256; + pub const SFD_CLOEXEC: ::c_int = 524288; + pub const NCCS: usize = 32; + pub const O_TRUNC: ::c_int = 512; +@@ -398,6 +403,7 @@ pub const EPOLL_CLOEXEC: ::c_int = 524288; + pub const EFD_CLOEXEC: ::c_int = 524288; + pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; ++pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + pub const O_DIRECT: ::c_int = 16384; + pub const O_DIRECTORY: ::c_int = 65536; + pub const O_NOFOLLOW: ::c_int = 131072; +@@ -418,9 +424,12 @@ pub const ENOTNAM: ::c_int = 118; + pub const ENAVAIL: ::c_int = 119; + pub const EISNAM: ::c_int = 120; + pub const EREMOTEIO: ::c_int = 121; +-pub const FIOCLEX: ::c_ulong = 21585; +-pub const FIONCLEX: ::c_ulong = 21584; +-pub const FIONBIO: ::c_ulong = 21537; ++pub const PTRACE_GETFPREGS: ::c_uint = 14; ++pub const PTRACE_SETFPREGS: ::c_uint = 15; ++pub const PTRACE_GETFPXREGS: ::c_uint = 18; ++pub const PTRACE_SETFPXREGS: ::c_uint = 19; ++pub const PTRACE_GETREGS: ::c_uint = 12; ++pub const PTRACE_SETREGS: ::c_uint = 13; + pub const MCL_CURRENT: ::c_int = 1; + pub const MCL_FUTURE: ::c_int = 2; + pub const SIGSTKSZ: ::size_t = 8192; +@@ -516,26 +525,20 @@ pub const IEXTEN: ::tcflag_t = 32768; + pub const TOSTOP: ::tcflag_t = 256; + pub const FLUSHO: ::tcflag_t = 4096; + pub const EXTPROC: ::tcflag_t = 65536; +-pub const TCGETS: ::c_ulong = 21505; +-pub const TCSETS: ::c_ulong = 21506; +-pub const TCSETSW: ::c_ulong = 21507; +-pub const TCSETSF: ::c_ulong = 21508; +-pub const TCGETA: ::c_ulong = 21509; +-pub const TCSETA: ::c_ulong = 21510; +-pub const TCSETAW: ::c_ulong = 21511; +-pub const TCSETAF: ::c_ulong = 21512; +-pub const TCSBRK: ::c_ulong = 21513; +-pub const TCXONC: ::c_ulong = 21514; +-pub const TCFLSH: ::c_ulong = 21515; +-pub const TIOCINQ: ::c_ulong = 21531; +-pub const TIOCGPGRP: ::c_ulong = 21519; +-pub const TIOCSPGRP: ::c_ulong = 21520; +-pub const TIOCOUTQ: ::c_ulong = 21521; +-pub const TIOCGWINSZ: ::c_ulong = 21523; +-pub const TIOCSWINSZ: ::c_ulong = 21524; +-pub const FIONREAD: ::c_ulong = 21531; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; ++pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; ++pub const NGREG: usize = 32; ++pub const REG_PC: usize = 0; ++pub const REG_RA: usize = 1; ++pub const REG_SP: usize = 2; ++pub const REG_TP: usize = 4; ++pub const REG_S0: usize = 8; ++pub const REG_S1: usize = 9; ++pub const REG_A0: usize = 10; ++pub const REG_S2: usize = 18; ++pub const REG_NARGS: usize = 8; ++ + pub const SYS_read: ::c_long = 63; + pub const SYS_write: ::c_long = 64; + pub const SYS_close: ::c_long = 57; +@@ -811,6 +814,7 @@ pub const SYS_pkey_mprotect: ::c_long = 288; + pub const SYS_pkey_alloc: ::c_long = 289; + pub const SYS_pkey_free: ::c_long = 290; + pub const SYS_statx: ::c_long = 291; ++pub const SYS_rseq: ::c_long = 293; + pub const SYS_pidfd_send_signal: ::c_long = 424; + pub const SYS_io_uring_setup: ::c_long = 425; + pub const SYS_io_uring_enter: ::c_long = 426; +@@ -830,3 +834,18 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; ++ ++cfg_if! { ++ if #[cfg(libc_align)] { ++ mod align; ++ pub use self::align::*; ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/s390x.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/s390x.rs +index 7685a34..c2c4f31 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/s390x.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/s390x.rs +@@ -11,6 +11,7 @@ pub type suseconds_t = i64; + pub type wchar_t = i32; + pub type greg_t = u64; + pub type __u64 = u64; ++pub type __s64 = i64; + + s! { + pub struct sigaction { +@@ -153,17 +154,6 @@ s! { + __f_spare: [::c_int; 6], + } + +- pub struct termios2 { +- pub c_iflag: ::tcflag_t, +- pub c_oflag: ::tcflag_t, +- pub c_cflag: ::tcflag_t, +- pub c_lflag: ::tcflag_t, +- pub c_line: ::cc_t, +- pub c_cc: [::cc_t; 19], +- pub c_ispeed: ::speed_t, +- pub c_ospeed: ::speed_t, +- } +- + pub struct __psw_t { + pub mask: u64, + pub addr: u64, +@@ -299,8 +289,10 @@ pub const EFD_CLOEXEC: ::c_int = 0x80000; + + pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; ++pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; ++pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + + align_const! { + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = +@@ -340,9 +332,6 @@ pub const EDEADLK: ::c_int = 35; + pub const ENOSYS: ::c_int = 38; + pub const ENOTCONN: ::c_int = 107; + pub const ETIMEDOUT: ::c_int = 110; +-pub const FIOCLEX: ::c_ulong = 0x5451; +-pub const FIONCLEX: ::c_ulong = 0x5450; +-pub const FIONBIO: ::c_ulong = 0x5421; + pub const O_APPEND: ::c_int = 1024; + pub const O_CREAT: ::c_int = 64; + pub const O_EXCL: ::c_int = 128; +@@ -358,12 +347,6 @@ pub const SIG_SETMASK: ::c_int = 2; + pub const SOCK_STREAM: ::c_int = 1; + pub const SOCK_DGRAM: ::c_int = 2; + +-pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; +-pub const RLIMIT_AS: ::__rlimit_resource_t = 9; +-pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; +-pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 7; +-pub const RLIMIT_NPROC: ::__rlimit_resource_t = 6; +- + pub const O_NOCTTY: ::c_int = 256; + pub const O_SYNC: ::c_int = 1052672; + pub const O_RSYNC: ::c_int = 1052672; +@@ -385,6 +368,7 @@ pub const MAP_POPULATE: ::c_int = 0x08000; + pub const MAP_NONBLOCK: ::c_int = 0x010000; + pub const MAP_STACK: ::c_int = 0x020000; + pub const MAP_HUGETLB: ::c_int = 0x040000; ++pub const MAP_SYNC: ::c_int = 0x080000; + + pub const EDEADLOCK: ::c_int = 35; + pub const ENAMETOOLONG: ::c_int = 36; +@@ -514,51 +498,10 @@ pub const F_OFD_SETLKW: ::c_int = 38; + + pub const SFD_NONBLOCK: ::c_int = 0x0800; + +-pub const TCGETS: ::c_ulong = 0x5401; +-pub const TCSETS: ::c_ulong = 0x5402; +-pub const TCSETSW: ::c_ulong = 0x5403; +-pub const TCSETSF: ::c_ulong = 0x5404; +-pub const TCGETA: ::c_ulong = 0x5405; +-pub const TCSETA: ::c_ulong = 0x5406; +-pub const TCSETAW: ::c_ulong = 0x5407; +-pub const TCSETAF: ::c_ulong = 0x5408; +-pub const TCSBRK: ::c_ulong = 0x5409; +-pub const TCXONC: ::c_ulong = 0x540A; +-pub const TCFLSH: ::c_ulong = 0x540B; +-pub const TIOCGSOFTCAR: ::c_ulong = 0x5419; +-pub const TIOCSSOFTCAR: ::c_ulong = 0x541A; +-pub const TIOCINQ: ::c_ulong = 0x541B; +-pub const TIOCEXCL: ::c_ulong = 0x540C; +-pub const TIOCNXCL: ::c_ulong = 0x540D; +-pub const TIOCSCTTY: ::c_ulong = 0x540E; +-pub const TIOCGPGRP: ::c_ulong = 0x540F; +-pub const TIOCSPGRP: ::c_ulong = 0x5410; +-pub const TIOCOUTQ: ::c_ulong = 0x5411; +-pub const TIOCSTI: ::c_ulong = 0x5412; +-pub const TIOCGWINSZ: ::c_ulong = 0x5413; +-pub const TIOCSWINSZ: ::c_ulong = 0x5414; +-pub const TIOCMGET: ::c_ulong = 0x5415; +-pub const TIOCMBIS: ::c_ulong = 0x5416; +-pub const TIOCMBIC: ::c_ulong = 0x5417; +-pub const TIOCMSET: ::c_ulong = 0x5418; +-pub const FIONREAD: ::c_ulong = 0x541B; +-pub const TIOCCONS: ::c_ulong = 0x541D; +-pub const TIOCSBRK: ::c_ulong = 0x5427; +-pub const TIOCCBRK: ::c_ulong = 0x5428; +- + pub const TCSANOW: ::c_int = 0; + pub const TCSADRAIN: ::c_int = 1; + pub const TCSAFLUSH: ::c_int = 2; + +-pub const TIOCLINUX: ::c_ulong = 0x541C; +-pub const TIOCGSERIAL: ::c_ulong = 0x541E; +-pub const TIOCM_ST: ::c_int = 0x008; +-pub const TIOCM_SR: ::c_int = 0x010; +-pub const TIOCM_CTS: ::c_int = 0x020; +-pub const TIOCM_CAR: ::c_int = 0x040; +-pub const TIOCM_RNG: ::c_int = 0x080; +-pub const TIOCM_DSR: ::c_int = 0x100; +- + pub const VTIME: usize = 5; + pub const VSWTC: usize = 7; + pub const VSTART: usize = 8; +@@ -616,7 +559,6 @@ pub const PARODD: ::tcflag_t = 0o001000; + pub const HUPCL: ::tcflag_t = 0o002000; + pub const CLOCAL: ::tcflag_t = 0o004000; + pub const CBAUDEX: ::tcflag_t = 0o010000; +-pub const BOTHER: ::speed_t = 0o010000; + pub const B57600: ::speed_t = 0o010001; + pub const B115200: ::speed_t = 0o010002; + pub const B230400: ::speed_t = 0o010003; +@@ -975,6 +917,7 @@ pub const SYS_setfsuid: ::c_long = 215; + pub const SYS_setfsgid: ::c_long = 216; + pub const SYS_newfstatat: ::c_long = 293; + pub const SYS_statx: ::c_long = 379; ++pub const SYS_rseq: ::c_long = 383; + pub const SYS_pidfd_send_signal: ::c_long = 424; + pub const SYS_io_uring_setup: ::c_long = 425; + pub const SYS_io_uring_enter: ::c_long = 426; +@@ -994,6 +937,14 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; + + extern "C" { + +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs +index 5ed83ab..2427c7a 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs +@@ -10,6 +10,7 @@ pub type nlink_t = u32; + pub type blksize_t = i64; + pub type suseconds_t = i32; + pub type __u64 = ::c_ulonglong; ++pub type __s64 = ::c_longlong; + + s! { + pub struct sigaction { +@@ -193,17 +194,6 @@ s! { + __reserved1: ::c_ulong, + __reserved2: ::c_ulong + } +- +- pub struct termios2 { +- pub c_iflag: ::tcflag_t, +- pub c_oflag: ::tcflag_t, +- pub c_cflag: ::tcflag_t, +- pub c_lflag: ::tcflag_t, +- pub c_line: ::cc_t, +- pub c_cc: [::cc_t; 19], +- pub c_ispeed: ::speed_t, +- pub c_ospeed: ::speed_t, +- } + } + + pub const POSIX_FADV_DONTNEED: ::c_int = 4; +@@ -214,15 +204,7 @@ pub const RTLD_DEEPBIND: ::c_int = 0x8; + pub const RTLD_GLOBAL: ::c_int = 0x100; + pub const RTLD_NOLOAD: ::c_int = 0x4; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +- +-pub const TIOCGSOFTCAR: ::c_ulong = 0x40047464; +-pub const TIOCSSOFTCAR: ::c_ulong = 0x80047465; +- +-pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; +-pub const RLIMIT_AS: ::__rlimit_resource_t = 9; +-pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; +-pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 6; +-pub const RLIMIT_NPROC: ::__rlimit_resource_t = 7; ++pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + + pub const O_APPEND: ::c_int = 0x8; + pub const O_CREAT: ::c_int = 0x200; +@@ -364,7 +346,7 @@ pub const POLLWRBAND: ::c_short = 0x100; + pub const O_ASYNC: ::c_int = 0x40; + pub const O_NDELAY: ::c_int = 0x4004; + +-pub const PTRACE_DETACH: ::c_uint = 11; ++pub const PTRACE_DETACH: ::c_uint = 17; + + pub const EFD_NONBLOCK: ::c_int = 0x4000; + +@@ -387,27 +369,6 @@ pub const TCSANOW: ::c_int = 0; + pub const TCSADRAIN: ::c_int = 1; + pub const TCSAFLUSH: ::c_int = 2; + +-pub const TIOCLINUX: ::c_ulong = 0x541C; +-pub const TIOCGSERIAL: ::c_ulong = 0x541E; +-pub const TIOCEXCL: ::c_ulong = 0x2000740d; +-pub const TIOCNXCL: ::c_ulong = 0x2000740e; +-pub const TIOCCONS: ::c_ulong = 0x20007424; +-pub const TIOCMGET: ::c_ulong = 0x4004746a; +-pub const TIOCMBIC: ::c_ulong = 0x8004746b; +-pub const TIOCMBIS: ::c_ulong = 0x8004746c; +-pub const TIOCMSET: ::c_ulong = 0x8004746d; +-pub const TIOCSTI: ::c_ulong = 0x80017472; +-pub const TIOCCBRK: ::c_ulong = 0x2000747a; +-pub const TIOCSBRK: ::c_ulong = 0x2000747b; +-pub const TIOCSCTTY: ::c_ulong = 0x20007484; +- +-pub const TIOCM_ST: ::c_int = 0x008; +-pub const TIOCM_SR: ::c_int = 0x010; +-pub const TIOCM_CTS: ::c_int = 0x020; +-pub const TIOCM_CAR: ::c_int = 0x040; +-pub const TIOCM_RNG: ::c_int = 0x080; +-pub const TIOCM_DSR: ::c_int = 0x100; +- + pub const SFD_CLOEXEC: ::c_int = 0x400000; + + pub const NCCS: usize = 17; +@@ -441,6 +402,7 @@ pub const EFD_CLOEXEC: ::c_int = 0x400000; + pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; ++pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + + align_const! { + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = +@@ -480,10 +442,6 @@ pub const ENAVAIL: ::c_int = 119; + pub const EISNAM: ::c_int = 120; + pub const EREMOTEIO: ::c_int = 121; + +-pub const FIOCLEX: ::c_ulong = 0x20006601; +-pub const FIONCLEX: ::c_ulong = 0x20006602; +-pub const FIONBIO: ::c_ulong = 0x8004667e; +- + pub const MCL_CURRENT: ::c_int = 0x2000; + pub const MCL_FUTURE: ::c_int = 0x4000; + +@@ -559,7 +517,6 @@ pub const B19200: ::speed_t = 0o000016; + pub const B38400: ::speed_t = 0o000017; + pub const EXTA: ::speed_t = B19200; + pub const EXTB: ::speed_t = B38400; +-pub const BOTHER: ::speed_t = 0x1000; + pub const B57600: ::speed_t = 0x1001; + pub const B115200: ::speed_t = 0x1002; + pub const B230400: ::speed_t = 0x1003; +@@ -583,24 +540,6 @@ pub const IEXTEN: ::tcflag_t = 0x8000; + pub const TOSTOP: ::tcflag_t = 0x100; + pub const FLUSHO: ::tcflag_t = 0x1000; + pub const EXTPROC: ::tcflag_t = 0x10000; +-pub const TCGETS: ::c_ulong = 0x40245408; +-pub const TCSETS: ::c_ulong = 0x80245409; +-pub const TCSETSW: ::c_ulong = 0x8024540a; +-pub const TCSETSF: ::c_ulong = 0x8024540b; +-pub const TCGETA: ::c_ulong = 0x40125401; +-pub const TCSETA: ::c_ulong = 0x80125402; +-pub const TCSETAW: ::c_ulong = 0x80125403; +-pub const TCSETAF: ::c_ulong = 0x80125404; +-pub const TCSBRK: ::c_ulong = 0x20005405; +-pub const TCXONC: ::c_ulong = 0x20005406; +-pub const TCFLSH: ::c_ulong = 0x20005407; +-pub const TIOCINQ: ::c_ulong = 0x4004667f; +-pub const TIOCGPGRP: ::c_ulong = 0x40047483; +-pub const TIOCSPGRP: ::c_ulong = 0x80047482; +-pub const TIOCOUTQ: ::c_ulong = 0x40047473; +-pub const TIOCGWINSZ: ::c_ulong = 0x40087468; +-pub const TIOCSWINSZ: ::c_ulong = 0x80087467; +-pub const FIONREAD: ::c_ulong = 0x4004667f; + + pub const SYS_restart_syscall: ::c_long = 0; + pub const SYS_exit: ::c_long = 1; +@@ -942,6 +881,7 @@ pub const SYS_copy_file_range: ::c_long = 357; + pub const SYS_preadv2: ::c_long = 358; + pub const SYS_pwritev2: ::c_long = 359; + pub const SYS_statx: ::c_long = 360; ++pub const SYS_rseq: ::c_long = 365; + pub const SYS_pidfd_send_signal: ::c_long = 424; + pub const SYS_io_uring_setup: ::c_long = 425; + pub const SYS_io_uring_enter: ::c_long = 426; +@@ -962,6 +902,14 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; + + extern "C" { + pub fn sysctl( +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/align.rs +index 7ca870f..ba3075e 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/align.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/align.rs +@@ -5,3 +5,20 @@ s_no_extra_traits! { + priv_: [f64; 4] + } + } ++ ++s! { ++ #[repr(align(8))] ++ pub struct clone_args { ++ pub flags: ::c_ulonglong, ++ pub pidfd: ::c_ulonglong, ++ pub child_tid: ::c_ulonglong, ++ pub parent_tid: ::c_ulonglong, ++ pub exit_signal: ::c_ulonglong, ++ pub stack: ::c_ulonglong, ++ pub stack_size: ::c_ulonglong, ++ pub tls: ::c_ulonglong, ++ pub set_tid: ::c_ulonglong, ++ pub set_tid_size: ::c_ulonglong, ++ pub cgroup: ::c_ulonglong, ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs +index 99937df..e6307e2 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs +@@ -7,6 +7,7 @@ pub type blksize_t = i64; + pub type greg_t = i64; + pub type suseconds_t = i64; + pub type __u64 = ::c_ulonglong; ++pub type __s64 = ::c_longlong; + + s! { + pub struct sigaction { +@@ -259,21 +260,18 @@ s! { + __unused5: u64 + } + +- pub struct termios2 { +- pub c_iflag: ::tcflag_t, +- pub c_oflag: ::tcflag_t, +- pub c_cflag: ::tcflag_t, +- pub c_lflag: ::tcflag_t, +- pub c_line: ::cc_t, +- pub c_cc: [::cc_t; 19], +- pub c_ispeed: ::speed_t, +- pub c_ospeed: ::speed_t, ++ pub struct seccomp_notif_sizes { ++ pub seccomp_notif: ::__u16, ++ pub seccomp_notif_resp: ::__u16, ++ pub seccomp_data: ::__u16, + } + +- pub struct ip_mreqn { +- pub imr_multiaddr: ::in_addr, +- pub imr_address: ::in_addr, +- pub imr_ifindex: ::c_int, ++ pub struct ptrace_rseq_configuration { ++ pub rseq_abi_pointer: ::__u64, ++ pub rseq_abi_size: ::__u32, ++ pub signature: ::__u32, ++ pub flags: ::__u32, ++ pub pad: ::__u32, + } + } + +@@ -409,16 +407,6 @@ pub const VEOF: usize = 4; + pub const RTLD_DEEPBIND: ::c_int = 0x8; + pub const RTLD_GLOBAL: ::c_int = 0x100; + pub const RTLD_NOLOAD: ::c_int = 0x4; +-pub const TIOCGSOFTCAR: ::c_ulong = 0x5419; +-pub const TIOCSSOFTCAR: ::c_ulong = 0x541A; +-pub const TIOCGRS485: ::c_int = 0x542E; +-pub const TIOCSRS485: ::c_int = 0x542F; +- +-pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; +-pub const RLIMIT_AS: ::__rlimit_resource_t = 9; +-pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; +-pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 7; +-pub const RLIMIT_NPROC: ::__rlimit_resource_t = 6; + + pub const O_APPEND: ::c_int = 1024; + pub const O_CREAT: ::c_int = 64; +@@ -555,6 +543,7 @@ pub const O_ASYNC: ::c_int = 0x2000; + pub const O_NDELAY: ::c_int = 0x800; + + pub const PTRACE_DETACH: ::c_uint = 17; ++pub const PTRACE_GET_RSEQ_CONFIGURATION: ::c_uint = 0x420f; + + pub const EFD_NONBLOCK: ::c_int = 0x800; + +@@ -577,25 +566,6 @@ pub const TCSANOW: ::c_int = 0; + pub const TCSADRAIN: ::c_int = 1; + pub const TCSAFLUSH: ::c_int = 2; + +-pub const TIOCLINUX: ::c_ulong = 0x541C; +-pub const TIOCGSERIAL: ::c_ulong = 0x541E; +-pub const TIOCEXCL: ::c_ulong = 0x540C; +-pub const TIOCNXCL: ::c_ulong = 0x540D; +-pub const TIOCSCTTY: ::c_ulong = 0x540E; +-pub const TIOCSTI: ::c_ulong = 0x5412; +-pub const TIOCMGET: ::c_ulong = 0x5415; +-pub const TIOCMBIS: ::c_ulong = 0x5416; +-pub const TIOCMBIC: ::c_ulong = 0x5417; +-pub const TIOCMSET: ::c_ulong = 0x5418; +-pub const TIOCCONS: ::c_ulong = 0x541D; +- +-pub const TIOCM_ST: ::c_int = 0x008; +-pub const TIOCM_SR: ::c_int = 0x010; +-pub const TIOCM_CTS: ::c_int = 0x020; +-pub const TIOCM_CAR: ::c_int = 0x040; +-pub const TIOCM_RNG: ::c_int = 0x080; +-pub const TIOCM_DSR: ::c_int = 0x100; +- + pub const SFD_CLOEXEC: ::c_int = 0x080000; + + pub const NCCS: usize = 32; +@@ -630,6 +600,7 @@ pub const EFD_CLOEXEC: ::c_int = 0x80000; + + pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; ++pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + + pub const O_DIRECT: ::c_int = 0x4000; + pub const O_DIRECTORY: ::c_int = 0x10000; +@@ -655,10 +626,6 @@ pub const ENAVAIL: ::c_int = 119; + pub const EISNAM: ::c_int = 120; + pub const EREMOTEIO: ::c_int = 121; + +-pub const FIOCLEX: ::c_ulong = 0x5451; +-pub const FIONCLEX: ::c_ulong = 0x5450; +-pub const FIONBIO: ::c_ulong = 0x5421; +- + pub const PTRACE_GETFPREGS: ::c_uint = 14; + pub const PTRACE_SETFPREGS: ::c_uint = 15; + pub const PTRACE_GETFPXREGS: ::c_uint = 18; +@@ -669,6 +636,19 @@ pub const PTRACE_PEEKSIGINFO_SHARED: ::c_uint = 1; + pub const PTRACE_SYSEMU: ::c_uint = 31; + pub const PTRACE_SYSEMU_SINGLESTEP: ::c_uint = 32; + ++pub const PR_GET_SPECULATION_CTRL: ::c_int = 52; ++pub const PR_SET_SPECULATION_CTRL: ::c_int = 53; ++pub const PR_SPEC_NOT_AFFECTED: ::c_uint = 0; ++pub const PR_SPEC_PRCTL: ::c_uint = 1 << 0; ++pub const PR_SPEC_ENABLE: ::c_uint = 1 << 1; ++pub const PR_SPEC_DISABLE: ::c_uint = 1 << 2; ++pub const PR_SPEC_FORCE_DISABLE: ::c_uint = 1 << 3; ++pub const PR_SPEC_DISABLE_NOEXEC: ::c_uint = 1 << 4; ++pub const PR_SPEC_STORE_BYPASS: ::c_int = 0; ++pub const PR_SPEC_INDIRECT_BRANCH: ::c_int = 1; ++// FIXME: perharps for later ++//pub const PR_SPEC_L1D_FLUSH: ::c_int = 2; ++ + pub const MCL_CURRENT: ::c_int = 0x0001; + pub const MCL_FUTURE: ::c_int = 0x0002; + +@@ -744,7 +724,6 @@ pub const B19200: ::speed_t = 0o000016; + pub const B38400: ::speed_t = 0o000017; + pub const EXTA: ::speed_t = B19200; + pub const EXTB: ::speed_t = B38400; +-pub const BOTHER: ::speed_t = 0o010000; + pub const B57600: ::speed_t = 0o010001; + pub const B115200: ::speed_t = 0o010002; + pub const B230400: ::speed_t = 0o010003; +@@ -768,26 +747,6 @@ pub const IEXTEN: ::tcflag_t = 0x00008000; + pub const TOSTOP: ::tcflag_t = 0x00000100; + pub const FLUSHO: ::tcflag_t = 0x00001000; + pub const EXTPROC: ::tcflag_t = 0x00010000; +-pub const TCGETS: ::c_ulong = 0x5401; +-pub const TCSETS: ::c_ulong = 0x5402; +-pub const TCSETSW: ::c_ulong = 0x5403; +-pub const TCSETSF: ::c_ulong = 0x5404; +-pub const TCGETA: ::c_ulong = 0x5405; +-pub const TCSETA: ::c_ulong = 0x5406; +-pub const TCSETAW: ::c_ulong = 0x5407; +-pub const TCSETAF: ::c_ulong = 0x5408; +-pub const TCSBRK: ::c_ulong = 0x5409; +-pub const TCXONC: ::c_ulong = 0x540A; +-pub const TCFLSH: ::c_ulong = 0x540B; +-pub const TIOCINQ: ::c_ulong = 0x541B; +-pub const TIOCGPGRP: ::c_ulong = 0x540F; +-pub const TIOCSPGRP: ::c_ulong = 0x5410; +-pub const TIOCOUTQ: ::c_ulong = 0x5411; +-pub const TIOCGWINSZ: ::c_ulong = 0x5413; +-pub const TIOCSWINSZ: ::c_ulong = 0x5414; +-pub const FIONREAD: ::c_ulong = 0x541B; +-pub const TIOCSBRK: ::c_ulong = 0x5427; +-pub const TIOCCBRK: ::c_ulong = 0x5428; + + // offsets in user_regs_structs, from sys/reg.h + pub const R15: ::c_int = 0; +@@ -843,6 +802,11 @@ pub const REG_TRAPNO: ::c_int = 20; + pub const REG_OLDMASK: ::c_int = 21; + pub const REG_CR2: ::c_int = 22; + ++pub const SECCOMP_SET_MODE_STRICT: ::c_uint = 0; ++pub const SECCOMP_SET_MODE_FILTER: ::c_uint = 1; ++pub const SECCOMP_GET_ACTION_AVAIL: ::c_uint = 2; ++pub const SECCOMP_GET_NOTIF_SIZES: ::c_uint = 3; ++ + extern "C" { + pub fn getcontext(ucp: *mut ucontext_t) -> ::c_int; + pub fn setcontext(ucp: *const ucontext_t) -> ::c_int; +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs +index e126984..3831dfa 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs +@@ -22,6 +22,7 @@ s! { + + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; ++pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + + align_const! { + #[cfg(target_endian = "little")] +@@ -409,6 +410,7 @@ pub const SYS_pkey_mprotect: ::c_long = 329; + pub const SYS_pkey_alloc: ::c_long = 330; + pub const SYS_pkey_free: ::c_long = 331; + pub const SYS_statx: ::c_long = 332; ++pub const SYS_rseq: ::c_long = 334; + pub const SYS_pidfd_send_signal: ::c_long = 424; + pub const SYS_io_uring_setup: ::c_long = 425; + pub const SYS_io_uring_enter: ::c_long = 426; +@@ -428,6 +430,14 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; + + extern "C" { + pub fn sysctl( +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs +index dcbc347..06aa0da 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs +@@ -22,6 +22,7 @@ s! { + + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 32; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 44; ++pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 20; + + align_const! { + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = +@@ -337,6 +338,7 @@ pub const SYS_pkey_mprotect: ::c_long = __X32_SYSCALL_BIT + 329; + pub const SYS_pkey_alloc: ::c_long = __X32_SYSCALL_BIT + 330; + pub const SYS_pkey_free: ::c_long = __X32_SYSCALL_BIT + 331; + pub const SYS_statx: ::c_long = __X32_SYSCALL_BIT + 332; ++pub const SYS_rseq: ::c_long = __X32_SYSCALL_BIT + 334; + pub const SYS_pidfd_send_signal: ::c_long = __X32_SYSCALL_BIT + 424; + pub const SYS_io_uring_setup: ::c_long = __X32_SYSCALL_BIT + 425; + pub const SYS_io_uring_enter: ::c_long = __X32_SYSCALL_BIT + 426; +@@ -356,6 +358,14 @@ pub const SYS_faccessat2: ::c_long = __X32_SYSCALL_BIT + 439; + pub const SYS_process_madvise: ::c_long = __X32_SYSCALL_BIT + 440; + pub const SYS_epoll_pwait2: ::c_long = __X32_SYSCALL_BIT + 441; + pub const SYS_mount_setattr: ::c_long = __X32_SYSCALL_BIT + 442; ++pub const SYS_quotactl_fd: ::c_long = __X32_SYSCALL_BIT + 443; ++pub const SYS_landlock_create_ruleset: ::c_long = __X32_SYSCALL_BIT + 444; ++pub const SYS_landlock_add_rule: ::c_long = __X32_SYSCALL_BIT + 445; ++pub const SYS_landlock_restrict_self: ::c_long = __X32_SYSCALL_BIT + 446; ++pub const SYS_memfd_secret: ::c_long = __X32_SYSCALL_BIT + 447; ++pub const SYS_process_mrelease: ::c_long = __X32_SYSCALL_BIT + 448; ++pub const SYS_futex_waitv: ::c_long = __X32_SYSCALL_BIT + 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = __X32_SYSCALL_BIT + 450; + pub const SYS_rt_sigaction: ::c_long = __X32_SYSCALL_BIT + 512; + pub const SYS_rt_sigreturn: ::c_long = __X32_SYSCALL_BIT + 513; + pub const SYS_ioctl: ::c_long = __X32_SYSCALL_BIT + 514; +diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs +index ad0f882..1aad836 100644 +--- a/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs +@@ -4,6 +4,16 @@ pub type __rlimit_resource_t = ::c_uint; + pub type Lmid_t = ::c_long; + pub type regoff_t = ::c_int; + ++cfg_if! { ++ if #[cfg(doc)] { ++ // Used in `linux::arch` to define ioctl constants. ++ pub(crate) type Ioctl = ::c_ulong; ++ } else { ++ #[doc(hidden)] ++ pub type Ioctl = ::c_ulong; ++ } ++} ++ + s! { + pub struct statx { + pub stx_mask: u32, +@@ -27,7 +37,8 @@ s! { + pub stx_dev_major: u32, + pub stx_dev_minor: u32, + pub stx_mnt_id: u64, +- __statx_pad2: u64, ++ pub stx_dio_mem_align: u32, ++ pub stx_dio_offset_align: u32, + __statx_pad3: [u64; 12], + } + +@@ -141,19 +152,6 @@ s! { + pub keepcost: ::size_t, + } + +- pub struct nlmsghdr { +- pub nlmsg_len: u32, +- pub nlmsg_type: u16, +- pub nlmsg_flags: u16, +- pub nlmsg_seq: u32, +- pub nlmsg_pid: u32, +- } +- +- pub struct nlmsgerr { +- pub error: ::c_int, +- pub msg: nlmsghdr, +- } +- + pub struct nl_pktinfo { + pub group: u32, + } +@@ -174,11 +172,6 @@ s! { + pub nm_gid: u32, + } + +- pub struct nlattr { +- pub nla_len: u16, +- pub nla_type: u16, +- } +- + pub struct rtentry { + pub rt_pad1: ::c_ulong, + pub rt_dst: ::sockaddr, +@@ -313,6 +306,51 @@ s! { + pub ch_size: ::Elf32_Word, + pub ch_addralign: ::Elf32_Word, + } ++ ++ pub struct seminfo { ++ pub semmap: ::c_int, ++ pub semmni: ::c_int, ++ pub semmns: ::c_int, ++ pub semmnu: ::c_int, ++ pub semmsl: ::c_int, ++ pub semopm: ::c_int, ++ pub semume: ::c_int, ++ pub semusz: ::c_int, ++ pub semvmx: ::c_int, ++ pub semaem: ::c_int, ++ } ++ ++ pub struct ptrace_peeksiginfo_args { ++ pub off: ::__u64, ++ pub flags: ::__u32, ++ pub nr: ::__s32, ++ } ++ ++ pub struct __c_anonymous_ptrace_syscall_info_entry { ++ pub nr: ::__u64, ++ pub args: [::__u64; 6], ++ } ++ ++ pub struct __c_anonymous_ptrace_syscall_info_exit { ++ pub sval: ::__s64, ++ pub is_error: ::__u8, ++ } ++ ++ pub struct __c_anonymous_ptrace_syscall_info_seccomp { ++ pub nr: ::__u64, ++ pub args: [::__u64; 6], ++ pub ret_data: ::__u32, ++ } ++ ++ pub struct ptrace_syscall_info { ++ pub op: ::__u8, ++ pub pad: [::__u8; 3], ++ pub arch: ::__u32, ++ pub instruction_pointer: ::__u64, ++ pub stack_pointer: ::__u64, ++ #[cfg(libc_union)] ++ pub u: __c_anonymous_ptrace_syscall_info_data, ++ } + } + + impl siginfo_t { +@@ -400,6 +438,18 @@ cfg_if! { + self.sifields().sigchld.si_stime + } + } ++ ++ pub union __c_anonymous_ptrace_syscall_info_data { ++ pub entry: __c_anonymous_ptrace_syscall_info_entry, ++ pub exit: __c_anonymous_ptrace_syscall_info_exit, ++ pub seccomp: __c_anonymous_ptrace_syscall_info_seccomp, ++ } ++ impl ::Copy for __c_anonymous_ptrace_syscall_info_data {} ++ impl ::Clone for __c_anonymous_ptrace_syscall_info_data { ++ fn clone(&self) -> __c_anonymous_ptrace_syscall_info_data { ++ *self ++ } ++ } + } + } + +@@ -416,22 +466,26 @@ s_no_extra_traits! { + + #[cfg(any(target_arch = "aarch64", + target_arch = "s390x", ++ target_arch = "loongarch64", + all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + pub ut_session: ::c_long, + #[cfg(any(target_arch = "aarch64", + target_arch = "s390x", ++ target_arch = "loongarch64", + all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + pub ut_tv: ::timeval, + + #[cfg(not(any(target_arch = "aarch64", + target_arch = "s390x", ++ target_arch = "loongarch64", + all(target_pointer_width = "32", + not(target_arch = "x86_64")))))] + pub ut_session: i32, + #[cfg(not(any(target_arch = "aarch64", + target_arch = "s390x", ++ target_arch = "loongarch64", + all(target_pointer_width = "32", + not(target_arch = "x86_64")))))] + pub ut_tv: __timeval, +@@ -498,6 +552,44 @@ cfg_if! { + self.__glibc_reserved.hash(state); + } + } ++ ++ #[cfg(libc_union)] ++ impl PartialEq for __c_anonymous_ptrace_syscall_info_data { ++ fn eq(&self, other: &__c_anonymous_ptrace_syscall_info_data) -> bool { ++ unsafe { ++ self.entry == other.entry || ++ self.exit == other.exit || ++ self.seccomp == other.seccomp ++ } ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl Eq for __c_anonymous_ptrace_syscall_info_data {} ++ ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for __c_anonymous_ptrace_syscall_info_data { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ unsafe { ++ f.debug_struct("__c_anonymous_ptrace_syscall_info_data") ++ .field("entry", &self.entry) ++ .field("exit", &self.exit) ++ .field("seccomp", &self.seccomp) ++ .finish() ++ } ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl ::hash::Hash for __c_anonymous_ptrace_syscall_info_data { ++ fn hash(&self, state: &mut H) { ++ unsafe { ++ self.entry.hash(state); ++ self.exit.hash(state); ++ self.seccomp.hash(state); ++ } ++ } ++ } + } + } + +@@ -542,20 +634,6 @@ pub const MAP_HUGE_1GB: ::c_int = HUGETLB_FLAG_ENCODE_1GB; + pub const MAP_HUGE_2GB: ::c_int = HUGETLB_FLAG_ENCODE_2GB; + pub const MAP_HUGE_16GB: ::c_int = HUGETLB_FLAG_ENCODE_16GB; + +-pub const RLIMIT_CPU: ::__rlimit_resource_t = 0; +-pub const RLIMIT_FSIZE: ::__rlimit_resource_t = 1; +-pub const RLIMIT_DATA: ::__rlimit_resource_t = 2; +-pub const RLIMIT_STACK: ::__rlimit_resource_t = 3; +-pub const RLIMIT_CORE: ::__rlimit_resource_t = 4; +-pub const RLIMIT_LOCKS: ::__rlimit_resource_t = 10; +-pub const RLIMIT_SIGPENDING: ::__rlimit_resource_t = 11; +-pub const RLIMIT_MSGQUEUE: ::__rlimit_resource_t = 12; +-pub const RLIMIT_NICE: ::__rlimit_resource_t = 13; +-pub const RLIMIT_RTPRIO: ::__rlimit_resource_t = 14; +-pub const RLIMIT_RTTIME: ::__rlimit_resource_t = 15; +-pub const RLIMIT_NLIMITS: ::__rlimit_resource_t = 16; +-pub const RLIM_NLIMITS: ::__rlimit_resource_t = RLIMIT_NLIMITS; +- + pub const PRIO_PROCESS: ::__priority_which_t = 0; + pub const PRIO_PGRP: ::__priority_which_t = 1; + pub const PRIO_USER: ::__priority_which_t = 2; +@@ -592,6 +670,7 @@ pub const RTLD_DI_TLS_MODID: ::c_int = 9; + pub const RTLD_DI_TLS_DATA: ::c_int = 10; + + pub const SOCK_NONBLOCK: ::c_int = O_NONBLOCK; ++pub const PIDFD_NONBLOCK: ::c_uint = O_NONBLOCK as ::c_uint; + + pub const SOL_RXRPC: ::c_int = 272; + pub const SOL_PPPOL2TP: ::c_int = 273; +@@ -651,27 +730,6 @@ pub const PF_NFC: ::c_int = AF_NFC; + pub const PF_VSOCK: ::c_int = AF_VSOCK; + pub const PF_XDP: ::c_int = AF_XDP; + +-/* DCCP socket options */ +-pub const DCCP_SOCKOPT_PACKET_SIZE: ::c_int = 1; +-pub const DCCP_SOCKOPT_SERVICE: ::c_int = 2; +-pub const DCCP_SOCKOPT_CHANGE_L: ::c_int = 3; +-pub const DCCP_SOCKOPT_CHANGE_R: ::c_int = 4; +-pub const DCCP_SOCKOPT_GET_CUR_MPS: ::c_int = 5; +-pub const DCCP_SOCKOPT_SERVER_TIMEWAIT: ::c_int = 6; +-pub const DCCP_SOCKOPT_SEND_CSCOV: ::c_int = 10; +-pub const DCCP_SOCKOPT_RECV_CSCOV: ::c_int = 11; +-pub const DCCP_SOCKOPT_AVAILABLE_CCIDS: ::c_int = 12; +-pub const DCCP_SOCKOPT_CCID: ::c_int = 13; +-pub const DCCP_SOCKOPT_TX_CCID: ::c_int = 14; +-pub const DCCP_SOCKOPT_RX_CCID: ::c_int = 15; +-pub const DCCP_SOCKOPT_QPOLICY_ID: ::c_int = 16; +-pub const DCCP_SOCKOPT_QPOLICY_TXQLEN: ::c_int = 17; +-pub const DCCP_SOCKOPT_CCID_RX_INFO: ::c_int = 128; +-pub const DCCP_SOCKOPT_CCID_TX_INFO: ::c_int = 192; +- +-/// maximum number of services provided on the same listening port +-pub const DCCP_SERVICE_LIST_MAX_LEN: ::c_int = 32; +- + pub const SIGEV_THREAD_ID: ::c_int = 4; + + pub const BUFSIZ: ::c_uint = 8192; +@@ -758,114 +816,15 @@ pub const O_ACCMODE: ::c_int = 3; + pub const ST_RELATIME: ::c_ulong = 4096; + pub const NI_MAXHOST: ::socklen_t = 1025; + ++// Most `*_SUPER_MAGIC` constants are defined at the `linux_like` level; the ++// following are only available on newer Linux versions than the versions ++// currently used in CI in some configurations, so we define them here. + cfg_if! { + if #[cfg(not(target_arch = "s390x"))] { +- pub const ADFS_SUPER_MAGIC: ::c_long = 0x0000adf5; +- pub const AFFS_SUPER_MAGIC: ::c_long = 0x0000adff; +- pub const AFS_SUPER_MAGIC: ::c_long = 0x5346414f; +- pub const AUTOFS_SUPER_MAGIC: ::c_long = 0x0187; + pub const BINDERFS_SUPER_MAGIC: ::c_long = 0x6c6f6f70; +- pub const BPF_FS_MAGIC: ::c_long = 0xcafe4a11; +- pub const BTRFS_SUPER_MAGIC: ::c_long = 0x9123683e; +- pub const CGROUP2_SUPER_MAGIC: ::c_long = 0x63677270; +- pub const CGROUP_SUPER_MAGIC: ::c_long = 0x27e0eb; +- pub const CODA_SUPER_MAGIC: ::c_long = 0x73757245; +- pub const CRAMFS_MAGIC: ::c_long = 0x28cd3d45; +- pub const DEBUGFS_MAGIC: ::c_long = 0x64626720; +- pub const DEVPTS_SUPER_MAGIC: ::c_long = 0x1cd1; +- pub const ECRYPTFS_SUPER_MAGIC: ::c_long = 0xf15f; +- pub const EFS_SUPER_MAGIC: ::c_long = 0x00414a53; +- pub const EXT2_SUPER_MAGIC: ::c_long = 0x0000ef53; +- pub const EXT3_SUPER_MAGIC: ::c_long = 0x0000ef53; +- pub const EXT4_SUPER_MAGIC: ::c_long = 0x0000ef53; +- pub const F2FS_SUPER_MAGIC: ::c_long = 0xf2f52010; +- pub const FUTEXFS_SUPER_MAGIC: ::c_long = 0xbad1dea; +- pub const HOSTFS_SUPER_MAGIC: ::c_long = 0x00c0ffee; +- pub const HPFS_SUPER_MAGIC: ::c_long = 0xf995e849; +- pub const HUGETLBFS_MAGIC: ::c_long = 0x958458f6; +- pub const ISOFS_SUPER_MAGIC: ::c_long = 0x00009660; +- pub const JFFS2_SUPER_MAGIC: ::c_long = 0x000072b6; +- pub const MINIX2_SUPER_MAGIC2: ::c_long = 0x00002478; +- pub const MINIX2_SUPER_MAGIC: ::c_long = 0x00002468; +- pub const MINIX3_SUPER_MAGIC: ::c_long = 0x4d5a; +- pub const MINIX_SUPER_MAGIC2: ::c_long = 0x0000138f; +- pub const MINIX_SUPER_MAGIC: ::c_long = 0x0000137f; +- pub const MSDOS_SUPER_MAGIC: ::c_long = 0x00004d44; +- pub const NCP_SUPER_MAGIC: ::c_long = 0x0000564c; +- pub const NFS_SUPER_MAGIC: ::c_long = 0x00006969; +- pub const NILFS_SUPER_MAGIC: ::c_long = 0x3434; +- pub const OCFS2_SUPER_MAGIC: ::c_long = 0x7461636f; +- pub const OPENPROM_SUPER_MAGIC: ::c_long = 0x00009fa1; +- pub const OVERLAYFS_SUPER_MAGIC: ::c_long = 0x794c7630; +- pub const PROC_SUPER_MAGIC: ::c_long = 0x00009fa0; +- pub const QNX4_SUPER_MAGIC: ::c_long = 0x0000002f; +- pub const QNX6_SUPER_MAGIC: ::c_long = 0x68191122; +- pub const RDTGROUP_SUPER_MAGIC: ::c_long = 0x7655821; +- pub const REISERFS_SUPER_MAGIC: ::c_long = 0x52654973; +- pub const SECURITYFS_MAGIC: ::c_long = 0x73636673; +- pub const SELINUX_MAGIC: ::c_long = 0xf97cff8c; +- pub const SMACK_MAGIC: ::c_long = 0x43415d53; +- pub const SMB_SUPER_MAGIC: ::c_long = 0x0000517b; +- pub const SYSFS_MAGIC: ::c_long = 0x62656572; +- pub const TMPFS_MAGIC: ::c_long = 0x01021994; +- pub const TRACEFS_MAGIC: ::c_long = 0x74726163; +- pub const UDF_SUPER_MAGIC: ::c_long = 0x15013346; +- pub const USBDEVICE_SUPER_MAGIC: ::c_long = 0x00009fa2; +- pub const XENFS_SUPER_MAGIC: ::c_long = 0xabba1974; + pub const XFS_SUPER_MAGIC: ::c_long = 0x58465342; + } else if #[cfg(target_arch = "s390x")] { +- pub const ADFS_SUPER_MAGIC: ::c_uint = 0x0000adf5; +- pub const AFFS_SUPER_MAGIC: ::c_uint = 0x0000adff; +- pub const AFS_SUPER_MAGIC: ::c_uint = 0x5346414f; +- pub const AUTOFS_SUPER_MAGIC: ::c_uint = 0x0187; + pub const BINDERFS_SUPER_MAGIC: ::c_uint = 0x6c6f6f70; +- pub const BPF_FS_MAGIC: ::c_uint = 0xcafe4a11; +- pub const BTRFS_SUPER_MAGIC: ::c_uint = 0x9123683e; +- pub const CGROUP2_SUPER_MAGIC: ::c_uint = 0x63677270; +- pub const CGROUP_SUPER_MAGIC: ::c_uint = 0x27e0eb; +- pub const CODA_SUPER_MAGIC: ::c_uint = 0x73757245; +- pub const CRAMFS_MAGIC: ::c_uint = 0x28cd3d45; +- pub const DEBUGFS_MAGIC: ::c_uint = 0x64626720; +- pub const DEVPTS_SUPER_MAGIC: ::c_uint = 0x1cd1; +- pub const ECRYPTFS_SUPER_MAGIC: ::c_uint = 0xf15f; +- pub const EFS_SUPER_MAGIC: ::c_uint = 0x00414a53; +- pub const EXT2_SUPER_MAGIC: ::c_uint = 0x0000ef53; +- pub const EXT3_SUPER_MAGIC: ::c_uint = 0x0000ef53; +- pub const EXT4_SUPER_MAGIC: ::c_uint = 0x0000ef53; +- pub const F2FS_SUPER_MAGIC: ::c_uint = 0xf2f52010; +- pub const FUTEXFS_SUPER_MAGIC: ::c_uint = 0xbad1dea; +- pub const HOSTFS_SUPER_MAGIC: ::c_uint = 0x00c0ffee; +- pub const HPFS_SUPER_MAGIC: ::c_uint = 0xf995e849; +- pub const HUGETLBFS_MAGIC: ::c_uint = 0x958458f6; +- pub const ISOFS_SUPER_MAGIC: ::c_uint = 0x00009660; +- pub const JFFS2_SUPER_MAGIC: ::c_uint = 0x000072b6; +- pub const MINIX2_SUPER_MAGIC2: ::c_uint = 0x00002478; +- pub const MINIX2_SUPER_MAGIC: ::c_uint = 0x00002468; +- pub const MINIX3_SUPER_MAGIC: ::c_uint = 0x4d5a; +- pub const MINIX_SUPER_MAGIC2: ::c_uint = 0x0000138f; +- pub const MINIX_SUPER_MAGIC: ::c_uint = 0x0000137f; +- pub const MSDOS_SUPER_MAGIC: ::c_uint = 0x00004d44; +- pub const NCP_SUPER_MAGIC: ::c_uint = 0x0000564c; +- pub const NFS_SUPER_MAGIC: ::c_uint = 0x00006969; +- pub const NILFS_SUPER_MAGIC: ::c_uint = 0x3434; +- pub const OCFS2_SUPER_MAGIC: ::c_uint = 0x7461636f; +- pub const OPENPROM_SUPER_MAGIC: ::c_uint = 0x00009fa1; +- pub const OVERLAYFS_SUPER_MAGIC: ::c_uint = 0x794c7630; +- pub const PROC_SUPER_MAGIC: ::c_uint = 0x00009fa0; +- pub const QNX4_SUPER_MAGIC: ::c_uint = 0x0000002f; +- pub const QNX6_SUPER_MAGIC: ::c_uint = 0x68191122; +- pub const RDTGROUP_SUPER_MAGIC: ::c_uint = 0x7655821; +- pub const REISERFS_SUPER_MAGIC: ::c_uint = 0x52654973; +- pub const SECURITYFS_MAGIC: ::c_uint = 0x73636673; +- pub const SELINUX_MAGIC: ::c_uint = 0xf97cff8c; +- pub const SMACK_MAGIC: ::c_uint = 0x43415d53; +- pub const SMB_SUPER_MAGIC: ::c_uint = 0x0000517b; +- pub const SYSFS_MAGIC: ::c_uint = 0x62656572; +- pub const TMPFS_MAGIC: ::c_uint = 0x01021994; +- pub const TRACEFS_MAGIC: ::c_uint = 0x74726163; +- pub const UDF_SUPER_MAGIC: ::c_uint = 0x15013346; +- pub const USBDEVICE_SUPER_MAGIC: ::c_uint = 0x00009fa2; +- pub const XENFS_SUPER_MAGIC: ::c_uint = 0xabba1974; + pub const XFS_SUPER_MAGIC: ::c_uint = 0x58465342; + } + } +@@ -894,6 +853,11 @@ pub const PTRACE_SEIZE: ::c_uint = 0x4206; + pub const PTRACE_INTERRUPT: ::c_uint = 0x4207; + pub const PTRACE_LISTEN: ::c_uint = 0x4208; + pub const PTRACE_PEEKSIGINFO: ::c_uint = 0x4209; ++pub const PTRACE_GET_SYSCALL_INFO: ::c_uint = 0x420e; ++pub const PTRACE_SYSCALL_INFO_NONE: ::__u8 = 0; ++pub const PTRACE_SYSCALL_INFO_ENTRY: ::__u8 = 1; ++pub const PTRACE_SYSCALL_INFO_EXIT: ::__u8 = 2; ++pub const PTRACE_SYSCALL_INFO_SECCOMP: ::__u8 = 3; + + // linux/fs.h + +@@ -955,11 +919,26 @@ pub const GENL_UNS_ADMIN_PERM: ::c_int = 0x10; + pub const GENL_ID_VFS_DQUOT: ::c_int = ::NLMSG_MIN_TYPE + 1; + pub const GENL_ID_PMCRAID: ::c_int = ::NLMSG_MIN_TYPE + 2; + +-pub const TIOCM_LE: ::c_int = 0x001; +-pub const TIOCM_DTR: ::c_int = 0x002; +-pub const TIOCM_RTS: ::c_int = 0x004; +-pub const TIOCM_CD: ::c_int = TIOCM_CAR; +-pub const TIOCM_RI: ::c_int = TIOCM_RNG; ++// elf.h ++pub const NT_PRSTATUS: ::c_int = 1; ++pub const NT_PRFPREG: ::c_int = 2; ++pub const NT_FPREGSET: ::c_int = 2; ++pub const NT_PRPSINFO: ::c_int = 3; ++pub const NT_PRXREG: ::c_int = 4; ++pub const NT_TASKSTRUCT: ::c_int = 4; ++pub const NT_PLATFORM: ::c_int = 5; ++pub const NT_AUXV: ::c_int = 6; ++pub const NT_GWINDOWS: ::c_int = 7; ++pub const NT_ASRS: ::c_int = 8; ++pub const NT_PSTATUS: ::c_int = 10; ++pub const NT_PSINFO: ::c_int = 13; ++pub const NT_PRCRED: ::c_int = 14; ++pub const NT_UTSNAME: ::c_int = 15; ++pub const NT_LWPSTATUS: ::c_int = 16; ++pub const NT_LWPSINFO: ::c_int = 17; ++pub const NT_PRFPXREG: ::c_int = 20; ++ ++pub const ELFOSABI_ARM_AEABI: u8 = 64; + + // linux/keyctl.h + pub const KEYCTL_DH_COMPUTE: u32 = 23; +@@ -1023,6 +1002,7 @@ pub const STATX_BLOCKS: ::c_uint = 0x0400; + pub const STATX_BASIC_STATS: ::c_uint = 0x07ff; + pub const STATX_BTIME: ::c_uint = 0x0800; + pub const STATX_MNT_ID: ::c_uint = 0x1000; ++pub const STATX_DIOALIGN: ::c_uint = 0x2000; + pub const STATX_ALL: ::c_uint = 0x0fff; + pub const STATX__RESERVED: ::c_int = 0x80000000; + pub const STATX_ATTR_COMPRESSED: ::c_int = 0x0004; +@@ -1031,6 +1011,11 @@ pub const STATX_ATTR_APPEND: ::c_int = 0x0020; + pub const STATX_ATTR_NODUMP: ::c_int = 0x0040; + pub const STATX_ATTR_ENCRYPTED: ::c_int = 0x0800; + pub const STATX_ATTR_AUTOMOUNT: ::c_int = 0x1000; ++pub const STATX_ATTR_MOUNT_ROOT: ::c_int = 0x2000; ++pub const STATX_ATTR_VERITY: ::c_int = 0x00100000; ++pub const STATX_ATTR_DAX: ::c_int = 0x00200000; ++ ++pub const SOMAXCONN: ::c_int = 4096; + + //sys/timex.h + pub const ADJ_OFFSET: ::c_uint = 0x0001; +@@ -1196,28 +1181,16 @@ extern "C" { + mask: ::c_uint, + statxbuf: *mut statx, + ) -> ::c_int; ++ pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; + pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; +- +- pub fn memmem( +- haystack: *const ::c_void, +- haystacklen: ::size_t, +- needle: *const ::c_void, +- needlelen: ::size_t, +- ) -> *mut ::c_void; + pub fn getauxval(type_: ::c_ulong) -> ::c_ulong; + + pub fn adjtimex(buf: *mut timex) -> ::c_int; + pub fn ntp_adjtime(buf: *mut timex) -> ::c_int; + #[link_name = "ntp_gettimex"] + pub fn ntp_gettime(buf: *mut ntptimeval) -> ::c_int; +- pub fn copy_file_range( +- fd_in: ::c_int, +- off_in: *mut ::off64_t, +- fd_out: ::c_int, +- off_out: *mut ::off64_t, +- len: ::size_t, +- flags: ::c_uint, +- ) -> ::ssize_t; ++ pub fn clock_adjtime(clk_id: ::clockid_t, buf: *mut ::timex) -> ::c_int; ++ + pub fn fanotify_mark( + fd: ::c_int, + flags: ::c_uint, +@@ -1239,6 +1212,20 @@ extern "C" { + offset: ::off_t, + flags: ::c_int, + ) -> ::ssize_t; ++ pub fn preadv64v2( ++ fd: ::c_int, ++ iov: *const ::iovec, ++ iovcnt: ::c_int, ++ offset: ::off64_t, ++ flags: ::c_int, ++ ) -> ::ssize_t; ++ pub fn pwritev64v2( ++ fd: ::c_int, ++ iov: *const ::iovec, ++ iovcnt: ::c_int, ++ offset: ::off64_t, ++ flags: ::c_int, ++ ) -> ::ssize_t; + pub fn renameat2( + olddirfd: ::c_int, + oldpath: *const ::c_char, +@@ -1249,6 +1236,10 @@ extern "C" { + + // Added in `glibc` 2.25 + pub fn explicit_bzero(s: *mut ::c_void, len: ::size_t); ++ // Added in `glibc` 2.29 ++ pub fn reallocarray(ptr: *mut ::c_void, nmemb: ::size_t, size: ::size_t) -> *mut ::c_void; ++ ++ pub fn ctermid(s: *mut ::c_char) -> *mut ::c_char; + } + + extern "C" { +@@ -1274,16 +1265,6 @@ extern "C" { + ) -> ::c_int; + pub fn getpriority(which: ::__priority_which_t, who: ::id_t) -> ::c_int; + pub fn setpriority(which: ::__priority_which_t, who: ::id_t, prio: ::c_int) -> ::c_int; +- pub fn pthread_getaffinity_np( +- thread: ::pthread_t, +- cpusetsize: ::size_t, +- cpuset: *mut ::cpu_set_t, +- ) -> ::c_int; +- pub fn pthread_setaffinity_np( +- thread: ::pthread_t, +- cpusetsize: ::size_t, +- cpuset: *const ::cpu_set_t, +- ) -> ::c_int; + pub fn pthread_rwlockattr_getkind_np( + attr: *const ::pthread_rwlockattr_t, + val: *mut ::c_int, +@@ -1292,9 +1273,10 @@ extern "C" { + attr: *mut ::pthread_rwlockattr_t, + val: ::c_int, + ) -> ::c_int; +- pub fn sched_getcpu() -> ::c_int; ++ pub fn pthread_sigqueue(thread: ::pthread_t, sig: ::c_int, value: ::sigval) -> ::c_int; + pub fn mallinfo() -> ::mallinfo; + pub fn mallinfo2() -> ::mallinfo2; ++ pub fn malloc_info(options: ::c_int, stream: *mut ::FILE) -> ::c_int; + pub fn malloc_usable_size(ptr: *mut ::c_void) -> ::size_t; + pub fn getpwent_r( + pwd: *mut ::passwd, +@@ -1308,18 +1290,104 @@ extern "C" { + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; +- pub fn pthread_getname_np(thread: ::pthread_t, name: *mut ::c_char, len: ::size_t) -> ::c_int; +- pub fn pthread_setname_np(thread: ::pthread_t, name: *const ::c_char) -> ::c_int; ++ pub fn fgetpwent_r( ++ stream: *mut ::FILE, ++ pwd: *mut ::passwd, ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ result: *mut *mut ::passwd, ++ ) -> ::c_int; ++ pub fn fgetgrent_r( ++ stream: *mut ::FILE, ++ grp: *mut ::group, ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ result: *mut *mut ::group, ++ ) -> ::c_int; ++ ++ pub fn sethostid(hostid: ::c_long) -> ::c_int; ++ ++ pub fn memfd_create(name: *const ::c_char, flags: ::c_uint) -> ::c_int; ++ pub fn mlock2(addr: *const ::c_void, len: ::size_t, flags: ::c_uint) -> ::c_int; ++ ++ pub fn euidaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int; ++ pub fn eaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int; ++ ++ pub fn asctime_r(tm: *const ::tm, buf: *mut ::c_char) -> *mut ::c_char; ++ pub fn ctime_r(timep: *const time_t, buf: *mut ::c_char) -> *mut ::c_char; ++ ++ pub fn strftime( ++ s: *mut ::c_char, ++ max: ::size_t, ++ format: *const ::c_char, ++ tm: *const ::tm, ++ ) -> ::size_t; ++ pub fn strptime(s: *const ::c_char, format: *const ::c_char, tm: *mut ::tm) -> *mut ::c_char; ++ ++ pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; ++ /// POSIX version of `basename(3)`, defined in `libgen.h`. ++ #[link_name = "__xpg_basename"] ++ pub fn posix_basename(path: *mut ::c_char) -> *mut ::c_char; ++ /// GNU version of `basename(3)`, defined in `string.h`. ++ #[link_name = "basename"] ++ pub fn gnu_basename(path: *const ::c_char) -> *mut ::c_char; + } + + extern "C" { + pub fn dlmopen(lmid: Lmid_t, filename: *const ::c_char, flag: ::c_int) -> *mut ::c_void; + pub fn dlinfo(handle: *mut ::c_void, request: ::c_int, info: *mut ::c_void) -> ::c_int; ++ pub fn dladdr1( ++ addr: *const ::c_void, ++ info: *mut ::Dl_info, ++ extra_info: *mut *mut ::c_void, ++ flags: ::c_int, ++ ) -> ::c_int; ++ pub fn malloc_trim(__pad: ::size_t) -> ::c_int; ++} ++ ++extern "C" { ++ pub fn gnu_get_libc_release() -> *const ::c_char; ++ pub fn gnu_get_libc_version() -> *const ::c_char; ++} ++ ++// posix/spawn.h ++extern "C" { ++ // Added in `glibc` 2.29 ++ pub fn posix_spawn_file_actions_addchdir_np( ++ actions: *mut ::posix_spawn_file_actions_t, ++ path: *const ::c_char, ++ ) -> ::c_int; ++ // Added in `glibc` 2.29 ++ pub fn posix_spawn_file_actions_addfchdir_np( ++ actions: *mut ::posix_spawn_file_actions_t, ++ fd: ::c_int, ++ ) -> ::c_int; ++ // Added in `glibc` 2.34 ++ pub fn posix_spawn_file_actions_addclosefrom_np( ++ actions: *mut ::posix_spawn_file_actions_t, ++ from: ::c_int, ++ ) -> ::c_int; ++ // Added in `glibc` 2.35 ++ pub fn posix_spawn_file_actions_addtcsetpgrp_np( ++ actions: *mut ::posix_spawn_file_actions_t, ++ tcfd: ::c_int, ++ ) -> ::c_int; ++} ++ ++// mntent.h ++extern "C" { ++ pub fn getmntent_r( ++ stream: *mut ::FILE, ++ mntbuf: *mut ::mntent, ++ buf: *mut ::c_char, ++ buflen: ::c_int, ++ ) -> *mut ::mntent; + } + + cfg_if! { + if #[cfg(any(target_arch = "x86", + target_arch = "arm", ++ target_arch = "m68k", + target_arch = "mips", + target_arch = "powerpc", + target_arch = "sparc", +@@ -1332,7 +1400,8 @@ cfg_if! { + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64", +- target_arch = "riscv64"))] { ++ target_arch = "riscv64", ++ target_arch = "loongarch64"))] { + mod b64; + pub use self::b64::*; + } else { +diff --git a/vendor/libc/src/unix/linux_like/linux/mod.rs b/vendor/libc/src/unix/linux_like/linux/mod.rs +index f4bed8e..a982901 100644 +--- a/vendor/libc/src/unix/linux_like/linux/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/mod.rs +@@ -14,6 +14,7 @@ pub type nl_item = ::c_int; + pub type idtype_t = ::c_uint; + pub type loff_t = ::c_longlong; + pub type pthread_key_t = ::c_uint; ++pub type pthread_spinlock_t = ::c_int; + + pub type __u8 = ::c_uchar; + pub type __u16 = ::c_ushort; +@@ -38,10 +39,18 @@ pub type Elf64_Section = u16; + + // linux/can.h + pub type canid_t = u32; ++ ++// linux/can/j1939.h + pub type can_err_mask_t = u32; ++pub type pgn_t = u32; ++pub type priority_t = u8; ++pub type name_t = u64; + + pub type iconv_t = *mut ::c_void; + ++// linux/sctp.h ++pub type sctp_assoc_t = ::__s32; ++ + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub enum fpos64_t {} // FIXME: fill this out with a struct + impl ::Copy for fpos64_t {} +@@ -462,9 +471,9 @@ s! { + __pgrp: ::pid_t, + __sd: ::sigset_t, + __ss: ::sigset_t, +- #[cfg(target_env = "musl")] ++ #[cfg(any(target_env = "musl", target_env = "ohos"))] + __prio: ::c_int, +- #[cfg(not(target_env = "musl"))] ++ #[cfg(not(any(target_env = "musl", target_env = "ohos")))] + __sp: ::sched_param, + __policy: ::c_int, + __pad: [::c_int; 16], +@@ -541,6 +550,141 @@ s! { + pub can_id: canid_t, + pub can_mask: canid_t, + } ++ ++ // linux/can/j1939.h ++ pub struct j1939_filter { ++ pub name: name_t, ++ pub name_mask: name_t, ++ pub pgn: pgn_t, ++ pub pgn_mask: pgn_t, ++ pub addr: u8, ++ pub addr_mask: u8, ++ } ++ ++ // linux/filter.h ++ pub struct sock_filter { ++ pub code: ::__u16, ++ pub jt: ::__u8, ++ pub jf: ::__u8, ++ pub k: ::__u32, ++ } ++ ++ pub struct sock_fprog { ++ pub len: ::c_ushort, ++ pub filter: *mut sock_filter, ++ } ++ ++ // linux/seccomp.h ++ pub struct seccomp_data { ++ pub nr: ::c_int, ++ pub arch: ::__u32, ++ pub instruction_pointer: ::__u64, ++ pub args: [::__u64; 6], ++ } ++ ++ pub struct nlmsghdr { ++ pub nlmsg_len: u32, ++ pub nlmsg_type: u16, ++ pub nlmsg_flags: u16, ++ pub nlmsg_seq: u32, ++ pub nlmsg_pid: u32, ++ } ++ ++ pub struct nlmsgerr { ++ pub error: ::c_int, ++ pub msg: nlmsghdr, ++ } ++ ++ pub struct nlattr { ++ pub nla_len: u16, ++ pub nla_type: u16, ++ } ++ ++ pub struct file_clone_range { ++ pub src_fd: ::__s64, ++ pub src_offset: ::__u64, ++ pub src_length: ::__u64, ++ pub dest_offset: ::__u64, ++ } ++ ++ pub struct __c_anonymous_ifru_map { ++ pub mem_start: ::c_ulong, ++ pub mem_end: ::c_ulong, ++ pub base_addr: ::c_ushort, ++ pub irq: ::c_uchar, ++ pub dma: ::c_uchar, ++ pub port: ::c_uchar, ++ } ++ ++ pub struct in6_ifreq { ++ pub ifr6_addr: ::in6_addr, ++ pub ifr6_prefixlen: u32, ++ pub ifr6_ifindex: ::c_int, ++ } ++ ++ pub struct option { ++ pub name: *const ::c_char, ++ pub has_arg: ::c_int, ++ pub flag: *mut ::c_int, ++ pub val: ::c_int, ++ } ++ ++ // linux/sctp.h ++ ++ pub struct sctp_initmsg { ++ pub sinit_num_ostreams: ::__u16, ++ pub sinit_max_instreams: ::__u16, ++ pub sinit_max_attempts: ::__u16, ++ pub sinit_max_init_timeo: ::__u16, ++ } ++ ++ pub struct sctp_sndrcvinfo { ++ pub sinfo_stream: ::__u16, ++ pub sinfo_ssn: ::__u16, ++ pub sinfo_flags: ::__u16, ++ pub sinfo_ppid: ::__u32, ++ pub sinfo_context: ::__u32, ++ pub sinfo_timetolive: ::__u32, ++ pub sinfo_tsn: ::__u32, ++ pub sinfo_cumtsn: ::__u32, ++ pub sinfo_assoc_id: ::sctp_assoc_t, ++ } ++ ++ pub struct sctp_sndinfo { ++ pub snd_sid: ::__u16, ++ pub snd_flags: ::__u16, ++ pub snd_ppid: ::__u32, ++ pub snd_context: ::__u32, ++ pub snd_assoc_id: ::sctp_assoc_t, ++ } ++ ++ pub struct sctp_rcvinfo { ++ pub rcv_sid: ::__u16, ++ pub rcv_ssn: ::__u16, ++ pub rcv_flags: ::__u16, ++ pub rcv_ppid: ::__u32, ++ pub rcv_tsn: ::__u32, ++ pub rcv_cumtsn: ::__u32, ++ pub rcv_context: ::__u32, ++ pub rcv_assoc_id: ::sctp_assoc_t, ++ } ++ ++ pub struct sctp_nxtinfo { ++ pub nxt_sid: ::__u16, ++ pub nxt_flags: ::__u16, ++ pub nxt_ppid: ::__u32, ++ pub nxt_length: ::__u32, ++ pub nxt_assoc_id: ::sctp_assoc_t, ++ } ++ ++ pub struct sctp_prinfo { ++ pub pr_policy: ::__u16, ++ pub pr_value: ::__u32, ++ } ++ ++ pub struct sctp_authinfo { ++ pub auth_keynumber: ::__u16, ++ } + } + + s_no_extra_traits! { +@@ -628,6 +772,47 @@ s_no_extra_traits! { + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pad: [::c_long; 4], + } ++ ++ #[cfg(libc_union)] ++ pub union __c_anonymous_ifr_ifru { ++ pub ifru_addr: ::sockaddr, ++ pub ifru_dstaddr: ::sockaddr, ++ pub ifru_broadaddr: ::sockaddr, ++ pub ifru_netmask: ::sockaddr, ++ pub ifru_hwaddr: ::sockaddr, ++ pub ifru_flags: ::c_short, ++ pub ifru_ifindex: ::c_int, ++ pub ifru_metric: ::c_int, ++ pub ifru_mtu: ::c_int, ++ pub ifru_map: __c_anonymous_ifru_map, ++ pub ifru_slave: [::c_char; ::IFNAMSIZ], ++ pub ifru_newname: [::c_char; ::IFNAMSIZ], ++ pub ifru_data: *mut ::c_char, ++ } ++ ++ pub struct ifreq { ++ /// interface name, e.g. "en0" ++ pub ifr_name: [::c_char; ::IFNAMSIZ], ++ #[cfg(libc_union)] ++ pub ifr_ifru: __c_anonymous_ifr_ifru, ++ #[cfg(not(libc_union))] ++ pub ifr_ifru: ::sockaddr, ++ } ++ ++ pub struct hwtstamp_config { ++ pub flags: ::c_int, ++ pub tx_type: ::c_int, ++ pub rx_filter: ::c_int, ++ } ++} ++ ++s_no_extra_traits! { ++ // linux/net_tstamp.h ++ #[allow(missing_debug_implementations)] ++ pub struct sock_txtime { ++ pub clockid: ::clockid_t, ++ pub flags: ::__u32, ++ } + } + + cfg_if! { +@@ -819,6 +1004,28 @@ cfg_if! { + } + } + ++ impl PartialEq for pthread_barrier_t { ++ fn eq(&self, other: &pthread_barrier_t) -> bool { ++ self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b) ++ } ++ } ++ ++ impl Eq for pthread_barrier_t {} ++ ++ impl ::fmt::Debug for pthread_barrier_t { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("pthread_barrier_t") ++ .field("size", &self.size) ++ .finish() ++ } ++ } ++ ++ impl ::hash::Hash for pthread_barrier_t { ++ fn hash(&self, state: &mut H) { ++ self.size.hash(state); ++ } ++ } ++ + impl PartialEq for sockaddr_alg { + fn eq(&self, other: &sockaddr_alg) -> bool { + self.salg_family == other.salg_family +@@ -992,11 +1199,64 @@ cfg_if! { + self.mq_curmsgs.hash(state); + } + } ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for __c_anonymous_ifr_ifru { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("ifr_ifru") ++ .field("ifru_addr", unsafe { &self.ifru_addr }) ++ .field("ifru_dstaddr", unsafe { &self.ifru_dstaddr }) ++ .field("ifru_broadaddr", unsafe { &self.ifru_broadaddr }) ++ .field("ifru_netmask", unsafe { &self.ifru_netmask }) ++ .field("ifru_hwaddr", unsafe { &self.ifru_hwaddr }) ++ .field("ifru_flags", unsafe { &self.ifru_flags }) ++ .field("ifru_ifindex", unsafe { &self.ifru_ifindex }) ++ .field("ifru_metric", unsafe { &self.ifru_metric }) ++ .field("ifru_mtu", unsafe { &self.ifru_mtu }) ++ .field("ifru_map", unsafe { &self.ifru_map }) ++ .field("ifru_slave", unsafe { &self.ifru_slave }) ++ .field("ifru_newname", unsafe { &self.ifru_newname }) ++ .field("ifru_data", unsafe { &self.ifru_data }) ++ .finish() ++ } ++ } ++ impl ::fmt::Debug for ifreq { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("ifreq") ++ .field("ifr_name", &self.ifr_name) ++ .field("ifr_ifru", &self.ifr_ifru) ++ .finish() ++ } ++ } ++ ++ impl ::fmt::Debug for hwtstamp_config { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("hwtstamp_config") ++ .field("flags", &self.flags) ++ .field("tx_type", &self.tx_type) ++ .field("rx_filter", &self.rx_filter) ++ .finish() ++ } ++ } ++ impl PartialEq for hwtstamp_config { ++ fn eq(&self, other: &hwtstamp_config) -> bool { ++ self.flags == other.flags && ++ self.tx_type == other.tx_type && ++ self.rx_filter == other.rx_filter ++ } ++ } ++ impl Eq for hwtstamp_config {} ++ impl ::hash::Hash for hwtstamp_config { ++ fn hash(&self, state: &mut H) { ++ self.flags.hash(state); ++ self.tx_type.hash(state); ++ self.rx_filter.hash(state); ++ } ++ } + } + } + + cfg_if! { +- if #[cfg(any(target_env = "gnu", target_env = "musl"))] { ++ if #[cfg(any(target_env = "gnu", target_env = "musl", target_env = "ohos"))] { + pub const ABDAY_1: ::nl_item = 0x20000; + pub const ABDAY_2: ::nl_item = 0x20001; + pub const ABDAY_3: ::nl_item = 0x20002; +@@ -1235,6 +1495,181 @@ pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 248; + pub const RLIM_SAVED_MAX: ::rlim_t = RLIM_INFINITY; + pub const RLIM_SAVED_CUR: ::rlim_t = RLIM_INFINITY; + ++// elf.h - Fields in the e_ident array. ++pub const EI_NIDENT: usize = 16; ++ ++pub const EI_MAG0: usize = 0; ++pub const ELFMAG0: u8 = 0x7f; ++pub const EI_MAG1: usize = 1; ++pub const ELFMAG1: u8 = b'E'; ++pub const EI_MAG2: usize = 2; ++pub const ELFMAG2: u8 = b'L'; ++pub const EI_MAG3: usize = 3; ++pub const ELFMAG3: u8 = b'F'; ++pub const SELFMAG: usize = 4; ++ ++pub const EI_CLASS: usize = 4; ++pub const ELFCLASSNONE: u8 = 0; ++pub const ELFCLASS32: u8 = 1; ++pub const ELFCLASS64: u8 = 2; ++pub const ELFCLASSNUM: usize = 3; ++ ++pub const EI_DATA: usize = 5; ++pub const ELFDATANONE: u8 = 0; ++pub const ELFDATA2LSB: u8 = 1; ++pub const ELFDATA2MSB: u8 = 2; ++pub const ELFDATANUM: usize = 3; ++ ++pub const EI_VERSION: usize = 6; ++ ++pub const EI_OSABI: usize = 7; ++pub const ELFOSABI_NONE: u8 = 0; ++pub const ELFOSABI_SYSV: u8 = 0; ++pub const ELFOSABI_HPUX: u8 = 1; ++pub const ELFOSABI_NETBSD: u8 = 2; ++pub const ELFOSABI_GNU: u8 = 3; ++pub const ELFOSABI_LINUX: u8 = ELFOSABI_GNU; ++pub const ELFOSABI_SOLARIS: u8 = 6; ++pub const ELFOSABI_AIX: u8 = 7; ++pub const ELFOSABI_IRIX: u8 = 8; ++pub const ELFOSABI_FREEBSD: u8 = 9; ++pub const ELFOSABI_TRU64: u8 = 10; ++pub const ELFOSABI_MODESTO: u8 = 11; ++pub const ELFOSABI_OPENBSD: u8 = 12; ++pub const ELFOSABI_ARM: u8 = 97; ++pub const ELFOSABI_STANDALONE: u8 = 255; ++ ++pub const EI_ABIVERSION: usize = 8; ++ ++pub const EI_PAD: usize = 9; ++ ++// elf.h - Legal values for e_type (object file type). ++pub const ET_NONE: u16 = 0; ++pub const ET_REL: u16 = 1; ++pub const ET_EXEC: u16 = 2; ++pub const ET_DYN: u16 = 3; ++pub const ET_CORE: u16 = 4; ++pub const ET_NUM: u16 = 5; ++pub const ET_LOOS: u16 = 0xfe00; ++pub const ET_HIOS: u16 = 0xfeff; ++pub const ET_LOPROC: u16 = 0xff00; ++pub const ET_HIPROC: u16 = 0xffff; ++ ++// elf.h - Legal values for e_machine (architecture). ++pub const EM_NONE: u16 = 0; ++pub const EM_M32: u16 = 1; ++pub const EM_SPARC: u16 = 2; ++pub const EM_386: u16 = 3; ++pub const EM_68K: u16 = 4; ++pub const EM_88K: u16 = 5; ++pub const EM_860: u16 = 7; ++pub const EM_MIPS: u16 = 8; ++pub const EM_S370: u16 = 9; ++pub const EM_MIPS_RS3_LE: u16 = 10; ++pub const EM_PARISC: u16 = 15; ++pub const EM_VPP500: u16 = 17; ++pub const EM_SPARC32PLUS: u16 = 18; ++pub const EM_960: u16 = 19; ++pub const EM_PPC: u16 = 20; ++pub const EM_PPC64: u16 = 21; ++pub const EM_S390: u16 = 22; ++pub const EM_V800: u16 = 36; ++pub const EM_FR20: u16 = 37; ++pub const EM_RH32: u16 = 38; ++pub const EM_RCE: u16 = 39; ++pub const EM_ARM: u16 = 40; ++pub const EM_FAKE_ALPHA: u16 = 41; ++pub const EM_SH: u16 = 42; ++pub const EM_SPARCV9: u16 = 43; ++pub const EM_TRICORE: u16 = 44; ++pub const EM_ARC: u16 = 45; ++pub const EM_H8_300: u16 = 46; ++pub const EM_H8_300H: u16 = 47; ++pub const EM_H8S: u16 = 48; ++pub const EM_H8_500: u16 = 49; ++pub const EM_IA_64: u16 = 50; ++pub const EM_MIPS_X: u16 = 51; ++pub const EM_COLDFIRE: u16 = 52; ++pub const EM_68HC12: u16 = 53; ++pub const EM_MMA: u16 = 54; ++pub const EM_PCP: u16 = 55; ++pub const EM_NCPU: u16 = 56; ++pub const EM_NDR1: u16 = 57; ++pub const EM_STARCORE: u16 = 58; ++pub const EM_ME16: u16 = 59; ++pub const EM_ST100: u16 = 60; ++pub const EM_TINYJ: u16 = 61; ++pub const EM_X86_64: u16 = 62; ++pub const EM_PDSP: u16 = 63; ++pub const EM_FX66: u16 = 66; ++pub const EM_ST9PLUS: u16 = 67; ++pub const EM_ST7: u16 = 68; ++pub const EM_68HC16: u16 = 69; ++pub const EM_68HC11: u16 = 70; ++pub const EM_68HC08: u16 = 71; ++pub const EM_68HC05: u16 = 72; ++pub const EM_SVX: u16 = 73; ++pub const EM_ST19: u16 = 74; ++pub const EM_VAX: u16 = 75; ++pub const EM_CRIS: u16 = 76; ++pub const EM_JAVELIN: u16 = 77; ++pub const EM_FIREPATH: u16 = 78; ++pub const EM_ZSP: u16 = 79; ++pub const EM_MMIX: u16 = 80; ++pub const EM_HUANY: u16 = 81; ++pub const EM_PRISM: u16 = 82; ++pub const EM_AVR: u16 = 83; ++pub const EM_FR30: u16 = 84; ++pub const EM_D10V: u16 = 85; ++pub const EM_D30V: u16 = 86; ++pub const EM_V850: u16 = 87; ++pub const EM_M32R: u16 = 88; ++pub const EM_MN10300: u16 = 89; ++pub const EM_MN10200: u16 = 90; ++pub const EM_PJ: u16 = 91; ++pub const EM_OPENRISC: u16 = 92; ++pub const EM_ARC_A5: u16 = 93; ++pub const EM_XTENSA: u16 = 94; ++pub const EM_AARCH64: u16 = 183; ++pub const EM_TILEPRO: u16 = 188; ++pub const EM_TILEGX: u16 = 191; ++pub const EM_ALPHA: u16 = 0x9026; ++ ++// elf.h - Legal values for e_version (version). ++pub const EV_NONE: u32 = 0; ++pub const EV_CURRENT: u32 = 1; ++pub const EV_NUM: u32 = 2; ++ ++// elf.h - Legal values for p_type (segment type). ++pub const PT_NULL: u32 = 0; ++pub const PT_LOAD: u32 = 1; ++pub const PT_DYNAMIC: u32 = 2; ++pub const PT_INTERP: u32 = 3; ++pub const PT_NOTE: u32 = 4; ++pub const PT_SHLIB: u32 = 5; ++pub const PT_PHDR: u32 = 6; ++pub const PT_TLS: u32 = 7; ++pub const PT_NUM: u32 = 8; ++pub const PT_LOOS: u32 = 0x60000000; ++pub const PT_GNU_EH_FRAME: u32 = 0x6474e550; ++pub const PT_GNU_STACK: u32 = 0x6474e551; ++pub const PT_GNU_RELRO: u32 = 0x6474e552; ++pub const PT_LOSUNW: u32 = 0x6ffffffa; ++pub const PT_SUNWBSS: u32 = 0x6ffffffa; ++pub const PT_SUNWSTACK: u32 = 0x6ffffffb; ++pub const PT_HISUNW: u32 = 0x6fffffff; ++pub const PT_HIOS: u32 = 0x6fffffff; ++pub const PT_LOPROC: u32 = 0x70000000; ++pub const PT_HIPROC: u32 = 0x7fffffff; ++ ++// Legal values for p_flags (segment flags). ++pub const PF_X: u32 = 1 << 0; ++pub const PF_W: u32 = 1 << 1; ++pub const PF_R: u32 = 1 << 2; ++pub const PF_MASKOS: u32 = 0x0ff00000; ++pub const PF_MASKPROC: u32 = 0xf0000000; ++ ++// elf.h - Legal values for a_type (entry type). + pub const AT_NULL: ::c_ulong = 0; + pub const AT_IGNORE: ::c_ulong = 1; + pub const AT_EXECFD: ::c_ulong = 2; +@@ -1261,6 +1696,10 @@ pub const AT_HWCAP2: ::c_ulong = 26; + + pub const AT_EXECFN: ::c_ulong = 31; + ++// defined in arch//include/uapi/asm/auxvec.h but has the same value ++// wherever it is defined. ++pub const AT_SYSINFO_EHDR: ::c_ulong = 33; ++ + pub const GLOB_ERR: ::c_int = 1 << 0; + pub const GLOB_MARK: ::c_int = 1 << 1; + pub const GLOB_NOSORT: ::c_int = 1 << 2; +@@ -1277,6 +1716,8 @@ pub const POSIX_MADV_NORMAL: ::c_int = 0; + pub const POSIX_MADV_RANDOM: ::c_int = 1; + pub const POSIX_MADV_SEQUENTIAL: ::c_int = 2; + pub const POSIX_MADV_WILLNEED: ::c_int = 3; ++pub const POSIX_SPAWN_USEVFORK: ::c_int = 64; ++pub const POSIX_SPAWN_SETSID: ::c_int = 128; + + pub const S_IEXEC: mode_t = 64; + pub const S_IWRITE: mode_t = 128; +@@ -1371,6 +1812,12 @@ pub const IFLA_PROP_LIST: ::c_ushort = 52; + pub const IFLA_ALT_IFNAME: ::c_ushort = 53; + pub const IFLA_PERM_ADDRESS: ::c_ushort = 54; + pub const IFLA_PROTO_DOWN_REASON: ::c_ushort = 55; ++pub const IFLA_PARENT_DEV_NAME: ::c_ushort = 56; ++pub const IFLA_PARENT_DEV_BUS_NAME: ::c_ushort = 57; ++pub const IFLA_GRO_MAX_SIZE: ::c_ushort = 58; ++pub const IFLA_TSO_MAX_SIZE: ::c_ushort = 59; ++pub const IFLA_TSO_MAX_SEGS: ::c_ushort = 60; ++pub const IFLA_ALLMULTI: ::c_ushort = 61; + + pub const IFLA_INFO_UNSPEC: ::c_ushort = 0; + pub const IFLA_INFO_KIND: ::c_ushort = 1; +@@ -1423,6 +1870,28 @@ pub const RTLD_NOW: ::c_int = 0x2; + + pub const AT_EACCESS: ::c_int = 0x200; + ++// linux/mempolicy.h ++pub const MPOL_DEFAULT: ::c_int = 0; ++pub const MPOL_PREFERRED: ::c_int = 1; ++pub const MPOL_BIND: ::c_int = 2; ++pub const MPOL_INTERLEAVE: ::c_int = 3; ++pub const MPOL_LOCAL: ::c_int = 4; ++pub const MPOL_F_NUMA_BALANCING: ::c_int = 1 << 13; ++pub const MPOL_F_RELATIVE_NODES: ::c_int = 1 << 14; ++pub const MPOL_F_STATIC_NODES: ::c_int = 1 << 15; ++ ++// linux/membarrier.h ++pub const MEMBARRIER_CMD_QUERY: ::c_int = 0; ++pub const MEMBARRIER_CMD_GLOBAL: ::c_int = 1 << 0; ++pub const MEMBARRIER_CMD_GLOBAL_EXPEDITED: ::c_int = 1 << 1; ++pub const MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED: ::c_int = 1 << 2; ++pub const MEMBARRIER_CMD_PRIVATE_EXPEDITED: ::c_int = 1 << 3; ++pub const MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED: ::c_int = 1 << 4; ++pub const MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE: ::c_int = 1 << 5; ++pub const MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE: ::c_int = 1 << 6; ++pub const MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ: ::c_int = 1 << 7; ++pub const MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ: ::c_int = 1 << 8; ++ + align_const! { + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + size: [0; __SIZEOF_PTHREAD_MUTEX_T], +@@ -1438,6 +1907,11 @@ pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; + pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1; + pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2; + pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; ++pub const PTHREAD_MUTEX_STALLED: ::c_int = 0; ++pub const PTHREAD_MUTEX_ROBUST: ::c_int = 1; ++pub const PTHREAD_PRIO_NONE: ::c_int = 0; ++pub const PTHREAD_PRIO_INHERIT: ::c_int = 1; ++pub const PTHREAD_PRIO_PROTECT: ::c_int = 2; + pub const PTHREAD_PROCESS_PRIVATE: ::c_int = 0; + pub const PTHREAD_PROCESS_SHARED: ::c_int = 1; + pub const __SIZEOF_PTHREAD_COND_T: usize = 48; +@@ -1454,6 +1928,8 @@ pub const SCHED_IDLE: ::c_int = 5; + + pub const SCHED_RESET_ON_FORK: ::c_int = 0x40000000; + ++pub const CLONE_PIDFD: ::c_int = 0x1000; ++ + // netinet/in.h + // NOTE: These are in addition to the constants defined in src/unix/mod.rs + +@@ -1480,9 +1956,11 @@ pub const IPC_STAT: ::c_int = 2; + pub const IPC_INFO: ::c_int = 3; + pub const MSG_STAT: ::c_int = 11; + pub const MSG_INFO: ::c_int = 12; ++pub const MSG_NOTIFICATION: ::c_int = 0x8000; + + pub const MSG_NOERROR: ::c_int = 0o10000; + pub const MSG_EXCEPT: ::c_int = 0o20000; ++pub const MSG_ZEROCOPY: ::c_int = 0x4000000; + + pub const SHM_R: ::c_int = 0o400; + pub const SHM_W: ::c_int = 0o200; +@@ -1498,11 +1976,6 @@ pub const SHM_HUGETLB: ::c_int = 0o4000; + #[cfg(not(all(target_env = "uclibc", target_arch = "mips")))] + pub const SHM_NORESERVE: ::c_int = 0o10000; + +-pub const EPOLLRDHUP: ::c_int = 0x2000; +-pub const EPOLLEXCLUSIVE: ::c_int = 0x10000000; +-pub const EPOLLWAKEUP: ::c_int = 0x20000000; +-pub const EPOLLONESHOT: ::c_int = 0x40000000; +- + pub const QFMT_VFS_OLD: ::c_int = 1; + pub const QFMT_VFS_V0: ::c_int = 2; + pub const QFMT_VFS_V1: ::c_int = 4; +@@ -1576,6 +2049,7 @@ cfg_if! { + + pub const MREMAP_MAYMOVE: ::c_int = 1; + pub const MREMAP_FIXED: ::c_int = 2; ++pub const MREMAP_DONTUNMAP: ::c_int = 4; + + pub const PR_SET_PDEATHSIG: ::c_int = 1; + pub const PR_GET_PDEATHSIG: ::c_int = 2; +@@ -1671,6 +2145,7 @@ pub const PR_SET_MM_MAP: ::c_int = 14; + pub const PR_SET_MM_MAP_SIZE: ::c_int = 15; + + pub const PR_SET_PTRACER: ::c_int = 0x59616d61; ++pub const PR_SET_PTRACER_ANY: ::c_ulong = 0xffffffffffffffff; + + pub const PR_SET_CHILD_SUBREAPER: ::c_int = 36; + pub const PR_GET_CHILD_SUBREAPER: ::c_int = 37; +@@ -1697,13 +2172,44 @@ pub const PR_CAP_AMBIENT_RAISE: ::c_int = 2; + pub const PR_CAP_AMBIENT_LOWER: ::c_int = 3; + pub const PR_CAP_AMBIENT_CLEAR_ALL: ::c_int = 4; + ++pub const PR_SET_VMA: ::c_int = 0x53564d41; ++pub const PR_SET_VMA_ANON_NAME: ::c_int = 0; ++ ++pub const PR_SCHED_CORE: ::c_int = 62; ++pub const PR_SCHED_CORE_GET: ::c_int = 0; ++pub const PR_SCHED_CORE_CREATE: ::c_int = 1; ++pub const PR_SCHED_CORE_SHARE_TO: ::c_int = 2; ++pub const PR_SCHED_CORE_SHARE_FROM: ::c_int = 3; ++pub const PR_SCHED_CORE_MAX: ::c_int = 4; ++pub const PR_SCHED_CORE_SCOPE_THREAD: ::c_int = 0; ++pub const PR_SCHED_CORE_SCOPE_THREAD_GROUP: ::c_int = 1; ++pub const PR_SCHED_CORE_SCOPE_PROCESS_GROUP: ::c_int = 2; ++ + pub const GRND_NONBLOCK: ::c_uint = 0x0001; + pub const GRND_RANDOM: ::c_uint = 0x0002; ++pub const GRND_INSECURE: ::c_uint = 0x0004; + + pub const SECCOMP_MODE_DISABLED: ::c_uint = 0; + pub const SECCOMP_MODE_STRICT: ::c_uint = 1; + pub const SECCOMP_MODE_FILTER: ::c_uint = 2; + ++pub const SECCOMP_FILTER_FLAG_TSYNC: ::c_ulong = 1; ++pub const SECCOMP_FILTER_FLAG_LOG: ::c_ulong = 2; ++pub const SECCOMP_FILTER_FLAG_SPEC_ALLOW: ::c_ulong = 4; ++ ++pub const SECCOMP_RET_KILL_PROCESS: ::c_uint = 0x80000000; ++pub const SECCOMP_RET_KILL_THREAD: ::c_uint = 0x00000000; ++pub const SECCOMP_RET_KILL: ::c_uint = SECCOMP_RET_KILL_THREAD; ++pub const SECCOMP_RET_TRAP: ::c_uint = 0x00030000; ++pub const SECCOMP_RET_ERRNO: ::c_uint = 0x00050000; ++pub const SECCOMP_RET_TRACE: ::c_uint = 0x7ff00000; ++pub const SECCOMP_RET_LOG: ::c_uint = 0x7ffc0000; ++pub const SECCOMP_RET_ALLOW: ::c_uint = 0x7fff0000; ++ ++pub const SECCOMP_RET_ACTION_FULL: ::c_uint = 0xffff0000; ++pub const SECCOMP_RET_ACTION: ::c_uint = 0x7fff0000; ++pub const SECCOMP_RET_DATA: ::c_uint = 0x0000ffff; ++ + pub const ITIMER_REAL: ::c_int = 0; + pub const ITIMER_VIRTUAL: ::c_int = 1; + pub const ITIMER_PROF: ::c_int = 2; +@@ -1711,6 +2217,7 @@ pub const ITIMER_PROF: ::c_int = 2; + pub const TFD_CLOEXEC: ::c_int = O_CLOEXEC; + pub const TFD_NONBLOCK: ::c_int = O_NONBLOCK; + pub const TFD_TIMER_ABSTIME: ::c_int = 1; ++pub const TFD_TIMER_CANCEL_ON_SET: ::c_int = 2; + + pub const _POSIX_VDISABLE: ::cc_t = 0; + +@@ -1742,6 +2249,17 @@ pub const IPV6_FLOWINFO_PRIORITY: ::c_int = 0x0ff00000; + pub const IPV6_RTHDR_LOOSE: ::c_int = 0; + pub const IPV6_RTHDR_STRICT: ::c_int = 1; + ++// SO_MEMINFO offsets ++pub const SK_MEMINFO_RMEM_ALLOC: ::c_int = 0; ++pub const SK_MEMINFO_RCVBUF: ::c_int = 1; ++pub const SK_MEMINFO_WMEM_ALLOC: ::c_int = 2; ++pub const SK_MEMINFO_SNDBUF: ::c_int = 3; ++pub const SK_MEMINFO_FWD_ALLOC: ::c_int = 4; ++pub const SK_MEMINFO_WMEM_QUEUED: ::c_int = 5; ++pub const SK_MEMINFO_OPTMEM: ::c_int = 6; ++pub const SK_MEMINFO_BACKLOG: ::c_int = 7; ++pub const SK_MEMINFO_DROPS: ::c_int = 8; ++ + pub const IUTF8: ::tcflag_t = 0x00004000; + #[cfg(not(all(target_env = "uclibc", target_arch = "mips")))] + pub const CMSPAR: ::tcflag_t = 0o10000000000; +@@ -1749,23 +2267,95 @@ pub const CMSPAR: ::tcflag_t = 0o10000000000; + pub const MFD_CLOEXEC: ::c_uint = 0x0001; + pub const MFD_ALLOW_SEALING: ::c_uint = 0x0002; + pub const MFD_HUGETLB: ::c_uint = 0x0004; +- +-// these are used in the p_type field of Elf32_Phdr and Elf64_Phdr, which has +-// the type Elf32Word and Elf64Word respectively. Luckily, both of those are u32 +-// so we can use that type here to avoid having to cast. +-pub const PT_NULL: u32 = 0; +-pub const PT_LOAD: u32 = 1; +-pub const PT_DYNAMIC: u32 = 2; +-pub const PT_INTERP: u32 = 3; +-pub const PT_NOTE: u32 = 4; +-pub const PT_SHLIB: u32 = 5; +-pub const PT_PHDR: u32 = 6; +-pub const PT_TLS: u32 = 7; +-pub const PT_NUM: u32 = 8; +-pub const PT_LOOS: u32 = 0x60000000; +-pub const PT_GNU_EH_FRAME: u32 = 0x6474e550; +-pub const PT_GNU_STACK: u32 = 0x6474e551; +-pub const PT_GNU_RELRO: u32 = 0x6474e552; ++pub const MFD_HUGE_64KB: ::c_uint = 0x40000000; ++pub const MFD_HUGE_512KB: ::c_uint = 0x4c000000; ++pub const MFD_HUGE_1MB: ::c_uint = 0x50000000; ++pub const MFD_HUGE_2MB: ::c_uint = 0x54000000; ++pub const MFD_HUGE_8MB: ::c_uint = 0x5c000000; ++pub const MFD_HUGE_16MB: ::c_uint = 0x60000000; ++pub const MFD_HUGE_32MB: ::c_uint = 0x64000000; ++pub const MFD_HUGE_256MB: ::c_uint = 0x70000000; ++pub const MFD_HUGE_512MB: ::c_uint = 0x74000000; ++pub const MFD_HUGE_1GB: ::c_uint = 0x78000000; ++pub const MFD_HUGE_2GB: ::c_uint = 0x7c000000; ++pub const MFD_HUGE_16GB: ::c_uint = 0x88000000; ++pub const MFD_HUGE_MASK: ::c_uint = 63; ++pub const MFD_HUGE_SHIFT: ::c_uint = 26; ++ ++// linux/close_range.h ++pub const CLOSE_RANGE_UNSHARE: ::c_uint = 1 << 1; ++pub const CLOSE_RANGE_CLOEXEC: ::c_uint = 1 << 2; ++ ++// linux/filter.h ++pub const SKF_AD_OFF: ::c_int = -0x1000; ++pub const SKF_AD_PROTOCOL: ::c_int = 0; ++pub const SKF_AD_PKTTYPE: ::c_int = 4; ++pub const SKF_AD_IFINDEX: ::c_int = 8; ++pub const SKF_AD_NLATTR: ::c_int = 12; ++pub const SKF_AD_NLATTR_NEST: ::c_int = 16; ++pub const SKF_AD_MARK: ::c_int = 20; ++pub const SKF_AD_QUEUE: ::c_int = 24; ++pub const SKF_AD_HATYPE: ::c_int = 28; ++pub const SKF_AD_RXHASH: ::c_int = 32; ++pub const SKF_AD_CPU: ::c_int = 36; ++pub const SKF_AD_ALU_XOR_X: ::c_int = 40; ++pub const SKF_AD_VLAN_TAG: ::c_int = 44; ++pub const SKF_AD_VLAN_TAG_PRESENT: ::c_int = 48; ++pub const SKF_AD_PAY_OFFSET: ::c_int = 52; ++pub const SKF_AD_RANDOM: ::c_int = 56; ++pub const SKF_AD_VLAN_TPID: ::c_int = 60; ++pub const SKF_AD_MAX: ::c_int = 64; ++pub const SKF_NET_OFF: ::c_int = -0x100000; ++pub const SKF_LL_OFF: ::c_int = -0x200000; ++pub const BPF_NET_OFF: ::c_int = SKF_NET_OFF; ++pub const BPF_LL_OFF: ::c_int = SKF_LL_OFF; ++pub const BPF_MEMWORDS: ::c_int = 16; ++pub const BPF_MAXINSNS: ::c_int = 4096; ++ ++// linux/bpf_common.h ++pub const BPF_LD: ::__u32 = 0x00; ++pub const BPF_LDX: ::__u32 = 0x01; ++pub const BPF_ST: ::__u32 = 0x02; ++pub const BPF_STX: ::__u32 = 0x03; ++pub const BPF_ALU: ::__u32 = 0x04; ++pub const BPF_JMP: ::__u32 = 0x05; ++pub const BPF_RET: ::__u32 = 0x06; ++pub const BPF_MISC: ::__u32 = 0x07; ++pub const BPF_W: ::__u32 = 0x00; ++pub const BPF_H: ::__u32 = 0x08; ++pub const BPF_B: ::__u32 = 0x10; ++pub const BPF_IMM: ::__u32 = 0x00; ++pub const BPF_ABS: ::__u32 = 0x20; ++pub const BPF_IND: ::__u32 = 0x40; ++pub const BPF_MEM: ::__u32 = 0x60; ++pub const BPF_LEN: ::__u32 = 0x80; ++pub const BPF_MSH: ::__u32 = 0xa0; ++pub const BPF_ADD: ::__u32 = 0x00; ++pub const BPF_SUB: ::__u32 = 0x10; ++pub const BPF_MUL: ::__u32 = 0x20; ++pub const BPF_DIV: ::__u32 = 0x30; ++pub const BPF_OR: ::__u32 = 0x40; ++pub const BPF_AND: ::__u32 = 0x50; ++pub const BPF_LSH: ::__u32 = 0x60; ++pub const BPF_RSH: ::__u32 = 0x70; ++pub const BPF_NEG: ::__u32 = 0x80; ++pub const BPF_MOD: ::__u32 = 0x90; ++pub const BPF_XOR: ::__u32 = 0xa0; ++pub const BPF_JA: ::__u32 = 0x00; ++pub const BPF_JEQ: ::__u32 = 0x10; ++pub const BPF_JGT: ::__u32 = 0x20; ++pub const BPF_JGE: ::__u32 = 0x30; ++pub const BPF_JSET: ::__u32 = 0x40; ++pub const BPF_K: ::__u32 = 0x00; ++pub const BPF_X: ::__u32 = 0x08; ++ ++// linux/openat2.h ++pub const RESOLVE_NO_XDEV: ::__u64 = 0x01; ++pub const RESOLVE_NO_MAGICLINKS: ::__u64 = 0x02; ++pub const RESOLVE_NO_SYMLINKS: ::__u64 = 0x04; ++pub const RESOLVE_BENEATH: ::__u64 = 0x08; ++pub const RESOLVE_IN_ROOT: ::__u64 = 0x10; ++pub const RESOLVE_CACHED: ::__u64 = 0x20; + + // linux/if_ether.h + pub const ETH_ALEN: ::c_int = 6; +@@ -1882,6 +2472,7 @@ pub const NFNLGRP_CONNTRACK_EXP_UPDATE: ::c_int = 5; + pub const NFNLGRP_CONNTRACK_EXP_DESTROY: ::c_int = 6; + pub const NFNLGRP_NFTABLES: ::c_int = 7; + pub const NFNLGRP_ACCT_QUOTA: ::c_int = 8; ++pub const NFNLGRP_NFTRACE: ::c_int = 9; + + pub const NFNETLINK_V0: ::c_int = 0; + +@@ -1897,15 +2488,23 @@ pub const NFNL_SUBSYS_CTNETLINK_TIMEOUT: ::c_int = 8; + pub const NFNL_SUBSYS_CTHELPER: ::c_int = 9; + pub const NFNL_SUBSYS_NFTABLES: ::c_int = 10; + pub const NFNL_SUBSYS_NFT_COMPAT: ::c_int = 11; +-pub const NFNL_SUBSYS_COUNT: ::c_int = 12; ++pub const NFNL_SUBSYS_HOOK: ::c_int = 12; ++pub const NFNL_SUBSYS_COUNT: ::c_int = 13; + + pub const NFNL_MSG_BATCH_BEGIN: ::c_int = NLMSG_MIN_TYPE; + pub const NFNL_MSG_BATCH_END: ::c_int = NLMSG_MIN_TYPE + 1; + ++pub const NFNL_BATCH_UNSPEC: ::c_int = 0; ++pub const NFNL_BATCH_GENID: ::c_int = 1; ++ + // linux/netfilter/nfnetlink_log.h + pub const NFULNL_MSG_PACKET: ::c_int = 0; + pub const NFULNL_MSG_CONFIG: ::c_int = 1; + ++pub const NFULA_VLAN_UNSPEC: ::c_int = 0; ++pub const NFULA_VLAN_PROTO: ::c_int = 1; ++pub const NFULA_VLAN_TCI: ::c_int = 2; ++ + pub const NFULA_UNSPEC: ::c_int = 0; + pub const NFULA_PACKET_HDR: ::c_int = 1; + pub const NFULA_MARK: ::c_int = 2; +@@ -1926,6 +2525,8 @@ pub const NFULA_HWHEADER: ::c_int = 16; + pub const NFULA_HWLEN: ::c_int = 17; + pub const NFULA_CT: ::c_int = 18; + pub const NFULA_CT_INFO: ::c_int = 19; ++pub const NFULA_VLAN: ::c_int = 20; ++pub const NFULA_L2HDR: ::c_int = 21; + + pub const NFULNL_CFG_CMD_NONE: ::c_int = 0; + pub const NFULNL_CFG_CMD_BIND: ::c_int = 1; +@@ -1949,7 +2550,7 @@ pub const NFULNL_CFG_F_SEQ: ::c_int = 0x0001; + pub const NFULNL_CFG_F_SEQ_GLOBAL: ::c_int = 0x0002; + pub const NFULNL_CFG_F_CONNTRACK: ::c_int = 0x0004; + +-// linux/netfilter/nfnetlink_log.h ++// linux/netfilter/nfnetlink_queue.h + pub const NFQNL_MSG_PACKET: ::c_int = 0; + pub const NFQNL_MSG_VERDICT: ::c_int = 1; + pub const NFQNL_MSG_CONFIG: ::c_int = 2; +@@ -1974,18 +2575,13 @@ pub const NFQA_EXP: ::c_int = 15; + pub const NFQA_UID: ::c_int = 16; + pub const NFQA_GID: ::c_int = 17; + pub const NFQA_SECCTX: ::c_int = 18; +-/* +- FIXME: These are not yet available in musl sanitized kernel headers and +- make the tests fail. Enable them once musl has them. +- +- See https://github.com/rust-lang/libc/pull/1628 for more details. + pub const NFQA_VLAN: ::c_int = 19; + pub const NFQA_L2HDR: ::c_int = 20; ++pub const NFQA_PRIORITY: ::c_int = 21; + + pub const NFQA_VLAN_UNSPEC: ::c_int = 0; + pub const NFQA_VLAN_PROTO: ::c_int = 1; + pub const NFQA_VLAN_TCI: ::c_int = 2; +-*/ + + pub const NFQNL_CFG_CMD_NONE: ::c_int = 0; + pub const NFQNL_CFG_CMD_BIND: ::c_int = 1; +@@ -2015,6 +2611,8 @@ pub const NFQA_SKB_CSUMNOTREADY: ::c_int = 0x0001; + pub const NFQA_SKB_GSO: ::c_int = 0x0002; + pub const NFQA_SKB_CSUM_NOTVERIFIED: ::c_int = 0x0004; + ++// linux/genetlink.h ++ + pub const GENL_NAMSIZ: ::c_int = 16; + + pub const GENL_MIN_ID: ::c_int = NLMSG_MIN_TYPE; +@@ -2178,6 +2776,24 @@ pub const SIOCGIFSLAVE: ::c_ulong = 0x00008929; + pub const SIOCSIFSLAVE: ::c_ulong = 0x00008930; + pub const SIOCADDMULTI: ::c_ulong = 0x00008931; + pub const SIOCDELMULTI: ::c_ulong = 0x00008932; ++pub const SIOCGIFINDEX: ::c_ulong = 0x00008933; ++pub const SIOGIFINDEX: ::c_ulong = SIOCGIFINDEX; ++pub const SIOCSIFPFLAGS: ::c_ulong = 0x00008934; ++pub const SIOCGIFPFLAGS: ::c_ulong = 0x00008935; ++pub const SIOCDIFADDR: ::c_ulong = 0x00008936; ++pub const SIOCSIFHWBROADCAST: ::c_ulong = 0x00008937; ++pub const SIOCGIFCOUNT: ::c_ulong = 0x00008938; ++pub const SIOCGIFBR: ::c_ulong = 0x00008940; ++pub const SIOCSIFBR: ::c_ulong = 0x00008941; ++pub const SIOCGIFTXQLEN: ::c_ulong = 0x00008942; ++pub const SIOCSIFTXQLEN: ::c_ulong = 0x00008943; ++pub const SIOCETHTOOL: ::c_ulong = 0x00008946; ++pub const SIOCGMIIPHY: ::c_ulong = 0x00008947; ++pub const SIOCGMIIREG: ::c_ulong = 0x00008948; ++pub const SIOCSMIIREG: ::c_ulong = 0x00008949; ++pub const SIOCWANDEV: ::c_ulong = 0x0000894A; ++pub const SIOCOUTQNSD: ::c_ulong = 0x0000894B; ++pub const SIOCGSKNS: ::c_ulong = 0x0000894C; + pub const SIOCDARP: ::c_ulong = 0x00008953; + pub const SIOCGARP: ::c_ulong = 0x00008954; + pub const SIOCSARP: ::c_ulong = 0x00008955; +@@ -2186,6 +2802,8 @@ pub const SIOCGRARP: ::c_ulong = 0x00008961; + pub const SIOCSRARP: ::c_ulong = 0x00008962; + pub const SIOCGIFMAP: ::c_ulong = 0x00008970; + pub const SIOCSIFMAP: ::c_ulong = 0x00008971; ++pub const SIOCSHWTSTAMP: ::c_ulong = 0x000089b0; ++pub const SIOCGHWTSTAMP: ::c_ulong = 0x000089b1; + + pub const IPTOS_TOS_MASK: u8 = 0x1E; + pub const IPTOS_PREC_MASK: u8 = 0xE0; +@@ -2319,6 +2937,8 @@ pub const NETLINK_TX_RING: ::c_int = 7; + pub const NETLINK_LISTEN_ALL_NSID: ::c_int = 8; + pub const NETLINK_LIST_MEMBERSHIPS: ::c_int = 9; + pub const NETLINK_CAP_ACK: ::c_int = 10; ++pub const NETLINK_EXT_ACK: ::c_int = 11; ++pub const NETLINK_GET_STRICT_CHK: ::c_int = 12; + + pub const NLA_F_NESTED: ::c_int = 1 << 15; + pub const NLA_F_NET_BYTEORDER: ::c_int = 1 << 14; +@@ -2455,6 +3075,70 @@ pub const ARPD_LOOKUP: ::c_ushort = 0x02; + pub const ARPD_FLUSH: ::c_ushort = 0x03; + pub const ATF_MAGIC: ::c_int = 0x80; + ++pub const RTEXT_FILTER_VF: ::c_int = 1 << 0; ++pub const RTEXT_FILTER_BRVLAN: ::c_int = 1 << 1; ++pub const RTEXT_FILTER_BRVLAN_COMPRESSED: ::c_int = 1 << 2; ++pub const RTEXT_FILTER_SKIP_STATS: ::c_int = 1 << 3; ++pub const RTEXT_FILTER_MRP: ::c_int = 1 << 4; ++pub const RTEXT_FILTER_CFM_CONFIG: ::c_int = 1 << 5; ++pub const RTEXT_FILTER_CFM_STATUS: ::c_int = 1 << 6; ++ ++// userspace compat definitions for RTNLGRP_* ++pub const RTMGRP_LINK: ::c_int = 0x00001; ++pub const RTMGRP_NOTIFY: ::c_int = 0x00002; ++pub const RTMGRP_NEIGH: ::c_int = 0x00004; ++pub const RTMGRP_TC: ::c_int = 0x00008; ++pub const RTMGRP_IPV4_IFADDR: ::c_int = 0x00010; ++pub const RTMGRP_IPV4_MROUTE: ::c_int = 0x00020; ++pub const RTMGRP_IPV4_ROUTE: ::c_int = 0x00040; ++pub const RTMGRP_IPV4_RULE: ::c_int = 0x00080; ++pub const RTMGRP_IPV6_IFADDR: ::c_int = 0x00100; ++pub const RTMGRP_IPV6_MROUTE: ::c_int = 0x00200; ++pub const RTMGRP_IPV6_ROUTE: ::c_int = 0x00400; ++pub const RTMGRP_IPV6_IFINFO: ::c_int = 0x00800; ++pub const RTMGRP_DECnet_IFADDR: ::c_int = 0x01000; ++pub const RTMGRP_DECnet_ROUTE: ::c_int = 0x04000; ++pub const RTMGRP_IPV6_PREFIX: ::c_int = 0x20000; ++ ++// enum rtnetlink_groups ++pub const RTNLGRP_NONE: ::c_uint = 0x00; ++pub const RTNLGRP_LINK: ::c_uint = 0x01; ++pub const RTNLGRP_NOTIFY: ::c_uint = 0x02; ++pub const RTNLGRP_NEIGH: ::c_uint = 0x03; ++pub const RTNLGRP_TC: ::c_uint = 0x04; ++pub const RTNLGRP_IPV4_IFADDR: ::c_uint = 0x05; ++pub const RTNLGRP_IPV4_MROUTE: ::c_uint = 0x06; ++pub const RTNLGRP_IPV4_ROUTE: ::c_uint = 0x07; ++pub const RTNLGRP_IPV4_RULE: ::c_uint = 0x08; ++pub const RTNLGRP_IPV6_IFADDR: ::c_uint = 0x09; ++pub const RTNLGRP_IPV6_MROUTE: ::c_uint = 0x0a; ++pub const RTNLGRP_IPV6_ROUTE: ::c_uint = 0x0b; ++pub const RTNLGRP_IPV6_IFINFO: ::c_uint = 0x0c; ++pub const RTNLGRP_DECnet_IFADDR: ::c_uint = 0x0d; ++pub const RTNLGRP_NOP2: ::c_uint = 0x0e; ++pub const RTNLGRP_DECnet_ROUTE: ::c_uint = 0x0f; ++pub const RTNLGRP_DECnet_RULE: ::c_uint = 0x10; ++pub const RTNLGRP_NOP4: ::c_uint = 0x11; ++pub const RTNLGRP_IPV6_PREFIX: ::c_uint = 0x12; ++pub const RTNLGRP_IPV6_RULE: ::c_uint = 0x13; ++pub const RTNLGRP_ND_USEROPT: ::c_uint = 0x14; ++pub const RTNLGRP_PHONET_IFADDR: ::c_uint = 0x15; ++pub const RTNLGRP_PHONET_ROUTE: ::c_uint = 0x16; ++pub const RTNLGRP_DCB: ::c_uint = 0x17; ++pub const RTNLGRP_IPV4_NETCONF: ::c_uint = 0x18; ++pub const RTNLGRP_IPV6_NETCONF: ::c_uint = 0x19; ++pub const RTNLGRP_MDB: ::c_uint = 0x1a; ++pub const RTNLGRP_MPLS_ROUTE: ::c_uint = 0x1b; ++pub const RTNLGRP_NSID: ::c_uint = 0x1c; ++pub const RTNLGRP_MPLS_NETCONF: ::c_uint = 0x1d; ++pub const RTNLGRP_IPV4_MROUTE_R: ::c_uint = 0x1e; ++pub const RTNLGRP_IPV6_MROUTE_R: ::c_uint = 0x1f; ++pub const RTNLGRP_NEXTHOP: ::c_uint = 0x20; ++pub const RTNLGRP_BRVLAN: ::c_uint = 0x21; ++pub const RTNLGRP_MCTP_IFADDR: ::c_uint = 0x22; ++pub const RTNLGRP_TUNNEL: ::c_uint = 0x23; ++pub const RTNLGRP_STATS: ::c_uint = 0x24; ++ + // linux/module.h + pub const MODULE_INIT_IGNORE_MODVERSIONS: ::c_uint = 0x0001; + pub const MODULE_INIT_IGNORE_VERMAGIC: ::c_uint = 0x0002; +@@ -2467,6 +3151,38 @@ pub const SOF_TIMESTAMPING_RX_SOFTWARE: ::c_uint = 1 << 3; + pub const SOF_TIMESTAMPING_SOFTWARE: ::c_uint = 1 << 4; + pub const SOF_TIMESTAMPING_SYS_HARDWARE: ::c_uint = 1 << 5; + pub const SOF_TIMESTAMPING_RAW_HARDWARE: ::c_uint = 1 << 6; ++pub const SOF_TIMESTAMPING_OPT_ID: ::c_uint = 1 << 7; ++pub const SOF_TIMESTAMPING_TX_SCHED: ::c_uint = 1 << 8; ++pub const SOF_TIMESTAMPING_TX_ACK: ::c_uint = 1 << 9; ++pub const SOF_TIMESTAMPING_OPT_CMSG: ::c_uint = 1 << 10; ++pub const SOF_TIMESTAMPING_OPT_TSONLY: ::c_uint = 1 << 11; ++pub const SOF_TIMESTAMPING_OPT_STATS: ::c_uint = 1 << 12; ++pub const SOF_TIMESTAMPING_OPT_PKTINFO: ::c_uint = 1 << 13; ++pub const SOF_TIMESTAMPING_OPT_TX_SWHW: ::c_uint = 1 << 14; ++pub const SOF_TXTIME_DEADLINE_MODE: u32 = 1 << 0; ++pub const SOF_TXTIME_REPORT_ERRORS: u32 = 1 << 1; ++ ++pub const HWTSTAMP_TX_OFF: ::c_uint = 0; ++pub const HWTSTAMP_TX_ON: ::c_uint = 1; ++pub const HWTSTAMP_TX_ONESTEP_SYNC: ::c_uint = 2; ++pub const HWTSTAMP_TX_ONESTEP_P2P: ::c_uint = 3; ++ ++pub const HWTSTAMP_FILTER_NONE: ::c_uint = 0; ++pub const HWTSTAMP_FILTER_ALL: ::c_uint = 1; ++pub const HWTSTAMP_FILTER_SOME: ::c_uint = 2; ++pub const HWTSTAMP_FILTER_PTP_V1_L4_EVENT: ::c_uint = 3; ++pub const HWTSTAMP_FILTER_PTP_V1_L4_SYNC: ::c_uint = 4; ++pub const HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: ::c_uint = 5; ++pub const HWTSTAMP_FILTER_PTP_V2_L4_EVENT: ::c_uint = 6; ++pub const HWTSTAMP_FILTER_PTP_V2_L4_SYNC: ::c_uint = 7; ++pub const HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: ::c_uint = 8; ++pub const HWTSTAMP_FILTER_PTP_V2_L2_EVENT: ::c_uint = 9; ++pub const HWTSTAMP_FILTER_PTP_V2_L2_SYNC: ::c_uint = 10; ++pub const HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: ::c_uint = 11; ++pub const HWTSTAMP_FILTER_PTP_V2_EVENT: ::c_uint = 12; ++pub const HWTSTAMP_FILTER_PTP_V2_SYNC: ::c_uint = 13; ++pub const HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: ::c_uint = 14; ++pub const HWTSTAMP_FILTER_NTP_ALL: ::c_uint = 15; + + // linux/if_alg.h + pub const ALG_SET_KEY: ::c_int = 1; +@@ -2489,6 +3205,7 @@ pub const MAP_SHARED_VALIDATE: ::c_int = 0x3; + + // include/uapi/asm-generic/mman-common.h + pub const MAP_FIXED_NOREPLACE: ::c_int = 0x100000; ++pub const MLOCK_ONFAULT: ::c_uint = 0x01; + + // uapi/linux/vm_sockets.h + pub const VMADDR_CID_ANY: ::c_uint = 0xFFFFFFFF; +@@ -2523,7 +3240,7 @@ pub const IN_Q_OVERFLOW: u32 = 0x0000_4000; + pub const IN_IGNORED: u32 = 0x0000_8000; + pub const IN_ONLYDIR: u32 = 0x0100_0000; + pub const IN_DONT_FOLLOW: u32 = 0x0200_0000; +-// pub const IN_EXCL_UNLINK: u32 = 0x0400_0000; ++pub const IN_EXCL_UNLINK: u32 = 0x0400_0000; + + // linux/keyctl.h + pub const KEY_SPEC_THREAD_KEYRING: i32 = -1; +@@ -2569,8 +3286,8 @@ pub const KEYCTL_INSTANTIATE_IOV: u32 = 20; + pub const KEYCTL_INVALIDATE: u32 = 21; + pub const KEYCTL_GET_PERSISTENT: u32 = 22; + +-// pub const IN_MASK_CREATE: u32 = 0x1000_0000; +-// pub const IN_MASK_ADD: u32 = 0x2000_0000; ++pub const IN_MASK_CREATE: u32 = 0x1000_0000; ++pub const IN_MASK_ADD: u32 = 0x2000_0000; + pub const IN_ISDIR: u32 = 0x4000_0000; + pub const IN_ONESHOT: u32 = 0x8000_0000; + +@@ -2590,6 +3307,10 @@ pub const IN_ALL_EVENTS: u32 = IN_ACCESS + pub const IN_CLOEXEC: ::c_int = O_CLOEXEC; + pub const IN_NONBLOCK: ::c_int = O_NONBLOCK; + ++// uapi/linux/mount.h ++pub const OPEN_TREE_CLONE: ::c_uint = 0x01; ++pub const OPEN_TREE_CLOEXEC: ::c_uint = O_CLOEXEC as ::c_uint; ++ + // uapi/linux/netfilter/nf_tables.h + pub const NFT_TABLE_MAXNAMELEN: ::c_int = 256; + pub const NFT_CHAIN_MAXNAMELEN: ::c_int = 256; +@@ -2865,11 +3586,41 @@ pub const FUTEX_WAIT_BITSET: ::c_int = 9; + pub const FUTEX_WAKE_BITSET: ::c_int = 10; + pub const FUTEX_WAIT_REQUEUE_PI: ::c_int = 11; + pub const FUTEX_CMP_REQUEUE_PI: ::c_int = 12; ++pub const FUTEX_LOCK_PI2: ::c_int = 13; + + pub const FUTEX_PRIVATE_FLAG: ::c_int = 128; + pub const FUTEX_CLOCK_REALTIME: ::c_int = 256; + pub const FUTEX_CMD_MASK: ::c_int = !(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME); + ++pub const FUTEX_BITSET_MATCH_ANY: ::c_int = 0xffffffff; ++ ++pub const FUTEX_OP_SET: ::c_int = 0; ++pub const FUTEX_OP_ADD: ::c_int = 1; ++pub const FUTEX_OP_OR: ::c_int = 2; ++pub const FUTEX_OP_ANDN: ::c_int = 3; ++pub const FUTEX_OP_XOR: ::c_int = 4; ++ ++pub const FUTEX_OP_OPARG_SHIFT: ::c_int = 8; ++ ++pub const FUTEX_OP_CMP_EQ: ::c_int = 0; ++pub const FUTEX_OP_CMP_NE: ::c_int = 1; ++pub const FUTEX_OP_CMP_LT: ::c_int = 2; ++pub const FUTEX_OP_CMP_LE: ::c_int = 3; ++pub const FUTEX_OP_CMP_GT: ::c_int = 4; ++pub const FUTEX_OP_CMP_GE: ::c_int = 5; ++ ++pub fn FUTEX_OP(op: ::c_int, oparg: ::c_int, cmp: ::c_int, cmparg: ::c_int) -> ::c_int { ++ ((op & 0xf) << 28) | ((cmp & 0xf) << 24) | ((oparg & 0xfff) << 12) | (cmparg & 0xfff) ++} ++ ++// linux/kexec.h ++pub const KEXEC_ON_CRASH: ::c_int = 0x00000001; ++pub const KEXEC_PRESERVE_CONTEXT: ::c_int = 0x00000002; ++pub const KEXEC_ARCH_MASK: ::c_int = 0xffff0000; ++pub const KEXEC_FILE_UNLOAD: ::c_int = 0x00000001; ++pub const KEXEC_FILE_ON_CRASH: ::c_int = 0x00000002; ++pub const KEXEC_FILE_NO_INITRAMFS: ::c_int = 0x00000004; ++ + // linux/reboot.h + pub const LINUX_REBOOT_MAGIC1: ::c_int = 0xfee1dead; + pub const LINUX_REBOOT_MAGIC2: ::c_int = 672274793; +@@ -2994,6 +3745,153 @@ pub const SOL_CAN_BASE: ::c_int = 100; + pub const CAN_INV_FILTER: canid_t = 0x20000000; + pub const CAN_RAW_FILTER_MAX: ::c_int = 512; + ++// linux/can/raw.h ++pub const SOL_CAN_RAW: ::c_int = SOL_CAN_BASE + CAN_RAW; ++pub const CAN_RAW_FILTER: ::c_int = 1; ++pub const CAN_RAW_ERR_FILTER: ::c_int = 2; ++pub const CAN_RAW_LOOPBACK: ::c_int = 3; ++pub const CAN_RAW_RECV_OWN_MSGS: ::c_int = 4; ++pub const CAN_RAW_FD_FRAMES: ::c_int = 5; ++pub const CAN_RAW_JOIN_FILTERS: ::c_int = 6; ++ ++// linux/can/j1939.h ++pub const SOL_CAN_J1939: ::c_int = SOL_CAN_BASE + CAN_J1939; ++ ++pub const J1939_MAX_UNICAST_ADDR: ::c_uchar = 0xfd; ++pub const J1939_IDLE_ADDR: ::c_uchar = 0xfe; ++pub const J1939_NO_ADDR: ::c_uchar = 0xff; ++pub const J1939_NO_NAME: ::c_ulong = 0; ++pub const J1939_PGN_REQUEST: ::c_uint = 0x0ea00; ++pub const J1939_PGN_ADDRESS_CLAIMED: ::c_uint = 0x0ee00; ++pub const J1939_PGN_ADDRESS_COMMANDED: ::c_uint = 0x0fed8; ++pub const J1939_PGN_PDU1_MAX: ::c_uint = 0x3ff00; ++pub const J1939_PGN_MAX: ::c_uint = 0x3ffff; ++pub const J1939_NO_PGN: ::c_uint = 0x40000; ++ ++pub const SO_J1939_FILTER: ::c_int = 1; ++pub const SO_J1939_PROMISC: ::c_int = 2; ++pub const SO_J1939_SEND_PRIO: ::c_int = 3; ++pub const SO_J1939_ERRQUEUE: ::c_int = 4; ++ ++pub const SCM_J1939_DEST_ADDR: ::c_int = 1; ++pub const SCM_J1939_DEST_NAME: ::c_int = 2; ++pub const SCM_J1939_PRIO: ::c_int = 3; ++pub const SCM_J1939_ERRQUEUE: ::c_int = 4; ++ ++pub const J1939_NLA_PAD: ::c_int = 0; ++pub const J1939_NLA_BYTES_ACKED: ::c_int = 1; ++pub const J1939_NLA_TOTAL_SIZE: ::c_int = 2; ++pub const J1939_NLA_PGN: ::c_int = 3; ++pub const J1939_NLA_SRC_NAME: ::c_int = 4; ++pub const J1939_NLA_DEST_NAME: ::c_int = 5; ++pub const J1939_NLA_SRC_ADDR: ::c_int = 6; ++pub const J1939_NLA_DEST_ADDR: ::c_int = 7; ++ ++pub const J1939_EE_INFO_NONE: ::c_int = 0; ++pub const J1939_EE_INFO_TX_ABORT: ::c_int = 1; ++pub const J1939_EE_INFO_RX_RTS: ::c_int = 2; ++pub const J1939_EE_INFO_RX_DPO: ::c_int = 3; ++pub const J1939_EE_INFO_RX_ABORT: ::c_int = 4; ++ ++pub const J1939_FILTER_MAX: ::c_int = 512; ++ ++// linux/sctp.h ++pub const SCTP_FUTURE_ASSOC: ::c_int = 0; ++pub const SCTP_CURRENT_ASSOC: ::c_int = 1; ++pub const SCTP_ALL_ASSOC: ::c_int = 2; ++pub const SCTP_RTOINFO: ::c_int = 0; ++pub const SCTP_ASSOCINFO: ::c_int = 1; ++pub const SCTP_INITMSG: ::c_int = 2; ++pub const SCTP_NODELAY: ::c_int = 3; ++pub const SCTP_AUTOCLOSE: ::c_int = 4; ++pub const SCTP_SET_PEER_PRIMARY_ADDR: ::c_int = 5; ++pub const SCTP_PRIMARY_ADDR: ::c_int = 6; ++pub const SCTP_ADAPTATION_LAYER: ::c_int = 7; ++pub const SCTP_DISABLE_FRAGMENTS: ::c_int = 8; ++pub const SCTP_PEER_ADDR_PARAMS: ::c_int = 9; ++pub const SCTP_DEFAULT_SEND_PARAM: ::c_int = 10; ++pub const SCTP_EVENTS: ::c_int = 11; ++pub const SCTP_I_WANT_MAPPED_V4_ADDR: ::c_int = 12; ++pub const SCTP_MAXSEG: ::c_int = 13; ++pub const SCTP_STATUS: ::c_int = 14; ++pub const SCTP_GET_PEER_ADDR_INFO: ::c_int = 15; ++pub const SCTP_DELAYED_ACK_TIME: ::c_int = 16; ++pub const SCTP_DELAYED_ACK: ::c_int = SCTP_DELAYED_ACK_TIME; ++pub const SCTP_DELAYED_SACK: ::c_int = SCTP_DELAYED_ACK_TIME; ++pub const SCTP_CONTEXT: ::c_int = 17; ++pub const SCTP_FRAGMENT_INTERLEAVE: ::c_int = 18; ++pub const SCTP_PARTIAL_DELIVERY_POINT: ::c_int = 19; ++pub const SCTP_MAX_BURST: ::c_int = 20; ++pub const SCTP_AUTH_CHUNK: ::c_int = 21; ++pub const SCTP_HMAC_IDENT: ::c_int = 22; ++pub const SCTP_AUTH_KEY: ::c_int = 23; ++pub const SCTP_AUTH_ACTIVE_KEY: ::c_int = 24; ++pub const SCTP_AUTH_DELETE_KEY: ::c_int = 25; ++pub const SCTP_PEER_AUTH_CHUNKS: ::c_int = 26; ++pub const SCTP_LOCAL_AUTH_CHUNKS: ::c_int = 27; ++pub const SCTP_GET_ASSOC_NUMBER: ::c_int = 28; ++pub const SCTP_GET_ASSOC_ID_LIST: ::c_int = 29; ++pub const SCTP_AUTO_ASCONF: ::c_int = 30; ++pub const SCTP_PEER_ADDR_THLDS: ::c_int = 31; ++pub const SCTP_RECVRCVINFO: ::c_int = 32; ++pub const SCTP_RECVNXTINFO: ::c_int = 33; ++pub const SCTP_DEFAULT_SNDINFO: ::c_int = 34; ++pub const SCTP_AUTH_DEACTIVATE_KEY: ::c_int = 35; ++pub const SCTP_REUSE_PORT: ::c_int = 36; ++pub const SCTP_PEER_ADDR_THLDS_V2: ::c_int = 37; ++pub const SCTP_PR_SCTP_NONE: ::c_int = 0x0000; ++pub const SCTP_PR_SCTP_TTL: ::c_int = 0x0010; ++pub const SCTP_PR_SCTP_RTX: ::c_int = 0x0020; ++pub const SCTP_PR_SCTP_PRIO: ::c_int = 0x0030; ++pub const SCTP_PR_SCTP_MAX: ::c_int = SCTP_PR_SCTP_PRIO; ++pub const SCTP_PR_SCTP_MASK: ::c_int = 0x0030; ++pub const SCTP_ENABLE_RESET_STREAM_REQ: ::c_int = 0x01; ++pub const SCTP_ENABLE_RESET_ASSOC_REQ: ::c_int = 0x02; ++pub const SCTP_ENABLE_CHANGE_ASSOC_REQ: ::c_int = 0x04; ++pub const SCTP_ENABLE_STRRESET_MASK: ::c_int = 0x07; ++pub const SCTP_STREAM_RESET_INCOMING: ::c_int = 0x01; ++pub const SCTP_STREAM_RESET_OUTGOING: ::c_int = 0x02; ++ ++pub const SCTP_INIT: ::c_int = 0; ++pub const SCTP_SNDRCV: ::c_int = 1; ++pub const SCTP_SNDINFO: ::c_int = 2; ++pub const SCTP_RCVINFO: ::c_int = 3; ++pub const SCTP_NXTINFO: ::c_int = 4; ++pub const SCTP_PRINFO: ::c_int = 5; ++pub const SCTP_AUTHINFO: ::c_int = 6; ++pub const SCTP_DSTADDRV4: ::c_int = 7; ++pub const SCTP_DSTADDRV6: ::c_int = 8; ++ ++pub const SCTP_UNORDERED: ::c_int = 1 << 0; ++pub const SCTP_ADDR_OVER: ::c_int = 1 << 1; ++pub const SCTP_ABORT: ::c_int = 1 << 2; ++pub const SCTP_SACK_IMMEDIATELY: ::c_int = 1 << 3; ++pub const SCTP_SENDALL: ::c_int = 1 << 6; ++pub const SCTP_PR_SCTP_ALL: ::c_int = 1 << 7; ++pub const SCTP_NOTIFICATION: ::c_int = MSG_NOTIFICATION; ++pub const SCTP_EOF: ::c_int = ::MSG_FIN; ++ ++/* DCCP socket options */ ++pub const DCCP_SOCKOPT_PACKET_SIZE: ::c_int = 1; ++pub const DCCP_SOCKOPT_SERVICE: ::c_int = 2; ++pub const DCCP_SOCKOPT_CHANGE_L: ::c_int = 3; ++pub const DCCP_SOCKOPT_CHANGE_R: ::c_int = 4; ++pub const DCCP_SOCKOPT_GET_CUR_MPS: ::c_int = 5; ++pub const DCCP_SOCKOPT_SERVER_TIMEWAIT: ::c_int = 6; ++pub const DCCP_SOCKOPT_SEND_CSCOV: ::c_int = 10; ++pub const DCCP_SOCKOPT_RECV_CSCOV: ::c_int = 11; ++pub const DCCP_SOCKOPT_AVAILABLE_CCIDS: ::c_int = 12; ++pub const DCCP_SOCKOPT_CCID: ::c_int = 13; ++pub const DCCP_SOCKOPT_TX_CCID: ::c_int = 14; ++pub const DCCP_SOCKOPT_RX_CCID: ::c_int = 15; ++pub const DCCP_SOCKOPT_QPOLICY_ID: ::c_int = 16; ++pub const DCCP_SOCKOPT_QPOLICY_TXQLEN: ::c_int = 17; ++pub const DCCP_SOCKOPT_CCID_RX_INFO: ::c_int = 128; ++pub const DCCP_SOCKOPT_CCID_TX_INFO: ::c_int = 192; ++ ++/// maximum number of services provided on the same listening port ++pub const DCCP_SERVICE_LIST_MAX_LEN: ::c_int = 32; ++ + f! { + pub fn NLA_ALIGN(len: ::c_int) -> ::c_int { + return ((len) + NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1) +@@ -3069,6 +3967,20 @@ f! { + set1.bits == set2.bits + } + ++ pub fn SCTP_PR_INDEX(policy: ::c_int) -> ::c_int { ++ policy >> 4 - 1 ++ } ++ ++ pub fn SCTP_PR_POLICY(policy: ::c_int) -> ::c_int { ++ policy & SCTP_PR_SCTP_MASK ++ } ++ ++ pub fn SCTP_PR_SET_POLICY(flags: &mut ::c_int, policy: ::c_int) -> () { ++ *flags &= !SCTP_PR_SCTP_MASK; ++ *flags |= policy; ++ () ++ } ++ + pub fn major(dev: ::dev_t) -> ::c_uint { + let mut major = 0; + major |= (dev & 0x00000000000fff00) >> 8; +@@ -3083,17 +3995,6 @@ f! { + minor as ::c_uint + } + +- pub fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { +- let major = major as ::dev_t; +- let minor = minor as ::dev_t; +- let mut dev = 0; +- dev |= (major & 0x00000fff) << 8; +- dev |= (major & 0xfffff000) << 32; +- dev |= (minor & 0x000000ff) << 0; +- dev |= (minor & 0xffffff00) << 12; +- dev +- } +- + pub fn IPTOS_TOS(tos: u8) -> u8 { + tos & IPTOS_TOS_MASK + } +@@ -3117,10 +4018,51 @@ f! { + pub fn SO_EE_OFFENDER(ee: *const ::sock_extended_err) -> *mut ::sockaddr { + ee.offset(1) as *mut ::sockaddr + } ++ ++ pub fn BPF_RVAL(code: ::__u32) -> ::__u32 { ++ code & 0x18 ++ } ++ ++ pub fn BPF_MISCOP(code: ::__u32) -> ::__u32 { ++ code & 0xf8 ++ } ++ ++ pub fn BPF_STMT(code: ::__u16, k: ::__u32) -> sock_filter { ++ sock_filter{code: code, jt: 0, jf: 0, k: k} ++ } ++ ++ pub fn BPF_JUMP(code: ::__u16, k: ::__u32, jt: ::__u8, jf: ::__u8) -> sock_filter { ++ sock_filter{code: code, jt: jt, jf: jf, k: k} ++ } ++} ++ ++safe_f! { ++ pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { ++ let major = major as ::dev_t; ++ let minor = minor as ::dev_t; ++ let mut dev = 0; ++ dev |= (major & 0x00000fff) << 8; ++ dev |= (major & 0xfffff000) << 32; ++ dev |= (minor & 0x000000ff) << 0; ++ dev |= (minor & 0xffffff00) << 12; ++ dev ++ } ++ ++ pub {const} fn SCTP_PR_TTL_ENABLED(policy: ::c_int) -> bool { ++ policy == SCTP_PR_SCTP_TTL ++ } ++ ++ pub {const} fn SCTP_PR_RTX_ENABLED(policy: ::c_int) -> bool { ++ policy == SCTP_PR_SCTP_RTX ++ } ++ ++ pub {const} fn SCTP_PR_PRIO_ENABLED(policy: ::c_int) -> bool { ++ policy == SCTP_PR_SCTP_PRIO ++ } + } + + cfg_if! { +- if #[cfg(not(target_env = "uclibc"))] { ++ if #[cfg(all(not(target_env = "uclibc"), not(target_env = "ohos")))] { + extern "C" { + pub fn aio_read(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_write(aiocbp: *mut aiocb) -> ::c_int; +@@ -3139,6 +4081,13 @@ cfg_if! { + nitems: ::c_int, + sevp: *mut ::sigevent, + ) -> ::c_int; ++ } ++ } ++} ++ ++cfg_if! { ++ if #[cfg(not(target_env = "uclibc"))] { ++ extern "C" { + pub fn pwritev( + fd: ::c_int, + iov: *const ::iovec, +@@ -3188,16 +4137,96 @@ cfg_if! { + } + } + ++// These functions are not available on OpenHarmony ++cfg_if! { ++ if #[cfg(not(target_env = "ohos"))] { ++ extern "C" { ++ // Only `getspnam_r` is implemented for musl, out of all of the reenterant ++ // functions from `shadow.h`. ++ // https://git.musl-libc.org/cgit/musl/tree/include/shadow.h ++ pub fn getspnam_r( ++ name: *const ::c_char, ++ spbuf: *mut spwd, ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ spbufp: *mut *mut spwd, ++ ) -> ::c_int; ++ ++ pub fn shm_open(name: *const c_char, oflag: ::c_int, mode: mode_t) -> ::c_int; ++ pub fn shm_unlink(name: *const ::c_char) -> ::c_int; ++ ++ pub fn mq_open(name: *const ::c_char, oflag: ::c_int, ...) -> ::mqd_t; ++ pub fn mq_close(mqd: ::mqd_t) -> ::c_int; ++ pub fn mq_unlink(name: *const ::c_char) -> ::c_int; ++ pub fn mq_receive( ++ mqd: ::mqd_t, ++ msg_ptr: *mut ::c_char, ++ msg_len: ::size_t, ++ msg_prio: *mut ::c_uint, ++ ) -> ::ssize_t; ++ pub fn mq_timedreceive( ++ mqd: ::mqd_t, ++ msg_ptr: *mut ::c_char, ++ msg_len: ::size_t, ++ msg_prio: *mut ::c_uint, ++ abs_timeout: *const ::timespec, ++ ) -> ::ssize_t; ++ pub fn mq_send( ++ mqd: ::mqd_t, ++ msg_ptr: *const ::c_char, ++ msg_len: ::size_t, ++ msg_prio: ::c_uint, ++ ) -> ::c_int; ++ pub fn mq_timedsend( ++ mqd: ::mqd_t, ++ msg_ptr: *const ::c_char, ++ msg_len: ::size_t, ++ msg_prio: ::c_uint, ++ abs_timeout: *const ::timespec, ++ ) -> ::c_int; ++ pub fn mq_getattr(mqd: ::mqd_t, attr: *mut ::mq_attr) -> ::c_int; ++ pub fn mq_setattr( ++ mqd: ::mqd_t, ++ newattr: *const ::mq_attr, ++ oldattr: *mut ::mq_attr ++ ) -> ::c_int; ++ ++ pub fn pthread_mutex_consistent(mutex: *mut pthread_mutex_t) -> ::c_int; ++ pub fn pthread_cancel(thread: ::pthread_t) -> ::c_int; ++ pub fn pthread_mutexattr_getrobust( ++ attr: *const pthread_mutexattr_t, ++ robustness: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_mutexattr_setrobust( ++ attr: *mut pthread_mutexattr_t, ++ robustness: ::c_int, ++ ) -> ::c_int; ++ } ++ } ++} ++ + extern "C" { +- #[cfg_attr(not(target_env = "musl"), link_name = "__xpg_strerror_r")] ++ #[cfg_attr( ++ not(any(target_env = "musl", target_env = "ohos")), ++ link_name = "__xpg_strerror_r" ++ )] + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + pub fn abs(i: ::c_int) -> ::c_int; +- pub fn atof(s: *const ::c_char) -> ::c_double; + pub fn labs(i: ::c_long) -> ::c_long; + pub fn rand() -> ::c_int; + pub fn srand(seed: ::c_uint); + ++ pub fn drand48() -> ::c_double; ++ pub fn erand48(xseed: *mut ::c_ushort) -> ::c_double; ++ pub fn lrand48() -> ::c_long; ++ pub fn nrand48(xseed: *mut ::c_ushort) -> ::c_long; ++ pub fn mrand48() -> ::c_long; ++ pub fn jrand48(xseed: *mut ::c_ushort) -> ::c_long; ++ pub fn srand48(seed: ::c_long); ++ pub fn seed48(xseed: *mut ::c_ushort) -> *mut ::c_ushort; ++ pub fn lcong48(p: *mut ::c_ushort); ++ + pub fn lutimes(file: *const ::c_char, times: *const ::timeval) -> ::c_int; + + pub fn setpwent(); +@@ -3211,18 +4240,6 @@ extern "C" { + pub fn getspent() -> *mut spwd; + + pub fn getspnam(name: *const ::c_char) -> *mut spwd; +- // Only `getspnam_r` is implemented for musl, out of all of the reenterant +- // functions from `shadow.h`. +- // https://git.musl-libc.org/cgit/musl/tree/include/shadow.h +- pub fn getspnam_r( +- name: *const ::c_char, +- spbuf: *mut spwd, +- buf: *mut ::c_char, +- buflen: ::size_t, +- spbufp: *mut *mut spwd, +- ) -> ::c_int; +- +- pub fn shm_open(name: *const c_char, oflag: ::c_int, mode: mode_t) -> ::c_int; + + // System V IPC + pub fn shmget(key: ::key_t, size: ::size_t, shmflg: ::c_int) -> ::c_int; +@@ -3314,7 +4331,7 @@ extern "C" { + pub fn lremovexattr(path: *const c_char, name: *const c_char) -> ::c_int; + pub fn fremovexattr(filedes: ::c_int, name: *const c_char) -> ::c_int; + pub fn signalfd(fd: ::c_int, mask: *const ::sigset_t, flags: ::c_int) -> ::c_int; +- pub fn timerfd_create(clockid: ::c_int, flags: ::c_int) -> ::c_int; ++ pub fn timerfd_create(clockid: ::clockid_t, flags: ::c_int) -> ::c_int; + pub fn timerfd_gettime(fd: ::c_int, curr_value: *mut itimerspec) -> ::c_int; + pub fn timerfd_settime( + fd: ::c_int, +@@ -3328,37 +4345,6 @@ extern "C" { + id: ::c_int, + data: *mut ::c_char, + ) -> ::c_int; +- pub fn mq_open(name: *const ::c_char, oflag: ::c_int, ...) -> ::mqd_t; +- pub fn mq_close(mqd: ::mqd_t) -> ::c_int; +- pub fn mq_unlink(name: *const ::c_char) -> ::c_int; +- pub fn mq_receive( +- mqd: ::mqd_t, +- msg_ptr: *mut ::c_char, +- msg_len: ::size_t, +- msg_prio: *mut ::c_uint, +- ) -> ::ssize_t; +- pub fn mq_timedreceive( +- mqd: ::mqd_t, +- msg_ptr: *mut ::c_char, +- msg_len: ::size_t, +- msg_prio: *mut ::c_uint, +- abs_timeout: *const ::timespec, +- ) -> ::ssize_t; +- pub fn mq_send( +- mqd: ::mqd_t, +- msg_ptr: *const ::c_char, +- msg_len: ::size_t, +- msg_prio: ::c_uint, +- ) -> ::c_int; +- pub fn mq_timedsend( +- mqd: ::mqd_t, +- msg_ptr: *const ::c_char, +- msg_len: ::size_t, +- msg_prio: ::c_uint, +- abs_timeout: *const ::timespec, +- ) -> ::c_int; +- pub fn mq_getattr(mqd: ::mqd_t, attr: *mut ::mq_attr) -> ::c_int; +- pub fn mq_setattr(mqd: ::mqd_t, newattr: *const ::mq_attr, oldattr: *mut ::mq_attr) -> ::c_int; + pub fn epoll_pwait( + epfd: ::c_int, + events: *mut ::epoll_event, +@@ -3382,6 +4368,16 @@ extern "C" { + len: *mut ::socklen_t, + flg: ::c_int, + ) -> ::c_int; ++ pub fn pthread_getaffinity_np( ++ thread: ::pthread_t, ++ cpusetsize: ::size_t, ++ cpuset: *mut ::cpu_set_t, ++ ) -> ::c_int; ++ pub fn pthread_setaffinity_np( ++ thread: ::pthread_t, ++ cpusetsize: ::size_t, ++ cpuset: *const ::cpu_set_t, ++ ) -> ::c_int; + pub fn pthread_setschedprio(native: ::pthread_t, priority: ::c_int) -> ::c_int; + pub fn reboot(how_to: ::c_int) -> ::c_int; + pub fn setfsgid(gid: ::gid_t) -> ::c_int; +@@ -3415,8 +4411,6 @@ extern "C" { + + pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + +- pub fn shm_unlink(name: *const ::c_char) -> ::c_int; +- + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; +@@ -3512,10 +4506,41 @@ extern "C" { + timeout: *const ::timespec, + sigmask: *const sigset_t, + ) -> ::c_int; ++ pub fn pthread_mutexattr_getprotocol( ++ attr: *const pthread_mutexattr_t, ++ protocol: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_mutexattr_setprotocol( ++ attr: *mut pthread_mutexattr_t, ++ protocol: ::c_int, ++ ) -> ::c_int; ++ + pub fn pthread_mutex_timedlock( + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; ++ pub fn pthread_barrierattr_init(attr: *mut ::pthread_barrierattr_t) -> ::c_int; ++ pub fn pthread_barrierattr_destroy(attr: *mut ::pthread_barrierattr_t) -> ::c_int; ++ pub fn pthread_barrierattr_getpshared( ++ attr: *const ::pthread_barrierattr_t, ++ shared: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_barrierattr_setpshared( ++ attr: *mut ::pthread_barrierattr_t, ++ shared: ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_barrier_init( ++ barrier: *mut pthread_barrier_t, ++ attr: *const ::pthread_barrierattr_t, ++ count: ::c_uint, ++ ) -> ::c_int; ++ pub fn pthread_barrier_destroy(barrier: *mut pthread_barrier_t) -> ::c_int; ++ pub fn pthread_barrier_wait(barrier: *mut pthread_barrier_t) -> ::c_int; ++ pub fn pthread_spin_init(lock: *mut ::pthread_spinlock_t, pshared: ::c_int) -> ::c_int; ++ pub fn pthread_spin_destroy(lock: *mut ::pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_lock(lock: *mut ::pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_trylock(lock: *mut ::pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_unlock(lock: *mut ::pthread_spinlock_t) -> ::c_int; + pub fn clone( + cb: extern "C" fn(*mut ::c_void) -> ::c_int, + child_stack: *mut ::c_void, +@@ -3587,7 +4612,6 @@ extern "C" { + pub fn pthread_sigmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; + pub fn sem_open(name: *const ::c_char, oflag: ::c_int, ...) -> *mut sem_t; + pub fn getgrnam(name: *const ::c_char) -> *mut ::group; +- pub fn pthread_cancel(thread: ::pthread_t) -> ::c_int; + pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; + pub fn sem_unlink(name: *const ::c_char) -> ::c_int; + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; +@@ -3770,13 +4794,58 @@ extern "C" { + pub fn iconv_close(cd: iconv_t) -> ::c_int; + + pub fn gettid() -> ::pid_t; ++ ++ pub fn timer_create( ++ clockid: ::clockid_t, ++ sevp: *mut ::sigevent, ++ timerid: *mut ::timer_t, ++ ) -> ::c_int; ++ pub fn timer_delete(timerid: ::timer_t) -> ::c_int; ++ pub fn timer_getoverrun(timerid: ::timer_t) -> ::c_int; ++ pub fn timer_gettime(timerid: ::timer_t, curr_value: *mut ::itimerspec) -> ::c_int; ++ pub fn timer_settime( ++ timerid: ::timer_t, ++ flags: ::c_int, ++ new_value: *const ::itimerspec, ++ old_value: *mut ::itimerspec, ++ ) -> ::c_int; ++ ++ pub fn gethostid() -> ::c_long; ++ ++ pub fn pthread_getcpuclockid(thread: ::pthread_t, clk_id: *mut ::clockid_t) -> ::c_int; ++ pub fn memmem( ++ haystack: *const ::c_void, ++ haystacklen: ::size_t, ++ needle: *const ::c_void, ++ needlelen: ::size_t, ++ ) -> *mut ::c_void; ++ pub fn sched_getcpu() -> ::c_int; ++ ++ pub fn pthread_getname_np(thread: ::pthread_t, name: *mut ::c_char, len: ::size_t) -> ::c_int; ++ pub fn pthread_setname_np(thread: ::pthread_t, name: *const ::c_char) -> ::c_int; ++ pub fn getopt_long( ++ argc: ::c_int, ++ argv: *const *mut c_char, ++ optstring: *const c_char, ++ longopts: *const option, ++ longindex: *mut ::c_int, ++ ) -> ::c_int; ++ ++ pub fn copy_file_range( ++ fd_in: ::c_int, ++ off_in: *mut ::off64_t, ++ fd_out: ::c_int, ++ off_out: *mut ::off64_t, ++ len: ::size_t, ++ flags: ::c_uint, ++ ) -> ::ssize_t; + } + + cfg_if! { + if #[cfg(target_env = "uclibc")] { + mod uclibc; + pub use self::uclibc::*; +- } else if #[cfg(target_env = "musl")] { ++ } else if #[cfg(any(target_env = "musl", target_env = "ohos"))] { + mod musl; + pub use self::musl::*; + } else if #[cfg(target_env = "gnu")] { +@@ -3798,3 +4867,10 @@ cfg_if! { + } + } + expand_align!(); ++ ++cfg_if! { ++ if #[cfg(libc_non_exhaustive)] { ++ mod non_exhaustive; ++ pub use self::non_exhaustive::*; ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/mod.rs +index 4e0f6c5..c47fa2c 100644 +--- a/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/mod.rs +@@ -150,6 +150,77 @@ s! { + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } ++ ++ pub struct mcontext_t { ++ pub trap_no: ::c_ulong, ++ pub error_code: ::c_ulong, ++ pub oldmask: ::c_ulong, ++ pub arm_r0: ::c_ulong, ++ pub arm_r1: ::c_ulong, ++ pub arm_r2: ::c_ulong, ++ pub arm_r3: ::c_ulong, ++ pub arm_r4: ::c_ulong, ++ pub arm_r5: ::c_ulong, ++ pub arm_r6: ::c_ulong, ++ pub arm_r7: ::c_ulong, ++ pub arm_r8: ::c_ulong, ++ pub arm_r9: ::c_ulong, ++ pub arm_r10: ::c_ulong, ++ pub arm_fp: ::c_ulong, ++ pub arm_ip: ::c_ulong, ++ pub arm_sp: ::c_ulong, ++ pub arm_lr: ::c_ulong, ++ pub arm_pc: ::c_ulong, ++ pub arm_cpsr: ::c_ulong, ++ pub fault_address: ::c_ulong, ++ } ++} ++ ++s_no_extra_traits! { ++ #[allow(missing_debug_implementations)] ++ pub struct ucontext_t { ++ pub uc_flags: ::c_ulong, ++ pub uc_link: *mut ucontext_t, ++ pub uc_stack: ::stack_t, ++ pub uc_mcontext: mcontext_t, ++ pub uc_sigmask: ::sigset_t, ++ pub uc_regspace: [::c_ulonglong; 64], ++ } ++} ++ ++cfg_if! { ++ if #[cfg(feature = "extra_traits")] { ++ impl PartialEq for ucontext_t { ++ fn eq(&self, other: &ucontext_t) -> bool { ++ self.uc_flags == other.uc_flags ++ && self.uc_link == other.uc_link ++ && self.uc_stack == other.uc_stack ++ && self.uc_mcontext == other.uc_mcontext ++ && self.uc_sigmask == other.uc_sigmask ++ } ++ } ++ impl Eq for ucontext_t {} ++ impl ::fmt::Debug for ucontext_t { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("ucontext_t") ++ .field("uc_flags", &self.uc_link) ++ .field("uc_link", &self.uc_link) ++ .field("uc_stack", &self.uc_stack) ++ .field("uc_mcontext", &self.uc_mcontext) ++ .field("uc_sigmask", &self.uc_sigmask) ++ .finish() ++ } ++ } ++ impl ::hash::Hash for ucontext_t { ++ fn hash(&self, state: &mut H) { ++ self.uc_flags.hash(state); ++ self.uc_link.hash(state); ++ self.uc_stack.hash(state); ++ self.uc_mcontext.hash(state); ++ self.uc_sigmask.hash(state); ++ } ++ } ++ } + } + + pub const SIGSTKSZ: ::size_t = 8192; +@@ -161,18 +232,6 @@ pub const O_NOFOLLOW: ::c_int = 0x8000; + pub const O_ASYNC: ::c_int = 0x2000; + pub const O_LARGEFILE: ::c_int = 0o400000; + +-pub const FIOCLEX: ::c_int = 0x5451; +-pub const FIONCLEX: ::c_int = 0x5450; +-pub const FIONBIO: ::c_int = 0x5421; +- +-pub const RLIMIT_RSS: ::c_int = 5; +-pub const RLIMIT_NOFILE: ::c_int = 7; +-pub const RLIMIT_AS: ::c_int = 9; +-pub const RLIMIT_NPROC: ::c_int = 6; +-pub const RLIMIT_MEMLOCK: ::c_int = 8; +-pub const RLIMIT_NLIMITS: ::c_int = 15; +-pub const RLIM_NLIMITS: ::c_int = RLIMIT_NLIMITS; +- + pub const MADV_SOFT_OFFLINE: ::c_int = 101; + pub const MCL_CURRENT: ::c_int = 0x0001; + pub const MCL_FUTURE: ::c_int = 0x0002; +@@ -404,55 +463,9 @@ pub const IEXTEN: ::tcflag_t = 0x00008000; + pub const TOSTOP: ::tcflag_t = 0x00000100; + pub const FLUSHO: ::tcflag_t = 0x00001000; + +-pub const TCGETS: ::c_int = 0x5401; +-pub const TCSETS: ::c_int = 0x5402; +-pub const TCSETSW: ::c_int = 0x5403; +-pub const TCSETSF: ::c_int = 0x5404; +-pub const TCGETA: ::c_int = 0x5405; +-pub const TCSETA: ::c_int = 0x5406; +-pub const TCSETAW: ::c_int = 0x5407; +-pub const TCSETAF: ::c_int = 0x5408; +-pub const TCSBRK: ::c_int = 0x5409; +-pub const TCXONC: ::c_int = 0x540A; +-pub const TCFLSH: ::c_int = 0x540B; +-pub const TIOCGSOFTCAR: ::c_int = 0x5419; +-pub const TIOCSSOFTCAR: ::c_int = 0x541A; +-pub const TIOCLINUX: ::c_int = 0x541C; +-pub const TIOCGSERIAL: ::c_int = 0x541E; +-pub const TIOCEXCL: ::c_int = 0x540C; +-pub const TIOCNXCL: ::c_int = 0x540D; +-pub const TIOCSCTTY: ::c_int = 0x540E; +-pub const TIOCGPGRP: ::c_int = 0x540F; +-pub const TIOCSPGRP: ::c_int = 0x5410; +-pub const TIOCOUTQ: ::c_int = 0x5411; +-pub const TIOCSTI: ::c_int = 0x5412; +-pub const TIOCGWINSZ: ::c_int = 0x5413; +-pub const TIOCSWINSZ: ::c_int = 0x5414; +-pub const TIOCMGET: ::c_int = 0x5415; +-pub const TIOCMBIS: ::c_int = 0x5416; +-pub const TIOCMBIC: ::c_int = 0x5417; +-pub const TIOCMSET: ::c_int = 0x5418; +-pub const FIONREAD: ::c_int = 0x541B; +-pub const TIOCCONS: ::c_int = 0x541D; +- +-pub const TIOCGRS485: ::c_int = 0x542E; +-pub const TIOCSRS485: ::c_int = 0x542F; +- + pub const POLLWRNORM: ::c_short = 0x100; + pub const POLLWRBAND: ::c_short = 0x200; + +-pub const TIOCM_LE: ::c_int = 0x001; +-pub const TIOCM_DTR: ::c_int = 0x002; +-pub const TIOCM_RTS: ::c_int = 0x004; +-pub const TIOCM_ST: ::c_int = 0x008; +-pub const TIOCM_SR: ::c_int = 0x010; +-pub const TIOCM_CTS: ::c_int = 0x020; +-pub const TIOCM_CAR: ::c_int = 0x040; +-pub const TIOCM_RNG: ::c_int = 0x080; +-pub const TIOCM_DSR: ::c_int = 0x100; +-pub const TIOCM_CD: ::c_int = TIOCM_CAR; +-pub const TIOCM_RI: ::c_int = TIOCM_RNG; +- + // Syscall table + pub const SYS_restart_syscall: ::c_long = 0; + pub const SYS_exit: ::c_long = 1; +@@ -824,6 +837,14 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; + + extern "C" { + pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b32/hexagon.rs b/vendor/libc/src/unix/linux_like/linux/musl/b32/hexagon.rs +index a94ebb6..f83d208 100644 +--- a/vendor/libc/src/unix/linux_like/linux/musl/b32/hexagon.rs ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/hexagon.rs +@@ -129,17 +129,6 @@ s! { + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } +- +- pub struct termios2 { +- pub c_iflag: ::tcflag_t, +- pub c_oflag: ::tcflag_t, +- pub c_cflag: ::tcflag_t, +- pub c_lflag: ::tcflag_t, +- pub c_line: ::cc_t, +- pub c_cc: [::cc_t; 19], +- pub c_ispeed: ::speed_t, +- pub c_ospeed: ::speed_t, +- } + } + + pub const AF_FILE: ::c_int = 1; +@@ -234,12 +223,6 @@ pub const F_GETOWN: ::c_int = 9; + pub const F_GETOWNER_UIDS: ::c_int = 17; + pub const F_GETOWN_EX: ::c_int = 16; + pub const F_GETSIG: ::c_int = 11; +-pub const FIOASYNC: ::c_int = 21586; +-pub const FIOCLEX: ::c_int = 21585; +-pub const FIONBIO: ::c_int = 21537; +-pub const FIONCLEX: ::c_int = 21584; +-pub const FIONREAD: ::c_int = 21531; +-pub const FIOQSIZE: ::c_int = 21600; + pub const F_LINUX_SPECIFIC_BASE: ::c_int = 1024; + pub const FLUSHO: ::c_int = 4096; + pub const F_OFD_GETLK: ::c_int = 36; +@@ -282,13 +265,7 @@ pub const PF_FILE: ::c_int = 1; + pub const PF_KCM: ::c_int = 41; + pub const PF_MAX: ::c_int = 43; + pub const PF_QIPCRTR: ::c_int = 42; +-pub const RLIMIT_AS: ::c_int = 9; +-pub const RLIMIT_MEMLOCK: ::c_int = 8; +-pub const RLIMIT_NOFILE: ::c_int = 7; +-pub const RLIMIT_NPROC: ::c_int = 6; +-pub const RLIMIT_RSS: ::c_int = 5; + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +-pub const RLIM_NLIMITS: ::c_int = 16; + pub const SA_ONSTACK: ::c_int = 0x08000000; + pub const SA_SIGINFO: ::c_int = 0x00000004; + pub const SA_NOCLDWAIT: ::c_int = 0x00000002; +@@ -666,83 +643,29 @@ pub const SYS_waitid: ::c_int = 95; + pub const SYS_write: ::c_int = 64; + pub const SYS_writev: ::c_int = 66; + pub const SYS_statx: ::c_int = 291; +-pub const TCFLSH: ::c_int = 21515; +-pub const TCGETA: ::c_int = 21509; +-pub const TCGETS: ::c_int = 21505; +-pub const TCGETX: ::c_int = 21554; +-pub const TCSBRK: ::c_int = 21513; +-pub const TCSBRKP: ::c_int = 21541; +-pub const TCSETA: ::c_int = 21510; +-pub const TCSETAF: ::c_int = 21512; +-pub const TCSETAW: ::c_int = 21511; +-pub const TCSETS: ::c_int = 21506; +-pub const TCSETSF: ::c_int = 21508; +-pub const TCSETSW: ::c_int = 21507; +-pub const TCSETX: ::c_int = 21555; +-pub const TCSETXF: ::c_int = 21556; +-pub const TCSETXW: ::c_int = 21557; +-pub const TCXONC: ::c_int = 21514; +-pub const TIOCCONS: ::c_int = 21533; +-pub const TIOCEXCL: ::c_int = 21516; +-pub const TIOCGETD: ::c_int = 21540; +-pub const TIOCGICOUNT: ::c_int = 21597; +-pub const TIOCGLCKTRMIOS: ::c_int = 21590; +-pub const TIOCGPGRP: ::c_int = 21519; +-pub const TIOCGRS485: ::c_int = 21550; +-pub const TIOCGSERIAL: ::c_int = 21534; +-pub const TIOCGSID: ::c_int = 21545; +-pub const TIOCGSOFTCAR: ::c_int = 21529; +-pub const TIOCGWINSZ: ::c_int = 21523; +-pub const TIOCLINUX: ::c_int = 21532; +-pub const TIOCMBIC: ::c_int = 21527; +-pub const TIOCMBIS: ::c_int = 21526; +-pub const TIOCM_CAR: ::c_int = 64; +-pub const TIOCM_CD: ::c_int = 64; +-pub const TIOCM_CTS: ::c_int = 32; +-pub const TIOCM_DSR: ::c_int = 256; +-pub const TIOCM_DTR: ::c_int = 2; +-pub const TIOCMGET: ::c_int = 21525; +-pub const TIOCMIWAIT: ::c_int = 21596; +-pub const TIOCM_LE: ::c_int = 1; ++pub const SYS_pidfd_send_signal: ::c_long = 424; ++pub const SYS_io_uring_setup: ::c_long = 425; ++pub const SYS_io_uring_enter: ::c_long = 426; ++pub const SYS_io_uring_register: ::c_long = 427; ++pub const SYS_open_tree: ::c_long = 428; ++pub const SYS_move_mount: ::c_long = 429; ++pub const SYS_fsopen: ::c_long = 430; ++pub const SYS_fsconfig: ::c_long = 431; ++pub const SYS_fsmount: ::c_long = 432; ++pub const SYS_fspick: ::c_long = 433; ++pub const SYS_pidfd_open: ::c_long = 434; ++pub const SYS_clone3: ::c_long = 435; ++pub const SYS_close_range: ::c_long = 436; ++pub const SYS_openat2: ::c_long = 437; ++pub const SYS_pidfd_getfd: ::c_long = 438; ++pub const SYS_faccessat2: ::c_long = 439; ++pub const SYS_process_madvise: ::c_long = 440; ++pub const SYS_epoll_pwait2: ::c_long = 441; ++pub const SYS_mount_setattr: ::c_long = 442; + pub const TIOCM_LOOP: ::c_int = 32768; + pub const TIOCM_OUT1: ::c_int = 8192; + pub const TIOCM_OUT2: ::c_int = 16384; +-pub const TIOCM_RI: ::c_int = 128; +-pub const TIOCM_RNG: ::c_int = 128; +-pub const TIOCM_RTS: ::c_int = 4; +-pub const TIOCMSET: ::c_int = 21528; +-pub const TIOCM_SR: ::c_int = 16; +-pub const TIOCM_ST: ::c_int = 8; +-pub const TIOCNOTTY: ::c_int = 21538; +-pub const TIOCNXCL: ::c_int = 21517; +-pub const TIOCOUTQ: ::c_int = 21521; +-pub const TIOCPKT: ::c_int = 21536; +-pub const TIOCPKT_DATA: ::c_int = 0; +-pub const TIOCPKT_DOSTOP: ::c_int = 32; +-pub const TIOCPKT_FLUSHREAD: ::c_int = 1; +-pub const TIOCPKT_FLUSHWRITE: ::c_int = 2; +-pub const TIOCPKT_IOCTL: ::c_int = 64; +-pub const TIOCPKT_NOSTOP: ::c_int = 16; +-pub const TIOCPKT_START: ::c_int = 8; +-pub const TIOCPKT_STOP: ::c_int = 4; +-pub const TIOCSCTTY: ::c_int = 21518; +-pub const TIOCSERCONFIG: ::c_int = 21587; +-pub const TIOCSERGETLSR: ::c_int = 21593; +-pub const TIOCSERGETMULTI: ::c_int = 21594; +-pub const TIOCSERGSTRUCT: ::c_int = 21592; +-pub const TIOCSERGWILD: ::c_int = 21588; +-pub const TIOCSERSETMULTI: ::c_int = 21595; +-pub const TIOCSERSWILD: ::c_int = 21589; + pub const TIOCSER_TEMT: ::c_int = 1; +-pub const TIOCSETD: ::c_int = 21539; +-pub const TIOCSLCKTRMIOS: ::c_int = 21591; +-pub const TIOCSPGRP: ::c_int = 21520; +-pub const TIOCSRS485: ::c_int = 21551; +-pub const TIOCSSERIAL: ::c_int = 21535; +-pub const TIOCSSOFTCAR: ::c_int = 21530; +-pub const TIOCSTI: ::c_int = 21522; +-pub const TIOCSWINSZ: ::c_int = 21524; +-pub const TIOCVHANGUP: ::c_int = 21559; + pub const TOSTOP: ::c_int = 256; + pub const VEOF: ::c_int = 4; + pub const VEOL2: ::c_int = 16; +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/mod.rs +index 0a67f74..d09b827 100644 +--- a/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/mod.rs +@@ -172,18 +172,6 @@ pub const O_NOFOLLOW: ::c_int = 0o400000; + pub const O_ASYNC: ::c_int = 0o10000; + pub const O_LARGEFILE: ::c_int = 0x2000; + +-pub const FIOCLEX: ::c_int = 0x6601; +-pub const FIONCLEX: ::c_int = 0x6602; +-pub const FIONBIO: ::c_int = 0x667E; +- +-pub const RLIMIT_RSS: ::c_int = 7; +-pub const RLIMIT_NOFILE: ::c_int = 5; +-pub const RLIMIT_AS: ::c_int = 6; +-pub const RLIMIT_NPROC: ::c_int = 8; +-pub const RLIMIT_MEMLOCK: ::c_int = 9; +-pub const RLIMIT_NLIMITS: ::c_int = 15; +-pub const RLIM_NLIMITS: ::c_int = RLIMIT_NLIMITS; +- + pub const MCL_CURRENT: ::c_int = 0x0001; + pub const MCL_FUTURE: ::c_int = 0x0002; + pub const CBAUD: ::tcflag_t = 0o0010017; +@@ -273,6 +261,7 @@ pub const MAP_NORESERVE: ::c_int = 0x0400; + pub const MAP_POPULATE: ::c_int = 0x10000; + pub const MAP_NONBLOCK: ::c_int = 0x20000; + pub const MAP_STACK: ::c_int = 0x40000; ++pub const MAP_HUGETLB: ::c_int = 0x80000; + + pub const EDEADLK: ::c_int = 45; + pub const ENAMETOOLONG: ::c_int = 78; +@@ -394,8 +383,6 @@ pub const SIG_UNBLOCK: ::c_int = 2; + + pub const EXTPROC: ::tcflag_t = 0o200000; + +-pub const MAP_HUGETLB: ::c_int = 0x80000; +- + pub const F_GETLK: ::c_int = 33; + pub const F_GETOWN: ::c_int = 23; + pub const F_SETLK: ::c_int = 34; +@@ -413,55 +400,9 @@ pub const IEXTEN: ::tcflag_t = 0o000400; + pub const TOSTOP: ::tcflag_t = 0o100000; + pub const FLUSHO: ::tcflag_t = 0o020000; + +-pub const TCGETS: ::c_int = 0x540D; +-pub const TCSETS: ::c_int = 0x540E; +-pub const TCSETSW: ::c_int = 0x540F; +-pub const TCSETSF: ::c_int = 0x5410; +-pub const TCGETA: ::c_int = 0x5401; +-pub const TCSETA: ::c_int = 0x5402; +-pub const TCSETAW: ::c_int = 0x5403; +-pub const TCSETAF: ::c_int = 0x5404; +-pub const TCSBRK: ::c_int = 0x5405; +-pub const TCXONC: ::c_int = 0x5406; +-pub const TCFLSH: ::c_int = 0x5407; +-pub const TIOCGSOFTCAR: ::c_int = 0x5481; +-pub const TIOCSSOFTCAR: ::c_int = 0x5482; +-pub const TIOCLINUX: ::c_int = 0x5483; +-pub const TIOCGSERIAL: ::c_int = 0x5484; +-pub const TIOCEXCL: ::c_int = 0x740D; +-pub const TIOCNXCL: ::c_int = 0x740E; +-pub const TIOCSCTTY: ::c_int = 0x5480; +-pub const TIOCGPGRP: ::c_int = 0x40047477; +-pub const TIOCSPGRP: ::c_int = 0x80047476; +-pub const TIOCOUTQ: ::c_int = 0x7472; +-pub const TIOCSTI: ::c_int = 0x5472; +-pub const TIOCGWINSZ: ::c_int = 0x40087468; +-pub const TIOCSWINSZ: ::c_int = 0x80087467; +-pub const TIOCMGET: ::c_int = 0x741D; +-pub const TIOCMBIS: ::c_int = 0x741B; +-pub const TIOCMBIC: ::c_int = 0x741C; +-pub const TIOCMSET: ::c_int = 0x741A; +-pub const FIONREAD: ::c_int = 0x467F; +-pub const TIOCCONS: ::c_int = 0x80047478; +- +-pub const TIOCGRS485: ::c_int = 0x4020542E; +-pub const TIOCSRS485: ::c_int = 0xC020542F; +- + pub const POLLWRNORM: ::c_short = 0x4; + pub const POLLWRBAND: ::c_short = 0x100; + +-pub const TIOCM_LE: ::c_int = 0x001; +-pub const TIOCM_DTR: ::c_int = 0x002; +-pub const TIOCM_RTS: ::c_int = 0x004; +-pub const TIOCM_ST: ::c_int = 0x010; +-pub const TIOCM_SR: ::c_int = 0x020; +-pub const TIOCM_CTS: ::c_int = 0x040; +-pub const TIOCM_CAR: ::c_int = 0x100; +-pub const TIOCM_CD: ::c_int = TIOCM_CAR; +-pub const TIOCM_RNG: ::c_int = 0x200; +-pub const TIOCM_RI: ::c_int = TIOCM_RNG; +-pub const TIOCM_DSR: ::c_int = 0x400; +- + pub const SYS_syscall: ::c_long = 4000 + 0; + pub const SYS_exit: ::c_long = 4000 + 1; + pub const SYS_fork: ::c_long = 4000 + 2; +@@ -835,6 +776,14 @@ pub const SYS_faccessat2: ::c_long = 4000 + 439; + pub const SYS_process_madvise: ::c_long = 4000 + 440; + pub const SYS_epoll_pwait2: ::c_long = 4000 + 441; + pub const SYS_mount_setattr: ::c_long = 4000 + 442; ++pub const SYS_quotactl_fd: ::c_long = 4000 + 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 4000 + 444; ++pub const SYS_landlock_add_rule: ::c_long = 4000 + 445; ++pub const SYS_landlock_restrict_self: ::c_long = 4000 + 446; ++pub const SYS_memfd_secret: ::c_long = 4000 + 447; ++pub const SYS_process_mrelease: ::c_long = 4000 + 448; ++pub const SYS_futex_waitv: ::c_long = 4000 + 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 4000 + 450; + + cfg_if! { + if #[cfg(libc_align)] { +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b32/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b32/mod.rs +index f54e5d9..cecd6dc 100644 +--- a/vendor/libc/src/unix/linux_like/linux/musl/b32/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/mod.rs +@@ -3,6 +3,7 @@ pub type c_ulong = u32; + pub type nlink_t = u32; + pub type blksize_t = ::c_long; + pub type __u64 = ::c_ulonglong; ++pub type __s64 = ::c_longlong; + pub type regoff_t = ::c_int; + + s! { +@@ -37,12 +38,7 @@ s! { + + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 24; +- +-pub const TIOCINQ: ::c_int = ::FIONREAD; +- +-extern "C" { +- pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; +-} ++pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 20; + + cfg_if! { + if #[cfg(any(target_arch = "x86"))] { +@@ -60,6 +56,9 @@ cfg_if! { + } else if #[cfg(any(target_arch = "hexagon"))] { + mod hexagon; + pub use self::hexagon::*; ++ } else if #[cfg(any(target_arch = "riscv32"))] { ++ mod riscv32; ++ pub use self::riscv32::*; + } else { + // Unknown target_arch + } +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b32/powerpc.rs b/vendor/libc/src/unix/linux_like/linux/musl/b32/powerpc.rs +index dacd78e..3b99832 100644 +--- a/vendor/libc/src/unix/linux_like/linux/musl/b32/powerpc.rs ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/powerpc.rs +@@ -165,18 +165,6 @@ pub const O_NOFOLLOW: ::c_int = 0x8000; + pub const O_ASYNC: ::c_int = 0x2000; + pub const O_LARGEFILE: ::c_int = 0x10000; + +-pub const FIOCLEX: ::c_int = 0x20006601; +-pub const FIONCLEX: ::c_int = 0x20006602; +-pub const FIONBIO: ::c_int = 0x8004667E; +- +-pub const RLIMIT_RSS: ::c_int = 5; +-pub const RLIMIT_NOFILE: ::c_int = 7; +-pub const RLIMIT_AS: ::c_int = 9; +-pub const RLIMIT_NPROC: ::c_int = 6; +-pub const RLIMIT_MEMLOCK: ::c_int = 8; +-pub const RLIMIT_NLIMITS: ::c_int = 15; +-pub const RLIM_NLIMITS: ::c_int = RLIMIT_NLIMITS; +- + pub const MCL_CURRENT: ::c_int = 0x2000; + pub const MCL_FUTURE: ::c_int = 0x4000; + pub const CBAUD: ::tcflag_t = 0o0000377; +@@ -266,6 +254,8 @@ pub const MAP_NORESERVE: ::c_int = 0x00040; + pub const MAP_POPULATE: ::c_int = 0x08000; + pub const MAP_NONBLOCK: ::c_int = 0x010000; + pub const MAP_STACK: ::c_int = 0x020000; ++pub const MAP_HUGETLB: ::c_int = 0x040000; ++pub const MAP_SYNC: ::c_int = 0x080000; + + pub const SOCK_STREAM: ::c_int = 1; + pub const SOCK_DGRAM: ::c_int = 2; +@@ -406,55 +396,9 @@ pub const IEXTEN: ::tcflag_t = 0x00000400; + pub const TOSTOP: ::tcflag_t = 0x00400000; + pub const FLUSHO: ::tcflag_t = 0x00800000; + +-pub const TCGETS: ::c_int = 0x402C7413; +-pub const TCSETS: ::c_int = 0x802C7414; +-pub const TCSETSW: ::c_int = 0x802C7415; +-pub const TCSETSF: ::c_int = 0x802C7416; +-pub const TCGETA: ::c_int = 0x40147417; +-pub const TCSETA: ::c_int = 0x80147418; +-pub const TCSETAW: ::c_int = 0x80147419; +-pub const TCSETAF: ::c_int = 0x8014741C; +-pub const TCSBRK: ::c_int = 0x2000741D; +-pub const TCXONC: ::c_int = 0x2000741E; +-pub const TCFLSH: ::c_int = 0x2000741F; +-pub const TIOCGSOFTCAR: ::c_int = 0x5419; +-pub const TIOCSSOFTCAR: ::c_int = 0x541A; +-pub const TIOCLINUX: ::c_int = 0x541C; +-pub const TIOCGSERIAL: ::c_int = 0x541E; +-pub const TIOCEXCL: ::c_int = 0x540C; +-pub const TIOCNXCL: ::c_int = 0x540D; +-pub const TIOCSCTTY: ::c_int = 0x540E; +-pub const TIOCGPGRP: ::c_int = 0x40047477; +-pub const TIOCSPGRP: ::c_int = 0x80047476; +-pub const TIOCOUTQ: ::c_int = 0x40047473; +-pub const TIOCSTI: ::c_int = 0x5412; +-pub const TIOCGWINSZ: ::c_int = 0x40087468; +-pub const TIOCSWINSZ: ::c_int = 0x80087467; +-pub const TIOCMGET: ::c_int = 0x5415; +-pub const TIOCMBIS: ::c_int = 0x5416; +-pub const TIOCMBIC: ::c_int = 0x5417; +-pub const TIOCMSET: ::c_int = 0x5418; +-pub const FIONREAD: ::c_int = 0x4004667F; +-pub const TIOCCONS: ::c_int = 0x541D; +- +-pub const TIOCGRS485: ::c_int = 0x542e; +-pub const TIOCSRS485: ::c_int = 0x542f; +- + pub const POLLWRNORM: ::c_short = 0x100; + pub const POLLWRBAND: ::c_short = 0x200; + +-pub const TIOCM_LE: ::c_int = 0x001; +-pub const TIOCM_DTR: ::c_int = 0x002; +-pub const TIOCM_RTS: ::c_int = 0x004; +-pub const TIOCM_ST: ::c_int = 0x008; +-pub const TIOCM_SR: ::c_int = 0x010; +-pub const TIOCM_CTS: ::c_int = 0x020; +-pub const TIOCM_CAR: ::c_int = 0x040; +-pub const TIOCM_RNG: ::c_int = 0x080; +-pub const TIOCM_DSR: ::c_int = 0x100; +-pub const TIOCM_CD: ::c_int = TIOCM_CAR; +-pub const TIOCM_RI: ::c_int = TIOCM_RNG; +- + // Syscall table + pub const SYS_restart_syscall: ::c_long = 0; + pub const SYS_exit: ::c_long = 1; +@@ -848,6 +792,14 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; + + extern "C" { + pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/align.rs b/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/align.rs +new file mode 100644 +index 0000000..048268c +--- /dev/null ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/align.rs +@@ -0,0 +1,7 @@ ++s_no_extra_traits! { ++ #[allow(missing_debug_implementations)] ++ #[repr(align(8))] ++ pub struct max_align_t { ++ priv_: (i64, f64) ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs +new file mode 100644 +index 0000000..9ce6a9f +--- /dev/null ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs +@@ -0,0 +1,810 @@ ++//! RISC-V-specific definitions for 32-bit linux-like values ++ ++pub type c_char = u8; ++pub type wchar_t = ::c_int; ++ ++s! { ++ pub struct pthread_attr_t { ++ __size: [::c_ulong; 7], ++ } ++ ++ pub struct stat { ++ pub st_dev: ::dev_t, ++ pub st_ino: ::ino_t, ++ pub st_mode: ::mode_t, ++ pub st_nlink: ::nlink_t, ++ pub st_uid: ::uid_t, ++ pub st_gid: ::gid_t, ++ pub st_rdev: ::dev_t, ++ pub __pad1: ::dev_t, ++ pub st_size: ::off_t, ++ pub st_blksize: ::blksize_t, ++ pub __pad2: ::c_int, ++ pub st_blocks: ::blkcnt_t, ++ pub st_atime: ::time_t, ++ pub st_atime_nsec: ::c_long, ++ pub st_mtime: ::time_t, ++ pub st_mtime_nsec: ::c_long, ++ pub st_ctime: ::time_t, ++ pub st_ctime_nsec: ::c_long, ++ __unused: [::c_int; 2usize], ++ } ++ ++ pub struct stat64 { ++ pub st_dev: ::dev_t, ++ pub st_ino: ::ino64_t, ++ pub st_mode: ::mode_t, ++ pub st_nlink: ::nlink_t, ++ pub st_uid: ::uid_t, ++ pub st_gid: ::gid_t, ++ pub st_rdev: ::dev_t, ++ pub __pad1: ::dev_t, ++ pub st_size: ::off64_t, ++ pub st_blksize: ::blksize_t, ++ pub __pad2: ::c_int, ++ pub st_blocks: ::blkcnt64_t, ++ pub st_atime: ::time_t, ++ pub st_atime_nsec: ::c_long, ++ pub st_mtime: ::time_t, ++ pub st_mtime_nsec: ::c_long, ++ pub st_ctime: ::time_t, ++ pub st_ctime_nsec: ::c_long, ++ __unused: [::c_int; 2], ++ } ++ ++ pub struct statfs { ++ pub f_type: ::c_long, ++ pub f_bsize: ::c_long, ++ pub f_blocks: ::fsblkcnt_t, ++ pub f_bfree: ::fsblkcnt_t, ++ pub f_bavail: ::fsblkcnt_t, ++ pub f_files: ::fsfilcnt_t, ++ pub f_ffree: ::fsfilcnt_t, ++ pub f_fsid: ::fsid_t, ++ pub f_namelen: ::c_long, ++ pub f_frsize: ::c_long, ++ pub f_flags: ::c_long, ++ pub f_spare: [::c_long; 4], ++ } ++ ++ pub struct statvfs { ++ pub f_bsize: ::c_ulong, ++ pub f_frsize: ::c_ulong, ++ pub f_blocks: ::fsblkcnt_t, ++ pub f_bfree: ::fsblkcnt_t, ++ pub f_bavail: ::fsblkcnt_t, ++ pub f_files: ::fsfilcnt_t, ++ pub f_ffree: ::fsfilcnt_t, ++ pub f_favail: ::fsfilcnt_t, ++ pub f_fsid: ::c_ulong, ++ pub f_flag: ::c_ulong, ++ pub f_namemax: ::c_ulong, ++ pub __f_spare: [::c_int; 6], ++ } ++ ++ pub struct statfs64 { ++ pub f_type: ::c_ulong, ++ pub f_bsize: ::c_ulong, ++ pub f_blocks: ::fsblkcnt_t, ++ pub f_bfree: ::fsblkcnt_t, ++ pub f_bavail: ::fsblkcnt_t, ++ pub f_files: ::fsfilcnt_t, ++ pub f_ffree: ::fsfilcnt_t, ++ pub f_fsid: ::fsid_t, ++ pub f_namelen: ::c_ulong, ++ pub f_frsize: ::c_ulong, ++ pub f_flags: ::c_ulong, ++ pub f_spare: [::c_ulong; 4], ++ } ++ ++ pub struct statvfs64 { ++ pub f_bsize: ::c_ulong, ++ pub f_frsize: ::c_ulong, ++ pub f_blocks: u64, ++ pub f_bfree: u64, ++ pub f_bavail: u64, ++ pub f_files: u64, ++ pub f_ffree: u64, ++ pub f_favail: u64, ++ pub f_fsid: ::c_ulong, ++ __f_unused: ::c_int, ++ pub f_flag: ::c_ulong, ++ pub f_namemax: ::c_ulong, ++ __f_spare: [::c_int; 6], ++ } ++ ++ pub struct siginfo_t { ++ pub si_signo: ::c_int, ++ pub si_errno: ::c_int, ++ pub si_code: ::c_int, ++ #[doc(hidden)] ++ #[deprecated( ++ since="0.2.54", ++ note="Please leave a comment on \ ++ https://github.com/rust-lang/libc/pull/1316 if you're using \ ++ this field" ++ )] ++ pub _pad: [::c_int; 29], ++ _align: [u64; 0], ++ } ++ ++ pub struct stack_t { ++ pub ss_sp: *mut ::c_void, ++ pub ss_flags: ::c_int, ++ pub ss_size: ::size_t, ++ } ++ ++ pub struct sigaction { ++ pub sa_sigaction: ::sighandler_t, ++ pub sa_mask: ::sigset_t, ++ pub sa_flags: ::c_int, ++ pub sa_restorer: ::Option, ++ } ++ ++ pub struct ipc_perm { ++ pub __key: ::key_t, ++ pub uid: ::uid_t, ++ pub gid: ::gid_t, ++ pub cuid: ::uid_t, ++ pub cgid: ::gid_t, ++ pub mode: ::c_ushort, ++ __pad1: ::c_ushort, ++ pub __seq: ::c_ushort, ++ __pad2: ::c_ushort, ++ __unused1: ::c_ulong, ++ __unused2: ::c_ulong, ++ } ++ ++ pub struct shmid_ds { ++ pub shm_perm: ::ipc_perm, ++ pub shm_segsz: ::size_t, ++ pub shm_atime: ::time_t, ++ pub shm_dtime: ::time_t, ++ pub shm_ctime: ::time_t, ++ pub shm_cpid: ::pid_t, ++ pub shm_lpid: ::pid_t, ++ pub shm_nattch: ::shmatt_t, ++ __unused5: ::c_ulong, ++ __unused6: ::c_ulong, ++ } ++ ++ pub struct msqid_ds { ++ pub msg_perm: ::ipc_perm, ++ pub msg_stime: ::time_t, ++ __unused1: ::c_int, ++ pub msg_rtime: ::time_t, ++ __unused2: ::c_int, ++ pub msg_ctime: ::time_t, ++ __unused3: ::c_int, ++ __msg_cbytes: ::c_ulong, ++ pub msg_qnum: ::msgqnum_t, ++ pub msg_qbytes: ::msglen_t, ++ pub msg_lspid: ::pid_t, ++ pub msg_lrpid: ::pid_t, ++ __pad1: ::c_ulong, ++ __pad2: ::c_ulong, ++ } ++ ++ pub struct flock { ++ pub l_type: ::c_short, ++ pub l_whence: ::c_short, ++ pub l_start: ::off_t, ++ pub l_len: ::off_t, ++ pub l_pid: ::pid_t, ++ } ++ ++ pub struct flock64 { ++ pub l_type: ::c_short, ++ pub l_whence: ::c_short, ++ pub l_start: ::off64_t, ++ pub l_len: ::off64_t, ++ pub l_pid: ::pid_t, ++ } ++} ++ ++//pub const RLIM_INFINITY: ::rlim_t = !0; ++pub const VEOF: usize = 4; ++pub const RTLD_DEEPBIND: ::c_int = 0x8; ++pub const RTLD_GLOBAL: ::c_int = 0x100; ++pub const RTLD_NOLOAD: ::c_int = 0x4; ++pub const TIOCGSOFTCAR: ::c_ulong = 21529; ++pub const TIOCSSOFTCAR: ::c_ulong = 21530; ++pub const TIOCGRS485: ::c_int = 21550; ++pub const TIOCSRS485: ::c_int = 21551; ++//pub const RLIMIT_RSS: ::__rlimit_resource_t = 5; ++//pub const RLIMIT_AS: ::__rlimit_resource_t = 9; ++//pub const RLIMIT_MEMLOCK: ::__rlimit_resource_t = 8; ++//pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 7; ++//pub const RLIMIT_NPROC: ::__rlimit_resource_t = 6; ++pub const O_APPEND: ::c_int = 1024; ++pub const O_CREAT: ::c_int = 64; ++pub const O_EXCL: ::c_int = 128; ++pub const O_NOCTTY: ::c_int = 256; ++pub const O_NONBLOCK: ::c_int = 2048; ++pub const O_SYNC: ::c_int = 1052672; ++pub const O_RSYNC: ::c_int = 1052672; ++pub const O_DSYNC: ::c_int = 4096; ++pub const O_FSYNC: ::c_int = 1052672; ++pub const MAP_GROWSDOWN: ::c_int = 256; ++pub const EDEADLK: ::c_int = 35; ++pub const ENAMETOOLONG: ::c_int = 36; ++pub const ENOLCK: ::c_int = 37; ++pub const ENOSYS: ::c_int = 38; ++pub const ENOTEMPTY: ::c_int = 39; ++pub const ELOOP: ::c_int = 40; ++pub const ENOMSG: ::c_int = 42; ++pub const EIDRM: ::c_int = 43; ++pub const ECHRNG: ::c_int = 44; ++pub const EL2NSYNC: ::c_int = 45; ++pub const EL3HLT: ::c_int = 46; ++pub const EL3RST: ::c_int = 47; ++pub const ELNRNG: ::c_int = 48; ++pub const EUNATCH: ::c_int = 49; ++pub const ENOCSI: ::c_int = 50; ++pub const EL2HLT: ::c_int = 51; ++pub const EBADE: ::c_int = 52; ++pub const EBADR: ::c_int = 53; ++pub const EXFULL: ::c_int = 54; ++pub const ENOANO: ::c_int = 55; ++pub const EBADRQC: ::c_int = 56; ++pub const EBADSLT: ::c_int = 57; ++pub const EMULTIHOP: ::c_int = 72; ++pub const EOVERFLOW: ::c_int = 75; ++pub const ENOTUNIQ: ::c_int = 76; ++pub const EBADFD: ::c_int = 77; ++pub const EBADMSG: ::c_int = 74; ++pub const EREMCHG: ::c_int = 78; ++pub const ELIBACC: ::c_int = 79; ++pub const ELIBBAD: ::c_int = 80; ++pub const ELIBSCN: ::c_int = 81; ++pub const ELIBMAX: ::c_int = 82; ++pub const ELIBEXEC: ::c_int = 83; ++pub const EILSEQ: ::c_int = 84; ++pub const ERESTART: ::c_int = 85; ++pub const ESTRPIPE: ::c_int = 86; ++pub const EUSERS: ::c_int = 87; ++pub const ENOTSOCK: ::c_int = 88; ++pub const EDESTADDRREQ: ::c_int = 89; ++pub const EMSGSIZE: ::c_int = 90; ++pub const EPROTOTYPE: ::c_int = 91; ++pub const ENOPROTOOPT: ::c_int = 92; ++pub const EPROTONOSUPPORT: ::c_int = 93; ++pub const ESOCKTNOSUPPORT: ::c_int = 94; ++pub const EOPNOTSUPP: ::c_int = 95; ++pub const ENOTSUP: ::c_int = EOPNOTSUPP; ++pub const EPFNOSUPPORT: ::c_int = 96; ++pub const EAFNOSUPPORT: ::c_int = 97; ++pub const EADDRINUSE: ::c_int = 98; ++pub const EADDRNOTAVAIL: ::c_int = 99; ++pub const ENETDOWN: ::c_int = 100; ++pub const ENETUNREACH: ::c_int = 101; ++pub const ENETRESET: ::c_int = 102; ++pub const ECONNABORTED: ::c_int = 103; ++pub const ECONNRESET: ::c_int = 104; ++pub const ENOBUFS: ::c_int = 105; ++pub const EISCONN: ::c_int = 106; ++pub const ENOTCONN: ::c_int = 107; ++pub const ESHUTDOWN: ::c_int = 108; ++pub const ETOOMANYREFS: ::c_int = 109; ++pub const ETIMEDOUT: ::c_int = 110; ++pub const ECONNREFUSED: ::c_int = 111; ++pub const EHOSTDOWN: ::c_int = 112; ++pub const EHOSTUNREACH: ::c_int = 113; ++pub const EALREADY: ::c_int = 114; ++pub const EINPROGRESS: ::c_int = 115; ++pub const ESTALE: ::c_int = 116; ++pub const EDQUOT: ::c_int = 122; ++pub const ENOMEDIUM: ::c_int = 123; ++pub const EMEDIUMTYPE: ::c_int = 124; ++pub const ECANCELED: ::c_int = 125; ++pub const ENOKEY: ::c_int = 126; ++pub const EKEYEXPIRED: ::c_int = 127; ++pub const EKEYREVOKED: ::c_int = 128; ++pub const EKEYREJECTED: ::c_int = 129; ++pub const EOWNERDEAD: ::c_int = 130; ++pub const ENOTRECOVERABLE: ::c_int = 131; ++pub const EHWPOISON: ::c_int = 133; ++pub const ERFKILL: ::c_int = 132; ++ ++pub const SOCK_STREAM: ::c_int = 1; ++pub const SOCK_DGRAM: ::c_int = 2; ++pub const SA_ONSTACK: ::c_int = 8; ++pub const SA_SIGINFO: ::c_int = 4; ++pub const SA_NOCLDWAIT: ::c_int = 2; ++pub const SIGTTIN: ::c_int = 21; ++pub const SIGTTOU: ::c_int = 22; ++pub const SIGXCPU: ::c_int = 24; ++pub const SIGXFSZ: ::c_int = 25; ++pub const SIGVTALRM: ::c_int = 26; ++pub const SIGPROF: ::c_int = 27; ++pub const SIGWINCH: ::c_int = 28; ++pub const SIGCHLD: ::c_int = 17; ++pub const SIGBUS: ::c_int = 7; ++pub const SIGUSR1: ::c_int = 10; ++pub const SIGUSR2: ::c_int = 12; ++pub const SIGCONT: ::c_int = 18; ++pub const SIGSTOP: ::c_int = 19; ++pub const SIGTSTP: ::c_int = 20; ++pub const SIGURG: ::c_int = 23; ++pub const SIGIO: ::c_int = 29; ++pub const SIGSYS: ::c_int = 31; ++pub const SIGSTKFLT: ::c_int = 16; ++pub const SIGPOLL: ::c_int = 29; ++pub const SIGPWR: ::c_int = 30; ++pub const SIG_SETMASK: ::c_int = 2; ++pub const SIG_BLOCK: ::c_int = 0; ++pub const SIG_UNBLOCK: ::c_int = 1; ++pub const POLLWRNORM: ::c_short = 256; ++pub const POLLWRBAND: ::c_short = 512; ++pub const O_ASYNC: ::c_int = 8192; ++pub const O_NDELAY: ::c_int = 2048; ++pub const EFD_NONBLOCK: ::c_int = 2048; ++pub const F_GETLK: ::c_int = 5; ++pub const F_GETOWN: ::c_int = 9; ++pub const F_SETOWN: ::c_int = 8; ++pub const SFD_NONBLOCK: ::c_int = 2048; ++pub const TCSANOW: ::c_int = 0; ++pub const TCSADRAIN: ::c_int = 1; ++pub const TCSAFLUSH: ::c_int = 2; ++pub const TIOCLINUX: ::c_ulong = 21532; ++pub const TIOCGSERIAL: ::c_ulong = 21534; ++pub const TIOCEXCL: ::c_ulong = 21516; ++pub const TIOCNXCL: ::c_ulong = 21517; ++pub const TIOCSCTTY: ::c_ulong = 21518; ++pub const TIOCSTI: ::c_ulong = 21522; ++pub const TIOCMGET: ::c_ulong = 21525; ++pub const TIOCMBIS: ::c_ulong = 21526; ++pub const TIOCMBIC: ::c_ulong = 21527; ++pub const TIOCMSET: ::c_ulong = 21528; ++pub const TIOCCONS: ::c_ulong = 21533; ++pub const TIOCM_ST: ::c_int = 8; ++pub const TIOCM_SR: ::c_int = 16; ++pub const TIOCM_CTS: ::c_int = 32; ++pub const TIOCM_CAR: ::c_int = 64; ++pub const TIOCM_RNG: ::c_int = 128; ++pub const TIOCM_DSR: ::c_int = 256; ++ ++pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; ++pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; ++pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; ++pub const O_DIRECT: ::c_int = 16384; ++pub const O_DIRECTORY: ::c_int = 65536; ++pub const O_NOFOLLOW: ::c_int = 131072; ++pub const MAP_HUGETLB: ::c_int = 262144; ++pub const MAP_LOCKED: ::c_int = 8192; ++pub const MAP_NORESERVE: ::c_int = 16384; ++pub const MAP_ANON: ::c_int = 32; ++pub const MAP_ANONYMOUS: ::c_int = 32; ++pub const MAP_DENYWRITE: ::c_int = 2048; ++pub const MAP_EXECUTABLE: ::c_int = 4096; ++pub const MAP_POPULATE: ::c_int = 32768; ++pub const MAP_NONBLOCK: ::c_int = 65536; ++pub const MAP_STACK: ::c_int = 131072; ++pub const MAP_SYNC: ::c_int = 0x080000; ++pub const EDEADLOCK: ::c_int = 35; ++pub const EUCLEAN: ::c_int = 117; ++pub const ENOTNAM: ::c_int = 118; ++pub const ENAVAIL: ::c_int = 119; ++pub const EISNAM: ::c_int = 120; ++pub const EREMOTEIO: ::c_int = 121; ++pub const FIOCLEX: ::c_int = 21585; ++pub const FIONCLEX: ::c_int = 21584; ++pub const FIONBIO: ::c_int = 21537; ++pub const MCL_CURRENT: ::c_int = 1; ++pub const MCL_FUTURE: ::c_int = 2; ++pub const SIGSTKSZ: ::size_t = 8192; ++pub const MINSIGSTKSZ: ::size_t = 2048; ++pub const CBAUD: ::tcflag_t = 4111; ++pub const TAB1: ::tcflag_t = 2048; ++pub const TAB2: ::tcflag_t = 4096; ++pub const TAB3: ::tcflag_t = 6144; ++pub const CR1: ::tcflag_t = 512; ++pub const CR2: ::tcflag_t = 1024; ++pub const CR3: ::tcflag_t = 1536; ++pub const FF1: ::tcflag_t = 32768; ++pub const BS1: ::tcflag_t = 8192; ++pub const VT1: ::tcflag_t = 16384; ++pub const VWERASE: usize = 14; ++pub const VREPRINT: usize = 12; ++pub const VSUSP: usize = 10; ++pub const VSTART: usize = 8; ++pub const VSTOP: usize = 9; ++pub const VDISCARD: usize = 13; ++pub const VTIME: usize = 5; ++pub const IXON: ::tcflag_t = 1024; ++pub const IXOFF: ::tcflag_t = 4096; ++pub const ONLCR: ::tcflag_t = 4; ++pub const CSIZE: ::tcflag_t = 48; ++pub const CS6: ::tcflag_t = 16; ++pub const CS7: ::tcflag_t = 32; ++pub const CS8: ::tcflag_t = 48; ++pub const CSTOPB: ::tcflag_t = 64; ++pub const CREAD: ::tcflag_t = 128; ++pub const PARENB: ::tcflag_t = 256; ++pub const PARODD: ::tcflag_t = 512; ++pub const HUPCL: ::tcflag_t = 1024; ++pub const CLOCAL: ::tcflag_t = 2048; ++pub const ECHOKE: ::tcflag_t = 2048; ++pub const ECHOE: ::tcflag_t = 16; ++pub const ECHOK: ::tcflag_t = 32; ++pub const ECHONL: ::tcflag_t = 64; ++pub const ECHOPRT: ::tcflag_t = 1024; ++pub const ECHOCTL: ::tcflag_t = 512; ++pub const ISIG: ::tcflag_t = 1; ++pub const ICANON: ::tcflag_t = 2; ++pub const PENDIN: ::tcflag_t = 16384; ++pub const NOFLSH: ::tcflag_t = 128; ++pub const CIBAUD: ::tcflag_t = 269418496; ++pub const CBAUDEX: ::tcflag_t = 4096; ++pub const VSWTC: usize = 7; ++pub const OLCUC: ::tcflag_t = 2; ++pub const NLDLY: ::tcflag_t = 256; ++pub const CRDLY: ::tcflag_t = 1536; ++pub const TABDLY: ::tcflag_t = 6144; ++pub const BSDLY: ::tcflag_t = 8192; ++pub const FFDLY: ::tcflag_t = 32768; ++pub const VTDLY: ::tcflag_t = 16384; ++pub const XTABS: ::tcflag_t = 6144; ++pub const B0: ::speed_t = 0; ++pub const B50: ::speed_t = 1; ++pub const B75: ::speed_t = 2; ++pub const B110: ::speed_t = 3; ++pub const B134: ::speed_t = 4; ++pub const B150: ::speed_t = 5; ++pub const B200: ::speed_t = 6; ++pub const B300: ::speed_t = 7; ++pub const B600: ::speed_t = 8; ++pub const B1200: ::speed_t = 9; ++pub const B1800: ::speed_t = 10; ++pub const B2400: ::speed_t = 11; ++pub const B4800: ::speed_t = 12; ++pub const B9600: ::speed_t = 13; ++pub const B19200: ::speed_t = 14; ++pub const B38400: ::speed_t = 15; ++pub const EXTA: ::speed_t = 14; ++pub const EXTB: ::speed_t = 15; ++pub const B57600: ::speed_t = 4097; ++pub const B115200: ::speed_t = 4098; ++pub const B230400: ::speed_t = 4099; ++pub const B460800: ::speed_t = 4100; ++pub const B500000: ::speed_t = 4101; ++pub const B576000: ::speed_t = 4102; ++pub const B921600: ::speed_t = 4103; ++pub const B1000000: ::speed_t = 4104; ++pub const B1152000: ::speed_t = 4105; ++pub const B1500000: ::speed_t = 4106; ++pub const B2000000: ::speed_t = 4107; ++pub const B2500000: ::speed_t = 4108; ++pub const B3000000: ::speed_t = 4109; ++pub const B3500000: ::speed_t = 4110; ++pub const B4000000: ::speed_t = 4111; ++pub const VEOL: usize = 11; ++pub const VEOL2: usize = 16; ++pub const VMIN: usize = 6; ++pub const IEXTEN: ::tcflag_t = 32768; ++pub const TOSTOP: ::tcflag_t = 256; ++pub const FLUSHO: ::tcflag_t = 4096; ++pub const EXTPROC: ::tcflag_t = 65536; ++pub const TCGETS: ::c_int = 21505; ++pub const TCSETS: ::c_int = 21506; ++pub const TCSETSW: ::c_int = 21507; ++pub const TCSETSF: ::c_int = 21508; ++pub const TCGETA: ::c_int = 21509; ++pub const TCSETA: ::c_int = 21510; ++pub const TCSETAW: ::c_int = 21511; ++pub const TCSETAF: ::c_int = 21512; ++pub const TCSBRK: ::c_int = 21513; ++pub const TCXONC: ::c_int = 21514; ++pub const TCFLSH: ::c_int = 21515; ++pub const TIOCINQ: ::c_int = 21531; ++pub const TIOCGPGRP: ::c_int = 21519; ++pub const TIOCSPGRP: ::c_int = 21520; ++pub const TIOCOUTQ: ::c_int = 21521; ++pub const TIOCGWINSZ: ::c_int = 21523; ++pub const TIOCSWINSZ: ::c_int = 21524; ++pub const FIONREAD: ::c_int = 21531; ++pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; ++pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; ++pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; ++ ++pub const SYS_read: ::c_long = 63; ++pub const SYS_write: ::c_long = 64; ++pub const SYS_close: ::c_long = 57; ++pub const SYS_fstat: ::c_long = 80; ++pub const SYS_lseek: ::c_long = 62; ++pub const SYS_mmap: ::c_long = 222; ++pub const SYS_mprotect: ::c_long = 226; ++pub const SYS_munmap: ::c_long = 215; ++pub const SYS_brk: ::c_long = 214; ++pub const SYS_rt_sigaction: ::c_long = 134; ++pub const SYS_rt_sigprocmask: ::c_long = 135; ++pub const SYS_rt_sigreturn: ::c_long = 139; ++pub const SYS_ioctl: ::c_long = 29; ++pub const SYS_pread64: ::c_long = 67; ++pub const SYS_pwrite64: ::c_long = 68; ++pub const SYS_readv: ::c_long = 65; ++pub const SYS_writev: ::c_long = 66; ++pub const SYS_sched_yield: ::c_long = 124; ++pub const SYS_mremap: ::c_long = 216; ++pub const SYS_msync: ::c_long = 227; ++pub const SYS_mincore: ::c_long = 232; ++pub const SYS_madvise: ::c_long = 233; ++pub const SYS_shmget: ::c_long = 194; ++pub const SYS_shmat: ::c_long = 196; ++pub const SYS_shmctl: ::c_long = 195; ++pub const SYS_dup: ::c_long = 23; ++pub const SYS_nanosleep: ::c_long = 101; ++pub const SYS_getitimer: ::c_long = 102; ++pub const SYS_setitimer: ::c_long = 103; ++pub const SYS_getpid: ::c_long = 172; ++pub const SYS_sendfile: ::c_long = 71; ++pub const SYS_socket: ::c_long = 198; ++pub const SYS_connect: ::c_long = 203; ++pub const SYS_accept: ::c_long = 202; ++pub const SYS_sendto: ::c_long = 206; ++pub const SYS_recvfrom: ::c_long = 207; ++pub const SYS_sendmsg: ::c_long = 211; ++pub const SYS_recvmsg: ::c_long = 212; ++pub const SYS_shutdown: ::c_long = 210; ++pub const SYS_bind: ::c_long = 200; ++pub const SYS_listen: ::c_long = 201; ++pub const SYS_getsockname: ::c_long = 204; ++pub const SYS_getpeername: ::c_long = 205; ++pub const SYS_socketpair: ::c_long = 199; ++pub const SYS_setsockopt: ::c_long = 208; ++pub const SYS_getsockopt: ::c_long = 209; ++pub const SYS_clone: ::c_long = 220; ++pub const SYS_execve: ::c_long = 221; ++pub const SYS_exit: ::c_long = 93; ++pub const SYS_wait4: ::c_long = 260; ++pub const SYS_kill: ::c_long = 129; ++pub const SYS_uname: ::c_long = 160; ++pub const SYS_semget: ::c_long = 190; ++pub const SYS_semop: ::c_long = 193; ++pub const SYS_semctl: ::c_long = 191; ++pub const SYS_shmdt: ::c_long = 197; ++pub const SYS_msgget: ::c_long = 186; ++pub const SYS_msgsnd: ::c_long = 189; ++pub const SYS_msgrcv: ::c_long = 188; ++pub const SYS_msgctl: ::c_long = 187; ++pub const SYS_fcntl: ::c_long = 25; ++pub const SYS_flock: ::c_long = 32; ++pub const SYS_fsync: ::c_long = 82; ++pub const SYS_fdatasync: ::c_long = 83; ++pub const SYS_truncate: ::c_long = 45; ++pub const SYS_ftruncate: ::c_long = 46; ++pub const SYS_getcwd: ::c_long = 17; ++pub const SYS_chdir: ::c_long = 49; ++pub const SYS_fchdir: ::c_long = 50; ++pub const SYS_fchmod: ::c_long = 52; ++pub const SYS_fchown: ::c_long = 55; ++pub const SYS_umask: ::c_long = 166; ++pub const SYS_gettimeofday: ::c_long = 169; ++pub const SYS_getrlimit: ::c_long = 163; ++pub const SYS_getrusage: ::c_long = 165; ++pub const SYS_sysinfo: ::c_long = 179; ++pub const SYS_times: ::c_long = 153; ++pub const SYS_ptrace: ::c_long = 117; ++pub const SYS_getuid: ::c_long = 174; ++pub const SYS_syslog: ::c_long = 116; ++pub const SYS_getgid: ::c_long = 176; ++pub const SYS_setuid: ::c_long = 146; ++pub const SYS_setgid: ::c_long = 144; ++pub const SYS_geteuid: ::c_long = 175; ++pub const SYS_getegid: ::c_long = 177; ++pub const SYS_setpgid: ::c_long = 154; ++pub const SYS_getppid: ::c_long = 173; ++pub const SYS_setsid: ::c_long = 157; ++pub const SYS_setreuid: ::c_long = 145; ++pub const SYS_setregid: ::c_long = 143; ++pub const SYS_getgroups: ::c_long = 158; ++pub const SYS_setgroups: ::c_long = 159; ++pub const SYS_setresuid: ::c_long = 147; ++pub const SYS_getresuid: ::c_long = 148; ++pub const SYS_setresgid: ::c_long = 149; ++pub const SYS_getresgid: ::c_long = 150; ++pub const SYS_getpgid: ::c_long = 155; ++pub const SYS_setfsuid: ::c_long = 151; ++pub const SYS_setfsgid: ::c_long = 152; ++pub const SYS_getsid: ::c_long = 156; ++pub const SYS_capget: ::c_long = 90; ++pub const SYS_capset: ::c_long = 91; ++pub const SYS_rt_sigpending: ::c_long = 136; ++pub const SYS_rt_sigtimedwait: ::c_long = 137; ++pub const SYS_rt_sigqueueinfo: ::c_long = 138; ++pub const SYS_rt_sigsuspend: ::c_long = 133; ++pub const SYS_sigaltstack: ::c_long = 132; ++pub const SYS_personality: ::c_long = 92; ++pub const SYS_statfs: ::c_long = 43; ++pub const SYS_fstatfs: ::c_long = 44; ++pub const SYS_getpriority: ::c_long = 141; ++pub const SYS_setpriority: ::c_long = 140; ++pub const SYS_sched_setparam: ::c_long = 118; ++pub const SYS_sched_getparam: ::c_long = 121; ++pub const SYS_sched_setscheduler: ::c_long = 119; ++pub const SYS_sched_getscheduler: ::c_long = 120; ++pub const SYS_sched_get_priority_max: ::c_long = 125; ++pub const SYS_sched_get_priority_min: ::c_long = 126; ++pub const SYS_sched_rr_get_interval: ::c_long = 127; ++pub const SYS_mlock: ::c_long = 228; ++pub const SYS_munlock: ::c_long = 229; ++pub const SYS_mlockall: ::c_long = 230; ++pub const SYS_munlockall: ::c_long = 231; ++pub const SYS_vhangup: ::c_long = 58; ++pub const SYS_pivot_root: ::c_long = 41; ++pub const SYS_prctl: ::c_long = 167; ++pub const SYS_adjtimex: ::c_long = 171; ++pub const SYS_setrlimit: ::c_long = 164; ++pub const SYS_chroot: ::c_long = 51; ++pub const SYS_sync: ::c_long = 81; ++pub const SYS_acct: ::c_long = 89; ++pub const SYS_settimeofday: ::c_long = 170; ++pub const SYS_mount: ::c_long = 40; ++pub const SYS_umount2: ::c_long = 39; ++pub const SYS_swapon: ::c_long = 224; ++pub const SYS_swapoff: ::c_long = 225; ++pub const SYS_reboot: ::c_long = 142; ++pub const SYS_sethostname: ::c_long = 161; ++pub const SYS_setdomainname: ::c_long = 162; ++pub const SYS_init_module: ::c_long = 105; ++pub const SYS_delete_module: ::c_long = 106; ++pub const SYS_quotactl: ::c_long = 60; ++pub const SYS_nfsservctl: ::c_long = 42; ++pub const SYS_gettid: ::c_long = 178; ++pub const SYS_readahead: ::c_long = 213; ++pub const SYS_setxattr: ::c_long = 5; ++pub const SYS_lsetxattr: ::c_long = 6; ++pub const SYS_fsetxattr: ::c_long = 7; ++pub const SYS_getxattr: ::c_long = 8; ++pub const SYS_lgetxattr: ::c_long = 9; ++pub const SYS_fgetxattr: ::c_long = 10; ++pub const SYS_listxattr: ::c_long = 11; ++pub const SYS_llistxattr: ::c_long = 12; ++pub const SYS_flistxattr: ::c_long = 13; ++pub const SYS_removexattr: ::c_long = 14; ++pub const SYS_lremovexattr: ::c_long = 15; ++pub const SYS_fremovexattr: ::c_long = 16; ++pub const SYS_tkill: ::c_long = 130; ++pub const SYS_futex: ::c_long = 98; ++pub const SYS_sched_setaffinity: ::c_long = 122; ++pub const SYS_sched_getaffinity: ::c_long = 123; ++pub const SYS_io_setup: ::c_long = 0; ++pub const SYS_io_destroy: ::c_long = 1; ++pub const SYS_io_getevents: ::c_long = 4; ++pub const SYS_io_submit: ::c_long = 2; ++pub const SYS_io_cancel: ::c_long = 3; ++pub const SYS_lookup_dcookie: ::c_long = 18; ++pub const SYS_remap_file_pages: ::c_long = 234; ++pub const SYS_getdents64: ::c_long = 61; ++pub const SYS_set_tid_address: ::c_long = 96; ++pub const SYS_restart_syscall: ::c_long = 128; ++pub const SYS_semtimedop: ::c_long = 192; ++pub const SYS_fadvise64: ::c_long = 223; ++pub const SYS_timer_create: ::c_long = 107; ++pub const SYS_timer_settime: ::c_long = 110; ++pub const SYS_timer_gettime: ::c_long = 108; ++pub const SYS_timer_getoverrun: ::c_long = 109; ++pub const SYS_timer_delete: ::c_long = 111; ++pub const SYS_clock_settime: ::c_long = 112; ++pub const SYS_clock_gettime: ::c_long = 113; ++pub const SYS_clock_getres: ::c_long = 114; ++pub const SYS_clock_nanosleep: ::c_long = 115; ++pub const SYS_exit_group: ::c_long = 94; ++pub const SYS_epoll_ctl: ::c_long = 21; ++pub const SYS_tgkill: ::c_long = 131; ++pub const SYS_mbind: ::c_long = 235; ++pub const SYS_set_mempolicy: ::c_long = 237; ++pub const SYS_get_mempolicy: ::c_long = 236; ++pub const SYS_mq_open: ::c_long = 180; ++pub const SYS_mq_unlink: ::c_long = 181; ++pub const SYS_mq_timedsend: ::c_long = 182; ++pub const SYS_mq_timedreceive: ::c_long = 183; ++pub const SYS_mq_notify: ::c_long = 184; ++pub const SYS_mq_getsetattr: ::c_long = 185; ++pub const SYS_kexec_load: ::c_long = 104; ++pub const SYS_waitid: ::c_long = 95; ++pub const SYS_add_key: ::c_long = 217; ++pub const SYS_request_key: ::c_long = 218; ++pub const SYS_keyctl: ::c_long = 219; ++pub const SYS_ioprio_set: ::c_long = 30; ++pub const SYS_ioprio_get: ::c_long = 31; ++pub const SYS_inotify_add_watch: ::c_long = 27; ++pub const SYS_inotify_rm_watch: ::c_long = 28; ++pub const SYS_migrate_pages: ::c_long = 238; ++pub const SYS_openat: ::c_long = 56; ++pub const SYS_mkdirat: ::c_long = 34; ++pub const SYS_mknodat: ::c_long = 33; ++pub const SYS_fchownat: ::c_long = 54; ++pub const SYS_newfstatat: ::c_long = 79; ++pub const SYS_unlinkat: ::c_long = 35; ++pub const SYS_linkat: ::c_long = 37; ++pub const SYS_symlinkat: ::c_long = 36; ++pub const SYS_readlinkat: ::c_long = 78; ++pub const SYS_fchmodat: ::c_long = 53; ++pub const SYS_faccessat: ::c_long = 48; ++pub const SYS_pselect6: ::c_long = 72; ++pub const SYS_ppoll: ::c_long = 73; ++pub const SYS_unshare: ::c_long = 97; ++pub const SYS_set_robust_list: ::c_long = 99; ++pub const SYS_get_robust_list: ::c_long = 100; ++pub const SYS_splice: ::c_long = 76; ++pub const SYS_tee: ::c_long = 77; ++pub const SYS_sync_file_range: ::c_long = 84; ++pub const SYS_vmsplice: ::c_long = 75; ++pub const SYS_move_pages: ::c_long = 239; ++pub const SYS_utimensat: ::c_long = 88; ++pub const SYS_epoll_pwait: ::c_long = 22; ++pub const SYS_timerfd_create: ::c_long = 85; ++pub const SYS_fallocate: ::c_long = 47; ++pub const SYS_timerfd_settime: ::c_long = 86; ++pub const SYS_timerfd_gettime: ::c_long = 87; ++pub const SYS_accept4: ::c_long = 242; ++pub const SYS_signalfd4: ::c_long = 74; ++pub const SYS_eventfd2: ::c_long = 19; ++pub const SYS_epoll_create1: ::c_long = 20; ++pub const SYS_dup3: ::c_long = 24; ++pub const SYS_pipe2: ::c_long = 59; ++pub const SYS_inotify_init1: ::c_long = 26; ++pub const SYS_preadv: ::c_long = 69; ++pub const SYS_pwritev: ::c_long = 70; ++pub const SYS_rt_tgsigqueueinfo: ::c_long = 240; ++pub const SYS_perf_event_open: ::c_long = 241; ++pub const SYS_recvmmsg: ::c_long = 243; ++pub const SYS_fanotify_init: ::c_long = 262; ++pub const SYS_fanotify_mark: ::c_long = 263; ++pub const SYS_prlimit64: ::c_long = 261; ++pub const SYS_name_to_handle_at: ::c_long = 264; ++pub const SYS_open_by_handle_at: ::c_long = 265; ++pub const SYS_clock_adjtime: ::c_long = 266; ++pub const SYS_syncfs: ::c_long = 267; ++pub const SYS_sendmmsg: ::c_long = 269; ++pub const SYS_setns: ::c_long = 268; ++pub const SYS_getcpu: ::c_long = 168; ++pub const SYS_process_vm_readv: ::c_long = 270; ++pub const SYS_process_vm_writev: ::c_long = 271; ++pub const SYS_kcmp: ::c_long = 272; ++pub const SYS_finit_module: ::c_long = 273; ++pub const SYS_sched_setattr: ::c_long = 274; ++pub const SYS_sched_getattr: ::c_long = 275; ++pub const SYS_renameat2: ::c_long = 276; ++pub const SYS_seccomp: ::c_long = 277; ++pub const SYS_getrandom: ::c_long = 278; ++pub const SYS_memfd_create: ::c_long = 279; ++pub const SYS_bpf: ::c_long = 280; ++pub const SYS_execveat: ::c_long = 281; ++pub const SYS_userfaultfd: ::c_long = 282; ++pub const SYS_membarrier: ::c_long = 283; ++pub const SYS_mlock2: ::c_long = 284; ++pub const SYS_copy_file_range: ::c_long = 285; ++pub const SYS_preadv2: ::c_long = 286; ++pub const SYS_pwritev2: ::c_long = 287; ++pub const SYS_pkey_mprotect: ::c_long = 288; ++pub const SYS_pkey_alloc: ::c_long = 289; ++pub const SYS_pkey_free: ::c_long = 290; ++pub const SYS_statx: ::c_long = 291; ++pub const SYS_pidfd_send_signal: ::c_long = 424; ++pub const SYS_io_uring_setup: ::c_long = 425; ++pub const SYS_io_uring_enter: ::c_long = 426; ++pub const SYS_io_uring_register: ::c_long = 427; ++pub const SYS_open_tree: ::c_long = 428; ++pub const SYS_move_mount: ::c_long = 429; ++pub const SYS_fsopen: ::c_long = 430; ++pub const SYS_fsconfig: ::c_long = 431; ++pub const SYS_fsmount: ::c_long = 432; ++pub const SYS_fspick: ::c_long = 433; ++pub const SYS_pidfd_open: ::c_long = 434; ++pub const SYS_clone3: ::c_long = 435; ++pub const SYS_close_range: ::c_long = 436; ++pub const SYS_openat2: ::c_long = 437; ++pub const SYS_pidfd_getfd: ::c_long = 438; ++pub const SYS_faccessat2: ::c_long = 439; ++pub const SYS_process_madvise: ::c_long = 440; ++pub const SYS_epoll_pwait2: ::c_long = 441; ++pub const SYS_mount_setattr: ::c_long = 442; ++ ++cfg_if! { ++ if #[cfg(libc_align)] { ++ mod align; ++ pub use self::align::*; ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/mod.rs +index 6489132..c319b91 100644 +--- a/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/mod.rs +@@ -221,18 +221,6 @@ pub const O_NOFOLLOW: ::c_int = 0x20000; + pub const O_ASYNC: ::c_int = 0x2000; + pub const O_LARGEFILE: ::c_int = 0o0100000; + +-pub const FIOCLEX: ::c_int = 0x5451; +-pub const FIONCLEX: ::c_int = 0x5450; +-pub const FIONBIO: ::c_int = 0x5421; +- +-pub const RLIMIT_RSS: ::c_int = 5; +-pub const RLIMIT_NOFILE: ::c_int = 7; +-pub const RLIMIT_AS: ::c_int = 9; +-pub const RLIMIT_NPROC: ::c_int = 6; +-pub const RLIMIT_MEMLOCK: ::c_int = 8; +-pub const RLIMIT_NLIMITS: ::c_int = 15; +-pub const RLIM_NLIMITS: ::c_int = RLIMIT_NLIMITS; +- + pub const MADV_SOFT_OFFLINE: ::c_int = 101; + pub const MCL_CURRENT: ::c_int = 0x0001; + pub const MCL_FUTURE: ::c_int = 0x0002; +@@ -465,55 +453,9 @@ pub const IEXTEN: ::tcflag_t = 0x00008000; + pub const TOSTOP: ::tcflag_t = 0x00000100; + pub const FLUSHO: ::tcflag_t = 0x00001000; + +-pub const TCGETS: ::c_int = 0x5401; +-pub const TCSETS: ::c_int = 0x5402; +-pub const TCSETSW: ::c_int = 0x5403; +-pub const TCSETSF: ::c_int = 0x5404; +-pub const TCGETA: ::c_int = 0x5405; +-pub const TCSETA: ::c_int = 0x5406; +-pub const TCSETAW: ::c_int = 0x5407; +-pub const TCSETAF: ::c_int = 0x5408; +-pub const TCSBRK: ::c_int = 0x5409; +-pub const TCXONC: ::c_int = 0x540A; +-pub const TCFLSH: ::c_int = 0x540B; +-pub const TIOCGSOFTCAR: ::c_int = 0x5419; +-pub const TIOCSSOFTCAR: ::c_int = 0x541A; +-pub const TIOCLINUX: ::c_int = 0x541C; +-pub const TIOCGSERIAL: ::c_int = 0x541E; +-pub const TIOCEXCL: ::c_int = 0x540C; +-pub const TIOCNXCL: ::c_int = 0x540D; +-pub const TIOCSCTTY: ::c_int = 0x540E; +-pub const TIOCGPGRP: ::c_int = 0x540F; +-pub const TIOCSPGRP: ::c_int = 0x5410; +-pub const TIOCOUTQ: ::c_int = 0x5411; +-pub const TIOCSTI: ::c_int = 0x5412; +-pub const TIOCGWINSZ: ::c_int = 0x5413; +-pub const TIOCSWINSZ: ::c_int = 0x5414; +-pub const TIOCMGET: ::c_int = 0x5415; +-pub const TIOCMBIS: ::c_int = 0x5416; +-pub const TIOCMBIC: ::c_int = 0x5417; +-pub const TIOCMSET: ::c_int = 0x5418; +-pub const FIONREAD: ::c_int = 0x541B; +-pub const TIOCCONS: ::c_int = 0x541D; +- +-pub const TIOCGRS485: ::c_int = 0x542E; +-pub const TIOCSRS485: ::c_int = 0x542F; +- + pub const POLLWRNORM: ::c_short = 0x100; + pub const POLLWRBAND: ::c_short = 0x200; + +-pub const TIOCM_LE: ::c_int = 0x001; +-pub const TIOCM_DTR: ::c_int = 0x002; +-pub const TIOCM_RTS: ::c_int = 0x004; +-pub const TIOCM_ST: ::c_int = 0x008; +-pub const TIOCM_SR: ::c_int = 0x010; +-pub const TIOCM_CTS: ::c_int = 0x020; +-pub const TIOCM_CAR: ::c_int = 0x040; +-pub const TIOCM_RNG: ::c_int = 0x080; +-pub const TIOCM_DSR: ::c_int = 0x100; +-pub const TIOCM_CD: ::c_int = TIOCM_CAR; +-pub const TIOCM_RI: ::c_int = TIOCM_RNG; +- + // Syscall table + pub const SYS_restart_syscall: ::c_long = 0; + pub const SYS_exit: ::c_long = 1; +@@ -914,6 +856,14 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; + + // offsets in user_regs_structs, from sys/reg.h + pub const EBX: ::c_int = 0; +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/align.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/align.rs +index 81c55c6..a4bf9bf 100644 +--- a/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/align.rs ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/align.rs +@@ -24,4 +24,19 @@ s! { + pub pstate: ::c_ulong, + __reserved: [[u64; 32]; 16], + } ++ ++ #[repr(align(8))] ++ pub struct clone_args { ++ pub flags: ::c_ulonglong, ++ pub pidfd: ::c_ulonglong, ++ pub child_tid: ::c_ulonglong, ++ pub parent_tid: ::c_ulonglong, ++ pub exit_signal: ::c_ulonglong, ++ pub stack: ::c_ulonglong, ++ pub stack_size: ::c_ulonglong, ++ pub tls: ::c_ulonglong, ++ pub set_tid: ::c_ulonglong, ++ pub set_tid_size: ::c_ulonglong, ++ pub cgroup: ::c_ulonglong, ++ } + } +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/int128.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/int128.rs +new file mode 100644 +index 0000000..4535e73 +--- /dev/null ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/int128.rs +@@ -0,0 +1,7 @@ ++s! { ++ pub struct user_fpsimd_struct { ++ pub vregs: [::__uint128_t; 32], ++ pub fpsr: u32, ++ pub fpcr: u32, ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs +index 73162c9..14b4bc6 100644 +--- a/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs +@@ -1,5 +1,6 @@ + pub type c_char = u8; + pub type __u64 = ::c_ulonglong; ++pub type __s64 = ::c_longlong; + pub type wchar_t = u32; + pub type nlink_t = u32; + pub type blksize_t = ::c_int; +@@ -49,6 +50,13 @@ s! { + __unused: [::c_uint; 2], + } + ++ pub struct user_regs_struct { ++ pub regs: [::c_ulonglong; 31], ++ pub sp: ::c_ulonglong, ++ pub pc: ::c_ulonglong, ++ pub pstate: ::c_ulonglong, ++ } ++ + pub struct ipc_perm { + pub __ipc_perm_key: ::key_t, + pub uid: ::uid_t, +@@ -548,10 +556,15 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +-pub const RLIMIT_NLIMITS: ::c_int = 15; +-pub const RLIM_NLIMITS: ::c_int = RLIMIT_NLIMITS; +-pub const TIOCINQ: ::c_int = ::FIONREAD; + pub const MCL_CURRENT: ::c_int = 0x0001; + pub const MCL_FUTURE: ::c_int = 0x0002; + pub const CBAUD: ::tcflag_t = 0o0010017; +@@ -621,9 +634,6 @@ pub const B3000000: ::speed_t = 0o010015; + pub const B3500000: ::speed_t = 0o010016; + pub const B4000000: ::speed_t = 0o010017; + +-pub const FIOCLEX: ::c_int = 0x5451; +-pub const FIONCLEX: ::c_int = 0x5450; +-pub const FIONBIO: ::c_int = 0x5421; + pub const EDEADLK: ::c_int = 35; + pub const EDEADLOCK: ::c_int = EDEADLK; + +@@ -634,55 +644,6 @@ pub const VMIN: usize = 6; + pub const IEXTEN: ::tcflag_t = 0x00008000; + pub const TOSTOP: ::tcflag_t = 0x00000100; + pub const FLUSHO: ::tcflag_t = 0x00001000; +-pub const TCGETS: ::c_int = 0x5401; +-pub const TCSETS: ::c_int = 0x5402; +-pub const TCSETSW: ::c_int = 0x5403; +-pub const TCSETSF: ::c_int = 0x5404; +-pub const TCGETA: ::c_int = 0x5405; +-pub const TCSETA: ::c_int = 0x5406; +-pub const TCSETAW: ::c_int = 0x5407; +-pub const TCSETAF: ::c_int = 0x5408; +-pub const TCSBRK: ::c_int = 0x5409; +-pub const TCXONC: ::c_int = 0x540A; +-pub const TCFLSH: ::c_int = 0x540B; +-pub const TIOCGSOFTCAR: ::c_int = 0x5419; +-pub const TIOCSSOFTCAR: ::c_int = 0x541A; +-pub const TIOCLINUX: ::c_int = 0x541C; +-pub const TIOCGSERIAL: ::c_int = 0x541E; +-pub const TIOCEXCL: ::c_int = 0x540C; +-pub const TIOCNXCL: ::c_int = 0x540D; +-pub const TIOCSCTTY: ::c_int = 0x540E; +-pub const TIOCGPGRP: ::c_int = 0x540F; +-pub const TIOCSPGRP: ::c_int = 0x5410; +-pub const TIOCOUTQ: ::c_int = 0x5411; +-pub const TIOCSTI: ::c_int = 0x5412; +-pub const TIOCGWINSZ: ::c_int = 0x5413; +-pub const TIOCSWINSZ: ::c_int = 0x5414; +-pub const TIOCMGET: ::c_int = 0x5415; +-pub const TIOCMBIS: ::c_int = 0x5416; +-pub const TIOCMBIC: ::c_int = 0x5417; +-pub const TIOCMSET: ::c_int = 0x5418; +-pub const FIONREAD: ::c_int = 0x541B; +-pub const TIOCCONS: ::c_int = 0x541D; +- +-pub const TIOCGRS485: ::c_int = 0x542E; +-pub const TIOCSRS485: ::c_int = 0x542F; +- +-pub const TIOCM_LE: ::c_int = 0x001; +-pub const TIOCM_DTR: ::c_int = 0x002; +-pub const TIOCM_RTS: ::c_int = 0x004; +-pub const TIOCM_ST: ::c_int = 0x008; +-pub const TIOCM_SR: ::c_int = 0x010; +-pub const TIOCM_CTS: ::c_int = 0x020; +-pub const TIOCM_CAR: ::c_int = 0x040; +-pub const TIOCM_RNG: ::c_int = 0x080; +-pub const TIOCM_DSR: ::c_int = 0x100; +-pub const TIOCM_CD: ::c_int = TIOCM_CAR; +-pub const TIOCM_RI: ::c_int = TIOCM_RNG; +- +-extern "C" { +- pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; +-} + + cfg_if! { + if #[cfg(libc_align)] { +@@ -690,3 +651,10 @@ cfg_if! { + pub use self::align::*; + } + } ++ ++cfg_if! { ++ if #[cfg(libc_int128)] { ++ mod int128; ++ pub use self::int128::*; ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs +index 4605a07..22ac916 100644 +--- a/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs +@@ -1,6 +1,7 @@ + pub type c_char = i8; + pub type wchar_t = i32; + pub type __u64 = ::c_ulong; ++pub type __s64 = ::c_long; + pub type nlink_t = u64; + pub type blksize_t = i64; + +@@ -444,6 +445,14 @@ pub const SYS_faccessat2: ::c_long = 5000 + 439; + pub const SYS_process_madvise: ::c_long = 5000 + 440; + pub const SYS_epoll_pwait2: ::c_long = 5000 + 441; + pub const SYS_mount_setattr: ::c_long = 5000 + 442; ++pub const SYS_quotactl_fd: ::c_long = 5000 + 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 5000 + 444; ++pub const SYS_landlock_add_rule: ::c_long = 5000 + 445; ++pub const SYS_landlock_restrict_self: ::c_long = 5000 + 446; ++pub const SYS_memfd_secret: ::c_long = 5000 + 447; ++pub const SYS_process_mrelease: ::c_long = 5000 + 448; ++pub const SYS_futex_waitv: ::c_long = 5000 + 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 5000 + 450; + + pub const O_DIRECT: ::c_int = 0x8000; + pub const O_DIRECTORY: ::c_int = 0x10000; +@@ -458,6 +467,7 @@ pub const O_SYNC: ::c_int = 0x4010; + pub const O_RSYNC: ::c_int = 0x4010; + pub const O_DSYNC: ::c_int = 0x10; + pub const O_ASYNC: ::c_int = 0x1000; ++pub const O_LARGEFILE: ::c_int = 0x2000; + + pub const EDEADLK: ::c_int = 45; + pub const ENAMETOOLONG: ::c_int = 78; +@@ -505,6 +515,7 @@ pub const ENOPROTOOPT: ::c_int = 99; + pub const EPROTONOSUPPORT: ::c_int = 120; + pub const ESOCKTNOSUPPORT: ::c_int = 121; + pub const EOPNOTSUPP: ::c_int = 122; ++pub const ENOTSUP: ::c_int = EOPNOTSUPP; + pub const EPFNOSUPPORT: ::c_int = 123; + pub const EAFNOSUPPORT: ::c_int = 124; + pub const EADDRINUSE: ::c_int = 125; +@@ -557,10 +568,6 @@ pub const MAP_HUGETLB: ::c_int = 0x080000; + pub const SOCK_STREAM: ::c_int = 2; + pub const SOCK_DGRAM: ::c_int = 1; + +-pub const FIOCLEX: ::c_int = 0x6601; +-pub const FIONCLEX: ::c_int = 0x6602; +-pub const FIONBIO: ::c_int = 0x667e; +- + pub const SA_ONSTACK: ::c_int = 0x08000000; + pub const SA_SIGINFO: ::c_int = 0x00000008; + pub const SA_NOCLDWAIT: ::c_int = 0x00010000; +@@ -609,38 +616,6 @@ pub const F_OFD_GETLK: ::c_int = 36; + pub const F_OFD_SETLK: ::c_int = 37; + pub const F_OFD_SETLKW: ::c_int = 38; + +-pub const TCGETS: ::c_int = 0x540d; +-pub const TCSETS: ::c_int = 0x540e; +-pub const TCSETSW: ::c_int = 0x540f; +-pub const TCSETSF: ::c_int = 0x5410; +-pub const TCGETA: ::c_int = 0x5401; +-pub const TCSETA: ::c_int = 0x5402; +-pub const TCSETAW: ::c_int = 0x5403; +-pub const TCSETAF: ::c_int = 0x5404; +-pub const TCSBRK: ::c_int = 0x5405; +-pub const TCXONC: ::c_int = 0x5406; +-pub const TCFLSH: ::c_int = 0x5407; +-pub const TIOCGSOFTCAR: ::c_int = 0x5481; +-pub const TIOCSSOFTCAR: ::c_int = 0x5482; +-pub const TIOCINQ: ::c_int = 0x467f; +-pub const TIOCLINUX: ::c_int = 0x5483; +-pub const TIOCGSERIAL: ::c_int = 0x5484; +-pub const TIOCEXCL: ::c_int = 0x740d; +-pub const TIOCNXCL: ::c_int = 0x740e; +-pub const TIOCSCTTY: ::c_int = 0x5480; +-pub const TIOCGPGRP: ::c_int = 0x40047477; +-pub const TIOCSPGRP: ::c_int = 0x80047476_u32 as i32; +-pub const TIOCOUTQ: ::c_int = 0x7472; +-pub const TIOCSTI: ::c_int = 0x5472; +-pub const TIOCGWINSZ: ::c_int = 0x40087468; +-pub const TIOCSWINSZ: ::c_int = 0x80087467_u32 as i32; +-pub const TIOCMGET: ::c_int = 0x741d; +-pub const TIOCMBIS: ::c_int = 0x741b; +-pub const TIOCMBIC: ::c_int = 0x741c; +-pub const TIOCMSET: ::c_int = 0x741a; +-pub const FIONREAD: ::c_int = 0x467f; +-pub const TIOCCONS: ::c_int = 0x80047478_u32 as i32; +- + pub const MCL_CURRENT: ::c_int = 0x0001; + pub const MCL_FUTURE: ::c_int = 0x0002; + +@@ -696,7 +671,6 @@ pub const FFDLY: ::tcflag_t = 0o100000; + pub const VTDLY: ::tcflag_t = 0o040000; + pub const XTABS: ::tcflag_t = 0o014000; + +-pub const BOTHER: ::speed_t = 0o010000; + pub const B57600: ::speed_t = 0o010001; + pub const B115200: ::speed_t = 0o010002; + pub const B230400: ::speed_t = 0o010003; +@@ -713,15 +687,4 @@ pub const B3000000: ::speed_t = 0o010015; + pub const B3500000: ::speed_t = 0o010016; + pub const B4000000: ::speed_t = 0o010017; + +-pub const TIOCM_ST: ::c_int = 0x010; +-pub const TIOCM_SR: ::c_int = 0x020; +-pub const TIOCM_CTS: ::c_int = 0x040; +-pub const TIOCM_CAR: ::c_int = 0x100; +-pub const TIOCM_RNG: ::c_int = 0x200; +-pub const TIOCM_DSR: ::c_int = 0x400; +- + pub const EHWPOISON: ::c_int = 168; +- +-extern "C" { +- pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; +-} +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/mod.rs +index cfcdaae..f437355 100644 +--- a/vendor/libc/src/unix/linux_like/linux/musl/b64/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/mod.rs +@@ -132,12 +132,7 @@ s! { + + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +- +-pub const RLIMIT_RSS: ::c_int = 5; +-pub const RLIMIT_NOFILE: ::c_int = 7; +-pub const RLIMIT_AS: ::c_int = 9; +-pub const RLIMIT_NPROC: ::c_int = 6; +-pub const RLIMIT_MEMLOCK: ::c_int = 8; ++pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + + pub const SOCK_NONBLOCK: ::c_int = 2048; + +@@ -163,6 +158,9 @@ cfg_if! { + } else if #[cfg(any(target_arch = "x86_64"))] { + mod x86_64; + pub use self::x86_64::*; ++ } else if #[cfg(any(target_arch = "riscv64"))] { ++ mod riscv64; ++ pub use self::riscv64::*; + } else { + // Unknown target_arch + } +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/powerpc64.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/powerpc64.rs +index d7e233a..0bb4cf8 100644 +--- a/vendor/libc/src/unix/linux_like/linux/musl/b64/powerpc64.rs ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/powerpc64.rs +@@ -1,6 +1,7 @@ + pub type c_char = u8; + pub type wchar_t = i32; + pub type __u64 = ::c_ulong; ++pub type __s64 = ::c_long; + pub type nlink_t = u64; + pub type blksize_t = ::c_long; + +@@ -600,10 +601,15 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; + +-pub const FIOCLEX: ::c_int = 0x20006601; +-pub const FIONCLEX: ::c_int = 0x20006602; +-pub const FIONBIO: ::c_int = 0x8004667e; + pub const EDEADLK: ::c_int = 58; + pub const EDEADLOCK: ::c_int = EDEADLK; + +@@ -614,53 +620,7 @@ pub const VMIN: usize = 5; + pub const IEXTEN: ::tcflag_t = 0x00000400; + pub const TOSTOP: ::tcflag_t = 0x00400000; + pub const FLUSHO: ::tcflag_t = 0x00800000; +-pub const TCGETS: ::c_int = 0x403c7413; +-pub const TCSETS: ::c_int = 0x803c7414; +-pub const TCSETSW: ::c_int = 0x803c7415; +-pub const TCSETSF: ::c_int = 0x803c7416; +-pub const TCGETA: ::c_int = 0x40147417; +-pub const TCSETA: ::c_int = 0x80147418; +-pub const TCSETAW: ::c_int = 0x80147419; +-pub const TCSETAF: ::c_int = 0x8014741c; +-pub const TCSBRK: ::c_int = 0x2000741d; +-pub const TCXONC: ::c_int = 0x2000741e; +-pub const TCFLSH: ::c_int = 0x2000741f; +-pub const TIOCGSOFTCAR: ::c_int = 0x5419; +-pub const TIOCSSOFTCAR: ::c_int = 0x541A; +-pub const TIOCLINUX: ::c_int = 0x541C; +-pub const TIOCGSERIAL: ::c_int = 0x541E; +-pub const TIOCEXCL: ::c_int = 0x540C; +-pub const TIOCNXCL: ::c_int = 0x540D; +-pub const TIOCSCTTY: ::c_int = 0x540E; +-pub const TIOCGPGRP: ::c_int = 0x40047477; +-pub const TIOCSPGRP: ::c_int = 0x80047476; +-pub const TIOCOUTQ: ::c_int = 0x40047473; +-pub const TIOCGWINSZ: ::c_int = 0x40087468; +-pub const TIOCSWINSZ: ::c_int = 0x80087467; +-pub const TIOCMGET: ::c_int = 0x5415; +-pub const TIOCMBIS: ::c_int = 0x5416; +-pub const TIOCMBIC: ::c_int = 0x5417; +-pub const TIOCMSET: ::c_int = 0x5418; +-pub const FIONREAD: ::c_int = 0x4004667f; +-pub const TIOCCONS: ::c_int = 0x541D; +-pub const TIOCM_LE: ::c_int = 0x001; +-pub const TIOCM_DTR: ::c_int = 0x002; +-pub const TIOCM_RTS: ::c_int = 0x004; +-pub const TIOCM_ST: ::c_int = 0x008; +-pub const TIOCM_SR: ::c_int = 0x010; +-pub const TIOCM_CTS: ::c_int = 0x020; +-pub const TIOCM_CAR: ::c_int = 0x040; +-pub const TIOCM_RNG: ::c_int = 0x080; +-pub const TIOCM_DSR: ::c_int = 0x100; +-pub const TIOCM_CD: ::c_int = TIOCM_CAR; +-pub const TIOCM_RI: ::c_int = TIOCM_RNG; + +-pub const TIOCGRS485: ::c_int = 0x542E; +-pub const TIOCSRS485: ::c_int = 0x542F; +- +-pub const RLIMIT_NLIMITS: ::c_int = 15; +-pub const RLIM_NLIMITS: ::c_int = RLIMIT_NLIMITS; +-pub const TIOCINQ: ::c_int = ::FIONREAD; + pub const MCL_CURRENT: ::c_int = 0x2000; + pub const MCL_FUTURE: ::c_int = 0x4000; + pub const CBAUD: ::tcflag_t = 0xff; +@@ -732,7 +692,3 @@ pub const B2500000: ::speed_t = 0o00033; + pub const B3000000: ::speed_t = 0o00034; + pub const B3500000: ::speed_t = 0o00035; + pub const B4000000: ::speed_t = 0o00036; +- +-extern "C" { +- pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; +-} +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/align.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/align.rs +new file mode 100644 +index 0000000..48d152a +--- /dev/null ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/align.rs +@@ -0,0 +1,44 @@ ++s_no_extra_traits! { ++ #[allow(missing_debug_implementations)] ++ pub struct ucontext_t { ++ pub __uc_flags: ::c_ulong, ++ pub uc_link: *mut ucontext_t, ++ pub uc_stack: ::stack_t, ++ pub uc_sigmask: ::sigset_t, ++ pub uc_mcontext: mcontext_t, ++ } ++ ++ #[allow(missing_debug_implementations)] ++ #[repr(align(16))] ++ pub struct mcontext_t { ++ pub __gregs: [::c_ulong; 32], ++ pub __fpregs: __riscv_mc_fp_state, ++ } ++ ++ #[allow(missing_debug_implementations)] ++ pub union __riscv_mc_fp_state { ++ pub __f: __riscv_mc_f_ext_state, ++ pub __d: __riscv_mc_d_ext_state, ++ pub __q: __riscv_mc_q_ext_state, ++ } ++ ++ #[allow(missing_debug_implementations)] ++ pub struct __riscv_mc_f_ext_state { ++ pub __f: [::c_uint; 32], ++ pub __fcsr: ::c_uint, ++ } ++ ++ #[allow(missing_debug_implementations)] ++ pub struct __riscv_mc_d_ext_state { ++ pub __f: [::c_ulonglong; 32], ++ pub __fcsr: ::c_uint, ++ } ++ ++ #[allow(missing_debug_implementations)] ++ #[repr(align(16))] ++ pub struct __riscv_mc_q_ext_state { ++ pub __f: [::c_ulonglong; 64], ++ pub __fcsr: ::c_uint, ++ pub __glibc_reserved: [::c_uint; 3], ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs +new file mode 100644 +index 0000000..f354293 +--- /dev/null ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs +@@ -0,0 +1,742 @@ ++//! RISC-V-specific definitions for 64-bit linux-like values ++ ++pub type c_char = u8; ++pub type wchar_t = ::c_int; ++ ++pub type nlink_t = ::c_uint; ++pub type blksize_t = ::c_int; ++pub type fsblkcnt64_t = ::c_ulong; ++pub type fsfilcnt64_t = ::c_ulong; ++pub type __u64 = ::c_ulonglong; ++pub type __s64 = ::c_longlong; ++ ++s! { ++ pub struct pthread_attr_t { ++ __size: [::c_ulong; 7], ++ } ++ ++ pub struct stat { ++ pub st_dev: ::dev_t, ++ pub st_ino: ::ino_t, ++ pub st_mode: ::mode_t, ++ pub st_nlink: ::nlink_t, ++ pub st_uid: ::uid_t, ++ pub st_gid: ::gid_t, ++ pub st_rdev: ::dev_t, ++ pub __pad1: ::dev_t, ++ pub st_size: ::off_t, ++ pub st_blksize: ::blksize_t, ++ pub __pad2: ::c_int, ++ pub st_blocks: ::blkcnt_t, ++ pub st_atime: ::time_t, ++ pub st_atime_nsec: ::c_long, ++ pub st_mtime: ::time_t, ++ pub st_mtime_nsec: ::c_long, ++ pub st_ctime: ::time_t, ++ pub st_ctime_nsec: ::c_long, ++ __unused: [::c_int; 2usize], ++ } ++ ++ pub struct stat64 { ++ pub st_dev: ::dev_t, ++ pub st_ino: ::ino64_t, ++ pub st_mode: ::mode_t, ++ pub st_nlink: ::nlink_t, ++ pub st_uid: ::uid_t, ++ pub st_gid: ::gid_t, ++ pub st_rdev: ::dev_t, ++ pub __pad1: ::dev_t, ++ pub st_size: ::off64_t, ++ pub st_blksize: ::blksize_t, ++ pub __pad2: ::c_int, ++ pub st_blocks: ::blkcnt_t, ++ pub st_atime: ::time_t, ++ pub st_atime_nsec: ::c_long, ++ pub st_mtime: ::time_t, ++ pub st_mtime_nsec: ::c_long, ++ pub st_ctime: ::time_t, ++ pub st_ctime_nsec: ::c_long, ++ __unused: [::c_int; 2], ++ } ++ ++ pub struct statfs { ++ pub f_type: ::c_long, ++ pub f_bsize: ::c_long, ++ pub f_blocks: ::fsblkcnt_t, ++ pub f_bfree: ::fsblkcnt_t, ++ pub f_bavail: ::fsblkcnt_t, ++ pub f_files: ::fsfilcnt_t, ++ pub f_ffree: ::fsfilcnt_t, ++ pub f_fsid: ::fsid_t, ++ pub f_namelen: ::c_long, ++ pub f_frsize: ::c_long, ++ pub f_flags: ::c_long, ++ pub f_spare: [::c_long; 4], ++ } ++ ++ pub struct statfs64 { ++ pub f_type: ::c_long, ++ pub f_bsize: ::c_long, ++ pub f_blocks: ::fsblkcnt64_t, ++ pub f_bfree: ::fsblkcnt64_t, ++ pub f_bavail: ::fsblkcnt64_t, ++ pub f_files: ::fsfilcnt64_t, ++ pub f_ffree: ::fsfilcnt64_t, ++ pub f_fsid: ::fsid_t, ++ pub f_namelen: ::c_long, ++ pub f_frsize: ::c_long, ++ pub f_flags: ::c_long, ++ pub f_spare: [::c_long; 4], ++ } ++ ++ pub struct statvfs { ++ pub f_bsize: ::c_ulong, ++ pub f_frsize: ::c_ulong, ++ pub f_blocks: ::fsblkcnt_t, ++ pub f_bfree: ::fsblkcnt_t, ++ pub f_bavail: ::fsblkcnt_t, ++ pub f_files: ::fsfilcnt_t, ++ pub f_ffree: ::fsfilcnt_t, ++ pub f_favail: ::fsfilcnt_t, ++ pub f_fsid: ::c_ulong, ++ pub f_flag: ::c_ulong, ++ pub f_namemax: ::c_ulong, ++ pub __f_spare: [::c_int; 6], ++ } ++ ++ pub struct statvfs64 { ++ pub f_bsize: ::c_ulong, ++ pub f_frsize: ::c_ulong, ++ pub f_blocks: ::fsblkcnt64_t, ++ pub f_bfree: ::fsblkcnt64_t, ++ pub f_bavail: ::fsblkcnt64_t, ++ pub f_files: ::fsfilcnt64_t, ++ pub f_ffree: ::fsfilcnt64_t, ++ pub f_favail: ::fsfilcnt64_t, ++ pub f_fsid: ::c_ulong, ++ pub f_flag: ::c_ulong, ++ pub f_namemax: ::c_ulong, ++ pub __f_spare: [::c_int; 6], ++ } ++ ++ pub struct siginfo_t { ++ pub si_signo: ::c_int, ++ pub si_errno: ::c_int, ++ pub si_code: ::c_int, ++ #[doc(hidden)] ++ #[deprecated( ++ since="0.2.54", ++ note="Please leave a comment on \ ++ https://github.com/rust-lang/libc/pull/1316 if you're using \ ++ this field" ++ )] ++ pub _pad: [::c_int; 29], ++ _align: [u64; 0], ++ } ++ ++ pub struct stack_t { ++ pub ss_sp: *mut ::c_void, ++ pub ss_flags: ::c_int, ++ pub ss_size: ::size_t, ++ } ++ ++ pub struct sigaction { ++ pub sa_sigaction: ::sighandler_t, ++ pub sa_mask: ::sigset_t, ++ pub sa_flags: ::c_int, ++ pub sa_restorer: ::Option, ++ } ++ ++ pub struct ipc_perm { ++ pub __key: ::key_t, ++ pub uid: ::uid_t, ++ pub gid: ::gid_t, ++ pub cuid: ::uid_t, ++ pub cgid: ::gid_t, ++ pub mode: ::c_ushort, ++ __pad1: ::c_ushort, ++ pub __seq: ::c_ushort, ++ __pad2: ::c_ushort, ++ __unused1: ::c_ulong, ++ __unused2: ::c_ulong, ++ } ++ ++ pub struct shmid_ds { ++ pub shm_perm: ::ipc_perm, ++ pub shm_segsz: ::size_t, ++ pub shm_atime: ::time_t, ++ pub shm_dtime: ::time_t, ++ pub shm_ctime: ::time_t, ++ pub shm_cpid: ::pid_t, ++ pub shm_lpid: ::pid_t, ++ pub shm_nattch: ::shmatt_t, ++ __unused5: ::c_ulong, ++ __unused6: ::c_ulong, ++ } ++ ++ pub struct flock { ++ pub l_type: ::c_short, ++ pub l_whence: ::c_short, ++ pub l_start: ::off_t, ++ pub l_len: ::off_t, ++ pub l_pid: ::pid_t, ++ } ++ ++ pub struct flock64 { ++ pub l_type: ::c_short, ++ pub l_whence: ::c_short, ++ pub l_start: ::off64_t, ++ pub l_len: ::off64_t, ++ pub l_pid: ::pid_t, ++ } ++} ++ ++pub const SYS_read: ::c_long = 63; ++pub const SYS_write: ::c_long = 64; ++pub const SYS_close: ::c_long = 57; ++pub const SYS_fstat: ::c_long = 80; ++pub const SYS_lseek: ::c_long = 62; ++pub const SYS_mmap: ::c_long = 222; ++pub const SYS_mprotect: ::c_long = 226; ++pub const SYS_munmap: ::c_long = 215; ++pub const SYS_brk: ::c_long = 214; ++pub const SYS_rt_sigaction: ::c_long = 134; ++pub const SYS_rt_sigprocmask: ::c_long = 135; ++pub const SYS_rt_sigreturn: ::c_long = 139; ++pub const SYS_ioctl: ::c_long = 29; ++pub const SYS_pread64: ::c_long = 67; ++pub const SYS_pwrite64: ::c_long = 68; ++pub const SYS_readv: ::c_long = 65; ++pub const SYS_writev: ::c_long = 66; ++pub const SYS_sched_yield: ::c_long = 124; ++pub const SYS_mremap: ::c_long = 216; ++pub const SYS_msync: ::c_long = 227; ++pub const SYS_mincore: ::c_long = 232; ++pub const SYS_madvise: ::c_long = 233; ++pub const SYS_shmget: ::c_long = 194; ++pub const SYS_shmat: ::c_long = 196; ++pub const SYS_shmctl: ::c_long = 195; ++pub const SYS_dup: ::c_long = 23; ++pub const SYS_nanosleep: ::c_long = 101; ++pub const SYS_getitimer: ::c_long = 102; ++pub const SYS_setitimer: ::c_long = 103; ++pub const SYS_getpid: ::c_long = 172; ++pub const SYS_sendfile: ::c_long = 71; ++pub const SYS_socket: ::c_long = 198; ++pub const SYS_connect: ::c_long = 203; ++pub const SYS_accept: ::c_long = 202; ++pub const SYS_sendto: ::c_long = 206; ++pub const SYS_recvfrom: ::c_long = 207; ++pub const SYS_sendmsg: ::c_long = 211; ++pub const SYS_recvmsg: ::c_long = 212; ++pub const SYS_shutdown: ::c_long = 210; ++pub const SYS_bind: ::c_long = 200; ++pub const SYS_listen: ::c_long = 201; ++pub const SYS_getsockname: ::c_long = 204; ++pub const SYS_getpeername: ::c_long = 205; ++pub const SYS_socketpair: ::c_long = 199; ++pub const SYS_setsockopt: ::c_long = 208; ++pub const SYS_getsockopt: ::c_long = 209; ++pub const SYS_clone: ::c_long = 220; ++pub const SYS_execve: ::c_long = 221; ++pub const SYS_exit: ::c_long = 93; ++pub const SYS_wait4: ::c_long = 260; ++pub const SYS_kill: ::c_long = 129; ++pub const SYS_uname: ::c_long = 160; ++pub const SYS_semget: ::c_long = 190; ++pub const SYS_semop: ::c_long = 193; ++pub const SYS_semctl: ::c_long = 191; ++pub const SYS_shmdt: ::c_long = 197; ++pub const SYS_msgget: ::c_long = 186; ++pub const SYS_msgsnd: ::c_long = 189; ++pub const SYS_msgrcv: ::c_long = 188; ++pub const SYS_msgctl: ::c_long = 187; ++pub const SYS_fcntl: ::c_long = 25; ++pub const SYS_flock: ::c_long = 32; ++pub const SYS_fsync: ::c_long = 82; ++pub const SYS_fdatasync: ::c_long = 83; ++pub const SYS_truncate: ::c_long = 45; ++pub const SYS_ftruncate: ::c_long = 46; ++pub const SYS_getcwd: ::c_long = 17; ++pub const SYS_chdir: ::c_long = 49; ++pub const SYS_fchdir: ::c_long = 50; ++pub const SYS_fchmod: ::c_long = 52; ++pub const SYS_fchown: ::c_long = 55; ++pub const SYS_umask: ::c_long = 166; ++pub const SYS_gettimeofday: ::c_long = 169; ++pub const SYS_getrlimit: ::c_long = 163; ++pub const SYS_getrusage: ::c_long = 165; ++pub const SYS_sysinfo: ::c_long = 179; ++pub const SYS_times: ::c_long = 153; ++pub const SYS_ptrace: ::c_long = 117; ++pub const SYS_getuid: ::c_long = 174; ++pub const SYS_syslog: ::c_long = 116; ++pub const SYS_getgid: ::c_long = 176; ++pub const SYS_setuid: ::c_long = 146; ++pub const SYS_setgid: ::c_long = 144; ++pub const SYS_geteuid: ::c_long = 175; ++pub const SYS_getegid: ::c_long = 177; ++pub const SYS_setpgid: ::c_long = 154; ++pub const SYS_getppid: ::c_long = 173; ++pub const SYS_setsid: ::c_long = 157; ++pub const SYS_setreuid: ::c_long = 145; ++pub const SYS_setregid: ::c_long = 143; ++pub const SYS_getgroups: ::c_long = 158; ++pub const SYS_setgroups: ::c_long = 159; ++pub const SYS_setresuid: ::c_long = 147; ++pub const SYS_getresuid: ::c_long = 148; ++pub const SYS_setresgid: ::c_long = 149; ++pub const SYS_getresgid: ::c_long = 150; ++pub const SYS_getpgid: ::c_long = 155; ++pub const SYS_setfsuid: ::c_long = 151; ++pub const SYS_setfsgid: ::c_long = 152; ++pub const SYS_getsid: ::c_long = 156; ++pub const SYS_capget: ::c_long = 90; ++pub const SYS_capset: ::c_long = 91; ++pub const SYS_rt_sigpending: ::c_long = 136; ++pub const SYS_rt_sigtimedwait: ::c_long = 137; ++pub const SYS_rt_sigqueueinfo: ::c_long = 138; ++pub const SYS_rt_sigsuspend: ::c_long = 133; ++pub const SYS_sigaltstack: ::c_long = 132; ++pub const SYS_personality: ::c_long = 92; ++pub const SYS_statfs: ::c_long = 43; ++pub const SYS_fstatfs: ::c_long = 44; ++pub const SYS_getpriority: ::c_long = 141; ++pub const SYS_setpriority: ::c_long = 140; ++pub const SYS_sched_setparam: ::c_long = 118; ++pub const SYS_sched_getparam: ::c_long = 121; ++pub const SYS_sched_setscheduler: ::c_long = 119; ++pub const SYS_sched_getscheduler: ::c_long = 120; ++pub const SYS_sched_get_priority_max: ::c_long = 125; ++pub const SYS_sched_get_priority_min: ::c_long = 126; ++pub const SYS_sched_rr_get_interval: ::c_long = 127; ++pub const SYS_mlock: ::c_long = 228; ++pub const SYS_munlock: ::c_long = 229; ++pub const SYS_mlockall: ::c_long = 230; ++pub const SYS_munlockall: ::c_long = 231; ++pub const SYS_vhangup: ::c_long = 58; ++pub const SYS_pivot_root: ::c_long = 41; ++pub const SYS_prctl: ::c_long = 167; ++pub const SYS_adjtimex: ::c_long = 171; ++pub const SYS_setrlimit: ::c_long = 164; ++pub const SYS_chroot: ::c_long = 51; ++pub const SYS_sync: ::c_long = 81; ++pub const SYS_acct: ::c_long = 89; ++pub const SYS_settimeofday: ::c_long = 170; ++pub const SYS_mount: ::c_long = 40; ++pub const SYS_umount2: ::c_long = 39; ++pub const SYS_swapon: ::c_long = 224; ++pub const SYS_swapoff: ::c_long = 225; ++pub const SYS_reboot: ::c_long = 142; ++pub const SYS_sethostname: ::c_long = 161; ++pub const SYS_setdomainname: ::c_long = 162; ++pub const SYS_init_module: ::c_long = 105; ++pub const SYS_delete_module: ::c_long = 106; ++pub const SYS_quotactl: ::c_long = 60; ++pub const SYS_nfsservctl: ::c_long = 42; ++pub const SYS_gettid: ::c_long = 178; ++pub const SYS_readahead: ::c_long = 213; ++pub const SYS_setxattr: ::c_long = 5; ++pub const SYS_lsetxattr: ::c_long = 6; ++pub const SYS_fsetxattr: ::c_long = 7; ++pub const SYS_getxattr: ::c_long = 8; ++pub const SYS_lgetxattr: ::c_long = 9; ++pub const SYS_fgetxattr: ::c_long = 10; ++pub const SYS_listxattr: ::c_long = 11; ++pub const SYS_llistxattr: ::c_long = 12; ++pub const SYS_flistxattr: ::c_long = 13; ++pub const SYS_removexattr: ::c_long = 14; ++pub const SYS_lremovexattr: ::c_long = 15; ++pub const SYS_fremovexattr: ::c_long = 16; ++pub const SYS_tkill: ::c_long = 130; ++pub const SYS_futex: ::c_long = 98; ++pub const SYS_sched_setaffinity: ::c_long = 122; ++pub const SYS_sched_getaffinity: ::c_long = 123; ++pub const SYS_io_setup: ::c_long = 0; ++pub const SYS_io_destroy: ::c_long = 1; ++pub const SYS_io_getevents: ::c_long = 4; ++pub const SYS_io_submit: ::c_long = 2; ++pub const SYS_io_cancel: ::c_long = 3; ++pub const SYS_lookup_dcookie: ::c_long = 18; ++pub const SYS_remap_file_pages: ::c_long = 234; ++pub const SYS_getdents64: ::c_long = 61; ++pub const SYS_set_tid_address: ::c_long = 96; ++pub const SYS_restart_syscall: ::c_long = 128; ++pub const SYS_semtimedop: ::c_long = 192; ++pub const SYS_fadvise64: ::c_long = 223; ++pub const SYS_timer_create: ::c_long = 107; ++pub const SYS_timer_settime: ::c_long = 110; ++pub const SYS_timer_gettime: ::c_long = 108; ++pub const SYS_timer_getoverrun: ::c_long = 109; ++pub const SYS_timer_delete: ::c_long = 111; ++pub const SYS_clock_settime: ::c_long = 112; ++pub const SYS_clock_gettime: ::c_long = 113; ++pub const SYS_clock_getres: ::c_long = 114; ++pub const SYS_clock_nanosleep: ::c_long = 115; ++pub const SYS_exit_group: ::c_long = 94; ++pub const SYS_epoll_ctl: ::c_long = 21; ++pub const SYS_tgkill: ::c_long = 131; ++pub const SYS_mbind: ::c_long = 235; ++pub const SYS_set_mempolicy: ::c_long = 237; ++pub const SYS_get_mempolicy: ::c_long = 236; ++pub const SYS_mq_open: ::c_long = 180; ++pub const SYS_mq_unlink: ::c_long = 181; ++pub const SYS_mq_timedsend: ::c_long = 182; ++pub const SYS_mq_timedreceive: ::c_long = 183; ++pub const SYS_mq_notify: ::c_long = 184; ++pub const SYS_mq_getsetattr: ::c_long = 185; ++pub const SYS_kexec_load: ::c_long = 104; ++pub const SYS_waitid: ::c_long = 95; ++pub const SYS_add_key: ::c_long = 217; ++pub const SYS_request_key: ::c_long = 218; ++pub const SYS_keyctl: ::c_long = 219; ++pub const SYS_ioprio_set: ::c_long = 30; ++pub const SYS_ioprio_get: ::c_long = 31; ++pub const SYS_inotify_add_watch: ::c_long = 27; ++pub const SYS_inotify_rm_watch: ::c_long = 28; ++pub const SYS_migrate_pages: ::c_long = 238; ++pub const SYS_openat: ::c_long = 56; ++pub const SYS_mkdirat: ::c_long = 34; ++pub const SYS_mknodat: ::c_long = 33; ++pub const SYS_fchownat: ::c_long = 54; ++pub const SYS_newfstatat: ::c_long = 79; ++pub const SYS_unlinkat: ::c_long = 35; ++pub const SYS_linkat: ::c_long = 37; ++pub const SYS_symlinkat: ::c_long = 36; ++pub const SYS_readlinkat: ::c_long = 78; ++pub const SYS_fchmodat: ::c_long = 53; ++pub const SYS_faccessat: ::c_long = 48; ++pub const SYS_pselect6: ::c_long = 72; ++pub const SYS_ppoll: ::c_long = 73; ++pub const SYS_unshare: ::c_long = 97; ++pub const SYS_set_robust_list: ::c_long = 99; ++pub const SYS_get_robust_list: ::c_long = 100; ++pub const SYS_splice: ::c_long = 76; ++pub const SYS_tee: ::c_long = 77; ++pub const SYS_sync_file_range: ::c_long = 84; ++pub const SYS_vmsplice: ::c_long = 75; ++pub const SYS_move_pages: ::c_long = 239; ++pub const SYS_utimensat: ::c_long = 88; ++pub const SYS_epoll_pwait: ::c_long = 22; ++pub const SYS_timerfd_create: ::c_long = 85; ++pub const SYS_fallocate: ::c_long = 47; ++pub const SYS_timerfd_settime: ::c_long = 86; ++pub const SYS_timerfd_gettime: ::c_long = 87; ++pub const SYS_accept4: ::c_long = 242; ++pub const SYS_signalfd4: ::c_long = 74; ++pub const SYS_eventfd2: ::c_long = 19; ++pub const SYS_epoll_create1: ::c_long = 20; ++pub const SYS_dup3: ::c_long = 24; ++pub const SYS_pipe2: ::c_long = 59; ++pub const SYS_inotify_init1: ::c_long = 26; ++pub const SYS_preadv: ::c_long = 69; ++pub const SYS_pwritev: ::c_long = 70; ++pub const SYS_rt_tgsigqueueinfo: ::c_long = 240; ++pub const SYS_perf_event_open: ::c_long = 241; ++pub const SYS_recvmmsg: ::c_long = 243; ++pub const SYS_fanotify_init: ::c_long = 262; ++pub const SYS_fanotify_mark: ::c_long = 263; ++pub const SYS_prlimit64: ::c_long = 261; ++pub const SYS_name_to_handle_at: ::c_long = 264; ++pub const SYS_open_by_handle_at: ::c_long = 265; ++pub const SYS_clock_adjtime: ::c_long = 266; ++pub const SYS_syncfs: ::c_long = 267; ++pub const SYS_sendmmsg: ::c_long = 269; ++pub const SYS_setns: ::c_long = 268; ++pub const SYS_getcpu: ::c_long = 168; ++pub const SYS_process_vm_readv: ::c_long = 270; ++pub const SYS_process_vm_writev: ::c_long = 271; ++pub const SYS_kcmp: ::c_long = 272; ++pub const SYS_finit_module: ::c_long = 273; ++pub const SYS_sched_setattr: ::c_long = 274; ++pub const SYS_sched_getattr: ::c_long = 275; ++pub const SYS_renameat2: ::c_long = 276; ++pub const SYS_seccomp: ::c_long = 277; ++pub const SYS_getrandom: ::c_long = 278; ++pub const SYS_memfd_create: ::c_long = 279; ++pub const SYS_bpf: ::c_long = 280; ++pub const SYS_execveat: ::c_long = 281; ++pub const SYS_userfaultfd: ::c_long = 282; ++pub const SYS_membarrier: ::c_long = 283; ++pub const SYS_mlock2: ::c_long = 284; ++pub const SYS_copy_file_range: ::c_long = 285; ++pub const SYS_preadv2: ::c_long = 286; ++pub const SYS_pwritev2: ::c_long = 287; ++pub const SYS_pkey_mprotect: ::c_long = 288; ++pub const SYS_pkey_alloc: ::c_long = 289; ++pub const SYS_pkey_free: ::c_long = 290; ++pub const SYS_statx: ::c_long = 291; ++pub const SYS_pidfd_send_signal: ::c_long = 424; ++pub const SYS_io_uring_setup: ::c_long = 425; ++pub const SYS_io_uring_enter: ::c_long = 426; ++pub const SYS_io_uring_register: ::c_long = 427; ++pub const SYS_open_tree: ::c_long = 428; ++pub const SYS_move_mount: ::c_long = 429; ++pub const SYS_fsopen: ::c_long = 430; ++pub const SYS_fsconfig: ::c_long = 431; ++pub const SYS_fsmount: ::c_long = 432; ++pub const SYS_fspick: ::c_long = 433; ++pub const SYS_pidfd_open: ::c_long = 434; ++pub const SYS_clone3: ::c_long = 435; ++pub const SYS_close_range: ::c_long = 436; ++pub const SYS_openat2: ::c_long = 437; ++pub const SYS_pidfd_getfd: ::c_long = 438; ++pub const SYS_faccessat2: ::c_long = 439; ++pub const SYS_process_madvise: ::c_long = 440; ++pub const SYS_epoll_pwait2: ::c_long = 441; ++pub const SYS_mount_setattr: ::c_long = 442; ++ ++pub const O_APPEND: ::c_int = 1024; ++pub const O_DIRECT: ::c_int = 0x4000; ++pub const O_DIRECTORY: ::c_int = 0x10000; ++pub const O_LARGEFILE: ::c_int = 0; ++pub const O_NOFOLLOW: ::c_int = 0x20000; ++pub const O_CREAT: ::c_int = 64; ++pub const O_EXCL: ::c_int = 128; ++pub const O_NOCTTY: ::c_int = 256; ++pub const O_NONBLOCK: ::c_int = 2048; ++pub const O_SYNC: ::c_int = 1052672; ++pub const O_RSYNC: ::c_int = 1052672; ++pub const O_DSYNC: ::c_int = 4096; ++pub const O_ASYNC: ::c_int = 0x2000; ++ ++pub const SIGSTKSZ: ::size_t = 8192; ++pub const MINSIGSTKSZ: ::size_t = 2048; ++ ++pub const ENAMETOOLONG: ::c_int = 36; ++pub const ENOLCK: ::c_int = 37; ++pub const ENOSYS: ::c_int = 38; ++pub const ENOTEMPTY: ::c_int = 39; ++pub const ELOOP: ::c_int = 40; ++pub const ENOMSG: ::c_int = 42; ++pub const EIDRM: ::c_int = 43; ++pub const ECHRNG: ::c_int = 44; ++pub const EL2NSYNC: ::c_int = 45; ++pub const EL3HLT: ::c_int = 46; ++pub const EL3RST: ::c_int = 47; ++pub const ELNRNG: ::c_int = 48; ++pub const EUNATCH: ::c_int = 49; ++pub const ENOCSI: ::c_int = 50; ++pub const EL2HLT: ::c_int = 51; ++pub const EBADE: ::c_int = 52; ++pub const EBADR: ::c_int = 53; ++pub const EXFULL: ::c_int = 54; ++pub const ENOANO: ::c_int = 55; ++pub const EBADRQC: ::c_int = 56; ++pub const EBADSLT: ::c_int = 57; ++pub const EMULTIHOP: ::c_int = 72; ++pub const EOVERFLOW: ::c_int = 75; ++pub const ENOTUNIQ: ::c_int = 76; ++pub const EBADFD: ::c_int = 77; ++pub const EBADMSG: ::c_int = 74; ++pub const EREMCHG: ::c_int = 78; ++pub const ELIBACC: ::c_int = 79; ++pub const ELIBBAD: ::c_int = 80; ++pub const ELIBSCN: ::c_int = 81; ++pub const ELIBMAX: ::c_int = 82; ++pub const ELIBEXEC: ::c_int = 83; ++pub const EILSEQ: ::c_int = 84; ++pub const ERESTART: ::c_int = 85; ++pub const ESTRPIPE: ::c_int = 86; ++pub const EUSERS: ::c_int = 87; ++pub const ENOTSOCK: ::c_int = 88; ++pub const EDESTADDRREQ: ::c_int = 89; ++pub const EMSGSIZE: ::c_int = 90; ++pub const EPROTOTYPE: ::c_int = 91; ++pub const ENOPROTOOPT: ::c_int = 92; ++pub const EPROTONOSUPPORT: ::c_int = 93; ++pub const ESOCKTNOSUPPORT: ::c_int = 94; ++pub const EOPNOTSUPP: ::c_int = 95; ++pub const ENOTSUP: ::c_int = EOPNOTSUPP; ++pub const EPFNOSUPPORT: ::c_int = 96; ++pub const EAFNOSUPPORT: ::c_int = 97; ++pub const EADDRINUSE: ::c_int = 98; ++pub const EADDRNOTAVAIL: ::c_int = 99; ++pub const ENETDOWN: ::c_int = 100; ++pub const ENETUNREACH: ::c_int = 101; ++pub const ENETRESET: ::c_int = 102; ++pub const ECONNABORTED: ::c_int = 103; ++pub const ECONNRESET: ::c_int = 104; ++pub const ENOBUFS: ::c_int = 105; ++pub const EISCONN: ::c_int = 106; ++pub const ENOTCONN: ::c_int = 107; ++pub const ESHUTDOWN: ::c_int = 108; ++pub const ETOOMANYREFS: ::c_int = 109; ++pub const ETIMEDOUT: ::c_int = 110; ++pub const ECONNREFUSED: ::c_int = 111; ++pub const EHOSTDOWN: ::c_int = 112; ++pub const EHOSTUNREACH: ::c_int = 113; ++pub const EALREADY: ::c_int = 114; ++pub const EINPROGRESS: ::c_int = 115; ++pub const ESTALE: ::c_int = 116; ++pub const EUCLEAN: ::c_int = 117; ++pub const ENOTNAM: ::c_int = 118; ++pub const ENAVAIL: ::c_int = 119; ++pub const EISNAM: ::c_int = 120; ++pub const EREMOTEIO: ::c_int = 121; ++pub const EDQUOT: ::c_int = 122; ++pub const ENOMEDIUM: ::c_int = 123; ++pub const EMEDIUMTYPE: ::c_int = 124; ++pub const ECANCELED: ::c_int = 125; ++pub const ENOKEY: ::c_int = 126; ++pub const EKEYEXPIRED: ::c_int = 127; ++pub const EKEYREVOKED: ::c_int = 128; ++pub const EKEYREJECTED: ::c_int = 129; ++pub const EOWNERDEAD: ::c_int = 130; ++pub const ENOTRECOVERABLE: ::c_int = 131; ++pub const EHWPOISON: ::c_int = 133; ++pub const ERFKILL: ::c_int = 132; ++ ++pub const SA_ONSTACK: ::c_int = 0x08000000; ++pub const SA_SIGINFO: ::c_int = 0x00000004; ++pub const SA_NOCLDWAIT: ::c_int = 0x00000002; ++ ++pub const SIGCHLD: ::c_int = 17; ++pub const SIGBUS: ::c_int = 7; ++pub const SIGTTIN: ::c_int = 21; ++pub const SIGTTOU: ::c_int = 22; ++pub const SIGXCPU: ::c_int = 24; ++pub const SIGXFSZ: ::c_int = 25; ++pub const SIGVTALRM: ::c_int = 26; ++pub const SIGPROF: ::c_int = 27; ++pub const SIGWINCH: ::c_int = 28; ++pub const SIGUSR1: ::c_int = 10; ++pub const SIGUSR2: ::c_int = 12; ++pub const SIGCONT: ::c_int = 18; ++pub const SIGSTOP: ::c_int = 19; ++pub const SIGTSTP: ::c_int = 20; ++pub const SIGURG: ::c_int = 23; ++pub const SIGIO: ::c_int = 29; ++pub const SIGSYS: ::c_int = 31; ++pub const SIGSTKFLT: ::c_int = 16; ++pub const SIGPOLL: ::c_int = 29; ++pub const SIGPWR: ::c_int = 30; ++pub const SIG_SETMASK: ::c_int = 2; ++pub const SIG_BLOCK: ::c_int = 0x000000; ++pub const SIG_UNBLOCK: ::c_int = 0x01; ++ ++pub const F_GETLK: ::c_int = 5; ++pub const F_GETOWN: ::c_int = 9; ++pub const F_SETLK: ::c_int = 6; ++pub const F_SETLKW: ::c_int = 7; ++pub const F_SETOWN: ::c_int = 8; ++pub const F_OFD_GETLK: ::c_int = 36; ++pub const F_OFD_SETLK: ::c_int = 37; ++pub const F_OFD_SETLKW: ::c_int = 38; ++ ++pub const VEOF: usize = 4; ++ ++pub const POLLWRNORM: ::c_short = 0x100; ++pub const POLLWRBAND: ::c_short = 0x200; ++ ++pub const SOCK_STREAM: ::c_int = 1; ++pub const SOCK_DGRAM: ::c_int = 2; ++ ++pub const MAP_ANON: ::c_int = 0x0020; ++pub const MAP_GROWSDOWN: ::c_int = 0x0100; ++pub const MAP_DENYWRITE: ::c_int = 0x0800; ++pub const MAP_EXECUTABLE: ::c_int = 0x01000; ++pub const MAP_LOCKED: ::c_int = 0x02000; ++pub const MAP_NORESERVE: ::c_int = 0x04000; ++pub const MAP_POPULATE: ::c_int = 0x08000; ++pub const MAP_NONBLOCK: ::c_int = 0x010000; ++pub const MAP_STACK: ::c_int = 0x020000; ++pub const MAP_HUGETLB: ::c_int = 0x040000; ++pub const MAP_SYNC: ::c_int = 0x080000; ++ ++pub const MCL_CURRENT: ::c_int = 0x0001; ++pub const MCL_FUTURE: ::c_int = 0x0002; ++pub const CBAUD: ::tcflag_t = 0o0010017; ++pub const TAB1: ::c_int = 0x00000800; ++pub const TAB2: ::c_int = 0x00001000; ++pub const TAB3: ::c_int = 0x00001800; ++pub const CR1: ::c_int = 0x00000200; ++pub const CR2: ::c_int = 0x00000400; ++pub const CR3: ::c_int = 0x00000600; ++pub const FF1: ::c_int = 0x00008000; ++pub const BS1: ::c_int = 0x00002000; ++pub const VT1: ::c_int = 0x00004000; ++pub const VWERASE: usize = 14; ++pub const VREPRINT: usize = 12; ++pub const VSUSP: usize = 10; ++pub const VSTART: usize = 8; ++pub const VSTOP: usize = 9; ++pub const VDISCARD: usize = 13; ++pub const VTIME: usize = 5; ++pub const IXON: ::tcflag_t = 0x00000400; ++pub const IXOFF: ::tcflag_t = 0x00001000; ++pub const ONLCR: ::tcflag_t = 0x4; ++pub const CSIZE: ::tcflag_t = 0x00000030; ++pub const CS6: ::tcflag_t = 0x00000010; ++pub const CS7: ::tcflag_t = 0x00000020; ++pub const CS8: ::tcflag_t = 0x00000030; ++pub const CSTOPB: ::tcflag_t = 0x00000040; ++pub const CREAD: ::tcflag_t = 0x00000080; ++pub const PARENB: ::tcflag_t = 0x00000100; ++pub const PARODD: ::tcflag_t = 0x00000200; ++pub const HUPCL: ::tcflag_t = 0x00000400; ++pub const CLOCAL: ::tcflag_t = 0x00000800; ++pub const ECHOKE: ::tcflag_t = 0x00000800; ++pub const ECHOE: ::tcflag_t = 0x00000010; ++pub const ECHOK: ::tcflag_t = 0x00000020; ++pub const ECHONL: ::tcflag_t = 0x00000040; ++pub const ECHOPRT: ::tcflag_t = 0x00000400; ++pub const ECHOCTL: ::tcflag_t = 0x00000200; ++pub const ISIG: ::tcflag_t = 0x00000001; ++pub const ICANON: ::tcflag_t = 0x00000002; ++pub const PENDIN: ::tcflag_t = 0x00004000; ++pub const NOFLSH: ::tcflag_t = 0x00000080; ++pub const CIBAUD: ::tcflag_t = 0o02003600000; ++pub const CBAUDEX: ::tcflag_t = 0o010000; ++pub const VSWTC: usize = 7; ++pub const OLCUC: ::tcflag_t = 0o000002; ++pub const NLDLY: ::tcflag_t = 0o000400; ++pub const CRDLY: ::tcflag_t = 0o003000; ++pub const TABDLY: ::tcflag_t = 0o014000; ++pub const BSDLY: ::tcflag_t = 0o020000; ++pub const FFDLY: ::tcflag_t = 0o100000; ++pub const VTDLY: ::tcflag_t = 0o040000; ++pub const XTABS: ::tcflag_t = 0o014000; ++pub const B57600: ::speed_t = 0o010001; ++pub const B115200: ::speed_t = 0o010002; ++pub const B230400: ::speed_t = 0o010003; ++pub const B460800: ::speed_t = 0o010004; ++pub const B500000: ::speed_t = 0o010005; ++pub const B576000: ::speed_t = 0o010006; ++pub const B921600: ::speed_t = 0o010007; ++pub const B1000000: ::speed_t = 0o010010; ++pub const B1152000: ::speed_t = 0o010011; ++pub const B1500000: ::speed_t = 0o010012; ++pub const B2000000: ::speed_t = 0o010013; ++pub const B2500000: ::speed_t = 0o010014; ++pub const B3000000: ::speed_t = 0o010015; ++pub const B3500000: ::speed_t = 0o010016; ++pub const B4000000: ::speed_t = 0o010017; ++ ++pub const EDEADLK: ::c_int = 35; ++pub const EDEADLOCK: ::c_int = EDEADLK; ++pub const EXTPROC: ::tcflag_t = 0x00010000; ++pub const VEOL: usize = 11; ++pub const VEOL2: usize = 16; ++pub const VMIN: usize = 6; ++pub const IEXTEN: ::tcflag_t = 0x00008000; ++pub const TOSTOP: ::tcflag_t = 0x00000100; ++pub const FLUSHO: ::tcflag_t = 0x00001000; ++ ++pub const NGREG: usize = 32; ++pub const REG_PC: usize = 0; ++pub const REG_RA: usize = 1; ++pub const REG_SP: usize = 2; ++pub const REG_TP: usize = 4; ++pub const REG_S0: usize = 8; ++pub const REG_S1: usize = 9; ++pub const REG_A0: usize = 10; ++pub const REG_S2: usize = 18; ++pub const REG_NARGS: usize = 8; ++ ++cfg_if! { ++ if #[cfg(libc_align)] { ++ mod align; ++ pub use self::align::*; ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs +index 3bdac44..d7dcce6 100644 +--- a/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs +@@ -4,6 +4,7 @@ pub type nlink_t = u64; + pub type wchar_t = i32; + pub type greg_t = u64; + pub type __u64 = u64; ++pub type __s64 = i64; + + s! { + pub struct ipc_perm { +@@ -141,9 +142,6 @@ pub const EDEADLK: ::c_int = 35; + pub const ENOSYS: ::c_int = 38; + pub const ENOTCONN: ::c_int = 107; + pub const ETIMEDOUT: ::c_int = 110; +-pub const FIOCLEX: ::c_ulong = 0x5451; +-pub const FIONCLEX: ::c_ulong = 0x5450; +-pub const FIONBIO: ::c_ulong = 0x5421; + pub const O_APPEND: ::c_int = 1024; + pub const O_CREAT: ::c_int = 64; + pub const O_EXCL: ::c_int = 128; +@@ -179,6 +177,7 @@ pub const MAP_POPULATE: ::c_int = 0x08000; + pub const MAP_NONBLOCK: ::c_int = 0x010000; + pub const MAP_STACK: ::c_int = 0x020000; + pub const MAP_HUGETLB: ::c_int = 0x040000; ++pub const MAP_SYNC: ::c_int = 0x080000; + + pub const EDEADLOCK: ::c_int = 35; + pub const ENAMETOOLONG: ::c_int = 36; +@@ -224,6 +223,7 @@ pub const ENOPROTOOPT: ::c_int = 92; + pub const EPROTONOSUPPORT: ::c_int = 93; + pub const ESOCKTNOSUPPORT: ::c_int = 94; + pub const EOPNOTSUPP: ::c_int = 95; ++pub const ENOTSUP: ::c_int = EOPNOTSUPP; + pub const EPFNOSUPPORT: ::c_int = 96; + pub const EAFNOSUPPORT: ::c_int = 97; + pub const ENETDOWN: ::c_int = 100; +@@ -296,45 +296,6 @@ pub const F_OFD_GETLK: ::c_int = 36; + pub const F_OFD_SETLK: ::c_int = 37; + pub const F_OFD_SETLKW: ::c_int = 38; + +-pub const TCGETS: ::c_int = 0x5401; +-pub const TCSETS: ::c_int = 0x5402; +-pub const TCSETSW: ::c_int = 0x5403; +-pub const TCSETSF: ::c_int = 0x5404; +-pub const TCGETA: ::c_int = 0x5405; +-pub const TCSETA: ::c_int = 0x5406; +-pub const TCSETAW: ::c_int = 0x5407; +-pub const TCSETAF: ::c_int = 0x5408; +-pub const TCSBRK: ::c_int = 0x5409; +-pub const TCXONC: ::c_int = 0x540A; +-pub const TCFLSH: ::c_int = 0x540B; +-pub const TIOCGSOFTCAR: ::c_int = 0x5419; +-pub const TIOCSSOFTCAR: ::c_int = 0x541A; +-pub const TIOCINQ: ::c_int = 0x541B; +-pub const TIOCEXCL: ::c_int = 0x540C; +-pub const TIOCNXCL: ::c_int = 0x540D; +-pub const TIOCSCTTY: ::c_int = 0x540E; +-pub const TIOCGPGRP: ::c_int = 0x540F; +-pub const TIOCSPGRP: ::c_int = 0x5410; +-pub const TIOCOUTQ: ::c_int = 0x5411; +-pub const TIOCSTI: ::c_int = 0x5412; +-pub const TIOCGWINSZ: ::c_int = 0x5413; +-pub const TIOCSWINSZ: ::c_int = 0x5414; +-pub const TIOCMGET: ::c_int = 0x5415; +-pub const TIOCMBIS: ::c_int = 0x5416; +-pub const TIOCMBIC: ::c_int = 0x5417; +-pub const TIOCMSET: ::c_int = 0x5418; +-pub const FIONREAD: ::c_int = 0x541B; +-pub const TIOCCONS: ::c_int = 0x541D; +- +-pub const TIOCLINUX: ::c_int = 0x541C; +-pub const TIOCGSERIAL: ::c_int = 0x541E; +-pub const TIOCM_ST: ::c_int = 0x008; +-pub const TIOCM_SR: ::c_int = 0x010; +-pub const TIOCM_CTS: ::c_int = 0x020; +-pub const TIOCM_CAR: ::c_int = 0x040; +-pub const TIOCM_RNG: ::c_int = 0x080; +-pub const TIOCM_DSR: ::c_int = 0x100; +- + pub const VTIME: usize = 5; + pub const VSWTC: usize = 7; + pub const VSTART: usize = 8; +@@ -374,7 +335,6 @@ pub const PARODD: ::tcflag_t = 0o001000; + pub const HUPCL: ::tcflag_t = 0o002000; + pub const CLOCAL: ::tcflag_t = 0o004000; + pub const CBAUDEX: ::tcflag_t = 0o010000; +-pub const BOTHER: ::speed_t = 0o010000; + pub const B57600: ::speed_t = 0o010001; + pub const B115200: ::speed_t = 0o010002; + pub const B230400: ::speed_t = 0o010003; +@@ -752,7 +712,11 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; +- +-extern "C" { +- pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; +-} ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/align.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/align.rs +index 7ca870f..94391a0 100644 +--- a/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/align.rs ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/align.rs +@@ -4,4 +4,22 @@ s_no_extra_traits! { + pub struct max_align_t { + priv_: [f64; 4] + } ++ ++} ++ ++s! { ++ #[repr(align(8))] ++ pub struct clone_args { ++ pub flags: ::c_ulonglong, ++ pub pidfd: ::c_ulonglong, ++ pub child_tid: ::c_ulonglong, ++ pub parent_tid: ::c_ulonglong, ++ pub exit_signal: ::c_ulonglong, ++ pub stack: ::c_ulonglong, ++ pub stack_size: ::c_ulonglong, ++ pub tls: ::c_ulonglong, ++ pub set_tid: ::c_ulonglong, ++ pub set_tid_size: ::c_ulonglong, ++ pub cgroup: ::c_ulonglong, ++ } + } +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs +index dac9f99..8198dc2 100644 +--- a/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs +@@ -3,6 +3,7 @@ pub type wchar_t = i32; + pub type nlink_t = u64; + pub type blksize_t = ::c_long; + pub type __u64 = ::c_ulonglong; ++pub type __s64 = ::c_longlong; + pub type greg_t = i64; + + s! { +@@ -599,6 +600,14 @@ pub const SYS_faccessat2: ::c_long = 439; + pub const SYS_process_madvise: ::c_long = 440; + pub const SYS_epoll_pwait2: ::c_long = 441; + pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; + + // offsets in user_regs_structs, from sys/reg.h + pub const R15: ::c_int = 0; +@@ -673,9 +682,6 @@ pub const O_RSYNC: ::c_int = 1052672; + pub const O_DSYNC: ::c_int = 4096; + pub const O_ASYNC: ::c_int = 0x2000; + +-pub const TIOCGRS485: ::c_int = 0x542E; +-pub const TIOCSRS485: ::c_int = 0x542F; +- + pub const SIGSTKSZ: ::size_t = 8192; + pub const MINSIGSTKSZ: ::size_t = 2048; + +@@ -820,9 +826,6 @@ pub const MAP_STACK: ::c_int = 0x020000; + pub const MAP_HUGETLB: ::c_int = 0x040000; + pub const MAP_SYNC: ::c_int = 0x080000; + +-pub const RLIMIT_NLIMITS: ::c_int = 15; +-pub const RLIM_NLIMITS: ::c_int = RLIMIT_NLIMITS; +-pub const TIOCINQ: ::c_int = ::FIONREAD; + pub const MCL_CURRENT: ::c_int = 0x0001; + pub const MCL_FUTURE: ::c_int = 0x0002; + pub const CBAUD: ::tcflag_t = 0o0010017; +@@ -892,9 +895,6 @@ pub const B3000000: ::speed_t = 0o010015; + pub const B3500000: ::speed_t = 0o010016; + pub const B4000000: ::speed_t = 0o010017; + +-pub const FIOCLEX: ::c_int = 0x5451; +-pub const FIONCLEX: ::c_int = 0x5450; +-pub const FIONBIO: ::c_int = 0x5421; + pub const EDEADLK: ::c_int = 35; + pub const EDEADLOCK: ::c_int = EDEADLK; + +@@ -905,52 +905,6 @@ pub const VMIN: usize = 6; + pub const IEXTEN: ::tcflag_t = 0x00008000; + pub const TOSTOP: ::tcflag_t = 0x00000100; + pub const FLUSHO: ::tcflag_t = 0x00001000; +-pub const TCGETS: ::c_int = 0x5401; +-pub const TCSETS: ::c_int = 0x5402; +-pub const TCSETSW: ::c_int = 0x5403; +-pub const TCSETSF: ::c_int = 0x5404; +-pub const TCGETA: ::c_int = 0x5405; +-pub const TCSETA: ::c_int = 0x5406; +-pub const TCSETAW: ::c_int = 0x5407; +-pub const TCSETAF: ::c_int = 0x5408; +-pub const TCSBRK: ::c_int = 0x5409; +-pub const TCXONC: ::c_int = 0x540A; +-pub const TCFLSH: ::c_int = 0x540B; +-pub const TIOCGSOFTCAR: ::c_int = 0x5419; +-pub const TIOCSSOFTCAR: ::c_int = 0x541A; +-pub const TIOCLINUX: ::c_int = 0x541C; +-pub const TIOCGSERIAL: ::c_int = 0x541E; +-pub const TIOCEXCL: ::c_int = 0x540C; +-pub const TIOCNXCL: ::c_int = 0x540D; +-pub const TIOCSCTTY: ::c_int = 0x540E; +-pub const TIOCGPGRP: ::c_int = 0x540F; +-pub const TIOCSPGRP: ::c_int = 0x5410; +-pub const TIOCOUTQ: ::c_int = 0x5411; +-pub const TIOCSTI: ::c_int = 0x5412; +-pub const TIOCGWINSZ: ::c_int = 0x5413; +-pub const TIOCSWINSZ: ::c_int = 0x5414; +-pub const TIOCMGET: ::c_int = 0x5415; +-pub const TIOCMBIS: ::c_int = 0x5416; +-pub const TIOCMBIC: ::c_int = 0x5417; +-pub const TIOCMSET: ::c_int = 0x5418; +-pub const FIONREAD: ::c_int = 0x541B; +-pub const TIOCCONS: ::c_int = 0x541D; +- +-pub const TIOCM_LE: ::c_int = 0x001; +-pub const TIOCM_DTR: ::c_int = 0x002; +-pub const TIOCM_RTS: ::c_int = 0x004; +-pub const TIOCM_ST: ::c_int = 0x008; +-pub const TIOCM_SR: ::c_int = 0x010; +-pub const TIOCM_CTS: ::c_int = 0x020; +-pub const TIOCM_CAR: ::c_int = 0x040; +-pub const TIOCM_RNG: ::c_int = 0x080; +-pub const TIOCM_DSR: ::c_int = 0x100; +-pub const TIOCM_CD: ::c_int = TIOCM_CAR; +-pub const TIOCM_RI: ::c_int = TIOCM_RNG; +- +-extern "C" { +- pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; +-} + + cfg_if! { + if #[cfg(libc_align)] { +diff --git a/vendor/libc/src/unix/linux_like/linux/musl/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/mod.rs +index 03f13e2..37a8ca2 100644 +--- a/vendor/libc/src/unix/linux_like/linux/musl/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/musl/mod.rs +@@ -24,6 +24,16 @@ pub type rlim_t = ::c_ulonglong; + + pub type flock64 = flock; + ++cfg_if! { ++ if #[cfg(doc)] { ++ // Used in `linux::arch` to define ioctl constants. ++ pub(crate) type Ioctl = ::c_int; ++ } else { ++ #[doc(hidden)] ++ pub type Ioctl = ::c_int; ++ } ++} ++ + impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + #[repr(C)] +@@ -133,24 +143,6 @@ s! { + __dummy4: [::c_char; 16], + } + +- pub struct nlmsghdr { +- pub nlmsg_len: u32, +- pub nlmsg_type: u16, +- pub nlmsg_flags: u16, +- pub nlmsg_seq: u32, +- pub nlmsg_pid: u32, +- } +- +- pub struct nlmsgerr { +- pub error: ::c_int, +- pub msg: nlmsghdr, +- } +- +- pub struct nlattr { +- pub nla_len: u16, +- pub nla_type: u16, +- } +- + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, +@@ -226,12 +218,6 @@ s! { + pub rt_irtt: ::c_ushort, + } + +- pub struct ip_mreqn { +- pub imr_multiaddr: ::in_addr, +- pub imr_address: ::in_addr, +- pub imr_ifindex: ::c_int, +- } +- + pub struct __exit_status { + pub e_termination: ::c_short, + pub e_exit: ::c_short, +@@ -249,6 +235,36 @@ s! { + pub ch_size: ::Elf32_Word, + pub ch_addralign: ::Elf32_Word, + } ++ ++ pub struct timex { ++ pub modes: ::c_uint, ++ pub offset: ::c_long, ++ pub freq: ::c_long, ++ pub maxerror: ::c_long, ++ pub esterror: ::c_long, ++ pub status: ::c_int, ++ pub constant: ::c_long, ++ pub precision: ::c_long, ++ pub tolerance: ::c_long, ++ pub time: ::timeval, ++ pub tick: ::c_long, ++ pub ppsfreq: ::c_long, ++ pub jitter: ::c_long, ++ pub shift: ::c_int, ++ pub stabil: ::c_long, ++ pub jitcnt: ::c_long, ++ pub calcnt: ::c_long, ++ pub errcnt: ::c_long, ++ pub stbcnt: ::c_long, ++ pub tai: ::c_int, ++ pub __padding: [::c_int; 11], ++ } ++ ++ pub struct ntptimeval { ++ pub time: ::timeval, ++ pub maxerror: ::c_long, ++ pub esterror: ::c_long, ++ } + } + + s_no_extra_traits! { +@@ -271,12 +287,14 @@ s_no_extra_traits! { + + // FIXME: musl added paddings and adjusted + // layout in 1.2.0 but our CI is still 1.1.24. +- // So, I'm leaving some fields as comments for now. ++ // So, I'm leaving some fields as cfg for now. + // ref. https://github.com/bminor/musl/commit/ + // 1e7f0fcd7ff2096904fd93a2ee6d12a2392be392 ++ // ++ // OpenHarmony uses the musl 1.2 layout. + pub struct utmpx { + pub ut_type: ::c_short, +- //__ut_pad1: ::c_short, ++ __ut_pad1: ::c_short, + pub ut_pid: ::pid_t, + pub ut_line: [::c_char; 32], + pub ut_id: [::c_char; 4], +@@ -284,15 +302,22 @@ s_no_extra_traits! { + pub ut_host: [::c_char; 256], + pub ut_exit: __exit_status, + +- //#[cfg(target_endian = "little")] ++ #[cfg(target_env = "musl")] + pub ut_session: ::c_long, +- //#[cfg(target_endian = "little")] +- //__ut_pad2: ::c_long, + +- //#[cfg(not(target_endian = "little"))] +- //__ut_pad2: ::c_int, +- //#[cfg(not(target_endian = "little"))] +- //pub ut_session: ::c_int, ++ #[cfg(target_env = "ohos")] ++ #[cfg(target_endian = "little")] ++ pub ut_session: ::c_int, ++ #[cfg(target_env = "ohos")] ++ #[cfg(target_endian = "little")] ++ __ut_pad2: ::c_int, ++ ++ #[cfg(target_env = "ohos")] ++ #[cfg(not(target_endian = "little"))] ++ __ut_pad2: ::c_int, ++ #[cfg(target_env = "ohos")] ++ #[cfg(not(target_endian = "little"))] ++ pub ut_session: ::c_int, + + pub ut_tv: ::timeval, + pub ut_addr_v6: [::c_uint; 4], +@@ -508,20 +533,20 @@ pub const PTHREAD_STACK_MIN: ::size_t = 2048; + + pub const POSIX_MADV_DONTNEED: ::c_int = 4; + +-pub const RLIM_INFINITY: ::rlim_t = !0; +-pub const RLIMIT_RTTIME: ::c_int = 15; +- + pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; + + pub const SOCK_DCCP: ::c_int = 6; + pub const SOCK_PACKET: ::c_int = 10; + ++pub const SOMAXCONN: ::c_int = 128; ++ + #[deprecated(since = "0.2.55", note = "Use SIGSYS instead")] + pub const SIGUNUSED: ::c_int = ::SIGSYS; + + pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; ++pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + + pub const CPU_SETSIZE: ::c_int = 128; + +@@ -575,6 +600,8 @@ pub const EFD_NONBLOCK: ::c_int = ::O_NONBLOCK; + + pub const SFD_NONBLOCK: ::c_int = ::O_NONBLOCK; + ++pub const PIDFD_NONBLOCK: ::c_uint = O_NONBLOCK as ::c_uint; ++ + pub const TCSANOW: ::c_int = 0; + pub const TCSADRAIN: ::c_int = 1; + pub const TCSAFLUSH: ::c_int = 2; +@@ -603,26 +630,70 @@ pub const B38400: ::speed_t = 0o000017; + pub const EXTA: ::speed_t = B19200; + pub const EXTB: ::speed_t = B38400; + +-pub const RLIMIT_CPU: ::c_int = 0; +-pub const RLIMIT_FSIZE: ::c_int = 1; +-pub const RLIMIT_DATA: ::c_int = 2; +-pub const RLIMIT_STACK: ::c_int = 3; +-pub const RLIMIT_CORE: ::c_int = 4; +-pub const RLIMIT_LOCKS: ::c_int = 10; +-pub const RLIMIT_SIGPENDING: ::c_int = 11; +-pub const RLIMIT_MSGQUEUE: ::c_int = 12; +-pub const RLIMIT_NICE: ::c_int = 13; +-pub const RLIMIT_RTPRIO: ::c_int = 14; +- + pub const REG_OK: ::c_int = 0; + +-pub const TIOCSBRK: ::c_int = 0x5427; +-pub const TIOCCBRK: ::c_int = 0x5428; +- + pub const PRIO_PROCESS: ::c_int = 0; + pub const PRIO_PGRP: ::c_int = 1; + pub const PRIO_USER: ::c_int = 2; + ++pub const ADJ_OFFSET: ::c_uint = 0x0001; ++pub const ADJ_FREQUENCY: ::c_uint = 0x0002; ++pub const ADJ_MAXERROR: ::c_uint = 0x0004; ++pub const ADJ_ESTERROR: ::c_uint = 0x0008; ++pub const ADJ_STATUS: ::c_uint = 0x0010; ++pub const ADJ_TIMECONST: ::c_uint = 0x0020; ++pub const ADJ_TAI: ::c_uint = 0x0080; ++pub const ADJ_SETOFFSET: ::c_uint = 0x0100; ++pub const ADJ_MICRO: ::c_uint = 0x1000; ++pub const ADJ_NANO: ::c_uint = 0x2000; ++pub const ADJ_TICK: ::c_uint = 0x4000; ++pub const ADJ_OFFSET_SINGLESHOT: ::c_uint = 0x8001; ++pub const ADJ_OFFSET_SS_READ: ::c_uint = 0xa001; ++pub const MOD_OFFSET: ::c_uint = ADJ_OFFSET; ++pub const MOD_FREQUENCY: ::c_uint = ADJ_FREQUENCY; ++pub const MOD_MAXERROR: ::c_uint = ADJ_MAXERROR; ++pub const MOD_ESTERROR: ::c_uint = ADJ_ESTERROR; ++pub const MOD_STATUS: ::c_uint = ADJ_STATUS; ++pub const MOD_TIMECONST: ::c_uint = ADJ_TIMECONST; ++pub const MOD_CLKB: ::c_uint = ADJ_TICK; ++pub const MOD_CLKA: ::c_uint = ADJ_OFFSET_SINGLESHOT; ++pub const MOD_TAI: ::c_uint = ADJ_TAI; ++pub const MOD_MICRO: ::c_uint = ADJ_MICRO; ++pub const MOD_NANO: ::c_uint = ADJ_NANO; ++pub const STA_PLL: ::c_int = 0x0001; ++pub const STA_PPSFREQ: ::c_int = 0x0002; ++pub const STA_PPSTIME: ::c_int = 0x0004; ++pub const STA_FLL: ::c_int = 0x0008; ++pub const STA_INS: ::c_int = 0x0010; ++pub const STA_DEL: ::c_int = 0x0020; ++pub const STA_UNSYNC: ::c_int = 0x0040; ++pub const STA_FREQHOLD: ::c_int = 0x0080; ++pub const STA_PPSSIGNAL: ::c_int = 0x0100; ++pub const STA_PPSJITTER: ::c_int = 0x0200; ++pub const STA_PPSWANDER: ::c_int = 0x0400; ++pub const STA_PPSERROR: ::c_int = 0x0800; ++pub const STA_CLOCKERR: ::c_int = 0x1000; ++pub const STA_NANO: ::c_int = 0x2000; ++pub const STA_MODE: ::c_int = 0x4000; ++pub const STA_CLK: ::c_int = 0x8000; ++pub const STA_RONLY: ::c_int = STA_PPSSIGNAL ++ | STA_PPSJITTER ++ | STA_PPSWANDER ++ | STA_PPSERROR ++ | STA_CLOCKERR ++ | STA_NANO ++ | STA_MODE ++ | STA_CLK; ++ ++pub const TIME_OK: ::c_int = 0; ++pub const TIME_INS: ::c_int = 1; ++pub const TIME_DEL: ::c_int = 2; ++pub const TIME_OOP: ::c_int = 3; ++pub const TIME_WAIT: ::c_int = 4; ++pub const TIME_ERROR: ::c_int = 5; ++pub const TIME_BAD: ::c_int = TIME_ERROR; ++pub const MAXTC: ::c_long = 6; ++ + cfg_if! { + if #[cfg(target_arch = "s390x")] { + pub const POSIX_FADV_DONTNEED: ::c_int = 6; +@@ -665,27 +736,11 @@ extern "C" { + old_limit: *mut ::rlimit64, + ) -> ::c_int; + ++ pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn ptrace(request: ::c_int, ...) -> ::c_long; + pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int; + pub fn setpriority(which: ::c_int, who: ::id_t, prio: ::c_int) -> ::c_int; +- pub fn pthread_getaffinity_np( +- thread: ::pthread_t, +- cpusetsize: ::size_t, +- cpuset: *mut ::cpu_set_t, +- ) -> ::c_int; +- pub fn pthread_setaffinity_np( +- thread: ::pthread_t, +- cpusetsize: ::size_t, +- cpuset: *const ::cpu_set_t, +- ) -> ::c_int; +- pub fn sched_getcpu() -> ::c_int; +- pub fn memmem( +- haystack: *const ::c_void, +- haystacklen: ::size_t, +- needle: *const ::c_void, +- needlelen: ::size_t, +- ) -> *mut ::c_void; + // Musl targets need the `mask` argument of `fanotify_mark` be specified + // `::c_ulonglong` instead of `u64` or there will be a type mismatch between + // `long long unsigned int` and the expected `uint64_t`. +@@ -700,6 +755,33 @@ extern "C" { + + // Added in `musl` 1.1.20 + pub fn explicit_bzero(s: *mut ::c_void, len: ::size_t); ++ // Added in `musl` 1.2.2 ++ pub fn reallocarray(ptr: *mut ::c_void, nmemb: ::size_t, size: ::size_t) -> *mut ::c_void; ++ ++ pub fn adjtimex(buf: *mut ::timex) -> ::c_int; ++ pub fn clock_adjtime(clk_id: ::clockid_t, buf: *mut ::timex) -> ::c_int; ++ ++ pub fn ctermid(s: *mut ::c_char) -> *mut ::c_char; ++ ++ pub fn memfd_create(name: *const ::c_char, flags: ::c_uint) -> ::c_int; ++ pub fn mlock2(addr: *const ::c_void, len: ::size_t, flags: ::c_uint) -> ::c_int; ++ pub fn malloc_usable_size(ptr: *mut ::c_void) -> ::size_t; ++ ++ pub fn euidaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int; ++ pub fn eaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int; ++ ++ pub fn asctime_r(tm: *const ::tm, buf: *mut ::c_char) -> *mut ::c_char; ++ ++ pub fn strftime( ++ s: *mut ::c_char, ++ max: ::size_t, ++ format: *const ::c_char, ++ tm: *const ::tm, ++ ) -> ::size_t; ++ pub fn strptime(s: *const ::c_char, format: *const ::c_char, tm: *mut ::tm) -> *mut ::c_char; ++ ++ pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; ++ pub fn basename(path: *mut ::c_char) -> *mut ::c_char; + } + + cfg_if! { +@@ -707,13 +789,15 @@ cfg_if! { + target_arch = "aarch64", + target_arch = "mips64", + target_arch = "powerpc64", +- target_arch = "s390x"))] { ++ target_arch = "s390x", ++ target_arch = "riscv64"))] { + mod b64; + pub use self::b64::*; + } else if #[cfg(any(target_arch = "x86", + target_arch = "mips", + target_arch = "powerpc", + target_arch = "hexagon", ++ target_arch = "riscv32", + target_arch = "arm"))] { + mod b32; + pub use self::b32::*; +diff --git a/vendor/libc/src/unix/linux_like/linux/no_align.rs b/vendor/libc/src/unix/linux_like/linux/no_align.rs +index de64be5..6f5f2f7 100644 +--- a/vendor/libc/src/unix/linux_like/linux/no_align.rs ++++ b/vendor/libc/src/unix/linux_like/linux/no_align.rs +@@ -9,8 +9,9 @@ macro_rules! expand_align { + target_arch = "sparc64", + target_arch = "riscv64", + target_arch = "riscv32", ++ target_arch = "loongarch64", + all(target_arch = "aarch64", +- target_env = "musl")))] ++ any(target_env = "musl", target_env = "ohos"))))] + __align: [::c_int; 0], + #[cfg(not(any(target_arch = "x86_64", + target_arch = "powerpc64", +@@ -19,16 +20,17 @@ macro_rules! expand_align { + target_arch = "sparc64", + target_arch = "riscv64", + target_arch = "riscv32", ++ target_arch = "loongarch64", + all(target_arch = "aarch64", +- target_env = "musl"))))] ++ any(target_env = "musl", target_env = "ohos")))))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + pub struct pthread_rwlockattr_t { +- #[cfg(target_env = "musl")] ++ #[cfg(any(target_env = "musl", target_env = "ohos"))] + __align: [::c_int; 0], +- #[cfg(not(target_env = "musl"))] ++ #[cfg(not(any(target_env = "musl", target_env = "ohos")))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } +@@ -38,6 +40,11 @@ macro_rules! expand_align { + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + ++ pub struct pthread_barrierattr_t { ++ __align: [::c_int; 0], ++ size: [u8; ::__SIZEOF_PTHREAD_BARRIERATTR_T], ++ } ++ + pub struct fanotify_event_metadata { + __align: [::c_long; 0], + pub event_len: __u32, +@@ -52,9 +59,9 @@ macro_rules! expand_align { + + s_no_extra_traits! { + pub struct pthread_cond_t { +- #[cfg(target_env = "musl")] ++ #[cfg(any(target_env = "musl", target_env = "ohos"))] + __align: [*const ::c_void; 0], +- #[cfg(not(target_env = "musl"))] ++ #[cfg(not(any(target_env = "musl", target_env = "ohos")))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } +@@ -62,6 +69,7 @@ macro_rules! expand_align { + pub struct pthread_mutex_t { + #[cfg(any(target_arch = "mips", + target_arch = "arm", ++ target_arch = "m68k", + target_arch = "powerpc", + target_arch = "sparc", + all(target_arch = "x86_64", +@@ -69,6 +77,7 @@ macro_rules! expand_align { + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "mips", + target_arch = "arm", ++ target_arch = "m68k", + target_arch = "powerpc", + target_arch = "sparc", + all(target_arch = "x86_64", +@@ -80,6 +89,7 @@ macro_rules! expand_align { + pub struct pthread_rwlock_t { + #[cfg(any(target_arch = "mips", + target_arch = "arm", ++ target_arch = "m68k", + target_arch = "powerpc", + target_arch = "sparc", + all(target_arch = "x86_64", +@@ -87,6 +97,7 @@ macro_rules! expand_align { + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "mips", + target_arch = "arm", ++ target_arch = "m68k", + target_arch = "powerpc", + target_arch = "sparc", + all(target_arch = "x86_64", +@@ -94,6 +105,26 @@ macro_rules! expand_align { + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } ++ ++ pub struct pthread_barrier_t { ++ #[cfg(any(target_arch = "mips", ++ target_arch = "arm", ++ target_arch = "m68k", ++ target_arch = "powerpc", ++ target_arch = "sparc", ++ all(target_arch = "x86_64", ++ target_pointer_width = "32")))] ++ __align: [::c_long; 0], ++ #[cfg(not(any(target_arch = "mips", ++ target_arch = "arm", ++ target_arch = "m68k", ++ target_arch = "powerpc", ++ target_arch = "sparc", ++ all(target_arch = "x86_64", ++ target_pointer_width = "32"))))] ++ __align: [::c_longlong; 0], ++ size: [u8; ::__SIZEOF_PTHREAD_BARRIER_T], ++ } + } + }; + } +diff --git a/vendor/libc/src/unix/linux_like/linux/non_exhaustive.rs b/vendor/libc/src/unix/linux_like/linux/non_exhaustive.rs +new file mode 100644 +index 0000000..e2e2cb8 +--- /dev/null ++++ b/vendor/libc/src/unix/linux_like/linux/non_exhaustive.rs +@@ -0,0 +1,9 @@ ++s! { ++ // linux/openat2.h ++ #[non_exhaustive] ++ pub struct open_how { ++ pub flags: ::__u64, ++ pub mode: ::__u64, ++ pub resolve: ::__u64, ++ } ++} +diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/arm/mod.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/arm/mod.rs +index dc6518c..cff82f0 100644 +--- a/vendor/libc/src/unix/linux_like/linux/uclibc/arm/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/uclibc/arm/mod.rs +@@ -10,7 +10,6 @@ pub type fsfilcnt_t = ::c_ulong; + pub type ino_t = ::c_ulong; + pub type off_t = ::c_long; + pub type pthread_t = ::c_ulong; +-pub type rlim_t = ::c_ulong; + pub type suseconds_t = ::c_long; + + pub type nlink_t = ::c_uint; +@@ -20,6 +19,7 @@ pub type blkcnt_t = ::c_long; + pub type fsblkcnt64_t = u64; + pub type fsfilcnt64_t = u64; + pub type __u64 = ::c_ulonglong; ++pub type __s64 = ::c_longlong; + + s! { + pub struct cmsghdr { +@@ -44,14 +44,14 @@ s! { + + pub struct stat { + pub st_dev: ::c_ulonglong, +- pub __pad1: ::c_ushort, ++ __pad1: ::c_ushort, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulonglong, +- pub __pad2: ::c_ushort, ++ __pad2: ::c_ushort, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, +@@ -61,8 +61,8 @@ s! { + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, +- pub __uclibc_unused4: ::c_ulong, +- pub __uclibc_unused5: ::c_ulong, ++ __unused4: ::c_ulong, ++ __unused5: ::c_ulong, + } + + pub struct stat64 +@@ -202,49 +202,48 @@ s! { + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_ushort, +- pub __pad1: ::c_ushort, ++ __pad1: ::c_ushort, + pub __seq: ::c_ushort, +- pub __pad2: ::c_ushort, +- pub __uclibc_unused1: ::c_ulong, +- pub __uclibc_unused2: ::c_ulong, ++ __pad2: ::c_ushort, ++ __unused1: ::c_ulong, ++ __unused2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, +- pub __uclibc_unused1: ::c_ulong, ++ __unused1: ::c_ulong, + pub msg_rtime: ::time_t, +- pub __uclibc_unused2: ::c_ulong, ++ __unused2: ::c_ulong, + pub msg_ctime: ::time_t, +- pub __uclibc_unused3: ::c_ulong, +- pub __msg_cbytes: ::c_ulong, ++ __unused3: ::c_ulong, ++ __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, +- pub __uclibc_unused4: ::c_ulong, +- pub __uclibc_unused5: ::c_ulong, ++ __unused4: ::c_ulong, ++ __unused5: ::c_ulong, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, +- pub __uclibc_unused1: ::c_ulong, ++ __unused1: ::c_ulong, + pub shm_dtime: ::time_t, +- pub __uclibc_unused2: ::c_ulong, ++ __unused2: ::c_ulong, + pub shm_ctime: ::time_t, +- pub __uclibc_unused3: ::c_ulong, ++ __unused3: ::c_ulong, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, +- pub __uclibc_unused4: ::c_ulong, +- pub __uclibc_unused5: ::c_ulong, ++ __unused4: ::c_ulong, ++ __unused5: ::c_ulong, + } + } + + pub const O_CLOEXEC: ::c_int = 0o2000000; +-pub const RLIM_INFINITY: rlim_t = !0; + pub const __SIZEOF_PTHREAD_ATTR_T: usize = 36; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 24; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +@@ -417,9 +416,6 @@ pub const EUSERS: ::c_int = 0x57; + pub const EXFULL: ::c_int = 0x36; + pub const FF1: ::c_int = 0x8000; + pub const FFDLY: ::c_int = 0x8000; +-pub const FIONBIO: ::c_ulong = 0x5421; +-pub const FIOCLEX: ::c_ulong = 0x5451; +-pub const FIONCLEX: ::c_ulong = 0x5450; + pub const FLUSHO: ::tcflag_t = 0x1000; + pub const F_GETLK: ::c_int = 0x5; + pub const F_SETLK: ::c_int = 0x6; +@@ -469,6 +465,8 @@ pub const PENDIN: ::tcflag_t = 0x4000; + pub const POLLWRBAND: ::c_short = 0x200; + pub const POLLWRNORM: ::c_short = 0x100; + pub const PTHREAD_STACK_MIN: ::size_t = 16384; ++pub const RTLD_GLOBAL: ::c_int = 0x00100; ++pub const PIDFD_NONBLOCK: ::c_int = 0x800; + + // These are typed unsigned to match sigaction + pub const SA_NOCLDSTOP: ::c_ulong = 0x1; +@@ -886,10 +884,35 @@ pub const SYS_pwritev2: ::c_long = 393; + pub const SYS_pkey_mprotect: ::c_long = 394; + pub const SYS_pkey_alloc: ::c_long = 395; + pub const SYS_pkey_free: ::c_long = 396; +- +-extern "C" { +- pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; +-} ++// FIXME: should be a `c_long` too, but a bug slipped in. ++pub const SYS_statx: ::c_int = 397; ++pub const SYS_pidfd_send_signal: ::c_long = 424; ++pub const SYS_io_uring_setup: ::c_long = 425; ++pub const SYS_io_uring_enter: ::c_long = 426; ++pub const SYS_io_uring_register: ::c_long = 427; ++pub const SYS_open_tree: ::c_long = 428; ++pub const SYS_move_mount: ::c_long = 429; ++pub const SYS_fsopen: ::c_long = 430; ++pub const SYS_fsconfig: ::c_long = 431; ++pub const SYS_fsmount: ::c_long = 432; ++pub const SYS_fspick: ::c_long = 433; ++pub const SYS_pidfd_open: ::c_long = 434; ++pub const SYS_clone3: ::c_long = 435; ++pub const SYS_close_range: ::c_long = 436; ++pub const SYS_openat2: ::c_long = 437; ++pub const SYS_pidfd_getfd: ::c_long = 438; ++pub const SYS_faccessat2: ::c_long = 439; ++pub const SYS_process_madvise: ::c_long = 440; ++pub const SYS_epoll_pwait2: ::c_long = 441; ++pub const SYS_mount_setattr: ::c_long = 442; ++pub const SYS_quotactl_fd: ::c_long = 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 444; ++pub const SYS_landlock_add_rule: ::c_long = 445; ++pub const SYS_landlock_restrict_self: ::c_long = 446; ++pub const SYS_memfd_secret: ::c_long = 447; ++pub const SYS_process_mrelease: ::c_long = 448; ++pub const SYS_futex_waitv: ::c_long = 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 450; + + cfg_if! { + if #[cfg(libc_align)] { +diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs +index 8edde11..a5aca85 100644 +--- a/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs +@@ -12,8 +12,8 @@ pub type blksize_t = i32; + pub type nlink_t = u32; + pub type fsblkcnt_t = ::c_ulong; + pub type fsfilcnt_t = ::c_ulong; +-pub type rlim_t = ::c_ulong; + pub type __u64 = ::c_ulonglong; ++pub type __s64 = ::c_longlong; + pub type fsblkcnt64_t = u64; + pub type fsfilcnt64_t = u64; + +@@ -265,8 +265,6 @@ pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; + pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 20; + pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + +-pub const RLIM_INFINITY: ::rlim_t = 0x7fffffff; +- + pub const SYS_syscall: ::c_long = 4000 + 0; + pub const SYS_exit: ::c_long = 4000 + 1; + pub const SYS_fork: ::c_long = 4000 + 2; +@@ -625,6 +623,34 @@ pub const SYS_pwritev2: ::c_long = 4000 + 362; + pub const SYS_pkey_mprotect: ::c_long = 4000 + 363; + pub const SYS_pkey_alloc: ::c_long = 4000 + 364; + pub const SYS_pkey_free: ::c_long = 4000 + 365; ++pub const SYS_statx: ::c_long = 4000 + 366; ++pub const SYS_pidfd_send_signal: ::c_long = 4000 + 424; ++pub const SYS_io_uring_setup: ::c_long = 4000 + 425; ++pub const SYS_io_uring_enter: ::c_long = 4000 + 426; ++pub const SYS_io_uring_register: ::c_long = 4000 + 427; ++pub const SYS_open_tree: ::c_long = 4000 + 428; ++pub const SYS_move_mount: ::c_long = 4000 + 429; ++pub const SYS_fsopen: ::c_long = 4000 + 430; ++pub const SYS_fsconfig: ::c_long = 4000 + 431; ++pub const SYS_fsmount: ::c_long = 4000 + 432; ++pub const SYS_fspick: ::c_long = 4000 + 433; ++pub const SYS_pidfd_open: ::c_long = 4000 + 434; ++pub const SYS_clone3: ::c_long = 4000 + 435; ++pub const SYS_close_range: ::c_long = 4000 + 436; ++pub const SYS_openat2: ::c_long = 4000 + 437; ++pub const SYS_pidfd_getfd: ::c_long = 4000 + 438; ++pub const SYS_faccessat2: ::c_long = 4000 + 439; ++pub const SYS_process_madvise: ::c_long = 4000 + 440; ++pub const SYS_epoll_pwait2: ::c_long = 4000 + 441; ++pub const SYS_mount_setattr: ::c_long = 4000 + 442; ++pub const SYS_quotactl_fd: ::c_long = 4000 + 443; ++pub const SYS_landlock_create_ruleset: ::c_long = 4000 + 444; ++pub const SYS_landlock_add_rule: ::c_long = 4000 + 445; ++pub const SYS_landlock_restrict_self: ::c_long = 4000 + 446; ++pub const SYS_memfd_secret: ::c_long = 4000 + 447; ++pub const SYS_process_mrelease: ::c_long = 4000 + 448; ++pub const SYS_futex_waitv: ::c_long = 4000 + 449; ++pub const SYS_set_mempolicy_home_node: ::c_long = 4000 + 450; + + #[link(name = "util")] + extern "C" { +@@ -636,7 +662,6 @@ extern "C" { + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; +- pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; + pub fn glob64( + pattern: *const ::c_char, + flags: ::c_int, +diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs +index 735eb85..8ca100f 100644 +--- a/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs +@@ -8,7 +8,6 @@ pub type fsfilcnt_t = ::c_ulong; + pub type ino_t = u64; + pub type nlink_t = u64; + pub type off_t = i64; +-pub type rlim_t = ::c_ulong; + pub type suseconds_t = i64; + pub type time_t = i64; + pub type wchar_t = i32; +@@ -190,18 +189,13 @@ s! { + + pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; ++pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +- +-pub const RLIM_INFINITY: ::rlim_t = 0xffff_ffff_ffff_ffff; ++pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + + pub const SYS_gettid: ::c_long = 5178; // Valid for n64 + +-#[link(name = "util")] +-extern "C" { +- pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; +-} +- + cfg_if! { + if #[cfg(libc_align)] { + mod align; +diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mod.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mod.rs +index 28fa9a2..56bfcc5 100644 +--- a/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mod.rs +@@ -32,24 +32,14 @@ pub const EPOLL_CLOEXEC: ::c_int = 0x80000; + + pub const EFD_CLOEXEC: ::c_int = 0x80000; + +-pub const BUFSIZ: ::c_uint = 4096; + pub const TMP_MAX: ::c_uint = 238328; +-pub const FOPEN_MAX: ::c_uint = 16; +-pub const POSIX_MADV_DONTNEED: ::c_int = 4; + pub const _SC_2_C_VERSION: ::c_int = 96; + pub const O_ACCMODE: ::c_int = 3; + pub const O_DIRECT: ::c_int = 0x8000; + pub const O_DIRECTORY: ::c_int = 0x10000; + pub const O_NOFOLLOW: ::c_int = 0x20000; +-pub const NI_MAXHOST: ::socklen_t = 1025; +- +-pub const RLIMIT_NOFILE: ::c_int = 5; +-pub const RLIMIT_AS: ::c_int = 6; +-pub const RLIMIT_RSS: ::c_int = 7; +-pub const RLIMIT_NPROC: ::c_int = 8; +-pub const RLIMIT_MEMLOCK: ::c_int = 9; +-pub const RLIMIT_NLIMITS: ::c_int = 15; +-pub const RLIM_NLIMITS: ::c_int = RLIMIT_NLIMITS; ++pub const O_NOATIME: ::c_int = 0x40000; ++pub const O_PATH: ::c_int = 0o010000000; + + pub const O_APPEND: ::c_int = 8; + pub const O_CREAT: ::c_int = 256; +@@ -61,9 +51,11 @@ pub const O_RSYNC: ::c_int = 0x10; + pub const O_DSYNC: ::c_int = 0x10; + pub const O_FSYNC: ::c_int = 0x10; + pub const O_ASYNC: ::c_int = 0x1000; ++pub const O_LARGEFILE: ::c_int = 0x2000; + pub const O_NDELAY: ::c_int = 0x80; + + pub const SOCK_NONBLOCK: ::c_int = 128; ++pub const PIDFD_NONBLOCK: ::c_int = 128; + + pub const EDEADLK: ::c_int = 45; + pub const ENAMETOOLONG: ::c_int = 78; +@@ -84,10 +76,10 @@ pub const EL2HLT: ::c_int = 44; + pub const EBADE: ::c_int = 50; + pub const EBADR: ::c_int = 51; + pub const EXFULL: ::c_int = 52; ++pub const FFDLY: ::c_int = 0o0100000; + pub const ENOANO: ::c_int = 53; + pub const EBADRQC: ::c_int = 54; + pub const EBADSLT: ::c_int = 55; +-pub const EDEADLOCK: ::c_int = 56; + pub const EMULTIHOP: ::c_int = 74; + pub const EOVERFLOW: ::c_int = 79; + pub const ENOTUNIQ: ::c_int = 80; +@@ -160,14 +152,12 @@ pub const MAP_POPULATE: ::c_int = 0x10000; + pub const MAP_NONBLOCK: ::c_int = 0x20000; + pub const MAP_STACK: ::c_int = 0x40000; + ++pub const NLDLY: ::tcflag_t = 0o0000400; ++ + pub const SOCK_STREAM: ::c_int = 2; + pub const SOCK_DGRAM: ::c_int = 1; + pub const SOCK_SEQPACKET: ::c_int = 5; + +-pub const FIOCLEX: ::c_ulong = 0x6601; +-pub const FIONCLEX: ::c_ulong = 0x6602; +-pub const FIONBIO: ::c_ulong = 0x667e; +- + pub const SA_ONSTACK: ::c_uint = 0x08000000; + pub const SA_SIGINFO: ::c_uint = 0x00000008; + pub const SA_NOCLDWAIT: ::c_int = 0x00010000; +@@ -189,7 +179,6 @@ pub const SIGTSTP: ::c_int = 24; + pub const SIGURG: ::c_int = 21; + pub const SIGIO: ::c_int = 22; + pub const SIGSYS: ::c_int = 12; +-pub const SIGPOLL: ::c_int = 22; + pub const SIGPWR: ::c_int = 19; + pub const SIG_SETMASK: ::c_int = 3; + pub const SIG_BLOCK: ::c_int = 0x1; +@@ -216,74 +205,48 @@ pub const CPU_SETSIZE: ::c_int = 0x400; + pub const EFD_NONBLOCK: ::c_int = 0x80; + + pub const F_GETLK: ::c_int = 14; +-pub const F_GETOWN: ::c_int = 23; +-pub const F_SETOWN: ::c_int = 24; + pub const F_SETLK: ::c_int = 6; + pub const F_SETLKW: ::c_int = 7; + + pub const SFD_NONBLOCK: ::c_int = 0x80; + +-pub const TCGETS: ::c_ulong = 0x540d; +-pub const TCSETS: ::c_ulong = 0x540e; +-pub const TCSETSW: ::c_ulong = 0x540f; +-pub const TCSETSF: ::c_ulong = 0x5410; +-pub const TCGETA: ::c_ulong = 0x5401; +-pub const TCSETA: ::c_ulong = 0x5402; +-pub const TCSETAW: ::c_ulong = 0x5403; +-pub const TCSETAF: ::c_ulong = 0x5404; +-pub const TCSBRK: ::c_ulong = 0x5405; +-pub const TCXONC: ::c_ulong = 0x5406; +-pub const TCFLSH: ::c_ulong = 0x5407; +-pub const TIOCGSOFTCAR: ::c_ulong = 0x5481; +-pub const TIOCSSOFTCAR: ::c_ulong = 0x5482; +-pub const TIOCINQ: ::c_ulong = 0x467f; +-pub const TIOCLINUX: ::c_ulong = 0x5483; +-pub const TIOCGSERIAL: ::c_ulong = 0x5484; +-pub const TIOCEXCL: ::c_ulong = 0x740d; +-pub const TIOCNXCL: ::c_ulong = 0x740e; +-pub const TIOCSCTTY: ::c_ulong = 0x5480; +-pub const TIOCGPGRP: ::c_ulong = 0x40047477; +-pub const TIOCSPGRP: ::c_ulong = 0x80047476; +-pub const TIOCOUTQ: ::c_ulong = 0x7472; +-pub const TIOCSTI: ::c_ulong = 0x5472; +-pub const TIOCGWINSZ: ::c_ulong = 0x40087468; +-pub const TIOCSWINSZ: ::c_ulong = 0x80087467; +-pub const TIOCMGET: ::c_ulong = 0x741d; +-pub const TIOCMBIS: ::c_ulong = 0x741b; +-pub const TIOCMBIC: ::c_ulong = 0x741c; +-pub const TIOCMSET: ::c_ulong = 0x741a; +-pub const FIONREAD: ::c_ulong = 0x467f; +-pub const TIOCCONS: ::c_ulong = 0x80047478; +- + pub const RTLD_GLOBAL: ::c_int = 0x4; +-pub const RTLD_NOLOAD: ::c_int = 0x8; + + pub const SIGSTKSZ: ::size_t = 8192; + pub const CBAUD: ::tcflag_t = 0o0010017; ++pub const CBAUDEX: ::tcflag_t = 0o0010000; ++pub const CIBAUD: ::tcflag_t = 0o002003600000; + pub const TAB1: ::tcflag_t = 0x00000800; + pub const TAB2: ::tcflag_t = 0x00001000; + pub const TAB3: ::tcflag_t = 0x00001800; ++pub const TABDLY: ::tcflag_t = 0o0014000; + pub const CR1: ::tcflag_t = 0x00000200; + pub const CR2: ::tcflag_t = 0x00000400; + pub const CR3: ::tcflag_t = 0x00000600; + pub const FF1: ::tcflag_t = 0x00008000; + pub const BS1: ::tcflag_t = 0x00002000; ++pub const BSDLY: ::tcflag_t = 0o0020000; + pub const VT1: ::tcflag_t = 0x00004000; + pub const VWERASE: usize = 14; ++pub const XTABS: ::tcflag_t = 0o0014000; + pub const VREPRINT: usize = 12; + pub const VSUSP: usize = 10; ++pub const VSWTC: usize = 7; ++pub const VTDLY: ::c_int = 0o0040000; + pub const VSTART: usize = 8; + pub const VSTOP: usize = 9; + pub const VDISCARD: usize = 13; + pub const VTIME: usize = 5; + pub const IXON: ::tcflag_t = 0x00000400; + pub const IXOFF: ::tcflag_t = 0x00001000; ++pub const OLCUC: ::tcflag_t = 0o0000002; + pub const ONLCR: ::tcflag_t = 0x4; + pub const CSIZE: ::tcflag_t = 0x00000030; + pub const CS6: ::tcflag_t = 0x00000010; + pub const CS7: ::tcflag_t = 0x00000020; + pub const CS8: ::tcflag_t = 0x00000030; + pub const CSTOPB: ::tcflag_t = 0x00000040; ++pub const CRDLY: ::c_int = 0o0003000; + pub const CREAD: ::tcflag_t = 0x00000080; + pub const PARENB: ::tcflag_t = 0x00000100; + pub const PARODD: ::tcflag_t = 0x00000200; +@@ -300,6 +263,8 @@ pub const ICANON: ::tcflag_t = 0x00000002; + pub const PENDIN: ::tcflag_t = 0x00004000; + pub const NOFLSH: ::tcflag_t = 0x00000080; + ++pub const MAP_HUGETLB: ::c_int = 0x80000; ++ + pub const B0: ::speed_t = 0o000000; + pub const B50: ::speed_t = 0o000001; + pub const B75: ::speed_t = 0o000002; +@@ -316,8 +281,6 @@ pub const B4800: ::speed_t = 0o000014; + pub const B9600: ::speed_t = 0o000015; + pub const B19200: ::speed_t = 0o000016; + pub const B38400: ::speed_t = 0o000017; +-pub const EXTA: ::speed_t = B19200; +-pub const EXTB: ::speed_t = B38400; + pub const B57600: ::speed_t = 0o010001; + pub const B115200: ::speed_t = 0o010002; + pub const B230400: ::speed_t = 0o010003; +diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/mod.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/mod.rs +index 60a40e7..4a01e0c 100644 +--- a/vendor/libc/src/unix/linux_like/linux/uclibc/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/uclibc/mod.rs +@@ -2,6 +2,19 @@ pub type shmatt_t = ::c_ulong; + pub type msgqnum_t = ::c_ulong; + pub type msglen_t = ::c_ulong; + pub type regoff_t = ::c_int; ++pub type rlim_t = ::c_ulong; ++pub type __rlimit_resource_t = ::c_ulong; ++pub type __priority_which_t = ::c_uint; ++ ++cfg_if! { ++ if #[cfg(doc)] { ++ // Used in `linux::arch` to define ioctl constants. ++ pub(crate) type Ioctl = ::c_ulong; ++ } else { ++ #[doc(hidden)] ++ pub type Ioctl = ::c_ulong; ++ } ++} + + s! { + pub struct statvfs { // Different than GNU! +@@ -34,6 +47,64 @@ s! { + __re_nsub: ::size_t, + __bitfield: u8, + } ++ ++ pub struct rtentry { ++ pub rt_pad1: ::c_ulong, ++ pub rt_dst: ::sockaddr, ++ pub rt_gateway: ::sockaddr, ++ pub rt_genmask: ::sockaddr, ++ pub rt_flags: ::c_ushort, ++ pub rt_pad2: ::c_short, ++ pub rt_pad3: ::c_ulong, ++ pub rt_tos: ::c_uchar, ++ pub rt_class: ::c_uchar, ++ #[cfg(target_pointer_width = "64")] ++ pub rt_pad4: [::c_short; 3usize], ++ #[cfg(not(target_pointer_width = "64"))] ++ pub rt_pad4: ::c_short, ++ pub rt_metric: ::c_short, ++ pub rt_dev: *mut ::c_char, ++ pub rt_mtu: ::c_ulong, ++ pub rt_window: ::c_ulong, ++ pub rt_irtt: ::c_ushort, ++ } ++ ++ pub struct __exit_status { ++ pub e_termination: ::c_short, ++ pub e_exit: ::c_short, ++ } ++ ++ pub struct ptrace_peeksiginfo_args { ++ pub off: ::__u64, ++ pub flags: ::__u32, ++ pub nr: ::__s32, ++ } ++} ++ ++impl siginfo_t { ++ pub unsafe fn si_addr(&self) -> *mut ::c_void { ++ #[repr(C)] ++ struct siginfo_sigfault { ++ _si_signo: ::c_int, ++ _si_errno: ::c_int, ++ _si_code: ::c_int, ++ si_addr: *mut ::c_void, ++ } ++ (*(self as *const siginfo_t as *const siginfo_sigfault)).si_addr ++ } ++ ++ pub unsafe fn si_value(&self) -> ::sigval { ++ #[repr(C)] ++ struct siginfo_si_value { ++ _si_signo: ::c_int, ++ _si_errno: ::c_int, ++ _si_code: ::c_int, ++ _si_timerid: ::c_int, ++ _si_overrun: ::c_int, ++ si_value: ::sigval, ++ } ++ (*(self as *const siginfo_t as *const siginfo_si_value)).si_value ++ } + } + + pub const MCL_CURRENT: ::c_int = 0x0001; +@@ -43,55 +114,10 @@ pub const SIGEV_THREAD_ID: ::c_int = 4; + + pub const AF_VSOCK: ::c_int = 40; + +-pub const ADFS_SUPER_MAGIC: ::c_long = 0x0000adf5; +-pub const AFFS_SUPER_MAGIC: ::c_long = 0x0000adff; +-pub const AFS_SUPER_MAGIC: ::c_long = 0x5346414f; +-pub const AUTOFS_SUPER_MAGIC: ::c_long = 0x0187; ++// Most `*_SUPER_MAGIC` constants are defined at the `linux_like` level; the ++// following are only available on newer Linux versions than the versions ++// currently used in CI in some configurations, so we define them here. + pub const BINDERFS_SUPER_MAGIC: ::c_long = 0x6c6f6f70; +-pub const BPF_FS_MAGIC: ::c_long = 0xcafe4a11; +-pub const BTRFS_SUPER_MAGIC: ::c_long = 0x9123683e; +-pub const CGROUP2_SUPER_MAGIC: ::c_long = 0x63677270; +-pub const CGROUP_SUPER_MAGIC: ::c_long = 0x27e0eb; +-pub const CODA_SUPER_MAGIC: ::c_long = 0x73757245; +-pub const CRAMFS_MAGIC: ::c_long = 0x28cd3d45; +-pub const DEBUGFS_MAGIC: ::c_long = 0x64626720; +-pub const DEVPTS_SUPER_MAGIC: ::c_long = 0x1cd1; +-pub const ECRYPTFS_SUPER_MAGIC: ::c_long = 0xf15f; +-pub const EFS_SUPER_MAGIC: ::c_long = 0x00414a53; +-pub const EXT2_SUPER_MAGIC: ::c_long = 0x0000ef53; +-pub const EXT3_SUPER_MAGIC: ::c_long = 0x0000ef53; +-pub const EXT4_SUPER_MAGIC: ::c_long = 0x0000ef53; +-pub const F2FS_SUPER_MAGIC: ::c_long = 0xf2f52010; +-pub const FUTEXFS_SUPER_MAGIC: ::c_long = 0xbad1dea; +-pub const HOSTFS_SUPER_MAGIC: ::c_long = 0x00c0ffee; +-pub const HPFS_SUPER_MAGIC: ::c_long = 0xf995e849; +-pub const HUGETLBFS_MAGIC: ::c_long = 0x958458f6; +-pub const ISOFS_SUPER_MAGIC: ::c_long = 0x00009660; +-pub const JFFS2_SUPER_MAGIC: ::c_long = 0x000072b6; +-pub const MINIX2_SUPER_MAGIC2: ::c_long = 0x00002478; +-pub const MINIX2_SUPER_MAGIC: ::c_long = 0x00002468; +-pub const MINIX3_SUPER_MAGIC: ::c_long = 0x4d5a; +-pub const MINIX_SUPER_MAGIC2: ::c_long = 0x0000138f; +-pub const MINIX_SUPER_MAGIC: ::c_long = 0x0000137f; +-pub const MSDOS_SUPER_MAGIC: ::c_long = 0x00004d44; +-pub const NCP_SUPER_MAGIC: ::c_long = 0x0000564c; +-pub const NFS_SUPER_MAGIC: ::c_long = 0x00006969; +-pub const NILFS_SUPER_MAGIC: ::c_long = 0x3434; +-pub const OCFS2_SUPER_MAGIC: ::c_long = 0x7461636f; +-pub const OPENPROM_SUPER_MAGIC: ::c_long = 0x00009fa1; +-pub const OVERLAYFS_SUPER_MAGIC: ::c_long = 0x794c7630; +-pub const PROC_SUPER_MAGIC: ::c_long = 0x00009fa0; +-pub const QNX4_SUPER_MAGIC: ::c_long = 0x0000002f; +-pub const QNX6_SUPER_MAGIC: ::c_long = 0x68191122; +-pub const RDTGROUP_SUPER_MAGIC: ::c_long = 0x7655821; +-pub const REISERFS_SUPER_MAGIC: ::c_long = 0x52654973; +-pub const SMB_SUPER_MAGIC: ::c_long = 0x0000517b; +-pub const SYSFS_MAGIC: ::c_long = 0x62656572; +-pub const TMPFS_MAGIC: ::c_long = 0x01021994; +-pub const TRACEFS_MAGIC: ::c_long = 0x74726163; +-pub const UDF_SUPER_MAGIC: ::c_long = 0x15013346; +-pub const USBDEVICE_SUPER_MAGIC: ::c_long = 0x00009fa2; +-pub const XENFS_SUPER_MAGIC: ::c_long = 0xabba1974; + pub const XFS_SUPER_MAGIC: ::c_long = 0x58465342; + + pub const PTRACE_TRACEME: ::c_int = 0; +@@ -122,22 +148,10 @@ pub const PTRACE_SETREGSET: ::c_int = 0x4205; + pub const PTRACE_SEIZE: ::c_int = 0x4206; + pub const PTRACE_INTERRUPT: ::c_int = 0x4207; + pub const PTRACE_LISTEN: ::c_int = 0x4208; +-pub const PTRACE_O_MASK: ::c_int = 0x000000ff; + + pub const POSIX_FADV_DONTNEED: ::c_int = 4; + pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +-pub const RLIMIT_CPU: ::c_int = 0; +-pub const RLIMIT_FSIZE: ::c_int = 1; +-pub const RLIMIT_DATA: ::c_int = 2; +-pub const RLIMIT_STACK: ::c_int = 3; +-pub const RLIMIT_CORE: ::c_int = 4; +-pub const RLIMIT_LOCKS: ::c_int = 10; +-pub const RLIMIT_SIGPENDING: ::c_int = 11; +-pub const RLIMIT_MSGQUEUE: ::c_int = 12; +-pub const RLIMIT_NICE: ::c_int = 13; +-pub const RLIMIT_RTPRIO: ::c_int = 14; +- + // These are different than GNU! + pub const LC_CTYPE: ::c_int = 0; + pub const LC_NUMERIC: ::c_int = 1; +@@ -221,9 +235,67 @@ pub const PRIO_PROCESS: ::c_int = 0; + pub const PRIO_PGRP: ::c_int = 1; + pub const PRIO_USER: ::c_int = 2; + ++pub const SOMAXCONN: ::c_int = 128; ++ + pub const ST_RELATIME: ::c_ulong = 4096; + ++pub const AF_NFC: ::c_int = PF_NFC; ++pub const BUFSIZ: ::c_int = 4096; ++pub const EDEADLOCK: ::c_int = EDEADLK; ++pub const EXTA: ::c_uint = B19200; ++pub const EXTB: ::c_uint = B38400; ++pub const EXTPROC: ::tcflag_t = 0200000; ++pub const FAN_MARK_FILESYSTEM: ::c_int = 0x00000100; ++pub const FAN_MARK_INODE: ::c_int = 0x00000000; ++pub const FAN_MARK_MOUNT: ::c_int = 0x10; ++pub const FOPEN_MAX: ::c_int = 16; ++pub const F_GETOWN: ::c_int = 9; ++pub const F_OFD_GETLK: ::c_int = 36; ++pub const F_OFD_SETLK: ::c_int = 37; ++pub const F_OFD_SETLKW: ::c_int = 38; ++pub const F_RDLCK: ::c_int = 0; ++pub const F_SETOWN: ::c_int = 8; ++pub const F_UNLCK: ::c_int = 2; ++pub const F_WRLCK: ::c_int = 1; ++pub const IPV6_MULTICAST_ALL: ::c_int = 29; ++pub const IPV6_ROUTER_ALERT_ISOLATE: ::c_int = 30; ++pub const MAP_HUGE_SHIFT: ::c_int = 26; ++pub const MAP_HUGE_MASK: ::c_int = 0x3f; ++pub const MAP_HUGE_64KB: ::c_int = 16 << MAP_HUGE_SHIFT; ++pub const MAP_HUGE_512KB: ::c_int = 19 << MAP_HUGE_SHIFT; ++pub const MAP_HUGE_1MB: ::c_int = 20 << MAP_HUGE_SHIFT; ++pub const MAP_HUGE_2MB: ::c_int = 21 << MAP_HUGE_SHIFT; ++pub const MAP_HUGE_8MB: ::c_int = 23 << MAP_HUGE_SHIFT; ++pub const MAP_HUGE_16MB: ::c_int = 24 << MAP_HUGE_SHIFT; ++pub const MAP_HUGE_32MB: ::c_int = 25 << MAP_HUGE_SHIFT; ++pub const MAP_HUGE_256MB: ::c_int = 28 << MAP_HUGE_SHIFT; ++pub const MAP_HUGE_512MB: ::c_int = 29 << MAP_HUGE_SHIFT; ++pub const MAP_HUGE_1GB: ::c_int = 30 << MAP_HUGE_SHIFT; ++pub const MAP_HUGE_2GB: ::c_int = 31 << MAP_HUGE_SHIFT; ++pub const MAP_HUGE_16GB: ::c_int = 34 << MAP_HUGE_SHIFT; ++pub const MINSIGSTKSZ: ::c_int = 2048; ++pub const MSG_COPY: ::c_int = 040000; ++pub const NI_MAXHOST: ::socklen_t = 1025; ++pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; ++pub const PACKET_MR_UNICAST: ::c_int = 3; ++pub const PF_NFC: ::c_int = 39; ++pub const PF_VSOCK: ::c_int = 40; ++pub const POSIX_MADV_DONTNEED: ::c_int = 4; ++pub const PTRACE_EVENT_STOP: ::c_int = 128; ++pub const PTRACE_PEEKSIGINFO: ::c_int = 0x4209; ++pub const RTLD_NOLOAD: ::c_int = 0x00004; ++pub const RUSAGE_THREAD: ::c_int = 1; ++pub const SHM_EXEC: ::c_int = 0100000; ++pub const SIGPOLL: ::c_int = SIGIO; ++pub const SOCK_DCCP: ::c_int = 6; ++pub const SOCK_PACKET: ::c_int = 10; ++pub const TCP_COOKIE_TRANSACTIONS: ::c_int = 15; ++pub const UDP_GRO: ::c_int = 104; ++pub const UDP_SEGMENT: ::c_int = 103; ++pub const YESEXPR: ::c_int = ((5) << 8) | (0); ++ + extern "C" { ++ pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::timezone) -> ::c_int; + + pub fn pthread_rwlockattr_getkind_np( +@@ -287,6 +359,21 @@ extern "C" { + iovcnt: ::c_int, + offset: ::off64_t, + ) -> ::ssize_t; ++ ++ pub fn sethostid(hostid: ::c_long) -> ::c_int; ++ pub fn fanotify_mark( ++ fd: ::c_int, ++ flags: ::c_uint, ++ mask: u64, ++ dirfd: ::c_int, ++ path: *const ::c_char, ++ ) -> ::c_int; ++ pub fn getrlimit64(resource: ::__rlimit_resource_t, rlim: *mut ::rlimit64) -> ::c_int; ++ pub fn setrlimit64(resource: ::__rlimit_resource_t, rlim: *const ::rlimit64) -> ::c_int; ++ pub fn getrlimit(resource: ::__rlimit_resource_t, rlim: *mut ::rlimit) -> ::c_int; ++ pub fn setrlimit(resource: ::__rlimit_resource_t, rlim: *const ::rlimit) -> ::c_int; ++ pub fn getpriority(which: ::__priority_which_t, who: ::id_t) -> ::c_int; ++ pub fn setpriority(which: ::__priority_which_t, who: ::id_t, prio: ::c_int) -> ::c_int; + } + + cfg_if! { +diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/l4re.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/l4re.rs +index 16ec0ef..c7cbafa 100644 +--- a/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/l4re.rs ++++ b/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/l4re.rs +@@ -46,3 +46,8 @@ pub struct pthread_attr_t { + // L4Re requires a min stack size of 64k; that isn't defined in uClibc, but + // somewhere in the core libraries. uClibc wants 16k, but that's not enough. + pub const PTHREAD_STACK_MIN: usize = 65536; ++ ++// Misc other constants required for building. ++pub const SIGIO: ::c_int = 29; ++pub const B19200: ::speed_t = 0o000016; ++pub const B38400: ::speed_t = 0o000017; +diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/mod.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/mod.rs +index 4f7974c..390119e 100644 +--- a/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/mod.rs ++++ b/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/mod.rs +@@ -11,7 +11,6 @@ pub type fsword_t = ::c_long; + pub type ino_t = ::c_ulong; + pub type nlink_t = ::c_uint; + pub type off_t = ::c_long; +-pub type rlim_t = c_ulong; + // [uClibc docs] Note stat64 has the same shape as stat for x86-64. + pub type stat64 = stat; + pub type suseconds_t = ::c_long; +@@ -21,6 +20,7 @@ pub type wchar_t = ::c_int; + pub type fsblkcnt64_t = u64; + pub type fsfilcnt64_t = u64; + pub type __u64 = ::c_ulong; ++pub type __s64 = ::c_long; + + s! { + pub struct ipc_perm { +@@ -292,8 +292,13 @@ s_no_extra_traits! { + } + + // constants ++pub const ENAMETOOLONG: ::c_int = 36; // File name too long ++pub const ENOTEMPTY: ::c_int = 39; // Directory not empty ++pub const ELOOP: ::c_int = 40; // Too many symbolic links encountered + pub const EADDRINUSE: ::c_int = 98; // Address already in use + pub const EADDRNOTAVAIL: ::c_int = 99; // Cannot assign requested address ++pub const ENETDOWN: ::c_int = 100; // Network is down ++pub const ENETUNREACH: ::c_int = 101; // Network is unreachable + pub const ECONNABORTED: ::c_int = 103; // Software caused connection abort + pub const ECONNREFUSED: ::c_int = 111; // Connection refused + pub const ECONNRESET: ::c_int = 104; // Connection reset by peer +@@ -301,6 +306,9 @@ pub const EDEADLK: ::c_int = 35; // Resource deadlock would occur + pub const ENOSYS: ::c_int = 38; // Function not implemented + pub const ENOTCONN: ::c_int = 107; // Transport endpoint is not connected + pub const ETIMEDOUT: ::c_int = 110; // connection timed out ++pub const ESTALE: ::c_int = 116; // Stale file handle ++pub const EHOSTUNREACH: ::c_int = 113; // No route to host ++pub const EDQUOT: ::c_int = 122; // Quota exceeded + pub const EOPNOTSUPP: ::c_int = 0x5f; + pub const ENODATA: ::c_int = 0x3d; + pub const O_APPEND: ::c_int = 02000; +@@ -309,6 +317,7 @@ pub const O_CLOEXEC: ::c_int = 0x80000; + pub const O_CREAT: ::c_int = 0100; + pub const O_DIRECTORY: ::c_int = 0200000; + pub const O_EXCL: ::c_int = 0200; ++pub const O_NOFOLLOW: ::c_int = 0x20000; + pub const O_NONBLOCK: ::c_int = 04000; + pub const O_TRUNC: ::c_int = 01000; + pub const NCCS: usize = 32; +@@ -317,11 +326,13 @@ pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; + pub const SOCK_DGRAM: ::c_int = 2; // connectionless, unreliable datagrams + pub const SOCK_STREAM: ::c_int = 1; // …/common/bits/socket_type.h +-pub const RLIM_INFINITY: u64 = 0xffffffffffffffff; + pub const __SIZEOF_PTHREAD_COND_T: usize = 48; + pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; + pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; ++pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; ++pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; ++pub const PIDFD_NONBLOCK: ::c_int = 04000; + + cfg_if! { + if #[cfg(target_os = "l4re")] { +diff --git a/vendor/libc/src/unix/linux_like/mod.rs b/vendor/libc/src/unix/linux_like/mod.rs +index 9654503..584e308 100644 +--- a/vendor/libc/src/unix/linux_like/mod.rs ++++ b/vendor/libc/src/unix/linux_like/mod.rs +@@ -2,6 +2,7 @@ pub type sa_family_t = u16; + pub type speed_t = ::c_uint; + pub type tcflag_t = ::c_uint; + pub type clockid_t = ::c_int; ++pub type timer_t = *mut ::c_void; + pub type key_t = ::c_int; + pub type id_t = ::c_uint; + +@@ -24,6 +25,12 @@ s! { + pub imr_interface: in_addr, + } + ++ pub struct ip_mreqn { ++ pub imr_multiaddr: in_addr, ++ pub imr_address: in_addr, ++ pub imr_ifindex: ::c_int, ++ } ++ + pub struct ip_mreq_source { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, +@@ -101,13 +108,13 @@ s! { + + pub struct sched_param { + pub sched_priority: ::c_int, +- #[cfg(any(target_env = "musl", target_os = "emscripten"))] ++ #[cfg(any(target_env = "musl", target_os = "emscripten", target_env = "ohos"))] + pub sched_ss_low_priority: ::c_int, +- #[cfg(any(target_env = "musl", target_os = "emscripten"))] ++ #[cfg(any(target_env = "musl", target_os = "emscripten", target_env = "ohos"))] + pub sched_ss_repl_period: ::timespec, +- #[cfg(any(target_env = "musl", target_os = "emscripten"))] ++ #[cfg(any(target_env = "musl", target_os = "emscripten", target_env = "ohos"))] + pub sched_ss_init_budget: ::timespec, +- #[cfg(any(target_env = "musl", target_os = "emscripten"))] ++ #[cfg(any(target_env = "musl", target_os = "emscripten", target_env = "ohos"))] + pub sched_ss_max_repl: ::c_int, + } + +@@ -224,11 +231,11 @@ s_no_extra_traits! { + + pub struct sockaddr_storage { + pub ss_family: sa_family_t, +- __ss_align: ::size_t, + #[cfg(target_pointer_width = "32")] +- __ss_pad2: [u8; 128 - 2 * 4], ++ __ss_pad2: [u8; 128 - 2 - 4], + #[cfg(target_pointer_width = "64")] +- __ss_pad2: [u8; 128 - 2 * 8], ++ __ss_pad2: [u8; 128 - 2 - 8], ++ __ss_align: ::size_t, + } + + pub struct utsname { +@@ -550,7 +557,29 @@ pub const XATTR_CREATE: ::c_int = 0x1; + pub const XATTR_REPLACE: ::c_int = 0x2; + + cfg_if! { +- if #[cfg(not(target_env = "uclibc"))] { ++ if #[cfg(target_os = "android")] { ++ pub const RLIM64_INFINITY: ::c_ulonglong = !0; ++ } else { ++ pub const RLIM64_INFINITY: ::rlim64_t = !0; ++ } ++} ++ ++cfg_if! { ++ if #[cfg(target_env = "ohos")] { ++ pub const LC_CTYPE: ::c_int = 0; ++ pub const LC_NUMERIC: ::c_int = 1; ++ pub const LC_TIME: ::c_int = 2; ++ pub const LC_COLLATE: ::c_int = 3; ++ pub const LC_MONETARY: ::c_int = 4; ++ pub const LC_MESSAGES: ::c_int = 5; ++ pub const LC_PAPER: ::c_int = 6; ++ pub const LC_NAME: ::c_int = 7; ++ pub const LC_ADDRESS: ::c_int = 8; ++ pub const LC_TELEPHONE: ::c_int = 9; ++ pub const LC_MEASUREMENT: ::c_int = 10; ++ pub const LC_IDENTIFICATION: ::c_int = 11; ++ pub const LC_ALL: ::c_int = 12; ++ } else if #[cfg(not(target_env = "uclibc"))] { + pub const LC_CTYPE: ::c_int = 0; + pub const LC_NUMERIC: ::c_int = 1; + pub const LC_TIME: ::c_int = 2; +@@ -752,8 +781,6 @@ pub const PF_IEEE802154: ::c_int = AF_IEEE802154; + pub const PF_CAIF: ::c_int = AF_CAIF; + pub const PF_ALG: ::c_int = AF_ALG; + +-pub const SOMAXCONN: ::c_int = 128; +- + pub const MSG_OOB: ::c_int = 1; + pub const MSG_PEEK: ::c_int = 2; + pub const MSG_DONTROUTE: ::c_int = 4; +@@ -876,6 +903,8 @@ pub const IPPROTO_MH: ::c_int = 135; + pub const IPPROTO_UDPLITE: ::c_int = 136; + /// raw IP packet + pub const IPPROTO_RAW: ::c_int = 255; ++pub const IPPROTO_BEETPH: ::c_int = 94; ++pub const IPPROTO_MPLS: ::c_int = 137; + + pub const MCAST_EXCLUDE: ::c_int = 0; + pub const MCAST_INCLUDE: ::c_int = 1; +@@ -912,6 +941,7 @@ pub const IPV6_JOIN_ANYCAST: ::c_int = 27; + pub const IPV6_LEAVE_ANYCAST: ::c_int = 28; + pub const IPV6_IPSEC_POLICY: ::c_int = 34; + pub const IPV6_XFRM_POLICY: ::c_int = 35; ++pub const IPV6_HDRINCL: ::c_int = 36; + pub const IPV6_RECVPKTINFO: ::c_int = 49; + pub const IPV6_PKTINFO: ::c_int = 50; + pub const IPV6_RECVHOPLIMIT: ::c_int = 51; +@@ -947,6 +977,8 @@ pub const IPV6_PMTUDISC_DONT: ::c_int = 0; + pub const IPV6_PMTUDISC_WANT: ::c_int = 1; + pub const IPV6_PMTUDISC_DO: ::c_int = 2; + pub const IPV6_PMTUDISC_PROBE: ::c_int = 3; ++pub const IPV6_PMTUDISC_INTERFACE: ::c_int = 4; ++pub const IPV6_PMTUDISC_OMIT: ::c_int = 5; + + pub const TCP_NODELAY: ::c_int = 1; + pub const TCP_MAXSEG: ::c_int = 2; +@@ -963,7 +995,11 @@ pub const TCP_QUICKACK: ::c_int = 12; + pub const TCP_CONGESTION: ::c_int = 13; + pub const TCP_MD5SIG: ::c_int = 14; + cfg_if! { +- if #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "musl")))] { ++ if #[cfg(all(target_os = "linux", any( ++ target_env = "gnu", ++ target_env = "musl", ++ target_env = "ohos" ++ )))] { + // WARN: deprecated + pub const TCP_COOKIE_TRANSACTIONS: ::c_int = 15; + } +@@ -996,6 +1032,7 @@ cfg_if! { + pub const TCP_CM_INQ: ::c_int = TCP_INQ; + // NOTE: Some CI images doesn't have this option yet. + // pub const TCP_TX_DELAY: ::c_int = 37; ++ pub const TCP_MD5SIG_MAXKEYLEN: usize = 80; + } + } + +@@ -1022,21 +1059,27 @@ pub const FD_SETSIZE: usize = 1024; + pub const EPOLLIN: ::c_int = 0x1; + pub const EPOLLPRI: ::c_int = 0x2; + pub const EPOLLOUT: ::c_int = 0x4; ++pub const EPOLLERR: ::c_int = 0x8; ++pub const EPOLLHUP: ::c_int = 0x10; + pub const EPOLLRDNORM: ::c_int = 0x40; + pub const EPOLLRDBAND: ::c_int = 0x80; + pub const EPOLLWRNORM: ::c_int = 0x100; + pub const EPOLLWRBAND: ::c_int = 0x200; + pub const EPOLLMSG: ::c_int = 0x400; +-pub const EPOLLERR: ::c_int = 0x8; +-pub const EPOLLHUP: ::c_int = 0x10; ++pub const EPOLLRDHUP: ::c_int = 0x2000; ++pub const EPOLLEXCLUSIVE: ::c_int = 0x10000000; ++pub const EPOLLWAKEUP: ::c_int = 0x20000000; ++pub const EPOLLONESHOT: ::c_int = 0x40000000; + pub const EPOLLET: ::c_int = 0x80000000; + + pub const EPOLL_CTL_ADD: ::c_int = 1; + pub const EPOLL_CTL_MOD: ::c_int = 3; + pub const EPOLL_CTL_DEL: ::c_int = 2; + ++pub const MNT_FORCE: ::c_int = 0x1; + pub const MNT_DETACH: ::c_int = 0x2; + pub const MNT_EXPIRE: ::c_int = 0x4; ++pub const UMOUNT_NOFOLLOW: ::c_int = 0x8; + + pub const Q_GETFMT: ::c_int = 0x800004; + pub const Q_GETINFO: ::c_int = 0x800005; +@@ -1052,8 +1095,6 @@ pub const QIF_USAGE: u32 = 10; + pub const QIF_TIMES: u32 = 48; + pub const QIF_ALL: u32 = 63; + +-pub const MNT_FORCE: ::c_int = 0x1; +- + pub const Q_SYNC: ::c_int = 0x800001; + pub const Q_QUOTAON: ::c_int = 0x800002; + pub const Q_QUOTAOFF: ::c_int = 0x800003; +@@ -1116,6 +1157,7 @@ pub const CLONE_CHILD_CLEARTID: ::c_int = 0x200000; + pub const CLONE_DETACHED: ::c_int = 0x400000; + pub const CLONE_UNTRACED: ::c_int = 0x800000; + pub const CLONE_CHILD_SETTID: ::c_int = 0x01000000; ++pub const CLONE_NEWCGROUP: ::c_int = 0x02000000; + pub const CLONE_NEWUTS: ::c_int = 0x04000000; + pub const CLONE_NEWIPC: ::c_int = 0x08000000; + pub const CLONE_NEWUSER: ::c_int = 0x10000000; +@@ -1131,11 +1173,15 @@ pub const WCONTINUED: ::c_int = 0x00000008; + pub const WNOWAIT: ::c_int = 0x01000000; + + // Options for personality(2). ++pub const ADDR_NO_RANDOMIZE: ::c_int = 0x0040000; + pub const MMAP_PAGE_ZERO: ::c_int = 0x0100000; ++pub const ADDR_COMPAT_LAYOUT: ::c_int = 0x0200000; ++pub const READ_IMPLIES_EXEC: ::c_int = 0x0400000; + pub const ADDR_LIMIT_32BIT: ::c_int = 0x0800000; + pub const SHORT_INODE: ::c_int = 0x1000000; + pub const WHOLE_SECONDS: ::c_int = 0x2000000; + pub const STICKY_TIMEOUTS: ::c_int = 0x4000000; ++pub const ADDR_LIMIT_3GB: ::c_int = 0x8000000; + + // Options set using PTRACE_SETOPTIONS. + pub const PTRACE_O_TRACESYSGOOD: ::c_int = 0x00000001; +@@ -1146,6 +1192,9 @@ pub const PTRACE_O_TRACEEXEC: ::c_int = 0x00000010; + pub const PTRACE_O_TRACEVFORKDONE: ::c_int = 0x00000020; + pub const PTRACE_O_TRACEEXIT: ::c_int = 0x00000040; + pub const PTRACE_O_TRACESECCOMP: ::c_int = 0x00000080; ++pub const PTRACE_O_SUSPEND_SECCOMP: ::c_int = 0x00200000; ++pub const PTRACE_O_EXITKILL: ::c_int = 0x00100000; ++pub const PTRACE_O_MASK: ::c_int = 0x003000ff; + + // Wait extended result codes for the above trace options. + pub const PTRACE_EVENT_FORK: ::c_int = 1; +@@ -1179,6 +1228,7 @@ pub const AT_REMOVEDIR: ::c_int = 0x200; + pub const AT_SYMLINK_FOLLOW: ::c_int = 0x400; + pub const AT_NO_AUTOMOUNT: ::c_int = 0x800; + pub const AT_EMPTY_PATH: ::c_int = 0x1000; ++pub const AT_RECURSIVE: ::c_int = 0x8000; + + pub const LOG_CRON: ::c_int = 9 << 3; + pub const LOG_AUTHPRIV: ::c_int = 10 << 3; +@@ -1189,6 +1239,15 @@ pub const PIPE_BUF: usize = 4096; + + pub const SI_LOAD_SHIFT: ::c_uint = 16; + ++// si_code values for SIGBUS signal ++pub const BUS_ADRALN: ::c_int = 1; ++pub const BUS_ADRERR: ::c_int = 2; ++pub const BUS_OBJERR: ::c_int = 3; ++// Linux-specific si_code values for SIGBUS signal ++pub const BUS_MCEERR_AR: ::c_int = 4; ++pub const BUS_MCEERR_AO: ::c_int = 5; ++ ++// si_code values for SIGCHLD signal + pub const CLD_EXITED: ::c_int = 1; + pub const CLD_KILLED: ::c_int = 2; + pub const CLD_DUMPED: ::c_int = 3; +@@ -1220,6 +1279,10 @@ pub const POLLHUP: ::c_short = 0x10; + pub const POLLNVAL: ::c_short = 0x20; + pub const POLLRDNORM: ::c_short = 0x040; + pub const POLLRDBAND: ::c_short = 0x080; ++#[cfg(not(any(target_arch = "sparc", target_arch = "sparc64")))] ++pub const POLLRDHUP: ::c_short = 0x2000; ++#[cfg(any(target_arch = "sparc", target_arch = "sparc64"))] ++pub const POLLRDHUP: ::c_short = 0x800; + + pub const IPTOS_LOWDELAY: u8 = 0x10; + pub const IPTOS_THROUGHPUT: u8 = 0x08; +@@ -1344,20 +1407,116 @@ pub const ARPHRD_VOID: u16 = 0xFFFF; + pub const ARPHRD_NONE: u16 = 0xFFFE; + + cfg_if! { +- if #[cfg(not(target_env = "uclibc"))] { +- pub const IPPROTO_BEETPH: ::c_int = 94; +- pub const IPPROTO_MPLS: ::c_int = 137; +- pub const IPV6_HDRINCL: ::c_int = 36; +- pub const IPV6_PMTUDISC_INTERFACE: ::c_int = 4; +- pub const IPV6_PMTUDISC_OMIT: ::c_int = 5; +- pub const CLONE_NEWCGROUP: ::c_int = 0x02000000; +- pub const ADDR_NO_RANDOMIZE: ::c_int = 0x0040000; +- pub const ADDR_COMPAT_LAYOUT: ::c_int = 0x0200000; +- pub const READ_IMPLIES_EXEC: ::c_int = 0x0400000; +- pub const ADDR_LIMIT_3GB: ::c_int = 0x8000000; +- pub const PTRACE_O_EXITKILL: ::c_int = 0x00100000; +- pub const PTRACE_O_SUSPEND_SECCOMP: ::c_int = 0x00200000; +- pub const PTRACE_O_MASK: ::c_int = 0x003000ff; ++ if #[cfg(target_os = "emscripten")] { ++ // Emscripten does not define any `*_SUPER_MAGIC` constants. ++ } else if #[cfg(not(target_arch = "s390x"))] { ++ pub const ADFS_SUPER_MAGIC: ::c_long = 0x0000adf5; ++ pub const AFFS_SUPER_MAGIC: ::c_long = 0x0000adff; ++ pub const AFS_SUPER_MAGIC: ::c_long = 0x5346414f; ++ pub const AUTOFS_SUPER_MAGIC: ::c_long = 0x0187; ++ pub const BPF_FS_MAGIC: ::c_long = 0xcafe4a11; ++ pub const BTRFS_SUPER_MAGIC: ::c_long = 0x9123683e; ++ pub const CGROUP2_SUPER_MAGIC: ::c_long = 0x63677270; ++ pub const CGROUP_SUPER_MAGIC: ::c_long = 0x27e0eb; ++ pub const CODA_SUPER_MAGIC: ::c_long = 0x73757245; ++ pub const CRAMFS_MAGIC: ::c_long = 0x28cd3d45; ++ pub const DEBUGFS_MAGIC: ::c_long = 0x64626720; ++ pub const DEVPTS_SUPER_MAGIC: ::c_long = 0x1cd1; ++ pub const ECRYPTFS_SUPER_MAGIC: ::c_long = 0xf15f; ++ pub const EFS_SUPER_MAGIC: ::c_long = 0x00414a53; ++ pub const EXT2_SUPER_MAGIC: ::c_long = 0x0000ef53; ++ pub const EXT3_SUPER_MAGIC: ::c_long = 0x0000ef53; ++ pub const EXT4_SUPER_MAGIC: ::c_long = 0x0000ef53; ++ pub const F2FS_SUPER_MAGIC: ::c_long = 0xf2f52010; ++ pub const FUSE_SUPER_MAGIC: ::c_long = 0x65735546; ++ pub const FUTEXFS_SUPER_MAGIC: ::c_long = 0xbad1dea; ++ pub const HOSTFS_SUPER_MAGIC: ::c_long = 0x00c0ffee; ++ pub const HPFS_SUPER_MAGIC: ::c_long = 0xf995e849; ++ pub const HUGETLBFS_MAGIC: ::c_long = 0x958458f6; ++ pub const ISOFS_SUPER_MAGIC: ::c_long = 0x00009660; ++ pub const JFFS2_SUPER_MAGIC: ::c_long = 0x000072b6; ++ pub const MINIX2_SUPER_MAGIC2: ::c_long = 0x00002478; ++ pub const MINIX2_SUPER_MAGIC: ::c_long = 0x00002468; ++ pub const MINIX3_SUPER_MAGIC: ::c_long = 0x4d5a; ++ pub const MINIX_SUPER_MAGIC2: ::c_long = 0x0000138f; ++ pub const MINIX_SUPER_MAGIC: ::c_long = 0x0000137f; ++ pub const MSDOS_SUPER_MAGIC: ::c_long = 0x00004d44; ++ pub const NCP_SUPER_MAGIC: ::c_long = 0x0000564c; ++ pub const NFS_SUPER_MAGIC: ::c_long = 0x00006969; ++ pub const NILFS_SUPER_MAGIC: ::c_long = 0x3434; ++ pub const OCFS2_SUPER_MAGIC: ::c_long = 0x7461636f; ++ pub const OPENPROM_SUPER_MAGIC: ::c_long = 0x00009fa1; ++ pub const OVERLAYFS_SUPER_MAGIC: ::c_long = 0x794c7630; ++ pub const PROC_SUPER_MAGIC: ::c_long = 0x00009fa0; ++ pub const QNX4_SUPER_MAGIC: ::c_long = 0x0000002f; ++ pub const QNX6_SUPER_MAGIC: ::c_long = 0x68191122; ++ pub const RDTGROUP_SUPER_MAGIC: ::c_long = 0x7655821; ++ pub const REISERFS_SUPER_MAGIC: ::c_long = 0x52654973; ++ pub const SECURITYFS_MAGIC: ::c_long = 0x73636673; ++ pub const SELINUX_MAGIC: ::c_long = 0xf97cff8c; ++ pub const SMACK_MAGIC: ::c_long = 0x43415d53; ++ pub const SMB_SUPER_MAGIC: ::c_long = 0x0000517b; ++ pub const SYSFS_MAGIC: ::c_long = 0x62656572; ++ pub const TMPFS_MAGIC: ::c_long = 0x01021994; ++ pub const TRACEFS_MAGIC: ::c_long = 0x74726163; ++ pub const UDF_SUPER_MAGIC: ::c_long = 0x15013346; ++ pub const USBDEVICE_SUPER_MAGIC: ::c_long = 0x00009fa2; ++ pub const XENFS_SUPER_MAGIC: ::c_long = 0xabba1974; ++ pub const NSFS_MAGIC: ::c_long = 0x6e736673; ++ } else if #[cfg(target_arch = "s390x")] { ++ pub const ADFS_SUPER_MAGIC: ::c_uint = 0x0000adf5; ++ pub const AFFS_SUPER_MAGIC: ::c_uint = 0x0000adff; ++ pub const AFS_SUPER_MAGIC: ::c_uint = 0x5346414f; ++ pub const AUTOFS_SUPER_MAGIC: ::c_uint = 0x0187; ++ pub const BPF_FS_MAGIC: ::c_uint = 0xcafe4a11; ++ pub const BTRFS_SUPER_MAGIC: ::c_uint = 0x9123683e; ++ pub const CGROUP2_SUPER_MAGIC: ::c_uint = 0x63677270; ++ pub const CGROUP_SUPER_MAGIC: ::c_uint = 0x27e0eb; ++ pub const CODA_SUPER_MAGIC: ::c_uint = 0x73757245; ++ pub const CRAMFS_MAGIC: ::c_uint = 0x28cd3d45; ++ pub const DEBUGFS_MAGIC: ::c_uint = 0x64626720; ++ pub const DEVPTS_SUPER_MAGIC: ::c_uint = 0x1cd1; ++ pub const ECRYPTFS_SUPER_MAGIC: ::c_uint = 0xf15f; ++ pub const EFS_SUPER_MAGIC: ::c_uint = 0x00414a53; ++ pub const EXT2_SUPER_MAGIC: ::c_uint = 0x0000ef53; ++ pub const EXT3_SUPER_MAGIC: ::c_uint = 0x0000ef53; ++ pub const EXT4_SUPER_MAGIC: ::c_uint = 0x0000ef53; ++ pub const F2FS_SUPER_MAGIC: ::c_uint = 0xf2f52010; ++ pub const FUSE_SUPER_MAGIC: ::c_uint = 0x65735546; ++ pub const FUTEXFS_SUPER_MAGIC: ::c_uint = 0xbad1dea; ++ pub const HOSTFS_SUPER_MAGIC: ::c_uint = 0x00c0ffee; ++ pub const HPFS_SUPER_MAGIC: ::c_uint = 0xf995e849; ++ pub const HUGETLBFS_MAGIC: ::c_uint = 0x958458f6; ++ pub const ISOFS_SUPER_MAGIC: ::c_uint = 0x00009660; ++ pub const JFFS2_SUPER_MAGIC: ::c_uint = 0x000072b6; ++ pub const MINIX2_SUPER_MAGIC2: ::c_uint = 0x00002478; ++ pub const MINIX2_SUPER_MAGIC: ::c_uint = 0x00002468; ++ pub const MINIX3_SUPER_MAGIC: ::c_uint = 0x4d5a; ++ pub const MINIX_SUPER_MAGIC2: ::c_uint = 0x0000138f; ++ pub const MINIX_SUPER_MAGIC: ::c_uint = 0x0000137f; ++ pub const MSDOS_SUPER_MAGIC: ::c_uint = 0x00004d44; ++ pub const NCP_SUPER_MAGIC: ::c_uint = 0x0000564c; ++ pub const NFS_SUPER_MAGIC: ::c_uint = 0x00006969; ++ pub const NILFS_SUPER_MAGIC: ::c_uint = 0x3434; ++ pub const OCFS2_SUPER_MAGIC: ::c_uint = 0x7461636f; ++ pub const OPENPROM_SUPER_MAGIC: ::c_uint = 0x00009fa1; ++ pub const OVERLAYFS_SUPER_MAGIC: ::c_uint = 0x794c7630; ++ pub const PROC_SUPER_MAGIC: ::c_uint = 0x00009fa0; ++ pub const QNX4_SUPER_MAGIC: ::c_uint = 0x0000002f; ++ pub const QNX6_SUPER_MAGIC: ::c_uint = 0x68191122; ++ pub const RDTGROUP_SUPER_MAGIC: ::c_uint = 0x7655821; ++ pub const REISERFS_SUPER_MAGIC: ::c_uint = 0x52654973; ++ pub const SECURITYFS_MAGIC: ::c_uint = 0x73636673; ++ pub const SELINUX_MAGIC: ::c_uint = 0xf97cff8c; ++ pub const SMACK_MAGIC: ::c_uint = 0x43415d53; ++ pub const SMB_SUPER_MAGIC: ::c_uint = 0x0000517b; ++ pub const SYSFS_MAGIC: ::c_uint = 0x62656572; ++ pub const TMPFS_MAGIC: ::c_uint = 0x01021994; ++ pub const TRACEFS_MAGIC: ::c_uint = 0x74726163; ++ pub const UDF_SUPER_MAGIC: ::c_uint = 0x15013346; ++ pub const USBDEVICE_SUPER_MAGIC: ::c_uint = 0x00009fa2; ++ pub const XENFS_SUPER_MAGIC: ::c_uint = 0xabba1974; ++ pub const NSFS_MAGIC: ::c_uint = 0x6e736673; + } + } + +@@ -1396,7 +1555,7 @@ f! { + return + } + +- pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool { ++ pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0 +@@ -1417,6 +1576,14 @@ f! { + } + + safe_f! { ++ pub fn SIGRTMAX() -> ::c_int { ++ unsafe { __libc_current_sigrtmax() } ++ } ++ ++ pub fn SIGRTMIN() -> ::c_int { ++ unsafe { __libc_current_sigrtmin() } ++ } ++ + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + (status & 0xff) == 0x7f + } +@@ -1476,9 +1643,22 @@ safe_f! { + pub {const} fn IPTOS_ECN(x: u8) -> u8 { + x & ::IPTOS_ECN_MASK + } ++ ++ #[allow(ellipsis_inclusive_range_patterns)] ++ pub {const} fn KERNEL_VERSION(a: u32, b: u32, c: u32) -> u32 { ++ ((a << 16) + (b << 8)) + match c { ++ 0 ... 255 => c, ++ _ => 255, ++ } ++ } + } + + extern "C" { ++ #[doc(hidden)] ++ pub fn __libc_current_sigrtmax() -> ::c_int; ++ #[doc(hidden)] ++ pub fn __libc_current_sigrtmin() -> ::c_int; ++ + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + pub fn fdatasync(fd: ::c_int) -> ::c_int; +@@ -1591,8 +1771,6 @@ extern "C" { + pub fn clearenv() -> ::c_int; + pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t, options: ::c_int) + -> ::c_int; +- pub fn setreuid(ruid: ::uid_t, euid: ::uid_t) -> ::c_int; +- pub fn setregid(rgid: ::gid_t, egid: ::gid_t) -> ::c_int; + pub fn getresuid(ruid: *mut ::uid_t, euid: *mut ::uid_t, suid: *mut ::uid_t) -> ::c_int; + pub fn getresgid(rgid: *mut ::gid_t, egid: *mut ::gid_t, sgid: *mut ::gid_t) -> ::c_int; + pub fn acct(filename: *const ::c_char) -> ::c_int; +@@ -1632,6 +1810,8 @@ extern "C" { + pub fn sendmsg(fd: ::c_int, msg: *const ::msghdr, flags: ::c_int) -> ::ssize_t; + pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; + pub fn uname(buf: *mut ::utsname) -> ::c_int; ++ ++ pub fn strchrnul(s: *const ::c_char, c: ::c_int) -> *mut ::c_char; + } + + cfg_if! { +diff --git a/vendor/libc/src/unix/mod.rs b/vendor/libc/src/unix/mod.rs +index be7b6e7..75d511e 100644 +--- a/vendor/libc/src/unix/mod.rs ++++ b/vendor/libc/src/unix/mod.rs +@@ -23,13 +23,24 @@ pub type uintptr_t = usize; + pub type ssize_t = isize; + + pub type pid_t = i32; +-pub type uid_t = u32; +-pub type gid_t = u32; + pub type in_addr_t = u32; + pub type in_port_t = u16; + pub type sighandler_t = ::size_t; + pub type cc_t = ::c_uchar; + ++cfg_if! { ++ if #[cfg(any(target_os = "espidf", target_os = "horizon"))] { ++ pub type uid_t = ::c_ushort; ++ pub type gid_t = ::c_ushort; ++ } else if #[cfg(target_os = "nto")] { ++ pub type uid_t = i32; ++ pub type gid_t = i32; ++ } else { ++ pub type uid_t = u32; ++ pub type gid_t = u32; ++ } ++} ++ + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub enum DIR {} + impl ::Copy for DIR {} +@@ -119,7 +130,7 @@ s! { + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad14: u32, + +- #[cfg(any(target_env = "musl", target_os = "emscripten"))] ++ #[cfg(any(target_env = "musl", target_env = "ohos", target_os = "emscripten"))] + __reserved: [c_long; 16], + } + +@@ -201,25 +212,31 @@ pub const INT_MAX: c_int = 2147483647; + pub const SIG_DFL: sighandler_t = 0 as sighandler_t; + pub const SIG_IGN: sighandler_t = 1 as sighandler_t; + pub const SIG_ERR: sighandler_t = !0 as sighandler_t; +- +-pub const DT_UNKNOWN: u8 = 0; +-pub const DT_FIFO: u8 = 1; +-pub const DT_CHR: u8 = 2; +-pub const DT_DIR: u8 = 4; +-pub const DT_BLK: u8 = 6; +-pub const DT_REG: u8 = 8; +-pub const DT_LNK: u8 = 10; +-pub const DT_SOCK: u8 = 12; +- ++cfg_if! { ++ if #[cfg(not(target_os = "nto"))] { ++ pub const DT_UNKNOWN: u8 = 0; ++ pub const DT_FIFO: u8 = 1; ++ pub const DT_CHR: u8 = 2; ++ pub const DT_DIR: u8 = 4; ++ pub const DT_BLK: u8 = 6; ++ pub const DT_REG: u8 = 8; ++ pub const DT_LNK: u8 = 10; ++ pub const DT_SOCK: u8 = 12; ++ } ++} + cfg_if! { + if #[cfg(not(target_os = "redox"))] { + pub const FD_CLOEXEC: ::c_int = 0x1; + } + } + +-pub const USRQUOTA: ::c_int = 0; +-pub const GRPQUOTA: ::c_int = 1; +- ++cfg_if! { ++ if #[cfg(not(target_os = "nto"))] ++ { ++ pub const USRQUOTA: ::c_int = 0; ++ pub const GRPQUOTA: ::c_int = 1; ++ } ++} + pub const SIGIOT: ::c_int = 6; + + pub const S_ISUID: ::mode_t = 0x800; +@@ -273,9 +290,13 @@ cfg_if! { + pub const LOG_PRIMASK: ::c_int = 7; + pub const LOG_FACMASK: ::c_int = 0x3f8; + +-pub const PRIO_MIN: ::c_int = -20; +-pub const PRIO_MAX: ::c_int = 20; +- ++cfg_if! { ++ if #[cfg(not(target_os = "nto"))] ++ { ++ pub const PRIO_MIN: ::c_int = -20; ++ pub const PRIO_MAX: ::c_int = 20; ++ } ++} + pub const IPPROTO_ICMP: ::c_int = 1; + pub const IPPROTO_ICMPV6: ::c_int = 58; + pub const IPPROTO_TCP: ::c_int = 6; +@@ -297,29 +318,31 @@ pub const ATF_PUBL: ::c_int = 0x08; + pub const ATF_USETRAILERS: ::c_int = 0x10; + + cfg_if! { +- if #[cfg(target_os = "l4re")] { +- // required libraries for L4Re are linked externally, ATM ++ if #[cfg(any(target_os = "l4re", target_os = "espidf"))] { ++ // required libraries for L4Re and the ESP-IDF framework are linked externally, ATM + } else if #[cfg(feature = "std")] { + // cargo build, don't pull in anything extra as the libstd dep + // already pulls in all libs. + } else if #[cfg(all(target_os = "linux", + any(target_env = "gnu", target_env = "uclibc"), + feature = "rustc-dep-of-std"))] { +- #[link(name = "util", kind = "static-nobundle", ++ #[link(name = "util", kind = "static", modifiers = "-bundle", ++ cfg(target_feature = "crt-static"))] ++ #[link(name = "rt", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] +- #[link(name = "rt", kind = "static-nobundle", ++ #[link(name = "pthread", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] +- #[link(name = "pthread", kind = "static-nobundle", ++ #[link(name = "m", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] +- #[link(name = "m", kind = "static-nobundle", ++ #[link(name = "dl", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] +- #[link(name = "dl", kind = "static-nobundle", ++ #[link(name = "c", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] +- #[link(name = "c", kind = "static-nobundle", ++ #[link(name = "gcc_eh", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] +- #[link(name = "gcc_eh", kind = "static-nobundle", ++ #[link(name = "gcc", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] +- #[link(name = "gcc", kind = "static-nobundle", ++ #[link(name = "c", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "util", cfg(not(target_feature = "crt-static")))] + #[link(name = "rt", cfg(not(target_feature = "crt-static")))] +@@ -328,9 +351,9 @@ cfg_if! { + #[link(name = "dl", cfg(not(target_feature = "crt-static")))] + #[link(name = "c", cfg(not(target_feature = "crt-static")))] + extern {} +- } else if #[cfg(target_env = "musl")] { ++ } else if #[cfg(any(target_env = "musl", target_env = "ohos"))] { + #[cfg_attr(feature = "rustc-dep-of-std", +- link(name = "c", kind = "static", ++ link(name = "c", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static")))] + #[cfg_attr(feature = "rustc-dep-of-std", + link(name = "c", cfg(not(target_feature = "crt-static"))))] +@@ -338,18 +361,22 @@ cfg_if! { + } else if #[cfg(target_os = "emscripten")] { + #[link(name = "c")] + extern {} +- } else if #[cfg(all(target_os = "netbsd", +- feature = "rustc-dep-of-std", +- target_vendor = "rumprun"))] { +- // Since we don't use -nodefaultlibs on Rumprun, libc is always pulled +- // in automatically by the linker. We avoid passing it explicitly, as it +- // causes some versions of binutils to crash with an assertion failure. +- #[link(name = "m")] ++ } else if #[cfg(all(target_os = "android", feature = "rustc-dep-of-std"))] { ++ #[link(name = "c", kind = "static", modifiers = "-bundle", ++ cfg(target_feature = "crt-static"))] ++ #[link(name = "m", kind = "static", modifiers = "-bundle", ++ cfg(target_feature = "crt-static"))] ++ #[link(name = "m", cfg(not(target_feature = "crt-static")))] ++ #[link(name = "c", cfg(not(target_feature = "crt-static")))] + extern {} + } else if #[cfg(any(target_os = "macos", + target_os = "ios", ++ target_os = "tvos", ++ target_os = "watchos", + target_os = "android", +- target_os = "openbsd"))] { ++ target_os = "openbsd", ++ target_os = "nto", ++ ))] { + #[link(name = "c")] + #[link(name = "m")] + extern {} +@@ -372,11 +399,17 @@ cfg_if! { + extern {} + } else if #[cfg(target_os = "redox")] { + #[cfg_attr(feature = "rustc-dep-of-std", +- link(name = "c", kind = "static-nobundle", ++ link(name = "c", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static")))] + #[cfg_attr(feature = "rustc-dep-of-std", + link(name = "c", cfg(not(target_feature = "crt-static"))))] + extern {} ++ } else if #[cfg(target_env = "aix")] { ++ #[link(name = "c")] ++ #[link(name = "m")] ++ #[link(name = "bsd")] ++ #[link(name = "pthread")] ++ extern {} + } else { + #[link(name = "c")] + #[link(name = "m")] +@@ -441,8 +474,6 @@ extern "C" { + link_name = "freopen$UNIX2003" + )] + pub fn freopen(filename: *const c_char, mode: *const c_char, file: *mut FILE) -> *mut FILE; +- pub fn fmemopen(buf: *mut c_void, size: size_t, mode: *const c_char) -> *mut FILE; +- pub fn open_memstream(ptr: *mut *mut c_char, sizeloc: *mut size_t) -> *mut FILE; + + pub fn fflush(file: *mut FILE) -> c_int; + pub fn fclose(file: *mut FILE) -> c_int; +@@ -480,14 +511,20 @@ extern "C" { + pub fn ferror(stream: *mut FILE) -> c_int; + pub fn clearerr(stream: *mut FILE); + pub fn perror(s: *const c_char); ++ pub fn atof(s: *const c_char) -> c_double; + pub fn atoi(s: *const c_char) -> c_int; ++ pub fn atol(s: *const c_char) -> c_long; ++ pub fn atoll(s: *const c_char) -> c_longlong; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "strtod$UNIX2003" + )] + pub fn strtod(s: *const c_char, endp: *mut *mut c_char) -> c_double; ++ pub fn strtof(s: *const c_char, endp: *mut *mut c_char) -> c_float; + pub fn strtol(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_long; ++ pub fn strtoll(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_longlong; + pub fn strtoul(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulong; ++ pub fn strtoull(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulonglong; + pub fn calloc(nobj: size_t, size: size_t) -> *mut c_void; + pub fn malloc(size: size_t) -> *mut c_void; + pub fn realloc(p: *mut c_void, size: size_t) -> *mut c_void; +@@ -495,7 +532,6 @@ extern "C" { + pub fn abort() -> !; + pub fn exit(status: c_int) -> !; + pub fn _exit(status: c_int) -> !; +- pub fn atexit(cb: extern "C" fn()) -> c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "system$UNIX2003" +@@ -505,6 +541,7 @@ extern "C" { + + pub fn strcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char; + pub fn strncpy(dst: *mut c_char, src: *const c_char, n: size_t) -> *mut c_char; ++ pub fn stpcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char; + pub fn strcat(s: *mut c_char, ct: *const c_char) -> *mut c_char; + pub fn strncat(s: *mut c_char, ct: *const c_char, n: size_t) -> *mut c_char; + pub fn strcmp(cs: *const c_char, ct: *const c_char) -> c_int; +@@ -528,6 +565,7 @@ extern "C" { + )] + pub fn strerror(n: c_int) -> *mut c_char; + pub fn strtok(s: *mut c_char, t: *const c_char) -> *mut c_char; ++ pub fn strtok_r(s: *mut c_char, t: *const c_char, p: *mut *mut c_char) -> *mut c_char; + pub fn strxfrm(s: *mut c_char, ct: *const c_char, n: size_t) -> size_t; + pub fn strsignal(sig: c_int) -> *mut c_char; + pub fn wcslen(buf: *const wchar_t) -> size_t; +@@ -576,6 +614,7 @@ extern "C" { + )))] + #[cfg_attr(target_os = "netbsd", link_name = "__socket30")] + #[cfg_attr(target_os = "illumos", link_name = "__xnet_socket")] ++ #[cfg_attr(target_os = "espidf", link_name = "lwip_socket")] + pub fn socket(domain: ::c_int, ty: ::c_int, protocol: ::c_int) -> ::c_int; + #[cfg(not(all( + libc_cfg_target_vendor, +@@ -587,11 +626,13 @@ extern "C" { + link_name = "connect$UNIX2003" + )] + #[cfg_attr(target_os = "illumos", link_name = "__xnet_connect")] ++ #[cfg_attr(target_os = "espidf", link_name = "lwip_connect")] + pub fn connect(socket: ::c_int, address: *const sockaddr, len: socklen_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "listen$UNIX2003" + )] ++ #[cfg_attr(target_os = "espidf", link_name = "lwip_listen")] + pub fn listen(socket: ::c_int, backlog: ::c_int) -> ::c_int; + #[cfg(not(all( + libc_cfg_target_vendor, +@@ -602,6 +643,7 @@ extern "C" { + all(target_os = "macos", target_arch = "x86"), + link_name = "accept$UNIX2003" + )] ++ #[cfg_attr(target_os = "espidf", link_name = "lwip_accept")] + pub fn accept(socket: ::c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> ::c_int; + #[cfg(not(all( + libc_cfg_target_vendor, +@@ -612,6 +654,7 @@ extern "C" { + all(target_os = "macos", target_arch = "x86"), + link_name = "getpeername$UNIX2003" + )] ++ #[cfg_attr(target_os = "espidf", link_name = "lwip_getpeername")] + pub fn getpeername( + socket: ::c_int, + address: *mut sockaddr, +@@ -626,11 +669,13 @@ extern "C" { + all(target_os = "macos", target_arch = "x86"), + link_name = "getsockname$UNIX2003" + )] ++ #[cfg_attr(target_os = "espidf", link_name = "lwip_getsockname")] + pub fn getsockname( + socket: ::c_int, + address: *mut sockaddr, + address_len: *mut socklen_t, + ) -> ::c_int; ++ #[cfg_attr(target_os = "espidf", link_name = "lwip_setsockopt")] + pub fn setsockopt( + socket: ::c_int, + level: ::c_int, +@@ -659,6 +704,7 @@ extern "C" { + link_name = "sendto$UNIX2003" + )] + #[cfg_attr(target_os = "illumos", link_name = "__xnet_sendto")] ++ #[cfg_attr(target_os = "espidf", link_name = "lwip_sendto")] + pub fn sendto( + socket: ::c_int, + buf: *const ::c_void, +@@ -667,6 +713,7 @@ extern "C" { + addr: *const sockaddr, + addrlen: socklen_t, + ) -> ::ssize_t; ++ #[cfg_attr(target_os = "espidf", link_name = "lwip_shutdown")] + pub fn shutdown(socket: ::c_int, how: ::c_int) -> ::c_int; + + #[cfg_attr( +@@ -880,6 +927,8 @@ extern "C" { + pub fn setpgid(pid: pid_t, pgid: pid_t) -> ::c_int; + pub fn setsid() -> pid_t; + pub fn setuid(uid: uid_t) -> ::c_int; ++ pub fn setreuid(ruid: uid_t, euid: uid_t) -> ::c_int; ++ pub fn setregid(rgid: gid_t, egid: gid_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "sleep$UNIX2003" +@@ -999,6 +1048,7 @@ extern "C" { + + pub fn symlink(path1: *const c_char, path2: *const c_char) -> ::c_int; + ++ pub fn truncate(path: *const c_char, length: off_t) -> ::c_int; + pub fn ftruncate(fd: ::c_int, length: off_t) -> ::c_int; + + pub fn signal(signum: ::c_int, handler: sighandler_t) -> sighandler_t; +@@ -1007,7 +1057,12 @@ extern "C" { + pub fn getrusage(resource: ::c_int, usage: *mut rusage) -> ::c_int; + + #[cfg_attr( +- any(target_os = "macos", target_os = "ios"), ++ any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "tvos", ++ target_os = "watchos" ++ ), + link_name = "realpath$DARWIN_EXTSN" + )] + pub fn realpath(pathname: *const ::c_char, resolved: *mut ::c_char) -> *mut ::c_char; +@@ -1122,6 +1177,7 @@ extern "C" { + pub fn pthread_rwlockattr_destroy(attr: *mut pthread_rwlockattr_t) -> ::c_int; + + #[cfg_attr(target_os = "illumos", link_name = "__xnet_getsockopt")] ++ #[cfg_attr(target_os = "espidf", link_name = "lwip_getsockopt")] + pub fn getsockopt( + sockfd: ::c_int, + level: ::c_int, +@@ -1130,8 +1186,6 @@ extern "C" { + optlen: *mut ::socklen_t, + ) -> ::c_int; + pub fn raise(signum: ::c_int) -> ::c_int; +- #[cfg_attr(target_os = "netbsd", link_name = "__sigaction14")] +- pub fn sigaction(signum: ::c_int, act: *const sigaction, oldact: *mut sigaction) -> ::c_int; + + #[cfg_attr(target_os = "netbsd", link_name = "__utimes50")] + pub fn utimes(filename: *const ::c_char, times: *const ::timeval) -> ::c_int; +@@ -1139,7 +1193,6 @@ extern "C" { + pub fn dlerror() -> *mut ::c_char; + pub fn dlsym(handle: *mut ::c_void, symbol: *const ::c_char) -> *mut ::c_void; + pub fn dlclose(handle: *mut ::c_void) -> ::c_int; +- pub fn dladdr(addr: *const ::c_void, info: *mut Dl_info) -> ::c_int; + + #[cfg(not(all( + libc_cfg_target_vendor, +@@ -1147,6 +1200,7 @@ extern "C" { + target_vendor = "nintendo" + )))] + #[cfg_attr(target_os = "illumos", link_name = "__xnet_getaddrinfo")] ++ #[cfg_attr(target_os = "espidf", link_name = "lwip_getaddrinfo")] + pub fn getaddrinfo( + node: *const c_char, + service: *const c_char, +@@ -1158,26 +1212,39 @@ extern "C" { + target_arch = "powerpc", + target_vendor = "nintendo" + )))] ++ #[cfg_attr(target_os = "espidf", link_name = "lwip_freeaddrinfo")] + pub fn freeaddrinfo(res: *mut addrinfo); ++ pub fn hstrerror(errcode: ::c_int) -> *const ::c_char; + pub fn gai_strerror(errcode: ::c_int) -> *const ::c_char; + #[cfg_attr( + any( +- all(target_os = "linux", not(target_env = "musl")), ++ all( ++ target_os = "linux", ++ not(any(target_env = "musl", target_env = "ohos")) ++ ), + target_os = "freebsd", + target_os = "dragonfly", + target_os = "haiku" + ), + link_name = "__res_init" + )] +- #[cfg_attr(any(target_os = "macos", target_os = "ios"), link_name = "res_9_init")] ++ #[cfg_attr( ++ any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "tvos", ++ target_os = "watchos" ++ ), ++ link_name = "res_9_init" ++ )] + pub fn res_init() -> ::c_int; + + #[cfg_attr(target_os = "netbsd", link_name = "__gmtime_r50")] +- #[cfg_attr(target_env = "musl", allow(deprecated))] ++ #[cfg_attr(any(target_env = "musl", target_env = "ohos"), allow(deprecated))] + // FIXME: for `time_t` + pub fn gmtime_r(time_p: *const time_t, result: *mut tm) -> *mut tm; + #[cfg_attr(target_os = "netbsd", link_name = "__localtime_r50")] +- #[cfg_attr(target_env = "musl", allow(deprecated))] ++ #[cfg_attr(any(target_env = "musl", target_env = "ohos"), allow(deprecated))] + // FIXME: for `time_t` + pub fn localtime_r(time_p: *const time_t, result: *mut tm) -> *mut tm; + #[cfg_attr( +@@ -1185,27 +1252,27 @@ extern "C" { + link_name = "mktime$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__mktime50")] +- #[cfg_attr(target_env = "musl", allow(deprecated))] ++ #[cfg_attr(any(target_env = "musl", target_env = "ohos"), allow(deprecated))] + // FIXME: for `time_t` + pub fn mktime(tm: *mut tm) -> time_t; + #[cfg_attr(target_os = "netbsd", link_name = "__time50")] +- #[cfg_attr(target_env = "musl", allow(deprecated))] ++ #[cfg_attr(any(target_env = "musl", target_env = "ohos"), allow(deprecated))] + // FIXME: for `time_t` + pub fn time(time: *mut time_t) -> time_t; + #[cfg_attr(target_os = "netbsd", link_name = "__gmtime50")] +- #[cfg_attr(target_env = "musl", allow(deprecated))] ++ #[cfg_attr(any(target_env = "musl", target_env = "ohos"), allow(deprecated))] + // FIXME: for `time_t` + pub fn gmtime(time_p: *const time_t) -> *mut tm; + #[cfg_attr(target_os = "netbsd", link_name = "__locatime50")] +- #[cfg_attr(target_env = "musl", allow(deprecated))] ++ #[cfg_attr(any(target_env = "musl", target_env = "ohos"), allow(deprecated))] + // FIXME: for `time_t` + pub fn localtime(time_p: *const time_t) -> *mut tm; + #[cfg_attr(target_os = "netbsd", link_name = "__difftime50")] +- #[cfg_attr(target_env = "musl", allow(deprecated))] ++ #[cfg_attr(any(target_env = "musl", target_env = "ohos"), allow(deprecated))] + // FIXME: for `time_t` + pub fn difftime(time1: time_t, time0: time_t) -> ::c_double; + #[cfg_attr(target_os = "netbsd", link_name = "__timegm50")] +- #[cfg_attr(target_env = "musl", allow(deprecated))] ++ #[cfg_attr(any(target_env = "musl", target_env = "ohos"), allow(deprecated))] + // FIXME: for `time_t` + pub fn timegm(tm: *mut ::tm) -> time_t; + +@@ -1233,11 +1300,13 @@ extern "C" { + all(target_os = "macos", target_arch = "x86"), + link_name = "send$UNIX2003" + )] ++ #[cfg_attr(target_os = "espidf", link_name = "lwip_send")] + pub fn send(socket: ::c_int, buf: *const ::c_void, len: ::size_t, flags: ::c_int) -> ::ssize_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "recv$UNIX2003" + )] ++ #[cfg_attr(target_os = "espidf", link_name = "lwip_recv")] + pub fn recv(socket: ::c_int, buf: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::ssize_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), +@@ -1261,7 +1330,7 @@ extern "C" { + #[cfg_attr(target_os = "netbsd", link_name = "__select50")] + pub fn select( + nfds: ::c_int, +- readfs: *mut fd_set, ++ readfds: *mut fd_set, + writefds: *mut fd_set, + errorfds: *mut fd_set, + timeout: *mut timeval, +@@ -1280,8 +1349,6 @@ extern "C" { + pub fn statvfs(path: *const c_char, buf: *mut statvfs) -> ::c_int; + pub fn fstatvfs(fd: ::c_int, buf: *mut statvfs) -> ::c_int; + +- pub fn readlink(path: *const c_char, buf: *mut c_char, bufsz: ::size_t) -> ::ssize_t; +- + #[cfg_attr(target_os = "netbsd", link_name = "__sigemptyset14")] + pub fn sigemptyset(set: *mut sigset_t) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__sigaddset14")] +@@ -1302,23 +1369,6 @@ extern "C" { + + pub fn mkfifo(path: *const c_char, mode: mode_t) -> ::c_int; + +- #[cfg_attr( +- all(target_os = "macos", target_arch = "x86_64"), +- link_name = "pselect$1050" +- )] +- #[cfg_attr( +- all(target_os = "macos", target_arch = "x86"), +- link_name = "pselect$UNIX2003" +- )] +- #[cfg_attr(target_os = "netbsd", link_name = "__pselect50")] +- pub fn pselect( +- nfds: ::c_int, +- readfs: *mut fd_set, +- writefds: *mut fd_set, +- errorfds: *mut fd_set, +- timeout: *const timespec, +- sigmask: *const sigset_t, +- ) -> ::c_int; + pub fn fseeko(stream: *mut ::FILE, offset: ::off_t, whence: ::c_int) -> ::c_int; + pub fn ftello(stream: *mut ::FILE) -> ::off_t; + #[cfg_attr( +@@ -1361,10 +1411,30 @@ extern "C" { + pub fn getline(lineptr: *mut *mut c_char, n: *mut size_t, stream: *mut FILE) -> ssize_t; + + pub fn lockf(fd: ::c_int, cmd: ::c_int, len: ::off_t) -> ::c_int; ++ ++} ++cfg_if! { ++ if #[cfg(not(any(target_os = "emscripten", ++ target_os = "android", ++ target_os = "haiku", ++ target_os = "nto")))] { ++ extern "C" { ++ pub fn adjtime(delta: *const timeval, olddelta: *mut timeval) -> ::c_int; ++ pub fn stpncpy(dst: *mut c_char, src: *const c_char, n: size_t) -> *mut c_char; ++ } ++ } + } + + cfg_if! { +- if #[cfg(not(target_env = "uclibc"))] { ++ if #[cfg(not(target_os = "aix"))] { ++ extern "C" { ++ pub fn dladdr(addr: *const ::c_void, info: *mut Dl_info) -> ::c_int; ++ } ++ } ++} ++ ++cfg_if! { ++ if #[cfg(not(any(target_env = "uclibc", target_os = "nto")))] { + extern "C" { + pub fn open_wmemstream( + ptr: *mut *mut wchar_t, +@@ -1378,17 +1448,12 @@ cfg_if! { + if #[cfg(not(target_os = "redox"))] { + extern { + pub fn getsid(pid: pid_t) -> pid_t; +- pub fn truncate(path: *const c_char, length: off_t) -> ::c_int; + #[cfg_attr(all(target_os = "macos", target_arch = "x86"), + link_name = "pause$UNIX2003")] + pub fn pause() -> ::c_int; + +- pub fn readlinkat(dirfd: ::c_int, +- pathname: *const ::c_char, +- buf: *mut ::c_char, +- bufsiz: ::size_t) -> ::ssize_t; + pub fn mkdirat(dirfd: ::c_int, pathname: *const ::c_char, +- mode: ::mode_t) -> ::c_int; ++ mode: ::mode_t) -> ::c_int; + pub fn openat(dirfd: ::c_int, pathname: *const ::c_char, + flags: ::c_int, ...) -> ::c_int; + +@@ -1419,7 +1484,64 @@ cfg_if! { + } + + cfg_if! { +- if #[cfg(not(any(target_os = "solaris", target_os = "illumos")))] { ++ if #[cfg(target_os = "nto")] { ++ extern { ++ pub fn readlinkat(dirfd: ::c_int, ++ pathname: *const ::c_char, ++ buf: *mut ::c_char, ++ bufsiz: ::size_t) -> ::c_int; ++ pub fn readlink(path: *const c_char, buf: *mut c_char, bufsz: ::size_t) -> ::c_int; ++ pub fn pselect( ++ nfds: ::c_int, ++ readfds: *mut fd_set, ++ writefds: *mut fd_set, ++ errorfds: *mut fd_set, ++ timeout: *mut timespec, ++ sigmask: *const sigset_t, ++ ) -> ::c_int; ++ } ++ } else { ++ extern { ++ pub fn readlinkat(dirfd: ::c_int, ++ pathname: *const ::c_char, ++ buf: *mut ::c_char, ++ bufsiz: ::size_t) -> ::ssize_t; ++ pub fn fmemopen(buf: *mut c_void, size: size_t, mode: *const c_char) -> *mut FILE; ++ pub fn open_memstream(ptr: *mut *mut c_char, sizeloc: *mut size_t) -> *mut FILE; ++ pub fn atexit(cb: extern "C" fn()) -> c_int; ++ #[cfg_attr(target_os = "netbsd", link_name = "__sigaction14")] ++ pub fn sigaction( ++ signum: ::c_int, ++ act: *const sigaction, ++ oldact: *mut sigaction ++ ) -> ::c_int; ++ pub fn readlink(path: *const c_char, buf: *mut c_char, bufsz: ::size_t) -> ::ssize_t; ++ #[cfg_attr( ++ all(target_os = "macos", target_arch = "x86_64"), ++ link_name = "pselect$1050" ++ )] ++ #[cfg_attr( ++ all(target_os = "macos", target_arch = "x86"), ++ link_name = "pselect$UNIX2003" ++ )] ++ #[cfg_attr(target_os = "netbsd", link_name = "__pselect50")] ++ pub fn pselect( ++ nfds: ::c_int, ++ readfds: *mut fd_set, ++ writefds: *mut fd_set, ++ errorfds: *mut fd_set, ++ timeout: *const timespec, ++ sigmask: *const sigset_t, ++ ) -> ::c_int; ++ } ++ } ++} ++ ++cfg_if! { ++ if #[cfg(not(any(target_os = "solaris", ++ target_os = "illumos", ++ target_os = "nto", ++ )))] { + extern { + pub fn cfmakeraw(termios: *mut ::termios); + pub fn cfsetspeed(termios: *mut ::termios, +@@ -1440,6 +1562,8 @@ cfg_if! { + pub use self::linux_like::*; + } else if #[cfg(any(target_os = "macos", + target_os = "ios", ++ target_os = "tvos", ++ target_os = "watchos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "openbsd", +@@ -1459,6 +1583,12 @@ cfg_if! { + } else if #[cfg(target_os = "redox")] { + mod redox; + pub use self::redox::*; ++ } else if #[cfg(target_os = "nto")] { ++ mod nto; ++ pub use self::nto::*; ++ } else if #[cfg(target_os = "aix")] { ++ mod aix; ++ pub use self::aix::*; + } else { + // Unknown target_os + } +diff --git a/vendor/libc/src/unix/newlib/aarch64/mod.rs b/vendor/libc/src/unix/newlib/aarch64/mod.rs +index 71aa894..d686b36 100644 +--- a/vendor/libc/src/unix/newlib/aarch64/mod.rs ++++ b/vendor/libc/src/unix/newlib/aarch64/mod.rs +@@ -50,3 +50,5 @@ pub const MSG_DONTROUTE: ::c_int = 0; + pub const MSG_WAITALL: ::c_int = 0; + pub const MSG_MORE: ::c_int = 0; + pub const MSG_NOSIGNAL: ::c_int = 0; ++ ++pub use crate::unix::newlib::generic::{sigset_t, stat}; +diff --git a/vendor/libc/src/unix/newlib/arm/mod.rs b/vendor/libc/src/unix/newlib/arm/mod.rs +index 78bea27..f644349 100644 +--- a/vendor/libc/src/unix/newlib/arm/mod.rs ++++ b/vendor/libc/src/unix/newlib/arm/mod.rs +@@ -52,3 +52,5 @@ pub const MSG_DONTROUTE: ::c_int = 0; + pub const MSG_WAITALL: ::c_int = 0; + pub const MSG_MORE: ::c_int = 0; + pub const MSG_NOSIGNAL: ::c_int = 0; ++ ++pub use crate::unix::newlib::generic::{sigset_t, stat}; +diff --git a/vendor/libc/src/unix/newlib/xtensa/mod.rs b/vendor/libc/src/unix/newlib/espidf/mod.rs +similarity index 78% +rename from vendor/libc/src/unix/newlib/xtensa/mod.rs +rename to vendor/libc/src/unix/newlib/espidf/mod.rs +index f520f7a..804cd66 100644 +--- a/vendor/libc/src/unix/newlib/xtensa/mod.rs ++++ b/vendor/libc/src/unix/newlib/espidf/mod.rs +@@ -83,11 +83,28 @@ pub const MSG_DONTROUTE: ::c_int = 0x4; + pub const MSG_WAITALL: ::c_int = 0x02; + pub const MSG_MORE: ::c_int = 0x10; + pub const MSG_NOSIGNAL: ::c_int = 0x20; ++pub const MSG_TRUNC: ::c_int = 0x04; ++pub const MSG_CTRUNC: ::c_int = 0x08; ++pub const MSG_EOR: ::c_int = 0x08; ++ ++pub const PTHREAD_STACK_MIN: ::size_t = 768; + + extern "C" { ++ pub fn pthread_create( ++ native: *mut ::pthread_t, ++ attr: *const ::pthread_attr_t, ++ f: extern "C" fn(_: *mut ::c_void) -> *mut ::c_void, ++ value: *mut ::c_void, ++ ) -> ::c_int; ++ ++ pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; ++ ++ #[link_name = "lwip_sendmsg"] + pub fn sendmsg(s: ::c_int, msg: *const ::msghdr, flags: ::c_int) -> ::ssize_t; ++ #[link_name = "lwip_recvmsg"] + pub fn recvmsg(s: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; + +- pub fn writev(s: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::c_int; +- pub fn readv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; ++ pub fn eventfd(initval: ::c_uint, flags: ::c_int) -> ::c_int; + } ++ ++pub use crate::unix::newlib::generic::{sigset_t, stat}; +diff --git a/vendor/libc/src/unix/newlib/generic.rs b/vendor/libc/src/unix/newlib/generic.rs +new file mode 100644 +index 0000000..db7797f +--- /dev/null ++++ b/vendor/libc/src/unix/newlib/generic.rs +@@ -0,0 +1,27 @@ ++//! Common types used by most newlib platforms ++ ++s! { ++ pub struct sigset_t { ++ __val: [::c_ulong; 16], ++ } ++ ++ pub struct stat { ++ pub st_dev: ::dev_t, ++ pub st_ino: ::ino_t, ++ pub st_mode: ::mode_t, ++ pub st_nlink: ::nlink_t, ++ pub st_uid: ::uid_t, ++ pub st_gid: ::gid_t, ++ pub st_rdev: ::dev_t, ++ pub st_size: ::off_t, ++ pub st_atime: ::time_t, ++ pub st_spare1: ::c_long, ++ pub st_mtime: ::time_t, ++ pub st_spare2: ::c_long, ++ pub st_ctime: ::time_t, ++ pub st_spare3: ::c_long, ++ pub st_blksize: ::blksize_t, ++ pub st_blocks: ::blkcnt_t, ++ pub st_spare4: [::c_long; 2usize], ++ } ++} +diff --git a/vendor/libc/src/unix/newlib/horizon/mod.rs b/vendor/libc/src/unix/newlib/horizon/mod.rs +new file mode 100644 +index 0000000..bcb93ad +--- /dev/null ++++ b/vendor/libc/src/unix/newlib/horizon/mod.rs +@@ -0,0 +1,268 @@ ++//! ARMv6K Nintendo 3DS C Newlib definitions ++ ++pub type c_char = u8; ++pub type c_long = i32; ++pub type c_ulong = u32; ++ ++pub type wchar_t = ::c_uint; ++ ++pub type u_register_t = ::c_uint; ++pub type u_char = ::c_uchar; ++pub type u_short = ::c_ushort; ++pub type u_int = ::c_uint; ++pub type u_long = c_ulong; ++pub type ushort = ::c_ushort; ++pub type uint = ::c_uint; ++pub type ulong = c_ulong; ++pub type clock_t = c_ulong; ++pub type daddr_t = c_long; ++pub type caddr_t = *mut c_char; ++pub type sbintime_t = ::c_longlong; ++pub type sigset_t = ::c_ulong; ++ ++s! { ++ pub struct sockaddr { ++ pub sa_family: ::sa_family_t, ++ pub sa_data: [::c_char; 26usize], ++ } ++ ++ pub struct sockaddr_storage { ++ pub ss_family: ::sa_family_t, ++ pub __ss_padding: [::c_char; 26usize], ++ } ++ ++ pub struct sockaddr_in { ++ pub sin_family: ::sa_family_t, ++ pub sin_port: ::in_port_t, ++ pub sin_addr: ::in_addr, ++ } ++ ++ pub struct sockaddr_in6 { ++ pub sin6_family: ::sa_family_t, ++ pub sin6_port: ::in_port_t, ++ pub sin6_flowinfo: u32, ++ pub sin6_addr: ::in6_addr, ++ pub sin6_scope_id: u32, ++ } ++ ++ pub struct sockaddr_un { ++ pub sun_len: ::c_uchar, ++ pub sun_family: ::sa_family_t, ++ pub sun_path: [::c_char; 104usize], ++ } ++ ++ pub struct sched_param { ++ pub sched_priority: ::c_int, ++ } ++ ++ pub struct stat { ++ pub st_dev: ::dev_t, ++ pub st_ino: ::ino_t, ++ pub st_mode: ::mode_t, ++ pub st_nlink: ::nlink_t, ++ pub st_uid: ::uid_t, ++ pub st_gid: ::gid_t, ++ pub st_rdev: ::dev_t, ++ pub st_size: ::off_t, ++ pub st_atim: ::timespec, ++ pub st_mtim: ::timespec, ++ pub st_ctim: ::timespec, ++ pub st_blksize: ::blksize_t, ++ pub st_blocks: ::blkcnt_t, ++ pub st_spare4: [::c_long; 2usize], ++ } ++} ++ ++pub const SIGEV_NONE: ::c_int = 1; ++pub const SIGEV_SIGNAL: ::c_int = 2; ++pub const SIGEV_THREAD: ::c_int = 3; ++pub const SA_NOCLDSTOP: ::c_int = 1; ++pub const MINSIGSTKSZ: ::c_int = 2048; ++pub const SIGSTKSZ: ::c_int = 8192; ++pub const SS_ONSTACK: ::c_int = 1; ++pub const SS_DISABLE: ::c_int = 2; ++pub const SIG_SETMASK: ::c_int = 0; ++pub const SIG_BLOCK: ::c_int = 1; ++pub const SIG_UNBLOCK: ::c_int = 2; ++pub const SIGHUP: ::c_int = 1; ++pub const SIGINT: ::c_int = 2; ++pub const SIGQUIT: ::c_int = 3; ++pub const SIGILL: ::c_int = 4; ++pub const SIGTRAP: ::c_int = 5; ++pub const SIGABRT: ::c_int = 6; ++pub const SIGEMT: ::c_int = 7; ++pub const SIGFPE: ::c_int = 8; ++pub const SIGKILL: ::c_int = 9; ++pub const SIGBUS: ::c_int = 10; ++pub const SIGSEGV: ::c_int = 11; ++pub const SIGSYS: ::c_int = 12; ++pub const SIGPIPE: ::c_int = 13; ++pub const SIGALRM: ::c_int = 14; ++pub const SIGTERM: ::c_int = 15; ++pub const SIGURG: ::c_int = 16; ++pub const SIGSTOP: ::c_int = 17; ++pub const SIGTSTP: ::c_int = 18; ++pub const SIGCONT: ::c_int = 19; ++pub const SIGCHLD: ::c_int = 20; ++pub const SIGCLD: ::c_int = 20; ++pub const SIGTTIN: ::c_int = 21; ++pub const SIGTTOU: ::c_int = 22; ++pub const SIGIO: ::c_int = 23; ++pub const SIGPOLL: ::c_int = 23; ++pub const SIGXCPU: ::c_int = 24; ++pub const SIGXFSZ: ::c_int = 25; ++pub const SIGVTALRM: ::c_int = 26; ++pub const SIGPROF: ::c_int = 27; ++pub const SIGWINCH: ::c_int = 28; ++pub const SIGLOST: ::c_int = 29; ++pub const SIGUSR1: ::c_int = 30; ++pub const SIGUSR2: ::c_int = 31; ++pub const NSIG: ::c_int = 32; ++pub const CLOCK_ENABLED: ::c_uint = 1; ++pub const CLOCK_DISABLED: ::c_uint = 0; ++pub const CLOCK_ALLOWED: ::c_uint = 1; ++pub const CLOCK_DISALLOWED: ::c_uint = 0; ++pub const TIMER_ABSTIME: ::c_uint = 4; ++pub const SOL_SOCKET: ::c_int = 65535; ++pub const MSG_OOB: ::c_int = 1; ++pub const MSG_PEEK: ::c_int = 2; ++pub const MSG_DONTWAIT: ::c_int = 4; ++pub const MSG_DONTROUTE: ::c_int = 0; ++pub const MSG_WAITALL: ::c_int = 0; ++pub const MSG_MORE: ::c_int = 0; ++pub const MSG_NOSIGNAL: ::c_int = 0; ++pub const SOL_CONFIG: ::c_uint = 65534; ++ ++pub const _SC_PAGESIZE: ::c_int = 8; ++pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 51; ++ ++pub const PTHREAD_STACK_MIN: ::size_t = 4096; ++pub const WNOHANG: ::c_int = 1; ++ ++pub const POLLIN: ::c_short = 0x0001; ++pub const POLLPRI: ::c_short = 0x0002; ++pub const POLLOUT: ::c_short = 0x0004; ++pub const POLLRDNORM: ::c_short = 0x0040; ++pub const POLLWRNORM: ::c_short = POLLOUT; ++pub const POLLRDBAND: ::c_short = 0x0080; ++pub const POLLWRBAND: ::c_short = 0x0100; ++pub const POLLERR: ::c_short = 0x0008; ++pub const POLLHUP: ::c_short = 0x0010; ++pub const POLLNVAL: ::c_short = 0x0020; ++ ++pub const EAI_AGAIN: ::c_int = 2; ++pub const EAI_BADFLAGS: ::c_int = 3; ++pub const EAI_FAIL: ::c_int = 4; ++pub const EAI_SERVICE: ::c_int = 9; ++pub const EAI_SYSTEM: ::c_int = 11; ++pub const EAI_BADHINTS: ::c_int = 12; ++pub const EAI_PROTOCOL: ::c_int = 13; ++pub const EAI_OVERFLOW: ::c_int = 14; ++pub const EAI_MAX: ::c_int = 15; ++ ++pub const AF_UNIX: ::c_int = 1; ++pub const AF_INET6: ::c_int = 23; ++ ++pub const FIONBIO: ::c_ulong = 1; ++ ++pub const RTLD_DEFAULT: *mut ::c_void = 0 as *mut ::c_void; ++ ++// For pthread get/setschedparam ++pub const SCHED_FIFO: ::c_int = 1; ++pub const SCHED_RR: ::c_int = 2; ++ ++// For getrandom() ++pub const GRND_NONBLOCK: ::c_uint = 0x1; ++pub const GRND_RANDOM: ::c_uint = 0x2; ++ ++// Horizon OS works doesn't or can't hold any of this information ++safe_f! { ++ pub {const} fn WIFSTOPPED(_status: ::c_int) -> bool { ++ false ++ } ++ ++ pub {const} fn WSTOPSIG(_status: ::c_int) -> ::c_int { ++ 0 ++ } ++ ++ pub {const} fn WIFCONTINUED(_status: ::c_int) -> bool { ++ true ++ } ++ ++ pub {const} fn WIFSIGNALED(_status: ::c_int) -> bool { ++ false ++ } ++ ++ pub {const} fn WTERMSIG(_status: ::c_int) -> ::c_int { ++ 0 ++ } ++ ++ pub {const} fn WIFEXITED(_status: ::c_int) -> bool { ++ true ++ } ++ ++ pub {const} fn WEXITSTATUS(_status: ::c_int) -> ::c_int { ++ 0 ++ } ++ ++ pub {const} fn WCOREDUMP(_status: ::c_int) -> bool { ++ false ++ } ++} ++ ++extern "C" { ++ pub fn pthread_create( ++ native: *mut ::pthread_t, ++ attr: *const ::pthread_attr_t, ++ f: extern "C" fn(_: *mut ::c_void) -> *mut ::c_void, ++ value: *mut ::c_void, ++ ) -> ::c_int; ++ ++ pub fn pthread_attr_getschedparam( ++ attr: *const ::pthread_attr_t, ++ param: *mut sched_param, ++ ) -> ::c_int; ++ ++ pub fn pthread_attr_setschedparam( ++ attr: *mut ::pthread_attr_t, ++ param: *const sched_param, ++ ) -> ::c_int; ++ ++ pub fn pthread_attr_getprocessorid_np( ++ attr: *const ::pthread_attr_t, ++ processor_id: *mut ::c_int, ++ ) -> ::c_int; ++ ++ pub fn pthread_attr_setprocessorid_np( ++ attr: *mut ::pthread_attr_t, ++ processor_id: ::c_int, ++ ) -> ::c_int; ++ ++ pub fn pthread_getschedparam( ++ native: ::pthread_t, ++ policy: *mut ::c_int, ++ param: *mut ::sched_param, ++ ) -> ::c_int; ++ ++ pub fn pthread_setschedparam( ++ native: ::pthread_t, ++ policy: ::c_int, ++ param: *const ::sched_param, ++ ) -> ::c_int; ++ ++ pub fn pthread_condattr_getclock( ++ attr: *const ::pthread_condattr_t, ++ clock_id: *mut ::clockid_t, ++ ) -> ::c_int; ++ ++ pub fn pthread_condattr_setclock( ++ attr: *mut ::pthread_condattr_t, ++ clock_id: ::clockid_t, ++ ) -> ::c_int; ++ ++ pub fn pthread_getprocessorid_np() -> ::c_int; ++ ++ pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; ++ ++ pub fn gethostid() -> ::c_long; ++} +diff --git a/vendor/libc/src/unix/newlib/mod.rs b/vendor/libc/src/unix/newlib/mod.rs +index 6e87983..1477a60 100644 +--- a/vendor/libc/src/unix/newlib/mod.rs ++++ b/vendor/libc/src/unix/newlib/mod.rs +@@ -1,28 +1,53 @@ + pub type blkcnt_t = i32; + pub type blksize_t = i32; + pub type clockid_t = ::c_ulong; +-pub type dev_t = u32; ++ ++cfg_if! { ++ if #[cfg(target_os = "espidf")] { ++ pub type dev_t = ::c_short; ++ pub type ino_t = ::c_ushort; ++ pub type off_t = ::c_long; ++ } else { ++ pub type dev_t = u32; ++ pub type ino_t = u32; ++ pub type off_t = i64; ++ } ++} ++ + pub type fsblkcnt_t = u64; + pub type fsfilcnt_t = u32; + pub type id_t = u32; +-pub type ino_t = u32; + pub type key_t = ::c_int; + pub type loff_t = ::c_longlong; + pub type mode_t = ::c_uint; + pub type nfds_t = u32; + pub type nlink_t = ::c_ushort; +-pub type off_t = i64; + pub type pthread_t = ::c_ulong; + pub type pthread_key_t = ::c_uint; + pub type rlim_t = u32; +-pub type sa_family_t = u8; ++ ++cfg_if! { ++ if #[cfg(target_os = "horizon")] { ++ pub type sa_family_t = u16; ++ } else { ++ pub type sa_family_t = u8; ++ } ++} ++ + pub type socklen_t = u32; + pub type speed_t = u32; + pub type suseconds_t = i32; + pub type tcflag_t = ::c_uint; +-pub type time_t = i32; + pub type useconds_t = u32; + ++cfg_if! { ++ if #[cfg(any(target_os = "horizon", all(target_os = "espidf", espidf_time64)))] { ++ pub type time_t = ::c_longlong; ++ } else { ++ pub type time_t = i32; ++ } ++} ++ + s! { + // The order of the `ai_addr` field in this struct is crucial + // for converting between the Rust and C types. +@@ -33,16 +58,14 @@ s! { + pub ai_protocol: ::c_int, + pub ai_addrlen: socklen_t, + +- #[cfg(not(all(libc_cfg_target_vendor, target_arch = "powerpc", +- target_vendor = "nintendo")))] +- #[cfg(target_arch = "xtensa")] ++ #[cfg(target_os = "espidf")] + pub ai_addr: *mut sockaddr, + + pub ai_canonname: *mut ::c_char, + +- #[cfg(not(all(libc_cfg_target_vendor, target_arch = "powerpc", +- target_vendor = "nintendo")))] +- #[cfg(not(target_arch = "xtensa"))] ++ #[cfg(not(any( ++ target_os = "espidf", ++ all(libc_cfg_target_vendor, target_arch = "powerpc", target_vendor = "nintendo"))))] + pub ai_addr: *mut sockaddr, + + pub ai_next: *mut addrinfo, +@@ -116,26 +139,6 @@ s! { + pub tm_isdst: ::c_int, + } + +- pub struct stat { +- pub st_dev: ::dev_t, +- pub st_ino: ::ino_t, +- pub st_mode: ::mode_t, +- pub st_nlink: ::nlink_t, +- pub st_uid: ::uid_t, +- pub st_gid: ::gid_t, +- pub st_rdev: dev_t, +- pub st_size: off_t, +- pub st_atime: time_t, +- pub st_spare1: ::c_long, +- pub st_mtime: time_t, +- pub st_spare2: ::c_long, +- pub st_ctime: time_t, +- pub st_spare3: ::c_long, +- pub st_blksize: blksize_t, +- pub st_blocks: blkcnt_t, +- pub st_spare4: [::c_long; 2usize], +- } +- + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, +@@ -150,10 +153,6 @@ s! { + pub f_namemax: ::c_ulong, + } + +- pub struct sigset_t { +- __val: [::c_ulong; 16], +- } +- + pub struct sigaction { + pub sa_handler: extern fn(arg1: ::c_int), + pub sa_mask: sigset_t, +@@ -232,23 +231,37 @@ s! { + // unverified constants + align_const! { + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { +- size: [0; __SIZEOF_PTHREAD_MUTEX_T], ++ size: [__PTHREAD_INITIALIZER_BYTE; __SIZEOF_PTHREAD_MUTEX_T], + }; + pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { +- size: [0; __SIZEOF_PTHREAD_COND_T], ++ size: [__PTHREAD_INITIALIZER_BYTE; __SIZEOF_PTHREAD_COND_T], + }; + pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { +- size: [0; __SIZEOF_PTHREAD_RWLOCK_T], ++ size: [__PTHREAD_INITIALIZER_BYTE; __SIZEOF_PTHREAD_RWLOCK_T], + }; + } + pub const NCCS: usize = 32; +-pub const __SIZEOF_PTHREAD_ATTR_T: usize = 56; +-pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +-pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +-pub const __SIZEOF_PTHREAD_COND_T: usize = 48; +-pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +-pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +-pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; ++cfg_if! { ++ if #[cfg(target_os = "espidf")] { ++ const __PTHREAD_INITIALIZER_BYTE: u8 = 0xff; ++ pub const __SIZEOF_PTHREAD_ATTR_T: usize = 32; ++ pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 4; ++ pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 12; ++ pub const __SIZEOF_PTHREAD_COND_T: usize = 4; ++ pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 8; ++ pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 4; ++ pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 12; ++ } else { ++ const __PTHREAD_INITIALIZER_BYTE: u8 = 0; ++ pub const __SIZEOF_PTHREAD_ATTR_T: usize = 56; ++ pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; ++ pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; ++ pub const __SIZEOF_PTHREAD_COND_T: usize = 48; ++ pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; ++ pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; ++ pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; ++ } ++} + pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + pub const __PTHREAD_MUTEX_HAVE_PREV: usize = 1; +@@ -256,7 +269,14 @@ pub const __PTHREAD_RWLOCK_INT_FLAGS_SHARED: usize = 1; + pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; + pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1; + pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2; +-pub const FD_SETSIZE: usize = 1024; ++ ++cfg_if! { ++ if #[cfg(any(target_os = "horizon", target_os = "espidf"))] { ++ pub const FD_SETSIZE: usize = 64; ++ } else { ++ pub const FD_SETSIZE: usize = 1024; ++ } ++} + // intentionally not public, only used for fd_set + const ULONG_SIZE: usize = 32; + +@@ -465,7 +485,13 @@ pub const SO_SNDLOWAT: ::c_int = 0x1003; + pub const SO_RCVLOWAT: ::c_int = 0x1004; + pub const SO_SNDTIMEO: ::c_int = 0x1005; + pub const SO_RCVTIMEO: ::c_int = 0x1006; +-pub const SO_ERROR: ::c_int = 0x1007; ++cfg_if! { ++ if #[cfg(target_os = "horizon")] { ++ pub const SO_ERROR: ::c_int = 0x1009; ++ } else { ++ pub const SO_ERROR: ::c_int = 0x1007; ++ } ++} + pub const SO_TYPE: ::c_int = 0x1008; + + pub const SOCK_CLOEXEC: ::c_int = O_CLOEXEC; +@@ -500,7 +526,13 @@ pub const TCP_KEEPIDLE: ::c_int = 256; + pub const TCP_KEEPINTVL: ::c_int = 512; + pub const TCP_KEEPCNT: ::c_int = 1024; + +-pub const IP_TOS: ::c_int = 3; ++cfg_if! { ++ if #[cfg(target_os = "horizon")] { ++ pub const IP_TOS: ::c_int = 7; ++ } else { ++ pub const IP_TOS: ::c_int = 3; ++ } ++} + pub const IP_TTL: ::c_int = 8; + pub const IP_MULTICAST_IF: ::c_int = 9; + pub const IP_MULTICAST_TTL: ::c_int = 10; +@@ -558,7 +590,7 @@ f! { + return + } + +- pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool { ++ pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0 +@@ -589,7 +621,6 @@ extern "C" { + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + + pub fn abs(i: ::c_int) -> ::c_int; +- pub fn atof(s: *const ::c_char) -> ::c_double; + pub fn labs(i: ::c_long) -> ::c_long; + pub fn rand() -> ::c_int; + pub fn srand(seed: ::c_uint); +@@ -599,10 +630,12 @@ extern "C" { + target_arch = "powerpc", + target_vendor = "nintendo" + )))] ++ #[cfg_attr(target_os = "espidf", link_name = "lwip_bind")] + pub fn bind(fd: ::c_int, addr: *const sockaddr, len: socklen_t) -> ::c_int; + pub fn clock_settime(clock_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; + pub fn clock_gettime(clock_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_getres(clock_id: ::clockid_t, res: *mut ::timespec) -> ::c_int; ++ #[cfg_attr(target_os = "espidf", link_name = "lwip_close")] + pub fn closesocket(sockfd: ::c_int) -> ::c_int; + pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; + #[cfg(not(all( +@@ -610,6 +643,7 @@ extern "C" { + target_arch = "powerpc", + target_vendor = "nintendo" + )))] ++ #[cfg_attr(target_os = "espidf", link_name = "lwip_recvfrom")] + pub fn recvfrom( + fd: ::c_int, + buf: *mut ::c_void, +@@ -687,16 +721,21 @@ extern "C" { + pub fn uname(buf: *mut ::utsname) -> ::c_int; + } + ++mod generic; ++ + cfg_if! { +- if #[cfg(target_arch = "arm")] { ++ if #[cfg(target_os = "espidf")] { ++ mod espidf; ++ pub use self::espidf::*; ++ } else if #[cfg(target_os = "horizon")] { ++ mod horizon; ++ pub use self::horizon::*; ++ } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::*; + } else if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; +- } else if #[cfg(target_arch = "xtensa")] { +- mod xtensa; +- pub use self::xtensa::*; + } else if #[cfg(target_arch = "powerpc")] { + mod powerpc; + pub use self::powerpc::*; +diff --git a/vendor/libc/src/unix/newlib/powerpc/mod.rs b/vendor/libc/src/unix/newlib/powerpc/mod.rs +index 4289658..6bed1ce 100644 +--- a/vendor/libc/src/unix/newlib/powerpc/mod.rs ++++ b/vendor/libc/src/unix/newlib/powerpc/mod.rs +@@ -5,6 +5,8 @@ pub type wchar_t = ::c_int; + pub type c_long = i32; + pub type c_ulong = u32; + ++pub use crate::unix::newlib::generic::{sigset_t, stat}; ++ + // the newlib shipped with devkitPPC does not support the following components: + // - sockaddr + // - AF_INET6 +diff --git a/vendor/libc/src/unix/nto/aarch64.rs b/vendor/libc/src/unix/nto/aarch64.rs +new file mode 100644 +index 0000000..6faf815 +--- /dev/null ++++ b/vendor/libc/src/unix/nto/aarch64.rs +@@ -0,0 +1,36 @@ ++pub type c_char = u8; ++pub type wchar_t = u32; ++pub type c_long = i64; ++pub type c_ulong = u64; ++pub type time_t = i64; ++ ++s! { ++ pub struct aarch64_qreg_t { ++ pub qlo: u64, ++ pub qhi: u64, ++ } ++ ++ pub struct aarch64_fpu_registers { ++ pub reg: [::aarch64_qreg_t; 32], ++ pub fpsr: u32, ++ pub fpcr: u32, ++ } ++ ++ pub struct aarch64_cpu_registers { ++ pub gpr: [u64; 32], ++ pub elr: u64, ++ pub pstate: u64, ++ } ++ ++ #[repr(align(16))] ++ pub struct mcontext_t { ++ pub cpu: ::aarch64_cpu_registers, ++ pub fpu: ::aarch64_fpu_registers, ++ } ++ ++ pub struct stack_t { ++ pub ss_sp: *mut ::c_void, ++ pub ss_size: ::size_t, ++ pub ss_flags: ::c_int, ++ } ++} +diff --git a/vendor/libc/src/unix/nto/mod.rs b/vendor/libc/src/unix/nto/mod.rs +new file mode 100644 +index 0000000..b8fcf9d +--- /dev/null ++++ b/vendor/libc/src/unix/nto/mod.rs +@@ -0,0 +1,3285 @@ ++pub type clock_t = u32; ++ ++pub type sa_family_t = u8; ++pub type speed_t = ::c_uint; ++pub type tcflag_t = ::c_uint; ++pub type clockid_t = ::c_int; ++pub type timer_t = ::c_int; ++pub type key_t = ::c_uint; ++pub type id_t = ::c_int; ++ ++pub type useconds_t = u32; ++pub type dev_t = u32; ++pub type socklen_t = u32; ++pub type mode_t = u32; ++pub type rlim64_t = u64; ++pub type mqd_t = ::c_int; ++pub type nfds_t = ::c_uint; ++pub type idtype_t = ::c_uint; ++pub type errno_t = ::c_int; ++pub type rsize_t = c_ulong; ++ ++pub type Elf32_Half = u16; ++pub type Elf32_Word = u32; ++pub type Elf32_Off = u32; ++pub type Elf32_Addr = u32; ++pub type Elf32_Lword = u64; ++pub type Elf32_Sword = i32; ++ ++pub type Elf64_Half = u16; ++pub type Elf64_Word = u32; ++pub type Elf64_Off = u64; ++pub type Elf64_Addr = u64; ++pub type Elf64_Xword = u64; ++pub type Elf64_Sxword = i64; ++pub type Elf64_Lword = u64; ++pub type Elf64_Sword = i32; ++ ++pub type Elf32_Section = u16; ++pub type Elf64_Section = u16; ++ ++pub type _Time32t = u32; ++ ++pub type pthread_t = ::c_int; ++pub type regoff_t = ::ssize_t; ++ ++pub type nlink_t = u32; ++pub type blksize_t = u32; ++pub type suseconds_t = i32; ++ ++pub type ino_t = u64; ++pub type off_t = i64; ++pub type blkcnt_t = u64; ++pub type msgqnum_t = u64; ++pub type msglen_t = u64; ++pub type fsblkcnt_t = u64; ++pub type fsfilcnt_t = u64; ++pub type rlim_t = u64; ++pub type posix_spawn_file_actions_t = *mut ::c_void; ++pub type posix_spawnattr_t = ::uintptr_t; ++ ++pub type pthread_mutex_t = ::sync_t; ++pub type pthread_mutexattr_t = ::_sync_attr; ++pub type pthread_cond_t = ::sync_t; ++pub type pthread_condattr_t = ::_sync_attr; ++pub type pthread_rwlockattr_t = ::_sync_attr; ++pub type pthread_key_t = ::c_int; ++pub type pthread_spinlock_t = sync_t; ++pub type pthread_barrierattr_t = _sync_attr; ++pub type sem_t = sync_t; ++ ++pub type nl_item = ::c_int; ++ ++#[cfg_attr(feature = "extra_traits", derive(Debug))] ++pub enum timezone {} ++impl ::Copy for timezone {} ++impl ::Clone for timezone { ++ fn clone(&self) -> timezone { ++ *self ++ } ++} ++ ++s! { ++ pub struct ip_mreq { ++ pub imr_multiaddr: in_addr, ++ pub imr_interface: in_addr, ++ } ++ ++ #[repr(packed)] ++ pub struct in_addr { ++ pub s_addr: ::in_addr_t, ++ } ++ ++ pub struct sockaddr { ++ pub sa_len: u8, ++ pub sa_family: sa_family_t, ++ pub sa_data: [::c_char; 14], ++ } ++ ++ pub struct sockaddr_in { ++ pub sin_len: u8, ++ pub sin_family: sa_family_t, ++ pub sin_port: ::in_port_t, ++ pub sin_addr: ::in_addr, ++ pub sin_zero: [i8; 8], ++ } ++ ++ pub struct sockaddr_in6 { ++ pub sin6_len: u8, ++ pub sin6_family: sa_family_t, ++ pub sin6_port: ::in_port_t, ++ pub sin6_flowinfo: u32, ++ pub sin6_addr: ::in6_addr, ++ pub sin6_scope_id: u32, ++ } ++ ++ // The order of the `ai_addr` field in this struct is crucial ++ // for converting between the Rust and C types. ++ pub struct addrinfo { ++ pub ai_flags: ::c_int, ++ pub ai_family: ::c_int, ++ pub ai_socktype: ::c_int, ++ pub ai_protocol: ::c_int, ++ pub ai_addrlen: socklen_t, ++ pub ai_canonname: *mut c_char, ++ pub ai_addr: *mut ::sockaddr, ++ pub ai_next: *mut addrinfo, ++ } ++ ++ pub struct fd_set { ++ fds_bits: [::c_uint; 2 * FD_SETSIZE / ULONG_SIZE], ++ } ++ ++ pub struct tm { ++ pub tm_sec: ::c_int, ++ pub tm_min: ::c_int, ++ pub tm_hour: ::c_int, ++ pub tm_mday: ::c_int, ++ pub tm_mon: ::c_int, ++ pub tm_year: ::c_int, ++ pub tm_wday: ::c_int, ++ pub tm_yday: ::c_int, ++ pub tm_isdst: ::c_int, ++ pub tm_gmtoff: ::c_long, ++ pub tm_zone: *const ::c_char, ++ } ++ ++ #[repr(align(8))] ++ pub struct sched_param { ++ pub sched_priority: ::c_int, ++ pub sched_curpriority: ::c_int, ++ pub reserved: [::c_int; 10], ++ } ++ ++ #[repr(align(8))] ++ pub struct __sched_param { ++ pub __sched_priority: ::c_int, ++ pub __sched_curpriority: ::c_int, ++ pub reserved: [::c_int; 10], ++ } ++ ++ pub struct Dl_info { ++ pub dli_fname: *const ::c_char, ++ pub dli_fbase: *mut ::c_void, ++ pub dli_sname: *const ::c_char, ++ pub dli_saddr: *mut ::c_void, ++ } ++ ++ pub struct lconv { ++ pub currency_symbol: *mut ::c_char, ++ pub int_curr_symbol: *mut ::c_char, ++ pub mon_decimal_point: *mut ::c_char, ++ pub mon_grouping: *mut ::c_char, ++ pub mon_thousands_sep: *mut ::c_char, ++ pub negative_sign: *mut ::c_char, ++ pub positive_sign: *mut ::c_char, ++ pub frac_digits: ::c_char, ++ pub int_frac_digits: ::c_char, ++ pub n_cs_precedes: ::c_char, ++ pub n_sep_by_space: ::c_char, ++ pub n_sign_posn: ::c_char, ++ pub p_cs_precedes: ::c_char, ++ pub p_sep_by_space: ::c_char, ++ pub p_sign_posn: ::c_char, ++ ++ pub int_n_cs_precedes: ::c_char, ++ pub int_n_sep_by_space: ::c_char, ++ pub int_n_sign_posn: ::c_char, ++ pub int_p_cs_precedes: ::c_char, ++ pub int_p_sep_by_space: ::c_char, ++ pub int_p_sign_posn: ::c_char, ++ ++ pub decimal_point: *mut ::c_char, ++ pub grouping: *mut ::c_char, ++ pub thousands_sep: *mut ::c_char, ++ ++ pub _Frac_grouping: *mut ::c_char, ++ pub _Frac_sep: *mut ::c_char, ++ pub _False: *mut ::c_char, ++ pub _True: *mut ::c_char, ++ ++ pub _No: *mut ::c_char, ++ pub _Yes: *mut ::c_char, ++ pub _Nostr: *mut ::c_char, ++ pub _Yesstr: *mut ::c_char, ++ pub _Reserved: [*mut ::c_char; 8], ++ } ++ ++ pub struct in_pktinfo { ++ pub ipi_addr: ::in_addr, ++ pub ipi_ifindex: ::c_uint, ++ } ++ ++ pub struct ifaddrs { ++ pub ifa_next: *mut ifaddrs, ++ pub ifa_name: *mut c_char, ++ pub ifa_flags: ::c_uint, ++ pub ifa_addr: *mut ::sockaddr, ++ pub ifa_netmask: *mut ::sockaddr, ++ pub ifa_dstaddr: *mut ::sockaddr, ++ pub ifa_data: *mut ::c_void ++ } ++ ++ pub struct arpreq { ++ pub arp_pa: ::sockaddr, ++ pub arp_ha: ::sockaddr, ++ pub arp_flags: ::c_int, ++ } ++ ++ #[repr(packed)] ++ pub struct arphdr { ++ pub ar_hrd: u16, ++ pub ar_pro: u16, ++ pub ar_hln: u8, ++ pub ar_pln: u8, ++ pub ar_op: u16, ++ } ++ ++ pub struct mmsghdr { ++ pub msg_hdr: ::msghdr, ++ pub msg_len: ::c_uint, ++ } ++ ++ #[repr(align(8))] ++ pub struct siginfo_t { ++ pub si_signo: ::c_int, ++ pub si_code: ::c_int, ++ pub si_errno: ::c_int, ++ __data: [u8; 36], // union ++ } ++ ++ pub struct sigaction { ++ pub sa_sigaction: ::sighandler_t, ++ pub sa_flags: ::c_int, ++ pub sa_mask: ::sigset_t, ++ } ++ ++ pub struct _sync { ++ _union: ::c_uint, ++ __owner: ::c_uint, ++ } ++ pub struct rlimit64 { ++ pub rlim_cur: rlim64_t, ++ pub rlim_max: rlim64_t, ++ } ++ ++ pub struct glob_t { ++ pub gl_pathc: ::size_t, ++ pub gl_matchc: ::c_int, ++ pub gl_pathv: *mut *mut c_char, ++ pub gl_offs: ::size_t, ++ pub gl_flags: ::c_int, ++ pub gl_errfunc: extern "C" fn(*const ::c_char, ::c_int) -> ::c_int, ++ ++ __unused1: *mut ::c_void, ++ __unused2: *mut ::c_void, ++ __unused3: *mut ::c_void, ++ __unused4: *mut ::c_void, ++ __unused5: *mut ::c_void, ++ } ++ ++ pub struct passwd { ++ pub pw_name: *mut ::c_char, ++ pub pw_passwd: *mut ::c_char, ++ pub pw_uid: ::uid_t, ++ pub pw_gid: ::gid_t, ++ pub pw_age: *mut ::c_char, ++ pub pw_comment: *mut ::c_char, ++ pub pw_gecos: *mut ::c_char, ++ pub pw_dir: *mut ::c_char, ++ pub pw_shell: *mut ::c_char, ++ } ++ ++ pub struct if_nameindex { ++ pub if_index: ::c_uint, ++ pub if_name: *mut ::c_char, ++ } ++ ++ pub struct sembuf { ++ pub sem_num: ::c_ushort, ++ pub sem_op: ::c_short, ++ pub sem_flg: ::c_short, ++ } ++ ++ pub struct Elf32_Ehdr { ++ pub e_ident: [::c_uchar; 16], ++ pub e_type: Elf32_Half, ++ pub e_machine: Elf32_Half, ++ pub e_version: Elf32_Word, ++ pub e_entry: Elf32_Addr, ++ pub e_phoff: Elf32_Off, ++ pub e_shoff: Elf32_Off, ++ pub e_flags: Elf32_Word, ++ pub e_ehsize: Elf32_Half, ++ pub e_phentsize: Elf32_Half, ++ pub e_phnum: Elf32_Half, ++ pub e_shentsize: Elf32_Half, ++ pub e_shnum: Elf32_Half, ++ pub e_shstrndx: Elf32_Half, ++ } ++ ++ pub struct Elf64_Ehdr { ++ pub e_ident: [::c_uchar; 16], ++ pub e_type: Elf64_Half, ++ pub e_machine: Elf64_Half, ++ pub e_version: Elf64_Word, ++ pub e_entry: Elf64_Addr, ++ pub e_phoff: Elf64_Off, ++ pub e_shoff: Elf64_Off, ++ pub e_flags: Elf64_Word, ++ pub e_ehsize: Elf64_Half, ++ pub e_phentsize: Elf64_Half, ++ pub e_phnum: Elf64_Half, ++ pub e_shentsize: Elf64_Half, ++ pub e_shnum: Elf64_Half, ++ pub e_shstrndx: Elf64_Half, ++ } ++ ++ pub struct Elf32_Sym { ++ pub st_name: Elf32_Word, ++ pub st_value: Elf32_Addr, ++ pub st_size: Elf32_Word, ++ pub st_info: ::c_uchar, ++ pub st_other: ::c_uchar, ++ pub st_shndx: Elf32_Section, ++ } ++ ++ pub struct Elf64_Sym { ++ pub st_name: Elf64_Word, ++ pub st_info: ::c_uchar, ++ pub st_other: ::c_uchar, ++ pub st_shndx: Elf64_Section, ++ pub st_value: Elf64_Addr, ++ pub st_size: Elf64_Xword, ++ } ++ ++ pub struct Elf32_Phdr { ++ pub p_type: Elf32_Word, ++ pub p_offset: Elf32_Off, ++ pub p_vaddr: Elf32_Addr, ++ pub p_paddr: Elf32_Addr, ++ pub p_filesz: Elf32_Word, ++ pub p_memsz: Elf32_Word, ++ pub p_flags: Elf32_Word, ++ pub p_align: Elf32_Word, ++ } ++ ++ pub struct Elf64_Phdr { ++ pub p_type: Elf64_Word, ++ pub p_flags: Elf64_Word, ++ pub p_offset: Elf64_Off, ++ pub p_vaddr: Elf64_Addr, ++ pub p_paddr: Elf64_Addr, ++ pub p_filesz: Elf64_Xword, ++ pub p_memsz: Elf64_Xword, ++ pub p_align: Elf64_Xword, ++ } ++ ++ pub struct Elf32_Shdr { ++ pub sh_name: Elf32_Word, ++ pub sh_type: Elf32_Word, ++ pub sh_flags: Elf32_Word, ++ pub sh_addr: Elf32_Addr, ++ pub sh_offset: Elf32_Off, ++ pub sh_size: Elf32_Word, ++ pub sh_link: Elf32_Word, ++ pub sh_info: Elf32_Word, ++ pub sh_addralign: Elf32_Word, ++ pub sh_entsize: Elf32_Word, ++ } ++ ++ pub struct Elf64_Shdr { ++ pub sh_name: Elf64_Word, ++ pub sh_type: Elf64_Word, ++ pub sh_flags: Elf64_Xword, ++ pub sh_addr: Elf64_Addr, ++ pub sh_offset: Elf64_Off, ++ pub sh_size: Elf64_Xword, ++ pub sh_link: Elf64_Word, ++ pub sh_info: Elf64_Word, ++ pub sh_addralign: Elf64_Xword, ++ pub sh_entsize: Elf64_Xword, ++ } ++ ++ pub struct in6_pktinfo { ++ pub ipi6_addr: ::in6_addr, ++ pub ipi6_ifindex: ::c_uint, ++ } ++ ++ pub struct inotify_event { ++ pub wd: ::c_int, ++ pub mask: u32, ++ pub cookie: u32, ++ pub len: u32 ++ } ++ ++ pub struct regmatch_t { ++ pub rm_so: regoff_t, ++ pub rm_eo: regoff_t, ++ } ++ ++ pub struct msghdr { ++ pub msg_name: *mut ::c_void, ++ pub msg_namelen: ::socklen_t, ++ pub msg_iov: *mut ::iovec, ++ pub msg_iovlen: ::c_int, ++ pub msg_control: *mut ::c_void, ++ pub msg_controllen: ::socklen_t, ++ pub msg_flags: ::c_int, ++ } ++ ++ pub struct cmsghdr { ++ pub cmsg_len: ::socklen_t, ++ pub cmsg_level: ::c_int, ++ pub cmsg_type: ::c_int, ++ } ++ ++ pub struct termios { ++ pub c_iflag: ::tcflag_t, ++ pub c_oflag: ::tcflag_t, ++ pub c_cflag: ::tcflag_t, ++ pub c_lflag: ::tcflag_t, ++ pub c_cc: [::cc_t; ::NCCS], ++ __reserved: [::c_uint; 3], ++ pub c_ispeed: ::speed_t, ++ pub c_ospeed: ::speed_t, ++ } ++ ++ pub struct mallinfo { ++ pub arena: ::c_int, ++ pub ordblks: ::c_int, ++ pub smblks: ::c_int, ++ pub hblks: ::c_int, ++ pub hblkhd: ::c_int, ++ pub usmblks: ::c_int, ++ pub fsmblks: ::c_int, ++ pub uordblks: ::c_int, ++ pub fordblks: ::c_int, ++ pub keepcost: ::c_int, ++ } ++ ++ pub struct flock { ++ pub l_type: i16, ++ pub l_whence: i16, ++ pub l_zero1: i32, ++ pub l_start: ::off_t, ++ pub l_len: ::off_t, ++ pub l_pid: ::pid_t, ++ pub l_sysid: u32, ++ } ++ ++ pub struct statvfs { ++ pub f_bsize: ::c_ulong, ++ pub f_frsize: ::c_ulong, ++ pub f_blocks: ::fsblkcnt_t, ++ pub f_bfree: ::fsblkcnt_t, ++ pub f_bavail: ::fsblkcnt_t, ++ pub f_files: ::fsfilcnt_t, ++ pub f_ffree: ::fsfilcnt_t, ++ pub f_favail: ::fsfilcnt_t, ++ pub f_fsid: ::c_ulong, ++ pub f_basetype: [::c_char; 16], ++ pub f_flag: ::c_ulong, ++ pub f_namemax: ::c_ulong, ++ f_filler: [::c_uint; 21], ++ } ++ ++ pub struct aiocb { ++ pub aio_fildes: ::c_int, ++ pub aio_reqprio: ::c_int, ++ pub aio_offset: off_t, ++ pub aio_buf: *mut ::c_void, ++ pub aio_nbytes: ::size_t, ++ pub aio_sigevent: ::sigevent, ++ pub aio_lio_opcode: ::c_int, ++ pub _aio_lio_state: *mut ::c_void, ++ _aio_pad: [::c_int; 3], ++ pub _aio_next: *mut ::aiocb, ++ pub _aio_flag: ::c_uint, ++ pub _aio_iotype: ::c_uint, ++ pub _aio_result: ::ssize_t, ++ pub _aio_error: ::c_uint, ++ pub _aio_suspend: *mut ::c_void, ++ pub _aio_plist: *mut ::c_void, ++ pub _aio_policy: ::c_int, ++ pub _aio_param: ::__sched_param, ++ } ++ ++ pub struct pthread_attr_t { ++ __data1: ::c_long, ++ __data2: [u8; 96] ++ } ++ ++ pub struct ipc_perm { ++ pub uid: ::uid_t, ++ pub gid: ::gid_t, ++ pub cuid: ::uid_t, ++ pub cgid: ::gid_t, ++ pub mode: ::mode_t, ++ pub seq: ::c_uint, ++ pub key: ::key_t, ++ _reserved: [::c_int; 4], ++ } ++ ++ pub struct regex_t { ++ re_magic: ::c_int, ++ re_nsub: ::size_t, ++ re_endp: *const ::c_char, ++ re_g: *mut ::c_void, ++ } ++ ++ pub struct _thread_attr { ++ pub __flags: ::c_int, ++ pub __stacksize: ::size_t, ++ pub __stackaddr: *mut ::c_void, ++ pub __exitfunc: ::Option, ++ pub __policy: ::c_int, ++ pub __param: ::__sched_param, ++ pub __guardsize: ::c_uint, ++ pub __prealloc: ::c_uint, ++ __spare: [::c_int; 2], ++ } ++ ++ pub struct _sync_attr { ++ pub __protocol: ::c_int, ++ pub __flags: ::c_int, ++ pub __prioceiling: ::c_int, ++ pub __clockid: ::c_int, ++ pub __count: ::c_int, ++ __reserved: [::c_int; 3], ++ } ++ ++ pub struct sockcred { ++ pub sc_uid: ::uid_t, ++ pub sc_euid: ::uid_t, ++ pub sc_gid: ::gid_t, ++ pub sc_egid: ::gid_t, ++ pub sc_ngroups: ::c_int, ++ pub sc_groups: [::gid_t; 1], ++ } ++ ++ pub struct bpf_program { ++ pub bf_len: ::c_uint, ++ pub bf_insns: *mut ::bpf_insn, ++ } ++ ++ pub struct bpf_stat { ++ pub bs_recv: u64, ++ pub bs_drop: u64, ++ pub bs_capt: u64, ++ bs_padding: [u64; 13], ++ } ++ ++ pub struct bpf_version { ++ pub bv_major: ::c_ushort, ++ pub bv_minor: ::c_ushort, ++ } ++ ++ pub struct bpf_hdr { ++ pub bh_tstamp: ::timeval, ++ pub bh_caplen: u32, ++ pub bh_datalen: u32, ++ pub bh_hdrlen: u16, ++ } ++ ++ pub struct bpf_insn { ++ pub code: u16, ++ pub jt: ::c_uchar, ++ pub jf: ::c_uchar, ++ pub k: u32, ++ } ++ ++ pub struct bpf_dltlist { ++ pub bfl_len: ::c_uint, ++ pub bfl_list: *mut ::c_uint, ++ } ++ ++ pub struct unpcbid { ++ pub unp_pid: ::pid_t, ++ pub unp_euid: ::uid_t, ++ pub unp_egid: ::gid_t, ++ } ++ ++ pub struct dl_phdr_info { ++ pub dlpi_addr: ::Elf64_Addr, ++ pub dlpi_name: *const ::c_char, ++ pub dlpi_phdr: *const ::Elf64_Phdr, ++ pub dlpi_phnum: ::Elf64_Half, ++ } ++ ++ #[repr(align(8))] ++ pub struct ucontext_t { ++ pub uc_link: *mut ucontext_t, ++ pub uc_sigmask: ::sigset_t, ++ pub uc_stack: stack_t, ++ pub uc_mcontext: mcontext_t, ++ } ++} ++ ++s_no_extra_traits! { ++ pub struct sockaddr_un { ++ pub sun_len: u8, ++ pub sun_family: sa_family_t, ++ pub sun_path: [::c_char; 104] ++ } ++ ++ pub struct sockaddr_storage { ++ pub ss_len: u8, ++ pub ss_family: sa_family_t, ++ __ss_pad1: [::c_char; 6], ++ __ss_align: i64, ++ __ss_pad2: [::c_char; 112], ++ } ++ ++ pub struct utsname { ++ pub sysname: [::c_char; _SYSNAME_SIZE], ++ pub nodename: [::c_char; _SYSNAME_SIZE], ++ pub release: [::c_char; _SYSNAME_SIZE], ++ pub version: [::c_char; _SYSNAME_SIZE], ++ pub machine: [::c_char; _SYSNAME_SIZE], ++ } ++ ++ pub struct sigevent { ++ pub sigev_notify: ::c_int, ++ __sigev_un1: usize, // union ++ pub sigev_value: ::sigval, ++ __sigev_un2: usize, // union ++ ++ } ++ pub struct dirent { ++ pub d_ino: ::ino_t, ++ pub d_offset: ::off_t, ++ pub d_reclen: ::c_short, ++ pub d_namelen: ::c_short, ++ pub d_name: [::c_char; 1], // flex array ++ } ++ ++ pub struct dirent_extra { ++ pub d_datalen: u16, ++ pub d_type: u16, ++ pub d_reserved: u32, ++ } ++ ++ pub struct stat { ++ pub st_ino: ::ino_t, ++ pub st_size: ::off_t, ++ pub st_dev: ::dev_t, ++ pub st_rdev: ::dev_t, ++ pub st_uid: ::uid_t, ++ pub st_gid: ::gid_t, ++ pub __old_st_mtime: ::_Time32t, ++ pub __old_st_atime: ::_Time32t, ++ pub __old_st_ctime: ::_Time32t, ++ pub st_mode: ::mode_t, ++ pub st_nlink: ::nlink_t, ++ pub st_blocksize: ::blksize_t, ++ pub st_nblocks: i32, ++ pub st_blksize: ::blksize_t, ++ pub st_blocks: ::blkcnt_t, ++ pub st_mtim: ::timespec, ++ pub st_atim: ::timespec, ++ pub st_ctim: ::timespec, ++ } ++ ++ pub struct sigset_t { ++ __val: [u32; 2], ++ } ++ ++ pub struct mq_attr { ++ pub mq_maxmsg: ::c_long, ++ pub mq_msgsize: ::c_long, ++ pub mq_flags: ::c_long, ++ pub mq_curmsgs: ::c_long, ++ pub mq_sendwait: ::c_long, ++ pub mq_recvwait: ::c_long, ++ } ++ ++ pub struct msg { ++ pub msg_next: *mut ::msg, ++ pub msg_type: ::c_long, ++ pub msg_ts: ::c_ushort, ++ pub msg_spot: ::c_short, ++ _pad: [u8; 4], ++ } ++ ++ pub struct msqid_ds { ++ pub msg_perm: ::ipc_perm, ++ pub msg_first: *mut ::msg, ++ pub msg_last: *mut ::msg, ++ pub msg_cbytes: ::msglen_t, ++ pub msg_qnum: ::msgqnum_t, ++ pub msg_qbytes: ::msglen_t, ++ pub msg_lspid: ::pid_t, ++ pub msg_lrpid: ::pid_t, ++ pub msg_stime: ::time_t, ++ msg_pad1: ::c_long, ++ pub msg_rtime: ::time_t, ++ msg_pad2: ::c_long, ++ pub msg_ctime: ::time_t, ++ msg_pad3: ::c_long, ++ msg_pad4: [::c_long; 4], ++ } ++ ++ pub struct sockaddr_dl { ++ pub sdl_len: ::c_uchar, ++ pub sdl_family: ::sa_family_t, ++ pub sdl_index: u16, ++ pub sdl_type: ::c_uchar, ++ pub sdl_nlen: ::c_uchar, ++ pub sdl_alen: ::c_uchar, ++ pub sdl_slen: ::c_uchar, ++ pub sdl_data: [::c_char; 12], ++ } ++ ++ pub struct sync_t { ++ __u: ::c_uint, // union ++ pub __owner: ::c_uint, ++ } ++ ++ #[repr(align(4))] ++ pub struct pthread_barrier_t { // union ++ __pad: [u8; 28], // union ++ } ++ ++ pub struct pthread_rwlock_t { ++ pub __active: ::c_int, ++ pub __blockedwriters: ::c_int, ++ pub __blockedreaders: ::c_int, ++ pub __heavy: ::c_int, ++ pub __lock: ::pthread_mutex_t, // union ++ pub __rcond: ::pthread_cond_t, // union ++ pub __wcond: ::pthread_cond_t, // union ++ pub __owner: ::c_uint, ++ pub __spare: ::c_uint, ++ } ++} ++ ++cfg_if! { ++ if #[cfg(feature = "extra_traits")] { ++ impl PartialEq for sockaddr_un { ++ fn eq(&self, other: &sockaddr_un) -> bool { ++ self.sun_len == other.sun_len ++ && self.sun_family == other.sun_family ++ && self ++ .sun_path ++ .iter() ++ .zip(other.sun_path.iter()) ++ .all(|(a,b)| a == b) ++ } ++ } ++ ++ impl Eq for sockaddr_un {} ++ ++ impl ::fmt::Debug for sockaddr_un { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("sockaddr_un") ++ .field("sun_len", &self.sun_len) ++ .field("sun_family", &self.sun_family) ++ // FIXME: .field("sun_path", &self.sun_path) ++ .finish() ++ } ++ } ++ ++ impl ::hash::Hash for sockaddr_un { ++ fn hash(&self, state: &mut H) { ++ self.sun_len.hash(state); ++ self.sun_family.hash(state); ++ self.sun_path.hash(state); ++ } ++ } ++ ++ impl PartialEq for utsname { ++ fn eq(&self, other: &utsname) -> bool { ++ self.sysname ++ .iter() ++ .zip(other.sysname.iter()) ++ .all(|(a,b)| a == b) ++ && self ++ .nodename ++ .iter() ++ .zip(other.nodename.iter()) ++ .all(|(a,b)| a == b) ++ && self ++ .release ++ .iter() ++ .zip(other.release.iter()) ++ .all(|(a,b)| a == b) ++ && self ++ .version ++ .iter() ++ .zip(other.version.iter()) ++ .all(|(a,b)| a == b) ++ && self ++ .machine ++ .iter() ++ .zip(other.machine.iter()) ++ .all(|(a,b)| a == b) ++ } ++ } ++ ++ impl Eq for utsname {} ++ ++ impl ::fmt::Debug for utsname { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("utsname") ++ // FIXME: .field("sysname", &self.sysname) ++ // FIXME: .field("nodename", &self.nodename) ++ // FIXME: .field("release", &self.release) ++ // FIXME: .field("version", &self.version) ++ // FIXME: .field("machine", &self.machine) ++ .finish() ++ } ++ } ++ ++ impl ::hash::Hash for utsname { ++ fn hash(&self, state: &mut H) { ++ self.sysname.hash(state); ++ self.nodename.hash(state); ++ self.release.hash(state); ++ self.version.hash(state); ++ self.machine.hash(state); ++ } ++ } ++ ++ impl PartialEq for mq_attr { ++ fn eq(&self, other: &mq_attr) -> bool { ++ self.mq_maxmsg == other.mq_maxmsg && ++ self.mq_msgsize == other.mq_msgsize && ++ self.mq_flags == other.mq_flags && ++ self.mq_curmsgs == other.mq_curmsgs && ++ self.mq_msgsize == other.mq_msgsize && ++ self.mq_sendwait == other.mq_sendwait && ++ self.mq_recvwait == other.mq_recvwait ++ } ++ } ++ ++ impl Eq for mq_attr {} ++ ++ impl ::fmt::Debug for mq_attr { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("mq_attr") ++ .field("mq_maxmsg", &self.mq_maxmsg) ++ .field("mq_msgsize", &self.mq_msgsize) ++ .field("mq_flags", &self.mq_flags) ++ .field("mq_curmsgs", &self.mq_curmsgs) ++ .field("mq_msgsize", &self.mq_msgsize) ++ .field("mq_sendwait", &self.mq_sendwait) ++ .field("mq_recvwait", &self.mq_recvwait) ++ .finish() ++ } ++ } ++ ++ impl PartialEq for sockaddr_storage { ++ fn eq(&self, other: &sockaddr_storage) -> bool { ++ self.ss_len == other.ss_len ++ && self.ss_family == other.ss_family ++ && self.__ss_pad1 == other.__ss_pad1 ++ && self.__ss_align == other.__ss_align ++ && self ++ .__ss_pad2 ++ .iter() ++ .zip(other.__ss_pad2.iter()) ++ .all(|(a, b)| a == b) ++ } ++ } ++ ++ impl Eq for sockaddr_storage {} ++ ++ impl ::fmt::Debug for sockaddr_storage { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("sockaddr_storage") ++ .field("ss_len", &self.ss_len) ++ .field("ss_family", &self.ss_family) ++ .field("__ss_pad1", &self.__ss_pad1) ++ .field("__ss_align", &self.__ss_align) ++ // FIXME: .field("__ss_pad2", &self.__ss_pad2) ++ .finish() ++ } ++ } ++ ++ impl ::hash::Hash for sockaddr_storage { ++ fn hash(&self, state: &mut H) { ++ self.ss_len.hash(state); ++ self.ss_family.hash(state); ++ self.__ss_pad1.hash(state); ++ self.__ss_align.hash(state); ++ self.__ss_pad2.hash(state); ++ } ++ } ++ ++ impl PartialEq for dirent { ++ fn eq(&self, other: &dirent) -> bool { ++ self.d_ino == other.d_ino ++ && self.d_offset == other.d_offset ++ && self.d_reclen == other.d_reclen ++ && self.d_namelen == other.d_namelen ++ && self ++ .d_name[..self.d_namelen as _] ++ .iter() ++ .zip(other.d_name.iter()) ++ .all(|(a,b)| a == b) ++ } ++ } ++ ++ impl Eq for dirent {} ++ ++ impl ::fmt::Debug for dirent { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("dirent") ++ .field("d_ino", &self.d_ino) ++ .field("d_offset", &self.d_offset) ++ .field("d_reclen", &self.d_reclen) ++ .field("d_namelen", &self.d_namelen) ++ .field("d_name", &&self.d_name[..self.d_namelen as _]) ++ .finish() ++ } ++ } ++ ++ impl ::hash::Hash for dirent { ++ fn hash(&self, state: &mut H) { ++ self.d_ino.hash(state); ++ self.d_offset.hash(state); ++ self.d_reclen.hash(state); ++ self.d_namelen.hash(state); ++ self.d_name[..self.d_namelen as _].hash(state); ++ } ++ } ++ } ++} ++ ++pub const _SYSNAME_SIZE: usize = 256 + 1; ++pub const RLIM_INFINITY: ::rlim_t = 0xfffffffffffffffd; ++pub const O_LARGEFILE: ::c_int = 0o0100000; ++ ++// intentionally not public, only used for fd_set ++cfg_if! { ++ if #[cfg(target_pointer_width = "32")] { ++ const ULONG_SIZE: usize = 32; ++ } else if #[cfg(target_pointer_width = "64")] { ++ const ULONG_SIZE: usize = 64; ++ } else { ++ // Unknown target_pointer_width ++ } ++} ++ ++pub const EXIT_FAILURE: ::c_int = 1; ++pub const EXIT_SUCCESS: ::c_int = 0; ++pub const RAND_MAX: ::c_int = 32767; ++pub const EOF: ::c_int = -1; ++pub const SEEK_SET: ::c_int = 0; ++pub const SEEK_CUR: ::c_int = 1; ++pub const SEEK_END: ::c_int = 2; ++pub const _IOFBF: ::c_int = 0; ++pub const _IONBF: ::c_int = 2; ++pub const _IOLBF: ::c_int = 1; ++ ++pub const F_DUPFD: ::c_int = 0; ++pub const F_GETFD: ::c_int = 1; ++pub const F_SETFD: ::c_int = 2; ++pub const F_GETFL: ::c_int = 3; ++pub const F_SETFL: ::c_int = 4; ++ ++pub const F_DUPFD_CLOEXEC: ::c_int = 5; ++ ++pub const SIGTRAP: ::c_int = 5; ++ ++pub const CLOCK_REALTIME: ::clockid_t = 0; ++pub const CLOCK_MONOTONIC: ::clockid_t = 2; ++pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 3; ++pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 4; ++pub const TIMER_ABSTIME: ::c_uint = 0x80000000; ++ ++pub const RUSAGE_SELF: ::c_int = 0; ++ ++pub const F_OK: ::c_int = 0; ++pub const X_OK: ::c_int = 1; ++pub const W_OK: ::c_int = 2; ++pub const R_OK: ::c_int = 4; ++ ++pub const STDIN_FILENO: ::c_int = 0; ++pub const STDOUT_FILENO: ::c_int = 1; ++pub const STDERR_FILENO: ::c_int = 2; ++ ++pub const SIGHUP: ::c_int = 1; ++pub const SIGINT: ::c_int = 2; ++pub const SIGQUIT: ::c_int = 3; ++pub const SIGILL: ::c_int = 4; ++pub const SIGABRT: ::c_int = 6; ++pub const SIGFPE: ::c_int = 8; ++pub const SIGKILL: ::c_int = 9; ++pub const SIGSEGV: ::c_int = 11; ++pub const SIGPIPE: ::c_int = 13; ++pub const SIGALRM: ::c_int = 14; ++pub const SIGTERM: ::c_int = 15; ++ ++pub const PROT_NONE: ::c_int = 0x00000000; ++pub const PROT_READ: ::c_int = 0x00000100; ++pub const PROT_WRITE: ::c_int = 0x00000200; ++pub const PROT_EXEC: ::c_int = 0x00000400; ++ ++pub const MAP_FILE: ::c_int = 0; ++pub const MAP_SHARED: ::c_int = 1; ++pub const MAP_PRIVATE: ::c_int = 2; ++pub const MAP_FIXED: ::c_int = 0x10; ++ ++pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; ++ ++pub const MS_ASYNC: ::c_int = 1; ++pub const MS_INVALIDATE: ::c_int = 4; ++pub const MS_SYNC: ::c_int = 2; ++ ++pub const SCM_RIGHTS: ::c_int = 0x01; ++pub const SCM_TIMESTAMP: ::c_int = 0x02; ++pub const SCM_CREDS: ::c_int = 0x04; ++ ++pub const MAP_TYPE: ::c_int = 0x3; ++ ++pub const IFF_UP: ::c_int = 0x00000001; ++pub const IFF_BROADCAST: ::c_int = 0x00000002; ++pub const IFF_DEBUG: ::c_int = 0x00000004; ++pub const IFF_LOOPBACK: ::c_int = 0x00000008; ++pub const IFF_POINTOPOINT: ::c_int = 0x00000010; ++pub const IFF_NOTRAILERS: ::c_int = 0x00000020; ++pub const IFF_RUNNING: ::c_int = 0x00000040; ++pub const IFF_NOARP: ::c_int = 0x00000080; ++pub const IFF_PROMISC: ::c_int = 0x00000100; ++pub const IFF_ALLMULTI: ::c_int = 0x00000200; ++pub const IFF_MULTICAST: ::c_int = 0x00008000; ++ ++pub const AF_UNSPEC: ::c_int = 0; ++pub const AF_UNIX: ::c_int = AF_LOCAL; ++pub const AF_LOCAL: ::c_int = 1; ++pub const AF_INET: ::c_int = 2; ++pub const AF_IPX: ::c_int = 23; ++pub const AF_APPLETALK: ::c_int = 16; ++pub const AF_INET6: ::c_int = 24; ++pub const AF_ROUTE: ::c_int = 17; ++pub const AF_SNA: ::c_int = 11; ++pub const AF_BLUETOOTH: ::c_int = 31; ++pub const AF_ISDN: ::c_int = 26; ++ ++pub const PF_UNSPEC: ::c_int = AF_UNSPEC; ++pub const PF_UNIX: ::c_int = PF_LOCAL; ++pub const PF_LOCAL: ::c_int = AF_LOCAL; ++pub const PF_INET: ::c_int = AF_INET; ++pub const PF_IPX: ::c_int = AF_IPX; ++pub const PF_APPLETALK: ::c_int = AF_APPLETALK; ++pub const PF_INET6: ::c_int = AF_INET6; ++pub const pseudo_AF_KEY: ::c_int = 29; ++pub const PF_KEY: ::c_int = pseudo_AF_KEY; ++pub const PF_ROUTE: ::c_int = AF_ROUTE; ++pub const PF_SNA: ::c_int = AF_SNA; ++ ++pub const PF_BLUETOOTH: ::c_int = AF_BLUETOOTH; ++pub const PF_ISDN: ::c_int = AF_ISDN; ++ ++pub const SOMAXCONN: ::c_int = 128; ++ ++pub const MSG_OOB: ::c_int = 0x0001; ++pub const MSG_PEEK: ::c_int = 0x0002; ++pub const MSG_DONTROUTE: ::c_int = 0x0004; ++pub const MSG_CTRUNC: ::c_int = 0x0020; ++pub const MSG_TRUNC: ::c_int = 0x0010; ++pub const MSG_DONTWAIT: ::c_int = 0x0080; ++pub const MSG_EOR: ::c_int = 0x0008; ++pub const MSG_WAITALL: ::c_int = 0x0040; ++pub const MSG_NOSIGNAL: ::c_int = 0x0800; ++pub const MSG_WAITFORONE: ::c_int = 0x2000; ++ ++pub const IP_TOS: ::c_int = 3; ++pub const IP_TTL: ::c_int = 4; ++pub const IP_HDRINCL: ::c_int = 2; ++pub const IP_OPTIONS: ::c_int = 1; ++pub const IP_RECVOPTS: ::c_int = 5; ++pub const IP_RETOPTS: ::c_int = 8; ++pub const IP_PKTINFO: ::c_int = 25; ++pub const IP_IPSEC_POLICY_COMPAT: ::c_int = 22; ++pub const IP_MULTICAST_IF: ::c_int = 9; ++pub const IP_MULTICAST_TTL: ::c_int = 10; ++pub const IP_MULTICAST_LOOP: ::c_int = 11; ++pub const IP_ADD_MEMBERSHIP: ::c_int = 12; ++pub const IP_DROP_MEMBERSHIP: ::c_int = 13; ++pub const IP_DEFAULT_MULTICAST_TTL: ::c_int = 1; ++pub const IP_DEFAULT_MULTICAST_LOOP: ::c_int = 1; ++ ++pub const IPPROTO_HOPOPTS: ::c_int = 0; ++pub const IPPROTO_IGMP: ::c_int = 2; ++pub const IPPROTO_IPIP: ::c_int = 4; ++pub const IPPROTO_EGP: ::c_int = 8; ++pub const IPPROTO_PUP: ::c_int = 12; ++pub const IPPROTO_IDP: ::c_int = 22; ++pub const IPPROTO_TP: ::c_int = 29; ++pub const IPPROTO_ROUTING: ::c_int = 43; ++pub const IPPROTO_FRAGMENT: ::c_int = 44; ++pub const IPPROTO_RSVP: ::c_int = 46; ++pub const IPPROTO_GRE: ::c_int = 47; ++pub const IPPROTO_ESP: ::c_int = 50; ++pub const IPPROTO_AH: ::c_int = 51; ++pub const IPPROTO_NONE: ::c_int = 59; ++pub const IPPROTO_DSTOPTS: ::c_int = 60; ++pub const IPPROTO_ENCAP: ::c_int = 98; ++pub const IPPROTO_PIM: ::c_int = 103; ++pub const IPPROTO_SCTP: ::c_int = 132; ++pub const IPPROTO_RAW: ::c_int = 255; ++pub const IPPROTO_MAX: ::c_int = 256; ++pub const IPPROTO_CARP: ::c_int = 112; ++pub const IPPROTO_DIVERT: ::c_int = 259; ++pub const IPPROTO_DONE: ::c_int = 257; ++pub const IPPROTO_EON: ::c_int = 80; ++pub const IPPROTO_ETHERIP: ::c_int = 97; ++pub const IPPROTO_GGP: ::c_int = 3; ++pub const IPPROTO_IPCOMP: ::c_int = 108; ++pub const IPPROTO_MOBILE: ::c_int = 55; ++ ++pub const IPV6_RTHDR_LOOSE: ::c_int = 0; ++pub const IPV6_RTHDR_STRICT: ::c_int = 1; ++pub const IPV6_UNICAST_HOPS: ::c_int = 4; ++pub const IPV6_MULTICAST_IF: ::c_int = 9; ++pub const IPV6_MULTICAST_HOPS: ::c_int = 10; ++pub const IPV6_MULTICAST_LOOP: ::c_int = 11; ++pub const IPV6_JOIN_GROUP: ::c_int = 12; ++pub const IPV6_LEAVE_GROUP: ::c_int = 13; ++pub const IPV6_CHECKSUM: ::c_int = 26; ++pub const IPV6_V6ONLY: ::c_int = 27; ++pub const IPV6_IPSEC_POLICY_COMPAT: ::c_int = 28; ++pub const IPV6_RTHDRDSTOPTS: ::c_int = 35; ++pub const IPV6_RECVPKTINFO: ::c_int = 36; ++pub const IPV6_RECVHOPLIMIT: ::c_int = 37; ++pub const IPV6_RECVRTHDR: ::c_int = 38; ++pub const IPV6_RECVHOPOPTS: ::c_int = 39; ++pub const IPV6_RECVDSTOPTS: ::c_int = 40; ++pub const IPV6_RECVPATHMTU: ::c_int = 43; ++pub const IPV6_PATHMTU: ::c_int = 44; ++pub const IPV6_PKTINFO: ::c_int = 46; ++pub const IPV6_HOPLIMIT: ::c_int = 47; ++pub const IPV6_NEXTHOP: ::c_int = 48; ++pub const IPV6_HOPOPTS: ::c_int = 49; ++pub const IPV6_DSTOPTS: ::c_int = 50; ++pub const IPV6_RECVTCLASS: ::c_int = 57; ++pub const IPV6_TCLASS: ::c_int = 61; ++pub const IPV6_DONTFRAG: ::c_int = 62; ++ ++pub const TCP_NODELAY: ::c_int = 0x01; ++pub const TCP_MAXSEG: ::c_int = 0x02; ++pub const TCP_MD5SIG: ::c_int = 0x10; ++pub const TCP_KEEPALIVE: ::c_int = 0x04; ++ ++pub const SHUT_RD: ::c_int = 0; ++pub const SHUT_WR: ::c_int = 1; ++pub const SHUT_RDWR: ::c_int = 2; ++ ++pub const LOCK_SH: ::c_int = 0x1; ++pub const LOCK_EX: ::c_int = 0x2; ++pub const LOCK_NB: ::c_int = 0x4; ++pub const LOCK_UN: ::c_int = 0x8; ++ ++pub const SS_ONSTACK: ::c_int = 1; ++pub const SS_DISABLE: ::c_int = 2; ++ ++pub const PATH_MAX: ::c_int = 1024; ++ ++pub const UIO_MAXIOV: ::c_int = 1024; ++ ++pub const FD_SETSIZE: usize = 256; ++ ++pub const TCIOFF: ::c_int = 0x0002; ++pub const TCION: ::c_int = 0x0003; ++pub const TCOOFF: ::c_int = 0x0000; ++pub const TCOON: ::c_int = 0x0001; ++pub const TCIFLUSH: ::c_int = 0; ++pub const TCOFLUSH: ::c_int = 1; ++pub const TCIOFLUSH: ::c_int = 2; ++pub const NL0: ::tcflag_t = 0x000; ++pub const NL1: ::tcflag_t = 0x100; ++pub const TAB0: ::tcflag_t = 0x0000; ++pub const CR0: ::tcflag_t = 0x000; ++pub const FF0: ::tcflag_t = 0x0000; ++pub const BS0: ::tcflag_t = 0x0000; ++pub const VT0: ::tcflag_t = 0x0000; ++pub const VERASE: usize = 2; ++pub const VKILL: usize = 3; ++pub const VINTR: usize = 0; ++pub const VQUIT: usize = 1; ++pub const VLNEXT: usize = 15; ++pub const IGNBRK: ::tcflag_t = 0x00000001; ++pub const BRKINT: ::tcflag_t = 0x00000002; ++pub const IGNPAR: ::tcflag_t = 0x00000004; ++pub const PARMRK: ::tcflag_t = 0x00000008; ++pub const INPCK: ::tcflag_t = 0x00000010; ++pub const ISTRIP: ::tcflag_t = 0x00000020; ++pub const INLCR: ::tcflag_t = 0x00000040; ++pub const IGNCR: ::tcflag_t = 0x00000080; ++pub const ICRNL: ::tcflag_t = 0x00000100; ++pub const IXANY: ::tcflag_t = 0x00000800; ++pub const IMAXBEL: ::tcflag_t = 0x00002000; ++pub const OPOST: ::tcflag_t = 0x00000001; ++pub const CS5: ::tcflag_t = 0x00; ++pub const ECHO: ::tcflag_t = 0x00000008; ++pub const OCRNL: ::tcflag_t = 0x00000008; ++pub const ONOCR: ::tcflag_t = 0x00000010; ++pub const ONLRET: ::tcflag_t = 0x00000020; ++pub const OFILL: ::tcflag_t = 0x00000040; ++pub const OFDEL: ::tcflag_t = 0x00000080; ++ ++pub const WNOHANG: ::c_int = 0x0040; ++pub const WUNTRACED: ::c_int = 0x0004; ++pub const WSTOPPED: ::c_int = WUNTRACED; ++pub const WEXITED: ::c_int = 0x0001; ++pub const WCONTINUED: ::c_int = 0x0008; ++pub const WNOWAIT: ::c_int = 0x0080; ++pub const WTRAPPED: ::c_int = 0x0002; ++ ++pub const RTLD_LOCAL: ::c_int = 0x0200; ++pub const RTLD_LAZY: ::c_int = 0x0001; ++ ++pub const POSIX_FADV_NORMAL: ::c_int = 0; ++pub const POSIX_FADV_RANDOM: ::c_int = 2; ++pub const POSIX_FADV_SEQUENTIAL: ::c_int = 1; ++pub const POSIX_FADV_WILLNEED: ::c_int = 3; ++ ++pub const AT_FDCWD: ::c_int = -100; ++pub const AT_EACCESS: ::c_int = 0x0001; ++pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x0002; ++pub const AT_SYMLINK_FOLLOW: ::c_int = 0x0004; ++pub const AT_REMOVEDIR: ::c_int = 0x0008; ++ ++pub const LOG_CRON: ::c_int = 9 << 3; ++pub const LOG_AUTHPRIV: ::c_int = 10 << 3; ++pub const LOG_FTP: ::c_int = 11 << 3; ++pub const LOG_PERROR: ::c_int = 0x20; ++ ++pub const PIPE_BUF: usize = 5120; ++ ++pub const CLD_EXITED: ::c_int = 1; ++pub const CLD_KILLED: ::c_int = 2; ++pub const CLD_DUMPED: ::c_int = 3; ++pub const CLD_TRAPPED: ::c_int = 4; ++pub const CLD_STOPPED: ::c_int = 5; ++pub const CLD_CONTINUED: ::c_int = 6; ++ ++pub const UTIME_OMIT: c_long = 0x40000002; ++pub const UTIME_NOW: c_long = 0x40000001; ++ ++pub const POLLIN: ::c_short = POLLRDNORM | POLLRDBAND; ++pub const POLLPRI: ::c_short = 0x0008; ++pub const POLLOUT: ::c_short = 0x0002; ++pub const POLLERR: ::c_short = 0x0020; ++pub const POLLHUP: ::c_short = 0x0040; ++pub const POLLNVAL: ::c_short = 0x1000; ++pub const POLLRDNORM: ::c_short = 0x0001; ++pub const POLLRDBAND: ::c_short = 0x0004; ++ ++pub const IPTOS_LOWDELAY: u8 = 0x10; ++pub const IPTOS_THROUGHPUT: u8 = 0x08; ++pub const IPTOS_RELIABILITY: u8 = 0x04; ++pub const IPTOS_MINCOST: u8 = 0x02; ++ ++pub const IPTOS_PREC_NETCONTROL: u8 = 0xe0; ++pub const IPTOS_PREC_INTERNETCONTROL: u8 = 0xc0; ++pub const IPTOS_PREC_CRITIC_ECP: u8 = 0xa0; ++pub const IPTOS_PREC_FLASHOVERRIDE: u8 = 0x80; ++pub const IPTOS_PREC_FLASH: u8 = 0x60; ++pub const IPTOS_PREC_IMMEDIATE: u8 = 0x40; ++pub const IPTOS_PREC_PRIORITY: u8 = 0x20; ++pub const IPTOS_PREC_ROUTINE: u8 = 0x00; ++ ++pub const IPTOS_ECN_MASK: u8 = 0x03; ++pub const IPTOS_ECN_ECT1: u8 = 0x01; ++pub const IPTOS_ECN_ECT0: u8 = 0x02; ++pub const IPTOS_ECN_CE: u8 = 0x03; ++ ++pub const IPOPT_CONTROL: u8 = 0x00; ++pub const IPOPT_RESERVED1: u8 = 0x20; ++pub const IPOPT_RESERVED2: u8 = 0x60; ++pub const IPOPT_LSRR: u8 = 131; ++pub const IPOPT_RR: u8 = 7; ++pub const IPOPT_SSRR: u8 = 137; ++pub const IPDEFTTL: u8 = 64; ++pub const IPOPT_OPTVAL: u8 = 0; ++pub const IPOPT_OLEN: u8 = 1; ++pub const IPOPT_OFFSET: u8 = 2; ++pub const IPOPT_MINOFF: u8 = 4; ++pub const IPOPT_NOP: u8 = 1; ++pub const IPOPT_EOL: u8 = 0; ++pub const IPOPT_TS: u8 = 68; ++pub const IPOPT_TS_TSONLY: u8 = 0; ++pub const IPOPT_TS_TSANDADDR: u8 = 1; ++pub const IPOPT_TS_PRESPEC: u8 = 3; ++ ++pub const MAX_IPOPTLEN: u8 = 40; ++pub const IPVERSION: u8 = 4; ++pub const MAXTTL: u8 = 255; ++ ++pub const ARPHRD_ETHER: u16 = 1; ++pub const ARPHRD_IEEE802: u16 = 6; ++pub const ARPHRD_ARCNET: u16 = 7; ++pub const ARPHRD_IEEE1394: u16 = 24; ++ ++pub const SOL_SOCKET: ::c_int = 0xffff; ++ ++pub const SO_DEBUG: ::c_int = 0x0001; ++pub const SO_REUSEADDR: ::c_int = 0x0004; ++pub const SO_TYPE: ::c_int = 0x1008; ++pub const SO_ERROR: ::c_int = 0x1007; ++pub const SO_DONTROUTE: ::c_int = 0x0010; ++pub const SO_BROADCAST: ::c_int = 0x0020; ++pub const SO_SNDBUF: ::c_int = 0x1001; ++pub const SO_RCVBUF: ::c_int = 0x1002; ++pub const SO_KEEPALIVE: ::c_int = 0x0008; ++pub const SO_OOBINLINE: ::c_int = 0x0100; ++pub const SO_LINGER: ::c_int = 0x0080; ++pub const SO_REUSEPORT: ::c_int = 0x0200; ++pub const SO_RCVLOWAT: ::c_int = 0x1004; ++pub const SO_SNDLOWAT: ::c_int = 0x1003; ++pub const SO_RCVTIMEO: ::c_int = 0x1006; ++pub const SO_SNDTIMEO: ::c_int = 0x1005; ++pub const SO_BINDTODEVICE: ::c_int = 0x0800; ++pub const SO_TIMESTAMP: ::c_int = 0x0400; ++pub const SO_ACCEPTCONN: ::c_int = 0x0002; ++ ++pub const TIOCM_LE: ::c_int = 0x0100; ++pub const TIOCM_DTR: ::c_int = 0x0001; ++pub const TIOCM_RTS: ::c_int = 0x0002; ++pub const TIOCM_ST: ::c_int = 0x0200; ++pub const TIOCM_SR: ::c_int = 0x0400; ++pub const TIOCM_CTS: ::c_int = 0x1000; ++pub const TIOCM_CAR: ::c_int = TIOCM_CD; ++pub const TIOCM_CD: ::c_int = 0x8000; ++pub const TIOCM_RNG: ::c_int = TIOCM_RI; ++pub const TIOCM_RI: ::c_int = 0x4000; ++pub const TIOCM_DSR: ::c_int = 0x2000; ++ ++pub const SCHED_OTHER: ::c_int = 3; ++pub const SCHED_FIFO: ::c_int = 1; ++pub const SCHED_RR: ::c_int = 2; ++ ++pub const IPC_PRIVATE: ::key_t = 0; ++ ++pub const IPC_CREAT: ::c_int = 0o001000; ++pub const IPC_EXCL: ::c_int = 0o002000; ++pub const IPC_NOWAIT: ::c_int = 0o004000; ++ ++pub const IPC_RMID: ::c_int = 0; ++pub const IPC_SET: ::c_int = 1; ++pub const IPC_STAT: ::c_int = 2; ++ ++pub const MSG_NOERROR: ::c_int = 0o010000; ++ ++pub const LOG_NFACILITIES: ::c_int = 24; ++ ++pub const SEM_FAILED: *mut ::sem_t = 0xFFFFFFFFFFFFFFFF as *mut sem_t; ++ ++pub const AI_PASSIVE: ::c_int = 0x00000001; ++pub const AI_CANONNAME: ::c_int = 0x00000002; ++pub const AI_NUMERICHOST: ::c_int = 0x00000004; ++ ++pub const AI_NUMERICSERV: ::c_int = 0x00000008; ++ ++pub const EAI_BADFLAGS: ::c_int = 3; ++pub const EAI_NONAME: ::c_int = 8; ++pub const EAI_AGAIN: ::c_int = 2; ++pub const EAI_FAIL: ::c_int = 4; ++pub const EAI_NODATA: ::c_int = 7; ++pub const EAI_FAMILY: ::c_int = 5; ++pub const EAI_SOCKTYPE: ::c_int = 10; ++pub const EAI_SERVICE: ::c_int = 9; ++pub const EAI_MEMORY: ::c_int = 6; ++pub const EAI_SYSTEM: ::c_int = 11; ++pub const EAI_OVERFLOW: ::c_int = 14; ++ ++pub const NI_NUMERICHOST: ::c_int = 0x00000002; ++pub const NI_NUMERICSERV: ::c_int = 0x00000008; ++pub const NI_NOFQDN: ::c_int = 0x00000001; ++pub const NI_NAMEREQD: ::c_int = 0x00000004; ++pub const NI_DGRAM: ::c_int = 0x00000010; ++ ++pub const AIO_CANCELED: ::c_int = 0; ++pub const AIO_NOTCANCELED: ::c_int = 2; ++pub const AIO_ALLDONE: ::c_int = 1; ++pub const LIO_READ: ::c_int = 1; ++pub const LIO_WRITE: ::c_int = 2; ++pub const LIO_NOP: ::c_int = 0; ++pub const LIO_WAIT: ::c_int = 1; ++pub const LIO_NOWAIT: ::c_int = 0; ++ ++pub const ITIMER_REAL: ::c_int = 0; ++pub const ITIMER_VIRTUAL: ::c_int = 1; ++pub const ITIMER_PROF: ::c_int = 2; ++ ++pub const POSIX_SPAWN_RESETIDS: ::c_int = 0x00000010; ++pub const POSIX_SPAWN_SETPGROUP: ::c_int = 0x00000001; ++pub const POSIX_SPAWN_SETSIGDEF: ::c_int = 0x00000004; ++pub const POSIX_SPAWN_SETSIGMASK: ::c_int = 0x00000002; ++pub const POSIX_SPAWN_SETSCHEDPARAM: ::c_int = 0x00000400; ++pub const POSIX_SPAWN_SETSCHEDULER: ::c_int = 0x00000040; ++ ++pub const IPTOS_ECN_NOT_ECT: u8 = 0x00; ++ ++pub const RTF_UP: ::c_ushort = 0x0001; ++pub const RTF_GATEWAY: ::c_ushort = 0x0002; ++ ++pub const RTF_HOST: ::c_ushort = 0x0004; ++pub const RTF_DYNAMIC: ::c_ushort = 0x0010; ++pub const RTF_MODIFIED: ::c_ushort = 0x0020; ++pub const RTF_REJECT: ::c_ushort = 0x0008; ++pub const RTF_STATIC: ::c_ushort = 0x0800; ++pub const RTF_XRESOLVE: ::c_ushort = 0x0200; ++pub const RTF_BROADCAST: u32 = 0x80000; ++pub const RTM_NEWADDR: u16 = 0xc; ++pub const RTM_DELADDR: u16 = 0xd; ++pub const RTA_DST: ::c_ushort = 0x1; ++pub const RTA_GATEWAY: ::c_ushort = 0x2; ++ ++pub const UDP_ENCAP: ::c_int = 100; ++ ++pub const IN_ACCESS: u32 = 0x00000001; ++pub const IN_MODIFY: u32 = 0x00000002; ++pub const IN_ATTRIB: u32 = 0x00000004; ++pub const IN_CLOSE_WRITE: u32 = 0x00000008; ++pub const IN_CLOSE_NOWRITE: u32 = 0x00000010; ++pub const IN_CLOSE: u32 = IN_CLOSE_WRITE | IN_CLOSE_NOWRITE; ++pub const IN_OPEN: u32 = 0x00000020; ++pub const IN_MOVED_FROM: u32 = 0x00000040; ++pub const IN_MOVED_TO: u32 = 0x00000080; ++pub const IN_MOVE: u32 = IN_MOVED_FROM | IN_MOVED_TO; ++pub const IN_CREATE: u32 = 0x00000100; ++pub const IN_DELETE: u32 = 0x00000200; ++pub const IN_DELETE_SELF: u32 = 0x00000400; ++pub const IN_MOVE_SELF: u32 = 0x00000800; ++pub const IN_UNMOUNT: u32 = 0x00002000; ++pub const IN_Q_OVERFLOW: u32 = 0x00004000; ++pub const IN_IGNORED: u32 = 0x00008000; ++pub const IN_ONLYDIR: u32 = 0x01000000; ++pub const IN_DONT_FOLLOW: u32 = 0x02000000; ++ ++pub const IN_ISDIR: u32 = 0x40000000; ++pub const IN_ONESHOT: u32 = 0x80000000; ++ ++pub const REG_EXTENDED: ::c_int = 0o0001; ++pub const REG_ICASE: ::c_int = 0o0002; ++pub const REG_NEWLINE: ::c_int = 0o0010; ++pub const REG_NOSUB: ::c_int = 0o0004; ++ ++pub const REG_NOTBOL: ::c_int = 0o00001; ++pub const REG_NOTEOL: ::c_int = 0o00002; ++ ++pub const REG_ENOSYS: ::c_int = 17; ++pub const REG_NOMATCH: ::c_int = 1; ++pub const REG_BADPAT: ::c_int = 2; ++pub const REG_ECOLLATE: ::c_int = 3; ++pub const REG_ECTYPE: ::c_int = 4; ++pub const REG_EESCAPE: ::c_int = 5; ++pub const REG_ESUBREG: ::c_int = 6; ++pub const REG_EBRACK: ::c_int = 7; ++pub const REG_EPAREN: ::c_int = 8; ++pub const REG_EBRACE: ::c_int = 9; ++pub const REG_BADBR: ::c_int = 10; ++pub const REG_ERANGE: ::c_int = 11; ++pub const REG_ESPACE: ::c_int = 12; ++pub const REG_BADRPT: ::c_int = 13; ++ ++// errno.h ++pub const EOK: ::c_int = 0; ++pub const EWOULDBLOCK: ::c_int = EAGAIN; ++pub const EPERM: ::c_int = 1; ++pub const ENOENT: ::c_int = 2; ++pub const ESRCH: ::c_int = 3; ++pub const EINTR: ::c_int = 4; ++pub const EIO: ::c_int = 5; ++pub const ENXIO: ::c_int = 6; ++pub const E2BIG: ::c_int = 7; ++pub const ENOEXEC: ::c_int = 8; ++pub const EBADF: ::c_int = 9; ++pub const ECHILD: ::c_int = 10; ++pub const EAGAIN: ::c_int = 11; ++pub const ENOMEM: ::c_int = 12; ++pub const EACCES: ::c_int = 13; ++pub const EFAULT: ::c_int = 14; ++pub const ENOTBLK: ::c_int = 15; ++pub const EBUSY: ::c_int = 16; ++pub const EEXIST: ::c_int = 17; ++pub const EXDEV: ::c_int = 18; ++pub const ENODEV: ::c_int = 19; ++pub const ENOTDIR: ::c_int = 20; ++pub const EISDIR: ::c_int = 21; ++pub const EINVAL: ::c_int = 22; ++pub const ENFILE: ::c_int = 23; ++pub const EMFILE: ::c_int = 24; ++pub const ENOTTY: ::c_int = 25; ++pub const ETXTBSY: ::c_int = 26; ++pub const EFBIG: ::c_int = 27; ++pub const ENOSPC: ::c_int = 28; ++pub const ESPIPE: ::c_int = 29; ++pub const EROFS: ::c_int = 30; ++pub const EMLINK: ::c_int = 31; ++pub const EPIPE: ::c_int = 32; ++pub const EDOM: ::c_int = 33; ++pub const ERANGE: ::c_int = 34; ++pub const ENOMSG: ::c_int = 35; ++pub const EIDRM: ::c_int = 36; ++pub const ECHRNG: ::c_int = 37; ++pub const EL2NSYNC: ::c_int = 38; ++pub const EL3HLT: ::c_int = 39; ++pub const EL3RST: ::c_int = 40; ++pub const ELNRNG: ::c_int = 41; ++pub const EUNATCH: ::c_int = 42; ++pub const ENOCSI: ::c_int = 43; ++pub const EL2HLT: ::c_int = 44; ++pub const EDEADLK: ::c_int = 45; ++pub const ENOLCK: ::c_int = 46; ++pub const ECANCELED: ::c_int = 47; ++pub const EDQUOT: ::c_int = 49; ++pub const EBADE: ::c_int = 50; ++pub const EBADR: ::c_int = 51; ++pub const EXFULL: ::c_int = 52; ++pub const ENOANO: ::c_int = 53; ++pub const EBADRQC: ::c_int = 54; ++pub const EBADSLT: ::c_int = 55; ++pub const EDEADLOCK: ::c_int = 56; ++pub const EBFONT: ::c_int = 57; ++pub const EOWNERDEAD: ::c_int = 58; ++pub const ENOSTR: ::c_int = 60; ++pub const ENODATA: ::c_int = 61; ++pub const ETIME: ::c_int = 62; ++pub const ENOSR: ::c_int = 63; ++pub const ENONET: ::c_int = 64; ++pub const ENOPKG: ::c_int = 65; ++pub const EREMOTE: ::c_int = 66; ++pub const ENOLINK: ::c_int = 67; ++pub const EADV: ::c_int = 68; ++pub const ESRMNT: ::c_int = 69; ++pub const ECOMM: ::c_int = 70; ++pub const EPROTO: ::c_int = 71; ++pub const EMULTIHOP: ::c_int = 74; ++pub const EBADMSG: ::c_int = 77; ++pub const ENAMETOOLONG: ::c_int = 78; ++pub const EOVERFLOW: ::c_int = 79; ++pub const ENOTUNIQ: ::c_int = 80; ++pub const EBADFD: ::c_int = 81; ++pub const EREMCHG: ::c_int = 82; ++pub const ELIBACC: ::c_int = 83; ++pub const ELIBBAD: ::c_int = 84; ++pub const ELIBSCN: ::c_int = 85; ++pub const ELIBMAX: ::c_int = 86; ++pub const ELIBEXEC: ::c_int = 87; ++pub const EILSEQ: ::c_int = 88; ++pub const ENOSYS: ::c_int = 89; ++pub const ELOOP: ::c_int = 90; ++pub const ERESTART: ::c_int = 91; ++pub const ESTRPIPE: ::c_int = 92; ++pub const ENOTEMPTY: ::c_int = 93; ++pub const EUSERS: ::c_int = 94; ++pub const ENOTRECOVERABLE: ::c_int = 95; ++pub const EOPNOTSUPP: ::c_int = 103; ++pub const EFPOS: ::c_int = 110; ++pub const ESTALE: ::c_int = 122; ++pub const EINPROGRESS: ::c_int = 236; ++pub const EALREADY: ::c_int = 237; ++pub const ENOTSOCK: ::c_int = 238; ++pub const EDESTADDRREQ: ::c_int = 239; ++pub const EMSGSIZE: ::c_int = 240; ++pub const EPROTOTYPE: ::c_int = 241; ++pub const ENOPROTOOPT: ::c_int = 242; ++pub const EPROTONOSUPPORT: ::c_int = 243; ++pub const ESOCKTNOSUPPORT: ::c_int = 244; ++pub const EPFNOSUPPORT: ::c_int = 246; ++pub const EAFNOSUPPORT: ::c_int = 247; ++pub const EADDRINUSE: ::c_int = 248; ++pub const EADDRNOTAVAIL: ::c_int = 249; ++pub const ENETDOWN: ::c_int = 250; ++pub const ENETUNREACH: ::c_int = 251; ++pub const ENETRESET: ::c_int = 252; ++pub const ECONNABORTED: ::c_int = 253; ++pub const ECONNRESET: ::c_int = 254; ++pub const ENOBUFS: ::c_int = 255; ++pub const EISCONN: ::c_int = 256; ++pub const ENOTCONN: ::c_int = 257; ++pub const ESHUTDOWN: ::c_int = 258; ++pub const ETOOMANYREFS: ::c_int = 259; ++pub const ETIMEDOUT: ::c_int = 260; ++pub const ECONNREFUSED: ::c_int = 261; ++pub const EHOSTDOWN: ::c_int = 264; ++pub const EHOSTUNREACH: ::c_int = 265; ++pub const EBADRPC: ::c_int = 272; ++pub const ERPCMISMATCH: ::c_int = 273; ++pub const EPROGUNAVAIL: ::c_int = 274; ++pub const EPROGMISMATCH: ::c_int = 275; ++pub const EPROCUNAVAIL: ::c_int = 276; ++pub const ENOREMOTE: ::c_int = 300; ++pub const ENONDP: ::c_int = 301; ++pub const EBADFSYS: ::c_int = 302; ++pub const EMORE: ::c_int = 309; ++pub const ECTRLTERM: ::c_int = 310; ++pub const ENOLIC: ::c_int = 311; ++pub const ESRVRFAULT: ::c_int = 312; ++pub const EENDIAN: ::c_int = 313; ++pub const ESECTYPEINVAL: ::c_int = 314; ++ ++pub const RUSAGE_CHILDREN: ::c_int = -1; ++pub const L_tmpnam: ::c_uint = 255; ++ ++pub const _PC_LINK_MAX: ::c_int = 1; ++pub const _PC_MAX_CANON: ::c_int = 2; ++pub const _PC_MAX_INPUT: ::c_int = 3; ++pub const _PC_NAME_MAX: ::c_int = 4; ++pub const _PC_PATH_MAX: ::c_int = 5; ++pub const _PC_PIPE_BUF: ::c_int = 6; ++pub const _PC_CHOWN_RESTRICTED: ::c_int = 9; ++pub const _PC_NO_TRUNC: ::c_int = 7; ++pub const _PC_VDISABLE: ::c_int = 8; ++pub const _PC_SYNC_IO: ::c_int = 14; ++pub const _PC_ASYNC_IO: ::c_int = 12; ++pub const _PC_PRIO_IO: ::c_int = 13; ++pub const _PC_SOCK_MAXBUF: ::c_int = 15; ++pub const _PC_FILESIZEBITS: ::c_int = 16; ++pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 22; ++pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 23; ++pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 24; ++pub const _PC_REC_XFER_ALIGN: ::c_int = 25; ++pub const _PC_ALLOC_SIZE_MIN: ::c_int = 21; ++pub const _PC_SYMLINK_MAX: ::c_int = 17; ++pub const _PC_2_SYMLINKS: ::c_int = 20; ++ ++pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; ++pub const _SC_ARG_MAX: ::c_int = 1; ++pub const _SC_CHILD_MAX: ::c_int = 2; ++pub const _SC_CLK_TCK: ::c_int = 3; ++pub const _SC_NGROUPS_MAX: ::c_int = 4; ++pub const _SC_OPEN_MAX: ::c_int = 5; ++pub const _SC_JOB_CONTROL: ::c_int = 6; ++pub const _SC_SAVED_IDS: ::c_int = 7; ++pub const _SC_VERSION: ::c_int = 8; ++pub const _SC_PASS_MAX: ::c_int = 9; ++pub const _SC_PAGESIZE: ::c_int = 11; ++pub const _SC_XOPEN_VERSION: ::c_int = 12; ++pub const _SC_STREAM_MAX: ::c_int = 13; ++pub const _SC_TZNAME_MAX: ::c_int = 14; ++pub const _SC_AIO_LISTIO_MAX: ::c_int = 15; ++pub const _SC_AIO_MAX: ::c_int = 16; ++pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 17; ++pub const _SC_DELAYTIMER_MAX: ::c_int = 18; ++pub const _SC_MQ_OPEN_MAX: ::c_int = 19; ++pub const _SC_MQ_PRIO_MAX: ::c_int = 20; ++pub const _SC_RTSIG_MAX: ::c_int = 21; ++pub const _SC_SEM_NSEMS_MAX: ::c_int = 22; ++pub const _SC_SEM_VALUE_MAX: ::c_int = 23; ++pub const _SC_SIGQUEUE_MAX: ::c_int = 24; ++pub const _SC_TIMER_MAX: ::c_int = 25; ++pub const _SC_ASYNCHRONOUS_IO: ::c_int = 26; ++pub const _SC_FSYNC: ::c_int = 27; ++pub const _SC_MAPPED_FILES: ::c_int = 28; ++pub const _SC_MEMLOCK: ::c_int = 29; ++pub const _SC_MEMLOCK_RANGE: ::c_int = 30; ++pub const _SC_MEMORY_PROTECTION: ::c_int = 31; ++pub const _SC_MESSAGE_PASSING: ::c_int = 32; ++pub const _SC_PRIORITIZED_IO: ::c_int = 33; ++pub const _SC_PRIORITY_SCHEDULING: ::c_int = 34; ++pub const _SC_REALTIME_SIGNALS: ::c_int = 35; ++pub const _SC_SEMAPHORES: ::c_int = 36; ++pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 37; ++pub const _SC_SYNCHRONIZED_IO: ::c_int = 38; ++pub const _SC_TIMERS: ::c_int = 39; ++pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 40; ++pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 41; ++pub const _SC_LOGIN_NAME_MAX: ::c_int = 42; ++pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 43; ++pub const _SC_THREAD_KEYS_MAX: ::c_int = 44; ++pub const _SC_THREAD_STACK_MIN: ::c_int = 45; ++pub const _SC_THREAD_THREADS_MAX: ::c_int = 46; ++pub const _SC_TTY_NAME_MAX: ::c_int = 47; ++pub const _SC_THREADS: ::c_int = 48; ++pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 49; ++pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 50; ++pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 51; ++pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 52; ++pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 53; ++pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 54; ++pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 55; ++pub const _SC_2_CHAR_TERM: ::c_int = 56; ++pub const _SC_2_C_BIND: ::c_int = 57; ++pub const _SC_2_C_DEV: ::c_int = 58; ++pub const _SC_2_C_VERSION: ::c_int = 59; ++pub const _SC_2_FORT_DEV: ::c_int = 60; ++pub const _SC_2_FORT_RUN: ::c_int = 61; ++pub const _SC_2_LOCALEDEF: ::c_int = 62; ++pub const _SC_2_SW_DEV: ::c_int = 63; ++pub const _SC_2_UPE: ::c_int = 64; ++pub const _SC_2_VERSION: ::c_int = 65; ++pub const _SC_ATEXIT_MAX: ::c_int = 66; ++pub const _SC_AVPHYS_PAGES: ::c_int = 67; ++pub const _SC_BC_BASE_MAX: ::c_int = 68; ++pub const _SC_BC_DIM_MAX: ::c_int = 69; ++pub const _SC_BC_SCALE_MAX: ::c_int = 70; ++pub const _SC_BC_STRING_MAX: ::c_int = 71; ++pub const _SC_CHARCLASS_NAME_MAX: ::c_int = 72; ++pub const _SC_CHAR_BIT: ::c_int = 73; ++pub const _SC_CHAR_MAX: ::c_int = 74; ++pub const _SC_CHAR_MIN: ::c_int = 75; ++pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 76; ++pub const _SC_EQUIV_CLASS_MAX: ::c_int = 77; ++pub const _SC_EXPR_NEST_MAX: ::c_int = 78; ++pub const _SC_INT_MAX: ::c_int = 79; ++pub const _SC_INT_MIN: ::c_int = 80; ++pub const _SC_LINE_MAX: ::c_int = 81; ++pub const _SC_LONG_BIT: ::c_int = 82; ++pub const _SC_MB_LEN_MAX: ::c_int = 83; ++pub const _SC_NL_ARGMAX: ::c_int = 84; ++pub const _SC_NL_LANGMAX: ::c_int = 85; ++pub const _SC_NL_MSGMAX: ::c_int = 86; ++pub const _SC_NL_NMAX: ::c_int = 87; ++pub const _SC_NL_SETMAX: ::c_int = 88; ++pub const _SC_NL_TEXTMAX: ::c_int = 89; ++pub const _SC_NPROCESSORS_CONF: ::c_int = 90; ++pub const _SC_NPROCESSORS_ONLN: ::c_int = 91; ++pub const _SC_NZERO: ::c_int = 92; ++pub const _SC_PHYS_PAGES: ::c_int = 93; ++pub const _SC_PII: ::c_int = 94; ++pub const _SC_PII_INTERNET: ::c_int = 95; ++pub const _SC_PII_INTERNET_DGRAM: ::c_int = 96; ++pub const _SC_PII_INTERNET_STREAM: ::c_int = 97; ++pub const _SC_PII_OSI: ::c_int = 98; ++pub const _SC_PII_OSI_CLTS: ::c_int = 99; ++pub const _SC_PII_OSI_COTS: ::c_int = 100; ++pub const _SC_PII_OSI_M: ::c_int = 101; ++pub const _SC_PII_SOCKET: ::c_int = 102; ++pub const _SC_PII_XTI: ::c_int = 103; ++pub const _SC_POLL: ::c_int = 104; ++pub const _SC_RE_DUP_MAX: ::c_int = 105; ++pub const _SC_SCHAR_MAX: ::c_int = 106; ++pub const _SC_SCHAR_MIN: ::c_int = 107; ++pub const _SC_SELECT: ::c_int = 108; ++pub const _SC_SHRT_MAX: ::c_int = 109; ++pub const _SC_SHRT_MIN: ::c_int = 110; ++pub const _SC_SSIZE_MAX: ::c_int = 111; ++pub const _SC_T_IOV_MAX: ::c_int = 112; ++pub const _SC_UCHAR_MAX: ::c_int = 113; ++pub const _SC_UINT_MAX: ::c_int = 114; ++pub const _SC_UIO_MAXIOV: ::c_int = 115; ++pub const _SC_ULONG_MAX: ::c_int = 116; ++pub const _SC_USHRT_MAX: ::c_int = 117; ++pub const _SC_WORD_BIT: ::c_int = 118; ++pub const _SC_XOPEN_CRYPT: ::c_int = 119; ++pub const _SC_XOPEN_ENH_I18N: ::c_int = 120; ++pub const _SC_XOPEN_SHM: ::c_int = 121; ++pub const _SC_XOPEN_UNIX: ::c_int = 122; ++pub const _SC_XOPEN_XCU_VERSION: ::c_int = 123; ++pub const _SC_XOPEN_XPG2: ::c_int = 124; ++pub const _SC_XOPEN_XPG3: ::c_int = 125; ++pub const _SC_XOPEN_XPG4: ::c_int = 126; ++pub const _SC_XBS5_ILP32_OFF32: ::c_int = 127; ++pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 128; ++pub const _SC_XBS5_LP64_OFF64: ::c_int = 129; ++pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 130; ++pub const _SC_ADVISORY_INFO: ::c_int = 131; ++pub const _SC_CPUTIME: ::c_int = 132; ++pub const _SC_SPAWN: ::c_int = 133; ++pub const _SC_SPORADIC_SERVER: ::c_int = 134; ++pub const _SC_THREAD_CPUTIME: ::c_int = 135; ++pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 136; ++pub const _SC_TIMEOUTS: ::c_int = 137; ++pub const _SC_BARRIERS: ::c_int = 138; ++pub const _SC_CLOCK_SELECTION: ::c_int = 139; ++pub const _SC_MONOTONIC_CLOCK: ::c_int = 140; ++pub const _SC_READER_WRITER_LOCKS: ::c_int = 141; ++pub const _SC_SPIN_LOCKS: ::c_int = 142; ++pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 143; ++pub const _SC_TRACE_EVENT_FILTER: ::c_int = 144; ++pub const _SC_TRACE: ::c_int = 145; ++pub const _SC_TRACE_INHERIT: ::c_int = 146; ++pub const _SC_TRACE_LOG: ::c_int = 147; ++pub const _SC_2_PBS: ::c_int = 148; ++pub const _SC_2_PBS_ACCOUNTING: ::c_int = 149; ++pub const _SC_2_PBS_CHECKPOINT: ::c_int = 150; ++pub const _SC_2_PBS_LOCATE: ::c_int = 151; ++pub const _SC_2_PBS_MESSAGE: ::c_int = 152; ++pub const _SC_2_PBS_TRACK: ::c_int = 153; ++pub const _SC_HOST_NAME_MAX: ::c_int = 154; ++pub const _SC_IOV_MAX: ::c_int = 155; ++pub const _SC_IPV6: ::c_int = 156; ++pub const _SC_RAW_SOCKETS: ::c_int = 157; ++pub const _SC_REGEXP: ::c_int = 158; ++pub const _SC_SHELL: ::c_int = 159; ++pub const _SC_SS_REPL_MAX: ::c_int = 160; ++pub const _SC_SYMLOOP_MAX: ::c_int = 161; ++pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 162; ++pub const _SC_TRACE_NAME_MAX: ::c_int = 163; ++pub const _SC_TRACE_SYS_MAX: ::c_int = 164; ++pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 165; ++pub const _SC_V6_ILP32_OFF32: ::c_int = 166; ++pub const _SC_V6_ILP32_OFFBIG: ::c_int = 167; ++pub const _SC_V6_LP64_OFF64: ::c_int = 168; ++pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 169; ++pub const _SC_XOPEN_REALTIME: ::c_int = 170; ++pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 171; ++pub const _SC_XOPEN_LEGACY: ::c_int = 172; ++pub const _SC_XOPEN_STREAMS: ::c_int = 173; ++pub const _SC_V7_ILP32_OFF32: ::c_int = 176; ++pub const _SC_V7_ILP32_OFFBIG: ::c_int = 177; ++pub const _SC_V7_LP64_OFF64: ::c_int = 178; ++pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 179; ++ ++pub const GLOB_ERR: ::c_int = 0x0001; ++pub const GLOB_MARK: ::c_int = 0x0002; ++pub const GLOB_NOSORT: ::c_int = 0x0004; ++pub const GLOB_DOOFFS: ::c_int = 0x0008; ++pub const GLOB_NOCHECK: ::c_int = 0x0010; ++pub const GLOB_APPEND: ::c_int = 0x0020; ++pub const GLOB_NOESCAPE: ::c_int = 0x0040; ++ ++pub const GLOB_NOSPACE: ::c_int = 1; ++pub const GLOB_ABORTED: ::c_int = 2; ++pub const GLOB_NOMATCH: ::c_int = 3; ++ ++pub const S_IEXEC: mode_t = ::S_IXUSR; ++pub const S_IWRITE: mode_t = ::S_IWUSR; ++pub const S_IREAD: mode_t = ::S_IRUSR; ++ ++pub const S_IFIFO: ::mode_t = 0x1000; ++pub const S_IFCHR: ::mode_t = 0x2000; ++pub const S_IFDIR: ::mode_t = 0x4000; ++pub const S_IFBLK: ::mode_t = 0x6000; ++pub const S_IFREG: ::mode_t = 0x8000; ++pub const S_IFLNK: ::mode_t = 0xA000; ++pub const S_IFSOCK: ::mode_t = 0xC000; ++pub const S_IFMT: ::mode_t = 0xF000; ++ ++pub const S_IXOTH: ::mode_t = 0o000001; ++pub const S_IWOTH: ::mode_t = 0o000002; ++pub const S_IROTH: ::mode_t = 0o000004; ++pub const S_IRWXO: ::mode_t = 0o000007; ++pub const S_IXGRP: ::mode_t = 0o000010; ++pub const S_IWGRP: ::mode_t = 0o000020; ++pub const S_IRGRP: ::mode_t = 0o000040; ++pub const S_IRWXG: ::mode_t = 0o000070; ++pub const S_IXUSR: ::mode_t = 0o000100; ++pub const S_IWUSR: ::mode_t = 0o000200; ++pub const S_IRUSR: ::mode_t = 0o000400; ++pub const S_IRWXU: ::mode_t = 0o000700; ++ ++pub const F_LOCK: ::c_int = 1; ++pub const F_TEST: ::c_int = 3; ++pub const F_TLOCK: ::c_int = 2; ++pub const F_ULOCK: ::c_int = 0; ++ ++pub const ST_RDONLY: ::c_ulong = 0x01; ++pub const ST_NOSUID: ::c_ulong = 0x04; ++pub const ST_NOEXEC: ::c_ulong = 0x02; ++pub const ST_NOATIME: ::c_ulong = 0x20; ++ ++pub const RTLD_NEXT: *mut ::c_void = -3i64 as *mut ::c_void; ++pub const RTLD_DEFAULT: *mut ::c_void = -2i64 as *mut ::c_void; ++pub const RTLD_NODELETE: ::c_int = 0x1000; ++pub const RTLD_NOW: ::c_int = 0x0002; ++ ++pub const EMPTY: ::c_short = 0; ++pub const RUN_LVL: ::c_short = 1; ++pub const BOOT_TIME: ::c_short = 2; ++pub const NEW_TIME: ::c_short = 4; ++pub const OLD_TIME: ::c_short = 3; ++pub const INIT_PROCESS: ::c_short = 5; ++pub const LOGIN_PROCESS: ::c_short = 6; ++pub const USER_PROCESS: ::c_short = 7; ++pub const DEAD_PROCESS: ::c_short = 8; ++pub const ACCOUNTING: ::c_short = 9; ++ ++pub const ENOTSUP: ::c_int = 48; ++ ++pub const BUFSIZ: ::c_uint = 1024; ++pub const TMP_MAX: ::c_uint = 26 * 26 * 26; ++pub const FOPEN_MAX: ::c_uint = 16; ++pub const FILENAME_MAX: ::c_uint = 255; ++ ++pub const NI_MAXHOST: ::socklen_t = 1025; ++pub const M_KEEP: ::c_int = 4; ++pub const REG_STARTEND: ::c_int = 0o00004; ++pub const VEOF: usize = 4; ++ ++pub const RTLD_GLOBAL: ::c_int = 0x0100; ++pub const RTLD_NOLOAD: ::c_int = 0x0004; ++ ++pub const O_RDONLY: ::c_int = 0o000000; ++pub const O_WRONLY: ::c_int = 0o000001; ++pub const O_RDWR: ::c_int = 0o000002; ++ ++pub const O_EXEC: ::c_int = 0o00003; ++pub const O_ASYNC: ::c_int = 0o0200000; ++pub const O_NDELAY: ::c_int = O_NONBLOCK; ++pub const O_TRUNC: ::c_int = 0o001000; ++pub const O_CLOEXEC: ::c_int = 0o020000; ++pub const O_DIRECTORY: ::c_int = 0o4000000; ++pub const O_ACCMODE: ::c_int = 0o000007; ++pub const O_APPEND: ::c_int = 0o000010; ++pub const O_CREAT: ::c_int = 0o000400; ++pub const O_EXCL: ::c_int = 0o002000; ++pub const O_NOCTTY: ::c_int = 0o004000; ++pub const O_NONBLOCK: ::c_int = 0o000200; ++pub const O_SYNC: ::c_int = 0o000040; ++pub const O_RSYNC: ::c_int = 0o000100; ++pub const O_DSYNC: ::c_int = 0o000020; ++pub const O_NOFOLLOW: ::c_int = 0o010000; ++ ++pub const POSIX_FADV_DONTNEED: ::c_int = 4; ++pub const POSIX_FADV_NOREUSE: ::c_int = 5; ++ ++pub const SOCK_SEQPACKET: ::c_int = 5; ++pub const SOCK_STREAM: ::c_int = 1; ++pub const SOCK_DGRAM: ::c_int = 2; ++pub const SOCK_RAW: ::c_int = 3; ++pub const SOCK_RDM: ::c_int = 4; ++pub const SOCK_CLOEXEC: ::c_int = 0x10000000; ++ ++pub const SA_SIGINFO: ::c_int = 0x0002; ++pub const SA_NOCLDWAIT: ::c_int = 0x0020; ++pub const SA_NODEFER: ::c_int = 0x0010; ++pub const SA_RESETHAND: ::c_int = 0x0004; ++pub const SA_NOCLDSTOP: ::c_int = 0x0001; ++ ++pub const SIGTTIN: ::c_int = 26; ++pub const SIGTTOU: ::c_int = 27; ++pub const SIGXCPU: ::c_int = 30; ++pub const SIGXFSZ: ::c_int = 31; ++pub const SIGVTALRM: ::c_int = 28; ++pub const SIGPROF: ::c_int = 29; ++pub const SIGWINCH: ::c_int = 20; ++pub const SIGCHLD: ::c_int = 18; ++pub const SIGBUS: ::c_int = 10; ++pub const SIGUSR1: ::c_int = 16; ++pub const SIGUSR2: ::c_int = 17; ++pub const SIGCONT: ::c_int = 25; ++pub const SIGSTOP: ::c_int = 23; ++pub const SIGTSTP: ::c_int = 24; ++pub const SIGURG: ::c_int = 21; ++pub const SIGIO: ::c_int = SIGPOLL; ++pub const SIGSYS: ::c_int = 12; ++pub const SIGPOLL: ::c_int = 22; ++pub const SIGPWR: ::c_int = 19; ++pub const SIG_SETMASK: ::c_int = 2; ++pub const SIG_BLOCK: ::c_int = 0; ++pub const SIG_UNBLOCK: ::c_int = 1; ++ ++pub const POLLWRNORM: ::c_short = ::POLLOUT; ++pub const POLLWRBAND: ::c_short = 0x0010; ++ ++pub const F_SETLK: ::c_int = 106; ++pub const F_SETLKW: ::c_int = 107; ++pub const F_ALLOCSP: ::c_int = 110; ++pub const F_FREESP: ::c_int = 111; ++pub const F_GETLK: ::c_int = 114; ++ ++pub const F_RDLCK: ::c_int = 1; ++pub const F_WRLCK: ::c_int = 2; ++pub const F_UNLCK: ::c_int = 3; ++ ++pub const NCCS: usize = 40; ++ ++pub const MAP_ANON: ::c_int = MAP_ANONYMOUS; ++pub const MAP_ANONYMOUS: ::c_int = 0x00080000; ++ ++pub const MCL_CURRENT: ::c_int = 0x000000001; ++pub const MCL_FUTURE: ::c_int = 0x000000002; ++ ++pub const _TIO_CBAUD: ::tcflag_t = 15; ++pub const CBAUD: ::tcflag_t = _TIO_CBAUD; ++pub const TAB1: ::tcflag_t = 0x0800; ++pub const TAB2: ::tcflag_t = 0x1000; ++pub const TAB3: ::tcflag_t = 0x1800; ++pub const CR1: ::tcflag_t = 0x200; ++pub const CR2: ::tcflag_t = 0x400; ++pub const CR3: ::tcflag_t = 0x600; ++pub const FF1: ::tcflag_t = 0x8000; ++pub const BS1: ::tcflag_t = 0x2000; ++pub const VT1: ::tcflag_t = 0x4000; ++pub const VWERASE: usize = 14; ++pub const VREPRINT: usize = 12; ++pub const VSUSP: usize = 10; ++pub const VSTART: usize = 8; ++pub const VSTOP: usize = 9; ++pub const VDISCARD: usize = 13; ++pub const VTIME: usize = 17; ++pub const IXON: ::tcflag_t = 0x00000400; ++pub const IXOFF: ::tcflag_t = 0x00001000; ++pub const ONLCR: ::tcflag_t = 0x00000004; ++pub const CSIZE: ::tcflag_t = 0x00000030; ++pub const CS6: ::tcflag_t = 0x10; ++pub const CS7: ::tcflag_t = 0x20; ++pub const CS8: ::tcflag_t = 0x30; ++pub const CSTOPB: ::tcflag_t = 0x00000040; ++pub const CREAD: ::tcflag_t = 0x00000080; ++pub const PARENB: ::tcflag_t = 0x00000100; ++pub const PARODD: ::tcflag_t = 0x00000200; ++pub const HUPCL: ::tcflag_t = 0x00000400; ++pub const CLOCAL: ::tcflag_t = 0x00000800; ++pub const ECHOKE: ::tcflag_t = 0x00000800; ++pub const ECHOE: ::tcflag_t = 0x00000010; ++pub const ECHOK: ::tcflag_t = 0x00000020; ++pub const ECHONL: ::tcflag_t = 0x00000040; ++pub const ECHOCTL: ::tcflag_t = 0x00000200; ++pub const ISIG: ::tcflag_t = 0x00000001; ++pub const ICANON: ::tcflag_t = 0x00000002; ++pub const NOFLSH: ::tcflag_t = 0x00000080; ++pub const OLCUC: ::tcflag_t = 0x00000002; ++pub const NLDLY: ::tcflag_t = 0x00000100; ++pub const CRDLY: ::tcflag_t = 0x00000600; ++pub const TABDLY: ::tcflag_t = 0x00001800; ++pub const BSDLY: ::tcflag_t = 0x00002000; ++pub const FFDLY: ::tcflag_t = 0x00008000; ++pub const VTDLY: ::tcflag_t = 0x00004000; ++pub const XTABS: ::tcflag_t = 0x1800; ++ ++pub const B0: ::speed_t = 0; ++pub const B50: ::speed_t = 1; ++pub const B75: ::speed_t = 2; ++pub const B110: ::speed_t = 3; ++pub const B134: ::speed_t = 4; ++pub const B150: ::speed_t = 5; ++pub const B200: ::speed_t = 6; ++pub const B300: ::speed_t = 7; ++pub const B600: ::speed_t = 8; ++pub const B1200: ::speed_t = 9; ++pub const B1800: ::speed_t = 10; ++pub const B2400: ::speed_t = 11; ++pub const B4800: ::speed_t = 12; ++pub const B9600: ::speed_t = 13; ++pub const B19200: ::speed_t = 14; ++pub const B38400: ::speed_t = 15; ++pub const EXTA: ::speed_t = 14; ++pub const EXTB: ::speed_t = 15; ++pub const B57600: ::speed_t = 57600; ++pub const B115200: ::speed_t = 115200; ++ ++pub const VEOL: usize = 5; ++pub const VEOL2: usize = 6; ++pub const VMIN: usize = 16; ++pub const IEXTEN: ::tcflag_t = 0x00008000; ++pub const TOSTOP: ::tcflag_t = 0x00000100; ++ ++pub const TCSANOW: ::c_int = 0x0001; ++pub const TCSADRAIN: ::c_int = 0x0002; ++pub const TCSAFLUSH: ::c_int = 0x0004; ++ ++pub const HW_MACHINE: ::c_int = 1; ++pub const HW_MODEL: ::c_int = 2; ++pub const HW_NCPU: ::c_int = 3; ++pub const HW_BYTEORDER: ::c_int = 4; ++pub const HW_PHYSMEM: ::c_int = 5; ++pub const HW_USERMEM: ::c_int = 6; ++pub const HW_PAGESIZE: ::c_int = 7; ++pub const HW_DISKNAMES: ::c_int = 8; ++pub const HW_IOSTATS: ::c_int = 9; ++pub const HW_MACHINE_ARCH: ::c_int = 10; ++pub const HW_ALIGNBYTES: ::c_int = 11; ++pub const HW_CNMAGIC: ::c_int = 12; ++pub const HW_PHYSMEM64: ::c_int = 13; ++pub const HW_USERMEM64: ::c_int = 14; ++pub const HW_IOSTATNAMES: ::c_int = 15; ++pub const HW_MAXID: ::c_int = 15; ++ ++pub const CTL_UNSPEC: ::c_int = 0; ++pub const CTL_KERN: ::c_int = 1; ++pub const CTL_VM: ::c_int = 2; ++pub const CTL_VFS: ::c_int = 3; ++pub const CTL_NET: ::c_int = 4; ++pub const CTL_DEBUG: ::c_int = 5; ++pub const CTL_HW: ::c_int = 6; ++pub const CTL_MACHDEP: ::c_int = 7; ++pub const CTL_USER: ::c_int = 8; ++pub const CTL_QNX: ::c_int = 9; ++pub const CTL_PROC: ::c_int = 10; ++pub const CTL_VENDOR: ::c_int = 11; ++pub const CTL_EMUL: ::c_int = 12; ++pub const CTL_SECURITY: ::c_int = 13; ++pub const CTL_MAXID: ::c_int = 14; ++ ++pub const DAY_1: ::nl_item = 8; ++pub const DAY_2: ::nl_item = 9; ++pub const DAY_3: ::nl_item = 10; ++pub const DAY_4: ::nl_item = 11; ++pub const DAY_5: ::nl_item = 12; ++pub const DAY_6: ::nl_item = 13; ++pub const DAY_7: ::nl_item = 14; ++ ++pub const MON_1: ::nl_item = 22; ++pub const MON_2: ::nl_item = 23; ++pub const MON_3: ::nl_item = 24; ++pub const MON_4: ::nl_item = 25; ++pub const MON_5: ::nl_item = 26; ++pub const MON_6: ::nl_item = 27; ++pub const MON_7: ::nl_item = 28; ++pub const MON_8: ::nl_item = 29; ++pub const MON_9: ::nl_item = 30; ++pub const MON_10: ::nl_item = 31; ++pub const MON_11: ::nl_item = 32; ++pub const MON_12: ::nl_item = 33; ++ ++pub const ABDAY_1: ::nl_item = 15; ++pub const ABDAY_2: ::nl_item = 16; ++pub const ABDAY_3: ::nl_item = 17; ++pub const ABDAY_4: ::nl_item = 18; ++pub const ABDAY_5: ::nl_item = 19; ++pub const ABDAY_6: ::nl_item = 20; ++pub const ABDAY_7: ::nl_item = 21; ++ ++pub const ABMON_1: ::nl_item = 34; ++pub const ABMON_2: ::nl_item = 35; ++pub const ABMON_3: ::nl_item = 36; ++pub const ABMON_4: ::nl_item = 37; ++pub const ABMON_5: ::nl_item = 38; ++pub const ABMON_6: ::nl_item = 39; ++pub const ABMON_7: ::nl_item = 40; ++pub const ABMON_8: ::nl_item = 41; ++pub const ABMON_9: ::nl_item = 42; ++pub const ABMON_10: ::nl_item = 43; ++pub const ABMON_11: ::nl_item = 44; ++pub const ABMON_12: ::nl_item = 45; ++ ++pub const AF_ARP: ::c_int = 28; ++pub const AF_CCITT: ::c_int = 10; ++pub const AF_CHAOS: ::c_int = 5; ++pub const AF_CNT: ::c_int = 21; ++pub const AF_COIP: ::c_int = 20; ++pub const AF_DATAKIT: ::c_int = 9; ++pub const AF_DECnet: ::c_int = 12; ++pub const AF_DLI: ::c_int = 13; ++pub const AF_E164: ::c_int = 26; ++pub const AF_ECMA: ::c_int = 8; ++pub const AF_HYLINK: ::c_int = 15; ++pub const AF_IEEE80211: ::c_int = 32; ++pub const AF_IMPLINK: ::c_int = 3; ++pub const AF_ISO: ::c_int = 7; ++pub const AF_LAT: ::c_int = 14; ++pub const AF_LINK: ::c_int = 18; ++pub const AF_NATM: ::c_int = 27; ++pub const AF_NS: ::c_int = 6; ++pub const AF_OSI: ::c_int = 7; ++pub const AF_PUP: ::c_int = 4; ++pub const ALT_DIGITS: ::nl_item = 50; ++pub const AM_STR: ::nl_item = 6; ++pub const B76800: ::speed_t = 76800; ++ ++pub const BIOCFLUSH: ::c_int = 17000; ++pub const BIOCGBLEN: ::c_int = 1074020966; ++pub const BIOCGDLT: ::c_int = 1074020970; ++pub const BIOCGDLTLIST: ::c_int = -1072676233; ++pub const BIOCGETIF: ::c_int = 1083196011; ++pub const BIOCGHDRCMPLT: ::c_int = 1074020980; ++pub const BIOCGRTIMEOUT: ::c_int = 1074807406; ++pub const BIOCGSEESENT: ::c_int = 1074020984; ++pub const BIOCGSTATS: ::c_int = 1082147439; ++pub const BIOCIMMEDIATE: ::c_int = -2147204496; ++pub const BIOCPROMISC: ::c_int = 17001; ++pub const BIOCSBLEN: ::c_int = -1073462682; ++pub const BIOCSDLT: ::c_int = -2147204490; ++pub const BIOCSETF: ::c_int = -2146418073; ++pub const BIOCSETIF: ::c_int = -2138029460; ++pub const BIOCSHDRCMPLT: ::c_int = -2147204491; ++pub const BIOCSRTIMEOUT: ::c_int = -2146418067; ++pub const BIOCSSEESENT: ::c_int = -2147204487; ++pub const BIOCVERSION: ::c_int = 1074020977; ++ ++pub const BPF_ALIGNMENT: usize = ::mem::size_of::<::c_long>(); ++pub const CHAR_BIT: usize = 8; ++pub const CODESET: ::nl_item = 1; ++pub const CRNCYSTR: ::nl_item = 55; ++ ++pub const D_FLAG_FILTER: ::c_int = 0x00000001; ++pub const D_FLAG_STAT: ::c_int = 0x00000002; ++pub const D_FLAG_STAT_FORM_MASK: ::c_int = 0x000000f0; ++pub const D_FLAG_STAT_FORM_T32_2001: ::c_int = 0x00000010; ++pub const D_FLAG_STAT_FORM_T32_2008: ::c_int = 0x00000020; ++pub const D_FLAG_STAT_FORM_T64_2008: ::c_int = 0x00000030; ++pub const D_FLAG_STAT_FORM_UNSET: ::c_int = 0x00000000; ++ ++pub const D_FMT: ::nl_item = 3; ++pub const D_GETFLAG: ::c_int = 1; ++pub const D_SETFLAG: ::c_int = 2; ++pub const D_T_FMT: ::nl_item = 2; ++pub const ERA: ::nl_item = 46; ++pub const ERA_D_FMT: ::nl_item = 47; ++pub const ERA_D_T_FMT: ::nl_item = 48; ++pub const ERA_T_FMT: ::nl_item = 49; ++pub const RADIXCHAR: ::nl_item = 51; ++pub const THOUSEP: ::nl_item = 52; ++pub const YESEXPR: ::nl_item = 53; ++pub const NOEXPR: ::nl_item = 54; ++pub const F_GETOWN: ::c_int = 35; ++ ++pub const FIONBIO: ::c_int = -2147195266; ++pub const FIOASYNC: ::c_int = -2147195267; ++pub const FIOCLEX: ::c_int = 26113; ++pub const FIOGETOWN: ::c_int = 1074030203; ++pub const FIONCLEX: ::c_int = 26114; ++pub const FIONREAD: ::c_int = 1074030207; ++pub const FIONSPACE: ::c_int = 1074030200; ++pub const FIONWRITE: ::c_int = 1074030201; ++pub const FIOSETOWN: ::c_int = -2147195268; ++ ++pub const F_SETOWN: ::c_int = 36; ++pub const IFF_ACCEPTRTADV: ::c_int = 0x40000000; ++pub const IFF_IP6FORWARDING: ::c_int = 0x20000000; ++pub const IFF_LINK0: ::c_int = 0x00001000; ++pub const IFF_LINK1: ::c_int = 0x00002000; ++pub const IFF_LINK2: ::c_int = 0x00004000; ++pub const IFF_OACTIVE: ::c_int = 0x00000400; ++pub const IFF_SHIM: ::c_int = 0x80000000; ++pub const IFF_SIMPLEX: ::c_int = 0x00000800; ++pub const IHFLOW: tcflag_t = 0x00000001; ++pub const IIDLE: tcflag_t = 0x00000008; ++pub const IP_RECVDSTADDR: ::c_int = 7; ++pub const IP_RECVIF: ::c_int = 20; ++pub const IPTOS_ECN_NOTECT: u8 = 0x00; ++pub const IUCLC: tcflag_t = 0x00000200; ++pub const IUTF8: tcflag_t = 0x0004000; ++ ++pub const KERN_ARGMAX: ::c_int = 8; ++pub const KERN_ARND: ::c_int = 81; ++pub const KERN_BOOTTIME: ::c_int = 21; ++pub const KERN_CLOCKRATE: ::c_int = 12; ++pub const KERN_FILE: ::c_int = 15; ++pub const KERN_HOSTID: ::c_int = 11; ++pub const KERN_HOSTNAME: ::c_int = 10; ++pub const KERN_IOV_MAX: ::c_int = 38; ++pub const KERN_JOB_CONTROL: ::c_int = 19; ++pub const KERN_LOGSIGEXIT: ::c_int = 46; ++pub const KERN_MAXFILES: ::c_int = 7; ++pub const KERN_MAXID: ::c_int = 83; ++pub const KERN_MAXPROC: ::c_int = 6; ++pub const KERN_MAXVNODES: ::c_int = 5; ++pub const KERN_NGROUPS: ::c_int = 18; ++pub const KERN_OSRELEASE: ::c_int = 2; ++pub const KERN_OSREV: ::c_int = 3; ++pub const KERN_OSTYPE: ::c_int = 1; ++pub const KERN_POSIX1: ::c_int = 17; ++pub const KERN_PROC: ::c_int = 14; ++pub const KERN_PROC_ALL: ::c_int = 0; ++pub const KERN_PROC_ARGS: ::c_int = 48; ++pub const KERN_PROC_ENV: ::c_int = 3; ++pub const KERN_PROC_GID: ::c_int = 7; ++pub const KERN_PROC_PGRP: ::c_int = 2; ++pub const KERN_PROC_PID: ::c_int = 1; ++pub const KERN_PROC_RGID: ::c_int = 8; ++pub const KERN_PROC_RUID: ::c_int = 6; ++pub const KERN_PROC_SESSION: ::c_int = 3; ++pub const KERN_PROC_TTY: ::c_int = 4; ++pub const KERN_PROC_UID: ::c_int = 5; ++pub const KERN_PROF: ::c_int = 16; ++pub const KERN_SAVED_IDS: ::c_int = 20; ++pub const KERN_SECURELVL: ::c_int = 9; ++pub const KERN_VERSION: ::c_int = 4; ++pub const KERN_VNODE: ::c_int = 13; ++ ++pub const LC_ALL: ::c_int = 63; ++pub const LC_COLLATE: ::c_int = 1; ++pub const LC_CTYPE: ::c_int = 2; ++pub const LC_MESSAGES: ::c_int = 32; ++pub const LC_MONETARY: ::c_int = 4; ++pub const LC_NUMERIC: ::c_int = 8; ++pub const LC_TIME: ::c_int = 16; ++ ++pub const LOCAL_CONNWAIT: ::c_int = 0x0002; ++pub const LOCAL_CREDS: ::c_int = 0x0001; ++pub const LOCAL_PEEREID: ::c_int = 0x0003; ++ ++pub const MAP_STACK: ::c_int = 0x00001000; ++pub const MNT_NOEXEC: ::c_int = 0x02; ++pub const MNT_NOSUID: ::c_int = 0x04; ++pub const MNT_RDONLY: ::c_int = 0x01; ++ ++pub const MSG_NOTIFICATION: ::c_int = 0x0400; ++ ++pub const NET_RT_DUMP: ::c_int = 1; ++pub const NET_RT_FLAGS: ::c_int = 2; ++pub const NET_RT_IFLIST: ::c_int = 4; ++pub const NI_NUMERICSCOPE: ::c_int = 0x00000040; ++pub const OHFLOW: tcflag_t = 0x00000002; ++pub const P_ALL: idtype_t = 0; ++pub const PARSTK: tcflag_t = 0x00000004; ++pub const PF_ARP: ::c_int = 28; ++pub const PF_CCITT: ::c_int = 10; ++pub const PF_CHAOS: ::c_int = 5; ++pub const PF_CNT: ::c_int = 21; ++pub const PF_COIP: ::c_int = 20; ++pub const PF_DATAKIT: ::c_int = 9; ++pub const PF_DECnet: ::c_int = 12; ++pub const PF_DLI: ::c_int = 13; ++pub const PF_ECMA: ::c_int = 8; ++pub const PF_HYLINK: ::c_int = 15; ++pub const PF_IMPLINK: ::c_int = 3; ++pub const PF_ISO: ::c_int = 7; ++pub const PF_LAT: ::c_int = 14; ++pub const PF_LINK: ::c_int = 18; ++pub const PF_NATM: ::c_int = 27; ++pub const PF_OSI: ::c_int = 7; ++pub const PF_PIP: ::c_int = 25; ++pub const PF_PUP: ::c_int = 4; ++pub const PF_RTIP: ::c_int = 22; ++pub const PF_XTP: ::c_int = 19; ++pub const PM_STR: ::nl_item = 7; ++pub const POSIX_MADV_DONTNEED: ::c_int = 4; ++pub const POSIX_MADV_NORMAL: ::c_int = 0; ++pub const POSIX_MADV_RANDOM: ::c_int = 2; ++pub const POSIX_MADV_SEQUENTIAL: ::c_int = 1; ++pub const POSIX_MADV_WILLNEED: ::c_int = 3; ++pub const _POSIX_VDISABLE: ::c_int = 0; ++pub const P_PGID: idtype_t = 2; ++pub const P_PID: idtype_t = 1; ++pub const PRIO_PGRP: ::c_int = 1; ++pub const PRIO_PROCESS: ::c_int = 0; ++pub const PRIO_USER: ::c_int = 2; ++pub const pseudo_AF_HDRCMPLT: ::c_int = 30; ++pub const pseudo_AF_PIP: ::c_int = 25; ++pub const pseudo_AF_RTIP: ::c_int = 22; ++pub const pseudo_AF_XTP: ::c_int = 19; ++pub const REG_ASSERT: ::c_int = 15; ++pub const REG_ATOI: ::c_int = 255; ++pub const REG_BACKR: ::c_int = 0x400; ++pub const REG_BASIC: ::c_int = 0x00; ++pub const REG_DUMP: ::c_int = 0x80; ++pub const REG_EMPTY: ::c_int = 14; ++pub const REG_INVARG: ::c_int = 16; ++pub const REG_ITOA: ::c_int = 0o400; ++pub const REG_LARGE: ::c_int = 0x200; ++pub const REG_NOSPEC: ::c_int = 0x10; ++pub const REG_OK: ::c_int = 0; ++pub const REG_PEND: ::c_int = 0x20; ++pub const REG_TRACE: ::c_int = 0x100; ++ ++pub const RLIMIT_AS: ::c_int = 6; ++pub const RLIMIT_CORE: ::c_int = 4; ++pub const RLIMIT_CPU: ::c_int = 0; ++pub const RLIMIT_DATA: ::c_int = 2; ++pub const RLIMIT_FSIZE: ::c_int = 1; ++pub const RLIMIT_MEMLOCK: ::c_int = 7; ++pub const RLIMIT_NOFILE: ::c_int = 5; ++pub const RLIMIT_NPROC: ::c_int = 8; ++pub const RLIMIT_RSS: ::c_int = 6; ++pub const RLIMIT_STACK: ::c_int = 3; ++pub const RLIMIT_VMEM: ::c_int = 6; ++pub const RLIM_NLIMITS: ::c_int = 14; ++ ++pub const SCHED_ADJTOHEAD: ::c_int = 5; ++pub const SCHED_ADJTOTAIL: ::c_int = 6; ++pub const SCHED_MAXPOLICY: ::c_int = 7; ++pub const SCHED_SETPRIO: ::c_int = 7; ++pub const SCHED_SPORADIC: ::c_int = 4; ++ ++pub const SHM_ANON: *mut ::c_char = -1isize as *mut ::c_char; ++pub const SIGCLD: ::c_int = SIGCHLD; ++pub const SIGDEADLK: ::c_int = 7; ++pub const SIGEMT: ::c_int = 7; ++pub const SIGEV_NONE: ::c_int = 0; ++pub const SIGEV_SIGNAL: ::c_int = 129; ++pub const SIGEV_THREAD: ::c_int = 135; ++pub const SIOCGIFADDR: ::c_int = -1064277727; ++pub const SO_FIB: ::c_int = 0x100a; ++pub const SO_OVERFLOWED: ::c_int = 0x1009; ++pub const SO_SETFIB: ::c_int = 0x100a; ++pub const SO_TXPRIO: ::c_int = 0x100b; ++pub const SO_USELOOPBACK: ::c_int = 0x0040; ++pub const SO_VLANPRIO: ::c_int = 0x100c; ++pub const _SS_ALIGNSIZE: usize = ::mem::size_of::(); ++pub const _SS_MAXSIZE: usize = 128; ++pub const _SS_PAD1SIZE: usize = _SS_ALIGNSIZE - 2; ++pub const _SS_PAD2SIZE: usize = _SS_MAXSIZE - 2 - _SS_PAD1SIZE - _SS_ALIGNSIZE; ++pub const TC_CPOSIX: tcflag_t = CLOCAL | CREAD | CSIZE | CSTOPB | HUPCL | PARENB | PARODD; ++pub const TCGETS: ::c_int = 0x404c540d; ++pub const TC_IPOSIX: tcflag_t = ++ BRKINT | ICRNL | IGNBRK | IGNPAR | INLCR | INPCK | ISTRIP | IXOFF | IXON | PARMRK; ++pub const TC_LPOSIX: tcflag_t = ++ ECHO | ECHOE | ECHOK | ECHONL | ICANON | IEXTEN | ISIG | NOFLSH | TOSTOP; ++pub const TC_OPOSIX: tcflag_t = OPOST; ++pub const T_FMT_AMPM: ::nl_item = 5; ++ ++pub const TIOCCBRK: ::c_int = 29818; ++pub const TIOCCDTR: ::c_int = 29816; ++pub const TIOCDRAIN: ::c_int = 29790; ++pub const TIOCEXCL: ::c_int = 29709; ++pub const TIOCFLUSH: ::c_int = -2147191792; ++pub const TIOCGETA: ::c_int = 1078752275; ++pub const TIOCGPGRP: ::c_int = 1074033783; ++pub const TIOCGWINSZ: ::c_int = 1074295912; ++pub const TIOCMBIC: ::c_int = -2147191701; ++pub const TIOCMBIS: ::c_int = -2147191700; ++pub const TIOCMGET: ::c_int = 1074033770; ++pub const TIOCMSET: ::c_int = -2147191699; ++pub const TIOCNOTTY: ::c_int = 29809; ++pub const TIOCNXCL: ::c_int = 29710; ++pub const TIOCOUTQ: ::c_int = 1074033779; ++pub const TIOCPKT: ::c_int = -2147191696; ++pub const TIOCPKT_DATA: ::c_int = 0x00; ++pub const TIOCPKT_DOSTOP: ::c_int = 0x20; ++pub const TIOCPKT_FLUSHREAD: ::c_int = 0x01; ++pub const TIOCPKT_FLUSHWRITE: ::c_int = 0x02; ++pub const TIOCPKT_IOCTL: ::c_int = 0x40; ++pub const TIOCPKT_NOSTOP: ::c_int = 0x10; ++pub const TIOCPKT_START: ::c_int = 0x08; ++pub const TIOCPKT_STOP: ::c_int = 0x04; ++pub const TIOCSBRK: ::c_int = 29819; ++pub const TIOCSCTTY: ::c_int = 29793; ++pub const TIOCSDTR: ::c_int = 29817; ++pub const TIOCSETA: ::c_int = -2142473196; ++pub const TIOCSETAF: ::c_int = -2142473194; ++pub const TIOCSETAW: ::c_int = -2142473195; ++pub const TIOCSPGRP: ::c_int = -2147191690; ++pub const TIOCSTART: ::c_int = 29806; ++pub const TIOCSTI: ::c_int = -2147388302; ++pub const TIOCSTOP: ::c_int = 29807; ++pub const TIOCSWINSZ: ::c_int = -2146929561; ++ ++pub const USER_CS_PATH: ::c_int = 1; ++pub const USER_BC_BASE_MAX: ::c_int = 2; ++pub const USER_BC_DIM_MAX: ::c_int = 3; ++pub const USER_BC_SCALE_MAX: ::c_int = 4; ++pub const USER_BC_STRING_MAX: ::c_int = 5; ++pub const USER_COLL_WEIGHTS_MAX: ::c_int = 6; ++pub const USER_EXPR_NEST_MAX: ::c_int = 7; ++pub const USER_LINE_MAX: ::c_int = 8; ++pub const USER_RE_DUP_MAX: ::c_int = 9; ++pub const USER_POSIX2_VERSION: ::c_int = 10; ++pub const USER_POSIX2_C_BIND: ::c_int = 11; ++pub const USER_POSIX2_C_DEV: ::c_int = 12; ++pub const USER_POSIX2_CHAR_TERM: ::c_int = 13; ++pub const USER_POSIX2_FORT_DEV: ::c_int = 14; ++pub const USER_POSIX2_FORT_RUN: ::c_int = 15; ++pub const USER_POSIX2_LOCALEDEF: ::c_int = 16; ++pub const USER_POSIX2_SW_DEV: ::c_int = 17; ++pub const USER_POSIX2_UPE: ::c_int = 18; ++pub const USER_STREAM_MAX: ::c_int = 19; ++pub const USER_TZNAME_MAX: ::c_int = 20; ++pub const USER_ATEXIT_MAX: ::c_int = 21; ++pub const USER_MAXID: ::c_int = 22; ++ ++pub const VDOWN: usize = 31; ++pub const VINS: usize = 32; ++pub const VDEL: usize = 33; ++pub const VRUB: usize = 34; ++pub const VCAN: usize = 35; ++pub const VHOME: usize = 36; ++pub const VEND: usize = 37; ++pub const VSPARE3: usize = 38; ++pub const VSPARE4: usize = 39; ++pub const VSWTCH: usize = 7; ++pub const VDSUSP: usize = 11; ++pub const VFWD: usize = 18; ++pub const VLOGIN: usize = 19; ++pub const VPREFIX: usize = 20; ++pub const VSUFFIX: usize = 24; ++pub const VLEFT: usize = 28; ++pub const VRIGHT: usize = 29; ++pub const VUP: usize = 30; ++pub const XCASE: tcflag_t = 0x00000004; ++ ++pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0x00; ++pub const PTHREAD_CREATE_DETACHED: ::c_int = 0x01; ++ ++pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 1; ++pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 2; ++pub const PTHREAD_MUTEX_NORMAL: ::c_int = 3; ++pub const PTHREAD_STACK_MIN: ::size_t = 256; ++pub const PTHREAD_MUTEX_DEFAULT: ::c_int = 0; ++pub const PTHREAD_MUTEX_STALLED: ::c_int = 0x00; ++pub const PTHREAD_MUTEX_ROBUST: ::c_int = 0x10; ++pub const PTHREAD_PROCESS_PRIVATE: ::c_int = 0x00; ++pub const PTHREAD_PROCESS_SHARED: ::c_int = 0x01; ++ ++pub const PTHREAD_KEYS_MAX: usize = 128; ++ ++pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { ++ __u: 0x80000000, ++ __owner: 0xffffffff, ++}; ++pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { ++ __u: CLOCK_REALTIME as u32, ++ __owner: 0xfffffffb, ++}; ++pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { ++ __active: 0, ++ __blockedwriters: 0, ++ __blockedreaders: 0, ++ __heavy: 0, ++ __lock: PTHREAD_MUTEX_INITIALIZER, ++ __rcond: PTHREAD_COND_INITIALIZER, ++ __wcond: PTHREAD_COND_INITIALIZER, ++ __owner: -2i32 as ::c_uint, ++ __spare: 0, ++}; ++ ++const_fn! { ++ {const} fn _CMSG_ALIGN(len: usize) -> usize { ++ len + ::mem::size_of::() - 1 & !(::mem::size_of::() - 1) ++ } ++ ++ {const} fn _ALIGN(p: usize, b: usize) -> usize { ++ (p + b - 1) & !(b-1) ++ } ++} ++ ++f! { ++ pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { ++ if (*mhdr).msg_controllen as usize >= ::mem::size_of::() { ++ (*mhdr).msg_control as *mut cmsghdr ++ } else { ++ 0 as *mut cmsghdr ++ } ++ } ++ ++ pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) ++ -> *mut ::cmsghdr ++ { ++ let msg = _CMSG_ALIGN((*cmsg).cmsg_len as usize); ++ let next = cmsg as usize + msg + _CMSG_ALIGN(::mem::size_of::<::cmsghdr>()); ++ if next > (*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize { ++ 0 as *mut ::cmsghdr ++ } else { ++ (cmsg as usize + msg) as *mut ::cmsghdr ++ } ++ } ++ ++ pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { ++ (cmsg as *mut ::c_uchar) ++ .offset(_CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) as isize) ++ } ++ ++ pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint { ++ _CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length ++ } ++ ++ pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { ++ (_CMSG_ALIGN(::mem::size_of::()) + _CMSG_ALIGN(length as usize) ) ++ as ::c_uint ++ } ++ ++ pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { ++ let fd = fd as usize; ++ let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; ++ (*set).fds_bits[fd / size] &= !(1 << (fd % size)); ++ return ++ } ++ ++ pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { ++ let fd = fd as usize; ++ let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; ++ return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0 ++ } ++ ++ pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { ++ let fd = fd as usize; ++ let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; ++ (*set).fds_bits[fd / size] |= 1 << (fd % size); ++ return ++ } ++ ++ pub fn FD_ZERO(set: *mut fd_set) -> () { ++ for slot in (*set).fds_bits.iter_mut() { ++ *slot = 0; ++ } ++ } ++ ++ pub fn _DEXTRA_FIRST(_d: *const dirent) -> *mut ::dirent_extra { ++ let _f = &((*(_d)).d_name) as *const _; ++ let _s = _d as usize; ++ ++ _ALIGN(_s + _f as usize - _s + (*_d).d_namelen as usize + 1, 8) as *mut ::dirent_extra ++ } ++ ++ pub fn _DEXTRA_VALID(_x: *const ::dirent_extra, _d: *const dirent) -> bool { ++ let sz = _x as usize - _d as usize + ::mem::size_of::<::dirent_extra>(); ++ let rsz = (*_d).d_reclen as usize; ++ ++ if sz > rsz || sz + (*_x).d_datalen as usize > rsz { ++ false ++ } else { ++ true ++ } ++ } ++ ++ pub fn _DEXTRA_NEXT(_x: *const ::dirent_extra) -> *mut ::dirent_extra { ++ _ALIGN( ++ _x as usize + ::mem::size_of::<::dirent_extra>() + (*_x).d_datalen as usize, 8 ++ ) as *mut ::dirent_extra ++ } ++ ++ pub fn SOCKCREDSIZE(ngrps: usize) -> usize { ++ let ngrps = if ngrps > 0 { ++ ngrps - 1 ++ } else { ++ 0 ++ }; ++ ::mem::size_of::() + ::mem::size_of::<::gid_t>() * ngrps ++ } ++} ++ ++safe_f! { ++ pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { ++ (status & 0xff) == 0x7f ++ } ++ ++ pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { ++ (status >> 8) & 0xff ++ } ++ ++ pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { ++ status == 0xffff ++ } ++ ++ pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { ++ ((status & 0x7f) + 1) as i8 >= 2 ++ } ++ ++ pub {const} fn WTERMSIG(status: ::c_int) -> ::c_int { ++ status & 0x7f ++ } ++ ++ pub {const} fn WIFEXITED(status: ::c_int) -> bool { ++ (status & 0x7f) == 0 ++ } ++ ++ pub {const} fn WEXITSTATUS(status: ::c_int) -> ::c_int { ++ (status >> 8) & 0xff ++ } ++ ++ pub {const} fn WCOREDUMP(status: ::c_int) -> bool { ++ (status & 0x80) != 0 ++ } ++ ++ pub {const} fn IPTOS_ECN(x: u8) -> u8 { ++ x & ::IPTOS_ECN_MASK ++ } ++} ++ ++// Network related functions are provided by libsocket and regex ++// functions are provided by libregex. ++#[link(name = "socket")] ++#[link(name = "regex")] ++ ++extern "C" { ++ pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; ++ pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; ++ pub fn fdatasync(fd: ::c_int) -> ::c_int; ++ pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int; ++ pub fn setpriority(which: ::c_int, who: ::id_t, prio: ::c_int) -> ::c_int; ++ pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; ++ ++ pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; ++ pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; ++ pub fn clock_settime(clk_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; ++ pub fn clock_getcpuclockid(pid: ::pid_t, clk_id: *mut ::clockid_t) -> ::c_int; ++ ++ pub fn pthread_attr_getstack( ++ attr: *const ::pthread_attr_t, ++ stackaddr: *mut *mut ::c_void, ++ stacksize: *mut ::size_t, ++ ) -> ::c_int; ++ pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; ++ pub fn setgroups(ngroups: ::c_int, ptr: *const ::gid_t) -> ::c_int; ++ ++ pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, advise: ::c_int) -> ::c_int; ++ pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; ++ pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; ++ ++ pub fn utimensat( ++ dirfd: ::c_int, ++ path: *const ::c_char, ++ times: *const ::timespec, ++ flag: ::c_int, ++ ) -> ::c_int; ++ ++ pub fn pthread_condattr_getclock( ++ attr: *const pthread_condattr_t, ++ clock_id: *mut clockid_t, ++ ) -> ::c_int; ++ pub fn pthread_condattr_setclock( ++ attr: *mut pthread_condattr_t, ++ clock_id: ::clockid_t, ++ ) -> ::c_int; ++ pub fn pthread_condattr_setpshared(attr: *mut pthread_condattr_t, pshared: ::c_int) -> ::c_int; ++ pub fn pthread_mutexattr_setpshared( ++ attr: *mut pthread_mutexattr_t, ++ pshared: ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_rwlockattr_getpshared( ++ attr: *const pthread_rwlockattr_t, ++ val: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_rwlockattr_setpshared(attr: *mut pthread_rwlockattr_t, val: ::c_int) -> ::c_int; ++ pub fn ptsname_r(fd: ::c_int, buf: *mut ::c_char, buflen: ::size_t) -> *mut ::c_char; ++ pub fn clearenv() -> ::c_int; ++ pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t, options: ::c_int) ++ -> ::c_int; ++ pub fn wait4( ++ pid: ::pid_t, ++ status: *mut ::c_int, ++ options: ::c_int, ++ rusage: *mut ::rusage, ++ ) -> ::pid_t; ++ pub fn execvpe( ++ file: *const ::c_char, ++ argv: *const *const ::c_char, ++ envp: *const *const ::c_char, ++ ) -> ::c_int; ++ ++ pub fn getifaddrs(ifap: *mut *mut ::ifaddrs) -> ::c_int; ++ pub fn freeifaddrs(ifa: *mut ::ifaddrs); ++ pub fn bind(socket: ::c_int, address: *const ::sockaddr, address_len: ::socklen_t) -> ::c_int; ++ ++ pub fn writev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; ++ pub fn readv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; ++ ++ pub fn sendmsg(fd: ::c_int, msg: *const ::msghdr, flags: ::c_int) -> ::ssize_t; ++ pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; ++ pub fn openpty( ++ amaster: *mut ::c_int, ++ aslave: *mut ::c_int, ++ name: *mut ::c_char, ++ termp: *mut termios, ++ winp: *mut ::winsize, ++ ) -> ::c_int; ++ pub fn forkpty( ++ amaster: *mut ::c_int, ++ name: *mut ::c_char, ++ termp: *mut termios, ++ winp: *mut ::winsize, ++ ) -> ::pid_t; ++ pub fn login_tty(fd: ::c_int) -> ::c_int; ++ ++ pub fn uname(buf: *mut ::utsname) -> ::c_int; ++ ++ pub fn getpeereid(socket: ::c_int, euid: *mut ::uid_t, egid: *mut ::gid_t) -> ::c_int; ++ ++ pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; ++ ++ pub fn abs(i: ::c_int) -> ::c_int; ++ pub fn labs(i: ::c_long) -> ::c_long; ++ pub fn rand() -> ::c_int; ++ pub fn srand(seed: ::c_uint); ++ ++ pub fn setpwent(); ++ pub fn endpwent(); ++ pub fn getpwent() -> *mut passwd; ++ pub fn setgrent(); ++ pub fn endgrent(); ++ pub fn getgrent() -> *mut ::group; ++ pub fn setspent(); ++ pub fn endspent(); ++ ++ pub fn shm_open(name: *const c_char, oflag: ::c_int, mode: mode_t) -> ::c_int; ++ ++ pub fn ftok(pathname: *const ::c_char, proj_id: ::c_int) -> ::key_t; ++ pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; ++ ++ pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; ++ pub fn mkostemp(template: *mut ::c_char, flags: ::c_int) -> ::c_int; ++ pub fn mkostemps(template: *mut ::c_char, suffixlen: ::c_int, flags: ::c_int) -> ::c_int; ++ pub fn sigtimedwait( ++ set: *const sigset_t, ++ info: *mut siginfo_t, ++ timeout: *const ::timespec, ++ ) -> ::c_int; ++ pub fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> ::c_int; ++ pub fn pthread_setschedprio(native: ::pthread_t, priority: ::c_int) -> ::c_int; ++ ++ pub fn if_nameindex() -> *mut if_nameindex; ++ pub fn if_freenameindex(ptr: *mut if_nameindex); ++ ++ pub fn glob( ++ pattern: *const c_char, ++ flags: ::c_int, ++ errfunc: ::Option ::c_int>, ++ pglob: *mut ::glob_t, ++ ) -> ::c_int; ++ pub fn globfree(pglob: *mut ::glob_t); ++ ++ pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; ++ ++ pub fn shm_unlink(name: *const ::c_char) -> ::c_int; ++ ++ pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); ++ ++ pub fn telldir(dirp: *mut ::DIR) -> ::c_long; ++ ++ pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; ++ ++ pub fn recvfrom( ++ socket: ::c_int, ++ buf: *mut ::c_void, ++ len: ::size_t, ++ flags: ::c_int, ++ addr: *mut ::sockaddr, ++ addrlen: *mut ::socklen_t, ++ ) -> ::ssize_t; ++ pub fn mkstemps(template: *mut ::c_char, suffixlen: ::c_int) -> ::c_int; ++ ++ pub fn getdomainname(name: *mut ::c_char, len: ::size_t) -> ::c_int; ++ pub fn setdomainname(name: *const ::c_char, len: ::size_t) -> ::c_int; ++ pub fn sync(); ++ pub fn pthread_getschedparam( ++ native: ::pthread_t, ++ policy: *mut ::c_int, ++ param: *mut ::sched_param, ++ ) -> ::c_int; ++ pub fn umount(target: *const ::c_char, flags: ::c_int) -> ::c_int; ++ pub fn sched_get_priority_max(policy: ::c_int) -> ::c_int; ++ pub fn settimeofday(tv: *const ::timeval, tz: *const ::c_void) -> ::c_int; ++ pub fn sched_rr_get_interval(pid: ::pid_t, tp: *mut ::timespec) -> ::c_int; ++ pub fn sem_timedwait(sem: *mut sem_t, abstime: *const ::timespec) -> ::c_int; ++ pub fn sem_getvalue(sem: *mut sem_t, sval: *mut ::c_int) -> ::c_int; ++ pub fn sched_setparam(pid: ::pid_t, param: *const ::sched_param) -> ::c_int; ++ pub fn mount( ++ special_device: *const ::c_char, ++ mount_directory: *const ::c_char, ++ flags: ::c_int, ++ mount_type: *const ::c_char, ++ mount_data: *const ::c_void, ++ mount_datalen: ::c_int, ++ ) -> ::c_int; ++ pub fn sched_getparam(pid: ::pid_t, param: *mut ::sched_param) -> ::c_int; ++ pub fn pthread_mutex_consistent(mutex: *mut pthread_mutex_t) -> ::c_int; ++ pub fn pthread_mutex_timedlock( ++ lock: *mut pthread_mutex_t, ++ abstime: *const ::timespec, ++ ) -> ::c_int; ++ pub fn pthread_spin_init(lock: *mut ::pthread_spinlock_t, pshared: ::c_int) -> ::c_int; ++ pub fn pthread_spin_destroy(lock: *mut ::pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_lock(lock: *mut ::pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_trylock(lock: *mut ::pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_spin_unlock(lock: *mut ::pthread_spinlock_t) -> ::c_int; ++ pub fn pthread_barrierattr_init(__attr: *mut ::pthread_barrierattr_t) -> ::c_int; ++ pub fn pthread_barrierattr_destroy(__attr: *mut ::pthread_barrierattr_t) -> ::c_int; ++ pub fn pthread_barrierattr_getpshared( ++ __attr: *const ::pthread_barrierattr_t, ++ __pshared: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_barrierattr_setpshared( ++ __attr: *mut ::pthread_barrierattr_t, ++ __pshared: ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_barrier_init( ++ __barrier: *mut ::pthread_barrier_t, ++ __attr: *const ::pthread_barrierattr_t, ++ __count: ::c_uint, ++ ) -> ::c_int; ++ pub fn pthread_barrier_destroy(__barrier: *mut ::pthread_barrier_t) -> ::c_int; ++ pub fn pthread_barrier_wait(__barrier: *mut ::pthread_barrier_t) -> ::c_int; ++ ++ pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int; ++ pub fn clock_nanosleep( ++ clk_id: ::clockid_t, ++ flags: ::c_int, ++ rqtp: *const ::timespec, ++ rmtp: *mut ::timespec, ++ ) -> ::c_int; ++ pub fn pthread_attr_getguardsize( ++ attr: *const ::pthread_attr_t, ++ guardsize: *mut ::size_t, ++ ) -> ::c_int; ++ pub fn sethostname(name: *const ::c_char, len: ::size_t) -> ::c_int; ++ pub fn sched_get_priority_min(policy: ::c_int) -> ::c_int; ++ pub fn pthread_condattr_getpshared( ++ attr: *const pthread_condattr_t, ++ pshared: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_setschedparam( ++ native: ::pthread_t, ++ policy: ::c_int, ++ param: *const ::sched_param, ++ ) -> ::c_int; ++ pub fn sched_setscheduler( ++ pid: ::pid_t, ++ policy: ::c_int, ++ param: *const ::sched_param, ++ ) -> ::c_int; ++ pub fn sigsuspend(mask: *const ::sigset_t) -> ::c_int; ++ pub fn getgrgid_r( ++ gid: ::gid_t, ++ grp: *mut ::group, ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ result: *mut *mut ::group, ++ ) -> ::c_int; ++ pub fn sem_close(sem: *mut sem_t) -> ::c_int; ++ pub fn getdtablesize() -> ::c_int; ++ pub fn getgrnam_r( ++ name: *const ::c_char, ++ grp: *mut ::group, ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ result: *mut *mut ::group, ++ ) -> ::c_int; ++ pub fn initgroups(user: *const ::c_char, group: ::gid_t) -> ::c_int; ++ pub fn pthread_sigmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; ++ pub fn sem_open(name: *const ::c_char, oflag: ::c_int, ...) -> *mut sem_t; ++ pub fn getgrnam(name: *const ::c_char) -> *mut ::group; ++ pub fn pthread_cancel(thread: ::pthread_t) -> ::c_int; ++ pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; ++ pub fn sem_unlink(name: *const ::c_char) -> ::c_int; ++ pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; ++ pub fn getpwnam_r( ++ name: *const ::c_char, ++ pwd: *mut passwd, ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ result: *mut *mut passwd, ++ ) -> ::c_int; ++ pub fn getpwuid_r( ++ uid: ::uid_t, ++ pwd: *mut passwd, ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ result: *mut *mut passwd, ++ ) -> ::c_int; ++ pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; ++ pub fn pthread_atfork( ++ prepare: ::Option, ++ parent: ::Option, ++ child: ::Option, ++ ) -> ::c_int; ++ pub fn getgrgid(gid: ::gid_t) -> *mut ::group; ++ pub fn getgrouplist( ++ user: *const ::c_char, ++ group: ::gid_t, ++ groups: *mut ::gid_t, ++ ngroups: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_mutexattr_getpshared( ++ attr: *const pthread_mutexattr_t, ++ pshared: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_mutexattr_getrobust( ++ attr: *const pthread_mutexattr_t, ++ robustness: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_mutexattr_setrobust( ++ attr: *mut pthread_mutexattr_t, ++ robustness: ::c_int, ++ ) -> ::c_int; ++ pub fn pthread_create( ++ native: *mut ::pthread_t, ++ attr: *const ::pthread_attr_t, ++ f: extern "C" fn(*mut ::c_void) -> *mut ::c_void, ++ value: *mut ::c_void, ++ ) -> ::c_int; ++ pub fn getitimer(which: ::c_int, curr_value: *mut ::itimerval) -> ::c_int; ++ pub fn setitimer( ++ which: ::c_int, ++ value: *const ::itimerval, ++ ovalue: *mut ::itimerval, ++ ) -> ::c_int; ++ pub fn posix_spawn( ++ pid: *mut ::pid_t, ++ path: *const ::c_char, ++ file_actions: *const ::posix_spawn_file_actions_t, ++ attrp: *const ::posix_spawnattr_t, ++ argv: *const *mut ::c_char, ++ envp: *const *mut ::c_char, ++ ) -> ::c_int; ++ pub fn posix_spawnp( ++ pid: *mut ::pid_t, ++ file: *const ::c_char, ++ file_actions: *const ::posix_spawn_file_actions_t, ++ attrp: *const ::posix_spawnattr_t, ++ argv: *const *mut ::c_char, ++ envp: *const *mut ::c_char, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_init(attr: *mut posix_spawnattr_t) -> ::c_int; ++ pub fn posix_spawnattr_destroy(attr: *mut posix_spawnattr_t) -> ::c_int; ++ pub fn posix_spawnattr_getsigdefault( ++ attr: *const posix_spawnattr_t, ++ default: *mut ::sigset_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setsigdefault( ++ attr: *mut posix_spawnattr_t, ++ default: *const ::sigset_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_getsigmask( ++ attr: *const posix_spawnattr_t, ++ default: *mut ::sigset_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setsigmask( ++ attr: *mut posix_spawnattr_t, ++ default: *const ::sigset_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_getflags( ++ attr: *const posix_spawnattr_t, ++ flags: *mut ::c_short, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setflags(attr: *mut posix_spawnattr_t, flags: ::c_short) -> ::c_int; ++ pub fn posix_spawnattr_getpgroup( ++ attr: *const posix_spawnattr_t, ++ flags: *mut ::pid_t, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: ::pid_t) -> ::c_int; ++ pub fn posix_spawnattr_getschedpolicy( ++ attr: *const posix_spawnattr_t, ++ flags: *mut ::c_int, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setschedpolicy(attr: *mut posix_spawnattr_t, flags: ::c_int) -> ::c_int; ++ pub fn posix_spawnattr_getschedparam( ++ attr: *const posix_spawnattr_t, ++ param: *mut ::sched_param, ++ ) -> ::c_int; ++ pub fn posix_spawnattr_setschedparam( ++ attr: *mut posix_spawnattr_t, ++ param: *const ::sched_param, ++ ) -> ::c_int; ++ ++ pub fn posix_spawn_file_actions_init(actions: *mut posix_spawn_file_actions_t) -> ::c_int; ++ pub fn posix_spawn_file_actions_destroy(actions: *mut posix_spawn_file_actions_t) -> ::c_int; ++ pub fn posix_spawn_file_actions_addopen( ++ actions: *mut posix_spawn_file_actions_t, ++ fd: ::c_int, ++ path: *const ::c_char, ++ oflag: ::c_int, ++ mode: ::mode_t, ++ ) -> ::c_int; ++ pub fn posix_spawn_file_actions_addclose( ++ actions: *mut posix_spawn_file_actions_t, ++ fd: ::c_int, ++ ) -> ::c_int; ++ pub fn posix_spawn_file_actions_adddup2( ++ actions: *mut posix_spawn_file_actions_t, ++ fd: ::c_int, ++ newfd: ::c_int, ++ ) -> ::c_int; ++ pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; ++ pub fn faccessat( ++ dirfd: ::c_int, ++ pathname: *const ::c_char, ++ mode: ::c_int, ++ flags: ::c_int, ++ ) -> ::c_int; ++ pub fn inotify_rm_watch(fd: ::c_int, wd: ::c_int) -> ::c_int; ++ pub fn inotify_init() -> ::c_int; ++ pub fn inotify_add_watch(fd: ::c_int, path: *const ::c_char, mask: u32) -> ::c_int; ++ ++ pub fn gettid() -> ::pid_t; ++ ++ pub fn pthread_getcpuclockid(thread: ::pthread_t, clk_id: *mut ::clockid_t) -> ::c_int; ++ ++ pub fn getnameinfo( ++ sa: *const ::sockaddr, ++ salen: ::socklen_t, ++ host: *mut ::c_char, ++ hostlen: ::socklen_t, ++ serv: *mut ::c_char, ++ sevlen: ::socklen_t, ++ flags: ::c_int, ++ ) -> ::c_int; ++ ++ pub fn sendmmsg( ++ sockfd: ::c_int, ++ msgvec: *mut ::mmsghdr, ++ vlen: ::c_uint, ++ flags: ::c_uint, ++ ) -> ::c_int; ++ pub fn recvmmsg( ++ sockfd: ::c_int, ++ msgvec: *mut ::mmsghdr, ++ vlen: ::c_uint, ++ flags: ::c_uint, ++ timeout: *mut ::timespec, ++ ) -> ::c_int; ++ ++ pub fn mallopt(param: ::c_int, value: i64) -> ::c_int; ++ pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; ++ ++ pub fn ctermid(s: *mut ::c_char) -> *mut ::c_char; ++ pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; ++ ++ pub fn mallinfo() -> ::mallinfo; ++ pub fn getpwent_r( ++ pwd: *mut ::passwd, ++ buf: *mut ::c_char, ++ __bufsize: ::c_int, ++ __result: *mut *mut ::passwd, ++ ) -> ::c_int; ++ pub fn pthread_getname_np(thread: ::pthread_t, name: *mut ::c_char, len: ::c_int) -> ::c_int; ++ pub fn pthread_setname_np(thread: ::pthread_t, name: *const ::c_char) -> ::c_int; ++ ++ pub fn sysctl( ++ _: *const ::c_int, ++ _: ::c_uint, ++ _: *mut ::c_void, ++ _: *mut ::size_t, ++ _: *const ::c_void, ++ _: ::size_t, ++ ) -> ::c_int; ++ ++ pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; ++ pub fn setrlimit(resource: ::c_int, rlp: *const ::rlimit) -> ::c_int; ++ ++ pub fn lio_listio( ++ __mode: ::c_int, ++ __list: *const *mut aiocb, ++ __nent: ::c_int, ++ __sig: *mut sigevent, ++ ) -> ::c_int; ++ ++ pub fn dl_iterate_phdr( ++ callback: ::Option< ++ unsafe extern "C" fn( ++ info: *const dl_phdr_info, ++ size: ::size_t, ++ data: *mut ::c_void, ++ ) -> ::c_int, ++ >, ++ data: *mut ::c_void, ++ ) -> ::c_int; ++ ++ pub fn memset_s(s: *mut ::c_void, smax: ::size_t, c: ::c_int, n: ::size_t) -> ::c_int; ++ ++ pub fn regcomp( ++ __preg: *mut ::regex_t, ++ __pattern: *const ::c_char, ++ __cflags: ::c_int, ++ ) -> ::c_int; ++ pub fn regexec( ++ __preg: *const ::regex_t, ++ __str: *const ::c_char, ++ __nmatch: ::size_t, ++ __pmatch: *mut ::regmatch_t, ++ __eflags: ::c_int, ++ ) -> ::c_int; ++ pub fn regerror( ++ __errcode: ::c_int, ++ __preg: *const ::regex_t, ++ __errbuf: *mut ::c_char, ++ __errbuf_size: ::size_t, ++ ) -> ::size_t; ++ pub fn regfree(__preg: *mut ::regex_t); ++ pub fn dirfd(__dirp: *mut ::DIR) -> ::c_int; ++ pub fn dircntl(dir: *mut ::DIR, cmd: ::c_int, ...) -> ::c_int; ++ ++ pub fn aio_cancel(__fd: ::c_int, __aiocbp: *mut ::aiocb) -> ::c_int; ++ pub fn aio_error(__aiocbp: *const ::aiocb) -> ::c_int; ++ pub fn aio_fsync(__operation: ::c_int, __aiocbp: *mut ::aiocb) -> ::c_int; ++ pub fn aio_read(__aiocbp: *mut ::aiocb) -> ::c_int; ++ pub fn aio_return(__aiocpb: *mut ::aiocb) -> ::ssize_t; ++ pub fn aio_suspend( ++ __list: *const *const ::aiocb, ++ __nent: ::c_int, ++ __timeout: *const ::timespec, ++ ) -> ::c_int; ++ pub fn aio_write(__aiocpb: *mut ::aiocb) -> ::c_int; ++ ++ pub fn mq_close(__mqdes: ::mqd_t) -> ::c_int; ++ pub fn mq_getattr(__mqdes: ::mqd_t, __mqstat: *mut ::mq_attr) -> ::c_int; ++ pub fn mq_notify(__mqdes: ::mqd_t, __notification: *const ::sigevent) -> ::c_int; ++ pub fn mq_open(__name: *const ::c_char, __oflag: ::c_int, ...) -> ::mqd_t; ++ pub fn mq_receive( ++ __mqdes: ::mqd_t, ++ __msg_ptr: *mut ::c_char, ++ __msg_len: ::size_t, ++ __msg_prio: *mut ::c_uint, ++ ) -> ::ssize_t; ++ pub fn mq_send( ++ __mqdes: ::mqd_t, ++ __msg_ptr: *const ::c_char, ++ __msg_len: ::size_t, ++ __msg_prio: ::c_uint, ++ ) -> ::c_int; ++ pub fn mq_setattr( ++ __mqdes: ::mqd_t, ++ __mqstat: *const mq_attr, ++ __omqstat: *mut mq_attr, ++ ) -> ::c_int; ++ pub fn mq_timedreceive( ++ __mqdes: ::mqd_t, ++ __msg_ptr: *mut ::c_char, ++ __msg_len: ::size_t, ++ __msg_prio: *mut ::c_uint, ++ __abs_timeout: *const ::timespec, ++ ) -> ::ssize_t; ++ pub fn mq_timedsend( ++ __mqdes: ::mqd_t, ++ __msg_ptr: *const ::c_char, ++ __msg_len: ::size_t, ++ __msg_prio: ::c_uint, ++ __abs_timeout: *const ::timespec, ++ ) -> ::c_int; ++ pub fn mq_unlink(__name: *const ::c_char) -> ::c_int; ++ pub fn __get_errno_ptr() -> *mut ::c_int; ++ ++ // System page, see https://www.qnx.com/developers/docs/7.1#com.qnx.doc.neutrino.building/topic/syspage/syspage_about.html ++ pub static mut _syspage_ptr: *mut syspage_entry; ++ ++ // Function on the stack after a call to pthread_create(). This is used ++ // as a sentinel to work around an infitnite loop in the unwinding code. ++ pub fn __my_thread_exit(value_ptr: *mut *const ::c_void); ++} ++ ++// Models the implementation in stdlib.h. Ctest will fail if trying to use the ++// default symbol from libc ++pub unsafe fn atexit(cb: extern "C" fn()) -> ::c_int { ++ extern "C" { ++ static __dso_handle: *mut ::c_void; ++ pub fn __cxa_atexit( ++ cb: extern "C" fn(), ++ __arg: *mut ::c_void, ++ __dso: *mut ::c_void, ++ ) -> ::c_int; ++ } ++ __cxa_atexit(cb, 0 as *mut ::c_void, __dso_handle) ++} ++ ++impl siginfo_t { ++ pub unsafe fn si_addr(&self) -> *mut ::c_void { ++ #[repr(C)] ++ struct siginfo_si_addr { ++ _pad: [u8; 32], ++ si_addr: *mut ::c_void, ++ } ++ (*(self as *const siginfo_t as *const siginfo_si_addr)).si_addr ++ } ++ ++ pub unsafe fn si_value(&self) -> ::sigval { ++ #[repr(C)] ++ struct siginfo_si_value { ++ _pad: [u8; 32], ++ si_value: ::sigval, ++ } ++ (*(self as *const siginfo_t as *const siginfo_si_value)).si_value ++ } ++ ++ pub unsafe fn si_pid(&self) -> ::pid_t { ++ #[repr(C)] ++ struct siginfo_si_pid { ++ _pad: [u8; 16], ++ si_pid: ::pid_t, ++ } ++ (*(self as *const siginfo_t as *const siginfo_si_pid)).si_pid ++ } ++ ++ pub unsafe fn si_uid(&self) -> ::uid_t { ++ #[repr(C)] ++ struct siginfo_si_uid { ++ _pad: [u8; 24], ++ si_uid: ::uid_t, ++ } ++ (*(self as *const siginfo_t as *const siginfo_si_uid)).si_uid ++ } ++ ++ pub unsafe fn si_status(&self) -> ::c_int { ++ #[repr(C)] ++ struct siginfo_si_status { ++ _pad: [u8; 28], ++ si_status: ::c_int, ++ } ++ (*(self as *const siginfo_t as *const siginfo_si_status)).si_status ++ } ++} ++ ++cfg_if! { ++ if #[cfg(target_arch = "x86_64")] { ++ mod x86_64; ++ pub use self::x86_64::*; ++ } ++ else if #[cfg(target_arch = "aarch64")] { ++ mod aarch64; ++ pub use self::aarch64::*; ++ } ++ else { ++ panic!("Unsupported arch"); ++ } ++} ++ ++mod neutrino; ++pub use self::neutrino::*; +diff --git a/vendor/libc/src/unix/nto/neutrino.rs b/vendor/libc/src/unix/nto/neutrino.rs +new file mode 100644 +index 0000000..cedd216 +--- /dev/null ++++ b/vendor/libc/src/unix/nto/neutrino.rs +@@ -0,0 +1,1288 @@ ++pub type nto_job_t = ::sync_t; ++ ++s! { ++ pub struct intrspin { ++ pub value: ::c_uint, // volatile ++ } ++ ++ pub struct iov_t { ++ pub iov_base: *mut ::c_void, // union ++ pub iov_len: ::size_t, ++ } ++ ++ pub struct _itimer { ++ pub nsec: u64, ++ pub interval_nsec: u64, ++ } ++ ++ pub struct _msg_info64 { ++ pub nd: u32, ++ pub srcnd: u32, ++ pub pid: ::pid_t, ++ pub tid: i32, ++ pub chid: i32, ++ pub scoid: i32, ++ pub coid: i32, ++ pub priority: i16, ++ pub flags: i16, ++ pub msglen: isize, ++ pub srcmsglen: isize, ++ pub dstmsglen: isize, ++ pub type_id: u32, ++ reserved: u32, ++ } ++ ++ pub struct _cred_info { ++ pub ruid: ::uid_t, ++ pub euid: ::uid_t, ++ pub suid: ::uid_t, ++ pub rgid: ::gid_t, ++ pub egid: ::gid_t, ++ pub sgid: ::gid_t, ++ pub ngroups: u32, ++ pub grouplist: [::gid_t; 8], ++ } ++ ++ pub struct _client_info { ++ pub nd: u32, ++ pub pid: ::pid_t, ++ pub sid: ::pid_t, ++ pub flags: u32, ++ pub cred: ::_cred_info, ++ } ++ ++ pub struct _client_able { ++ pub ability: u32, ++ pub flags: u32, ++ pub range_lo: u64, ++ pub range_hi: u64, ++ } ++ ++ pub struct nto_channel_config { ++ pub event: ::sigevent, ++ pub num_pulses: ::c_uint, ++ pub rearm_threshold: ::c_uint, ++ pub options: ::c_uint, ++ reserved: [::c_uint; 3], ++ } ++ ++ // TODO: The following structures are defined in a header file which doesn't ++ // appear as part of the default headers found in a standard installation ++ // of Neutrino 7.1 SDP. Commented out for now. ++ //pub struct _asyncmsg_put_header { ++ // pub err: ::c_int, ++ // pub iov: *mut ::iov_t, ++ // pub parts: ::c_int, ++ // pub handle: ::c_uint, ++ // pub cb: ::Option< ++ // unsafe extern "C" fn( ++ // err: ::c_int, ++ // buf: *mut ::c_void, ++ // handle: ::c_uint, ++ // ) -> ::c_int>, ++ // pub put_hdr_flags: ::c_uint, ++ //} ++ ++ //pub struct _asyncmsg_connection_attr { ++ // pub call_back: ::Option< ++ // unsafe extern "C" fn( ++ // err: ::c_int, ++ // buff: *mut ::c_void, ++ // handle: ::c_uint, ++ // ) -> ::c_int>, ++ // pub buffer_size: ::size_t, ++ // pub max_num_buffer: ::c_uint, ++ // pub trigger_num_msg: ::c_uint, ++ // pub trigger_time: ::_itimer, ++ // reserve: ::c_uint, ++ //} ++ ++ //pub struct _asyncmsg_connection_descriptor { ++ // pub flags: ::c_uint, ++ // pub sendq_size: ::c_uint, ++ // pub sendq_head: ::c_uint, ++ // pub sendq_tail: ::c_uint, ++ // pub sendq_free: ::c_uint, ++ // pub err: ::c_int, ++ // pub ev: ::sigevent, ++ // pub num_curmsg: ::c_uint, ++ // pub ttimer: ::timer_t, ++ // pub block_con: ::pthread_cond_t, ++ // pub mu: ::pthread_mutex_t, ++ // reserved: ::c_uint, ++ // pub attr: ::_asyncmsg_connection_attr, ++ // pub reserves: [::c_uint; 3], ++ // pub sendq: [::_asyncmsg_put_header; 1], // flexarray ++ //} ++ ++ pub struct __c_anonymous_struct_ev { ++ pub event: ::sigevent, ++ pub coid: ::c_int, ++ } ++ ++ pub struct _channel_connect_attr { // union ++ pub ev: ::__c_anonymous_struct_ev, ++ } ++ ++ pub struct _sighandler_info { ++ pub siginfo: ::siginfo_t, ++ pub handler: ::Option, ++ pub context: *mut ::c_void, ++ } ++ ++ pub struct __c_anonymous_struct_time { ++ pub length: ::c_uint, ++ pub scale: ::c_uint, ++ } ++ ++ pub struct _idle_hook { ++ pub hook_size: ::c_uint, ++ pub cmd: ::c_uint, ++ pub mode: ::c_uint, ++ pub latency: ::c_uint, ++ pub next_fire: u64, ++ pub curr_time: u64, ++ pub tod_adjust: u64, ++ pub resp: ::c_uint, ++ pub time: __c_anonymous_struct_time, ++ pub trigger: ::sigevent, ++ pub intrs: *mut ::c_uint, ++ pub block_stack_size: ::c_uint, ++ } ++ ++ pub struct _clockadjust { ++ pub tick_count: u32, ++ pub tick_nsec_inc: i32, ++ } ++ ++ pub struct qtime_entry { ++ pub cycles_per_sec: u64, ++ pub nsec_tod_adjust: u64, // volatile ++ pub nsec: u64, // volatile ++ pub nsec_inc: u32, ++ pub boot_time: u32, ++ pub adjust: _clockadjust, ++ pub timer_rate: u32, ++ pub timer_scale: i32, ++ pub timer_load: u32, ++ pub intr: i32, ++ pub epoch: u32, ++ pub flags: u32, ++ pub rr_interval_mul: u32, ++ pub timer_load_hi: u32, ++ pub nsec_stable: u64, // volatile ++ pub timer_load_max: u64, ++ pub timer_prog_time: u32, ++ spare: [u32; 7], ++ } ++ ++ pub struct _sched_info { ++ pub priority_min: ::c_int, ++ pub priority_max: ::c_int, ++ pub interval: u64, ++ pub priority_priv: ::c_int, ++ reserved: [::c_int; 11], ++ } ++ ++ pub struct _timer_info { ++ pub itime: ::_itimer, ++ pub otime: ::_itimer, ++ pub flags: u32, ++ pub tid: i32, ++ pub notify: i32, ++ pub clockid: ::clockid_t, ++ pub overruns: u32, ++ pub event: ::sigevent, // union ++ } ++ ++ pub struct _clockperiod { ++ pub nsec: u32, ++ pub fract: i32, ++ } ++} ++ ++s_no_extra_traits! { ++ pub struct syspage_entry_info { ++ pub entry_off: u16, ++ pub entry_size: u16, ++ } ++ ++ pub struct syspage_array_info { ++ entry_off: u16, ++ entry_size: u16, ++ element_size: u16, ++ } ++ ++ #[repr(align(8))] ++ pub struct syspage_entry { ++ pub size: u16, ++ pub total_size: u16, ++ pub type_: u16, ++ pub num_cpu: u16, ++ pub system_private: syspage_entry_info, ++ pub old_asinfo: syspage_entry_info, ++ pub __mangle_name_to_cause_compilation_errs_meminfo: syspage_entry_info, ++ pub hwinfo: syspage_entry_info, ++ pub old_cpuinfo: syspage_entry_info, ++ pub old_cacheattr: syspage_entry_info, ++ pub qtime: syspage_entry_info, ++ pub callout: syspage_entry_info, ++ pub callin: syspage_entry_info, ++ pub typed_strings: syspage_entry_info, ++ pub strings: syspage_entry_info, ++ pub old_intrinfo: syspage_entry_info, ++ pub smp: syspage_entry_info, ++ pub pminfo: syspage_entry_info, ++ pub old_mdriver: syspage_entry_info, ++ spare0: [u32; 1], ++ __reserved: [u8; 160], // anonymous union with architecture dependent structs ++ pub new_asinfo: syspage_array_info, ++ pub new_cpuinfo: syspage_array_info, ++ pub new_cacheattr: syspage_array_info, ++ pub new_intrinfo: syspage_array_info, ++ pub new_mdriver: syspage_array_info, ++ } ++} ++ ++pub const SYSMGR_PID: u32 = 1; ++pub const SYSMGR_CHID: u32 = 1; ++pub const SYSMGR_COID: u32 = _NTO_SIDE_CHANNEL; ++pub const SYSMGR_HANDLE: u32 = 0; ++ ++pub const STATE_DEAD: ::c_int = 0x00; ++pub const STATE_RUNNING: ::c_int = 0x01; ++pub const STATE_READY: ::c_int = 0x02; ++pub const STATE_STOPPED: ::c_int = 0x03; ++pub const STATE_SEND: ::c_int = 0x04; ++pub const STATE_RECEIVE: ::c_int = 0x05; ++pub const STATE_REPLY: ::c_int = 0x06; ++pub const STATE_STACK: ::c_int = 0x07; ++pub const STATE_WAITTHREAD: ::c_int = 0x08; ++pub const STATE_WAITPAGE: ::c_int = 0x09; ++pub const STATE_SIGSUSPEND: ::c_int = 0x0a; ++pub const STATE_SIGWAITINFO: ::c_int = 0x0b; ++pub const STATE_NANOSLEEP: ::c_int = 0x0c; ++pub const STATE_MUTEX: ::c_int = 0x0d; ++pub const STATE_CONDVAR: ::c_int = 0x0e; ++pub const STATE_JOIN: ::c_int = 0x0f; ++pub const STATE_INTR: ::c_int = 0x10; ++pub const STATE_SEM: ::c_int = 0x11; ++pub const STATE_WAITCTX: ::c_int = 0x12; ++pub const STATE_NET_SEND: ::c_int = 0x13; ++pub const STATE_NET_REPLY: ::c_int = 0x14; ++pub const STATE_MAX: ::c_int = 0x18; ++ ++pub const _NTO_TIMEOUT_RECEIVE: i32 = 1 << STATE_RECEIVE; ++pub const _NTO_TIMEOUT_SEND: i32 = 1 << STATE_SEND; ++pub const _NTO_TIMEOUT_REPLY: i32 = 1 << STATE_REPLY; ++pub const _NTO_TIMEOUT_SIGSUSPEND: i32 = 1 << STATE_SIGSUSPEND; ++pub const _NTO_TIMEOUT_SIGWAITINFO: i32 = 1 << STATE_SIGWAITINFO; ++pub const _NTO_TIMEOUT_NANOSLEEP: i32 = 1 << STATE_NANOSLEEP; ++pub const _NTO_TIMEOUT_MUTEX: i32 = 1 << STATE_MUTEX; ++pub const _NTO_TIMEOUT_CONDVAR: i32 = 1 << STATE_CONDVAR; ++pub const _NTO_TIMEOUT_JOIN: i32 = 1 << STATE_JOIN; ++pub const _NTO_TIMEOUT_INTR: i32 = 1 << STATE_INTR; ++pub const _NTO_TIMEOUT_SEM: i32 = 1 << STATE_SEM; ++ ++pub const _NTO_MI_ENDIAN_BIG: u32 = 1; ++pub const _NTO_MI_ENDIAN_DIFF: u32 = 2; ++pub const _NTO_MI_UNBLOCK_REQ: u32 = 256; ++pub const _NTO_MI_NET_CRED_DIRTY: u32 = 512; ++pub const _NTO_MI_CONSTRAINED: u32 = 1024; ++pub const _NTO_MI_CHROOT: u32 = 2048; ++pub const _NTO_MI_BITS_64: u32 = 4096; ++pub const _NTO_MI_BITS_DIFF: u32 = 8192; ++pub const _NTO_MI_SANDBOX: u32 = 16384; ++ ++pub const _NTO_CI_ENDIAN_BIG: u32 = 1; ++pub const _NTO_CI_BKGND_PGRP: u32 = 4; ++pub const _NTO_CI_ORPHAN_PGRP: u32 = 8; ++pub const _NTO_CI_STOPPED: u32 = 128; ++pub const _NTO_CI_UNABLE: u32 = 256; ++pub const _NTO_CI_TYPE_ID: u32 = 512; ++pub const _NTO_CI_CHROOT: u32 = 2048; ++pub const _NTO_CI_BITS_64: u32 = 4096; ++pub const _NTO_CI_SANDBOX: u32 = 16384; ++pub const _NTO_CI_LOADER: u32 = 32768; ++pub const _NTO_CI_FULL_GROUPS: u32 = 2147483648; ++ ++pub const _NTO_TI_ACTIVE: u32 = 1; ++pub const _NTO_TI_ABSOLUTE: u32 = 2; ++pub const _NTO_TI_EXPIRED: u32 = 4; ++pub const _NTO_TI_TOD_BASED: u32 = 8; ++pub const _NTO_TI_TARGET_PROCESS: u32 = 16; ++pub const _NTO_TI_REPORT_TOLERANCE: u32 = 32; ++pub const _NTO_TI_PRECISE: u32 = 64; ++pub const _NTO_TI_TOLERANT: u32 = 128; ++pub const _NTO_TI_WAKEUP: u32 = 256; ++pub const _NTO_TI_PROCESS_TOLERANT: u32 = 512; ++pub const _NTO_TI_HIGH_RESOLUTION: u32 = 1024; ++ ++pub const _PULSE_TYPE: u32 = 0; ++pub const _PULSE_SUBTYPE: u32 = 0; ++pub const _PULSE_CODE_UNBLOCK: i32 = -32; ++pub const _PULSE_CODE_DISCONNECT: i32 = -33; ++pub const _PULSE_CODE_THREADDEATH: i32 = -34; ++pub const _PULSE_CODE_COIDDEATH: i32 = -35; ++pub const _PULSE_CODE_NET_ACK: i32 = -36; ++pub const _PULSE_CODE_NET_UNBLOCK: i32 = -37; ++pub const _PULSE_CODE_NET_DETACH: i32 = -38; ++pub const _PULSE_CODE_RESTART: i32 = -39; ++pub const _PULSE_CODE_NORESTART: i32 = -40; ++pub const _PULSE_CODE_UNBLOCK_RESTART: i32 = -41; ++pub const _PULSE_CODE_UNBLOCK_TIMER: i32 = -42; ++pub const _PULSE_CODE_MINAVAIL: u32 = 0; ++pub const _PULSE_CODE_MAXAVAIL: u32 = 127; ++ ++pub const _NTO_HARD_FLAGS_END: u32 = 1; ++ ++pub const _NTO_PULSE_IF_UNIQUE: u32 = 4096; ++pub const _NTO_PULSE_REPLACE: u32 = 8192; ++ ++pub const _NTO_PF_NOCLDSTOP: u32 = 1; ++pub const _NTO_PF_LOADING: u32 = 2; ++pub const _NTO_PF_TERMING: u32 = 4; ++pub const _NTO_PF_ZOMBIE: u32 = 8; ++pub const _NTO_PF_NOZOMBIE: u32 = 16; ++pub const _NTO_PF_FORKED: u32 = 32; ++pub const _NTO_PF_ORPHAN_PGRP: u32 = 64; ++pub const _NTO_PF_STOPPED: u32 = 128; ++pub const _NTO_PF_DEBUG_STOPPED: u32 = 256; ++pub const _NTO_PF_BKGND_PGRP: u32 = 512; ++pub const _NTO_PF_NOISYNC: u32 = 1024; ++pub const _NTO_PF_CONTINUED: u32 = 2048; ++pub const _NTO_PF_CHECK_INTR: u32 = 4096; ++pub const _NTO_PF_COREDUMP: u32 = 8192; ++pub const _NTO_PF_RING0: u32 = 32768; ++pub const _NTO_PF_SLEADER: u32 = 65536; ++pub const _NTO_PF_WAITINFO: u32 = 131072; ++pub const _NTO_PF_DESTROYALL: u32 = 524288; ++pub const _NTO_PF_NOCOREDUMP: u32 = 1048576; ++pub const _NTO_PF_WAITDONE: u32 = 4194304; ++pub const _NTO_PF_TERM_WAITING: u32 = 8388608; ++pub const _NTO_PF_ASLR: u32 = 16777216; ++pub const _NTO_PF_EXECED: u32 = 33554432; ++pub const _NTO_PF_APP_STOPPED: u32 = 67108864; ++pub const _NTO_PF_64BIT: u32 = 134217728; ++pub const _NTO_PF_NET: u32 = 268435456; ++pub const _NTO_PF_NOLAZYSTACK: u32 = 536870912; ++pub const _NTO_PF_NOEXEC_STACK: u32 = 1073741824; ++pub const _NTO_PF_LOADER_PERMS: u32 = 2147483648; ++ ++pub const _NTO_TF_INTR_PENDING: u32 = 65536; ++pub const _NTO_TF_DETACHED: u32 = 131072; ++pub const _NTO_TF_SHR_MUTEX: u32 = 262144; ++pub const _NTO_TF_SHR_MUTEX_EUID: u32 = 524288; ++pub const _NTO_TF_THREADS_HOLD: u32 = 1048576; ++pub const _NTO_TF_UNBLOCK_REQ: u32 = 4194304; ++pub const _NTO_TF_ALIGN_FAULT: u32 = 16777216; ++pub const _NTO_TF_SSTEP: u32 = 33554432; ++pub const _NTO_TF_ALLOCED_STACK: u32 = 67108864; ++pub const _NTO_TF_NOMULTISIG: u32 = 134217728; ++pub const _NTO_TF_LOW_LATENCY: u32 = 268435456; ++pub const _NTO_TF_IOPRIV: u32 = 2147483648; ++ ++pub const _NTO_TCTL_IO_PRIV: u32 = 1; ++pub const _NTO_TCTL_THREADS_HOLD: u32 = 2; ++pub const _NTO_TCTL_THREADS_CONT: u32 = 3; ++pub const _NTO_TCTL_RUNMASK: u32 = 4; ++pub const _NTO_TCTL_ALIGN_FAULT: u32 = 5; ++pub const _NTO_TCTL_RUNMASK_GET_AND_SET: u32 = 6; ++pub const _NTO_TCTL_PERFCOUNT: u32 = 7; ++pub const _NTO_TCTL_ONE_THREAD_HOLD: u32 = 8; ++pub const _NTO_TCTL_ONE_THREAD_CONT: u32 = 9; ++pub const _NTO_TCTL_RUNMASK_GET_AND_SET_INHERIT: u32 = 10; ++pub const _NTO_TCTL_NAME: u32 = 11; ++pub const _NTO_TCTL_RCM_GET_AND_SET: u32 = 12; ++pub const _NTO_TCTL_SHR_MUTEX: u32 = 13; ++pub const _NTO_TCTL_IO: u32 = 14; ++pub const _NTO_TCTL_NET_KIF_GET_AND_SET: u32 = 15; ++pub const _NTO_TCTL_LOW_LATENCY: u32 = 16; ++pub const _NTO_TCTL_ADD_EXIT_EVENT: u32 = 17; ++pub const _NTO_TCTL_DEL_EXIT_EVENT: u32 = 18; ++pub const _NTO_TCTL_IO_LEVEL: u32 = 19; ++pub const _NTO_TCTL_RESERVED: u32 = 2147483648; ++pub const _NTO_TCTL_IO_LEVEL_INHERIT: u32 = 1073741824; ++pub const _NTO_IO_LEVEL_NONE: u32 = 1; ++pub const _NTO_IO_LEVEL_1: u32 = 2; ++pub const _NTO_IO_LEVEL_2: u32 = 3; ++ ++pub const _NTO_THREAD_NAME_MAX: u32 = 100; ++ ++pub const _NTO_CHF_FIXED_PRIORITY: u32 = 1; ++pub const _NTO_CHF_UNBLOCK: u32 = 2; ++pub const _NTO_CHF_THREAD_DEATH: u32 = 4; ++pub const _NTO_CHF_DISCONNECT: u32 = 8; ++pub const _NTO_CHF_NET_MSG: u32 = 16; ++pub const _NTO_CHF_SENDER_LEN: u32 = 32; ++pub const _NTO_CHF_COID_DISCONNECT: u32 = 64; ++pub const _NTO_CHF_REPLY_LEN: u32 = 128; ++pub const _NTO_CHF_PULSE_POOL: u32 = 256; ++pub const _NTO_CHF_ASYNC_NONBLOCK: u32 = 512; ++pub const _NTO_CHF_ASYNC: u32 = 1024; ++pub const _NTO_CHF_GLOBAL: u32 = 2048; ++pub const _NTO_CHF_PRIVATE: u32 = 4096; ++pub const _NTO_CHF_MSG_PAUSING: u32 = 8192; ++pub const _NTO_CHF_INHERIT_RUNMASK: u32 = 16384; ++pub const _NTO_CHF_UNBLOCK_TIMER: u32 = 32768; ++ ++pub const _NTO_CHO_CUSTOM_EVENT: u32 = 1; ++ ++pub const _NTO_COF_CLOEXEC: u32 = 1; ++pub const _NTO_COF_DEAD: u32 = 2; ++pub const _NTO_COF_NOSHARE: u32 = 64; ++pub const _NTO_COF_NETCON: u32 = 128; ++pub const _NTO_COF_NONBLOCK: u32 = 256; ++pub const _NTO_COF_ASYNC: u32 = 512; ++pub const _NTO_COF_GLOBAL: u32 = 1024; ++pub const _NTO_COF_NOEVENT: u32 = 2048; ++pub const _NTO_COF_INSECURE: u32 = 4096; ++pub const _NTO_COF_REG_EVENTS: u32 = 8192; ++pub const _NTO_COF_UNREG_EVENTS: u32 = 16384; ++pub const _NTO_COF_MASK: u32 = 65535; ++ ++pub const _NTO_SIDE_CHANNEL: u32 = 1073741824; ++ ++pub const _NTO_CONNECTION_SCOID: u32 = 65536; ++pub const _NTO_GLOBAL_CHANNEL: u32 = 1073741824; ++ ++pub const _NTO_TIMEOUT_MASK: u32 = (1 << STATE_MAX) - 1; ++pub const _NTO_TIMEOUT_ACTIVE: u32 = 1 << STATE_MAX; ++pub const _NTO_TIMEOUT_IMMEDIATE: u32 = 1 << (STATE_MAX + 1); ++ ++pub const _NTO_IC_LATENCY: u32 = 0; ++ ++pub const _NTO_INTR_FLAGS_END: u32 = 1; ++pub const _NTO_INTR_FLAGS_NO_UNMASK: u32 = 2; ++pub const _NTO_INTR_FLAGS_PROCESS: u32 = 4; ++pub const _NTO_INTR_FLAGS_TRK_MSK: u32 = 8; ++pub const _NTO_INTR_FLAGS_ARRAY: u32 = 16; ++pub const _NTO_INTR_FLAGS_EXCLUSIVE: u32 = 32; ++pub const _NTO_INTR_FLAGS_FPU: u32 = 64; ++ ++pub const _NTO_INTR_CLASS_EXTERNAL: u32 = 0; ++pub const _NTO_INTR_CLASS_SYNTHETIC: u32 = 2147418112; ++ ++pub const _NTO_INTR_SPARE: u32 = 2147483647; ++ ++pub const _NTO_HOOK_IDLE: u32 = 2147418113; ++pub const _NTO_HOOK_OVERDRIVE: u32 = 2147418114; ++pub const _NTO_HOOK_LAST: u32 = 2147418114; ++pub const _NTO_HOOK_IDLE2_FLAG: u32 = 32768; ++ ++pub const _NTO_IH_CMD_SLEEP_SETUP: u32 = 1; ++pub const _NTO_IH_CMD_SLEEP_BLOCK: u32 = 2; ++pub const _NTO_IH_CMD_SLEEP_WAKEUP: u32 = 4; ++pub const _NTO_IH_CMD_SLEEP_ONLINE: u32 = 8; ++pub const _NTO_IH_RESP_NEEDS_BLOCK: u32 = 1; ++pub const _NTO_IH_RESP_NEEDS_WAKEUP: u32 = 2; ++pub const _NTO_IH_RESP_NEEDS_ONLINE: u32 = 4; ++pub const _NTO_IH_RESP_SYNC_TIME: u32 = 16; ++pub const _NTO_IH_RESP_SYNC_TLB: u32 = 32; ++pub const _NTO_IH_RESP_SUGGEST_OFFLINE: u32 = 256; ++pub const _NTO_IH_RESP_SLEEP_MODE_REACHED: u32 = 512; ++pub const _NTO_IH_RESP_DELIVER_INTRS: u32 = 1024; ++ ++pub const _NTO_READIOV_SEND: u32 = 0; ++pub const _NTO_READIOV_REPLY: u32 = 1; ++ ++pub const _NTO_KEYDATA_VTID: u32 = 2147483648; ++ ++pub const _NTO_KEYDATA_PATHSIGN: u32 = 32768; ++pub const _NTO_KEYDATA_OP_MASK: u32 = 255; ++pub const _NTO_KEYDATA_VERIFY: u32 = 0; ++pub const _NTO_KEYDATA_CALCULATE: u32 = 1; ++pub const _NTO_KEYDATA_CALCULATE_REUSE: u32 = 2; ++pub const _NTO_KEYDATA_PATHSIGN_VERIFY: u32 = 32768; ++pub const _NTO_KEYDATA_PATHSIGN_CALCULATE: u32 = 32769; ++pub const _NTO_KEYDATA_PATHSIGN_CALCULATE_REUSE: u32 = 32770; ++ ++pub const _NTO_SCTL_SETPRIOCEILING: u32 = 1; ++pub const _NTO_SCTL_GETPRIOCEILING: u32 = 2; ++pub const _NTO_SCTL_SETEVENT: u32 = 3; ++pub const _NTO_SCTL_MUTEX_WAKEUP: u32 = 4; ++pub const _NTO_SCTL_MUTEX_CONSISTENT: u32 = 5; ++pub const _NTO_SCTL_SEM_VALUE: u32 = 6; ++ ++pub const _NTO_CLIENTINFO_GETGROUPS: u32 = 1; ++pub const _NTO_CLIENTINFO_GETTYPEID: u32 = 2; ++ ++extern "C" { ++ pub fn ChannelCreate(__flags: ::c_uint) -> ::c_int; ++ pub fn ChannelCreate_r(__flags: ::c_uint) -> ::c_int; ++ pub fn ChannelCreatePulsePool( ++ __flags: ::c_uint, ++ __config: *const nto_channel_config, ++ ) -> ::c_int; ++ pub fn ChannelCreateExt( ++ __flags: ::c_uint, ++ __mode: ::mode_t, ++ __bufsize: usize, ++ __maxnumbuf: ::c_uint, ++ __ev: *const ::sigevent, ++ __cred: *mut _cred_info, ++ ) -> ::c_int; ++ pub fn ChannelDestroy(__chid: ::c_int) -> ::c_int; ++ pub fn ChannelDestroy_r(__chid: ::c_int) -> ::c_int; ++ pub fn ConnectAttach( ++ __nd: u32, ++ __pid: ::pid_t, ++ __chid: ::c_int, ++ __index: ::c_uint, ++ __flags: ::c_int, ++ ) -> ::c_int; ++ pub fn ConnectAttach_r( ++ __nd: u32, ++ __pid: ::pid_t, ++ __chid: ::c_int, ++ __index: ::c_uint, ++ __flags: ::c_int, ++ ) -> ::c_int; ++ ++ // TODO: The following function uses a structure defined in a header file ++ // which doesn't appear as part of the default headers found in a ++ // standard installation of Neutrino 7.1 SDP. Commented out for now. ++ //pub fn ConnectAttachExt( ++ // __nd: u32, ++ // __pid: ::pid_t, ++ // __chid: ::c_int, ++ // __index: ::c_uint, ++ // __flags: ::c_int, ++ // __cd: *mut _asyncmsg_connection_descriptor, ++ //) -> ::c_int; ++ pub fn ConnectDetach(__coid: ::c_int) -> ::c_int; ++ pub fn ConnectDetach_r(__coid: ::c_int) -> ::c_int; ++ pub fn ConnectServerInfo(__pid: ::pid_t, __coid: ::c_int, __info: *mut _msg_info64) -> ::c_int; ++ pub fn ConnectServerInfo_r( ++ __pid: ::pid_t, ++ __coid: ::c_int, ++ __info: *mut _msg_info64, ++ ) -> ::c_int; ++ pub fn ConnectClientInfoExtraArgs( ++ __scoid: ::c_int, ++ __info_pp: *mut _client_info, ++ __ngroups: ::c_int, ++ __abilities: *mut _client_able, ++ __nable: ::c_int, ++ __type_id: *mut ::c_uint, ++ ) -> ::c_int; ++ pub fn ConnectClientInfoExtraArgs_r( ++ __scoid: ::c_int, ++ __info_pp: *mut _client_info, ++ __ngroups: ::c_int, ++ __abilities: *mut _client_able, ++ __nable: ::c_int, ++ __type_id: *mut ::c_uint, ++ ) -> ::c_int; ++ pub fn ConnectClientInfo( ++ __scoid: ::c_int, ++ __info: *mut _client_info, ++ __ngroups: ::c_int, ++ ) -> ::c_int; ++ pub fn ConnectClientInfo_r( ++ __scoid: ::c_int, ++ __info: *mut _client_info, ++ __ngroups: ::c_int, ++ ) -> ::c_int; ++ pub fn ConnectClientInfoExt( ++ __scoid: ::c_int, ++ __info_pp: *mut *mut _client_info, ++ flags: ::c_int, ++ ) -> ::c_int; ++ pub fn ClientInfoExtFree(__info_pp: *mut *mut _client_info) -> ::c_int; ++ pub fn ConnectClientInfoAble( ++ __scoid: ::c_int, ++ __info_pp: *mut *mut _client_info, ++ flags: ::c_int, ++ abilities: *mut _client_able, ++ nable: ::c_int, ++ ) -> ::c_int; ++ pub fn ConnectFlags( ++ __pid: ::pid_t, ++ __coid: ::c_int, ++ __mask: ::c_uint, ++ __bits: ::c_uint, ++ ) -> ::c_int; ++ pub fn ConnectFlags_r( ++ __pid: ::pid_t, ++ __coid: ::c_int, ++ __mask: ::c_uint, ++ __bits: ::c_uint, ++ ) -> ::c_int; ++ pub fn ChannelConnectAttr( ++ __id: ::c_uint, ++ __old_attr: *mut _channel_connect_attr, ++ __new_attr: *mut _channel_connect_attr, ++ __flags: ::c_uint, ++ ) -> ::c_int; ++ pub fn MsgSend( ++ __coid: ::c_int, ++ __smsg: *const ::c_void, ++ __sbytes: usize, ++ __rmsg: *mut ::c_void, ++ __rbytes: usize, ++ ) -> ::c_long; ++ pub fn MsgSend_r( ++ __coid: ::c_int, ++ __smsg: *const ::c_void, ++ __sbytes: usize, ++ __rmsg: *mut ::c_void, ++ __rbytes: usize, ++ ) -> ::c_long; ++ pub fn MsgSendnc( ++ __coid: ::c_int, ++ __smsg: *const ::c_void, ++ __sbytes: usize, ++ __rmsg: *mut ::c_void, ++ __rbytes: usize, ++ ) -> ::c_long; ++ pub fn MsgSendnc_r( ++ __coid: ::c_int, ++ __smsg: *const ::c_void, ++ __sbytes: usize, ++ __rmsg: *mut ::c_void, ++ __rbytes: usize, ++ ) -> ::c_long; ++ pub fn MsgSendsv( ++ __coid: ::c_int, ++ __smsg: *const ::c_void, ++ __sbytes: usize, ++ __riov: *const ::iovec, ++ __rparts: usize, ++ ) -> ::c_long; ++ pub fn MsgSendsv_r( ++ __coid: ::c_int, ++ __smsg: *const ::c_void, ++ __sbytes: usize, ++ __riov: *const ::iovec, ++ __rparts: usize, ++ ) -> ::c_long; ++ pub fn MsgSendsvnc( ++ __coid: ::c_int, ++ __smsg: *const ::c_void, ++ __sbytes: usize, ++ __riov: *const ::iovec, ++ __rparts: usize, ++ ) -> ::c_long; ++ pub fn MsgSendsvnc_r( ++ __coid: ::c_int, ++ __smsg: *const ::c_void, ++ __sbytes: usize, ++ __riov: *const ::iovec, ++ __rparts: usize, ++ ) -> ::c_long; ++ pub fn MsgSendvs( ++ __coid: ::c_int, ++ __siov: *const ::iovec, ++ __sparts: usize, ++ __rmsg: *mut ::c_void, ++ __rbytes: usize, ++ ) -> ::c_long; ++ pub fn MsgSendvs_r( ++ __coid: ::c_int, ++ __siov: *const ::iovec, ++ __sparts: usize, ++ __rmsg: *mut ::c_void, ++ __rbytes: usize, ++ ) -> ::c_long; ++ pub fn MsgSendvsnc( ++ __coid: ::c_int, ++ __siov: *const ::iovec, ++ __sparts: usize, ++ __rmsg: *mut ::c_void, ++ __rbytes: usize, ++ ) -> ::c_long; ++ pub fn MsgSendvsnc_r( ++ __coid: ::c_int, ++ __siov: *const ::iovec, ++ __sparts: usize, ++ __rmsg: *mut ::c_void, ++ __rbytes: usize, ++ ) -> ::c_long; ++ pub fn MsgSendv( ++ __coid: ::c_int, ++ __siov: *const ::iovec, ++ __sparts: usize, ++ __riov: *const ::iovec, ++ __rparts: usize, ++ ) -> ::c_long; ++ pub fn MsgSendv_r( ++ __coid: ::c_int, ++ __siov: *const ::iovec, ++ __sparts: usize, ++ __riov: *const ::iovec, ++ __rparts: usize, ++ ) -> ::c_long; ++ pub fn MsgSendvnc( ++ __coid: ::c_int, ++ __siov: *const ::iovec, ++ __sparts: usize, ++ __riov: *const ::iovec, ++ __rparts: usize, ++ ) -> ::c_long; ++ pub fn MsgSendvnc_r( ++ __coid: ::c_int, ++ __siov: *const ::iovec, ++ __sparts: usize, ++ __riov: *const ::iovec, ++ __rparts: usize, ++ ) -> ::c_long; ++ pub fn MsgReceive( ++ __chid: ::c_int, ++ __msg: *mut ::c_void, ++ __bytes: usize, ++ __info: *mut _msg_info64, ++ ) -> ::c_int; ++ pub fn MsgReceive_r( ++ __chid: ::c_int, ++ __msg: *mut ::c_void, ++ __bytes: usize, ++ __info: *mut _msg_info64, ++ ) -> ::c_int; ++ pub fn MsgReceivev( ++ __chid: ::c_int, ++ __iov: *const ::iovec, ++ __parts: usize, ++ __info: *mut _msg_info64, ++ ) -> ::c_int; ++ pub fn MsgReceivev_r( ++ __chid: ::c_int, ++ __iov: *const ::iovec, ++ __parts: usize, ++ __info: *mut _msg_info64, ++ ) -> ::c_int; ++ pub fn MsgReceivePulse( ++ __chid: ::c_int, ++ __pulse: *mut ::c_void, ++ __bytes: usize, ++ __info: *mut _msg_info64, ++ ) -> ::c_int; ++ pub fn MsgReceivePulse_r( ++ __chid: ::c_int, ++ __pulse: *mut ::c_void, ++ __bytes: usize, ++ __info: *mut _msg_info64, ++ ) -> ::c_int; ++ pub fn MsgReceivePulsev( ++ __chid: ::c_int, ++ __iov: *const ::iovec, ++ __parts: usize, ++ __info: *mut _msg_info64, ++ ) -> ::c_int; ++ pub fn MsgReceivePulsev_r( ++ __chid: ::c_int, ++ __iov: *const ::iovec, ++ __parts: usize, ++ __info: *mut _msg_info64, ++ ) -> ::c_int; ++ pub fn MsgReply( ++ __rcvid: ::c_int, ++ __status: ::c_long, ++ __msg: *const ::c_void, ++ __bytes: usize, ++ ) -> ::c_int; ++ pub fn MsgReply_r( ++ __rcvid: ::c_int, ++ __status: ::c_long, ++ __msg: *const ::c_void, ++ __bytes: usize, ++ ) -> ::c_int; ++ pub fn MsgReplyv( ++ __rcvid: ::c_int, ++ __status: ::c_long, ++ __iov: *const ::iovec, ++ __parts: usize, ++ ) -> ::c_int; ++ pub fn MsgReplyv_r( ++ __rcvid: ::c_int, ++ __status: ::c_long, ++ __iov: *const ::iovec, ++ __parts: usize, ++ ) -> ::c_int; ++ pub fn MsgReadiov( ++ __rcvid: ::c_int, ++ __iov: *const ::iovec, ++ __parts: usize, ++ __offset: usize, ++ __flags: ::c_int, ++ ) -> isize; ++ pub fn MsgReadiov_r( ++ __rcvid: ::c_int, ++ __iov: *const ::iovec, ++ __parts: usize, ++ __offset: usize, ++ __flags: ::c_int, ++ ) -> isize; ++ pub fn MsgRead( ++ __rcvid: ::c_int, ++ __msg: *mut ::c_void, ++ __bytes: usize, ++ __offset: usize, ++ ) -> isize; ++ pub fn MsgRead_r( ++ __rcvid: ::c_int, ++ __msg: *mut ::c_void, ++ __bytes: usize, ++ __offset: usize, ++ ) -> isize; ++ pub fn MsgReadv( ++ __rcvid: ::c_int, ++ __iov: *const ::iovec, ++ __parts: usize, ++ __offset: usize, ++ ) -> isize; ++ pub fn MsgReadv_r( ++ __rcvid: ::c_int, ++ __iov: *const ::iovec, ++ __parts: usize, ++ __offset: usize, ++ ) -> isize; ++ pub fn MsgWrite( ++ __rcvid: ::c_int, ++ __msg: *const ::c_void, ++ __bytes: usize, ++ __offset: usize, ++ ) -> isize; ++ pub fn MsgWrite_r( ++ __rcvid: ::c_int, ++ __msg: *const ::c_void, ++ __bytes: usize, ++ __offset: usize, ++ ) -> isize; ++ pub fn MsgWritev( ++ __rcvid: ::c_int, ++ __iov: *const ::iovec, ++ __parts: usize, ++ __offset: usize, ++ ) -> isize; ++ pub fn MsgWritev_r( ++ __rcvid: ::c_int, ++ __iov: *const ::iovec, ++ __parts: usize, ++ __offset: usize, ++ ) -> isize; ++ pub fn MsgSendPulse( ++ __coid: ::c_int, ++ __priority: ::c_int, ++ __code: ::c_int, ++ __value: ::c_int, ++ ) -> ::c_int; ++ pub fn MsgSendPulse_r( ++ __coid: ::c_int, ++ __priority: ::c_int, ++ __code: ::c_int, ++ __value: ::c_int, ++ ) -> ::c_int; ++ pub fn MsgSendPulsePtr( ++ __coid: ::c_int, ++ __priority: ::c_int, ++ __code: ::c_int, ++ __value: *mut ::c_void, ++ ) -> ::c_int; ++ pub fn MsgSendPulsePtr_r( ++ __coid: ::c_int, ++ __priority: ::c_int, ++ __code: ::c_int, ++ __value: *mut ::c_void, ++ ) -> ::c_int; ++ pub fn MsgDeliverEvent(__rcvid: ::c_int, __event: *const ::sigevent) -> ::c_int; ++ pub fn MsgDeliverEvent_r(__rcvid: ::c_int, __event: *const ::sigevent) -> ::c_int; ++ pub fn MsgVerifyEvent(__rcvid: ::c_int, __event: *const ::sigevent) -> ::c_int; ++ pub fn MsgVerifyEvent_r(__rcvid: ::c_int, __event: *const ::sigevent) -> ::c_int; ++ pub fn MsgRegisterEvent(__event: *mut ::sigevent, __coid: ::c_int) -> ::c_int; ++ pub fn MsgRegisterEvent_r(__event: *mut ::sigevent, __coid: ::c_int) -> ::c_int; ++ pub fn MsgUnregisterEvent(__event: *const ::sigevent) -> ::c_int; ++ pub fn MsgUnregisterEvent_r(__event: *const ::sigevent) -> ::c_int; ++ pub fn MsgInfo(__rcvid: ::c_int, __info: *mut _msg_info64) -> ::c_int; ++ pub fn MsgInfo_r(__rcvid: ::c_int, __info: *mut _msg_info64) -> ::c_int; ++ pub fn MsgKeyData( ++ __rcvid: ::c_int, ++ __oper: ::c_int, ++ __key: u32, ++ __newkey: *mut u32, ++ __iov: *const ::iovec, ++ __parts: ::c_int, ++ ) -> ::c_int; ++ pub fn MsgKeyData_r( ++ __rcvid: ::c_int, ++ __oper: ::c_int, ++ __key: u32, ++ __newkey: *mut u32, ++ __iov: *const ::iovec, ++ __parts: ::c_int, ++ ) -> ::c_int; ++ pub fn MsgError(__rcvid: ::c_int, __err: ::c_int) -> ::c_int; ++ pub fn MsgError_r(__rcvid: ::c_int, __err: ::c_int) -> ::c_int; ++ pub fn MsgCurrent(__rcvid: ::c_int) -> ::c_int; ++ pub fn MsgCurrent_r(__rcvid: ::c_int) -> ::c_int; ++ pub fn MsgSendAsyncGbl( ++ __coid: ::c_int, ++ __smsg: *const ::c_void, ++ __sbytes: usize, ++ __msg_prio: ::c_uint, ++ ) -> ::c_int; ++ pub fn MsgSendAsync(__coid: ::c_int) -> ::c_int; ++ pub fn MsgReceiveAsyncGbl( ++ __chid: ::c_int, ++ __rmsg: *mut ::c_void, ++ __rbytes: usize, ++ __info: *mut _msg_info64, ++ __coid: ::c_int, ++ ) -> ::c_int; ++ pub fn MsgReceiveAsync(__chid: ::c_int, __iov: *const ::iovec, __parts: ::c_uint) -> ::c_int; ++ pub fn MsgPause(__rcvid: ::c_int, __cookie: ::c_uint) -> ::c_int; ++ pub fn MsgPause_r(__rcvid: ::c_int, __cookie: ::c_uint) -> ::c_int; ++ ++ pub fn SignalKill( ++ __nd: u32, ++ __pid: ::pid_t, ++ __tid: ::c_int, ++ __signo: ::c_int, ++ __code: ::c_int, ++ __value: ::c_int, ++ ) -> ::c_int; ++ pub fn SignalKill_r( ++ __nd: u32, ++ __pid: ::pid_t, ++ __tid: ::c_int, ++ __signo: ::c_int, ++ __code: ::c_int, ++ __value: ::c_int, ++ ) -> ::c_int; ++ pub fn SignalKillSigval( ++ __nd: u32, ++ __pid: ::pid_t, ++ __tid: ::c_int, ++ __signo: ::c_int, ++ __code: ::c_int, ++ __value: *const ::sigval, ++ ) -> ::c_int; ++ pub fn SignalKillSigval_r( ++ __nd: u32, ++ __pid: ::pid_t, ++ __tid: ::c_int, ++ __signo: ::c_int, ++ __code: ::c_int, ++ __value: *const ::sigval, ++ ) -> ::c_int; ++ pub fn SignalReturn(__info: *mut _sighandler_info) -> ::c_int; ++ pub fn SignalFault(__sigcode: ::c_uint, __regs: *mut ::c_void, __refaddr: usize) -> ::c_int; ++ pub fn SignalAction( ++ __pid: ::pid_t, ++ __sigstub: unsafe extern "C" fn(), ++ __signo: ::c_int, ++ __act: *const ::sigaction, ++ __oact: *mut ::sigaction, ++ ) -> ::c_int; ++ pub fn SignalAction_r( ++ __pid: ::pid_t, ++ __sigstub: unsafe extern "C" fn(), ++ __signo: ::c_int, ++ __act: *const ::sigaction, ++ __oact: *mut ::sigaction, ++ ) -> ::c_int; ++ pub fn SignalProcmask( ++ __pid: ::pid_t, ++ __tid: ::c_int, ++ __how: ::c_int, ++ __set: *const ::sigset_t, ++ __oldset: *mut ::sigset_t, ++ ) -> ::c_int; ++ pub fn SignalProcmask_r( ++ __pid: ::pid_t, ++ __tid: ::c_int, ++ __how: ::c_int, ++ __set: *const ::sigset_t, ++ __oldset: *mut ::sigset_t, ++ ) -> ::c_int; ++ pub fn SignalSuspend(__set: *const ::sigset_t) -> ::c_int; ++ pub fn SignalSuspend_r(__set: *const ::sigset_t) -> ::c_int; ++ pub fn SignalWaitinfo(__set: *const ::sigset_t, __info: *mut ::siginfo_t) -> ::c_int; ++ pub fn SignalWaitinfo_r(__set: *const ::sigset_t, __info: *mut ::siginfo_t) -> ::c_int; ++ pub fn SignalWaitinfoMask( ++ __set: *const ::sigset_t, ++ __info: *mut ::siginfo_t, ++ __mask: *const ::sigset_t, ++ ) -> ::c_int; ++ pub fn SignalWaitinfoMask_r( ++ __set: *const ::sigset_t, ++ __info: *mut ::siginfo_t, ++ __mask: *const ::sigset_t, ++ ) -> ::c_int; ++ pub fn ThreadCreate( ++ __pid: ::pid_t, ++ __func: unsafe extern "C" fn(__arg: *mut ::c_void) -> *mut ::c_void, ++ __arg: *mut ::c_void, ++ __attr: *const ::_thread_attr, ++ ) -> ::c_int; ++ pub fn ThreadCreate_r( ++ __pid: ::pid_t, ++ __func: unsafe extern "C" fn(__arg: *mut ::c_void) -> *mut ::c_void, ++ __arg: *mut ::c_void, ++ __attr: *const ::_thread_attr, ++ ) -> ::c_int; ++ ++ pub fn ThreadDestroy(__tid: ::c_int, __priority: ::c_int, __status: *mut ::c_void) -> ::c_int; ++ pub fn ThreadDestroy_r(__tid: ::c_int, __priority: ::c_int, __status: *mut ::c_void) ++ -> ::c_int; ++ pub fn ThreadDetach(__tid: ::c_int) -> ::c_int; ++ pub fn ThreadDetach_r(__tid: ::c_int) -> ::c_int; ++ pub fn ThreadJoin(__tid: ::c_int, __status: *mut *mut ::c_void) -> ::c_int; ++ pub fn ThreadJoin_r(__tid: ::c_int, __status: *mut *mut ::c_void) -> ::c_int; ++ pub fn ThreadCancel(__tid: ::c_int, __canstub: unsafe extern "C" fn()) -> ::c_int; ++ pub fn ThreadCancel_r(__tid: ::c_int, __canstub: unsafe extern "C" fn()) -> ::c_int; ++ pub fn ThreadCtl(__cmd: ::c_int, __data: *mut ::c_void) -> ::c_int; ++ pub fn ThreadCtl_r(__cmd: ::c_int, __data: *mut ::c_void) -> ::c_int; ++ pub fn ThreadCtlExt( ++ __pid: ::pid_t, ++ __tid: ::c_int, ++ __cmd: ::c_int, ++ __data: *mut ::c_void, ++ ) -> ::c_int; ++ pub fn ThreadCtlExt_r( ++ __pid: ::pid_t, ++ __tid: ::c_int, ++ __cmd: ::c_int, ++ __data: *mut ::c_void, ++ ) -> ::c_int; ++ ++ pub fn InterruptHookTrace( ++ __handler: ::Option *const ::sigevent>, ++ __flags: ::c_uint, ++ ) -> ::c_int; ++ pub fn InterruptHookIdle( ++ __handler: ::Option, ++ __flags: ::c_uint, ++ ) -> ::c_int; ++ pub fn InterruptHookIdle2( ++ __handler: ::Option< ++ unsafe extern "C" fn(arg1: ::c_uint, arg2: *mut syspage_entry, arg3: *mut _idle_hook), ++ >, ++ __flags: ::c_uint, ++ ) -> ::c_int; ++ pub fn InterruptHookOverdriveEvent(__event: *const ::sigevent, __flags: ::c_uint) -> ::c_int; ++ pub fn InterruptAttachEvent( ++ __intr: ::c_int, ++ __event: *const ::sigevent, ++ __flags: ::c_uint, ++ ) -> ::c_int; ++ pub fn InterruptAttachEvent_r( ++ __intr: ::c_int, ++ __event: *const ::sigevent, ++ __flags: ::c_uint, ++ ) -> ::c_int; ++ pub fn InterruptAttach( ++ __intr: ::c_int, ++ __handler: ::Option< ++ unsafe extern "C" fn(__area: *mut ::c_void, __id: ::c_int) -> *const ::sigevent, ++ >, ++ __area: *const ::c_void, ++ __size: ::c_int, ++ __flags: ::c_uint, ++ ) -> ::c_int; ++ pub fn InterruptAttach_r( ++ __intr: ::c_int, ++ __handler: ::Option< ++ unsafe extern "C" fn(__area: *mut ::c_void, __id: ::c_int) -> *const ::sigevent, ++ >, ++ __area: *const ::c_void, ++ __size: ::c_int, ++ __flags: ::c_uint, ++ ) -> ::c_int; ++ pub fn InterruptAttachArray( ++ __intr: ::c_int, ++ __handler: ::Option< ++ unsafe extern "C" fn(__area: *mut ::c_void, __id: ::c_int) -> *const *const ::sigevent, ++ >, ++ __area: *const ::c_void, ++ __size: ::c_int, ++ __flags: ::c_uint, ++ ) -> ::c_int; ++ pub fn InterruptAttachArray_r( ++ __intr: ::c_int, ++ __handler: ::Option< ++ unsafe extern "C" fn(__area: *mut ::c_void, __id: ::c_int) -> *const *const ::sigevent, ++ >, ++ __area: *const ::c_void, ++ __size: ::c_int, ++ __flags: ::c_uint, ++ ) -> ::c_int; ++ pub fn InterruptDetach(__id: ::c_int) -> ::c_int; ++ pub fn InterruptDetach_r(__id: ::c_int) -> ::c_int; ++ pub fn InterruptWait(__flags: ::c_int, __timeout: *const u64) -> ::c_int; ++ pub fn InterruptWait_r(__flags: ::c_int, __timeout: *const u64) -> ::c_int; ++ pub fn InterruptCharacteristic( ++ __type: ::c_int, ++ __id: ::c_int, ++ __new: *mut ::c_uint, ++ __old: *mut ::c_uint, ++ ) -> ::c_int; ++ pub fn InterruptCharacteristic_r( ++ __type: ::c_int, ++ __id: ::c_int, ++ __new: *mut ::c_uint, ++ __old: *mut ::c_uint, ++ ) -> ::c_int; ++ ++ pub fn SchedGet(__pid: ::pid_t, __tid: ::c_int, __param: *mut ::sched_param) -> ::c_int; ++ pub fn SchedGet_r(__pid: ::pid_t, __tid: ::c_int, __param: *mut ::sched_param) -> ::c_int; ++ pub fn SchedGetCpuNum() -> ::c_uint; ++ pub fn SchedSet( ++ __pid: ::pid_t, ++ __tid: ::c_int, ++ __algorithm: ::c_int, ++ __param: *const ::sched_param, ++ ) -> ::c_int; ++ pub fn SchedSet_r( ++ __pid: ::pid_t, ++ __tid: ::c_int, ++ __algorithm: ::c_int, ++ __param: *const ::sched_param, ++ ) -> ::c_int; ++ pub fn SchedInfo(__pid: ::pid_t, __algorithm: ::c_int, __info: *mut ::_sched_info) -> ::c_int; ++ pub fn SchedInfo_r(__pid: ::pid_t, __algorithm: ::c_int, __info: *mut ::_sched_info) ++ -> ::c_int; ++ pub fn SchedYield() -> ::c_int; ++ pub fn SchedYield_r() -> ::c_int; ++ pub fn SchedCtl(__cmd: ::c_int, __data: *mut ::c_void, __length: usize) -> ::c_int; ++ pub fn SchedCtl_r(__cmd: ::c_int, __data: *mut ::c_void, __length: usize) -> ::c_int; ++ pub fn SchedJobCreate(__job: *mut nto_job_t) -> ::c_int; ++ pub fn SchedJobCreate_r(__job: *mut nto_job_t) -> ::c_int; ++ pub fn SchedJobDestroy(__job: *mut nto_job_t) -> ::c_int; ++ pub fn SchedJobDestroy_r(__job: *mut nto_job_t) -> ::c_int; ++ pub fn SchedWaypoint( ++ __job: *mut nto_job_t, ++ __new: *const i64, ++ __max: *const i64, ++ __old: *mut i64, ++ ) -> ::c_int; ++ pub fn SchedWaypoint_r( ++ __job: *mut nto_job_t, ++ __new: *const i64, ++ __max: *const i64, ++ __old: *mut i64, ++ ) -> ::c_int; ++ ++ pub fn TimerCreate(__id: ::clockid_t, __notify: *const ::sigevent) -> ::c_int; ++ pub fn TimerCreate_r(__id: ::clockid_t, __notify: *const ::sigevent) -> ::c_int; ++ pub fn TimerDestroy(__id: ::timer_t) -> ::c_int; ++ pub fn TimerDestroy_r(__id: ::timer_t) -> ::c_int; ++ pub fn TimerSettime( ++ __id: ::timer_t, ++ __flags: ::c_int, ++ __itime: *const ::_itimer, ++ __oitime: *mut ::_itimer, ++ ) -> ::c_int; ++ pub fn TimerSettime_r( ++ __id: ::timer_t, ++ __flags: ::c_int, ++ __itime: *const ::_itimer, ++ __oitime: *mut ::_itimer, ++ ) -> ::c_int; ++ pub fn TimerInfo( ++ __pid: ::pid_t, ++ __id: ::timer_t, ++ __flags: ::c_int, ++ __info: *mut ::_timer_info, ++ ) -> ::c_int; ++ pub fn TimerInfo_r( ++ __pid: ::pid_t, ++ __id: ::timer_t, ++ __flags: ::c_int, ++ __info: *mut ::_timer_info, ++ ) -> ::c_int; ++ pub fn TimerAlarm( ++ __id: ::clockid_t, ++ __itime: *const ::_itimer, ++ __otime: *mut ::_itimer, ++ ) -> ::c_int; ++ pub fn TimerAlarm_r( ++ __id: ::clockid_t, ++ __itime: *const ::_itimer, ++ __otime: *mut ::_itimer, ++ ) -> ::c_int; ++ pub fn TimerTimeout( ++ __id: ::clockid_t, ++ __flags: ::c_int, ++ __notify: *const ::sigevent, ++ __ntime: *const u64, ++ __otime: *mut u64, ++ ) -> ::c_int; ++ pub fn TimerTimeout_r( ++ __id: ::clockid_t, ++ __flags: ::c_int, ++ __notify: *const ::sigevent, ++ __ntime: *const u64, ++ __otime: *mut u64, ++ ) -> ::c_int; ++ ++ pub fn SyncTypeCreate( ++ __type: ::c_uint, ++ __sync: *mut ::sync_t, ++ __attr: *const ::_sync_attr, ++ ) -> ::c_int; ++ pub fn SyncTypeCreate_r( ++ __type: ::c_uint, ++ __sync: *mut ::sync_t, ++ __attr: *const ::_sync_attr, ++ ) -> ::c_int; ++ pub fn SyncDestroy(__sync: *mut ::sync_t) -> ::c_int; ++ pub fn SyncDestroy_r(__sync: *mut ::sync_t) -> ::c_int; ++ pub fn SyncCtl(__cmd: ::c_int, __sync: *mut ::sync_t, __data: *mut ::c_void) -> ::c_int; ++ pub fn SyncCtl_r(__cmd: ::c_int, __sync: *mut ::sync_t, __data: *mut ::c_void) -> ::c_int; ++ pub fn SyncMutexEvent(__sync: *mut ::sync_t, event: *const ::sigevent) -> ::c_int; ++ pub fn SyncMutexEvent_r(__sync: *mut ::sync_t, event: *const ::sigevent) -> ::c_int; ++ pub fn SyncMutexLock(__sync: *mut ::sync_t) -> ::c_int; ++ pub fn SyncMutexLock_r(__sync: *mut ::sync_t) -> ::c_int; ++ pub fn SyncMutexUnlock(__sync: *mut ::sync_t) -> ::c_int; ++ pub fn SyncMutexUnlock_r(__sync: *mut ::sync_t) -> ::c_int; ++ pub fn SyncMutexRevive(__sync: *mut ::sync_t) -> ::c_int; ++ pub fn SyncMutexRevive_r(__sync: *mut ::sync_t) -> ::c_int; ++ pub fn SyncCondvarWait(__sync: *mut ::sync_t, __mutex: *mut ::sync_t) -> ::c_int; ++ pub fn SyncCondvarWait_r(__sync: *mut ::sync_t, __mutex: *mut ::sync_t) -> ::c_int; ++ pub fn SyncCondvarSignal(__sync: *mut ::sync_t, __all: ::c_int) -> ::c_int; ++ pub fn SyncCondvarSignal_r(__sync: *mut ::sync_t, __all: ::c_int) -> ::c_int; ++ pub fn SyncSemPost(__sync: *mut ::sync_t) -> ::c_int; ++ pub fn SyncSemPost_r(__sync: *mut ::sync_t) -> ::c_int; ++ pub fn SyncSemWait(__sync: *mut ::sync_t, __tryto: ::c_int) -> ::c_int; ++ pub fn SyncSemWait_r(__sync: *mut ::sync_t, __tryto: ::c_int) -> ::c_int; ++ ++ pub fn ClockTime(__id: ::clockid_t, _new: *const u64, __old: *mut u64) -> ::c_int; ++ pub fn ClockTime_r(__id: ::clockid_t, _new: *const u64, __old: *mut u64) -> ::c_int; ++ pub fn ClockAdjust( ++ __id: ::clockid_t, ++ _new: *const ::_clockadjust, ++ __old: *mut ::_clockadjust, ++ ) -> ::c_int; ++ pub fn ClockAdjust_r( ++ __id: ::clockid_t, ++ _new: *const ::_clockadjust, ++ __old: *mut ::_clockadjust, ++ ) -> ::c_int; ++ pub fn ClockPeriod( ++ __id: ::clockid_t, ++ _new: *const ::_clockperiod, ++ __old: *mut ::_clockperiod, ++ __reserved: ::c_int, ++ ) -> ::c_int; ++ pub fn ClockPeriod_r( ++ __id: ::clockid_t, ++ _new: *const ::_clockperiod, ++ __old: *mut ::_clockperiod, ++ __reserved: ::c_int, ++ ) -> ::c_int; ++ pub fn ClockId(__pid: ::pid_t, __tid: ::c_int) -> ::c_int; ++ pub fn ClockId_r(__pid: ::pid_t, __tid: ::c_int) -> ::c_int; ++ ++ // ++ //TODO: The following commented out functions are implemented in assembly. ++ // We can implmement them either via a C stub or rust's inline assembly. ++ // ++ //pub fn InterruptEnable(); ++ //pub fn InterruptDisable(); ++ pub fn InterruptMask(__intr: ::c_int, __id: ::c_int) -> ::c_int; ++ pub fn InterruptUnmask(__intr: ::c_int, __id: ::c_int) -> ::c_int; ++ //pub fn InterruptLock(__spin: *mut ::intrspin); ++ //pub fn InterruptUnlock(__spin: *mut ::intrspin); ++ //pub fn InterruptStatus() -> ::c_uint; ++} +diff --git a/vendor/libc/src/unix/nto/x86_64.rs b/vendor/libc/src/unix/nto/x86_64.rs +new file mode 100644 +index 0000000..3a1d230 +--- /dev/null ++++ b/vendor/libc/src/unix/nto/x86_64.rs +@@ -0,0 +1,132 @@ ++pub type c_char = i8; ++pub type wchar_t = u32; ++pub type c_long = i64; ++pub type c_ulong = u64; ++pub type time_t = i64; ++ ++s! { ++ #[repr(align(8))] ++ pub struct x86_64_cpu_registers { ++ pub rdi: u64, ++ pub rsi: u64, ++ pub rdx: u64, ++ pub r10: u64, ++ pub r8: u64, ++ pub r9: u64, ++ pub rax: u64, ++ pub rbx: u64, ++ pub rbp: u64, ++ pub rcx: u64, ++ pub r11: u64, ++ pub r12: u64, ++ pub r13: u64, ++ pub r14: u64, ++ pub r15: u64, ++ pub rip: u64, ++ pub cs: u32, ++ rsvd1: u32, ++ pub rflags: u64, ++ pub rsp: u64, ++ pub ss: u32, ++ rsvd2: u32, ++ } ++ ++ #[repr(align(8))] ++ pub struct mcontext_t { ++ pub cpu: x86_64_cpu_registers, ++ #[cfg(libc_union)] ++ pub fpu: x86_64_fpu_registers, ++ #[cfg(not(libc_union))] ++ __reserved: [u8; 1024], ++ } ++ ++ pub struct stack_t { ++ pub ss_sp: *mut ::c_void, ++ pub ss_size: ::size_t, ++ pub ss_flags: ::c_int, ++ } ++ ++ pub struct fsave_area_64 { ++ pub fpu_control_word: u32, ++ pub fpu_status_word: u32, ++ pub fpu_tag_word: u32, ++ pub fpu_ip: u32, ++ pub fpu_cs: u32, ++ pub fpu_op: u32, ++ pub fpu_ds: u32, ++ pub st_regs: [u8; 80], ++ } ++ ++ pub struct fxsave_area_64 { ++ pub fpu_control_word: u16, ++ pub fpu_status_word: u16, ++ pub fpu_tag_word: u16, ++ pub fpu_operand: u16, ++ pub fpu_rip: u64, ++ pub fpu_rdp: u64, ++ pub mxcsr: u32, ++ pub mxcsr_mask: u32, ++ pub st_regs: [u8; 128], ++ pub xmm_regs: [u8; 128], ++ reserved2: [u8; 224], ++ } ++ ++ pub struct fpu_extention_savearea_64 { ++ pub other: [u8; 512], ++ pub xstate_bv: u64, ++ pub xstate_undef: [u64; 7], ++ pub xstate_info: [u8; 224], ++ } ++} ++ ++s_no_extra_traits! { ++ #[cfg(libc_union)] ++ pub union x86_64_fpu_registers { ++ pub fsave_area: fsave_area_64, ++ pub fxsave_area: fxsave_area_64, ++ pub xsave_area: fpu_extention_savearea_64, ++ pub data: [u8; 1024], ++ } ++} ++ ++cfg_if! { ++ if #[cfg(feature = "extra_traits")] { ++ #[cfg(libc_union)] ++ impl Eq for x86_64_fpu_registers {} ++ ++ #[cfg(libc_union)] ++ impl PartialEq for x86_64_fpu_registers { ++ fn eq(&self, other: &x86_64_fpu_registers) -> bool { ++ unsafe { ++ self.fsave_area == other.fsave_area ++ || self.fxsave_area == other.fxsave_area ++ || self.xsave_area == other.xsave_area ++ } ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for x86_64_fpu_registers { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ unsafe { ++ f.debug_struct("x86_64_fpu_registers") ++ .field("fsave_area", &self.fsave_area) ++ .field("fxsave_area", &self.fxsave_area) ++ .field("xsave_area", &self.xsave_area) ++ .finish() ++ } ++ } ++ } ++ ++ #[cfg(libc_union)] ++ impl ::hash::Hash for x86_64_fpu_registers { ++ fn hash(&self, state: &mut H) { ++ unsafe { ++ self.fsave_area.hash(state); ++ self.fxsave_area.hash(state); ++ self.xsave_area.hash(state); ++ } ++ } ++ } ++ } ++} +diff --git a/vendor/libc/src/unix/redox/mod.rs b/vendor/libc/src/unix/redox/mod.rs +index 1601a8a..dec47c6 100644 +--- a/vendor/libc/src/unix/redox/mod.rs ++++ b/vendor/libc/src/unix/redox/mod.rs +@@ -1,8 +1,20 @@ + pub type c_char = i8; +-pub type c_long = i64; +-pub type c_ulong = u64; + pub type wchar_t = i32; + ++cfg_if! { ++ if #[cfg(target_pointer_width = "32")] { ++ pub type c_long = i32; ++ pub type c_ulong = u32; ++ } ++} ++ ++cfg_if! { ++ if #[cfg(target_pointer_width = "64")] { ++ pub type c_long = i64; ++ pub type c_ulong = u64; ++ } ++} ++ + pub type blkcnt_t = ::c_ulong; + pub type blksize_t = ::c_long; + pub type clock_t = ::c_long; +@@ -14,7 +26,7 @@ pub type ino_t = ::c_ulong; + pub type mode_t = ::c_int; + pub type nfds_t = ::c_ulong; + pub type nlink_t = ::c_ulong; +-pub type off_t = ::c_long; ++pub type off_t = ::c_longlong; + pub type pthread_t = *mut ::c_void; + pub type pthread_attr_t = *mut ::c_void; + pub type pthread_cond_t = *mut ::c_void; +@@ -34,7 +46,7 @@ pub type socklen_t = u32; + pub type speed_t = u32; + pub type suseconds_t = ::c_int; + pub type tcflag_t = u32; +-pub type time_t = ::c_long; ++pub type time_t = ::c_longlong; + + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub enum timezone {} +@@ -151,12 +163,20 @@ s! { + } + + pub struct sigaction { +- pub sa_handler: ::sighandler_t, ++ pub sa_sigaction: ::sighandler_t, + pub sa_flags: ::c_ulong, + pub sa_restorer: ::Option, + pub sa_mask: ::sigset_t, + } + ++ pub struct siginfo_t { ++ pub si_signo: ::c_int, ++ pub si_errno: ::c_int, ++ pub si_code: ::c_int, ++ _pad: [::c_int; 29], ++ _align: [usize; 0], ++ } ++ + pub struct sockaddr { + pub sa_family: ::sa_family_t, + pub sa_data: [::c_char; 14], +@@ -367,6 +387,7 @@ pub const EPROTONOSUPPORT: ::c_int = 93; /* Protocol not supported */ + pub const ESOCKTNOSUPPORT: ::c_int = 94; /* Socket type not supported */ + /* Operation not supported on transport endpoint */ + pub const EOPNOTSUPP: ::c_int = 95; ++pub const ENOTSUP: ::c_int = EOPNOTSUPP; + pub const EPFNOSUPPORT: ::c_int = 96; /* Protocol family not supported */ + /* Address family not supported by protocol */ + pub const EAFNOSUPPORT: ::c_int = 97; +@@ -438,6 +459,15 @@ pub const O_SYMLINK: ::c_int = 0x4000_0000; + // FIXME: Fix negative values missing from includes + pub const O_NOFOLLOW: ::c_int = -0x8000_0000; + ++// locale.h ++pub const LC_ALL: ::c_int = 0; ++pub const LC_COLLATE: ::c_int = 1; ++pub const LC_CTYPE: ::c_int = 2; ++pub const LC_MESSAGES: ::c_int = 3; ++pub const LC_MONETARY: ::c_int = 4; ++pub const LC_NUMERIC: ::c_int = 5; ++pub const LC_TIME: ::c_int = 6; ++ + // netdb.h + pub const AI_PASSIVE: ::c_int = 0x0001; + pub const AI_CANONNAME: ::c_int = 0x0002; +@@ -481,6 +511,7 @@ pub const IP_MULTICAST_TTL: ::c_int = 33; + pub const IP_MULTICAST_LOOP: ::c_int = 34; + pub const IP_ADD_MEMBERSHIP: ::c_int = 35; + pub const IP_DROP_MEMBERSHIP: ::c_int = 36; ++pub const IPPROTO_RAW: ::c_int = 255; + // } + + // netinet/tcp.h +@@ -607,6 +638,7 @@ pub const EXIT_FAILURE: ::c_int = 1; + + // sys/ioctl.h + // FIXME: relibc { ++pub const FIONREAD: ::c_ulong = 0x541B; + pub const FIONBIO: ::c_ulong = 0x5421; + pub const FIOCLEX: ::c_ulong = 0x5451; + // } +@@ -624,6 +656,12 @@ pub const PROT_READ: ::c_int = 0x0004; + pub const PROT_WRITE: ::c_int = 0x0002; + pub const PROT_EXEC: ::c_int = 0x0001; + ++pub const MADV_NORMAL: ::c_int = 0; ++pub const MADV_RANDOM: ::c_int = 1; ++pub const MADV_SEQUENTIAL: ::c_int = 2; ++pub const MADV_WILLNEED: ::c_int = 3; ++pub const MADV_DONTNEED: ::c_int = 4; ++ + pub const MAP_SHARED: ::c_int = 0x0001; + pub const MAP_PRIVATE: ::c_int = 0x0002; + pub const MAP_ANON: ::c_int = 0x0020; +@@ -653,6 +691,7 @@ pub const MSG_EOR: ::c_int = 128; + pub const MSG_OOB: ::c_int = 1; + pub const MSG_PEEK: ::c_int = 2; + pub const MSG_TRUNC: ::c_int = 32; ++pub const MSG_DONTWAIT: ::c_int = 64; + pub const MSG_WAITALL: ::c_int = 256; + pub const SHUT_RD: ::c_int = 0; + pub const SHUT_WR: ::c_int = 1; +@@ -692,25 +731,24 @@ pub const SOCK_SEQPACKET: ::c_int = 5; + pub const SOL_SOCKET: ::c_int = 1; + + // sys/termios.h +-pub const NCCS: usize = 32; +- +-pub const VINTR: usize = 0; +-pub const VQUIT: usize = 1; +-pub const VERASE: usize = 2; +-pub const VKILL: usize = 3; +-pub const VEOF: usize = 4; +-pub const VTIME: usize = 5; +-pub const VMIN: usize = 6; ++pub const VEOF: usize = 0; ++pub const VEOL: usize = 1; ++pub const VEOL2: usize = 2; ++pub const VERASE: usize = 3; ++pub const VWERASE: usize = 4; ++pub const VKILL: usize = 5; ++pub const VREPRINT: usize = 6; + pub const VSWTC: usize = 7; +-pub const VSTART: usize = 8; +-pub const VSTOP: usize = 9; ++pub const VINTR: usize = 8; ++pub const VQUIT: usize = 9; + pub const VSUSP: usize = 10; +-pub const VEOL: usize = 11; +-pub const VREPRINT: usize = 12; +-pub const VDISCARD: usize = 13; +-pub const VWERASE: usize = 14; +-pub const VLNEXT: usize = 15; +-pub const VEOL2: usize = 16; ++pub const VSTART: usize = 12; ++pub const VSTOP: usize = 13; ++pub const VLNEXT: usize = 14; ++pub const VDISCARD: usize = 15; ++pub const VMIN: usize = 16; ++pub const VTIME: usize = 17; ++pub const NCCS: usize = 32; + + pub const IGNBRK: ::tcflag_t = 0o000_001; + pub const BRKINT: ::tcflag_t = 0o000_002; +@@ -721,25 +759,17 @@ pub const ISTRIP: ::tcflag_t = 0o000_040; + pub const INLCR: ::tcflag_t = 0o000_100; + pub const IGNCR: ::tcflag_t = 0o000_200; + pub const ICRNL: ::tcflag_t = 0o000_400; +-pub const IUCLC: ::tcflag_t = 0o001_000; +-pub const IXON: ::tcflag_t = 0o002_000; +-pub const IXANY: ::tcflag_t = 0o004_000; +-pub const IXOFF: ::tcflag_t = 0o010_000; +-pub const IMAXBEL: ::tcflag_t = 0o020_000; +-pub const IUTF8: ::tcflag_t = 0o040_000; ++pub const IXON: ::tcflag_t = 0o001_000; ++pub const IXOFF: ::tcflag_t = 0o002_000; + + pub const OPOST: ::tcflag_t = 0o000_001; +-pub const OLCUC: ::tcflag_t = 0o000_002; +-pub const ONLCR: ::tcflag_t = 0o000_004; ++pub const ONLCR: ::tcflag_t = 0o000_002; ++pub const OLCUC: ::tcflag_t = 0o000_004; + pub const OCRNL: ::tcflag_t = 0o000_010; + pub const ONOCR: ::tcflag_t = 0o000_020; +-pub const ONLRET: ::tcflag_t = 0o00_0040; +-pub const OFILL: ::tcflag_t = 0o000_100; +-pub const OFDEL: ::tcflag_t = 0o000_200; +- +-pub const VTDLY: usize = 0o040_000; +-pub const VT0: usize = 0o000_000; +-pub const VT1: usize = 0o040_000; ++pub const ONLRET: ::tcflag_t = 0o000_040; ++pub const OFILL: ::tcflag_t = 0o0000_100; ++pub const OFDEL: ::tcflag_t = 0o0000_200; + + pub const B0: speed_t = 0o000_000; + pub const B50: speed_t = 0o000_001; +@@ -758,43 +788,45 @@ pub const B9600: speed_t = 0o000_015; + pub const B19200: speed_t = 0o000_016; + pub const B38400: speed_t = 0o000_017; + +-pub const B57600: speed_t = 0o010_001; +-pub const B115200: speed_t = 0o010_002; +-pub const B230400: speed_t = 0o010_003; +-pub const B460800: speed_t = 0o010_004; +-pub const B500000: speed_t = 0o010_005; +-pub const B576000: speed_t = 0o010_006; +-pub const B921600: speed_t = 0o010_007; +-pub const B1000000: speed_t = 0o010_010; +-pub const B1152000: speed_t = 0o010_011; +-pub const B1500000: speed_t = 0o010_012; +-pub const B2000000: speed_t = 0o010_013; +-pub const B2500000: speed_t = 0o010_014; +-pub const B3000000: speed_t = 0o010_015; +-pub const B3500000: speed_t = 0o010_016; +-pub const B4000000: speed_t = 0o010_017; +- +-pub const CSIZE: ::tcflag_t = 0o000_060; ++pub const B57600: speed_t = 0o0_020; ++pub const B115200: speed_t = 0o0_021; ++pub const B230400: speed_t = 0o0_022; ++pub const B460800: speed_t = 0o0_023; ++pub const B500000: speed_t = 0o0_024; ++pub const B576000: speed_t = 0o0_025; ++pub const B921600: speed_t = 0o0_026; ++pub const B1000000: speed_t = 0o0_027; ++pub const B1152000: speed_t = 0o0_030; ++pub const B1500000: speed_t = 0o0_031; ++pub const B2000000: speed_t = 0o0_032; ++pub const B2500000: speed_t = 0o0_033; ++pub const B3000000: speed_t = 0o0_034; ++pub const B3500000: speed_t = 0o0_035; ++pub const B4000000: speed_t = 0o0_036; ++ ++pub const CSIZE: ::tcflag_t = 0o001_400; + pub const CS5: ::tcflag_t = 0o000_000; +-pub const CS6: ::tcflag_t = 0o000_020; +-pub const CS7: ::tcflag_t = 0o000_040; +-pub const CS8: ::tcflag_t = 0o000_060; +-pub const CSTOPB: ::tcflag_t = 0o000_100; +-pub const CREAD: ::tcflag_t = 0o000_200; +-pub const PARENB: ::tcflag_t = 0o000_400; +-pub const PARODD: ::tcflag_t = 0o001_000; +-pub const HUPCL: ::tcflag_t = 0o002_000; +-pub const CLOCAL: ::tcflag_t = 0o004_000; +- +-pub const ISIG: ::tcflag_t = 0o000_001; +-pub const ICANON: ::tcflag_t = 0o000_002; +-pub const ECHO: ::tcflag_t = 0o000_010; +-pub const ECHOE: ::tcflag_t = 0o000_020; +-pub const ECHOK: ::tcflag_t = 0o000_040; +-pub const ECHONL: ::tcflag_t = 0o000_100; +-pub const NOFLSH: ::tcflag_t = 0o000_200; +-pub const TOSTOP: ::tcflag_t = 0o000_400; +-pub const IEXTEN: ::tcflag_t = 0o100_000; ++pub const CS6: ::tcflag_t = 0o000_400; ++pub const CS7: ::tcflag_t = 0o001_000; ++pub const CS8: ::tcflag_t = 0o001_400; ++ ++pub const CSTOPB: ::tcflag_t = 0o002_000; ++pub const CREAD: ::tcflag_t = 0o004_000; ++pub const PARENB: ::tcflag_t = 0o010_000; ++pub const PARODD: ::tcflag_t = 0o020_000; ++pub const HUPCL: ::tcflag_t = 0o040_000; ++ ++pub const CLOCAL: ::tcflag_t = 0o0100000; ++ ++pub const ISIG: ::tcflag_t = 0x0000_0080; ++pub const ICANON: ::tcflag_t = 0x0000_0100; ++pub const ECHO: ::tcflag_t = 0x0000_0008; ++pub const ECHOE: ::tcflag_t = 0x0000_0002; ++pub const ECHOK: ::tcflag_t = 0x0000_0004; ++pub const ECHONL: ::tcflag_t = 0x0000_0010; ++pub const NOFLSH: ::tcflag_t = 0x8000_0000; ++pub const TOSTOP: ::tcflag_t = 0x0040_0000; ++pub const IEXTEN: ::tcflag_t = 0x0000_0400; + + pub const TCOOFF: ::c_int = 0; + pub const TCOON: ::c_int = 1; +@@ -826,6 +858,8 @@ pub const __WCLONE: ::c_int = 0x8000_0000; + // time.h + pub const CLOCK_REALTIME: ::c_int = 1; + pub const CLOCK_MONOTONIC: ::c_int = 4; ++pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 2; ++pub const CLOCKS_PER_SEC: ::clock_t = 1_000_000; + + // unistd.h + // POSIX.1 { +@@ -898,7 +932,7 @@ f! { + return + } + +- pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool { ++ pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0 +@@ -959,6 +993,7 @@ extern "C" { + + // unistd.h + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; ++ pub fn getdtablesize() -> ::c_int; + + // malloc.h + pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; +@@ -1006,6 +1041,15 @@ extern "C" { + set: *const ::sigset_t, + oldset: *mut ::sigset_t, + ) -> ::c_int; ++ pub fn pthread_cancel(thread: ::pthread_t) -> ::c_int; ++ pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; ++ ++ // stdlib.h ++ pub fn reallocarray(ptr: *mut ::c_void, nmemb: ::size_t, size: ::size_t) -> *mut ::c_void; ++ ++ // string.h ++ pub fn strlcat(dst: *mut ::c_char, src: *const ::c_char, siz: ::size_t) -> ::size_t; ++ pub fn strlcpy(dst: *mut ::c_char, src: *const ::c_char, siz: ::size_t) -> ::size_t; + + // sys/epoll.h + pub fn epoll_create(size: ::c_int) -> ::c_int; +@@ -1023,6 +1067,7 @@ extern "C" { + pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; + + // sys/mman.h ++ pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn shm_open(name: *const c_char, oflag: ::c_int, mode: mode_t) -> ::c_int; +@@ -1056,6 +1101,9 @@ extern "C" { + // time.h + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::timezone) -> ::c_int; + pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; ++ ++ // strings.h ++ pub fn explicit_bzero(p: *mut ::c_void, len: ::size_t); + } + + cfg_if! { +diff --git a/vendor/libc/src/unix/solarish/compat.rs b/vendor/libc/src/unix/solarish/compat.rs +index 4a232f0..cbf955a 100644 +--- a/vendor/libc/src/unix/solarish/compat.rs ++++ b/vendor/libc/src/unix/solarish/compat.rs +@@ -1,6 +1,7 @@ + // Common functions that are unfortunately missing on illumos and + // Solaris, but often needed by other crates. + ++use core::cmp::min; + use unix::solarish::*; + + const PTEM: &[u8] = b"ptem\0"; +@@ -169,3 +170,51 @@ pub unsafe fn forkpty( + + 0 + } ++ ++pub unsafe fn getpwent_r( ++ pwd: *mut passwd, ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ result: *mut *mut passwd, ++) -> ::c_int { ++ let old_errno = *::___errno(); ++ *::___errno() = 0; ++ *result = native_getpwent_r( ++ pwd, ++ buf, ++ min(buflen, ::c_int::max_value() as ::size_t) as ::c_int, ++ ); ++ ++ let ret = if (*result).is_null() { ++ *::___errno() ++ } else { ++ 0 ++ }; ++ *::___errno() = old_errno; ++ ++ ret ++} ++ ++pub unsafe fn getgrent_r( ++ grp: *mut ::group, ++ buf: *mut ::c_char, ++ buflen: ::size_t, ++ result: *mut *mut ::group, ++) -> ::c_int { ++ let old_errno = *::___errno(); ++ *::___errno() = 0; ++ *result = native_getgrent_r( ++ grp, ++ buf, ++ min(buflen, ::c_int::max_value() as ::size_t) as ::c_int, ++ ); ++ ++ let ret = if (*result).is_null() { ++ *::___errno() ++ } else { ++ 0 ++ }; ++ *::___errno() = old_errno; ++ ++ ret ++} +diff --git a/vendor/libc/src/unix/solarish/illumos.rs b/vendor/libc/src/unix/solarish/illumos.rs +index 730bb69..404f013 100644 +--- a/vendor/libc/src/unix/solarish/illumos.rs ++++ b/vendor/libc/src/unix/solarish/illumos.rs +@@ -13,6 +13,12 @@ s! { + pub shm_ctime: ::time_t, + pub shm_pad4: [i64; 4], + } ++ ++ pub struct fil_info { ++ pub fi_flags: ::c_int, ++ pub fi_pos: ::c_int, ++ pub fi_name: [::c_char; ::FILNAME_MAX as usize], ++ } + } + + pub const AF_LOCAL: ::c_int = 1; // AF_UNIX +@@ -27,14 +33,56 @@ pub const TCP_KEEPCNT: ::c_int = 35; + pub const TCP_KEEPINTVL: ::c_int = 36; + pub const TCP_CONGESTION: ::c_int = 37; + +-pub const F_OFD_GETLK: ::c_int = 50; +-pub const F_OFD_SETLKL: ::c_int = 51; +-pub const F_OFD_SETLKW: ::c_int = 52; +-pub const F_FLOCK: ::c_int = 55; +-pub const F_FLOCKW: ::c_int = 56; ++// These constants are correct for 64-bit programs or 32-bit programs that are ++// not using large-file mode. If Rust ever supports anything other than 64-bit ++// compilation on illumos, this may require adjustment: ++pub const F_OFD_GETLK: ::c_int = 47; ++pub const F_OFD_SETLK: ::c_int = 48; ++pub const F_OFD_SETLKW: ::c_int = 49; ++pub const F_FLOCK: ::c_int = 53; ++pub const F_FLOCKW: ::c_int = 54; ++ ++pub const F_DUPFD_CLOEXEC: ::c_int = 37; ++pub const F_DUP2FD_CLOEXEC: ::c_int = 36; ++ ++pub const FIL_ATTACH: ::c_int = 0x1; ++pub const FIL_DETACH: ::c_int = 0x2; ++pub const FIL_LIST: ::c_int = 0x3; ++pub const FILNAME_MAX: ::c_int = 32; ++pub const FILF_PROG: ::c_int = 0x1; ++pub const FILF_AUTO: ::c_int = 0x2; ++pub const FILF_BYPASS: ::c_int = 0x4; ++pub const SOL_FILTER: ::c_int = 0xfffc; ++ ++pub const MADV_PURGE: ::c_int = 9; ++ ++pub const B1000000: ::speed_t = 24; ++pub const B1152000: ::speed_t = 25; ++pub const B1500000: ::speed_t = 26; ++pub const B2000000: ::speed_t = 27; ++pub const B2500000: ::speed_t = 28; ++pub const B3000000: ::speed_t = 29; ++pub const B3500000: ::speed_t = 30; ++pub const B4000000: ::speed_t = 31; ++ ++// sys/systeminfo.h ++pub const SI_ADDRESS_WIDTH: ::c_int = 520; + + extern "C" { + pub fn eventfd(init: ::c_uint, flags: ::c_int) -> ::c_int; + + pub fn mincore(addr: ::caddr_t, len: ::size_t, vec: *mut ::c_char) -> ::c_int; ++ ++ pub fn pset_bind_lwp( ++ pset: ::psetid_t, ++ id: ::id_t, ++ pid: ::pid_t, ++ opset: *mut ::psetid_t, ++ ) -> ::c_int; ++ pub fn pset_getloadavg(pset: ::psetid_t, load: *mut ::c_double, num: ::c_int) -> ::c_int; ++ ++ pub fn preadv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) -> ::ssize_t; ++ pub fn pwritev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) ++ -> ::ssize_t; ++ pub fn getpagesizes2(pagesize: *mut ::size_t, nelem: ::c_int) -> ::c_int; + } +diff --git a/vendor/libc/src/unix/solarish/mod.rs b/vendor/libc/src/unix/solarish/mod.rs +index 6166da5..cc68833 100644 +--- a/vendor/libc/src/unix/solarish/mod.rs ++++ b/vendor/libc/src/unix/solarish/mod.rs +@@ -25,6 +25,10 @@ pub type wchar_t = ::c_int; + pub type nfds_t = ::c_ulong; + pub type projid_t = ::c_int; + pub type zoneid_t = ::c_int; ++pub type psetid_t = ::c_int; ++pub type processorid_t = ::c_int; ++pub type chipid_t = ::c_int; ++pub type ctid_t = ::id_t; + + pub type suseconds_t = ::c_long; + pub type off_t = ::c_long; +@@ -33,6 +37,7 @@ pub type socklen_t = ::c_uint; + pub type sa_family_t = u16; + pub type pthread_t = ::c_uint; + pub type pthread_key_t = ::c_uint; ++pub type thread_t = ::c_uint; + pub type blksize_t = ::c_int; + pub type nl_item = ::c_int; + pub type mqd_t = *mut ::c_void; +@@ -40,6 +45,16 @@ pub type id_t = ::c_int; + pub type idtype_t = ::c_uint; + pub type shmatt_t = ::c_ulong; + ++pub type lgrp_rsrc_t = ::c_int; ++pub type lgrp_affinity_t = ::c_int; ++pub type lgrp_id_t = ::id_t; ++pub type lgrp_mem_size_t = ::c_longlong; ++pub type lgrp_cookie_t = ::uintptr_t; ++pub type lgrp_content_t = ::c_uint; ++pub type lgrp_lat_between_t = ::c_uint; ++pub type lgrp_mem_size_flag_t = ::c_uint; ++pub type lgrp_view_t = ::c_uint; ++ + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub enum timezone {} + impl ::Copy for timezone {} +@@ -68,6 +83,12 @@ s! { + pub imr_interface: in_addr, + } + ++ pub struct ip_mreq_source { ++ pub imr_multiaddr: in_addr, ++ pub imr_sourceaddr: in_addr, ++ pub imr_interface: in_addr, ++ } ++ + pub struct ipc_perm { + pub uid: ::uid_t, + pub gid: ::gid_t, +@@ -264,6 +285,13 @@ s! { + pub f_fstr: [::c_char; 32] + } + ++ pub struct sendfilevec_t { ++ pub sfv_fd: ::c_int, ++ pub sfv_flag: ::c_uint, ++ pub sfv_off: ::off_t, ++ pub sfv_len: ::size_t, ++ } ++ + pub struct sched_param { + pub sched_priority: ::c_int, + sched_pad: [::c_int; 8] +@@ -416,6 +444,35 @@ s! { + pub esterror: i32, + } + ++ pub struct mmapobj_result_t { ++ pub mr_addr: ::caddr_t, ++ pub mr_msize: ::size_t, ++ pub mr_fsize: ::size_t, ++ pub mr_offset: ::size_t, ++ pub mr_prot: ::c_uint, ++ pub mr_flags: ::c_uint, ++ } ++ ++ pub struct lgrp_affinity_args { ++ pub idtype: ::idtype_t, ++ pub id: ::id_t, ++ pub lgrp: ::lgrp_id_t, ++ pub aff: ::lgrp_affinity_t, ++ } ++ ++ pub struct processor_info_t { ++ pub pi_state: ::c_int, ++ pub pi_processor_type: [::c_char; PI_TYPELEN as usize], ++ pub pi_fputypes: [::c_char; PI_FPUTYPE as usize], ++ pub pi_clock: ::c_int, ++ } ++ ++ pub struct option { ++ pub name: *const ::c_char, ++ pub has_arg: ::c_int, ++ pub flag: *mut ::c_int, ++ pub val: ::c_int, ++ } + } + + s_no_extra_traits! { +@@ -473,13 +530,15 @@ s_no_extra_traits! { + __ss_pad2: [u8; 240], + } + ++ #[cfg_attr(all(target_pointer_width = "64", libc_align), repr(align(8)))] + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, ++ #[cfg(target_pointer_width = "64")] + pub si_pad: ::c_int, +- pub si_addr: *mut ::c_void, +- __pad: [u8; 232], ++ ++ __data_pad: [::c_int; SIGINFO_DATA_SIZE], + } + + pub struct sockaddr_dl { +@@ -500,6 +559,20 @@ s_no_extra_traits! { + pub sigev_notify_attributes: *const ::pthread_attr_t, + __sigev_pad2: ::c_int, + } ++ ++ #[cfg(libc_union)] ++ #[cfg_attr(libc_align, repr(align(16)))] ++ pub union pad128_t { ++ // pub _q in this structure would be a "long double", of 16 bytes ++ pub _l: [i32; 4], ++ } ++ ++ #[cfg(libc_union)] ++ #[cfg_attr(libc_align, repr(align(16)))] ++ pub union upad128_t { ++ // pub _q in this structure would be a "long double", of 16 bytes ++ pub _l: [u32; 4], ++ } + } + + cfg_if! { +@@ -716,17 +789,52 @@ cfg_if! { + } + } + ++ impl siginfo_t { ++ /// The siginfo_t will have differing contents based on the delivered signal. Based on ++ /// `si_signo`, this determines how many of the `c_int` pad fields contain valid data ++ /// exposed by the C unions. ++ /// ++ /// It is not yet exhausitive for the OS-defined types, and defaults to assuming the ++ /// entire data pad area is "valid" for otherwise unrecognized signal numbers. ++ fn data_field_count(&self) -> usize { ++ match self.si_signo { ++ ::SIGSEGV | ::SIGBUS | ::SIGILL | ::SIGTRAP | ::SIGFPE => { ++ ::mem::size_of::() / ::mem::size_of::<::c_int>() ++ } ++ ::SIGCLD => ::mem::size_of::() / ::mem::size_of::<::c_int>(), ++ ::SIGHUP ++ | ::SIGINT ++ | ::SIGQUIT ++ | ::SIGABRT ++ | ::SIGSYS ++ | ::SIGPIPE ++ | ::SIGALRM ++ | ::SIGTERM ++ | ::SIGUSR1 ++ | ::SIGUSR2 ++ | ::SIGPWR ++ | ::SIGWINCH ++ | ::SIGURG => ::mem::size_of::() / ::mem::size_of::<::c_int>(), ++ _ => SIGINFO_DATA_SIZE, ++ } ++ } ++ } + impl PartialEq for siginfo_t { + fn eq(&self, other: &siginfo_t) -> bool { +- self.si_signo == other.si_signo ++ if self.si_signo == other.si_signo + && self.si_code == other.si_code +- && self.si_errno == other.si_errno +- && self.si_addr == other.si_addr +- && self +- .__pad +- .iter() +- .zip(other.__pad.iter()) +- .all(|(a, b)| a == b) ++ && self.si_errno == other.si_errno { ++ // FIXME: The `si_pad` field in the 64-bit version of the struct is ignored ++ // (for now) when doing comparisons. ++ ++ let field_count = self.data_field_count(); ++ self.__data_pad[..field_count] ++ .iter() ++ .zip(other.__data_pad[..field_count].iter()) ++ .all(|(a, b)| a == b) ++ } else { ++ false ++ } + } + } + impl Eq for siginfo_t {} +@@ -736,7 +844,6 @@ cfg_if! { + .field("si_signo", &self.si_signo) + .field("si_code", &self.si_code) + .field("si_errno", &self.si_errno) +- .field("si_addr", &self.si_addr) + // FIXME: .field("__pad", &self.__pad) + .finish() + } +@@ -746,8 +853,12 @@ cfg_if! { + self.si_signo.hash(state); + self.si_code.hash(state); + self.si_errno.hash(state); +- self.si_addr.hash(state); +- self.__pad.hash(state); ++ ++ // FIXME: The `si_pad` field in the 64-bit version of the struct is ignored ++ // (for now) when doing hashing. ++ ++ let field_count = self.data_field_count(); ++ self.__data_pad[..field_count].hash(state) + } + } + +@@ -825,6 +936,178 @@ cfg_if! { + } + } + ++ #[cfg(libc_union)] ++ impl PartialEq for pad128_t { ++ fn eq(&self, other: &pad128_t) -> bool { ++ unsafe { ++ // FIXME: self._q == other._q || ++ self._l == other._l ++ } ++ } ++ } ++ #[cfg(libc_union)] ++ impl Eq for pad128_t {} ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for pad128_t { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ unsafe { ++ f.debug_struct("pad128_t") ++ // FIXME: .field("_q", &{self._q}) ++ .field("_l", &{self._l}) ++ .finish() ++ } ++ } ++ } ++ #[cfg(libc_union)] ++ impl ::hash::Hash for pad128_t { ++ fn hash(&self, state: &mut H) { ++ unsafe { ++ // FIXME: state.write_i64(self._q as i64); ++ self._l.hash(state); ++ } ++ } ++ } ++ #[cfg(libc_union)] ++ impl PartialEq for upad128_t { ++ fn eq(&self, other: &upad128_t) -> bool { ++ unsafe { ++ // FIXME: self._q == other._q || ++ self._l == other._l ++ } ++ } ++ } ++ #[cfg(libc_union)] ++ impl Eq for upad128_t {} ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for upad128_t { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ unsafe { ++ f.debug_struct("upad128_t") ++ // FIXME: .field("_q", &{self._q}) ++ .field("_l", &{self._l}) ++ .finish() ++ } ++ } ++ } ++ #[cfg(libc_union)] ++ impl ::hash::Hash for upad128_t { ++ fn hash(&self, state: &mut H) { ++ unsafe { ++ // FIXME: state.write_i64(self._q as i64); ++ self._l.hash(state); ++ } ++ } ++ } ++ } ++} ++ ++cfg_if! { ++ if #[cfg(target_pointer_width = "64")] { ++ const SIGINFO_DATA_SIZE: usize = 60; ++ } else { ++ const SIGINFO_DATA_SIZE: usize = 29; ++ } ++} ++ ++#[repr(C)] ++struct siginfo_fault { ++ addr: *mut ::c_void, ++ trapno: ::c_int, ++ pc: *mut ::caddr_t, ++} ++impl ::Copy for siginfo_fault {} ++impl ::Clone for siginfo_fault { ++ fn clone(&self) -> Self { ++ *self ++ } ++} ++ ++#[repr(C)] ++struct siginfo_cldval { ++ utime: ::clock_t, ++ status: ::c_int, ++ stime: ::clock_t, ++} ++impl ::Copy for siginfo_cldval {} ++impl ::Clone for siginfo_cldval { ++ fn clone(&self) -> Self { ++ *self ++ } ++} ++ ++#[repr(C)] ++struct siginfo_killval { ++ uid: ::uid_t, ++ value: ::sigval, ++ // Pad out to match the SIGCLD value size ++ _pad: *mut ::c_void, ++} ++impl ::Copy for siginfo_killval {} ++impl ::Clone for siginfo_killval { ++ fn clone(&self) -> Self { ++ *self ++ } ++} ++ ++#[repr(C)] ++struct siginfo_sigcld { ++ pid: ::pid_t, ++ val: siginfo_cldval, ++ ctid: ::ctid_t, ++ zoneid: ::zoneid_t, ++} ++impl ::Copy for siginfo_sigcld {} ++impl ::Clone for siginfo_sigcld { ++ fn clone(&self) -> Self { ++ *self ++ } ++} ++ ++#[repr(C)] ++struct siginfo_kill { ++ pid: ::pid_t, ++ val: siginfo_killval, ++ ctid: ::ctid_t, ++ zoneid: ::zoneid_t, ++} ++impl ::Copy for siginfo_kill {} ++impl ::Clone for siginfo_kill { ++ fn clone(&self) -> Self { ++ *self ++ } ++} ++ ++impl siginfo_t { ++ unsafe fn sidata(&self) -> T { ++ *((&self.__data_pad) as *const ::c_int as *const T) ++ } ++ pub unsafe fn si_addr(&self) -> *mut ::c_void { ++ let sifault: siginfo_fault = self.sidata(); ++ sifault.addr ++ } ++ pub unsafe fn si_uid(&self) -> ::uid_t { ++ let kill: siginfo_kill = self.sidata(); ++ kill.val.uid ++ } ++ pub unsafe fn si_value(&self) -> ::sigval { ++ let kill: siginfo_kill = self.sidata(); ++ kill.val.value ++ } ++ pub unsafe fn si_pid(&self) -> ::pid_t { ++ let sigcld: siginfo_sigcld = self.sidata(); ++ sigcld.pid ++ } ++ pub unsafe fn si_status(&self) -> ::c_int { ++ let sigcld: siginfo_sigcld = self.sidata(); ++ sigcld.val.status ++ } ++ pub unsafe fn si_utime(&self) -> ::c_long { ++ let sigcld: siginfo_sigcld = self.sidata(); ++ sigcld.val.utime ++ } ++ pub unsafe fn si_stime(&self) -> ::c_long { ++ let sigcld: siginfo_sigcld = self.sidata(); ++ sigcld.val.stime + } + } + +@@ -936,6 +1219,7 @@ pub const FIOSETOWN: ::c_int = 0x8004667c; + pub const FIOGETOWN: ::c_int = 0x4004667b; + + pub const SIGCHLD: ::c_int = 18; ++pub const SIGCLD: ::c_int = ::SIGCHLD; + pub const SIGBUS: ::c_int = 10; + pub const SIGINFO: ::c_int = 41; + pub const SIG_BLOCK: ::c_int = 1; +@@ -946,6 +1230,13 @@ pub const SIGEV_NONE: ::c_int = 1; + pub const SIGEV_SIGNAL: ::c_int = 2; + pub const SIGEV_THREAD: ::c_int = 3; + ++pub const CLD_EXITED: ::c_int = 1; ++pub const CLD_KILLED: ::c_int = 2; ++pub const CLD_DUMPED: ::c_int = 3; ++pub const CLD_TRAPPED: ::c_int = 4; ++pub const CLD_STOPPED: ::c_int = 5; ++pub const CLD_CONTINUED: ::c_int = 6; ++ + pub const IP_RECVDSTADDR: ::c_int = 0x7; + pub const IP_SEC_OPT: ::c_int = 0x22; + +@@ -969,6 +1260,7 @@ pub const ST_RDONLY: ::c_ulong = 1; + pub const ST_NOSUID: ::c_ulong = 2; + + pub const NI_MAXHOST: ::socklen_t = 1025; ++pub const NI_MAXSERV: ::socklen_t = 32; + + pub const EXIT_FAILURE: ::c_int = 1; + pub const EXIT_SUCCESS: ::c_int = 0; +@@ -988,6 +1280,9 @@ pub const FILENAME_MAX: ::c_uint = 1024; + pub const L_tmpnam: ::c_uint = 25; + pub const TMP_MAX: ::c_uint = 17576; + ++pub const GRND_NONBLOCK: ::c_uint = 0x0001; ++pub const GRND_RANDOM: ::c_uint = 0x0002; ++ + pub const O_RDONLY: ::c_int = 0; + pub const O_WRONLY: ::c_int = 1; + pub const O_RDWR: ::c_int = 2; +@@ -1039,7 +1334,6 @@ pub const F_LOCK: ::c_int = 1; + pub const F_TEST: ::c_int = 3; + pub const F_TLOCK: ::c_int = 2; + pub const F_ULOCK: ::c_int = 0; +-pub const F_DUPFD_CLOEXEC: ::c_int = 37; + pub const F_SETLK: ::c_int = 6; + pub const F_SETLKW: ::c_int = 7; + pub const F_GETLK: ::c_int = 14; +@@ -1049,6 +1343,14 @@ pub const F_BLOCKS: ::c_int = 18; + pub const F_BLKSIZE: ::c_int = 19; + pub const F_SHARE: ::c_int = 40; + pub const F_UNSHARE: ::c_int = 41; ++pub const F_ISSTREAM: ::c_int = 13; ++pub const F_PRIV: ::c_int = 15; ++pub const F_NPRIV: ::c_int = 16; ++pub const F_QUOTACTL: ::c_int = 17; ++pub const F_GETOWN: ::c_int = 23; ++pub const F_SETOWN: ::c_int = 24; ++pub const F_REVOKE: ::c_int = 25; ++pub const F_HASREMOTELOCKS: ::c_int = 26; + pub const SIGHUP: ::c_int = 1; + pub const SIGINT: ::c_int = 2; + pub const SIGQUIT: ::c_int = 3; +@@ -1112,6 +1414,20 @@ pub const P_CTID: idtype_t = 13; + pub const P_CPUID: idtype_t = 14; + pub const P_PSETID: idtype_t = 15; + ++pub const PBIND_NONE: ::processorid_t = -1; ++pub const PBIND_QUERY: ::processorid_t = -2; ++pub const PBIND_HARD: ::processorid_t = -3; ++pub const PBIND_SOFT: ::processorid_t = -4; ++ ++pub const PS_NONE: ::c_int = -1; ++pub const PS_QUERY: ::c_int = -2; ++pub const PS_MYID: ::c_int = -3; ++pub const PS_SOFT: ::c_int = -4; ++pub const PS_HARD: ::c_int = -5; ++pub const PS_QUERY_TYPE: ::c_int = -6; ++pub const PS_SYSTEM: ::c_int = 1; ++pub const PS_PRIVATE: ::c_int = 2; ++ + pub const UTIME_OMIT: c_long = -2; + pub const UTIME_NOW: c_long = -1; + +@@ -1131,6 +1447,7 @@ pub const MAP_RENAME: ::c_int = 0x20; + pub const MAP_ALIGN: ::c_int = 0x200; + pub const MAP_TEXT: ::c_int = 0x400; + pub const MAP_INITDATA: ::c_int = 0x800; ++pub const MAP_32BIT: ::c_int = 0x80; + pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; + + pub const MCL_CURRENT: ::c_int = 0x0001; +@@ -1140,6 +1457,11 @@ pub const MS_SYNC: ::c_int = 0x0004; + pub const MS_ASYNC: ::c_int = 0x0001; + pub const MS_INVALIDATE: ::c_int = 0x0002; + ++pub const MMOBJ_PADDING: ::c_uint = 0x10000; ++pub const MMOBJ_INTERPRET: ::c_uint = 0x20000; ++pub const MR_PADDING: ::c_uint = 0x1; ++pub const MR_HDR_ELF: ::c_uint = 0x2; ++ + pub const EPERM: ::c_int = 1; + pub const ENOENT: ::c_int = 2; + pub const ESRCH: ::c_int = 3; +@@ -1276,9 +1598,16 @@ pub const EAI_SOCKTYPE: ::c_int = 10; + pub const EAI_SYSTEM: ::c_int = 11; + pub const EAI_OVERFLOW: ::c_int = 12; + ++pub const NI_NOFQDN: ::c_uint = 0x0001; ++pub const NI_NUMERICHOST: ::c_uint = 0x0002; ++pub const NI_NAMEREQD: ::c_uint = 0x0004; ++pub const NI_NUMERICSERV: ::c_uint = 0x0008; ++pub const NI_DGRAM: ::c_uint = 0x0010; ++pub const NI_WITHSCOPEID: ::c_uint = 0x0020; ++pub const NI_NUMERICSCOPE: ::c_uint = 0x0040; ++ + pub const F_DUPFD: ::c_int = 0; + pub const F_DUP2FD: ::c_int = 9; +-pub const F_DUP2FD_CLOEXEC: ::c_int = 36; + pub const F_GETFD: ::c_int = 1; + pub const F_SETFD: ::c_int = 2; + pub const F_GETFL: ::c_int = 3; +@@ -1362,6 +1691,9 @@ pub const MADV_SEQUENTIAL: ::c_int = 2; + pub const MADV_WILLNEED: ::c_int = 3; + pub const MADV_DONTNEED: ::c_int = 4; + pub const MADV_FREE: ::c_int = 5; ++pub const MADV_ACCESS_DEFAULT: ::c_int = 6; ++pub const MADV_ACCESS_LWP: ::c_int = 7; ++pub const MADV_ACCESS_MANY: ::c_int = 8; + + pub const AF_UNSPEC: ::c_int = 0; + pub const AF_UNIX: ::c_int = 1; +@@ -1397,6 +1729,42 @@ pub const AF_INET_OFFLOAD: ::c_int = 30; + pub const AF_TRILL: ::c_int = 31; + pub const AF_PACKET: ::c_int = 32; + ++pub const PF_UNSPEC: ::c_int = AF_UNSPEC; ++pub const PF_UNIX: ::c_int = AF_UNIX; ++pub const PF_LOCAL: ::c_int = PF_UNIX; ++pub const PF_FILE: ::c_int = PF_UNIX; ++pub const PF_INET: ::c_int = AF_INET; ++pub const PF_IMPLINK: ::c_int = AF_IMPLINK; ++pub const PF_PUP: ::c_int = AF_PUP; ++pub const PF_CHAOS: ::c_int = AF_CHAOS; ++pub const PF_NS: ::c_int = AF_NS; ++pub const PF_NBS: ::c_int = AF_NBS; ++pub const PF_ECMA: ::c_int = AF_ECMA; ++pub const PF_DATAKIT: ::c_int = AF_DATAKIT; ++pub const PF_CCITT: ::c_int = AF_CCITT; ++pub const PF_SNA: ::c_int = AF_SNA; ++pub const PF_DECnet: ::c_int = AF_DECnet; ++pub const PF_DLI: ::c_int = AF_DLI; ++pub const PF_LAT: ::c_int = AF_LAT; ++pub const PF_HYLINK: ::c_int = AF_HYLINK; ++pub const PF_APPLETALK: ::c_int = AF_APPLETALK; ++pub const PF_NIT: ::c_int = AF_NIT; ++pub const PF_802: ::c_int = AF_802; ++pub const PF_OSI: ::c_int = AF_OSI; ++pub const PF_X25: ::c_int = AF_X25; ++pub const PF_OSINET: ::c_int = AF_OSINET; ++pub const PF_GOSIP: ::c_int = AF_GOSIP; ++pub const PF_IPX: ::c_int = AF_IPX; ++pub const PF_ROUTE: ::c_int = AF_ROUTE; ++pub const PF_LINK: ::c_int = AF_LINK; ++pub const PF_INET6: ::c_int = AF_INET6; ++pub const PF_KEY: ::c_int = AF_KEY; ++pub const PF_NCA: ::c_int = AF_NCA; ++pub const PF_POLICY: ::c_int = AF_POLICY; ++pub const PF_INET_OFFLOAD: ::c_int = AF_INET_OFFLOAD; ++pub const PF_TRILL: ::c_int = AF_TRILL; ++pub const PF_PACKET: ::c_int = AF_PACKET; ++ + pub const SOCK_DGRAM: ::c_int = 1; + pub const SOCK_STREAM: ::c_int = 2; + pub const SOCK_RAW: ::c_int = 4; +@@ -1411,6 +1779,10 @@ pub const IP_ADD_MEMBERSHIP: ::c_int = 19; + pub const IP_DROP_MEMBERSHIP: ::c_int = 20; + pub const IPV6_JOIN_GROUP: ::c_int = 9; + pub const IPV6_LEAVE_GROUP: ::c_int = 10; ++pub const IP_ADD_SOURCE_MEMBERSHIP: ::c_int = 23; ++pub const IP_DROP_SOURCE_MEMBERSHIP: ::c_int = 24; ++pub const IP_BLOCK_SOURCE: ::c_int = 21; ++pub const IP_UNBLOCK_SOURCE: ::c_int = 22; + + // These TCP socket options are common between illumos and Solaris, while higher + // numbers have generally diverged: +@@ -1433,6 +1805,8 @@ pub const TCP_LINGER2: ::c_int = 0x1c; + + pub const UDP_NAT_T_ENDPOINT: ::c_int = 0x0103; + ++pub const SOMAXCONN: ::c_int = 128; ++ + pub const SOL_SOCKET: ::c_int = 0xffff; + pub const SO_DEBUG: ::c_int = 0x01; + pub const SO_ACCEPTCONN: ::c_int = 0x0002; +@@ -1529,6 +1903,14 @@ pub const IPC_RMID: ::c_int = 10; + pub const IPC_SET: ::c_int = 11; + pub const IPC_SEAT: ::c_int = 12; + ++// sys/shm.h ++pub const SHM_R: ::c_int = 0o400; ++pub const SHM_W: ::c_int = 0o200; ++pub const SHM_RDONLY: ::c_int = 0o10000; ++pub const SHM_RND: ::c_int = 0o20000; ++pub const SHM_SHARE_MMU: ::c_int = 0o40000; ++pub const SHM_PAGEABLE: ::c_int = 0o100000; ++ + pub const SHUT_RD: ::c_int = 0; + pub const SHUT_WR: ::c_int = 1; + pub const SHUT_RDWR: ::c_int = 2; +@@ -1881,6 +2263,18 @@ pub const TIOCMGET: ::c_int = tIOC | 29; + pub const TIOCREMOTE: ::c_int = tIOC | 30; + pub const TIOCSIGNAL: ::c_int = tIOC | 31; + ++pub const TIOCM_LE: ::c_int = 0o0001; ++pub const TIOCM_DTR: ::c_int = 0o0002; ++pub const TIOCM_RTS: ::c_int = 0o0004; ++pub const TIOCM_ST: ::c_int = 0o0010; ++pub const TIOCM_SR: ::c_int = 0o0020; ++pub const TIOCM_CTS: ::c_int = 0o0040; ++pub const TIOCM_CAR: ::c_int = 0o0100; ++pub const TIOCM_CD: ::c_int = TIOCM_CAR; ++pub const TIOCM_RNG: ::c_int = 0o0200; ++pub const TIOCM_RI: ::c_int = TIOCM_RNG; ++pub const TIOCM_DSR: ::c_int = 0o0400; ++ + pub const EPOLLIN: ::c_int = 0x1; + pub const EPOLLPRI: ::c_int = 0x2; + pub const EPOLLOUT: ::c_int = 0x4; +@@ -1929,6 +2323,10 @@ pub const B921600: speed_t = 23; + pub const CSTART: ::tcflag_t = 0o21; + pub const CSTOP: ::tcflag_t = 0o23; + pub const CSWTCH: ::tcflag_t = 0o32; ++pub const CBAUD: ::tcflag_t = 0o17; ++pub const CIBAUD: ::tcflag_t = 0o3600000; ++pub const CBAUDEXT: ::tcflag_t = 0o10000000; ++pub const CIBAUDEXT: ::tcflag_t = 0o20000000; + pub const CSIZE: ::tcflag_t = 0o000060; + pub const CS5: ::tcflag_t = 0; + pub const CS6: ::tcflag_t = 0o000020; +@@ -1952,20 +2350,26 @@ pub const ISTRIP: ::tcflag_t = 0o000040; + pub const INLCR: ::tcflag_t = 0o000100; + pub const IGNCR: ::tcflag_t = 0o000200; + pub const ICRNL: ::tcflag_t = 0o000400; ++pub const IUCLC: ::tcflag_t = 0o001000; + pub const IXON: ::tcflag_t = 0o002000; + pub const IXOFF: ::tcflag_t = 0o010000; + pub const IXANY: ::tcflag_t = 0o004000; + pub const IMAXBEL: ::tcflag_t = 0o020000; ++pub const DOSMODE: ::tcflag_t = 0o100000; + pub const OPOST: ::tcflag_t = 0o000001; ++pub const OLCUC: ::tcflag_t = 0o000002; + pub const ONLCR: ::tcflag_t = 0o000004; + pub const OCRNL: ::tcflag_t = 0o000010; + pub const ONOCR: ::tcflag_t = 0o000020; + pub const ONLRET: ::tcflag_t = 0o000040; ++pub const OFILL: ::tcflag_t = 0o0000100; ++pub const OFDEL: ::tcflag_t = 0o0000200; + pub const CREAD: ::tcflag_t = 0o000200; + pub const PARENB: ::tcflag_t = 0o000400; + pub const PARODD: ::tcflag_t = 0o001000; + pub const HUPCL: ::tcflag_t = 0o002000; + pub const CLOCAL: ::tcflag_t = 0o004000; ++pub const CRTSXOFF: ::tcflag_t = 0o10000000000; + pub const CRTSCTS: ::tcflag_t = 0o20000000000; + pub const ISIG: ::tcflag_t = 0o000001; + pub const ICANON: ::tcflag_t = 0o000002; +@@ -2091,11 +2495,91 @@ pub const PRIO_PROCESS: ::c_int = 0; + pub const PRIO_PGRP: ::c_int = 1; + pub const PRIO_USER: ::c_int = 2; + ++pub const SCHED_OTHER: ::c_int = 0; ++pub const SCHED_FIFO: ::c_int = 1; ++pub const SCHED_RR: ::c_int = 2; ++pub const SCHED_SYS: ::c_int = 3; ++pub const SCHED_IA: ::c_int = 4; ++pub const SCHED_FSS: ::c_int = 5; ++pub const SCHED_FX: ::c_int = 6; ++ ++// sys/priv.h ++pub const PRIV_DEBUG: ::c_uint = 0x0001; ++pub const PRIV_AWARE: ::c_uint = 0x0002; ++pub const PRIV_AWARE_INHERIT: ::c_uint = 0x0004; ++pub const __PROC_PROTECT: ::c_uint = 0x0008; ++pub const NET_MAC_AWARE: ::c_uint = 0x0010; ++pub const NET_MAC_AWARE_INHERIT: ::c_uint = 0x0020; ++pub const PRIV_AWARE_RESET: ::c_uint = 0x0040; ++pub const PRIV_XPOLICY: ::c_uint = 0x0080; ++pub const PRIV_PFEXEC: ::c_uint = 0x0100; ++pub const PRIV_USER: ::c_uint = PRIV_DEBUG ++ | NET_MAC_AWARE ++ | NET_MAC_AWARE_INHERIT ++ | PRIV_XPOLICY ++ | PRIV_AWARE_RESET ++ | PRIV_PFEXEC; ++ ++// sys/systeminfo.h ++pub const SI_SYSNAME: ::c_int = 1; ++pub const SI_HOSTNAME: ::c_int = 2; ++pub const SI_RELEASE: ::c_int = 3; ++pub const SI_VERSION: ::c_int = 4; ++pub const SI_MACHINE: ::c_int = 5; ++pub const SI_ARCHITECTURE: ::c_int = 6; ++pub const SI_HW_SERIAL: ::c_int = 7; ++pub const SI_HW_PROVIDER: ::c_int = 8; ++pub const SI_SET_HOSTNAME: ::c_int = 258; ++pub const SI_SET_SRPC_DOMAIN: ::c_int = 265; ++pub const SI_PLATFORM: ::c_int = 513; ++pub const SI_ISALIST: ::c_int = 514; ++pub const SI_DHCP_CACHE: ::c_int = 515; ++pub const SI_ARCHITECTURE_32: ::c_int = 516; ++pub const SI_ARCHITECTURE_64: ::c_int = 517; ++pub const SI_ARCHITECTURE_K: ::c_int = 518; ++pub const SI_ARCHITECTURE_NATIVE: ::c_int = 519; ++ ++// sys/lgrp_user.h ++pub const LGRP_COOKIE_NONE: ::lgrp_cookie_t = 0; ++pub const LGRP_AFF_NONE: ::lgrp_affinity_t = 0x0; ++pub const LGRP_AFF_WEAK: ::lgrp_affinity_t = 0x10; ++pub const LGRP_AFF_STRONG: ::lgrp_affinity_t = 0x100; ++pub const LGRP_RSRC_COUNT: ::lgrp_rsrc_t = 2; ++pub const LGRP_RSRC_CPU: ::lgrp_rsrc_t = 0; ++pub const LGRP_RSRC_MEM: ::lgrp_rsrc_t = 1; ++pub const LGRP_CONTENT_ALL: ::lgrp_content_t = 0; ++pub const LGRP_CONTENT_HIERARCHY: ::lgrp_content_t = LGRP_CONTENT_ALL; ++pub const LGRP_CONTENT_DIRECT: ::lgrp_content_t = 1; ++pub const LGRP_LAT_CPU_TO_MEM: ::lgrp_lat_between_t = 0; ++pub const LGRP_MEM_SZ_FREE: ::lgrp_mem_size_flag_t = 0; ++pub const LGRP_MEM_SZ_INSTALLED: ::lgrp_mem_size_flag_t = 1; ++pub const LGRP_VIEW_CALLER: ::lgrp_view_t = 0; ++pub const LGRP_VIEW_OS: ::lgrp_view_t = 1; ++ ++// sys/processor.h ++ ++pub const P_OFFLINE: ::c_int = 0x001; ++pub const P_ONLINE: ::c_int = 0x002; ++pub const P_STATUS: ::c_int = 0x003; ++pub const P_FAULTED: ::c_int = 0x004; ++pub const P_POWEROFF: ::c_int = 0x005; ++pub const P_NOINTR: ::c_int = 0x006; ++pub const P_SPARE: ::c_int = 0x007; ++pub const P_DISABLED: ::c_int = 0x008; ++pub const P_FORCED: ::c_int = 0x10000000; ++pub const PI_TYPELEN: ::c_int = 16; ++pub const PI_FPUTYPE: ::c_int = 32; ++ ++// sys/auxv.h ++pub const AT_SUN_HWCAP: ::c_uint = 2009; ++pub const AT_SUN_HWCAP2: ::c_uint = 2023; ++pub const AT_SUN_FPTYPE: ::c_uint = 2027; ++ + // As per sys/socket.h, header alignment must be 8 bytes on SPARC + // and 4 bytes everywhere else: + #[cfg(target_arch = "sparc64")] + const _CMSG_HDR_ALIGNMENT: usize = 8; +-#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] ++#[cfg(not(target_arch = "sparc64"))] + const _CMSG_HDR_ALIGNMENT: usize = 4; + + const _CMSG_DATA_ALIGNMENT: usize = ::mem::size_of::<::c_int>(); +@@ -2157,7 +2641,7 @@ f! { + return + } + +- pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool { ++ pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0 +@@ -2209,6 +2693,10 @@ safe_f! { + pub {const} fn WCOREDUMP(status: ::c_int) -> bool { + (status & 0x80) != 0 + } ++ ++ pub {const} fn MR_GET_TYPE(flags: ::c_uint) -> ::c_uint { ++ flags & 0x0000ffff ++ } + } + + extern "C" { +@@ -2222,11 +2710,12 @@ extern "C" { + + pub fn abs(i: ::c_int) -> ::c_int; + pub fn acct(filename: *const ::c_char) -> ::c_int; +- pub fn atof(s: *const ::c_char) -> ::c_double; + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; + pub fn labs(i: ::c_long) -> ::c_long; + pub fn rand() -> ::c_int; + pub fn srand(seed: ::c_uint); ++ pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; ++ pub fn getrandom(bbuf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; + + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn settimeofday(tp: *const ::timeval, tz: *const ::c_void) -> ::c_int; +@@ -2234,6 +2723,12 @@ extern "C" { + pub fn freeifaddrs(ifa: *mut ::ifaddrs); + + pub fn stack_getbounds(sp: *mut ::stack_t) -> ::c_int; ++ pub fn getgrouplist( ++ name: *const ::c_char, ++ basegid: ::gid_t, ++ groups: *mut ::gid_t, ++ ngroups: *mut ::c_int, ++ ) -> ::c_int; + pub fn initgroups(name: *const ::c_char, basegid: ::gid_t) -> ::c_int; + pub fn setgroups(ngroups: ::c_int, ptr: *const ::gid_t) -> ::c_int; + pub fn ioctl(fildes: ::c_int, request: ::c_int, ...) -> ::c_int; +@@ -2307,6 +2802,8 @@ extern "C" { + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; ++ pub fn pthread_getname_np(tid: ::pthread_t, name: *mut ::c_char, len: ::size_t) -> ::c_int; ++ pub fn pthread_setname_np(tid: ::pthread_t, name: *const ::c_char) -> ::c_int; + pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t, options: ::c_int) + -> ::c_int; + +@@ -2484,10 +2981,21 @@ extern "C" { + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; ++ pub fn thr_self() -> ::thread_t; + pub fn pthread_sigmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; + pub fn sem_open(name: *const ::c_char, oflag: ::c_int, ...) -> *mut sem_t; + pub fn getgrnam(name: *const ::c_char) -> *mut ::group; + pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; ++ pub fn sched_get_priority_min(policy: ::c_int) -> ::c_int; ++ pub fn sched_get_priority_max(policy: ::c_int) -> ::c_int; ++ pub fn sched_getparam(pid: ::pid_t, param: *mut sched_param) -> ::c_int; ++ pub fn sched_setparam(pid: ::pid_t, param: *const sched_param) -> ::c_int; ++ pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int; ++ pub fn sched_setscheduler( ++ pid: ::pid_t, ++ policy: ::c_int, ++ param: *const ::sched_param, ++ ) -> ::c_int; + pub fn sem_unlink(name: *const ::c_char) -> ::c_int; + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + #[cfg_attr( +@@ -2514,24 +3022,14 @@ extern "C" { + ) -> ::c_int; + #[cfg_attr( + any(target_os = "solaris", target_os = "illumos"), +- link_name = "__posix_getpwent_r" ++ link_name = "getpwent_r" + )] +- pub fn getpwent_r( +- pwd: *mut passwd, +- buf: *mut ::c_char, +- buflen: ::size_t, +- result: *mut *mut passwd, +- ) -> ::c_int; ++ fn native_getpwent_r(pwd: *mut passwd, buf: *mut ::c_char, buflen: ::c_int) -> *mut passwd; + #[cfg_attr( + any(target_os = "solaris", target_os = "illumos"), +- link_name = "__posix_getgrent_r" ++ link_name = "getgrent_r" + )] +- pub fn getgrent_r( +- grp: *mut ::group, +- buf: *mut ::c_char, +- buflen: ::size_t, +- result: *mut *mut ::group, +- ) -> ::c_int; ++ fn native_getgrent_r(grp: *mut ::group, buf: *mut ::c_char, buflen: ::c_int) -> *mut ::group; + #[cfg_attr( + any(target_os = "solaris", target_os = "illumos"), + link_name = "__posix_sigwait" +@@ -2607,6 +3105,153 @@ extern "C" { + pub fn ucred_getpflags(ucred: *const ucred_t, flags: ::c_uint) -> ::c_uint; + + pub fn ucred_size() -> ::size_t; ++ ++ pub fn pset_create(newpset: *mut ::psetid_t) -> ::c_int; ++ pub fn pset_destroy(pset: ::psetid_t) -> ::c_int; ++ pub fn pset_assign(pset: ::psetid_t, cpu: ::processorid_t, opset: *mut psetid_t) -> ::c_int; ++ pub fn pset_info( ++ pset: ::psetid_t, ++ tpe: *mut ::c_int, ++ numcpus: *mut ::c_uint, ++ cpulist: *mut processorid_t, ++ ) -> ::c_int; ++ pub fn pset_bind( ++ pset: ::psetid_t, ++ idtype: ::idtype_t, ++ id: ::id_t, ++ opset: *mut psetid_t, ++ ) -> ::c_int; ++ pub fn pset_list(pset: *mut psetid_t, numpsets: *mut ::c_uint) -> ::c_int; ++ pub fn pset_setattr(pset: psetid_t, attr: ::c_uint) -> ::c_int; ++ pub fn pset_getattr(pset: psetid_t, attr: *mut ::c_uint) -> ::c_int; ++ pub fn processor_bind( ++ idtype: ::idtype_t, ++ id: ::id_t, ++ new_binding: ::processorid_t, ++ old_binding: *mut processorid_t, ++ ) -> ::c_int; ++ pub fn p_online(processorid: ::processorid_t, flag: ::c_int) -> ::c_int; ++ pub fn processor_info(processorid: ::processorid_t, infop: *mut processor_info_t) -> ::c_int; ++ ++ pub fn getexecname() -> *const ::c_char; ++ ++ pub fn gethostid() -> ::c_long; ++ ++ pub fn getpflags(flags: ::c_uint) -> ::c_uint; ++ pub fn setpflags(flags: ::c_uint, value: ::c_uint) -> ::c_int; ++ ++ pub fn sysinfo(command: ::c_int, buf: *mut ::c_char, count: ::c_long) -> ::c_int; ++ ++ pub fn faccessat(fd: ::c_int, path: *const ::c_char, amode: ::c_int, flag: ::c_int) -> ::c_int; ++ ++ // #include ++ #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] ++ pub fn dl_iterate_phdr( ++ callback: ::Option< ++ unsafe extern "C" fn( ++ info: *mut dl_phdr_info, ++ size: usize, ++ data: *mut ::c_void, ++ ) -> ::c_int, ++ >, ++ data: *mut ::c_void, ++ ) -> ::c_int; ++ pub fn getpagesize() -> ::c_int; ++ pub fn getpagesizes(pagesize: *mut ::size_t, nelem: ::c_int) -> ::c_int; ++ pub fn mmapobj( ++ fd: ::c_int, ++ flags: ::c_uint, ++ storage: *mut mmapobj_result_t, ++ elements: *mut ::c_uint, ++ arg: *mut ::c_void, ++ ) -> ::c_int; ++ pub fn meminfo( ++ inaddr: *const u64, ++ addr_count: ::c_int, ++ info_req: *const ::c_uint, ++ info_count: ::c_int, ++ outdata: *mut u64, ++ validity: *mut ::c_uint, ++ ) -> ::c_int; ++ ++ pub fn strcasecmp_l(s1: *const ::c_char, s2: *const ::c_char, loc: ::locale_t) -> ::c_int; ++ pub fn strncasecmp_l( ++ s1: *const ::c_char, ++ s2: *const ::c_char, ++ n: ::size_t, ++ loc: ::locale_t, ++ ) -> ::c_int; ++ pub fn strsep(string: *mut *mut ::c_char, delim: *const ::c_char) -> *mut ::c_char; ++ ++ pub fn getisax(array: *mut u32, n: ::c_uint) -> ::c_uint; ++ ++ pub fn backtrace(buffer: *mut *mut ::c_void, size: ::c_int) -> ::c_int; ++ pub fn backtrace_symbols(buffer: *const *mut ::c_void, size: ::c_int) -> *mut *mut ::c_char; ++ pub fn backtrace_symbols_fd(buffer: *const *mut ::c_void, size: ::c_int, fd: ::c_int); ++ ++ pub fn getopt_long( ++ argc: ::c_int, ++ argv: *const *mut c_char, ++ optstring: *const c_char, ++ longopts: *const option, ++ longindex: *mut ::c_int, ++ ) -> ::c_int; ++ ++ pub fn sync(); ++} ++ ++#[link(name = "sendfile")] ++extern "C" { ++ pub fn sendfile(out_fd: ::c_int, in_fd: ::c_int, off: *mut ::off_t, len: ::size_t) ++ -> ::ssize_t; ++ pub fn sendfilev( ++ fildes: ::c_int, ++ vec: *const sendfilevec_t, ++ sfvcnt: ::c_int, ++ xferred: *mut ::size_t, ++ ) -> ::ssize_t; ++} ++ ++#[link(name = "lgrp")] ++extern "C" { ++ pub fn lgrp_init(view: lgrp_view_t) -> lgrp_cookie_t; ++ pub fn lgrp_fini(cookie: lgrp_cookie_t) -> ::c_int; ++ pub fn lgrp_affinity_get( ++ idtype: ::idtype_t, ++ id: ::id_t, ++ lgrp: ::lgrp_id_t, ++ ) -> ::lgrp_affinity_t; ++ pub fn lgrp_affinity_set( ++ idtype: ::idtype_t, ++ id: ::id_t, ++ lgrp: ::lgrp_id_t, ++ aff: lgrp_affinity_t, ++ ) -> ::lgrp_affinity_t; ++ pub fn lgrp_cpus( ++ cookie: ::lgrp_cookie_t, ++ lgrp: ::lgrp_id_t, ++ cpuids: *mut ::processorid_t, ++ count: ::c_uint, ++ content: ::lgrp_content_t, ++ ) -> ::c_int; ++ pub fn lgrp_mem_size( ++ cookie: ::lgrp_cookie_t, ++ lgrp: ::lgrp_id_t, ++ tpe: ::lgrp_mem_size_flag_t, ++ content: ::lgrp_content_t, ++ ) -> ::lgrp_mem_size_t; ++ pub fn lgrp_nlgrps(cookie: ::lgrp_cookie_t) -> ::c_int; ++ pub fn lgrp_view(cookie: ::lgrp_cookie_t) -> ::lgrp_view_t; ++ pub fn lgrp_home(idtype: ::idtype_t, id: ::id_t) -> ::lgrp_id_t; ++ pub fn lgrp_version(version: ::c_int) -> ::c_int; ++ pub fn lgrp_resources( ++ cookie: ::lgrp_cookie_t, ++ lgrp: ::lgrp_id_t, ++ lgrps: *mut ::lgrp_id_t, ++ count: ::c_uint, ++ tpe: ::lgrp_rsrc_t, ++ ) -> ::c_int; ++ pub fn lgrp_root(cookie: ::lgrp_cookie_t) -> ::lgrp_id_t; + } + + mod compat; +@@ -2623,3 +3268,17 @@ cfg_if! { + // Unknown target_os + } + } ++ ++cfg_if! { ++ if #[cfg(target_arch = "x86_64")] { ++ mod x86_64; ++ mod x86_common; ++ pub use self::x86_64::*; ++ pub use self::x86_common::*; ++ } else if #[cfg(target_arch = "x86")] { ++ mod x86; ++ mod x86_common; ++ pub use self::x86::*; ++ pub use self::x86_common::*; ++ } ++} +diff --git a/vendor/libc/src/unix/solarish/solaris.rs b/vendor/libc/src/unix/solarish/solaris.rs +index 8ea070c..80bad28 100644 +--- a/vendor/libc/src/unix/solarish/solaris.rs ++++ b/vendor/libc/src/unix/solarish/solaris.rs +@@ -26,6 +26,30 @@ s! { + } + } + ++s_no_extra_traits! { ++ #[cfg_attr(feature = "extra_traits", allow(missing_debug_implementations))] ++ pub union door_desc_t__d_data { ++ pub d_desc: door_desc_t__d_data__d_desc, ++ d_resv: [::c_int; 5], /* Check out /usr/include/sys/door.h */ ++ } ++ ++ #[cfg_attr(feature = "extra_traits", allow(missing_debug_implementations))] ++ pub struct door_desc_t { ++ pub d_attributes: door_attr_t, ++ pub d_data: door_desc_t__d_data, ++ } ++ ++ #[cfg_attr(feature = "extra_traits", allow(missing_debug_implementations))] ++ pub struct door_arg_t { ++ pub data_ptr: *const ::c_char, ++ pub data_size: ::size_t, ++ pub desc_ptr: *const door_desc_t, ++ pub dec_num: ::c_uint, ++ pub rbuf: *const ::c_char, ++ pub rsize: ::size_t, ++ } ++} ++ + pub const PORT_SOURCE_POSTWAIT: ::c_int = 8; + pub const PORT_SOURCE_SIGNAL: ::c_int = 9; + +@@ -33,8 +57,13 @@ pub const AF_LOCAL: ::c_int = 0; + pub const AF_FILE: ::c_int = 0; + + pub const TCP_KEEPIDLE: ::c_int = 0x1d; +-pub const TCP_KEEPCNT: ::c_int = 0x1e; +-pub const TCP_KEEPINTVL: ::c_int = 0x1f; ++pub const TCP_KEEPINTVL: ::c_int = 0x1e; ++pub const TCP_KEEPCNT: ::c_int = 0x1f; ++ ++pub const F_DUPFD_CLOEXEC: ::c_int = 47; ++pub const F_DUPFD_CLOFORK: ::c_int = 49; ++pub const F_DUP2FD_CLOEXEC: ::c_int = 48; ++pub const F_DUP2FD_CLOFORK: ::c_int = 50; + + extern "C" { + pub fn fexecve( +@@ -67,28 +96,6 @@ extern "C" { + pub fn fattach(fildes: ::c_int, path: *const ::c_char) -> ::c_int; + + pub fn pthread_getattr_np(thread: ::pthread_t, attr: *mut ::pthread_attr_t) -> ::c_int; +-} +- +-s_no_extra_traits! { +- #[cfg_attr(feature = "extra_traits", allow(missing_debug_implementations))] +- pub union door_desc_t__d_data { +- pub d_desc: door_desc_t__d_data__d_desc, +- d_resv: [::c_int; 5], /* Check out /usr/include/sys/door.h */ +- } +- +- #[cfg_attr(feature = "extra_traits", allow(missing_debug_implementations))] +- pub struct door_desc_t { +- pub d_attributes: door_attr_t, +- pub d_data: door_desc_t__d_data, +- } + +- #[cfg_attr(feature = "extra_traits", allow(missing_debug_implementations))] +- pub struct door_arg_t { +- pub data_ptr: *const ::c_char, +- pub data_size: ::size_t, +- pub desc_ptr: *const door_desc_t, +- pub dec_num: ::c_uint, +- pub rbuf: *const ::c_char, +- pub rsize: ::size_t, +- } ++ pub fn euidaccess(path: *const ::c_char, amode: ::c_int) -> ::c_int; + } +diff --git a/vendor/libc/src/unix/solarish/x86.rs b/vendor/libc/src/unix/solarish/x86.rs +new file mode 100644 +index 0000000..23f52ad +--- /dev/null ++++ b/vendor/libc/src/unix/solarish/x86.rs +@@ -0,0 +1,29 @@ ++pub type Elf32_Addr = ::c_ulong; ++pub type Elf32_Half = ::c_ushort; ++pub type Elf32_Off = ::c_ulong; ++pub type Elf32_Sword = ::c_long; ++pub type Elf32_Word = ::c_ulong; ++pub type Elf32_Lword = ::c_ulonglong; ++pub type Elf32_Phdr = __c_anonymous_Elf32_Phdr; ++ ++s! { ++ pub struct __c_anonymous_Elf32_Phdr { ++ pub p_type: ::Elf32_Word, ++ pub p_offset: ::Elf32_Off, ++ pub p_vaddr: ::Elf32_Addr, ++ pub p_paddr: ::Elf32_Addr, ++ pub p_filesz: ::Elf32_Word, ++ pub p_memsz: ::Elf32_Word, ++ pub p_flags: ::Elf32_Word, ++ pub p_align: ::Elf32_Word, ++ } ++ ++ pub struct dl_phdr_info { ++ pub dlpi_addr: ::Elf32_Addr, ++ pub dlpi_name: *const ::c_char, ++ pub dlpi_phdr: *const ::Elf32_Phdr, ++ pub dlpi_phnum: ::Elf32_Half, ++ pub dlpi_adds: ::c_ulonglong, ++ pub dlpi_subs: ::c_ulonglong, ++ } ++} +diff --git a/vendor/libc/src/unix/solarish/x86_64.rs b/vendor/libc/src/unix/solarish/x86_64.rs +new file mode 100644 +index 0000000..bca552f +--- /dev/null ++++ b/vendor/libc/src/unix/solarish/x86_64.rs +@@ -0,0 +1,190 @@ ++pub type greg_t = ::c_long; ++ ++pub type Elf64_Addr = ::c_ulong; ++pub type Elf64_Half = ::c_ushort; ++pub type Elf64_Off = ::c_ulong; ++pub type Elf64_Sword = ::c_int; ++pub type Elf64_Sxword = ::c_long; ++pub type Elf64_Word = ::c_uint; ++pub type Elf64_Xword = ::c_ulong; ++pub type Elf64_Lword = ::c_ulong; ++pub type Elf64_Phdr = __c_anonymous_Elf64_Phdr; ++ ++s! { ++ pub struct __c_anonymous_fpchip_state { ++ pub cw: u16, ++ pub sw: u16, ++ pub fctw: u8, ++ pub __fx_rsvd: u8, ++ pub fop: u16, ++ pub rip: u64, ++ pub rdp: u64, ++ pub mxcsr: u32, ++ pub mxcsr_mask: u32, ++ pub st: [::upad128_t; 8], ++ pub xmm: [::upad128_t; 16], ++ pub __fx_ign: [::upad128_t; 6], ++ pub status: u32, ++ pub xstatus: u32, ++ } ++ ++ pub struct __c_anonymous_Elf64_Phdr { ++ pub p_type: ::Elf64_Word, ++ pub p_flags: ::Elf64_Word, ++ pub p_offset: ::Elf64_Off, ++ pub p_vaddr: ::Elf64_Addr, ++ pub p_paddr: ::Elf64_Addr, ++ pub p_filesz: ::Elf64_Xword, ++ pub p_memsz: ::Elf64_Xword, ++ pub p_align: ::Elf64_Xword, ++ } ++ ++ pub struct dl_phdr_info { ++ pub dlpi_addr: ::Elf64_Addr, ++ pub dlpi_name: *const ::c_char, ++ pub dlpi_phdr: *const ::Elf64_Phdr, ++ pub dlpi_phnum: ::Elf64_Half, ++ pub dlpi_adds: ::c_ulonglong, ++ pub dlpi_subs: ::c_ulonglong, ++ } ++} ++ ++s_no_extra_traits! { ++ #[cfg(libc_union)] ++ pub union __c_anonymous_fp_reg_set { ++ pub fpchip_state: __c_anonymous_fpchip_state, ++ pub f_fpregs: [[u32; 13]; 10], ++ } ++ ++ pub struct fpregset_t { ++ pub fp_reg_set: __c_anonymous_fp_reg_set, ++ } ++ ++ pub struct mcontext_t { ++ pub gregs: [::greg_t; 28], ++ pub fpregs: fpregset_t, ++ } ++ ++ pub struct ucontext_t { ++ pub uc_flags: ::c_ulong, ++ pub uc_link: *mut ucontext_t, ++ pub uc_sigmask: ::sigset_t, ++ pub uc_stack: ::stack_t, ++ pub uc_mcontext: mcontext_t, ++ pub uc_filler: [::c_long; 5], ++ } ++} ++ ++cfg_if! { ++ if #[cfg(feature = "extra_traits")] { ++ #[cfg(libc_union)] ++ impl PartialEq for __c_anonymous_fp_reg_set { ++ fn eq(&self, other: &__c_anonymous_fp_reg_set) -> bool { ++ unsafe { ++ self.fpchip_state == other.fpchip_state || ++ self. ++ f_fpregs. ++ iter(). ++ zip(other.f_fpregs.iter()). ++ all(|(a, b)| a == b) ++ } ++ } ++ } ++ #[cfg(libc_union)] ++ impl Eq for __c_anonymous_fp_reg_set {} ++ #[cfg(libc_union)] ++ impl ::fmt::Debug for __c_anonymous_fp_reg_set { ++ fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { ++ unsafe { ++ f.debug_struct("__c_anonymous_fp_reg_set") ++ .field("fpchip_state", &{self.fpchip_state}) ++ .field("f_fpregs", &{self.f_fpregs}) ++ .finish() ++ } ++ } ++ } ++ impl PartialEq for fpregset_t { ++ fn eq(&self, other: &fpregset_t) -> bool { ++ self.fp_reg_set == other.fp_reg_set ++ } ++ } ++ impl Eq for fpregset_t {} ++ impl ::fmt::Debug for fpregset_t { ++ fn fmt(&self, f:&mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("fpregset_t") ++ .field("fp_reg_set", &self.fp_reg_set) ++ .finish() ++ } ++ } ++ impl PartialEq for mcontext_t { ++ fn eq(&self, other: &mcontext_t) -> bool { ++ self.gregs == other.gregs && ++ self.fpregs == other.fpregs ++ } ++ } ++ impl Eq for mcontext_t {} ++ impl ::fmt::Debug for mcontext_t { ++ fn fmt(&self, f:&mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("mcontext_t") ++ .field("gregs", &self.gregs) ++ .field("fpregs", &self.fpregs) ++ .finish() ++ } ++ } ++ impl PartialEq for ucontext_t { ++ fn eq(&self, other: &ucontext_t) -> bool { ++ self.uc_flags == other.uc_flags ++ && self.uc_link == other.uc_link ++ && self.uc_sigmask == other.uc_sigmask ++ && self.uc_stack == other.uc_stack ++ && self.uc_mcontext == other.uc_mcontext ++ && self.uc_filler == other.uc_filler ++ } ++ } ++ impl Eq for ucontext_t {} ++ impl ::fmt::Debug for ucontext_t { ++ fn fmt(&self, f:&mut ::fmt::Formatter) -> ::fmt::Result { ++ f.debug_struct("ucontext_t") ++ .field("uc_flags", &self.uc_flags) ++ .field("uc_link", &self.uc_link) ++ .field("uc_sigmask", &self.uc_sigmask) ++ .field("uc_stack", &self.uc_stack) ++ .field("uc_mcontext", &self.uc_mcontext) ++ .field("uc_filler", &self.uc_filler) ++ .finish() ++ } ++ } ++ ++ } ++} ++ ++// sys/regset.h ++ ++pub const REG_GSBASE: ::c_int = 27; ++pub const REG_FSBASE: ::c_int = 26; ++pub const REG_DS: ::c_int = 25; ++pub const REG_ES: ::c_int = 24; ++pub const REG_GS: ::c_int = 23; ++pub const REG_FS: ::c_int = 22; ++pub const REG_SS: ::c_int = 21; ++pub const REG_RSP: ::c_int = 20; ++pub const REG_RFL: ::c_int = 19; ++pub const REG_CS: ::c_int = 18; ++pub const REG_RIP: ::c_int = 17; ++pub const REG_ERR: ::c_int = 16; ++pub const REG_TRAPNO: ::c_int = 15; ++pub const REG_RAX: ::c_int = 14; ++pub const REG_RCX: ::c_int = 13; ++pub const REG_RDX: ::c_int = 12; ++pub const REG_RBX: ::c_int = 11; ++pub const REG_RBP: ::c_int = 10; ++pub const REG_RSI: ::c_int = 9; ++pub const REG_RDI: ::c_int = 8; ++pub const REG_R8: ::c_int = 7; ++pub const REG_R9: ::c_int = 6; ++pub const REG_R10: ::c_int = 5; ++pub const REG_R11: ::c_int = 4; ++pub const REG_R12: ::c_int = 3; ++pub const REG_R13: ::c_int = 2; ++pub const REG_R14: ::c_int = 1; ++pub const REG_R15: ::c_int = 0; +diff --git a/vendor/libc/src/unix/solarish/x86_common.rs b/vendor/libc/src/unix/solarish/x86_common.rs +new file mode 100644 +index 0000000..515f234 +--- /dev/null ++++ b/vendor/libc/src/unix/solarish/x86_common.rs +@@ -0,0 +1,65 @@ ++// AT_SUN_HWCAP ++pub const AV_386_FPU: u32 = 0x00001; ++pub const AV_386_TSC: u32 = 0x00002; ++pub const AV_386_CX8: u32 = 0x00004; ++pub const AV_386_SEP: u32 = 0x00008; ++pub const AV_386_AMD_SYSC: u32 = 0x00010; ++pub const AV_386_CMOV: u32 = 0x00020; ++pub const AV_386_MMX: u32 = 0x00040; ++pub const AV_386_AMD_MMX: u32 = 0x00080; ++pub const AV_386_AMD_3DNow: u32 = 0x00100; ++pub const AV_386_AMD_3DNowx: u32 = 0x00200; ++pub const AV_386_FXSR: u32 = 0x00400; ++pub const AV_386_SSE: u32 = 0x00800; ++pub const AV_386_SSE2: u32 = 0x01000; ++pub const AV_386_CX16: u32 = 0x10000; ++pub const AV_386_AHF: u32 = 0x20000; ++pub const AV_386_TSCP: u32 = 0x40000; ++pub const AV_386_AMD_SSE4A: u32 = 0x80000; ++pub const AV_386_POPCNT: u32 = 0x100000; ++pub const AV_386_AMD_LZCNT: u32 = 0x200000; ++pub const AV_386_SSSE3: u32 = 0x400000; ++pub const AV_386_SSE4_1: u32 = 0x800000; ++pub const AV_386_SSE4_2: u32 = 0x1000000; ++pub const AV_386_MOVBE: u32 = 0x2000000; ++pub const AV_386_AES: u32 = 0x4000000; ++pub const AV_386_PCLMULQDQ: u32 = 0x8000000; ++pub const AV_386_XSAVE: u32 = 0x10000000; ++pub const AV_386_AVX: u32 = 0x20000000; ++pub const AV_386_VMX: u32 = 0x40000000; ++pub const AV_386_AMD_SVM: u32 = 0x80000000; ++// AT_SUN_HWCAP2 ++pub const AV_386_2_F16C: u32 = 0x00000001; ++pub const AV_386_2_RDRAND: u32 = 0x00000002; ++pub const AV_386_2_BMI1: u32 = 0x00000004; ++pub const AV_386_2_BMI2: u32 = 0x00000008; ++pub const AV_386_2_FMA: u32 = 0x00000010; ++pub const AV_386_2_AVX2: u32 = 0x00000020; ++pub const AV_386_2_ADX: u32 = 0x00000040; ++pub const AV_386_2_RDSEED: u32 = 0x00000080; ++pub const AV_386_2_AVX512F: u32 = 0x00000100; ++pub const AV_386_2_AVX512DQ: u32 = 0x00000200; ++pub const AV_386_2_AVX512IFMA: u32 = 0x00000400; ++pub const AV_386_2_AVX512PF: u32 = 0x00000800; ++pub const AV_386_2_AVX512ER: u32 = 0x00001000; ++pub const AV_386_2_AVX512CD: u32 = 0x00002000; ++pub const AV_386_2_AVX512BW: u32 = 0x00004000; ++pub const AV_386_2_AVX512VL: u32 = 0x00008000; ++pub const AV_386_2_AVX512VBMI: u32 = 0x00010000; ++pub const AV_386_2_AVX512VPOPCDQ: u32 = 0x00020000; ++pub const AV_386_2_AVX512_4NNIW: u32 = 0x00040000; ++pub const AV_386_2_AVX512_4FMAPS: u32 = 0x00080000; ++pub const AV_386_2_SHA: u32 = 0x00100000; ++pub const AV_386_2_FSGSBASE: u32 = 0x00200000; ++pub const AV_386_2_CLFLUSHOPT: u32 = 0x00400000; ++pub const AV_386_2_CLWB: u32 = 0x00800000; ++pub const AV_386_2_MONITORX: u32 = 0x01000000; ++pub const AV_386_2_CLZERO: u32 = 0x02000000; ++pub const AV_386_2_AVX512_VNNI: u32 = 0x04000000; ++pub const AV_386_2_VPCLMULQDQ: u32 = 0x08000000; ++pub const AV_386_2_VAES: u32 = 0x10000000; ++// AT_SUN_FPTYPE ++pub const AT_386_FPINFO_NONE: u32 = 0; ++pub const AT_386_FPINFO_FXSAVE: u32 = 1; ++pub const AT_386_FPINFO_XSAVE: u32 = 2; ++pub const AT_386_FPINFO_XSAVE_AMD: u32 = 3; +diff --git a/vendor/libc/src/vxworks/mod.rs b/vendor/libc/src/vxworks/mod.rs +old mode 100755 +new mode 100644 +index 1e4deb7..6b705e8 +--- a/vendor/libc/src/vxworks/mod.rs ++++ b/vendor/libc/src/vxworks/mod.rs +@@ -631,6 +631,7 @@ pub const EFAULT: ::c_int = 14; + pub const ENOTEMPTY: ::c_int = 15; + pub const EBUSY: ::c_int = 16; + pub const EEXIST: ::c_int = 17; ++pub const EXDEV: ::c_int = 18; + pub const ENODEV: ::c_int = 19; + pub const ENOTDIR: ::c_int = 20; + pub const EISDIR: ::c_int = 21; +@@ -638,7 +639,9 @@ pub const EINVAL: ::c_int = 22; + pub const ENAMETOOLONG: ::c_int = 26; + pub const EFBIG: ::c_int = 27; + pub const ENOSPC: ::c_int = 28; ++pub const ESPIPE: ::c_int = 29; + pub const EROFS: ::c_int = 30; ++pub const EMLINK: ::c_int = 31; + pub const EPIPE: ::c_int = 32; + pub const EDEADLK: ::c_int = 33; + pub const ERANGE: ::c_int = 38; +@@ -664,6 +667,10 @@ pub const ESHUTDOWN: ::c_int = 58; + pub const ETOOMANYREFS: ::c_int = 59; + pub const ETIMEDOUT: ::c_int = 60; + pub const ECONNREFUSED: ::c_int = 61; ++pub const ENETDOWN: ::c_int = 62; ++pub const ETXTBSY: ::c_int = 63; ++pub const ELOOP: ::c_int = 64; ++pub const EHOSTUNREACH: ::c_int = 65; + pub const EINPROGRESS: ::c_int = 68; + pub const EALREADY: ::c_int = 69; + pub const EWOULDBLOCK: ::c_int = 70; +@@ -1112,10 +1119,16 @@ extern "C" { + pub fn feof(stream: *mut FILE) -> c_int; + pub fn ferror(stream: *mut FILE) -> c_int; + pub fn perror(s: *const c_char); ++ pub fn atof(s: *const c_char) -> c_double; + pub fn atoi(s: *const c_char) -> c_int; ++ pub fn atol(s: *const c_char) -> c_long; ++ pub fn atoll(s: *const c_char) -> c_longlong; + pub fn strtod(s: *const c_char, endp: *mut *mut c_char) -> c_double; ++ pub fn strtof(s: *const c_char, endp: *mut *mut c_char) -> c_float; + pub fn strtol(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_long; ++ pub fn strtoll(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_longlong; + pub fn strtoul(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulong; ++ pub fn strtoull(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulonglong; + pub fn calloc(nobj: size_t, size: size_t) -> *mut c_void; + pub fn malloc(size: size_t) -> *mut c_void; + pub fn realloc(p: *mut c_void, size: size_t) -> *mut c_void; +@@ -1212,6 +1225,8 @@ extern "C" { + + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + ++ pub fn sigaddset(set: *mut sigset_t, signum: ::c_int) -> ::c_int; ++ + pub fn sigaction(signum: ::c_int, act: *const sigaction, oldact: *mut sigaction) -> ::c_int; + + pub fn utimes(filename: *const ::c_char, times: *const ::timeval) -> ::c_int; +diff --git a/vendor/libc/src/wasi.rs b/vendor/libc/src/wasi.rs +index 5ef5438..1a855e0 100644 +--- a/vendor/libc/src/wasi.rs ++++ b/vendor/libc/src/wasi.rs +@@ -1,3 +1,5 @@ ++use super::{Send, Sync}; ++ + pub use ffi::c_void; + + pub type c_char = i8; +@@ -36,9 +38,17 @@ pub type blksize_t = c_long; + pub type blkcnt_t = i64; + pub type nfds_t = c_ulong; + pub type wchar_t = i32; +- ++pub type nl_item = c_int; + pub type __wasi_rights_t = u64; + ++s_no_extra_traits! { ++ #[repr(align(16))] ++ #[allow(missing_debug_implementations)] ++ pub struct max_align_t { ++ priv_: [f64; 4] ++ } ++} ++ + #[allow(missing_copy_implementations)] + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub enum FILE {} +@@ -51,6 +61,16 @@ pub enum __locale_struct {} + + pub type locale_t = *mut __locale_struct; + ++s_paren! { ++ // in wasi-libc clockid_t is const struct __clockid* (where __clockid is an opaque struct), ++ // but that's an implementation detail that we don't want to have to deal with ++ #[repr(transparent)] ++ pub struct clockid_t(*const u8); ++} ++ ++unsafe impl Send for clockid_t {} ++unsafe impl Sync for clockid_t {} ++ + s! { + #[repr(align(8))] + pub struct fpos_t { +@@ -226,6 +246,21 @@ pub const S_IFREG: mode_t = 32768; + pub const S_IFLNK: mode_t = 40960; + pub const S_IFSOCK: mode_t = 49152; + pub const S_IFMT: mode_t = 57344; ++pub const S_IRWXO: mode_t = 0x7; ++pub const S_IXOTH: mode_t = 0x1; ++pub const S_IWOTH: mode_t = 0x2; ++pub const S_IROTH: mode_t = 0x4; ++pub const S_IRWXG: mode_t = 0x38; ++pub const S_IXGRP: mode_t = 0x8; ++pub const S_IWGRP: mode_t = 0x10; ++pub const S_IRGRP: mode_t = 0x20; ++pub const S_IRWXU: mode_t = 0x1c0; ++pub const S_IXUSR: mode_t = 0x40; ++pub const S_IWUSR: mode_t = 0x80; ++pub const S_IRUSR: mode_t = 0x100; ++pub const S_ISVTX: mode_t = 0x200; ++pub const S_ISGID: mode_t = 0x400; ++pub const S_ISUID: mode_t = 0x800; + pub const DT_UNKNOWN: u8 = 0; + pub const DT_BLK: u8 = 1; + pub const DT_CHR: u8 = 2; +@@ -330,9 +365,86 @@ pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; + pub const _SC_IOV_MAX: c_int = 60; + pub const _SC_SYMLOOP_MAX: c_int = 173; + ++pub static CLOCK_MONOTONIC: clockid_t = unsafe { clockid_t(ptr_addr_of!(_CLOCK_MONOTONIC)) }; ++pub static CLOCK_PROCESS_CPUTIME_ID: clockid_t = ++ unsafe { clockid_t(ptr_addr_of!(_CLOCK_PROCESS_CPUTIME_ID)) }; ++pub static CLOCK_REALTIME: clockid_t = unsafe { clockid_t(ptr_addr_of!(_CLOCK_REALTIME)) }; ++pub static CLOCK_THREAD_CPUTIME_ID: clockid_t = ++ unsafe { clockid_t(ptr_addr_of!(_CLOCK_THREAD_CPUTIME_ID)) }; ++ ++pub const ABDAY_1: ::nl_item = 0x20000; ++pub const ABDAY_2: ::nl_item = 0x20001; ++pub const ABDAY_3: ::nl_item = 0x20002; ++pub const ABDAY_4: ::nl_item = 0x20003; ++pub const ABDAY_5: ::nl_item = 0x20004; ++pub const ABDAY_6: ::nl_item = 0x20005; ++pub const ABDAY_7: ::nl_item = 0x20006; ++ ++pub const DAY_1: ::nl_item = 0x20007; ++pub const DAY_2: ::nl_item = 0x20008; ++pub const DAY_3: ::nl_item = 0x20009; ++pub const DAY_4: ::nl_item = 0x2000A; ++pub const DAY_5: ::nl_item = 0x2000B; ++pub const DAY_6: ::nl_item = 0x2000C; ++pub const DAY_7: ::nl_item = 0x2000D; ++ ++pub const ABMON_1: ::nl_item = 0x2000E; ++pub const ABMON_2: ::nl_item = 0x2000F; ++pub const ABMON_3: ::nl_item = 0x20010; ++pub const ABMON_4: ::nl_item = 0x20011; ++pub const ABMON_5: ::nl_item = 0x20012; ++pub const ABMON_6: ::nl_item = 0x20013; ++pub const ABMON_7: ::nl_item = 0x20014; ++pub const ABMON_8: ::nl_item = 0x20015; ++pub const ABMON_9: ::nl_item = 0x20016; ++pub const ABMON_10: ::nl_item = 0x20017; ++pub const ABMON_11: ::nl_item = 0x20018; ++pub const ABMON_12: ::nl_item = 0x20019; ++ ++pub const MON_1: ::nl_item = 0x2001A; ++pub const MON_2: ::nl_item = 0x2001B; ++pub const MON_3: ::nl_item = 0x2001C; ++pub const MON_4: ::nl_item = 0x2001D; ++pub const MON_5: ::nl_item = 0x2001E; ++pub const MON_6: ::nl_item = 0x2001F; ++pub const MON_7: ::nl_item = 0x20020; ++pub const MON_8: ::nl_item = 0x20021; ++pub const MON_9: ::nl_item = 0x20022; ++pub const MON_10: ::nl_item = 0x20023; ++pub const MON_11: ::nl_item = 0x20024; ++pub const MON_12: ::nl_item = 0x20025; ++ ++pub const AM_STR: ::nl_item = 0x20026; ++pub const PM_STR: ::nl_item = 0x20027; ++ ++pub const D_T_FMT: ::nl_item = 0x20028; ++pub const D_FMT: ::nl_item = 0x20029; ++pub const T_FMT: ::nl_item = 0x2002A; ++pub const T_FMT_AMPM: ::nl_item = 0x2002B; ++ ++pub const ERA: ::nl_item = 0x2002C; ++pub const ERA_D_FMT: ::nl_item = 0x2002E; ++pub const ALT_DIGITS: ::nl_item = 0x2002F; ++pub const ERA_D_T_FMT: ::nl_item = 0x20030; ++pub const ERA_T_FMT: ::nl_item = 0x20031; ++ ++pub const CODESET: ::nl_item = 14; ++pub const CRNCYSTR: ::nl_item = 0x4000F; ++pub const RADIXCHAR: ::nl_item = 0x10000; ++pub const THOUSEP: ::nl_item = 0x10001; ++pub const YESEXPR: ::nl_item = 0x50000; ++pub const NOEXPR: ::nl_item = 0x50001; ++pub const YESSTR: ::nl_item = 0x50002; ++pub const NOSTR: ::nl_item = 0x50003; ++ + #[cfg_attr( + feature = "rustc-dep-of-std", +- link(name = "c", kind = "static", cfg(target_feature = "crt-static")) ++ link( ++ name = "c", ++ kind = "static", ++ modifiers = "-bundle", ++ cfg(target_feature = "crt-static") ++ ) + )] + #[cfg_attr( + feature = "rustc-dep-of-std", +@@ -405,15 +517,14 @@ extern "C" { + pub fn asctime_r(a: *const tm, b: *mut c_char) -> *mut c_char; + pub fn ctime_r(a: *const time_t, b: *mut c_char) -> *mut c_char; + ++ static _CLOCK_MONOTONIC: u8; ++ static _CLOCK_PROCESS_CPUTIME_ID: u8; ++ static _CLOCK_REALTIME: u8; ++ static _CLOCK_THREAD_CPUTIME_ID: u8; + pub fn nanosleep(a: *const timespec, b: *mut timespec) -> c_int; +- // pub fn clock_getres(a: clockid_t, b: *mut timespec) -> c_int; +- // pub fn clock_gettime(a: clockid_t, b: *mut timespec) -> c_int; +- // pub fn clock_nanosleep( +- // a: clockid_t, +- // a2: c_int, +- // b: *const timespec, +- // c: *mut timespec, +- // ) -> c_int; ++ pub fn clock_getres(a: clockid_t, b: *mut timespec) -> c_int; ++ pub fn clock_gettime(a: clockid_t, b: *mut timespec) -> c_int; ++ pub fn clock_nanosleep(a: clockid_t, a2: c_int, b: *const timespec, c: *mut timespec) -> c_int; + + pub fn isalnum(c: c_int) -> c_int; + pub fn isalpha(c: c_int) -> c_int; +@@ -432,11 +543,16 @@ extern "C" { + pub fn setvbuf(stream: *mut FILE, buffer: *mut c_char, mode: c_int, size: size_t) -> c_int; + pub fn setbuf(stream: *mut FILE, buf: *mut c_char); + pub fn fgets(buf: *mut c_char, n: c_int, stream: *mut FILE) -> *mut c_char; +- pub fn atoi(s: *const c_char) -> c_int; + pub fn atof(s: *const c_char) -> c_double; ++ pub fn atoi(s: *const c_char) -> c_int; ++ pub fn atol(s: *const c_char) -> c_long; ++ pub fn atoll(s: *const c_char) -> c_longlong; + pub fn strtod(s: *const c_char, endp: *mut *mut c_char) -> c_double; ++ pub fn strtof(s: *const c_char, endp: *mut *mut c_char) -> c_float; + pub fn strtol(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_long; ++ pub fn strtoll(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_longlong; + pub fn strtoul(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulong; ++ pub fn strtoull(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulonglong; + + pub fn strcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char; + pub fn strncpy(dst: *mut c_char, src: *const c_char, n: size_t) -> *mut c_char; +@@ -610,6 +726,11 @@ extern "C" { + pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t; + pub fn uselocale(loc: ::locale_t) -> ::locale_t; + pub fn sched_yield() -> ::c_int; ++ pub fn getcwd(buf: *mut c_char, size: ::size_t) -> *mut c_char; ++ pub fn chdir(dir: *const c_char) -> ::c_int; ++ ++ pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; ++ pub fn nl_langinfo_l(item: ::nl_item, loc: ::locale_t) -> *mut ::c_char; + + pub fn __wasilibc_register_preopened_fd(fd: c_int, path: *const c_char) -> c_int; + pub fn __wasilibc_fd_renumber(fd: c_int, newfd: c_int) -> c_int; +@@ -704,4 +825,6 @@ extern "C" { + pub fn arc4random() -> u32; + pub fn arc4random_buf(a: *mut c_void, b: size_t); + pub fn arc4random_uniform(a: u32) -> u32; ++ ++ pub fn __errno_location() -> *mut ::c_int; + } +diff --git a/vendor/libc/src/windows/mod.rs b/vendor/libc/src/windows/mod.rs +index ad0dc77..7f2f1de 100644 +--- a/vendor/libc/src/windows/mod.rs ++++ b/vendor/libc/src/windows/mod.rs +@@ -27,6 +27,8 @@ pub type wchar_t = u16; + + pub type clock_t = i32; + ++pub type errno_t = ::c_int; ++ + cfg_if! { + if #[cfg(all(target_arch = "x86", target_env = "gnu"))] { + pub type time_t = i32; +@@ -275,6 +277,16 @@ impl ::Clone for fpos_t { + } + } + ++// Special handling for all print and scan type functions because of https://github.com/rust-lang/libc/issues/2860 ++#[cfg_attr( ++ all(windows, target_env = "msvc"), ++ link(name = "legacy_stdio_definitions") ++)] ++extern "C" { ++ pub fn printf(format: *const c_char, ...) -> ::c_int; ++ pub fn fprintf(stream: *mut FILE, format: *const c_char, ...) -> ::c_int; ++} ++ + extern "C" { + pub fn isalnum(c: c_int) -> c_int; + pub fn isalpha(c: c_int) -> c_int; +@@ -317,10 +329,16 @@ extern "C" { + pub fn feof(stream: *mut FILE) -> c_int; + pub fn ferror(stream: *mut FILE) -> c_int; + pub fn perror(s: *const c_char); ++ pub fn atof(s: *const c_char) -> c_double; + pub fn atoi(s: *const c_char) -> c_int; ++ pub fn atol(s: *const c_char) -> c_long; ++ pub fn atoll(s: *const c_char) -> c_longlong; + pub fn strtod(s: *const c_char, endp: *mut *mut c_char) -> c_double; ++ pub fn strtof(s: *const c_char, endp: *mut *mut c_char) -> c_float; + pub fn strtol(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_long; ++ pub fn strtoll(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_longlong; + pub fn strtoul(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulong; ++ pub fn strtoull(s: *const c_char, endp: *mut *mut c_char, base: c_int) -> c_ulonglong; + pub fn calloc(nobj: size_t, size: size_t) -> *mut c_void; + pub fn malloc(size: size_t) -> *mut c_void; + pub fn realloc(p: *mut c_void, size: size_t) -> *mut c_void; +@@ -361,7 +379,6 @@ extern "C" { + pub fn memset(dest: *mut c_void, c: c_int, n: size_t) -> *mut c_void; + + pub fn abs(i: c_int) -> c_int; +- pub fn atof(s: *const c_char) -> c_double; + pub fn labs(i: c_long) -> c_long; + pub fn rand() -> c_int; + pub fn srand(seed: c_uint); +@@ -371,6 +388,8 @@ extern "C" { + + #[link_name = "_gmtime64_s"] + pub fn gmtime_s(destTime: *mut tm, srcTime: *const time_t) -> ::c_int; ++ #[link_name = "_localtime64_s"] ++ pub fn localtime_s(tmDest: *mut tm, sourceTime: *const time_t) -> ::errno_t; + #[link_name = "_time64"] + pub fn time(destTime: *mut time_t) -> time_t; + #[link_name = "_chmod"] +@@ -492,6 +511,16 @@ extern "C" { + pub fn wsetlocale(category: ::c_int, locale: *const wchar_t) -> *mut wchar_t; + #[link_name = "_aligned_malloc"] + pub fn aligned_malloc(size: size_t, alignment: size_t) -> *mut c_void; ++ #[link_name = "_aligned_free"] ++ pub fn aligned_free(ptr: *mut ::c_void); ++ #[link_name = "_putenv"] ++ pub fn putenv(envstring: *const ::c_char) -> ::c_int; ++ #[link_name = "_wputenv"] ++ pub fn wputenv(envstring: *const ::wchar_t) -> ::c_int; ++ #[link_name = "_putenv_s"] ++ pub fn putenv_s(envstring: *const ::c_char, value_string: *const ::c_char) -> ::errno_t; ++ #[link_name = "_wputenv_s"] ++ pub fn wputenv_s(envstring: *const ::wchar_t, value_string: *const ::wchar_t) -> ::errno_t; + } + + extern "system" { +diff --git a/vendor/libc/src/windows/msvc.rs b/vendor/libc/src/windows/msvc/mod.rs +similarity index 72% +rename from vendor/libc/src/windows/msvc.rs +rename to vendor/libc/src/windows/msvc/mod.rs +index b4c98a8..f5a1d95 100644 +--- a/vendor/libc/src/windows/msvc.rs ++++ b/vendor/libc/src/windows/msvc/mod.rs +@@ -10,4 +10,11 @@ extern "C" { + pub fn stricmp(s1: *const ::c_char, s2: *const ::c_char) -> ::c_int; + #[link_name = "_strnicmp"] + pub fn strnicmp(s1: *const ::c_char, s2: *const ::c_char, n: ::size_t) -> ::c_int; ++ #[link_name = "_memccpy"] ++ pub fn memccpy( ++ dest: *mut ::c_void, ++ src: *const ::c_void, ++ c: ::c_int, ++ count: ::size_t, ++ ) -> *mut ::c_void; + } +diff --git a/vendor/libc/src/xous.rs b/vendor/libc/src/xous.rs +new file mode 100644 +index 0000000..e6c0c25 +--- /dev/null ++++ b/vendor/libc/src/xous.rs +@@ -0,0 +1,49 @@ ++//! Xous C type definitions ++ ++pub type c_schar = i8; ++pub type c_uchar = u8; ++pub type c_short = i16; ++pub type c_ushort = u16; ++pub type c_int = i32; ++pub type c_uint = u32; ++pub type c_float = f32; ++pub type c_double = f64; ++pub type c_longlong = i64; ++pub type c_ulonglong = u64; ++pub type intmax_t = i64; ++pub type uintmax_t = u64; ++ ++pub type size_t = usize; ++pub type ptrdiff_t = isize; ++pub type intptr_t = isize; ++pub type uintptr_t = usize; ++pub type ssize_t = isize; ++ ++pub type off_t = i64; ++pub type c_char = u8; ++pub type c_long = i64; ++pub type c_ulong = u64; ++pub type wchar_t = u32; ++ ++pub const INT_MIN: c_int = -2147483648; ++pub const INT_MAX: c_int = 2147483647; ++ ++cfg_if! { ++ if #[cfg(libc_core_cvoid)] { ++ pub use ::ffi::c_void; ++ } else { ++ // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help ++ // enable more optimization opportunities around it recognizing things ++ // like malloc/free. ++ #[repr(u8)] ++ #[allow(missing_copy_implementations)] ++ #[allow(missing_debug_implementations)] ++ pub enum c_void { ++ // Two dummy variants so the #[repr] attribute can be used. ++ #[doc(hidden)] ++ __variant1, ++ #[doc(hidden)] ++ __variant2, ++ } ++ } ++} +diff --git a/vendor/memoffset/.cargo-checksum.json b/vendor/memoffset/.cargo-checksum.json +new file mode 100644 +index 0000000..60f2c09 +--- /dev/null ++++ b/vendor/memoffset/.cargo-checksum.json +@@ -0,0 +1 @@ ++{"files":{"Cargo.toml":"2122b76e5dff09497c7edf7f184155e456e44209c05e4f8abb01632be7241b56","LICENSE":"3234ac55816264ee7b6c7ee27efd61cf0a1fe775806870e3d9b4c41ea73c5cb1","README.md":"7a7935d96a1a40b56afeadca391c742f7ac3a6e0f1deab1d43430553f71b6d23","build.rs":"6d677e33a1c98d588c97ec7985d4d5c3b954683e0a73c3dc53d79db4fbb5e638","src/lib.rs":"e7976d295371a3c1e0cf31b0d50210cd6b1135caba3a5111403a97ec6175c0a2","src/offset_of.rs":"ea04e76e3ab1fa192618fffb0c6a047795c275f1deaf6c6617245badaba8660c","src/raw_field.rs":"ef54087d5f507c2b639a4f61f2881eb1e41a46e22191ffd0e23b2fe9e3f17c25","src/span_of.rs":"b900faef2b852b52c37c55a172c05c9144bfff7d84dbc06e943fb0453d68adfc"},"package":"5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"} +\ No newline at end of file +diff --git a/vendor/memoffset/Cargo.toml b/vendor/memoffset/Cargo.toml +new file mode 100644 +index 0000000..1677446 +--- /dev/null ++++ b/vendor/memoffset/Cargo.toml +@@ -0,0 +1,36 @@ ++# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO ++# ++# When uploading crates to the registry Cargo will automatically ++# "normalize" Cargo.toml files for maximal compatibility ++# with all versions of Cargo and also rewrite `path` dependencies ++# to registry (e.g., crates.io) dependencies. ++# ++# If you are reading this file be aware that the original Cargo.toml ++# will likely look very different (and much more reasonable). ++# See Cargo.toml.orig for the original contents. ++ ++[package] ++name = "memoffset" ++version = "0.7.1" ++authors = ["Gilad Naaman "] ++description = "offset_of functionality for Rust structs." ++readme = "README.md" ++keywords = [ ++ "mem", ++ "offset", ++ "offset_of", ++ "offsetof", ++] ++categories = ["no-std"] ++license = "MIT" ++repository = "https://github.com/Gilnaa/memoffset" ++ ++[dev-dependencies.doc-comment] ++version = "0.3" ++ ++[build-dependencies.autocfg] ++version = "1" ++ ++[features] ++default = [] ++unstable_const = [] +diff --git a/vendor/memoffset/LICENSE b/vendor/memoffset/LICENSE +new file mode 100644 +index 0000000..61f6081 +--- /dev/null ++++ b/vendor/memoffset/LICENSE +@@ -0,0 +1,19 @@ ++Copyright (c) 2017 Gilad Naaman ++ ++Permission is hereby granted, free of charge, to any person obtaining a copy ++of this software and associated documentation files (the "Software"), to deal ++in the Software without restriction, including without limitation the rights ++to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++copies of the Software, and to permit persons to whom the Software is ++furnished to do so, subject to the following conditions: ++ ++The above copyright notice and this permission notice shall be included in all ++copies or substantial portions of the Software. ++ ++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++SOFTWARE. +\ No newline at end of file +diff --git a/vendor/memoffset/README.md b/vendor/memoffset/README.md +new file mode 100644 +index 0000000..e297b33 +--- /dev/null ++++ b/vendor/memoffset/README.md +@@ -0,0 +1,65 @@ ++# memoffset # ++ ++[![](https://img.shields.io/crates/v/memoffset.svg)](https://crates.io/crates/memoffset) ++ ++C-Like `offset_of` functionality for Rust structs. ++ ++Introduces the following macros: ++ * `offset_of!` for obtaining the offset of a member of a struct. ++ * `offset_of_tuple!` for obtaining the offset of a member of a tuple. (Requires Rust 1.20+) ++ * `span_of!` for obtaining the range that a field, or fields, span. ++ ++`memoffset` works under `no_std` environments. ++ ++## Usage ## ++Add the following dependency to your `Cargo.toml`: ++ ++```toml ++[dependencies] ++memoffset = "0.7" ++``` ++ ++These versions will compile fine with rustc versions greater or equal to 1.19. ++ ++## Examples ## ++```rust ++use memoffset::{offset_of, span_of}; ++ ++#[repr(C, packed)] ++struct Foo { ++ a: u32, ++ b: u32, ++ c: [u8; 5], ++ d: u32, ++} ++ ++fn main() { ++ assert_eq!(offset_of!(Foo, b), 4); ++ assert_eq!(offset_of!(Foo, d), 4+4+5); ++ ++ assert_eq!(span_of!(Foo, a), 0..4); ++ assert_eq!(span_of!(Foo, a .. c), 0..8); ++ assert_eq!(span_of!(Foo, a ..= c), 0..13); ++ assert_eq!(span_of!(Foo, ..= d), 0..17); ++ assert_eq!(span_of!(Foo, b ..), 4..17); ++} ++``` ++ ++## Feature flags ## ++ ++### Usage in constants ### ++`memoffset` has **experimental** support for compile-time `offset_of!` on a nightly compiler. ++ ++In order to use it, you must enable the `unstable_const` crate feature and several compiler features. ++ ++Cargo.toml: ++```toml ++[dependencies.memoffset] ++version = "0.7" ++features = ["unstable_const"] ++``` ++ ++Your crate root: (`lib.rs`/`main.rs`) ++```rust,ignore ++#![feature(const_ptr_offset_from, const_refs_to_cell)] ++``` +diff --git a/vendor/memoffset/build.rs b/vendor/memoffset/build.rs +new file mode 100644 +index 0000000..0604c19 +--- /dev/null ++++ b/vendor/memoffset/build.rs +@@ -0,0 +1,22 @@ ++extern crate autocfg; ++ ++fn main() { ++ let ac = autocfg::new(); ++ ++ // Check for a minimum version for a few features ++ if ac.probe_rustc_version(1, 20) { ++ println!("cargo:rustc-cfg=tuple_ty"); ++ } ++ if ac.probe_rustc_version(1, 31) { ++ println!("cargo:rustc-cfg=allow_clippy"); ++ } ++ if ac.probe_rustc_version(1, 36) { ++ println!("cargo:rustc-cfg=maybe_uninit"); ++ } ++ if ac.probe_rustc_version(1, 40) { ++ println!("cargo:rustc-cfg=doctests"); ++ } ++ if ac.probe_rustc_version(1, 51) { ++ println!("cargo:rustc-cfg=raw_ref_macros"); ++ } ++} +diff --git a/vendor/memoffset/src/lib.rs b/vendor/memoffset/src/lib.rs +new file mode 100644 +index 0000000..d80ff17 +--- /dev/null ++++ b/vendor/memoffset/src/lib.rs +@@ -0,0 +1,92 @@ ++// Copyright (c) 2017 Gilad Naaman ++// ++// Permission is hereby granted, free of charge, to any person obtaining a copy ++// of this software and associated documentation files (the "Software"), to deal ++// in the Software without restriction, including without limitation the rights ++// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++// copies of the Software, and to permit persons to whom the Software is ++// furnished to do so, subject to the following conditions: ++// ++// The above copyright notice and this permission notice shall be included in all ++// copies or substantial portions of the Software. ++// ++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++// SOFTWARE. ++ ++//! A crate used for calculating offsets of struct members and their spans. ++//! ++//! This functionality currently can not be used in compile time code such as `const` or `const fn` definitions. ++//! ++//! ## Examples ++//! ``` ++//! use memoffset::{offset_of, span_of}; ++//! ++//! #[repr(C, packed)] ++//! struct HelpMeIAmTrappedInAStructFactory { ++//! help_me_before_they_: [u8; 15], ++//! a: u32 ++//! } ++//! ++//! fn main() { ++//! assert_eq!(offset_of!(HelpMeIAmTrappedInAStructFactory, a), 15); ++//! assert_eq!(span_of!(HelpMeIAmTrappedInAStructFactory, a), 15..19); ++//! assert_eq!(span_of!(HelpMeIAmTrappedInAStructFactory, help_me_before_they_ .. a), 0..15); ++//! } ++//! ``` ++//! ++//! This functionality can be useful, for example, for checksum calculations: ++//! ++//! ```ignore ++//! #[repr(C, packed)] ++//! struct Message { ++//! header: MessageHeader, ++//! fragment_index: u32, ++//! fragment_count: u32, ++//! payload: [u8; 1024], ++//! checksum: u16 ++//! } ++//! ++//! let checksum_range = &raw[span_of!(Message, header..checksum)]; ++//! let checksum = crc16(checksum_range); ++//! ``` ++ ++#![no_std] ++#![cfg_attr( ++ feature = "unstable_const", ++ feature(const_ptr_offset_from, const_refs_to_cell) ++)] ++ ++#[macro_use] ++#[cfg(doctests)] ++#[cfg(doctest)] ++extern crate doc_comment; ++#[cfg(doctests)] ++#[cfg(doctest)] ++doctest!("../README.md"); ++ ++/// Hidden module for things the macros need to access. ++#[doc(hidden)] ++pub mod __priv { ++ #[doc(hidden)] ++ pub use core::mem; ++ #[doc(hidden)] ++ pub use core::ptr; ++ ++ /// Use type inference to obtain the size of the pointee (without actually using the pointer). ++ #[doc(hidden)] ++ pub fn size_of_pointee(_ptr: *const T) -> usize { ++ mem::size_of::() ++ } ++} ++ ++#[macro_use] ++mod raw_field; ++#[macro_use] ++mod offset_of; ++#[macro_use] ++mod span_of; +diff --git a/vendor/memoffset/src/offset_of.rs b/vendor/memoffset/src/offset_of.rs +new file mode 100644 +index 0000000..d070181 +--- /dev/null ++++ b/vendor/memoffset/src/offset_of.rs +@@ -0,0 +1,356 @@ ++// Copyright (c) 2017 Gilad Naaman ++// ++// Permission is hereby granted, free of charge, to any person obtaining a copy ++// of this software and associated documentation files (the "Software"), to deal ++// in the Software without restriction, including without limitation the rights ++// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++// copies of the Software, and to permit persons to whom the Software is ++// furnished to do so, subject to the following conditions: ++// ++// The above copyright notice and this permission notice shall be included in all ++// copies or substantial portions of the Software. ++// ++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++// SOFTWARE. ++ ++/// Macro to create a local `base_ptr` raw pointer of the given type, avoiding UB as ++/// much as is possible currently. ++#[cfg(maybe_uninit)] ++#[macro_export] ++#[doc(hidden)] ++macro_rules! _memoffset__let_base_ptr { ++ ($name:ident, $type:ty) => { ++ // No UB here, and the pointer does not dangle, either. ++ // But we have to make sure that `uninit` lives long enough, ++ // so it has to be in the same scope as `$name`. That's why ++ // `let_base_ptr` declares a variable (several, actually) ++ // instead of returning one. ++ let uninit = $crate::__priv::mem::MaybeUninit::<$type>::uninit(); ++ let $name: *const $type = uninit.as_ptr(); ++ }; ++} ++#[cfg(not(maybe_uninit))] ++#[macro_export] ++#[doc(hidden)] ++macro_rules! _memoffset__let_base_ptr { ++ ($name:ident, $type:ty) => { ++ // No UB right here, but we will later dereference this pointer to ++ // offset into a field, and that is UB because the pointer is dangling. ++ let $name = $crate::__priv::mem::align_of::<$type>() as *const $type; ++ }; ++} ++ ++/// Macro to compute the distance between two pointers. ++#[cfg(feature = "unstable_const")] ++#[macro_export] ++#[doc(hidden)] ++macro_rules! _memoffset_offset_from_unsafe { ++ ($field:expr, $base:expr) => {{ ++ let field = $field; // evaluate $field outside the `unsafe` block ++ let base = $base; // evaluate $base outside the `unsafe` block ++ // Compute offset, with unstable `offset_from` for const-compatibility. ++ // (Requires the pointers to not dangle, but we already need that for `raw_field!` anyway.) ++ unsafe { (field as *const u8).offset_from(base as *const u8) as usize } ++ }}; ++} ++#[cfg(not(feature = "unstable_const"))] ++#[macro_export] ++#[doc(hidden)] ++macro_rules! _memoffset_offset_from_unsafe { ++ ($field:expr, $base:expr) => { ++ // Compute offset. ++ ($field as usize) - ($base as usize) ++ }; ++} ++ ++/// Calculates the offset of the specified field from the start of the named struct. ++/// ++/// ## Examples ++/// ``` ++/// use memoffset::offset_of; ++/// ++/// #[repr(C, packed)] ++/// struct Foo { ++/// a: u32, ++/// b: u64, ++/// c: [u8; 5] ++/// } ++/// ++/// fn main() { ++/// assert_eq!(offset_of!(Foo, a), 0); ++/// assert_eq!(offset_of!(Foo, b), 4); ++/// } ++/// ``` ++/// ++/// ## Notes ++/// Rust's ABI is unstable, and [type layout can be changed with each ++/// compilation](https://doc.rust-lang.org/reference/type-layout.html). ++/// ++/// Using `offset_of!` with a `repr(Rust)` struct will return the correct offset of the ++/// specified `field` for a particular compilation, but the exact value may change ++/// based on the compiler version, concrete struct type, time of day, or rustc's mood. ++/// ++/// As a result, the value should not be retained and used between different compilations. ++#[macro_export(local_inner_macros)] ++macro_rules! offset_of { ++ ($parent:path, $field:tt) => {{ ++ // Get a base pointer (non-dangling if rustc supports `MaybeUninit`). ++ _memoffset__let_base_ptr!(base_ptr, $parent); ++ // Get field pointer. ++ let field_ptr = raw_field!(base_ptr, $parent, $field); ++ // Compute offset. ++ _memoffset_offset_from_unsafe!(field_ptr, base_ptr) ++ }}; ++} ++ ++/// Calculates the offset of the specified field from the start of the tuple. ++/// ++/// ## Examples ++/// ``` ++/// use memoffset::offset_of_tuple; ++/// ++/// fn main() { ++/// assert!(offset_of_tuple!((u8, u32), 1) >= 0, "Tuples do not have a defined layout"); ++/// } ++/// ``` ++#[cfg(tuple_ty)] ++#[macro_export(local_inner_macros)] ++macro_rules! offset_of_tuple { ++ ($parent:ty, $field:tt) => {{ ++ // Get a base pointer (non-dangling if rustc supports `MaybeUninit`). ++ _memoffset__let_base_ptr!(base_ptr, $parent); ++ // Get field pointer. ++ let field_ptr = raw_field_tuple!(base_ptr, $parent, $field); ++ // Compute offset. ++ _memoffset_offset_from_unsafe!(field_ptr, base_ptr) ++ }}; ++} ++ ++/// Calculates the offset of the specified union member from the start of the union. ++/// ++/// ## Examples ++/// ``` ++/// use memoffset::offset_of_union; ++/// ++/// #[repr(C, packed)] ++/// union Foo { ++/// foo32: i32, ++/// foo64: i64, ++/// } ++/// ++/// fn main() { ++/// assert!(offset_of_union!(Foo, foo64) == 0); ++/// } ++/// ``` ++/// ++/// ## Note ++/// Due to macro_rules limitations, this macro will accept structs with a single field as well as unions. ++/// This is not a stable guarantee, and future versions of this crate might fail ++/// on any use of this macro with a struct, without a semver bump. ++#[macro_export(local_inner_macros)] ++macro_rules! offset_of_union { ++ ($parent:path, $field:tt) => {{ ++ // Get a base pointer (non-dangling if rustc supports `MaybeUninit`). ++ _memoffset__let_base_ptr!(base_ptr, $parent); ++ // Get field pointer. ++ let field_ptr = raw_field_union!(base_ptr, $parent, $field); ++ // Compute offset. ++ _memoffset_offset_from_unsafe!(field_ptr, base_ptr) ++ }}; ++} ++ ++#[cfg(test)] ++mod tests { ++ #[test] ++ fn offset_simple() { ++ #[repr(C)] ++ struct Foo { ++ a: u32, ++ b: [u8; 2], ++ c: i64, ++ } ++ ++ assert_eq!(offset_of!(Foo, a), 0); ++ assert_eq!(offset_of!(Foo, b), 4); ++ assert_eq!(offset_of!(Foo, c), 8); ++ } ++ ++ #[test] ++ #[cfg_attr(miri, ignore)] // this creates unaligned references ++ fn offset_simple_packed() { ++ #[repr(C, packed)] ++ struct Foo { ++ a: u32, ++ b: [u8; 2], ++ c: i64, ++ } ++ ++ assert_eq!(offset_of!(Foo, a), 0); ++ assert_eq!(offset_of!(Foo, b), 4); ++ assert_eq!(offset_of!(Foo, c), 6); ++ } ++ ++ #[test] ++ fn tuple_struct() { ++ #[repr(C)] ++ struct Tup(i32, i32); ++ ++ assert_eq!(offset_of!(Tup, 0), 0); ++ assert_eq!(offset_of!(Tup, 1), 4); ++ } ++ ++ #[test] ++ fn offset_union() { ++ // Since we're specifying repr(C), all fields are supposed to be at offset 0 ++ #[repr(C)] ++ union Foo { ++ a: u32, ++ b: [u8; 2], ++ c: i64, ++ } ++ ++ assert_eq!(offset_of_union!(Foo, a), 0); ++ assert_eq!(offset_of_union!(Foo, b), 0); ++ assert_eq!(offset_of_union!(Foo, c), 0); ++ } ++ ++ #[test] ++ fn path() { ++ mod sub { ++ #[repr(C)] ++ pub struct Foo { ++ pub x: u32, ++ } ++ } ++ ++ assert_eq!(offset_of!(sub::Foo, x), 0); ++ } ++ ++ #[test] ++ fn inside_generic_method() { ++ struct Pair(T, U); ++ ++ fn foo(_: Pair) -> usize { ++ offset_of!(Pair, 1) ++ } ++ ++ assert_eq!(foo(Pair(0, 0)), 4); ++ } ++ ++ #[cfg(tuple_ty)] ++ #[test] ++ fn test_tuple_offset() { ++ let f = (0i32, 0.0f32, 0u8); ++ let f_ptr = &f as *const _; ++ let f1_ptr = &f.1 as *const _; ++ ++ assert_eq!( ++ f1_ptr as usize - f_ptr as usize, ++ offset_of_tuple!((i32, f32, u8), 1) ++ ); ++ } ++ ++ #[test] ++ fn test_raw_field() { ++ #[repr(C)] ++ struct Foo { ++ a: u32, ++ b: [u8; 2], ++ c: i64, ++ } ++ ++ let f: Foo = Foo { ++ a: 0, ++ b: [0, 0], ++ c: 0, ++ }; ++ let f_ptr = &f as *const _; ++ assert_eq!(f_ptr as usize + 0, raw_field!(f_ptr, Foo, a) as usize); ++ assert_eq!(f_ptr as usize + 4, raw_field!(f_ptr, Foo, b) as usize); ++ assert_eq!(f_ptr as usize + 8, raw_field!(f_ptr, Foo, c) as usize); ++ } ++ ++ #[cfg(tuple_ty)] ++ #[test] ++ fn test_raw_field_tuple() { ++ let t = (0u32, 0u8, false); ++ let t_ptr = &t as *const _; ++ let t_addr = t_ptr as usize; ++ ++ assert_eq!( ++ &t.0 as *const _ as usize - t_addr, ++ raw_field_tuple!(t_ptr, (u32, u8, bool), 0) as usize - t_addr ++ ); ++ assert_eq!( ++ &t.1 as *const _ as usize - t_addr, ++ raw_field_tuple!(t_ptr, (u32, u8, bool), 1) as usize - t_addr ++ ); ++ assert_eq!( ++ &t.2 as *const _ as usize - t_addr, ++ raw_field_tuple!(t_ptr, (u32, u8, bool), 2) as usize - t_addr ++ ); ++ } ++ ++ #[test] ++ fn test_raw_field_union() { ++ #[repr(C)] ++ union Foo { ++ a: u32, ++ b: [u8; 2], ++ c: i64, ++ } ++ ++ let f = Foo { a: 0 }; ++ let f_ptr = &f as *const _; ++ assert_eq!(f_ptr as usize + 0, raw_field_union!(f_ptr, Foo, a) as usize); ++ assert_eq!(f_ptr as usize + 0, raw_field_union!(f_ptr, Foo, b) as usize); ++ assert_eq!(f_ptr as usize + 0, raw_field_union!(f_ptr, Foo, c) as usize); ++ } ++ ++ #[cfg(feature = "unstable_const")] ++ #[test] ++ fn const_offset() { ++ #[repr(C)] ++ struct Foo { ++ a: u32, ++ b: [u8; 2], ++ c: i64, ++ } ++ ++ assert_eq!([0; offset_of!(Foo, b)].len(), 4); ++ } ++ ++ #[cfg(feature = "unstable_const")] ++ #[test] ++ fn const_offset_interior_mutable() { ++ #[repr(C)] ++ struct Foo { ++ a: u32, ++ b: core::cell::Cell, ++ } ++ ++ assert_eq!([0; offset_of!(Foo, b)].len(), 4); ++ } ++ ++ #[cfg(feature = "unstable_const")] ++ #[test] ++ fn const_fn_offset() { ++ const fn test_fn() -> usize { ++ #[repr(C)] ++ struct Foo { ++ a: u32, ++ b: [u8; 2], ++ c: i64, ++ } ++ ++ offset_of!(Foo, b) ++ } ++ ++ assert_eq!([0; test_fn()].len(), 4); ++ } ++} +diff --git a/vendor/memoffset/src/raw_field.rs b/vendor/memoffset/src/raw_field.rs +new file mode 100644 +index 0000000..e16df9f +--- /dev/null ++++ b/vendor/memoffset/src/raw_field.rs +@@ -0,0 +1,226 @@ ++// Copyright (c) 2020 Gilad Naaman, Ralf Jung ++// ++// Permission is hereby granted, free of charge, to any person obtaining a copy ++// of this software and associated documentation files (the "Software"), to deal ++// in the Software without restriction, including without limitation the rights ++// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++// copies of the Software, and to permit persons to whom the Software is ++// furnished to do so, subject to the following conditions: ++// ++// The above copyright notice and this permission notice shall be included in all ++// copies or substantial portions of the Software. ++// ++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++// SOFTWARE. ++ ++/// `addr_of!`, or just ref-then-cast when that is not available. ++#[cfg(raw_ref_macros)] ++#[macro_export] ++#[doc(hidden)] ++macro_rules! _memoffset__addr_of { ++ ($path:expr) => {{ ++ $crate::__priv::ptr::addr_of!($path) ++ }}; ++} ++#[cfg(not(raw_ref_macros))] ++#[macro_export] ++#[doc(hidden)] ++macro_rules! _memoffset__addr_of { ++ ($path:expr) => {{ ++ // This is UB because we create an intermediate reference to uninitialized memory. ++ // Nothing we can do about that without `addr_of!` though. ++ &$path as *const _ ++ }}; ++} ++ ++/// Deref-coercion protection macro. ++/// ++/// Prevents complilation if the specified field name is not a part of the ++/// struct definition. ++/// ++/// ```compile_fail ++/// use memoffset::_memoffset__field_check; ++/// ++/// struct Foo { ++/// foo: i32, ++/// } ++/// ++/// type BoxedFoo = Box; ++/// ++/// _memoffset__field_check!(BoxedFoo, foo); ++/// ``` ++#[cfg(allow_clippy)] ++#[macro_export] ++#[doc(hidden)] ++macro_rules! _memoffset__field_check { ++ ($type:path, $field:tt) => { ++ // Make sure the field actually exists. This line ensures that a ++ // compile-time error is generated if $field is accessed through a ++ // Deref impl. ++ #[allow(clippy::unneeded_field_pattern)] ++ let $type { $field: _, .. }; ++ }; ++} ++#[cfg(not(allow_clippy))] ++#[macro_export] ++#[doc(hidden)] ++macro_rules! _memoffset__field_check { ++ ($type:path, $field:tt) => { ++ // Make sure the field actually exists. This line ensures that a ++ // compile-time error is generated if $field is accessed through a ++ // Deref impl. ++ let $type { $field: _, .. }; ++ }; ++} ++ ++/// Deref-coercion protection macro. ++/// ++/// Prevents complilation if the specified type is not a tuple. ++/// ++/// ```compile_fail ++/// use memoffset::_memoffset__field_check_tuple; ++/// ++/// _memoffset__field_check_tuple!(i32, 0); ++/// ``` ++#[cfg(allow_clippy)] ++#[macro_export] ++#[doc(hidden)] ++macro_rules! _memoffset__field_check_tuple { ++ ($type:ty, $field:tt) => { ++ // Make sure the type argument is a tuple ++ #[allow(clippy::unneeded_wildcard_pattern)] ++ let (_, ..): $type; ++ }; ++} ++#[cfg(not(allow_clippy))] ++#[macro_export] ++#[doc(hidden)] ++macro_rules! _memoffset__field_check_tuple { ++ ($type:ty, $field:tt) => { ++ // Make sure the type argument is a tuple ++ let (_, ..): $type; ++ }; ++} ++ ++/// Deref-coercion protection macro for unions. ++/// Unfortunately accepts single-field structs as well, which is not ideal, ++/// but ultimately pretty harmless. ++/// ++/// ```compile_fail ++/// use memoffset::_memoffset__field_check_union; ++/// ++/// union Foo { ++/// variant_a: i32, ++/// } ++/// ++/// type BoxedFoo = Box; ++/// ++/// _memoffset__field_check_union!(BoxedFoo, variant_a); ++/// ``` ++#[cfg(allow_clippy)] ++#[macro_export] ++#[doc(hidden)] ++macro_rules! _memoffset__field_check_union { ++ ($type:path, $field:tt) => { ++ // Make sure the field actually exists. This line ensures that a ++ // compile-time error is generated if $field is accessed through a ++ // Deref impl. ++ #[allow(clippy::unneeded_wildcard_pattern)] ++ // rustc1.19 requires unsafe here for the pattern; not needed in newer versions ++ #[allow(unused_unsafe)] ++ unsafe { ++ let $type { $field: _ }; ++ } ++ }; ++} ++#[cfg(not(allow_clippy))] ++#[macro_export] ++#[doc(hidden)] ++macro_rules! _memoffset__field_check_union { ++ ($type:path, $field:tt) => { ++ // Make sure the field actually exists. This line ensures that a ++ // compile-time error is generated if $field is accessed through a ++ // Deref impl. ++ // rustc1.19 requires unsafe here for the pattern; not needed in newer versions ++ #[allow(unused_unsafe)] ++ unsafe { ++ let $type { $field: _ }; ++ } ++ }; ++} ++ ++/// Computes a const raw pointer to the given field of the given base pointer ++/// to the given parent type. ++/// ++/// The `base` pointer *must not* be dangling, but it *may* point to ++/// uninitialized memory. ++#[macro_export(local_inner_macros)] ++macro_rules! raw_field { ++ ($base:expr, $parent:path, $field:tt) => {{ ++ _memoffset__field_check!($parent, $field); ++ let base = $base; // evaluate $base outside the `unsafe` block ++ ++ // Get the field address. ++ // Crucially, we know that this will not trigger a deref coercion because ++ // of the field check we did above. ++ #[allow(unused_unsafe)] // for when the macro is used in an unsafe block ++ unsafe { ++ _memoffset__addr_of!((*(base as *const $parent)).$field) ++ } ++ }}; ++} ++ ++/// Computes a const raw pointer to the given field of the given base pointer ++/// to the given parent tuple typle. ++/// ++/// The `base` pointer *must not* be dangling, but it *may* point to ++/// uninitialized memory. ++#[cfg(tuple_ty)] ++#[macro_export(local_inner_macros)] ++macro_rules! raw_field_tuple { ++ ($base:expr, $parent:ty, $field:tt) => {{ ++ _memoffset__field_check_tuple!($parent, $field); ++ let base = $base; // evaluate $base outside the `unsafe` block ++ ++ // Get the field address. ++ // Crucially, we know that this will not trigger a deref coercion because ++ // of the field check we did above. ++ #[allow(unused_unsafe)] // for when the macro is used in an unsafe block ++ unsafe { ++ _memoffset__addr_of!((*(base as *const $parent)).$field) ++ } ++ }}; ++} ++ ++/// Computes a const raw pointer to the given field of the given base pointer ++/// to the given parent tuple typle. ++/// ++/// The `base` pointer *must not* be dangling, but it *may* point to ++/// uninitialized memory. ++/// ++/// ## Note ++/// This macro is the same as `raw_field`, except for a different Deref-coercion check that ++/// supports unions. ++/// Due to macro_rules limitations, this check will accept structs with a single field as well as unions. ++/// This is not a stable guarantee, and future versions of this crate might fail ++/// on any use of this macro with a struct, without a semver bump. ++#[macro_export(local_inner_macros)] ++macro_rules! raw_field_union { ++ ($base:expr, $parent:path, $field:tt) => {{ ++ _memoffset__field_check_union!($parent, $field); ++ let base = $base; // evaluate $base outside the `unsafe` block ++ ++ // Get the field address. ++ // Crucially, we know that this will not trigger a deref coercion because ++ // of the field check we did above. ++ #[allow(unused_unsafe)] // for when the macro is used in an unsafe block ++ unsafe { ++ _memoffset__addr_of!((*(base as *const $parent)).$field) ++ } ++ }}; ++} +diff --git a/vendor/memoffset/src/span_of.rs b/vendor/memoffset/src/span_of.rs +new file mode 100644 +index 0000000..89fccce +--- /dev/null ++++ b/vendor/memoffset/src/span_of.rs +@@ -0,0 +1,263 @@ ++// Copyright (c) 2017 Gilad Naaman ++// ++// Permission is hereby granted, free of charge, to any person obtaining a copy ++// of this software and associated documentation files (the "Software"), to deal ++// in the Software without restriction, including without limitation the rights ++// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++// copies of the Software, and to permit persons to whom the Software is ++// furnished to do so, subject to the following conditions: ++// ++// The above copyright notice and this permission notice shall be included in all ++// copies or substantial portions of the Software. ++// ++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++// SOFTWARE. ++ ++/// Reexport for `local_inner_macros`; see ++/// . ++#[doc(hidden)] ++#[macro_export] ++macro_rules! _memoffset__compile_error { ++ ($($inner:tt)*) => { ++ compile_error! { $($inner)* } ++ } ++} ++ ++/// Produces a range instance representing the sub-slice containing the specified member. ++/// ++/// This macro provides 2 forms of differing functionalities. ++/// ++/// The first form is identical to the appearance of the `offset_of!` macro. ++/// ++/// ```ignore ++/// span_of!(Struct, member) ++/// ``` ++/// ++/// The second form of `span_of!` returns a sub-slice which starts at one field, and ends at another. ++/// The general pattern of this form is: ++/// ++/// ```ignore ++/// // Exclusive ++/// span_of!(Struct, member_a .. member_b) ++/// // Inclusive ++/// span_of!(Struct, member_a ..= member_b) ++/// ++/// // Open-ended ranges ++/// span_of!(Struct, .. end) ++/// span_of!(Struct, start ..) ++/// ``` ++/// ++/// ### Note ++/// This macro uses recursion in order to resolve the range expressions, so there is a limit to ++/// the complexity of the expression. ++/// In order to raise the limit, the compiler's recursion limit should be lifted. ++/// ++/// ### Safety ++/// The inter-field form mentioned above assumes that the first field is positioned before the ++/// second. ++/// This is only guarenteed for `repr(C)` structs. ++/// Usage with `repr(Rust)` structs may yield unexpected results, like downward-going ranges, ++/// spans that include unexpected fields, empty spans, or spans that include *unexpected* padding bytes. ++/// ++/// ## Examples ++/// ``` ++/// use memoffset::span_of; ++/// ++/// #[repr(C)] ++/// struct Florp { ++/// a: u32 ++/// } ++/// ++/// #[repr(C)] ++/// struct Blarg { ++/// x: [u32; 2], ++/// y: [u8; 56], ++/// z: Florp, ++/// egg: [[u8; 4]; 4] ++/// } ++/// ++/// fn main() { ++/// assert_eq!(0..84, span_of!(Blarg, ..)); ++/// assert_eq!(0..8, span_of!(Blarg, .. y)); ++/// assert_eq!(0..64, span_of!(Blarg, ..= y)); ++/// assert_eq!(0..8, span_of!(Blarg, x)); ++/// assert_eq!(8..84, span_of!(Blarg, y ..)); ++/// assert_eq!(0..8, span_of!(Blarg, x .. y)); ++/// assert_eq!(0..64, span_of!(Blarg, x ..= y)); ++/// } ++/// ``` ++#[macro_export(local_inner_macros)] ++macro_rules! span_of { ++ (@helper $root:ident, [] ..=) => { ++ _memoffset__compile_error!("Expected a range, found '..='") ++ }; ++ (@helper $root:ident, [] ..) => { ++ _memoffset__compile_error!("Expected a range, found '..'") ++ }; ++ // No explicit begin for range. ++ (@helper $root:ident, $parent:path, [] ..) => {{ ++ ($root as usize, ++ $root as usize + $crate::__priv::size_of_pointee($root)) ++ }}; ++ (@helper $root:ident, $parent:path, [] ..= $end:tt) => {{ ++ let end = raw_field!($root, $parent, $end); ++ ($root as usize, end as usize + $crate::__priv::size_of_pointee(end)) ++ }}; ++ (@helper $root:ident, $parent:path, [] .. $end:tt) => {{ ++ ($root as usize, raw_field!($root, $parent, $end) as usize) ++ }}; ++ // Explicit begin and end for range. ++ (@helper $root:ident, $parent:path, # $begin:tt [] ..= $end:tt) => {{ ++ let begin = raw_field!($root, $parent, $begin); ++ let end = raw_field!($root, $parent, $end); ++ (begin as usize, end as usize + $crate::__priv::size_of_pointee(end)) ++ }}; ++ (@helper $root:ident, $parent:path, # $begin:tt [] .. $end:tt) => {{ ++ (raw_field!($root, $parent, $begin) as usize, ++ raw_field!($root, $parent, $end) as usize) ++ }}; ++ // No explicit end for range. ++ (@helper $root:ident, $parent:path, # $begin:tt [] ..) => {{ ++ (raw_field!($root, $parent, $begin) as usize, ++ $root as usize + $crate::__priv::size_of_pointee($root)) ++ }}; ++ (@helper $root:ident, $parent:path, # $begin:tt [] ..=) => {{ ++ _memoffset__compile_error!( ++ "Found inclusive range to the end of a struct. Did you mean '..' instead of '..='?") ++ }}; ++ // Just one field. ++ (@helper $root:ident, $parent:path, # $field:tt []) => {{ ++ let field = raw_field!($root, $parent, $field); ++ (field as usize, field as usize + $crate::__priv::size_of_pointee(field)) ++ }}; ++ // Parsing. ++ (@helper $root:ident, $parent:path, $(# $begin:tt)+ [] $tt:tt $($rest:tt)*) => {{ ++ span_of!(@helper $root, $parent, $(#$begin)* #$tt [] $($rest)*) ++ }}; ++ (@helper $root:ident, $parent:path, [] $tt:tt $($rest:tt)*) => {{ ++ span_of!(@helper $root, $parent, #$tt [] $($rest)*) ++ }}; ++ ++ // Entry point. ++ ($sty:path, $($exp:tt)+) => ({ ++ // Get a base pointer. ++ _memoffset__let_base_ptr!(root, $sty); ++ let base = root as usize; ++ let (begin, end) = span_of!(@helper root, $sty, [] $($exp)*); ++ begin-base..end-base ++ }); ++} ++ ++#[cfg(test)] ++mod tests { ++ use core::mem; ++ ++ #[test] ++ fn span_simple() { ++ #[repr(C)] ++ struct Foo { ++ a: u32, ++ b: [u8; 2], ++ c: i64, ++ } ++ ++ assert_eq!(span_of!(Foo, a), 0..4); ++ assert_eq!(span_of!(Foo, b), 4..6); ++ assert_eq!(span_of!(Foo, c), 8..8 + 8); ++ } ++ ++ #[test] ++ #[cfg_attr(miri, ignore)] // this creates unaligned references ++ fn span_simple_packed() { ++ #[repr(C, packed)] ++ struct Foo { ++ a: u32, ++ b: [u8; 2], ++ c: i64, ++ } ++ ++ assert_eq!(span_of!(Foo, a), 0..4); ++ assert_eq!(span_of!(Foo, b), 4..6); ++ assert_eq!(span_of!(Foo, c), 6..6 + 8); ++ } ++ ++ #[test] ++ fn span_forms() { ++ #[repr(C)] ++ struct Florp { ++ a: u32, ++ } ++ ++ #[repr(C)] ++ struct Blarg { ++ x: u64, ++ y: [u8; 56], ++ z: Florp, ++ egg: [[u8; 4]; 5], ++ } ++ ++ // Love me some brute force ++ assert_eq!(0..8, span_of!(Blarg, x)); ++ assert_eq!(64..68, span_of!(Blarg, z)); ++ assert_eq!(68..mem::size_of::(), span_of!(Blarg, egg)); ++ ++ assert_eq!(8..64, span_of!(Blarg, y..z)); ++ assert_eq!(0..64, span_of!(Blarg, x..=y)); ++ } ++ ++ #[test] ++ fn ig_test() { ++ #[repr(C)] ++ struct Member { ++ foo: u32, ++ } ++ ++ #[repr(C)] ++ struct Test { ++ x: u64, ++ y: [u8; 56], ++ z: Member, ++ egg: [[u8; 4]; 4], ++ } ++ ++ assert_eq!(span_of!(Test, ..x), 0..0); ++ assert_eq!(span_of!(Test, ..=x), 0..8); ++ assert_eq!(span_of!(Test, ..y), 0..8); ++ assert_eq!(span_of!(Test, ..=y), 0..64); ++ assert_eq!(span_of!(Test, ..z), 0..64); ++ assert_eq!(span_of!(Test, ..=z), 0..68); ++ assert_eq!(span_of!(Test, ..egg), 0..68); ++ assert_eq!(span_of!(Test, ..=egg), 0..84); ++ assert_eq!(span_of!(Test, ..), 0..mem::size_of::()); ++ assert_eq!( ++ span_of!(Test, x..), ++ offset_of!(Test, x)..mem::size_of::() ++ ); ++ assert_eq!( ++ span_of!(Test, y..), ++ offset_of!(Test, y)..mem::size_of::() ++ ); ++ ++ assert_eq!( ++ span_of!(Test, z..), ++ offset_of!(Test, z)..mem::size_of::() ++ ); ++ assert_eq!( ++ span_of!(Test, egg..), ++ offset_of!(Test, egg)..mem::size_of::() ++ ); ++ assert_eq!( ++ span_of!(Test, x..y), ++ offset_of!(Test, x)..offset_of!(Test, y) ++ ); ++ assert_eq!( ++ span_of!(Test, x..=y), ++ offset_of!(Test, x)..offset_of!(Test, y) + mem::size_of::<[u8; 56]>() ++ ); ++ } ++} +diff --git a/vendor/nix/.cargo-checksum.json b/vendor/nix/.cargo-checksum.json +index 7bbbc5b..f4c932b 100644 +--- a/vendor/nix/.cargo-checksum.json ++++ b/vendor/nix/.cargo-checksum.json +@@ -1 +1 @@ +-{"files":{"CHANGELOG.md":"207a9468b625f4ceb0563411cc7e5eb6dc1196bb7f17e186ce0ae5cfe81f2f5d","CONTRIBUTING.md":"a9101e3d1487170d691d5f062ff49a433c167582ac8984dd41a744be92652f74","CONVENTIONS.md":"df0d4fe9fe65af0bfa4723dc7b641d5130087259799e6b404ad63884f79031cb","Cargo.toml":"25dc104eac5c89df76b2ced11270f7f81eea15654f66d33ca5bd8e5eeeac47f9","LICENSE":"66e3ee1fa7f909ad3c612d556f2a0cdabcd809ad6e66f3b0605015ac64841b70","README.md":"ac2aa95fb09bbd97b60c0b56d1f050ad8fed7b98a677b6c6ecb90a6d2c45085f","build.rs":"14c9c678c33f5894509da47f77d6a326b14aecb4190ce87a24cce98687ca63b2","src/dir.rs":"df41cf42ce92d284f70f0e7ff3ba171715f98eeba06284207e9fdb5ecf62f40b","src/errno.rs":"aee1bb59285c5296ee3fdcf6876858d84dcdc70dcf034960034546c45c4c8ceb","src/errno_dragonfly.c":"a857e47b114acb85fddcb252a610ab5734d225c26b7bedd7c35d7789d46c8526","src/fcntl.rs":"f491c98ee9aa1af6e02e11cd423abae21bd68dc3c4b847492a5aeff667bd4b44","src/features.rs":"22ff626ff8287a07dd55bcfc63c9f518c19c56144e15f9b6f9e3bbdcda51c2a8","src/ifaddrs.rs":"aff966a2b8eb46db2d9898157446607112bbf57d946d5dcd209aee967a230e41","src/kmod.rs":"4d8a695d3d761f351a39d654303a1bd168e74295b7d142b918737e355b24f34d","src/lib.rs":"29be2bb775a5b8112e36fc035df2632915f9232acc271809f9a1b52db5028dd4","src/macros.rs":"bf93a5a1869033e2ce2668269d8af0f40bf213c2fc5c279c9074e1eff389fa84","src/mount.rs":"cdf5db8409017483132db9d7493b5d6cc96df5560d0fa5ad8f385aff72db10ca","src/mqueue.rs":"e94e858814f66272b31a3669e9e19284f8131a92f9e5206bdd5971bb975b44d7","src/net/if_.rs":"f7e02076fcf3cadf3fdf141884c9bd2c468a7047ba60bc490f0057df802b53ce","src/net/mod.rs":"577f70170e53d4a6de1abb70bf8f1031ec3e65c0e63ef5fcf05c907125e7ac17","src/poll.rs":"e31ed102ee621a5e03d2893be3b22c3b2d7102f856a2f8979bab4438e6181b22","src/pty.rs":"9f2a92de983f3b9a76fe8d350e28b078056fe5d4cc3480d1684f54cd79bfd47a","src/sched.rs":"6651f0ea2f8792bca44e7228abdbea44536710f42de62ce043166df46cd349ab","src/sys/aio.rs":"e7d16a5711d90fff83dc25ab4b42d12d904aa9f2f75d3fd2f43e580db3f4dd64","src/sys/epoll.rs":"f0b539e0645569657f2142db91a38c94ebe1925f44852d64c61c818758dbbf0b","src/sys/event.rs":"88798385aed11be86da09b03f8ad2cd369a289ece926e89181b01ef32c77b863","src/sys/eventfd.rs":"08008cf3dc64c2216847c02c0dd8d7189cf08edbaafe35ba2c57c053fde09ef4","src/sys/inotify.rs":"687c8417d737939aa93f805d6003afc4f84f50828b1bd9429ef5d00bef0e0955","src/sys/ioctl/bsd.rs":"56ca6ecf5f7cfb566f4f3ba589fcc778f747a517dd45e13780981922e6215344","src/sys/ioctl/linux.rs":"642b25d3997518815dea454fa976e9067ad5fe4ed75622e7540e3f0d0c7d320a","src/sys/ioctl/mod.rs":"94f6023c6d1f5c04cf2489c229fa9258be0c2755d87ed6a0eafb474214f5ee3d","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":"279f5b3a1534b1f6a04a95b85eea6db7bc60250772df29e41810c4bc8cf815da","src/sys/ptrace/linux.rs":"b16cbc4855ed88aab38d1daedd4f5f869f6c8a8cf6b94c950edec5f9d0be143b","src/sys/ptrace/mod.rs":"671a6ccac955e75d5998f7e53ffc45ed4c7b6522a0f24a0937d60141f692dd39","src/sys/quota.rs":"754b90390e103e479cf009f1db5756fef547472893aaec078f55211c081a9e47","src/sys/reboot.rs":"fde9da27c2928f7026231430fa14fec2058df4e49a0aeda2a237a60524f11241","src/sys/select.rs":"152fef5e5add14c5e4522d0cfa22aa339feefd2914d6196be83a98f9a6f3d2a2","src/sys/sendfile.rs":"91aabfb801dcb1048a9f4f62d1d35d248ee806debca6c28414d0b0e1bcc6ae30","src/sys/signal.rs":"8c0c30875733743b29e4a6be23f7ba641d2f752f9e4cf8d3faba4a30f3ca6e61","src/sys/signalfd.rs":"fe90180bd099183e95130197f6288391ee1c76eaea0b601c9f3bfc530b2e073d","src/sys/socket/addr.rs":"f539ac91a88afcdbab3388e4841271b7ac9e5e1dbffe9399e64abbe96ab0b529","src/sys/socket/mod.rs":"d292c77c7642cf1fd643f0f10116e55e635e2d124e3add74751214325fe1c8e5","src/sys/socket/sockopt.rs":"069b90408386b00d155c6bcb7b60555297c05526c720468771f1bf9052661165","src/sys/stat.rs":"78c31f661fe652fd1b1b863f40b1118c42ddc6d8a850858ca6c14ae7a9ed5a01","src/sys/statfs.rs":"cc4100541a467f6728a7e208bcb2792c5c5230f1dac4a4d635bcb9a2a0afd09f","src/sys/statvfs.rs":"e10e7ae608c3a09a26aa6497a3b95a3c22efd7b1d8dac4a56760a7cb5e19eea0","src/sys/sysinfo.rs":"759ad12061d517753425d1a9b732d915fa4e77575949b684bc56a6d85164c3ca","src/sys/termios.rs":"dd359d248464d3eac991dad9ec49de4b25198fc0054f7363d9277b02cf955997","src/sys/time.rs":"5d3466c895b09e49454f866cec39b94d1a0ea91c0111d6412c77925183860849","src/sys/uio.rs":"60a974275ff8c485ea183bdd6f7e25894e6f2360a5bfb25442391a825a3b9b8c","src/sys/utsname.rs":"9509a092c837d1700f9f4ac30e4568e5b9b63ad8925a56cd8ad7add05d0ac452","src/sys/wait.rs":"a4cc7ac1a2d942c8b03dfadb1c6086eac89992919831a815f1d78e187edf0d0b","src/ucontext.rs":"ebf57ba74caaf073e3483d9cca479938b916941aacd2022db0d1c6fed4e9c841","src/unistd.rs":"011da412802ab3aee7de20ade0b2b585cbc052ca422c0f0de5e0a58ab5046887","test/sys/mod.rs":"e0821cbc289ad952f17229609c7de4282cca1e44cd13e1a7494a6378ecbc12f8","test/sys/test_aio.rs":"c9844cfd4259f1c84f4da2f9f32bba22f03ff71d7bea49da79e1b437b1ea3ead","test/sys/test_aio_drop.rs":"30dd1d238269d00381fa50f6d3cb2b13794b7cceb9f6455f3878fcbffa9aa62d","test/sys/test_epoll.rs":"35093d0cb1096a934dfc4f6efc737eadc4bdc2e2134d2a879061374a51b10c97","test/sys/test_inotify.rs":"a4f804bcf414b6635d9863c8534769a609009c451c3476cc839cdc30c439b3b1","test/sys/test_ioctl.rs":"5ae688bd9ec9ee25126459dfaf665d6bbd57568551db6492c27a415d1eb7eb15","test/sys/test_lio_listio_resubmit.rs":"203a583313542593148f375b087ae30620222a745680173fa98fc448d1e5ae7f","test/sys/test_pthread.rs":"3890e5ecbf2082e0d05d102cc9cec6e76ede3c15f250d104e3483b1c1c3400b1","test/sys/test_ptrace.rs":"9d7c0ba12d8957522ad274b915aa0b771c9c61981c74ad203dfc09510143ec23","test/sys/test_select.rs":"bdb20211fc6ec1e3f186337eac51e08757acb6901d307d67c71bf9011f0d54bd","test/sys/test_signal.rs":"2a208a9a458696f0e0e295bba641912c0711a50a931616ca9df60891c80a989b","test/sys/test_signalfd.rs":"9e75274113d23e65447b97ed7b6d4779c17930717db58d3a626a6b40ffd9e0f5","test/sys/test_socket.rs":"f62784f4f184880cdfd992da16284fe941381bbea56bbf9e5583365f731c2da6","test/sys/test_sockopt.rs":"b3d386c8279f86bf9439c772317bafcdba5630fa806c8319e87ddac0ccfa3a03","test/sys/test_sysinfo.rs":"1e1bea9130fe38ccb07cd0ad7334c7be1e45efc33f7656a5973f8cad7126f225","test/sys/test_termios.rs":"fa4be3ade859b527bf33408f85a6f57b127917cf5f2afb662d09f6019d07913a","test/sys/test_uio.rs":"259ce81677b453c3c9ad7271ef70fb41155d049a5c7c89e62f73ef3b57783705","test/sys/test_wait.rs":"832ebc04ad236d38f1b3b08305a136b2974532d318f4a38078ec98565e6e2415","test/test.rs":"8506471d3b19506d48a8e4b2d2b337fb10e2e75df12929e8f25f30cad2a5eb2e","test/test_dir.rs":"5d137a62f11d1a4993b4bb35dccc38a4c4416b7da374887f2335a9895b4fdee4","test/test_fcntl.rs":"b7a0504d019081783221851da608176c96ae5fd6036b33eee81e99f1a2b74fd6","test/test_kmod/hello_mod/Makefile":"0219f7bce0603f97d997fb377ca071966c90333ecc665e78a54dfeb97a9c811b","test/test_kmod/hello_mod/hello.c":"bcac6b19c5bd807e1f3878c15e426acc85785a8ade9840c3bb4d068635c9188c","test/test_kmod/mod.rs":"f4754f028402a8ba788c87686288424cd3784e77c7eb5d96682ef491b1dd5262","test/test_mount.rs":"78ddc657f5098360c764fffa3a7d844503e4b6b65b44bfd42d9aa9045b415cb6","test/test_mq.rs":"ee653fade4d769576702fa54440660d353ed7ab1284aa5a321f73fa1f6fedf93","test/test_net.rs":"ec6d580b87292519d514b0236bdd5abdd576fcf4835cfe49ed1ddb47c5f1aea3","test/test_nix_path.rs":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","test/test_poll.rs":"46c71ee988fe1b85561ea0530d099750be8c1b8f95ab6e845c8a9f46f16f060c","test/test_pty.rs":"f6beeaa2d1ac30dfda9432f07413a4ab682f4d107904cb1d3d13a673a1b75dce","test/test_ptymaster_drop.rs":"5cfbbb79551c205ab510c2d4ef497bf937ceac9151fbe2f2e543d6515e406990","test/test_sched.rs":"f8ad92eb554164b0f92428f716db99040186d741cc6e1976f7930f099652f70c","test/test_sendfile.rs":"e0cbabbd34052ccaa03d6555d5631686aa076728f6378ee90f7ecec68f891144","test/test_stat.rs":"457af188428f64bf6c5744e152d92d2ee3d956d9892f75453666b98d6a8ee07d","test/test_unistd.rs":"694093e9e5b2c1d90d7513e34ba751221964aa3c8d861c9da8cf16481dff4cff"},"package":"50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363"} +\ No newline at end of file ++{"files":{"CHANGELOG.md":"8ee4e556e53d1b39400a48675d3ecff0bf27e419accab7ca3be76ab934289548","Cargo.toml":"2e6eff9170182f107188b8bc9802efd044ef47178afc7f138950ecff1c1ceb96","LICENSE":"66e3ee1fa7f909ad3c612d556f2a0cdabcd809ad6e66f3b0605015ac64841b70","README.md":"1ed9a0e26ae6e575b3262ae734dd02889455593b761ee62403ea5a64104f3c9c","src/dir.rs":"0280a2dc480bd913f24ed84fbe26569fa2e8eefa660e5ad7c21e05fc34c14d16","src/env.rs":"028bc5e20139ebba418a655a2978a53335dc7680bf1de43d2c8333dd72cfa5c4","src/errno.rs":"e55d075858e349d9afea9ce0480f7fb7ba4dccccf0694fd7b3280b918836203c","src/fcntl.rs":"ea8f43d8fec0b6c3b7d903333e4c1ce85611684a4afd561c55cfe4b61a979e94","src/features.rs":"5b4a0831e5f4b79a6f0e42ed052fd66c875da18959750be51e41fb59ac19feed","src/ifaddrs.rs":"377865eb48040d28c392a1aec0221320108e3392ea285d23405ae2cfa5c54b20","src/kmod.rs":"c818ced08d55ae36fdf82fa914ba856b688e37234d574d3faa37128211d512fb","src/lib.rs":"a62fac2ba7111157c5b64251f67f8a189f04bd587d5c80703454a596ea7ae5d9","src/macros.rs":"e23d7d8be22ef0bf9febaaf2739585453103607c0139bd3995a324e4a16d011e","src/mount/bsd.rs":"4cf35606a63d7ca41caac3b38f01e2b70c63e71978c0529f19fc79182629dbe0","src/mount/linux.rs":"6e5d61788dedf1ca4416c6c6a3a9c6c747f9352c26d863f4a1d4142e288584d6","src/mount/mod.rs":"ba9f60eb831224ab73bdd87e00e15d13b9ce9efb70b18bf8f3fe60406d522b3e","src/mqueue.rs":"ed0a189036b2437b5f7f7f1312fa545540b06ca72171b451d8bce42cc3627534","src/net/if_.rs":"b32a8a1f952de60d95e549779a5c673fd72aa665e86bfdfc8ec6badf3016b9b1","src/net/mod.rs":"577f70170e53d4a6de1abb70bf8f1031ec3e65c0e63ef5fcf05c907125e7ac17","src/poll.rs":"2fc1d144fb40db51811c6357b520ab7993529702d8f0d8060c903118ff4f7259","src/pty.rs":"27b4f76c23acf02542674017067fee74cdcac907338458700a1aa4d6f6a62e27","src/sched.rs":"403aa5ebed81910263d42a94717612b737550bf053227b7d90f1c8949188d919","src/sys/aio.rs":"ae091de8540c97da374a39e7d154c1b3ce50f41e6fc20a45c6b06eb838e74366","src/sys/epoll.rs":"28e22debf474d1b047e8044a00b354c25dab2fa125960f9f2f14cc34289fd5c9","src/sys/event.rs":"dbd8e84bccb813839295b0a336485783ef19548d2317931f0ceb5ee62f839a40","src/sys/eventfd.rs":"c8db8f5874726fdad289ad5e2603a7d71a1ae5a899dcde3a35d3edff8b498b7e","src/sys/inotify.rs":"5b4da774313afa9c28c3f92f9d07dce9bf4c8d044fd6a16f19480e79a19e808b","src/sys/ioctl/bsd.rs":"bbd02e30b0a78c1cb22777d9b00cfcbba9c68505cffc06118ac68474cf6fea39","src/sys/ioctl/linux.rs":"028181834d119b834bf399f2b8a6176cc57e75144693f28f32059d087d8c8018","src/sys/ioctl/mod.rs":"89b20579476b2e0254e0ecb1b41830cccd7027a22cbdb816a9d4ec3924842ac1","src/sys/memfd.rs":"f58d7fbe67c4b994832d72f5fbd59c136c8f1ae88ea8b0bc1c099db2d847ee6c","src/sys/mman.rs":"17df1bc34ba92bdd6bad1e11e4ef139998117f6c468c8f560421858f3cc899a5","src/sys/mod.rs":"baabf649f758ad4acce849ec1795dd4e4f9c6539e677bad5fa777300a4871dcb","src/sys/personality.rs":"aa89760c023bfec3fca5d8636f9eac9d337f5547933793ce6df7a0de97ae6ee1","src/sys/pthread.rs":"258cdf7ff0b61a4afa6d228109e4cb4fb88d859bb8dfe6c959d95130fb010906","src/sys/ptrace/bsd.rs":"4c590d8f023ff52f396f8b6f2150c08e5c9486d3088d9c173db33a70d616b800","src/sys/ptrace/linux.rs":"c82db3fb18aa97755f9ccb440a957cd46d664968a94045830c5d74d2d53bc19f","src/sys/ptrace/mod.rs":"e9e5d970097f5eafffba900959d4fdbf233bff9ed7f599fc9896bb44d86a57a4","src/sys/quota.rs":"02e698a25f0986fb43aa88689f3d3d8b9edc6ae48496ad02f7214fccaa493e00","src/sys/reboot.rs":"eacdf57694a6629fb05787e16450446102a62818274495f2ad4e445807d09221","src/sys/resource.rs":"d498d0c00fd30e35e1269a8902cb812014d813f63ec95364f8f59f1912ba5657","src/sys/select.rs":"65c39b129d3cc85b8ca026ff26dcf80c5639824f43715881c3c1bbb6bf0c8a60","src/sys/sendfile.rs":"7a62099f9771fecff49b9c11210341e3c1a4acf22f8dfb96d395e29421648676","src/sys/signal.rs":"c3e13a2edea54d190a4b051f62efc97953c00b5051a9fda0e39e3bc732a31939","src/sys/signalfd.rs":"583524434fd37143be3db37fa6f6cbd339f7946416f05b58a95e246947e5cc9d","src/sys/socket/addr.rs":"84df895052f59ec84774b189ffb285d2a37a9703af6c8310ae5040cca1a2583e","src/sys/socket/mod.rs":"6deb55438cad3606385303f036b0efd842dfd759fba93611911f5a4f2613c9dc","src/sys/socket/sockopt.rs":"ed1f920364bfe88bbe6eaeeefb27a63bfcdd7d67604aca2f03e22f2b502df55a","src/sys/stat.rs":"337dea8d55d6177dc85b3235b40b8a3e81af7f4a6e2806a0b2f730bec5424350","src/sys/statfs.rs":"17103659a85279bac046c69cb3b22bf2c11c2492cffb0edfa4c3b233d161a2f2","src/sys/statvfs.rs":"f81e3900ef90d62e7eceaf1b6ff8dcfd965466714c033eb4717687f692171f48","src/sys/sysinfo.rs":"b4519b1ca091c9dbe94d2a6fd6304944bf3df5626973d2c6884022559706f0d9","src/sys/termios.rs":"7923f9846a8122096b6b1cd240d3618b876ce500a751ac434954d172e2e85745","src/sys/time.rs":"9026033b60a5ccc95b70424aef043c8c748722e2ea8c7c86366ecd4585b651a0","src/sys/timer.rs":"8c10f0e7cfac857ad00460be30bc68b957909cc9296e70718d3b5d4a0babafde","src/sys/timerfd.rs":"ef7c48aefdcfac13316eeddbef5da04cf12e9f574b8d9f43402c02b6b8db86b3","src/sys/uio.rs":"e1d59ccbee9d46c65d3aa8c36aa3a3222539beea0d20163a8b707d08fca14e09","src/sys/utsname.rs":"0cdda0cc111caaa0e4ebe2d4588bdc825d878e5bcb7a9136073b15f87a20e11f","src/sys/wait.rs":"cc70d2d9b880ff6c48577a479c209af6127067bc013a90ee22538e4dfad7d2b4","src/time.rs":"d4e0872361a57810837f5bd790cbca3a2b9db1ac4694a3c52d1564ad3532d3be","src/ucontext.rs":"b8f2e04757a9c2bc38c3b1e259d3a013da8a730fe9bfbe5487637395681b43d3","src/unistd.rs":"e19be456124731c5b93aef92ed72a7c4c9092e28db0649814ba3fcc1f0d620fa","test/common/mod.rs":"1d7e28e3635754664cd056f3a1079232ff5c118df619e1d0551a9972eb0b3cd6","test/sys/mod.rs":"87b2891d83067ff21f72b8ff7fde3019dc45b6877282ac278b6da151de45c7a7","test/sys/test_aio.rs":"4dac9f716f852f1f438f78d6e64bf041e6fd316bf15dcb27afffaf0894bdefa6","test/sys/test_aio_drop.rs":"614070155fa16a979b7341d001639c5ce24a1d6f632c3abce45a5a6d49c4039b","test/sys/test_epoll.rs":"ffe95e36c79e37426ef8e8ca3b137b7f35ea0333ce666a20a4b7878db17680e9","test/sys/test_inotify.rs":"a141b9a995892547b51ceeb6761a70a6b86d37e8f38d13ea2c497b81b4b0f49f","test/sys/test_ioctl.rs":"00ccc5afb665e533a0a4b6d6a6be438bcaea19fce335390feef4e91d17b3036c","test/sys/test_mman.rs":"2b4161964c9204b74659028b0f89a88f4e3bcc9886137a3039737cd91d2698cb","test/sys/test_pthread.rs":"ace36a2f5587f1874854281b4fd84e4e4d892a1e3c5cc38ced57975739522ad6","test/sys/test_ptrace.rs":"0385eebc8b1b8c72f655b745769decd9143ad83018198375982da0896310456b","test/sys/test_select.rs":"54cea1c34ad28d5770a613c1c3cbc3b1064b22037ec2b9d3fcd422d3be9e60a7","test/sys/test_signal.rs":"acc9941227bd3e2afad323613c2b8c83902ed0486d3745fd72704f395924f1e4","test/sys/test_signalfd.rs":"0e1060143e2612c490bc3d0168d0bbb042ef55e3f1d91d2578b9e42e4310a14d","test/sys/test_socket.rs":"d2df1001f9a0b2dac0b88051a67c3868bb216e72e4da4eecd11c4448b9fa4b40","test/sys/test_sockopt.rs":"4465f22f718442f3f7b502e052dad02b93cebfa3b71fa55ff4f25fb02534acab","test/sys/test_stat.rs":"6630a28217fd708bb84cd4f7e7101836b74f2420f9888923fdab664ccc331c1d","test/sys/test_sysinfo.rs":"ffd49bc96375914a2c4a4a59730cae8072f85771e2c4a80d3403df38d967e272","test/sys/test_termios.rs":"e5bcef10c84bd7583d600d5601835bcb3cfc88781cb283ab0185bbef5faf4327","test/sys/test_timerfd.rs":"cfed3abf58118611d08f6985251a7739cff67108e11214222a1d2394a3a026ce","test/sys/test_uio.rs":"32656bd0a5699e4d019aa928edf104637937179782914a82d50d37226e84c421","test/sys/test_wait.rs":"6fd59fffeeb09ff620c359baefd062ba777598982b6cb001ccc07b6bc7605493","test/test.rs":"11f40b0718ddd1a150cb9e703d56d0b2a9462306505a2245ddf273a2011f48b5","test/test_clearenv.rs":"45ca548035b3c20ec87314715feaba2be973709a635d85b8cde46fd1d9f1ecd4","test/test_dir.rs":"ae3c11c58cb06da6557aa2a839c6653c54cd7724283fffe9df5a5d3feabdd89a","test/test_fcntl.rs":"71dcb87f7b04d78fc62937ba46cb7f0f1f2dbb330b63a996ea2e8ec9056b98a9","test/test_kmod/hello_mod/Makefile":"0219f7bce0603f97d997fb377ca071966c90333ecc665e78a54dfeb97a9c811b","test/test_kmod/hello_mod/hello.c":"bcac6b19c5bd807e1f3878c15e426acc85785a8ade9840c3bb4d068635c9188c","test/test_kmod/mod.rs":"b4ae25841c2f06f32de9f1acd8230eeccd7095721302ebe78ad454e4e4f9c783","test/test_mount.rs":"6dd242b6e23c9c39e1a75612bbea62573898818ab374c3c032c2cdb97033554d","test/test_mq.rs":"136071f24131aac0e65d5f29ac18e3806641dfae1164813f5570c0e3a6f70553","test/test_net.rs":"f2912327ebb2a3d37e6cff02a5ac3106cf889cc5c74404db4ef0034059ba26f1","test/test_nix_path.rs":"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b","test/test_nmount.rs":"d6c112547bb80968170b5497cda4b6cbf69dabec6f51d494bd52298995ceff18","test/test_poll.rs":"3e0b8f0397ba080785c61a3bfc3d637bc87f324bc4e52b5f1bf3ca0d32dbc9fe","test/test_pty.rs":"b26238a0783746cb31880e11eebc1913149be999ce75fbc2d6677bdd1e2731b2","test/test_ptymaster_drop.rs":"ae63c815f5028ddc67d194e86559483018ab1816316bdb917f40cee9364fd8a5","test/test_resource.rs":"40aef790ab745cec31a4b333d2ca406b462aa9bdf4a6d3756371e498b8d51e9a","test/test_sched.rs":"c4579bd376fab8816e63b07fa9ace31dc08e63ebb7c855a2c450698090d1d1e8","test/test_sendfile.rs":"bb41b4f3621b518e397d3a5b5ad3c5dcef3fe506afe516eab7572fbab92b77e3","test/test_stat.rs":"c407ca47a5258750076d041afad2f6add4c3563be36628bde1c5b314f5d0765d","test/test_time.rs":"f7a21b1e279e60e84909d5dadda97ded66d3326b131fe317badf9af0a1b50335","test/test_timer.rs":"3ae20d364f075d2811f3ff94eda9886682cc21d8807656007d2464fe36d1e361","test/test_unistd.rs":"20a00be4fbe26302ea5fe50ce25b99265dc763db138663d6aa1d7ac729a1d292"},"package":"bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"} +\ No newline at end of file +diff --git a/vendor/nix/CHANGELOG.md b/vendor/nix/CHANGELOG.md +index def99c1..283cb86 100644 +--- a/vendor/nix/CHANGELOG.md ++++ b/vendor/nix/CHANGELOG.md +@@ -1,34 +1,716 @@ + # Change Log + + All notable changes to this project will be documented in this file. +-This project adheres to [Semantic Versioning](http://semver.org/). ++This project adheres to [Semantic Versioning](https://semver.org/). + +-## [Unreleased] - ReleaseDate ++## [0.26.2] - 2023-01-18 ++### Fixed ++- Fix `SockaddrIn6` bug that was swapping flowinfo and scope_id byte ordering. ++ ([#1964](https://github.com/nix-rust/nix/pull/1964)) ++ ++## [0.26.1] - 2022-11-29 ++### Fixed ++- Fix UB with `sys::socket::sockopt::SockType` using `SOCK_PACKET`. ++ ([#1821](https://github.com/nix-rust/nix/pull/1821)) ++ ++## [0.26.0] - 2022-11-29 ++### Added ++ ++- Added `SockaddrStorage::{as_unix_addr, as_unix_addr_mut}` ++ ([#1871](https://github.com/nix-rust/nix/pull/1871)) ++- Added `MntFlags` and `unmount` on all of the BSDs. ++- Added `any()` and `all()` to `poll::PollFd`. ++ ([#1877](https://github.com/nix-rust/nix/pull/1877)) ++- Add `MntFlags` and `unmount` on all of the BSDs. ++ ([#1849](https://github.com/nix-rust/nix/pull/1849)) ++- Added a `Statfs::flags` method. ++ ([#1849](https://github.com/nix-rust/nix/pull/1849)) ++- Added `NSFS_MAGIC` FsType on Linux and Android. ++ ([#1829](https://github.com/nix-rust/nix/pull/1829)) ++- Added `sched_getcpu` on platforms that support it. ++ ([#1825](https://github.com/nix-rust/nix/pull/1825)) ++- Added `sched_getaffinity` and `sched_setaffinity` on FreeBSD. ++ ([#1804](https://github.com/nix-rust/nix/pull/1804)) ++- Added `line_discipline` field to `Termios` on Linux, Android and Haiku ++ ([#1805](https://github.com/nix-rust/nix/pull/1805)) ++- Expose the memfd module on FreeBSD (memfd was added in FreeBSD 13) ++ ([#1808](https://github.com/nix-rust/nix/pull/1808)) ++- Added `domainname` field of `UtsName` on Android and Linux ++ ([#1817](https://github.com/nix-rust/nix/pull/1817)) ++- Re-export `RLIM_INFINITY` from `libc` ++ ([#1831](https://github.com/nix-rust/nix/pull/1831)) ++- Added `syncfs(2)` on Linux ++ ([#1833](https://github.com/nix-rust/nix/pull/1833)) ++- Added `faccessat(2)` on illumos ++ ([#1841](https://github.com/nix-rust/nix/pull/1841)) ++- Added `eaccess()` on FreeBSD, DragonFly and Linux (glibc and musl). ++ ([#1842](https://github.com/nix-rust/nix/pull/1842)) ++- Added `IP_TOS` `SO_PRIORITY` and `IPV6_TCLASS` sockopts for Linux ++ ([#1853](https://github.com/nix-rust/nix/pull/1853)) ++- Added `new_unnamed` and `is_unnamed` for `UnixAddr` on Linux and Android. ++ ([#1857](https://github.com/nix-rust/nix/pull/1857)) ++- Added `SockProtocol::Raw` for raw sockets ++ ([#1848](https://github.com/nix-rust/nix/pull/1848)) ++- added `IP_MTU` (`IpMtu`) `IPPROTO_IP` sockopt on Linux and Android. ++ ([#1865](https://github.com/nix-rust/nix/pull/1865)) ++ ++### Changed ++ ++- The MSRV is now 1.56.1 ++ ([#1792](https://github.com/nix-rust/nix/pull/1792)) ++- The `addr` argument of `sys::mman::mmap` is now of type `Option`. ++ ([#1870](https://github.com/nix-rust/nix/pull/1870)) ++- The `length` argument of `sys::mman::mmap` is now of type `NonZeroUsize`. ++ ([#1873](https://github.com/nix-rust/nix/pull/1873)) ++ ++### Fixed ++ ++- Fixed using `SockaddrStorage` to store a Unix-domain socket address on Linux. ++ ([#1871](https://github.com/nix-rust/nix/pull/1871)) ++- Fix microsecond calculation for `TimeSpec`. ++ ([#1801](https://github.com/nix-rust/nix/pull/1801)) ++- Fix `User::from_name` and `Group::from_name` panicking ++ when given a name containing a nul. ++ ([#1815](https://github.com/nix-rust/nix/pull/1815)) ++- Fix `User::from_uid` and `User::from_name` crash on Android platform. ++ ([#1824](https://github.com/nix-rust/nix/pull/1824)) ++- Workaround XNU bug causing netmasks returned by `getifaddrs` to misbehave. ++ ([#1788](https://github.com/nix-rust/nix/pull/1788)) ++ ++### Removed ++ ++- Removed deprecated error constants and conversions. ++ ([#1860](https://github.com/nix-rust/nix/pull/1860)) ++ ++## [0.25.0] - 2022-08-13 ++### Added ++ ++- Added `faccessat` ++ ([#1780](https://github.com/nix-rust/nix/pull/1780)) ++- Added `memfd` on Android. ++ (#[1773](https://github.com/nix-rust/nix/pull/1773)) ++- Added `ETH_P_ALL` to `SockProtocol` enum ++ (#[1768](https://github.com/nix-rust/nix/pull/1768)) ++- Added four non-standard Linux `SysconfVar` variants ++ (#[1761](https://github.com/nix-rust/nix/pull/1761)) ++- Added const constructors for `TimeSpec` and `TimeVal` ++ (#[1760](https://github.com/nix-rust/nix/pull/1760)) ++- Added `chflags`. ++ (#[1758](https://github.com/nix-rust/nix/pull/1758)) ++- Added `aio_writev` and `aio_readv`. ++ (#[1713](https://github.com/nix-rust/nix/pull/1713)) ++- impl `From` for `Uid` and `From` for `Gid` ++ (#[1727](https://github.com/nix-rust/nix/pull/1727)) ++- impl `From` for `std::net::SocketAddrV4` and ++ impl `From` for `std::net::SocketAddrV6`. ++ (#[1711](https://github.com/nix-rust/nix/pull/1711)) ++- Added support for the `x86_64-unknown-haiku` target. ++ (#[1703](https://github.com/nix-rust/nix/pull/1703)) ++- Added `ptrace::read_user` and `ptrace::write_user` for Linux. ++ (#[1697](https://github.com/nix-rust/nix/pull/1697)) ++- Added `getrusage` and helper types `UsageWho` and `Usage` ++ (#[1747](https://github.com/nix-rust/nix/pull/1747)) ++- Added the `DontRoute` SockOpt ++ (#[1752](https://github.com/nix-rust/nix/pull/1752)) ++- Added `signal::SigSet::from_sigset_t_unchecked()`. ++ (#[1741](https://github.com/nix-rust/nix/pull/1741)) ++- Added the `Ipv4OrigDstAddr` sockopt and control message. ++ (#[1772](https://github.com/nix-rust/nix/pull/1772)) ++- Added the `Ipv6OrigDstAddr` sockopt and control message. ++ (#[1772](https://github.com/nix-rust/nix/pull/1772)) ++- Added the `Ipv4SendSrcAddr` control message. ++ (#[1776](https://github.com/nix-rust/nix/pull/1776)) ++ ++### Changed ++ ++- Reimplemented sendmmsg/recvmmsg to avoid allocations and with better API ++ (#[1744](https://github.com/nix-rust/nix/pull/1744)) ++ ++- Rewrote the aio module. The new module: ++ * Does more type checking at compile time rather than runtime. ++ * Gives the caller control over whether and when to `Box` an aio operation. ++ * Changes the type of the `priority` arguments to `i32`. ++ * Changes the return type of `aio_return` to `usize`. ++ (#[1713](https://github.com/nix-rust/nix/pull/1713)) ++- `nix::poll::ppoll`: `sigmask` parameter is now optional. ++ (#[1739](https://github.com/nix-rust/nix/pull/1739)) ++- Changed `gethostname` to return an owned `OsString`. ++ (#[1745](https://github.com/nix-rust/nix/pull/1745)) ++- `signal:SigSet` is now marked as `repr(transparent)`. ++ (#[1741](https://github.com/nix-rust/nix/pull/1741)) ++ ++### Removed ++ ++- Removed support for resubmitting partially complete `lio_listio` operations. ++ It was too complicated, and didn't fit Nix's theme of zero-cost abstractions. ++ Instead, it can be reimplemented downstream. ++ (#[1713](https://github.com/nix-rust/nix/pull/1713)) ++ ++## [0.24.2] - 2022-07-17 ++### Fixed ++ ++- Fixed buffer overflow in `nix::sys::socket::recvfrom`. ++ (#[1763](https://github.com/nix-rust/nix/pull/1763)) ++- Enabled `SockaddrStorage::{as_link_addr, as_link_addr_mut}` for Linux-like ++ operating systems. ++ (#[1729](https://github.com/nix-rust/nix/pull/1729)) ++- Fixed `SockaddrLike::from_raw` implementations for `VsockAddr` and ++ `SysControlAddr`. ++ (#[1736](https://github.com/nix-rust/nix/pull/1736)) ++ ++## [0.24.1] - 2022-04-22 ++### Fixed ++ ++- Fixed `UnixAddr::size` on Linux-based OSes. ++ (#[1702](https://github.com/nix-rust/nix/pull/1702)) ++ ++## [0.24.0] - 2022-04-21 + ### Added ++ ++- Added fine-grained features flags. Most Nix functionality can now be ++ conditionally enabled. By default, all features are enabled. ++ (#[1611](https://github.com/nix-rust/nix/pull/1611)) ++- Added statfs FS type magic constants for `target_os = "android"` ++ and synced constants with libc v0.2.121. ++ (#[1690](https://github.com/nix-rust/nix/pull/1690)) ++- Added `fexecve` on DragonFly. ++ (#[1577](https://github.com/nix-rust/nix/pull/1577)) ++- `sys::uio::IoVec` is now `Send` and `Sync` ++ (#[1582](https://github.com/nix-rust/nix/pull/1582)) ++- Added `EPOLLEXCLUSIVE` on Android. ++ (#[1567](https://github.com/nix-rust/nix/pull/1567)) ++- Added `fdatasync` for FreeBSD, Fuchsia, NetBSD, and OpenBSD. ++ (#[1581](https://github.com/nix-rust/nix/pull/1581)) ++- Added `sched_setaffinity` and `sched_getaffinity` on DragonFly. ++ (#[1537](https://github.com/nix-rust/nix/pull/1537)) ++- Added `posix_fallocate` on DragonFly. ++ (#[1621](https://github.com/nix-rust/nix/pull/1621)) ++- Added `SO_TIMESTAMPING` support ++ (#[1547](https://github.com/nix-rust/nix/pull/1547)) ++- Added getter methods to `MqAttr` struct ++ (#[1619](https://github.com/nix-rust/nix/pull/1619)) ++- Added the `TxTime` sockopt and control message. ++ (#[1564](https://github.com/nix-rust/nix/pull/1564)) ++- Added POSIX per-process timer support ++ (#[1622](https://github.com/nix-rust/nix/pull/1622)) ++- Added `sendfile` on DragonFly. ++ (#[1615](https://github.com/nix-rust/nix/pull/1615)) ++- Added `UMOUNT_NOFOLLOW`, `FUSE_SUPER_MAGIC` on Linux. ++ (#[1634](https://github.com/nix-rust/nix/pull/1634)) ++- Added `getresuid`, `setresuid`, `getresgid`, and `setresgid` on DragonFly, FreeBSD, and OpenBSD. ++ (#[1628](https://github.com/nix-rust/nix/pull/1628)) ++- Added `MAP_FIXED_NOREPLACE` on Linux. ++ (#[1636](https://github.com/nix-rust/nix/pull/1636)) ++- Added `fspacectl` on FreeBSD ++ (#[1640](https://github.com/nix-rust/nix/pull/1640)) ++- Added `accept4` on DragonFly, Emscripten, Fuchsia, Illumos, and NetBSD. ++ (#[1654](https://github.com/nix-rust/nix/pull/1654)) ++- Added `AsRawFd` implementation on `OwningIter`. ++ (#[1563](https://github.com/nix-rust/nix/pull/1563)) ++- Added `process_vm_readv` and `process_vm_writev` on Android. ++ (#[1557](https://github.com/nix-rust/nix/pull/1557)) ++- Added `nix::uncontext` module on s390x. ++ (#[1662](https://github.com/nix-rust/nix/pull/1662)) ++- Implemented `Extend`, `FromIterator`, and `IntoIterator` for `SigSet` and ++ added `SigSet::iter` and `SigSetIter`. ++ (#[1553](https://github.com/nix-rust/nix/pull/1553)) ++- Added `ENOTRECOVERABLE` and `EOWNERDEAD` error codes on DragonFly. ++ (#[1665](https://github.com/nix-rust/nix/pull/1665)) ++- Implemented `Read` and `Write` for `&PtyMaster` ++ (#[1664](https://github.com/nix-rust/nix/pull/1664)) ++- Added `MSG_NOSIGNAL` for Android, Dragonfly, FreeBSD, Fuchsia, Haiku, Illumos, Linux, NetBSD, OpenBSD and Solaris. ++ (#[1670](https://github.com/nix-rust/nix/pull/1670)) ++- Added `waitid`. ++ (#[1584](https://github.com/nix-rust/nix/pull/1584)) ++- Added `Ipv6DontFrag` for android, iOS, linux and macOS. ++- Added `IpDontFrag` for iOS, macOS. ++ (#[1692](https://github.com/nix-rust/nix/pull/1692)) ++ + ### Changed ++ ++- `mqueue` functions now operate on a distinct type, `nix::mqueue::MqdT`. ++ Accessors take this type by reference, not by value. ++ (#[1639](https://github.com/nix-rust/nix/pull/1639)) ++- Removed `SigSet::extend` in favor of `>::extend`. ++ Because of this change, you now need `use std::iter::Extend` to call `extend` ++ on a `SigSet`. ++ (#[1553](https://github.com/nix-rust/nix/pull/1553)) ++- Removed the the `PATH_MAX` restriction from APIs accepting paths. Paths ++ will now be allocated on the heap if they are too long. In addition, large ++ instruction count improvements (~30x) were made to path handling. ++ (#[1656](https://github.com/nix-rust/nix/pull/1656)) ++- Changed `getrlimit` and `setrlimit` to use `rlim_t` directly ++ instead of `Option`. ++ (#[1668](https://github.com/nix-rust/nix/pull/1668)) ++- Deprecated `InetAddr` and `SockAddr` in favor of `SockaddrIn`, `SockaddrIn6`, ++ and `SockaddrStorage`. ++ (#[1684](https://github.com/nix-rust/nix/pull/1684)) ++- Deprecated `IpAddr`, `Ipv4Addr`, and `Ipv6Addr` in favor of their equivalents ++ from the standard library. ++ (#[1685](https://github.com/nix-rust/nix/pull/1685)) ++- `uname` now returns a `Result` instead of just a `UtsName` and ++ ignoring failures from libc. And getters on the `UtsName` struct now return ++ an `&OsStr` instead of `&str`. ++ (#[1672](https://github.com/nix-rust/nix/pull/1672)) ++- Replaced `IoVec` with `IoSlice` and `IoSliceMut`, and replaced `IoVec::from_slice` with ++ `IoSlice::new`. (#[1643](https://github.com/nix-rust/nix/pull/1643)) ++ + ### Fixed ++ ++- `InetAddr::from_std` now sets the `sin_len`/`sin6_len` fields on the BSDs. ++ (#[1642](https://github.com/nix-rust/nix/pull/1642)) ++- Fixed a panic in `LinkAddr::addr`. That function now returns an `Option`. ++ (#[1675](https://github.com/nix-rust/nix/pull/1675)) ++ (#[1677](https://github.com/nix-rust/nix/pull/1677)) ++ + ### Removed + ++- Removed public access to the inner fields of `NetlinkAddr`, `AlgAddr`, ++ `SysControlAddr`, `LinkAddr`, and `VsockAddr`. ++ (#[1614](https://github.com/nix-rust/nix/pull/1614)) ++- Removed `EventFlag::EV_SYSFLAG`. ++ (#[1635](https://github.com/nix-rust/nix/pull/1635)) ++ ++## [0.23.1] - 2021-12-16 ++ ++### Changed ++ ++- Relaxed the bitflags requirement from 1.3.1 to 1.1. This partially reverts ++ #1492. From now on, the MSRV is not guaranteed to work with all versions of ++ all dependencies, just with some version of all dependencies. ++ (#[1607](https://github.com/nix-rust/nix/pull/1607)) ++ ++### Fixed ++ ++- Fixed soundness issues in `FdSet::insert`, `FdSet::remove`, and ++ `FdSet::contains` involving file descriptors outside of the range ++ `0..FD_SETSIZE`. ++ (#[1575](https://github.com/nix-rust/nix/pull/1575)) ++ ++## [0.23.0] - 2021-09-28 ++### Added ++ ++- Added the `LocalPeerCred` sockopt. ++ (#[1482](https://github.com/nix-rust/nix/pull/1482)) ++- Added `TimeSpec::from_duration` and `TimeSpec::from_timespec` ++ (#[1465](https://github.com/nix-rust/nix/pull/1465)) ++- Added `IPV6_V6ONLY` sockopt. ++ (#[1470](https://github.com/nix-rust/nix/pull/1470)) ++- Added `impl From for libc::passwd` trait implementation to convert a `User` ++ into a `libc::passwd`. Consumes the `User` struct to give ownership over ++ the member pointers. ++ (#[1471](https://github.com/nix-rust/nix/pull/1471)) ++- Added `pthread_kill`. ++ (#[1472](https://github.com/nix-rust/nix/pull/1472)) ++- Added `mknodat`. ++ (#[1473](https://github.com/nix-rust/nix/pull/1473)) ++- Added `setrlimit` and `getrlimit`. ++ (#[1302](https://github.com/nix-rust/nix/pull/1302)) ++- Added `ptrace::interrupt` method for platforms that support `PTRACE_INTERRUPT` ++ (#[1422](https://github.com/nix-rust/nix/pull/1422)) ++- Added `IP6T_SO_ORIGINAL_DST` sockopt. ++ (#[1490](https://github.com/nix-rust/nix/pull/1490)) ++- Added the `PTRACE_EVENT_STOP` variant to the `sys::ptrace::Event` enum ++ (#[1335](https://github.com/nix-rust/nix/pull/1335)) ++- Exposed `SockAddr::from_raw_sockaddr` ++ (#[1447](https://github.com/nix-rust/nix/pull/1447)) ++- Added `TcpRepair` ++ (#[1503](https://github.com/nix-rust/nix/pull/1503)) ++- Enabled `pwritev` and `preadv` for more operating systems. ++ (#[1511](https://github.com/nix-rust/nix/pull/1511)) ++- Added support for `TCP_MAXSEG` TCP Maximum Segment Size socket options ++ (#[1292](https://github.com/nix-rust/nix/pull/1292)) ++- Added `Ipv4RecvErr` and `Ipv6RecvErr` sockopts and associated control messages. ++ (#[1514](https://github.com/nix-rust/nix/pull/1514)) ++- Added `AsRawFd` implementation on `PollFd`. ++ (#[1516](https://github.com/nix-rust/nix/pull/1516)) ++- Added `Ipv4Ttl` and `Ipv6Ttl` sockopts. ++ (#[1515](https://github.com/nix-rust/nix/pull/1515)) ++- Added `MAP_EXCL`, `MAP_ALIGNED_SUPER`, and `MAP_CONCEAL` mmap flags, and ++ exposed `MAP_ANONYMOUS` for all operating systems. ++ (#[1522](https://github.com/nix-rust/nix/pull/1522)) ++ (#[1525](https://github.com/nix-rust/nix/pull/1525)) ++ (#[1531](https://github.com/nix-rust/nix/pull/1531)) ++ (#[1534](https://github.com/nix-rust/nix/pull/1534)) ++- Added read/write accessors for 'events' on `PollFd`. ++ (#[1517](https://github.com/nix-rust/nix/pull/1517)) ++ ++### Changed ++ ++- `FdSet::{contains, highest, fds}` no longer require a mutable reference. ++ (#[1464](https://github.com/nix-rust/nix/pull/1464)) ++- `User::gecos` and corresponding `libc::passwd::pw_gecos` are supported on ++ 64-bit Android, change conditional compilation to include the field in ++ 64-bit Android builds ++ (#[1471](https://github.com/nix-rust/nix/pull/1471)) ++- `eventfd`s are supported on Android, change conditional compilation to ++ include `sys::eventfd::eventfd` and `sys::eventfd::EfdFlags`for Android ++ builds. ++ (#[1481](https://github.com/nix-rust/nix/pull/1481)) ++- Most enums that come from C, for example `Errno`, are now marked as ++ `#[non_exhaustive]`. ++ (#[1474](https://github.com/nix-rust/nix/pull/1474)) ++- Many more functions, mostly contructors, are now `const`. ++ (#[1476](https://github.com/nix-rust/nix/pull/1476)) ++ (#[1492](https://github.com/nix-rust/nix/pull/1492)) ++- `sys::event::KEvent::filter` now returns a `Result` instead of being ++ infalliable. The only cases where it will now return an error are cases ++ where it previously would've had undefined behavior. ++ (#[1484](https://github.com/nix-rust/nix/pull/1484)) ++- Minimum supported Rust version is now 1.46.0. ++ ([#1492](https://github.com/nix-rust/nix/pull/1492)) ++- Rework `UnixAddr` to encapsulate internals better in order to fix soundness ++ issues. No longer allows creating a `UnixAddr` from a raw `sockaddr_un`. ++ ([#1496](https://github.com/nix-rust/nix/pull/1496)) ++- Raised bitflags to 1.3.0 and the MSRV to 1.46.0. ++ ([#1492](https://github.com/nix-rust/nix/pull/1492)) ++ ++### Fixed ++ ++- `posix_fadvise` now returns errors in the conventional way, rather than as a ++ non-zero value in `Ok()`. ++ (#[1538](https://github.com/nix-rust/nix/pull/1538)) ++- Added more errno definitions for better backwards compatibility with ++ Nix 0.21.0. ++ (#[1467](https://github.com/nix-rust/nix/pull/1467)) ++- Fixed potential undefined behavior in `Signal::try_from` on some platforms. ++ (#[1484](https://github.com/nix-rust/nix/pull/1484)) ++- Fixed buffer overflow in `unistd::getgrouplist`. ++ (#[1545](https://github.com/nix-rust/nix/pull/1545)) ++ ++ ++### Removed ++ ++- Removed a couple of termios constants on redox that were never actually ++ supported. ++ (#[1483](https://github.com/nix-rust/nix/pull/1483)) ++- Removed `nix::sys::signal::NSIG`. It was of dubious utility, and not correct ++ for all platforms. ++ (#[1484](https://github.com/nix-rust/nix/pull/1484)) ++- Removed support for 32-bit Apple targets, since they've been dropped by both ++ Rustc and Xcode. ++ (#[1492](https://github.com/nix-rust/nix/pull/1492)) ++- Deprecated `SockAddr/InetAddr::to_str` in favor of `ToString::to_string` ++ (#[1495](https://github.com/nix-rust/nix/pull/1495)) ++- Removed `SigevNotify` on OpenBSD and Redox. ++ (#[1511](https://github.com/nix-rust/nix/pull/1511)) ++ ++## [0.22.3] - 22 January 2022 ++### Changed ++- Relaxed the bitflags requirement from 1.3.1 to 1.1. This partially reverts ++ #1492. From now on, the MSRV is not guaranteed to work with all versions of ++ all dependencies, just with some version of all dependencies. ++ (#[1607](https://github.com/nix-rust/nix/pull/1607)) ++ ++## [0.22.2] - 28 September 2021 ++### Fixed ++- Fixed buffer overflow in `unistd::getgrouplist`. ++ (#[1545](https://github.com/nix-rust/nix/pull/1545)) ++- Added more errno definitions for better backwards compatibility with ++ Nix 0.21.0. ++ (#[1467](https://github.com/nix-rust/nix/pull/1467)) ++ ++## [0.22.1] - 13 August 2021 ++### Fixed ++- Locked bitflags to < 1.3.0 to fix the build with rust < 1.46.0. ++ ++### Removed ++- Removed a couple of termios constants on redox that were never actually ++ supported. ++ (#[1483](https://github.com/nix-rust/nix/pull/1483)) ++ ++## [0.22.0] - 9 July 2021 ++### Added ++- Added `if_nameindex` (#[1445](https://github.com/nix-rust/nix/pull/1445)) ++- Added `nmount` for FreeBSD. ++ (#[1453](https://github.com/nix-rust/nix/pull/1453)) ++- Added `IpFreebind` socket option (sockopt) on Linux, Fuchsia and Android. ++ (#[1456](https://github.com/nix-rust/nix/pull/1456)) ++- Added `TcpUserTimeout` socket option (sockopt) on Linux and Fuchsia. ++ (#[1457](https://github.com/nix-rust/nix/pull/1457)) ++- Added `renameat2` for Linux ++ (#[1458](https://github.com/nix-rust/nix/pull/1458)) ++- Added `RxqOvfl` support on Linux, Fuchsia and Android. ++ (#[1455](https://github.com/nix-rust/nix/pull/1455)) ++ ++### Changed ++- `ptsname_r` now returns a lossily-converted string in the event of bad UTF, ++ just like `ptsname`. ++ ([#1446](https://github.com/nix-rust/nix/pull/1446)) ++- Nix's error type is now a simple wrapper around the platform's Errno. This ++ means it is now `Into`. It's also `Clone`, `Copy`, `Eq`, and ++ has a small fixed size. It also requires less typing. For example, the old ++ enum variant `nix::Error::Sys(nix::errno::Errno::EINVAL)` is now simply ++ `nix::Error::EINVAL`. ++ ([#1446](https://github.com/nix-rust/nix/pull/1446)) ++ ++## [0.21.2] - 29 September 2021 ++### Fixed ++- Fixed buffer overflow in `unistd::getgrouplist`. ++ (#[1545](https://github.com/nix-rust/nix/pull/1545)) ++ ++## [0.21.1] - 13 August 2021 ++### Fixed ++- Locked bitflags to < 1.3.0 to fix the build with rust < 1.46.0. ++ ++### Removed ++- Removed a couple of termios constants on redox that were never actually ++ supported. ++ (#[1483](https://github.com/nix-rust/nix/pull/1483)) ++ ++## [0.21.0] - 31 May 2021 ++### Added ++- Added `getresuid` and `getresgid` ++ (#[1430](https://github.com/nix-rust/nix/pull/1430)) ++- Added TIMESTAMPNS support for linux ++ (#[1402](https://github.com/nix-rust/nix/pull/1402)) ++- Added `sendfile64` (#[1439](https://github.com/nix-rust/nix/pull/1439)) ++- Added `MS_LAZYTIME` to `MsFlags` ++ (#[1437](https://github.com/nix-rust/nix/pull/1437)) ++ ++### Changed ++- Made `forkpty` unsafe, like `fork` ++ (#[1390](https://github.com/nix-rust/nix/pull/1390)) ++- Made `Uid`, `Gid` and `Pid` methods `from_raw` and `as_raw` a `const fn` ++ (#[1429](https://github.com/nix-rust/nix/pull/1429)) ++- Made `Uid::is_root` a `const fn` ++ (#[1429](https://github.com/nix-rust/nix/pull/1429)) ++- `AioCb` is now always pinned. Once a `libc::aiocb` gets sent to the kernel, ++ its address in memory must not change. Nix now enforces that by using ++ `std::pin`. Most users won't need to change anything, except when using ++ `aio_suspend`. See that method's documentation for the new usage. ++ (#[1440](https://github.com/nix-rust/nix/pull/1440)) ++- `LioCb` is now constructed using a distinct `LioCbBuilder` struct. This ++ avoids a soundness issue with the old `LioCb`. Usage is similar but ++ construction now uses the builder pattern. See the documentation for ++ details. ++ (#[1440](https://github.com/nix-rust/nix/pull/1440)) ++- Minimum supported Rust version is now 1.41.0. ++ ([#1440](https://github.com/nix-rust/nix/pull/1440)) ++- Errno aliases are now associated consts on `Errno`, instead of consts in the ++ `errno` module. ++ (#[1452](https://github.com/nix-rust/nix/pull/1452)) ++ ++### Fixed ++- Allow `sockaddr_ll` size, as reported by the Linux kernel, to be smaller then it's definition ++ (#[1395](https://github.com/nix-rust/nix/pull/1395)) ++- Fix spurious errors using `sendmmsg` with multiple cmsgs ++ (#[1414](https://github.com/nix-rust/nix/pull/1414)) ++- Added `Errno::EOPNOTSUPP` to FreeBSD, where it was missing. ++ (#[1452](https://github.com/nix-rust/nix/pull/1452)) ++ ++### Removed ++ ++- Removed `sys::socket::accept4` from Android arm because libc removed it in ++ version 0.2.87. ++ ([#1399](https://github.com/nix-rust/nix/pull/1399)) ++- `AioCb::from_boxed_slice` and `AioCb::from_boxed_mut_slice` have been ++ removed. They were useful with earlier versions of Rust, but should no ++ longer be needed now that async/await are available. `AioCb`s now work ++ exclusively with borrowed buffers, not owned ones. ++ (#[1440](https://github.com/nix-rust/nix/pull/1440)) ++- Removed some Errno values from platforms where they aren't actually defined. ++ (#[1452](https://github.com/nix-rust/nix/pull/1452)) ++ ++## [0.20.2] - 28 September 2021 ++### Fixed ++- Fixed buffer overflow in `unistd::getgrouplist`. ++ (#[1545](https://github.com/nix-rust/nix/pull/1545)) ++ ++## [0.20.1] - 13 August 2021 ++### Fixed ++- Locked bitflags to < 1.3.0 to fix the build with rust < 1.46.0. ++ ++### Removed ++- Removed a couple of termios constants on redox that were never actually ++ supported. ++ (#[1483](https://github.com/nix-rust/nix/pull/1483)) ++ ++## [0.20.0] - 20 February 2021 ++### Added ++ ++- Added a `passwd` field to `Group` (#[1338](https://github.com/nix-rust/nix/pull/1338)) ++- Added `mremap` (#[1306](https://github.com/nix-rust/nix/pull/1306)) ++- Added `personality` (#[1331](https://github.com/nix-rust/nix/pull/1331)) ++- Added limited Fuchsia support (#[1285](https://github.com/nix-rust/nix/pull/1285)) ++- Added `getpeereid` (#[1342](https://github.com/nix-rust/nix/pull/1342)) ++- Implemented `IntoIterator` for `Dir` ++ (#[1333](https://github.com/nix-rust/nix/pull/1333)). ++ ++### Changed ++ ++- Minimum supported Rust version is now 1.40.0. ++ ([#1356](https://github.com/nix-rust/nix/pull/1356)) ++- i686-apple-darwin has been demoted to Tier 2 support, because it's deprecated ++ by Xcode. ++ (#[1350](https://github.com/nix-rust/nix/pull/1350)) ++- Fixed calling `recvfrom` on an `AddrFamily::Packet` socket ++ (#[1344](https://github.com/nix-rust/nix/pull/1344)) ++ ++### Fixed ++- `TimerFd` now closes the underlying fd on drop. ++ ([#1381](https://github.com/nix-rust/nix/pull/1381)) ++- Define `*_MAGIC` filesystem constants on Linux s390x ++ (#[1372](https://github.com/nix-rust/nix/pull/1372)) ++- mqueue, sysinfo, timespec, statfs, test_ptrace_syscall() on x32 ++ (#[1366](https://github.com/nix-rust/nix/pull/1366)) ++ ++### Removed ++ ++- `Dir`, `SignalFd`, and `PtyMaster` are no longer `Clone`. ++ (#[1382](https://github.com/nix-rust/nix/pull/1382)) ++- Removed `SockLevel`, which hasn't been used for a few years ++ (#[1362](https://github.com/nix-rust/nix/pull/1362)) ++- Removed both `Copy` and `Clone` from `TimerFd`. ++ ([#1381](https://github.com/nix-rust/nix/pull/1381)) ++ ++## [0.19.1] - 28 November 2020 ++### Fixed ++- Fixed bugs in `recvmmsg`. ++ (#[1341](https://github.com/nix-rust/nix/pull/1341)) ++ ++## [0.19.0] - 6 October 2020 ++### Added ++- Added Netlink protocol families to the `SockProtocol` enum ++ (#[1289](https://github.com/nix-rust/nix/pull/1289)) ++- Added `clock_gettime`, `clock_settime`, `clock_getres`, ++ `clock_getcpuclockid` functions and `ClockId` struct. ++ (#[1281](https://github.com/nix-rust/nix/pull/1281)) ++- Added wrapper functions for `PTRACE_SYSEMU` and `PTRACE_SYSEMU_SINGLESTEP`. ++ (#[1300](https://github.com/nix-rust/nix/pull/1300)) ++- Add support for Vsock on Android rather than just Linux. ++ (#[1301](https://github.com/nix-rust/nix/pull/1301)) ++- Added `TCP_KEEPCNT` and `TCP_KEEPINTVL` TCP keepalive options. ++ (#[1283](https://github.com/nix-rust/nix/pull/1283)) ++### Changed ++- Expose `SeekData` and `SeekHole` on all Linux targets ++ (#[1284](https://github.com/nix-rust/nix/pull/1284)) ++- Changed unistd::{execv,execve,execvp,execvpe,fexecve,execveat} to take both `&[&CStr]` and `&[CString]` as its list argument(s). ++ (#[1278](https://github.com/nix-rust/nix/pull/1278)) ++- Made `unistd::fork` an unsafe funtion, bringing it in line with [libstd's decision](https://github.com/rust-lang/rust/pull/58059). ++ (#[1293](https://github.com/nix-rust/nix/pull/1293)) ++ ++## [0.18.0] - 26 July 2020 ++### Added ++- Added `fchown(2)` wrapper. ++ (#[1257](https://github.com/nix-rust/nix/pull/1257)) ++- Added support on linux systems for `MAP_HUGE_`_`SIZE`_ family of flags. ++ (#[1211](https://github.com/nix-rust/nix/pull/1211)) ++- Added support for `F_OFD_*` `fcntl` commands on Linux and Android. ++ (#[1195](https://github.com/nix-rust/nix/pull/1195)) ++- Added `env::clearenv()`: calls `libc::clearenv` on platforms ++ where it's available, and clears the environment of all variables ++ via `std::env::vars` and `std::env::remove_var` on others. ++ (#[1185](https://github.com/nix-rust/nix/pull/1185)) ++- `FsType` inner value made public. ++ (#[1187](https://github.com/nix-rust/nix/pull/1187)) ++- Added `unistd::setfsuid` and `unistd::setfsgid` to set the user or group ++ identity for filesystem checks per-thread. ++ (#[1163](https://github.com/nix-rust/nix/pull/1163)) ++- Derived `Ord`, `PartialOrd` for `unistd::Pid` (#[1189](https://github.com/nix-rust/nix/pull/1189)) ++- Added `select::FdSet::fds` method to iterate over file descriptors in a set. ++ ([#1207](https://github.com/nix-rust/nix/pull/1207)) ++- Added support for UDP generic segmentation offload (GSO) and generic ++ receive offload (GRO) ([#1209](https://github.com/nix-rust/nix/pull/1209)) ++- Added support for `sendmmsg` and `recvmmsg` calls ++ (#[1208](https://github.com/nix-rust/nix/pull/1208)) ++- Added support for `SCM_CREDS` messages (`UnixCredentials`) on FreeBSD/DragonFly ++ (#[1216](https://github.com/nix-rust/nix/pull/1216)) ++- Added `BindToDevice` socket option (sockopt) on Linux ++ (#[1233](https://github.com/nix-rust/nix/pull/1233)) ++- Added `EventFilter` bitflags for `EV_DISPATCH` and `EV_RECEIPT` on OpenBSD. ++ (#[1252](https://github.com/nix-rust/nix/pull/1252)) ++- Added support for `Ipv4PacketInfo` and `Ipv6PacketInfo` to `ControlMessage`. ++ (#[1222](https://github.com/nix-rust/nix/pull/1222)) ++- `CpuSet` and `UnixCredentials` now implement `Default`. ++ (#[1244](https://github.com/nix-rust/nix/pull/1244)) ++- Added `unistd::ttyname` ++ (#[1259](https://github.com/nix-rust/nix/pull/1259)) ++- Added support for `Ipv4PacketInfo` and `Ipv6PacketInfo` to `ControlMessage` for iOS and Android. ++ (#[1265](https://github.com/nix-rust/nix/pull/1265)) ++- Added support for `TimerFd`. ++ (#[1261](https://github.com/nix-rust/nix/pull/1261)) ++ ++### Changed ++- Changed `fallocate` return type from `c_int` to `()` (#[1201](https://github.com/nix-rust/nix/pull/1201)) ++- Enabled `sys::ptrace::setregs` and `sys::ptrace::getregs` on x86_64-unknown-linux-musl target ++ (#[1198](https://github.com/nix-rust/nix/pull/1198)) ++- On Linux, `ptrace::write` is now an `unsafe` function. Caveat programmer. ++ (#[1245](https://github.com/nix-rust/nix/pull/1245)) ++- `execv`, `execve`, `execvp` and `execveat` in `::nix::unistd` and `reboot` in ++ `::nix::sys::reboot` now return `Result` instead of `Result` (#[1239](https://github.com/nix-rust/nix/pull/1239)) ++- `sys::socket::sockaddr_storage_to_addr` is no longer `unsafe`. So is ++ `offset_of!`. ++- `sys::socket::sockaddr_storage_to_addr`, `offset_of!`, and `Errno::clear` are ++ no longer `unsafe`. ++- `SockAddr::as_ffi_pair`,`sys::socket::sockaddr_storage_to_addr`, `offset_of!`, ++ and `Errno::clear` are no longer `unsafe`. ++ (#[1244](https://github.com/nix-rust/nix/pull/1244)) ++- Several `Inotify` methods now take `self` by value instead of by reference ++ (#[1244](https://github.com/nix-rust/nix/pull/1244)) ++- `nix::poll::ppoll`: `timeout` parameter is now optional, None is equivalent for infinite timeout. ++ ++### Fixed ++ ++- Fixed `getsockopt`. The old code produced UB which triggers a panic with ++ Rust 1.44.0. ++ (#[1214](https://github.com/nix-rust/nix/pull/1214)) ++ ++- Fixed a bug in nix::unistd that would result in an infinite loop ++ when a group or user lookup required a buffer larger than ++ 16KB. (#[1198](https://github.com/nix-rust/nix/pull/1198)) ++- Fixed unaligned casting of `cmsg_data` to `af_alg_iv` (#[1206](https://github.com/nix-rust/nix/pull/1206)) ++- Fixed `readlink`/`readlinkat` when reading symlinks longer than `PATH_MAX` (#[1231](https://github.com/nix-rust/nix/pull/1231)) ++- `PollFd`, `EpollEvent`, `IpMembershipRequest`, `Ipv6MembershipRequest`, ++ `TimeVal`, and `IoVec` are now `repr(transparent)`. This is required for ++ correctness's sake across all architectures and compilers, though now bugs ++ have been reported so far. ++ (#[1243](https://github.com/nix-rust/nix/pull/1243)) ++- Fixed unaligned pointer read in `Inotify::read_events`. ++ (#[1244](https://github.com/nix-rust/nix/pull/1244)) ++ ++### Removed ++ ++- Removed `sys::socket::addr::from_libc_sockaddr` from the public API. ++ (#[1215](https://github.com/nix-rust/nix/pull/1215)) ++- Removed `sys::termios::{get_libc_termios, get_libc_termios_mut, update_wrapper` ++ from the public API. These were previously hidden in the docs but still usable ++ by downstream. ++ (#[1235](https://github.com/nix-rust/nix/pull/1235)) ++ ++- Nix no longer implements `NixPath` for `Option

where P: NixPath`. Most ++ Nix functions that accept `NixPath` arguments can't do anything useful with ++ `None`. The exceptions (`mount` and `quotactl_sync`) already take explicitly ++ optional arguments. ++ (#[1242](https://github.com/nix-rust/nix/pull/1242)) ++ ++- Removed `unistd::daemon` and `unistd::pipe2` on OSX and ios ++ (#[1255](https://github.com/nix-rust/nix/pull/1255)) ++ ++- Removed `sys::event::FilterFlag::NOTE_EXIT_REPARENTED` and ++ `sys::event::FilterFlag::NOTE_REAP` on OSX and ios. ++ (#[1255](https://github.com/nix-rust/nix/pull/1255)) ++ ++- Removed `sys::ptrace::ptrace` on Android and Linux. ++ (#[1255](https://github.com/nix-rust/nix/pull/1255)) ++ ++- Dropped support for powerpc64-unknown-linux-gnu ++ (#[1266](https://github.com/nix-rust/nix/pull/1268)) ++ + ## [0.17.0] - 3 February 2020 + ### Added + - Add `CLK_TCK` to `SysconfVar` + (#[1177](https://github.com/nix-rust/nix/pull/1177)) +-### Changed +-### Fixed + ### Removed + - Removed deprecated Error::description from error types + (#[1175](https://github.com/nix-rust/nix/pull/1175)) + + ## [0.16.1] - 23 December 2019 +-### Added +-### Changed + ### Fixed + + - Fixed the build for OpenBSD + (#[1168](https://github.com/nix-rust/nix/pull/1168)) + +-### Removed +- + ## [0.16.0] - 1 December 2019 + ### Added + - Added `ptrace::seize()`: similar to `attach()` on Linux +@@ -96,7 +778,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). + + // old code `readlink(&path, &mut buf)` can be replaced with the following + let _: OsString = readlink(&path); +- ++ + // old code `readlinkat(dirfd, &path, &mut buf)` can be replaced with the following + let _: OsString = readlinkat(dirfd, &path); + ``` +@@ -156,8 +838,6 @@ This project adheres to [Semantic Versioning](http://semver.org/). + - Enabled `sched_yield` for all nix hosts. + ([#1090](https://github.com/nix-rust/nix/pull/1090)) + +-### Removed +- + ## [0.14.1] - 2019-06-06 + ### Added + - Macros exported by `nix` may now be imported via `use` on the Rust 2018 +@@ -182,8 +862,6 @@ This project adheres to [Semantic Versioning](http://semver.org/). + - Fix the build on Android and Linux/mips with recent versions of libc. + ([#1072](https://github.com/nix-rust/nix/pull/1072/commits)) + +-### Removed +- + ## [0.14.0] - 2019-05-21 + ### Added + - Add IP_RECVIF & IP_RECVDSTADDR. Enable IP_PKTINFO and IP6_PKTINFO on netbsd/openbsd. +@@ -252,6 +930,23 @@ This project adheres to [Semantic Versioning](http://semver.org/). + should've been defined in the first place. + ([#1055](https://github.com/nix-rust/nix/pull/1055)) + ++## [0.13.1] - 2019-06-10 ++### Changed ++- Changed some public types from reexports of libc types like `uint32_t` to the ++ native equivalents like `u32.` ++ ([#1072](https://github.com/nix-rust/nix/pull/1072/commits)) ++ ++### Fixed ++- Fix the build on Android and Linux/mips with recent versions of libc. ++ ([#1072](https://github.com/nix-rust/nix/pull/1072/commits)) ++- Fixed build on Linux/arm and Linux/s390x with the latest Rust libc ++ ([52102cb](https://github.com/nix-rust/nix/commit/52102cb76398c4dfb9ea141b98c5b01a2e050973)) ++ ++### Removed ++- `Daemon`, `NOTE_REAP`, and `NOTE_EXIT_REPARENTED` are now deprecated on OSX ++ and iOS. ++ ([#1033](https://github.com/nix-rust/nix/pull/1033)) ++ + ## [0.13.0] - 2019-01-15 + ### Added + - Added PKTINFO(V4) & V6PKTINFO cmsg support - Android/FreeBSD/iOS/Linux/MacOS. +@@ -269,14 +964,30 @@ This project adheres to [Semantic Versioning](http://semver.org/). + - Added an `mprotect` wrapper. + ([#991](https://github.com/nix-rust/nix/pull/991)) + +-### Changed + ### Fixed + - `lutimes` never worked on OpenBSD as it is not implemented on OpenBSD. It has + been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000)) + - `fexecve` never worked on NetBSD or on OpenBSD as it is not implemented on + either OS. It has been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000)) + ++## [0.12.1] 2019-06-08 ++### Changed ++- Changed some public types from reexports of libc types like `uint32_t` to the ++ native equivalents like `u32.` ++ ([#1072](https://github.com/nix-rust/nix/pull/1072/commits)) ++ ++### Fixed ++- Fix the build on Android and Linux/mips with recent versions of libc. ++ ([#1072](https://github.com/nix-rust/nix/pull/1072/commits)) ++- Fixed build on Linux/arm and Linux/s390x with the latest Rust libc ++ ([52102cb](https://github.com/nix-rust/nix/commit/52102cb76398c4dfb9ea141b98c5b01a2e050973)) ++ + ### Removed ++- `fexecve` never worked on NetBSD or on OpenBSD as it is not implemented on ++ either OS. It has been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000)) ++- `Daemon`, `NOTE_REAP`, and `NOTE_EXIT_REPARENTED` are now deprecated on OSX ++ and iOS. ++ ([#1033](https://github.com/nix-rust/nix/pull/1033)) + + ## [0.12.0] 2018-11-28 + +@@ -328,7 +1039,24 @@ This project adheres to [Semantic Versioning](http://semver.org/). + - Fixed passing multiple file descriptors over Unix Sockets. + ([#918](https://github.com/nix-rust/nix/pull/918)) + ++## [0.11.1] 2019-06-06 ++### Changed ++- Changed some public types from reexports of libc types like `uint32_t` to the ++ native equivalents like `u32.` ++ ([#1072](https://github.com/nix-rust/nix/pull/1072/commits)) ++ ++### Fixed ++- Fix the build on Android and Linux/mips with recent versions of libc. ++ ([#1072](https://github.com/nix-rust/nix/pull/1072/commits)) ++- Fixed build on Linux/arm and Linux/s390x with the latest Rust libc ++ ([52102cb](https://github.com/nix-rust/nix/commit/52102cb76398c4dfb9ea141b98c5b01a2e050973)) ++ + ### Removed ++- `fexecve` never worked on NetBSD or on OpenBSD as it is not implemented on ++ either OS. It has been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000)) ++- `Daemon`, `NOTE_REAP`, and `NOTE_EXIT_REPARENTED` are now deprecated on OSX ++ and iOS. ++ ([#1033](https://github.com/nix-rust/nix/pull/1033)) + + ## [0.11.0] 2018-06-01 + +diff --git a/vendor/nix/CONTRIBUTING.md b/vendor/nix/CONTRIBUTING.md +deleted file mode 100644 +index 03a1f63..0000000 +--- a/vendor/nix/CONTRIBUTING.md ++++ /dev/null +@@ -1,114 +0,0 @@ +-# Contributing to nix +- +-We're really glad you're interested in contributing to nix! This +-document has a few pointers and guidelines to help get you started. +- +-To have a welcoming and inclusive project, nix uses the Rust project's +-[Code of Conduct][conduct]. All contributors are expected to follow it. +- +-[conduct]: https://www.rust-lang.org/conduct.html +- +- +-# Issues +- +-We use GitHub's [issue tracker][issues]. +- +-[issues]: https://github.com/nix-rust/nix/issues +- +- +-## Bug reports +- +-Before submitting a new bug report, please [search existing +-issues][issue-search] to see if there's something related. If not, just +-[open a new issue][new-issue]! +- +-As a reminder, the more information you can give in your issue, the +-easier it is to figure out how to fix it. For nix, this will likely +-include the OS and version, and the architecture. +- +-[issue-search]: https://github.com/nix-rust/nix/search?utf8=%E2%9C%93&q=is%3Aissue&type=Issues +-[new-issue]: https://github.com/nix-rust/nix/issues/new +- +- +-## Feature / API requests +- +-If you'd like a new API or feature added, please [open a new +-issue][new-issue] requesting it. As with reporting a bug, the more +-information you can provide, the better. +- +- +-## Labels +- +-We use labels to help manage issues. The structure is modeled after +-[Rust's issue labeling scheme][rust-labels]: +-- **A-**prefixed labels state which area of the project the issue +- relates to +-- **E-**prefixed labels explain the level of experience necessary to fix the +- issue +-- **O-**prefixed labels specify the OS for issues that are OS-specific +-- **R-**prefixed labels specify the architecture for issues that are +- architecture-specific +- +-[rust-labels]: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#issue-triage +- +- +-# Pull requests +- +-GitHub pull requests are the primary mechanism we use to change nix. GitHub itself has +-some [great documentation][pr-docs] on using the Pull Request feature. We use the 'fork and +-pull' model described there. +- +-Please make pull requests against the `master` branch. +- +-If you change the API by way of adding, removing or changing something or if +-you fix a bug, please add an appropriate note to the [change log][cl]. We +-follow the conventions of [Keep A CHANGELOG][kacl]. +- +-[cl]: https://github.com/nix-rust/nix/blob/master/CHANGELOG.md +-[kacl]: https://github.com/olivierlacan/keep-a-changelog/tree/18adb5f5be7a898d046f6a4acb93e39dcf40c4ad +-[pr-docs]: https://help.github.com/articles/using-pull-requests/ +- +-## Testing +- +-nix has a test suite that you can run with `cargo test`. Ideally, we'd like pull +-requests to include tests where they make sense. For example, when fixing a bug, +-add a test that would have failed without the fix. +- +-After you've made your change, make sure the tests pass in your development +-environment. We also have [continuous integration set up on +-Travis-CI][travis-ci], which might find some issues on other platforms. The CI +-will run once you open a pull request. +- +-There is also infrastructure for running tests for other targets +-locally. More information is available in the [CI Readme][ci-readme]. +- +-[travis-ci]: https://travis-ci.org/nix-rust/nix +-[ci-readme]: ci/README.md +- +-### Disabling a test in the CI environment +- +-Sometimes there are features that cannot be tested in the CI environment. +-To stop a test from running under CI, add `#[cfg_attr(travis, ignore)]` +-to it. Please include a comment describing the reason it shouldn't run +-under CI, and a link to an upstream issue if possible! +- +-## bors, the bot who merges all the PRs +- +-All pull requests are merged via [bors], an integration bot. After the +-pull request has been reviewed, the reviewer will leave a comment like +- +-> bors r+ +- +-to let bors know that it was approved. Then bors will check that it passes +-tests when merged with the latest changes in the `master` branch, and +-merge if the tests succeed. +- +-[bors]: https://bors-ng.github.io/ +- +- +-## API conventions +- +-If you're adding a new API, we have a [document with +-conventions][conventions] to use throughout the nix project. +- +-[conventions]: https://github.com/nix-rust/nix/blob/master/CONVENTIONS.md +diff --git a/vendor/nix/CONVENTIONS.md b/vendor/nix/CONVENTIONS.md +deleted file mode 100644 +index 2461085..0000000 +--- a/vendor/nix/CONVENTIONS.md ++++ /dev/null +@@ -1,86 +0,0 @@ +-# Conventions +- +-In order to achieve our goal of wrapping [libc][libc] code in idiomatic rust +-constructs with minimal performance overhead, we follow the following +-conventions. +- +-Note that, thus far, not all the code follows these conventions and not all +-conventions we try to follow have been documented here. If you find an instance +-of either, feel free to remedy the flaw by opening a pull request with +-appropriate changes or additions. +- +-## Change Log +- +-We follow the conventions laid out in [Keep A CHANGELOG][kacl]. +- +-[kacl]: https://github.com/olivierlacan/keep-a-changelog/tree/18adb5f5be7a898d046f6a4acb93e39dcf40c4ad +- +-## libc constants, functions and structs +- +-We do not define integer constants ourselves, but use or reexport them from the +-[libc crate][libc]. +- +-We use the functions exported from [libc][libc] instead of writing our own +-`extern` declarations. +- +-We use the `struct` definitions from [libc][libc] internally instead of writing +-our own. If we want to add methods to a libc type, we use the newtype pattern. +-For example, +- +-```rust +-pub struct SigSet(libc::sigset_t); +- +-impl SigSet { +- ... +-} +-``` +- +-When creating newtypes, we use Rust's `CamelCase` type naming convention. +- +-## Bitflags +- +-Many C functions have flags parameters that are combined from constants using +-bitwise operations. We represent the types of these parameters by types defined +-using our `libc_bitflags!` macro, which is a convenience wrapper around the +-`bitflags!` macro from the [bitflags crate][bitflags] that brings in the +-constant value from `libc`. +- +-We name the type for a set of constants whose element's names start with `FOO_` +-`FooFlags`. +- +-For example, +- +-```rust +-libc_bitflags!{ +- pub struct ProtFlags: libc::c_int { +- PROT_NONE; +- PROT_READ; +- PROT_WRITE; +- PROT_EXEC; +- #[cfg(any(target_os = "linux", target_os = "android"))] +- PROT_GROWSDOWN; +- #[cfg(any(target_os = "linux", target_os = "android"))] +- PROT_GROWSUP; +- } +-} +-``` +- +- +-## Enumerations +- +-We represent sets of constants that are intended as mutually exclusive arguments +-to parameters of functions by [enumerations][enum]. +- +- +-## Structures Initialized by libc Functions +- +-Whenever we need to use a [libc][libc] function to properly initialize a +-variable and said function allows us to use uninitialized memory, we use +-[`std::mem::MaybeUninit`][std_MaybeUninit] when defining the variable. This +-allows us to avoid the overhead incurred by zeroing or otherwise initializing +-the variable. +- +-[bitflags]: https://crates.io/crates/bitflags/ +-[enum]: https://doc.rust-lang.org/reference.html#enumerations +-[libc]: https://crates.io/crates/libc/ +-[std_MaybeUninit]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html +diff --git a/vendor/nix/Cargo.toml b/vendor/nix/Cargo.toml +index bff7c2a..0afc445 100644 +--- a/vendor/nix/Cargo.toml ++++ b/vendor/nix/Cargo.toml +@@ -3,23 +3,50 @@ + # When uploading crates to the registry Cargo will automatically + # "normalize" Cargo.toml files for maximal compatibility + # with all versions of Cargo and also rewrite `path` dependencies +-# to registry (e.g., crates.io) dependencies ++# to registry (e.g., crates.io) dependencies. + # +-# If you believe there's an error in this file please file an +-# issue against the rust-lang/cargo repository. If you're +-# editing this file be aware that the upstream Cargo.toml +-# will likely look very different (and much more reasonable) ++# If you are reading this file be aware that the original Cargo.toml ++# will likely look very different (and much more reasonable). ++# See Cargo.toml.orig for the original contents. + + [package] ++edition = "2018" ++rust-version = "1.56" + name = "nix" +-version = "0.17.0" ++version = "0.26.2" + authors = ["The nix-rust Project Developers"] +-exclude = ["/.gitignore", "/.travis.yml", "/ci/*", "/Cross.toml", "/RELEASE_PROCEDURE.md", "/bors.toml"] ++include = [ ++ "src/**/*", ++ "test/**/*", ++ "LICENSE", ++ "README.md", ++ "CHANGELOG.md", ++] + description = "Rust friendly bindings to *nix APIs" ++readme = "README.md" + categories = ["os::unix-apis"] + license = "MIT" + repository = "https://github.com/nix-rust/nix" + ++[package.metadata.docs.rs] ++rustdoc-args = [ ++ "--cfg", ++ "docsrs", ++] ++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", ++ "x86_64-unknown-illumos", ++] ++ + [[test]] + name = "test" + path = "test/test.rs" +@@ -29,8 +56,8 @@ name = "test-aio-drop" + path = "test/sys/test_aio_drop.rs" + + [[test]] +-name = "test-lio-listio-resubmit" +-path = "test/sys/test_lio_listio_resubmit.rs" ++name = "test-clearenv" ++path = "test/test_clearenv.rs" + + [[test]] + name = "test-mount" +@@ -40,32 +67,119 @@ harness = false + [[test]] + name = "test-ptymaster-drop" + path = "test/test_ptymaster_drop.rs" ++ + [dependencies.bitflags] + version = "1.1" + + [dependencies.cfg-if] +-version = "0.1.2" ++version = "1.0" + + [dependencies.libc] +-version = "0.2.60" ++version = "0.2.137" + features = ["extra_traits"] + +-[dependencies.void] +-version = "1.0.2" +-[dev-dependencies.bytes] +-version = "0.4.8" ++[dependencies.pin-utils] ++version = "0.1.0" ++optional = true ++ ++[dependencies.static_assertions] ++version = "1" ++ ++[dev-dependencies.assert-impl] ++version = "0.1" + + [dev-dependencies.lazy_static] +-version = "1.2" ++version = "1.4" ++ ++[dev-dependencies.parking_lot] ++version = "0.12" + + [dev-dependencies.rand] +-version = "0.6" ++version = "0.8" ++ ++[dev-dependencies.semver] ++version = "1.0.7" + + [dev-dependencies.tempfile] +-version = "3.0.5" ++version = "3.3.0" ++ ++[features] ++acct = [] ++aio = ["pin-utils"] ++default = [ ++ "acct", ++ "aio", ++ "dir", ++ "env", ++ "event", ++ "feature", ++ "fs", ++ "hostname", ++ "inotify", ++ "ioctl", ++ "kmod", ++ "mman", ++ "mount", ++ "mqueue", ++ "net", ++ "personality", ++ "poll", ++ "process", ++ "pthread", ++ "ptrace", ++ "quota", ++ "reboot", ++ "resource", ++ "sched", ++ "signal", ++ "socket", ++ "term", ++ "time", ++ "ucontext", ++ "uio", ++ "user", ++ "zerocopy", ++] ++dir = ["fs"] ++env = [] ++event = [] ++feature = [] ++fs = [] ++hostname = [] ++inotify = [] ++ioctl = [] ++kmod = [] ++mman = [] ++mount = ["uio"] ++mqueue = ["fs"] ++net = ["socket"] ++personality = [] ++poll = [] ++process = [] ++pthread = [] ++ptrace = ["process"] ++quota = [] ++reboot = [] ++resource = [] ++sched = ["process"] ++signal = ["process"] ++socket = ["memoffset"] ++term = [] ++time = [] ++ucontext = ["signal"] ++uio = [] ++user = ["feature"] ++zerocopy = [ ++ "fs", ++ "uio", ++] ++ + [target."cfg(any(target_os = \"android\", target_os = \"linux\"))".dev-dependencies.caps] +-version = "0.3.1" +-[target."cfg(target_os = \"dragonfly\")".build-dependencies.cc] +-version = "1" ++version = "0.5.3" ++ ++[target."cfg(not(target_os = \"redox\"))".dependencies.memoffset] ++version = "0.7" ++optional = true ++ + [target."cfg(target_os = \"freebsd\")".dev-dependencies.sysctl] +-version = "0.1" ++version = "0.4" +diff --git a/vendor/nix/README.md b/vendor/nix/README.md +index a7af207..2c42b90 100644 +--- a/vendor/nix/README.md ++++ b/vendor/nix/README.md +@@ -1,7 +1,7 @@ + # Rust bindings to *nix APIs + +-[![Build Status](https://travis-ci.org/nix-rust/nix.svg?branch=master)](https://travis-ci.org/nix-rust/nix) +-[![crates.io](http://meritbadge.herokuapp.com/nix)](https://crates.io/crates/nix) ++[![Cirrus Build Status](https://api.cirrus-ci.com/github/nix-rust/nix.svg)](https://cirrus-ci.com/github/nix-rust/nix) ++[![crates.io](https://img.shields.io/crates/v/nix.svg)](https://crates.io/crates/nix) + + [Documentation (Releases)](https://docs.rs/nix/) + +@@ -17,15 +17,15 @@ usage. + + As an example of what Nix provides, examine the differences between what is + exposed by libc and nix for the +-[gethostname](http://man7.org/linux/man-pages/man2/gethostname.2.html) system ++[gethostname](https://man7.org/linux/man-pages/man2/gethostname.2.html) system + call: + + ```rust,ignore + // libc api (unsafe, requires handling return code/errno) + pub unsafe extern fn gethostname(name: *mut c_char, len: size_t) -> c_int; + +-// nix api (returns a nix::Result) +-pub fn gethostname<'a>(buffer: &'a mut [u8]) -> Result<&'a CStr>; ++// nix api (returns a nix::Result) ++pub fn gethostname() -> Result; + ``` + + ## Supported Platforms +@@ -47,10 +47,10 @@ limitations. Support for platforms is split into three tiers: + The following targets are supported by `nix`: + + Tier 1: ++ * aarch64-apple-darwin + * aarch64-unknown-linux-gnu + * arm-unknown-linux-gnueabi + * armv7-unknown-linux-gnueabihf +- * i686-apple-darwin + * i686-unknown-freebsd + * i686-unknown-linux-gnu + * i686-unknown-linux-musl +@@ -58,9 +58,7 @@ Tier 1: + * mips64-unknown-linux-gnuabi64 + * mips64el-unknown-linux-gnuabi64 + * mipsel-unknown-linux-gnu +- * powerpc64-unknown-linux-gnu + * powerpc64le-unknown-linux-gnu +- * x86_64-apple-darwin + * x86_64-unknown-freebsd + * x86_64-unknown-linux-gnu + * x86_64-unknown-linux-musl +@@ -70,33 +68,29 @@ Tier 2: + * aarch64-linux-android + * arm-linux-androideabi + * arm-unknown-linux-musleabi +- * armv7-apple-ios + * armv7-linux-androideabi +- * armv7s-apple-ios +- * i386-apple-ios + * i686-linux-android + * powerpc-unknown-linux-gnu + * s390x-unknown-linux-gnu + * x86_64-apple-ios + * x86_64-linux-android ++ * x86_64-apple-darwin ++ * x86_64-unknown-illumos + * x86_64-unknown-netbsd + +-## Usage +- +-`nix` requires Rust 1.36.0 or newer. +- +-To use `nix`, first add this to your `Cargo.toml`: ++Tier 3: ++ * armv7-unknown-linux-uclibceabihf ++ * x86_64-fuchsia ++ * x86_64-unknown-dragonfly ++ * x86_64-unknown-haiku ++ * x86_64-unknown-linux-gnux32 ++ * x86_64-unknown-openbsd ++ * x86_64-unknown-redox + +-```toml +-[dependencies] +-nix = "0.17.0" +-``` +- +-Then, add this to your crate root: ++## Minimum Supported Rust Version (MSRV) + +-```rust,ignore +-extern crate nix; +-``` ++nix is supported on Rust 1.56.1 and higher. Its MSRV will not be ++changed in the future without bumping the major or minor version. + + ## Contributing + +diff --git a/vendor/nix/build.rs b/vendor/nix/build.rs +deleted file mode 100644 +index 92fd366..0000000 +--- a/vendor/nix/build.rs ++++ /dev/null +@@ -1,12 +0,0 @@ +-#[cfg(target_os = "dragonfly")] +-extern crate cc; +- +-#[cfg(target_os = "dragonfly")] +-fn main() { +- cc::Build::new() +- .file("src/errno_dragonfly.c") +- .compile("liberrno_dragonfly.a"); +-} +- +-#[cfg(not(target_os = "dragonfly"))] +-fn main() {} +diff --git a/vendor/nix/src/dir.rs b/vendor/nix/src/dir.rs +index d8c05e9..5ce5036 100644 +--- a/vendor/nix/src/dir.rs ++++ b/vendor/nix/src/dir.rs +@@ -1,10 +1,13 @@ +-use {Error, NixPath, Result}; +-use errno::Errno; +-use fcntl::{self, OFlag}; +-use libc; ++//! List directory contents ++ ++use crate::errno::Errno; ++use crate::fcntl::{self, OFlag}; ++use crate::sys; ++use crate::{Error, NixPath, Result}; ++use cfg_if::cfg_if; ++use std::ffi; + use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd}; +-use std::{ffi, ptr}; +-use sys; ++use std::ptr; + + #[cfg(target_os = "linux")] + use libc::{dirent64 as dirent, readdir64_r as readdir_r}; +@@ -25,22 +28,27 @@ use libc::{dirent, readdir_r}; + /// * returns entries for `.` (current directory) and `..` (parent directory). + /// * returns entries' names as a `CStr` (no allocation or conversion beyond whatever libc + /// does). +-#[derive(Clone, Debug, Eq, Hash, PartialEq)] +-pub struct Dir( +- ptr::NonNull +-); ++#[derive(Debug, Eq, Hash, PartialEq)] ++pub struct Dir(ptr::NonNull); + + impl Dir { + /// Opens the given path as with `fcntl::open`. +- pub fn open(path: &P, oflag: OFlag, +- mode: sys::stat::Mode) -> Result { ++ pub fn open( ++ path: &P, ++ oflag: OFlag, ++ mode: sys::stat::Mode, ++ ) -> Result { + let fd = fcntl::open(path, oflag, mode)?; + Dir::from_fd(fd) + } + + /// Opens the given path as with `fcntl::openat`. +- pub fn openat(dirfd: RawFd, path: &P, oflag: OFlag, +- mode: sys::stat::Mode) -> Result { ++ pub fn openat( ++ dirfd: RawFd, ++ path: &P, ++ oflag: OFlag, ++ mode: sys::stat::Mode, ++ ) -> Result { + let fd = fcntl::openat(dirfd, path, oflag, mode)?; + Dir::from_fd(fd) + } +@@ -52,15 +60,16 @@ impl Dir { + } + + /// Converts from a file descriptor, closing it on success or failure. ++ #[doc(alias("fdopendir"))] + pub fn from_fd(fd: RawFd) -> Result { +- let d = unsafe { libc::fdopendir(fd) }; +- if d.is_null() { +- let e = Error::last(); +- unsafe { libc::close(fd) }; +- return Err(e); +- }; +- // Always guaranteed to be non-null by the previous check +- Ok(Dir(ptr::NonNull::new(d).unwrap())) ++ let d = ptr::NonNull::new(unsafe { libc::fdopendir(fd) }).ok_or_else( ++ || { ++ let e = Error::last(); ++ unsafe { libc::close(fd) }; ++ e ++ }, ++ )?; ++ Ok(Dir(d)) + } + + /// Returns an iterator of `Result` which rewinds when finished. +@@ -85,10 +94,38 @@ impl AsRawFd for Dir { + + impl Drop for Dir { + fn drop(&mut self) { +- unsafe { libc::closedir(self.0.as_ptr()) }; ++ let e = Errno::result(unsafe { libc::closedir(self.0.as_ptr()) }); ++ if !std::thread::panicking() && e == Err(Errno::EBADF) { ++ panic!("Closing an invalid file descriptor!"); ++ }; ++ } ++} ++ ++fn next(dir: &mut Dir) -> Option> { ++ unsafe { ++ // Note: POSIX specifies that portable applications should dynamically allocate a ++ // buffer with room for a `d_name` field of size `pathconf(..., _PC_NAME_MAX)` plus 1 ++ // for the NUL byte. It doesn't look like the std library does this; it just uses ++ // fixed-sized buffers (and libc's dirent seems to be sized so this is appropriate). ++ // Probably fine here too then. ++ let mut ent = std::mem::MaybeUninit::::uninit(); ++ let mut result = ptr::null_mut(); ++ if let Err(e) = Errno::result(readdir_r( ++ dir.0.as_ptr(), ++ ent.as_mut_ptr(), ++ &mut result, ++ )) { ++ return Some(Err(e)); ++ } ++ if result.is_null() { ++ return None; ++ } ++ assert_eq!(result, ent.as_mut_ptr()); ++ Some(Ok(Entry(ent.assume_init()))) + } + } + ++/// Return type of [`Dir::iter`]. + #[derive(Debug, Eq, Hash, PartialEq)] + pub struct Iter<'d>(&'d mut Dir); + +@@ -96,25 +133,7 @@ impl<'d> Iterator for Iter<'d> { + type Item = Result; + + fn next(&mut self) -> Option { +- unsafe { +- // Note: POSIX specifies that portable applications should dynamically allocate a +- // buffer with room for a `d_name` field of size `pathconf(..., _PC_NAME_MAX)` plus 1 +- // for the NUL byte. It doesn't look like the std library does this; it just uses +- // fixed-sized buffers (and libc's dirent seems to be sized so this is appropriate). +- // Probably fine here too then. +- let mut ent = std::mem::MaybeUninit::::uninit(); +- let mut result = ptr::null_mut(); +- if let Err(e) = Errno::result( +- readdir_r((self.0).0.as_ptr(), ent.as_mut_ptr(), &mut result)) +- { +- return Some(Err(e)); +- } +- if result.is_null() { +- return None; +- } +- assert_eq!(result, ent.as_mut_ptr()); +- Some(Ok(Entry(ent.assume_init()))) +- } ++ next(self.0) + } + } + +@@ -124,6 +143,51 @@ impl<'d> Drop for Iter<'d> { + } + } + ++/// The return type of [Dir::into_iter] ++#[derive(Debug, Eq, Hash, PartialEq)] ++pub struct OwningIter(Dir); ++ ++impl Iterator for OwningIter { ++ type Item = Result; ++ ++ fn next(&mut self) -> Option { ++ next(&mut self.0) ++ } ++} ++ ++/// The file descriptor continues to be owned by the `OwningIter`, ++/// so callers must not keep a `RawFd` after the `OwningIter` is dropped. ++impl AsRawFd for OwningIter { ++ fn as_raw_fd(&self) -> RawFd { ++ self.0.as_raw_fd() ++ } ++} ++ ++impl IntoIterator for Dir { ++ type Item = Result; ++ type IntoIter = OwningIter; ++ ++ /// Creates a owning iterator, that is, one that takes ownership of the ++ /// `Dir`. The `Dir` cannot be used after calling this. This can be useful ++ /// when you have a function that both creates a `Dir` instance and returns ++ /// an `Iterator`. ++ /// ++ /// Example: ++ /// ++ /// ``` ++ /// use nix::{dir::Dir, fcntl::OFlag, sys::stat::Mode}; ++ /// use std::{iter::Iterator, string::String}; ++ /// ++ /// fn ls_upper(dirname: &str) -> impl Iterator { ++ /// let d = Dir::open(dirname, OFlag::O_DIRECTORY, Mode::S_IXUSR).unwrap(); ++ /// d.into_iter().map(|x| x.unwrap().file_name().as_ref().to_string_lossy().to_ascii_uppercase()) ++ /// } ++ /// ``` ++ fn into_iter(self) -> Self::IntoIter { ++ OwningIter(self) ++ } ++} ++ + /// A directory entry, similar to `std::fs::DirEntry`. + /// + /// Note that unlike the std version, this may represent the `.` or `..` entries. +@@ -131,44 +195,47 @@ impl<'d> Drop for Iter<'d> { + #[repr(transparent)] + pub struct Entry(dirent); + ++/// Type of file referenced by a directory entry + #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] + pub enum Type { ++ /// FIFO (Named pipe) + Fifo, ++ /// Character device + CharacterDevice, ++ /// Directory + Directory, ++ /// Block device + BlockDevice, ++ /// Regular file + File, ++ /// Symbolic link + Symlink, ++ /// Unix-domain socket + Socket, + } + + impl Entry { + /// Returns the inode number (`d_ino`) of the underlying `dirent`. +- #[cfg(any(target_os = "android", +- target_os = "emscripten", +- target_os = "fuchsia", +- target_os = "haiku", +- target_os = "ios", +- target_os = "l4re", +- target_os = "linux", +- target_os = "macos", +- target_os = "solaris"))] ++ #[allow(clippy::useless_conversion)] // Not useless on all OSes ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] + pub fn ino(&self) -> u64 { +- self.0.d_ino as u64 +- } +- +- /// Returns the inode number (`d_fileno`) of the underlying `dirent`. +- #[cfg(not(any(target_os = "android", +- target_os = "emscripten", +- target_os = "fuchsia", +- target_os = "haiku", +- target_os = "ios", +- target_os = "l4re", +- target_os = "linux", +- target_os = "macos", +- target_os = "solaris")))] +- pub fn ino(&self) -> u64 { +- u64::from(self.0.d_fileno) ++ cfg_if! { ++ if #[cfg(any(target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "haiku", ++ target_os = "illumos", ++ target_os = "ios", ++ target_os = "l4re", ++ target_os = "linux", ++ target_os = "macos", ++ target_os = "solaris"))] { ++ self.0.d_ino as u64 ++ } else { ++ u64::from(self.0.d_fileno) ++ } ++ } + } + + /// Returns the bare file name of this directory entry without any other leading path component. +@@ -182,6 +249,11 @@ impl Entry { + /// notably, some Linux filesystems don't implement this. The caller should use `stat` or + /// `fstat` if this returns `None`. + pub fn file_type(&self) -> Option { ++ #[cfg(not(any( ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "haiku" ++ )))] + match self.0.d_type { + libc::DT_FIFO => Some(Type::Fifo), + libc::DT_CHR => Some(Type::CharacterDevice), +@@ -192,5 +264,13 @@ impl Entry { + libc::DT_SOCK => Some(Type::Socket), + /* libc::DT_UNKNOWN | */ _ => None, + } ++ ++ // illumos, Solaris, and Haiku systems do not have the d_type member at all: ++ #[cfg(any( ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "haiku" ++ ))] ++ None + } + } +diff --git a/vendor/nix/src/env.rs b/vendor/nix/src/env.rs +new file mode 100644 +index 0000000..95177a1 +--- /dev/null ++++ b/vendor/nix/src/env.rs +@@ -0,0 +1,64 @@ ++//! Environment variables ++use cfg_if::cfg_if; ++use std::fmt; ++ ++/// Indicates that [`clearenv`] failed for some unknown reason ++#[derive(Clone, Copy, Debug)] ++pub struct ClearEnvError; ++ ++impl fmt::Display for ClearEnvError { ++ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ++ write!(f, "clearenv failed") ++ } ++} ++ ++impl std::error::Error for ClearEnvError {} ++ ++/// Clear the environment of all name-value pairs. ++/// ++/// On platforms where libc provides `clearenv()`, it will be used. libc's ++/// `clearenv()` is documented to return an error code but not set errno; if the ++/// return value indicates a failure, this function will return ++/// [`ClearEnvError`]. ++/// ++/// On platforms where libc does not provide `clearenv()`, a fallback ++/// implementation will be used that iterates over all environment variables and ++/// removes them one-by-one. ++/// ++/// # Safety ++/// ++/// This function is not threadsafe and can cause undefined behavior in ++/// combination with `std::env` or other program components that access the ++/// environment. See, for example, the discussion on `std::env::remove_var`; this ++/// function is a case of an "inherently unsafe non-threadsafe API" dealing with ++/// the environment. ++/// ++/// The caller must ensure no other threads access the process environment while ++/// this function executes and that no raw pointers to an element of libc's ++/// `environ` is currently held. The latter is not an issue if the only other ++/// environment access in the program is via `std::env`, but the requirement on ++/// thread safety must still be upheld. ++pub unsafe fn clearenv() -> std::result::Result<(), ClearEnvError> { ++ cfg_if! { ++ if #[cfg(any(target_os = "fuchsia", ++ target_os = "wasi", ++ target_env = "uclibc", ++ target_os = "linux", ++ target_os = "android", ++ target_os = "emscripten"))] { ++ let ret = libc::clearenv(); ++ } else { ++ use std::env; ++ for (name, _) in env::vars_os() { ++ env::remove_var(name); ++ } ++ let ret = 0; ++ } ++ } ++ ++ if ret == 0 { ++ Ok(()) ++ } else { ++ Err(ClearEnvError) ++ } ++} +diff --git a/vendor/nix/src/errno.rs b/vendor/nix/src/errno.rs +index a8a2bf2..d8ad28d 100644 +--- a/vendor/nix/src/errno.rs ++++ b/vendor/nix/src/errno.rs +@@ -1,8 +1,8 @@ +-#[cfg(not(target_os = "dragonfly"))] +-use libc; ++use crate::Result; ++use cfg_if::cfg_if; + use libc::{c_int, c_void}; +-use std::{fmt, io, error}; +-use {Error, Result}; ++use std::convert::TryFrom; ++use std::{error, fmt, io}; + + pub use self::consts::*; + +@@ -13,48 +13,41 @@ cfg_if! { + unsafe fn errno_location() -> *mut c_int { + libc::__error() + } +- } else if #[cfg(target_os = "dragonfly")] { +- // DragonFly uses a thread-local errno variable, but #[thread_local] is +- // feature-gated and not available in stable Rust as of this writing +- // (Rust 1.21.0). We have to use a C extension to access it +- // (src/errno_dragonfly.c). +- // +- // Tracking issue for `thread_local` stabilization: +- // +- // https://github.com/rust-lang/rust/issues/29594 +- // +- // Once this becomes stable, we can remove build.rs, +- // src/errno_dragonfly.c, and use: +- // +- // extern { #[thread_local] static errno: c_int; } +- // +- #[link(name="errno_dragonfly", kind="static")] +- extern { +- pub fn errno_location() -> *mut c_int; +- } + } else if #[cfg(any(target_os = "android", + target_os = "netbsd", + target_os = "openbsd"))] { + unsafe fn errno_location() -> *mut c_int { + libc::__errno() + } +- } else if #[cfg(target_os = "linux")] { ++ } else if #[cfg(any(target_os = "linux", ++ target_os = "redox", ++ target_os = "dragonfly", ++ target_os = "fuchsia"))] { + unsafe fn errno_location() -> *mut c_int { + libc::__errno_location() + } ++ } else if #[cfg(any(target_os = "illumos", target_os = "solaris"))] { ++ unsafe fn errno_location() -> *mut c_int { ++ libc::___errno() ++ } ++ } else if #[cfg(any(target_os = "haiku",))] { ++ unsafe fn errno_location() -> *mut c_int { ++ libc::_errnop() ++ } + } + } + + /// Sets the platform-specific errno to no-error +-unsafe fn clear() { +- *errno_location() = 0; ++fn clear() { ++ // Safe because errno is a thread-local variable ++ unsafe { ++ *errno_location() = 0; ++ } + } + + /// Returns the platform-specific value of errno + pub fn errno() -> i32 { +- unsafe { +- (*errno_location()) as i32 +- } ++ unsafe { *errno_location() } + } + + impl Errno { +@@ -66,19 +59,20 @@ impl Errno { + desc(self) + } + +- pub fn from_i32(err: i32) -> Errno { ++ pub const fn from_i32(err: i32) -> Errno { + from_i32(err) + } + +- pub unsafe fn clear() { ++ pub fn clear() { + clear() + } + + /// Returns `Ok(value)` if it does not contain the sentinel value. This + /// should not be used when `-1` is not the errno sentinel value. ++ #[inline] + pub fn result>(value: S) -> Result { + if value == S::sentinel() { +- Err(Error::Sys(Self::last())) ++ Err(Self::last()) + } else { + Ok(value) + } +@@ -92,23 +86,33 @@ pub trait ErrnoSentinel: Sized { + } + + impl ErrnoSentinel for isize { +- fn sentinel() -> Self { -1 } ++ fn sentinel() -> Self { ++ -1 ++ } + } + + impl ErrnoSentinel for i32 { +- fn sentinel() -> Self { -1 } ++ fn sentinel() -> Self { ++ -1 ++ } + } + + impl ErrnoSentinel for i64 { +- fn sentinel() -> Self { -1 } ++ fn sentinel() -> Self { ++ -1 ++ } + } + + impl ErrnoSentinel for *mut c_void { +- fn sentinel() -> Self { (-1 as isize) as *mut c_void } ++ fn sentinel() -> Self { ++ -1isize as *mut c_void ++ } + } + + impl ErrnoSentinel for libc::sighandler_t { +- fn sentinel() -> Self { libc::SIG_ERR } ++ fn sentinel() -> Self { ++ libc::SIG_ERR ++ } + } + + impl error::Error for Errno {} +@@ -125,6 +129,14 @@ impl From for io::Error { + } + } + ++impl TryFrom for Errno { ++ type Error = io::Error; ++ ++ fn try_from(ioerror: io::Error) -> std::result::Result { ++ ioerror.raw_os_error().map(Errno::from_i32).ok_or(ioerror) ++ } ++} ++ + fn last() -> Errno { + Errno::from_i32(errno()) + } +@@ -132,591 +144,1126 @@ fn last() -> Errno { + fn desc(errno: Errno) -> &'static str { + use self::Errno::*; + match errno { +- UnknownErrno => "Unknown errno", +- EPERM => "Operation not permitted", +- ENOENT => "No such file or directory", +- ESRCH => "No such process", +- EINTR => "Interrupted system call", +- EIO => "I/O error", +- ENXIO => "No such device or address", +- E2BIG => "Argument list too long", +- ENOEXEC => "Exec format error", +- EBADF => "Bad file number", +- ECHILD => "No child processes", +- EAGAIN => "Try again", +- ENOMEM => "Out of memory", +- EACCES => "Permission denied", +- EFAULT => "Bad address", +- ENOTBLK => "Block device required", +- EBUSY => "Device or resource busy", +- EEXIST => "File exists", +- EXDEV => "Cross-device link", +- ENODEV => "No such device", +- ENOTDIR => "Not a directory", +- EISDIR => "Is a directory", +- EINVAL => "Invalid argument", +- ENFILE => "File table overflow", +- EMFILE => "Too many open files", +- ENOTTY => "Not a typewriter", +- ETXTBSY => "Text file busy", +- EFBIG => "File too large", +- ENOSPC => "No space left on device", +- ESPIPE => "Illegal seek", +- EROFS => "Read-only file system", +- EMLINK => "Too many links", +- EPIPE => "Broken pipe", +- EDOM => "Math argument out of domain of func", +- ERANGE => "Math result not representable", +- EDEADLK => "Resource deadlock would occur", +- ENAMETOOLONG => "File name too long", +- ENOLCK => "No record locks available", +- ENOSYS => "Function not implemented", +- ENOTEMPTY => "Directory not empty", +- ELOOP => "Too many symbolic links encountered", +- ENOMSG => "No message of desired type", +- EIDRM => "Identifier removed", +- EINPROGRESS => "Operation now in progress", +- EALREADY => "Operation already in progress", +- ENOTSOCK => "Socket operation on non-socket", +- EDESTADDRREQ => "Destination address required", +- EMSGSIZE => "Message too long", +- EPROTOTYPE => "Protocol wrong type for socket", +- ENOPROTOOPT => "Protocol not available", ++ UnknownErrno => "Unknown errno", ++ EPERM => "Operation not permitted", ++ ENOENT => "No such file or directory", ++ ESRCH => "No such process", ++ EINTR => "Interrupted system call", ++ EIO => "I/O error", ++ ENXIO => "No such device or address", ++ E2BIG => "Argument list too long", ++ ENOEXEC => "Exec format error", ++ EBADF => "Bad file number", ++ ECHILD => "No child processes", ++ EAGAIN => "Try again", ++ ENOMEM => "Out of memory", ++ EACCES => "Permission denied", ++ EFAULT => "Bad address", ++ #[cfg(not(target_os = "haiku"))] ++ ENOTBLK => "Block device required", ++ EBUSY => "Device or resource busy", ++ EEXIST => "File exists", ++ EXDEV => "Cross-device link", ++ ENODEV => "No such device", ++ ENOTDIR => "Not a directory", ++ EISDIR => "Is a directory", ++ EINVAL => "Invalid argument", ++ ENFILE => "File table overflow", ++ EMFILE => "Too many open files", ++ ENOTTY => "Not a typewriter", ++ ETXTBSY => "Text file busy", ++ EFBIG => "File too large", ++ ENOSPC => "No space left on device", ++ ESPIPE => "Illegal seek", ++ EROFS => "Read-only file system", ++ EMLINK => "Too many links", ++ EPIPE => "Broken pipe", ++ EDOM => "Math argument out of domain of func", ++ ERANGE => "Math result not representable", ++ EDEADLK => "Resource deadlock would occur", ++ ENAMETOOLONG => "File name too long", ++ ENOLCK => "No record locks available", ++ ENOSYS => "Function not implemented", ++ ENOTEMPTY => "Directory not empty", ++ ELOOP => "Too many symbolic links encountered", ++ ENOMSG => "No message of desired type", ++ EIDRM => "Identifier removed", ++ EINPROGRESS => "Operation now in progress", ++ EALREADY => "Operation already in progress", ++ ENOTSOCK => "Socket operation on non-socket", ++ EDESTADDRREQ => "Destination address required", ++ EMSGSIZE => "Message too long", ++ EPROTOTYPE => "Protocol wrong type for socket", ++ ENOPROTOOPT => "Protocol not available", + EPROTONOSUPPORT => "Protocol not supported", ++ #[cfg(not(target_os = "haiku"))] + ESOCKTNOSUPPORT => "Socket type not supported", +- EPFNOSUPPORT => "Protocol family not supported", +- EAFNOSUPPORT => "Address family not supported by protocol", +- EADDRINUSE => "Address already in use", +- EADDRNOTAVAIL => "Cannot assign requested address", +- ENETDOWN => "Network is down", +- ENETUNREACH => "Network is unreachable", +- ENETRESET => "Network dropped connection because of reset", +- ECONNABORTED => "Software caused connection abort", +- ECONNRESET => "Connection reset by peer", +- ENOBUFS => "No buffer space available", +- EISCONN => "Transport endpoint is already connected", +- ENOTCONN => "Transport endpoint is not connected", +- ESHUTDOWN => "Cannot send after transport endpoint shutdown", +- ETOOMANYREFS => "Too many references: cannot splice", +- ETIMEDOUT => "Connection timed out", +- ECONNREFUSED => "Connection refused", +- EHOSTDOWN => "Host is down", +- EHOSTUNREACH => "No route to host", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ECHRNG => "Channel number out of range", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EL2NSYNC => "Level 2 not synchronized", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EL3HLT => "Level 3 halted", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EL3RST => "Level 3 reset", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ELNRNG => "Link number out of range", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EUNATCH => "Protocol driver not attached", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ENOCSI => "No CSI structure available", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EL2HLT => "Level 2 halted", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EBADE => "Invalid exchange", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EBADR => "Invalid request descriptor", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EXFULL => "Exchange full", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ENOANO => "No anode", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EBADRQC => "Invalid request code", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EBADSLT => "Invalid slot", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EBFONT => "Bad font file format", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ENOSTR => "Device not a stream", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ENODATA => "No data available", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ETIME => "Timer expired", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ENOSR => "Out of streams resources", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ENONET => "Machine is not on the network", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ENOPKG => "Package not installed", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EREMOTE => "Object is remote", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ENOLINK => "Link has been severed", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EADV => "Advertise error", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ESRMNT => "Srmount error", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ECOMM => "Communication error on send", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EPROTO => "Protocol error", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EMULTIHOP => "Multihop attempted", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EDOTDOT => "RFS specific error", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EBADMSG => "Not a data message", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EOVERFLOW => "Value too large for defined data type", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ENOTUNIQ => "Name not unique on network", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EBADFD => "File descriptor in bad state", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EREMCHG => "Remote address changed", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ELIBACC => "Can not access a needed shared library", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ELIBBAD => "Accessing a corrupted shared library", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ELIBSCN => ".lib section in a.out corrupted", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ELIBMAX => "Attempting to link in too many shared libraries", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ELIBEXEC => "Cannot exec a shared library directly", +- +- #[cfg(any(target_os = "linux", target_os = "android", target_os = "openbsd"))] +- EILSEQ => "Illegal byte sequence", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ERESTART => "Interrupted system call should be restarted", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ESTRPIPE => "Streams pipe error", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EUSERS => "Too many users", +- +- #[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))] +- EOPNOTSUPP => "Operation not supported on transport endpoint", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ESTALE => "Stale file handle", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EUCLEAN => "Structure needs cleaning", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ENOTNAM => "Not a XENIX named type file", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ENAVAIL => "No XENIX semaphores available", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EISNAM => "Is a named type file", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EREMOTEIO => "Remote I/O error", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EDQUOT => "Quota exceeded", +- +- #[cfg(any(target_os = "linux", target_os = "android", +- target_os = "openbsd", target_os = "dragonfly"))] +- ENOMEDIUM => "No medium found", +- +- #[cfg(any(target_os = "linux", target_os = "android", target_os = "openbsd"))] +- EMEDIUMTYPE => "Wrong medium type", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ECANCELED => "Operation canceled", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- ENOKEY => "Required key not available", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EKEYEXPIRED => "Key has expired", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EKEYREVOKED => "Key has been revoked", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EKEYREJECTED => "Key was rejected by service", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] +- EOWNERDEAD => "Owner died", +- +- #[cfg(any(target_os = "linux", target_os = "android"))] ++ #[cfg(not(target_os = "haiku"))] ++ EPFNOSUPPORT => "Protocol family not supported", ++ #[cfg(not(target_os = "haiku"))] ++ EAFNOSUPPORT => "Address family not supported by protocol", ++ EADDRINUSE => "Address already in use", ++ EADDRNOTAVAIL => "Cannot assign requested address", ++ ENETDOWN => "Network is down", ++ ENETUNREACH => "Network is unreachable", ++ ENETRESET => "Network dropped connection because of reset", ++ ECONNABORTED => "Software caused connection abort", ++ ECONNRESET => "Connection reset by peer", ++ ENOBUFS => "No buffer space available", ++ EISCONN => "Transport endpoint is already connected", ++ ENOTCONN => "Transport endpoint is not connected", ++ ESHUTDOWN => "Cannot send after transport endpoint shutdown", ++ #[cfg(not(target_os = "haiku"))] ++ ETOOMANYREFS => "Too many references: cannot splice", ++ ETIMEDOUT => "Connection timed out", ++ ECONNREFUSED => "Connection refused", ++ EHOSTDOWN => "Host is down", ++ EHOSTUNREACH => "No route to host", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ECHRNG => "Channel number out of range", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EL2NSYNC => "Level 2 not synchronized", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EL3HLT => "Level 3 halted", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EL3RST => "Level 3 reset", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ELNRNG => "Link number out of range", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EUNATCH => "Protocol driver not attached", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ENOCSI => "No CSI structure available", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EL2HLT => "Level 2 halted", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EBADE => "Invalid exchange", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EBADR => "Invalid request descriptor", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EXFULL => "Exchange full", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ENOANO => "No anode", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EBADRQC => "Invalid request code", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EBADSLT => "Invalid slot", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EBFONT => "Bad font file format", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ENOSTR => "Device not a stream", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ENODATA => "No data available", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ETIME => "Timer expired", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ENOSR => "Out of streams resources", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ENONET => "Machine is not on the network", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ENOPKG => "Package not installed", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EREMOTE => "Object is remote", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ENOLINK => "Link has been severed", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EADV => "Advertise error", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ESRMNT => "Srmount error", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ECOMM => "Communication error on send", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EPROTO => "Protocol error", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EMULTIHOP => "Multihop attempted", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia" ++ ))] ++ EDOTDOT => "RFS specific error", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia" ++ ))] ++ EBADMSG => "Not a data message", ++ ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ EBADMSG => "Trying to read unreadable message", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia", ++ target_os = "haiku" ++ ))] ++ EOVERFLOW => "Value too large for defined data type", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ENOTUNIQ => "Name not unique on network", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EBADFD => "File descriptor in bad state", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EREMCHG => "Remote address changed", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ELIBACC => "Can not access a needed shared library", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ELIBBAD => "Accessing a corrupted shared library", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ELIBSCN => ".lib section in a.out corrupted", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ELIBMAX => "Attempting to link in too many shared libraries", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ELIBEXEC => "Cannot exec a shared library directly", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia", ++ target_os = "openbsd" ++ ))] ++ EILSEQ => "Illegal byte sequence", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ERESTART => "Interrupted system call should be restarted", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ ESTRPIPE => "Streams pipe error", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia" ++ ))] ++ EUSERS => "Too many users", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia", ++ target_os = "netbsd", ++ target_os = "redox" ++ ))] ++ EOPNOTSUPP => "Operation not supported on transport endpoint", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia" ++ ))] ++ ESTALE => "Stale file handle", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia" ++ ))] ++ EUCLEAN => "Structure needs cleaning", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia" ++ ))] ++ ENOTNAM => "Not a XENIX named type file", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia" ++ ))] ++ ENAVAIL => "No XENIX semaphores available", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia" ++ ))] ++ EISNAM => "Is a named type file", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia" ++ ))] ++ EREMOTEIO => "Remote I/O error", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia" ++ ))] ++ EDQUOT => "Quota exceeded", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia", ++ target_os = "openbsd", ++ target_os = "dragonfly" ++ ))] ++ ENOMEDIUM => "No medium found", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia", ++ target_os = "openbsd" ++ ))] ++ EMEDIUMTYPE => "Wrong medium type", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "fuchsia", ++ target_os = "haiku" ++ ))] ++ ECANCELED => "Operation canceled", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia" ++ ))] ++ ENOKEY => "Required key not available", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia" ++ ))] ++ EKEYEXPIRED => "Key has expired", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia" ++ ))] ++ EKEYREVOKED => "Key has been revoked", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia" ++ ))] ++ EKEYREJECTED => "Key was rejected by service", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia" ++ ))] ++ EOWNERDEAD => "Owner died", ++ ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ EOWNERDEAD => "Process died with lock", ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia" ++ ))] + ENOTRECOVERABLE => "State not recoverable", + +- #[cfg(all(target_os = "linux", not(target_arch="mips")))] +- ERFKILL => "Operation not possible due to RF-kill", +- +- #[cfg(all(target_os = "linux", not(target_arch="mips")))] +- EHWPOISON => "Memory page has hardware error", ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ ENOTRECOVERABLE => "Lock is not recoverable", + +- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] +- EDOOFUS => "Programming error", ++ #[cfg(any( ++ all(target_os = "linux", not(target_arch = "mips")), ++ target_os = "fuchsia" ++ ))] ++ ERFKILL => "Operation not possible due to RF-kill", + +- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] +- EMULTIHOP => "Multihop attempted", ++ #[cfg(any( ++ all(target_os = "linux", not(target_arch = "mips")), ++ target_os = "fuchsia" ++ ))] ++ EHWPOISON => "Memory page has hardware error", + + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] +- ENOLINK => "Link has been severed", ++ EDOOFUS => "Programming error", ++ ++ #[cfg(any( ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "redox" ++ ))] ++ EMULTIHOP => "Multihop attempted", ++ ++ #[cfg(any( ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "redox" ++ ))] ++ ENOLINK => "Link has been severed", + + #[cfg(target_os = "freebsd")] +- ENOTCAPABLE => "Capabilities insufficient", ++ ENOTCAPABLE => "Capabilities insufficient", + + #[cfg(target_os = "freebsd")] +- ECAPMODE => "Not permitted in capability mode", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- ENEEDAUTH => "Need authenticator", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- EOVERFLOW => "Value too large to be stored in data type", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "netbsd"))] +- EILSEQ => "Illegal byte sequence", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- ENOATTR => "Attribute not found", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- EBADMSG => "Bad message", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- EPROTO => "Protocol error", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "ios", target_os = "openbsd", ))] ++ ECAPMODE => "Not permitted in capability mode", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd" ++ ))] ++ ENEEDAUTH => "Need authenticator", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "redox", ++ target_os = "illumos", ++ target_os = "solaris" ++ ))] ++ EOVERFLOW => "Value too large to be stored in data type", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "netbsd", ++ target_os = "redox", ++ target_os = "haiku" ++ ))] ++ EILSEQ => "Illegal byte sequence", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "haiku" ++ ))] ++ ENOATTR => "Attribute not found", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "redox", ++ target_os = "haiku" ++ ))] ++ EBADMSG => "Bad message", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "redox", ++ target_os = "haiku" ++ ))] ++ EPROTO => "Protocol error", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd" ++ ))] + ENOTRECOVERABLE => "State not recoverable", + +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "ios", target_os = "openbsd"))] +- EOWNERDEAD => "Previous owner died", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- ENOTSUP => "Operation not supported", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- EPROCLIM => "Too many processes", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- EUSERS => "Too many users", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- EDQUOT => "Disc quota exceeded", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- ESTALE => "Stale NFS file handle", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- EREMOTE => "Too many levels of remote in path", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- EBADRPC => "RPC struct is bad", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- ERPCMISMATCH => "RPC version wrong", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- EPROGUNAVAIL => "RPC prog. not avail", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- EPROGMISMATCH => "Program version wrong", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- EPROCUNAVAIL => "Bad procedure for program", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- EFTYPE => "Inappropriate file type or format", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- EAUTH => "Authentication error", +- +- #[cfg(any(target_os = "macos", target_os = "freebsd", +- target_os = "dragonfly", target_os = "ios", +- target_os = "openbsd", target_os = "netbsd"))] +- ECANCELED => "Operation canceled", ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd" ++ ))] ++ EOWNERDEAD => "Previous owner died", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "haiku" ++ ))] ++ ENOTSUP => "Operation not supported", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd" ++ ))] ++ EPROCLIM => "Too many processes", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "redox" ++ ))] ++ EUSERS => "Too many users", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "redox", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "haiku" ++ ))] ++ EDQUOT => "Disc quota exceeded", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "redox", ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "haiku" ++ ))] ++ ESTALE => "Stale NFS file handle", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "redox" ++ ))] ++ EREMOTE => "Too many levels of remote in path", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd" ++ ))] ++ EBADRPC => "RPC struct is bad", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd" ++ ))] ++ ERPCMISMATCH => "RPC version wrong", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd" ++ ))] ++ EPROGUNAVAIL => "RPC prog. not avail", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd" ++ ))] ++ EPROGMISMATCH => "Program version wrong", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd" ++ ))] ++ EPROCUNAVAIL => "Bad procedure for program", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd" ++ ))] ++ EFTYPE => "Inappropriate file type or format", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd" ++ ))] ++ EAUTH => "Authentication error", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "redox" ++ ))] ++ ECANCELED => "Operation canceled", + + #[cfg(any(target_os = "macos", target_os = "ios"))] +- EPWROFF => "Device power is off", ++ EPWROFF => "Device power is off", + + #[cfg(any(target_os = "macos", target_os = "ios"))] +- EDEVERR => "Device error, e.g. paper out", ++ EDEVERR => "Device error, e.g. paper out", + + #[cfg(any(target_os = "macos", target_os = "ios"))] +- EBADEXEC => "Bad executable", ++ EBADEXEC => "Bad executable", + + #[cfg(any(target_os = "macos", target_os = "ios"))] +- EBADARCH => "Bad CPU type in executable", ++ EBADARCH => "Bad CPU type in executable", + + #[cfg(any(target_os = "macos", target_os = "ios"))] +- ESHLIBVERS => "Shared library version mismatch", ++ ESHLIBVERS => "Shared library version mismatch", + + #[cfg(any(target_os = "macos", target_os = "ios"))] +- EBADMACHO => "Malformed Macho file", +- +- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))] +- EMULTIHOP => "Reserved", +- +- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))] +- ENODATA => "No message available on STREAM", +- +- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))] +- ENOLINK => "Reserved", +- +- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))] +- ENOSR => "No STREAM resources", +- +- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))] +- ENOSTR => "Not a STREAM", +- +- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))] +- ETIME => "STREAM ioctl timeout", ++ EBADMACHO => "Malformed Macho file", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "netbsd", ++ target_os = "haiku" ++ ))] ++ EMULTIHOP => "Reserved", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "netbsd", ++ target_os = "redox" ++ ))] ++ ENODATA => "No message available on STREAM", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "netbsd", ++ target_os = "haiku" ++ ))] ++ ENOLINK => "Reserved", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "netbsd", ++ target_os = "redox" ++ ))] ++ ENOSR => "No STREAM resources", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "netbsd", ++ target_os = "redox" ++ ))] ++ ENOSTR => "Not a STREAM", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "netbsd", ++ target_os = "redox" ++ ))] ++ ETIME => "STREAM ioctl timeout", ++ ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "illumos", ++ target_os = "solaris" ++ ))] ++ EOPNOTSUPP => "Operation not supported on socket", + + #[cfg(any(target_os = "macos", target_os = "ios"))] +- EOPNOTSUPP => "Operation not supported on socket", ++ ENOPOLICY => "No such policy registered", + + #[cfg(any(target_os = "macos", target_os = "ios"))] +- ENOPOLICY => "No such policy registered", +- +- #[cfg(any(target_os = "macos", target_os = "ios"))] +- EQFULL => "Interface output queue is full", ++ EQFULL => "Interface output queue is full", + + #[cfg(target_os = "openbsd")] +- EOPNOTSUPP => "Operation not supported", ++ EOPNOTSUPP => "Operation not supported", + + #[cfg(target_os = "openbsd")] +- EIPSEC => "IPsec processing failure", ++ EIPSEC => "IPsec processing failure", + + #[cfg(target_os = "dragonfly")] +- EASYNC => "Async", ++ EASYNC => "Async", ++ ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ EDEADLOCK => "Resource deadlock would occur", ++ ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ ELOCKUNMAPPED => "Locked lock was unmapped", ++ ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ ENOTACTIVE => "Facility is not active", + } + } + +-#[cfg(any(target_os = "linux", target_os = "android"))] ++#[cfg(any(target_os = "linux", target_os = "android", target_os = "fuchsia"))] + mod consts { +- use libc; +- + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + #[repr(i32)] ++ #[non_exhaustive] + pub enum Errno { +- UnknownErrno = 0, +- EPERM = libc::EPERM, +- ENOENT = libc::ENOENT, +- ESRCH = libc::ESRCH, +- EINTR = libc::EINTR, +- EIO = libc::EIO, +- ENXIO = libc::ENXIO, +- E2BIG = libc::E2BIG, +- ENOEXEC = libc::ENOEXEC, +- EBADF = libc::EBADF, +- ECHILD = libc::ECHILD, +- EAGAIN = libc::EAGAIN, +- ENOMEM = libc::ENOMEM, +- EACCES = libc::EACCES, +- EFAULT = libc::EFAULT, +- ENOTBLK = libc::ENOTBLK, +- EBUSY = libc::EBUSY, +- EEXIST = libc::EEXIST, +- EXDEV = libc::EXDEV, +- ENODEV = libc::ENODEV, +- ENOTDIR = libc::ENOTDIR, +- EISDIR = libc::EISDIR, +- EINVAL = libc::EINVAL, +- ENFILE = libc::ENFILE, +- EMFILE = libc::EMFILE, +- ENOTTY = libc::ENOTTY, +- ETXTBSY = libc::ETXTBSY, +- EFBIG = libc::EFBIG, +- ENOSPC = libc::ENOSPC, +- ESPIPE = libc::ESPIPE, +- EROFS = libc::EROFS, +- EMLINK = libc::EMLINK, +- EPIPE = libc::EPIPE, +- EDOM = libc::EDOM, +- ERANGE = libc::ERANGE, +- EDEADLK = libc::EDEADLK, +- ENAMETOOLONG = libc::ENAMETOOLONG, +- ENOLCK = libc::ENOLCK, +- ENOSYS = libc::ENOSYS, +- ENOTEMPTY = libc::ENOTEMPTY, +- ELOOP = libc::ELOOP, +- ENOMSG = libc::ENOMSG, +- EIDRM = libc::EIDRM, +- ECHRNG = libc::ECHRNG, +- EL2NSYNC = libc::EL2NSYNC, +- EL3HLT = libc::EL3HLT, +- EL3RST = libc::EL3RST, +- ELNRNG = libc::ELNRNG, +- EUNATCH = libc::EUNATCH, +- ENOCSI = libc::ENOCSI, +- EL2HLT = libc::EL2HLT, +- EBADE = libc::EBADE, +- EBADR = libc::EBADR, +- EXFULL = libc::EXFULL, +- ENOANO = libc::ENOANO, +- EBADRQC = libc::EBADRQC, +- EBADSLT = libc::EBADSLT, +- EBFONT = libc::EBFONT, +- ENOSTR = libc::ENOSTR, +- ENODATA = libc::ENODATA, +- ETIME = libc::ETIME, +- ENOSR = libc::ENOSR, +- ENONET = libc::ENONET, +- ENOPKG = libc::ENOPKG, +- EREMOTE = libc::EREMOTE, +- ENOLINK = libc::ENOLINK, +- EADV = libc::EADV, +- ESRMNT = libc::ESRMNT, +- ECOMM = libc::ECOMM, +- EPROTO = libc::EPROTO, +- EMULTIHOP = libc::EMULTIHOP, +- EDOTDOT = libc::EDOTDOT, +- EBADMSG = libc::EBADMSG, +- EOVERFLOW = libc::EOVERFLOW, +- ENOTUNIQ = libc::ENOTUNIQ, +- EBADFD = libc::EBADFD, +- EREMCHG = libc::EREMCHG, +- ELIBACC = libc::ELIBACC, +- ELIBBAD = libc::ELIBBAD, +- ELIBSCN = libc::ELIBSCN, +- ELIBMAX = libc::ELIBMAX, +- ELIBEXEC = libc::ELIBEXEC, +- EILSEQ = libc::EILSEQ, +- ERESTART = libc::ERESTART, +- ESTRPIPE = libc::ESTRPIPE, +- EUSERS = libc::EUSERS, +- ENOTSOCK = libc::ENOTSOCK, +- EDESTADDRREQ = libc::EDESTADDRREQ, +- EMSGSIZE = libc::EMSGSIZE, +- EPROTOTYPE = libc::EPROTOTYPE, +- ENOPROTOOPT = libc::ENOPROTOOPT, ++ UnknownErrno = 0, ++ EPERM = libc::EPERM, ++ ENOENT = libc::ENOENT, ++ ESRCH = libc::ESRCH, ++ EINTR = libc::EINTR, ++ EIO = libc::EIO, ++ ENXIO = libc::ENXIO, ++ E2BIG = libc::E2BIG, ++ ENOEXEC = libc::ENOEXEC, ++ EBADF = libc::EBADF, ++ ECHILD = libc::ECHILD, ++ EAGAIN = libc::EAGAIN, ++ ENOMEM = libc::ENOMEM, ++ EACCES = libc::EACCES, ++ EFAULT = libc::EFAULT, ++ ENOTBLK = libc::ENOTBLK, ++ EBUSY = libc::EBUSY, ++ EEXIST = libc::EEXIST, ++ EXDEV = libc::EXDEV, ++ ENODEV = libc::ENODEV, ++ ENOTDIR = libc::ENOTDIR, ++ EISDIR = libc::EISDIR, ++ EINVAL = libc::EINVAL, ++ ENFILE = libc::ENFILE, ++ EMFILE = libc::EMFILE, ++ ENOTTY = libc::ENOTTY, ++ ETXTBSY = libc::ETXTBSY, ++ EFBIG = libc::EFBIG, ++ ENOSPC = libc::ENOSPC, ++ ESPIPE = libc::ESPIPE, ++ EROFS = libc::EROFS, ++ EMLINK = libc::EMLINK, ++ EPIPE = libc::EPIPE, ++ EDOM = libc::EDOM, ++ ERANGE = libc::ERANGE, ++ EDEADLK = libc::EDEADLK, ++ ENAMETOOLONG = libc::ENAMETOOLONG, ++ ENOLCK = libc::ENOLCK, ++ ENOSYS = libc::ENOSYS, ++ ENOTEMPTY = libc::ENOTEMPTY, ++ ELOOP = libc::ELOOP, ++ ENOMSG = libc::ENOMSG, ++ EIDRM = libc::EIDRM, ++ ECHRNG = libc::ECHRNG, ++ EL2NSYNC = libc::EL2NSYNC, ++ EL3HLT = libc::EL3HLT, ++ EL3RST = libc::EL3RST, ++ ELNRNG = libc::ELNRNG, ++ EUNATCH = libc::EUNATCH, ++ ENOCSI = libc::ENOCSI, ++ EL2HLT = libc::EL2HLT, ++ EBADE = libc::EBADE, ++ EBADR = libc::EBADR, ++ EXFULL = libc::EXFULL, ++ ENOANO = libc::ENOANO, ++ EBADRQC = libc::EBADRQC, ++ EBADSLT = libc::EBADSLT, ++ EBFONT = libc::EBFONT, ++ ENOSTR = libc::ENOSTR, ++ ENODATA = libc::ENODATA, ++ ETIME = libc::ETIME, ++ ENOSR = libc::ENOSR, ++ ENONET = libc::ENONET, ++ ENOPKG = libc::ENOPKG, ++ EREMOTE = libc::EREMOTE, ++ ENOLINK = libc::ENOLINK, ++ EADV = libc::EADV, ++ ESRMNT = libc::ESRMNT, ++ ECOMM = libc::ECOMM, ++ EPROTO = libc::EPROTO, ++ EMULTIHOP = libc::EMULTIHOP, ++ EDOTDOT = libc::EDOTDOT, ++ EBADMSG = libc::EBADMSG, ++ EOVERFLOW = libc::EOVERFLOW, ++ ENOTUNIQ = libc::ENOTUNIQ, ++ EBADFD = libc::EBADFD, ++ EREMCHG = libc::EREMCHG, ++ ELIBACC = libc::ELIBACC, ++ ELIBBAD = libc::ELIBBAD, ++ ELIBSCN = libc::ELIBSCN, ++ ELIBMAX = libc::ELIBMAX, ++ ELIBEXEC = libc::ELIBEXEC, ++ EILSEQ = libc::EILSEQ, ++ ERESTART = libc::ERESTART, ++ ESTRPIPE = libc::ESTRPIPE, ++ EUSERS = libc::EUSERS, ++ ENOTSOCK = libc::ENOTSOCK, ++ EDESTADDRREQ = libc::EDESTADDRREQ, ++ EMSGSIZE = libc::EMSGSIZE, ++ EPROTOTYPE = libc::EPROTOTYPE, ++ ENOPROTOOPT = libc::ENOPROTOOPT, + EPROTONOSUPPORT = libc::EPROTONOSUPPORT, + ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT, +- EOPNOTSUPP = libc::EOPNOTSUPP, +- EPFNOSUPPORT = libc::EPFNOSUPPORT, +- EAFNOSUPPORT = libc::EAFNOSUPPORT, +- EADDRINUSE = libc::EADDRINUSE, +- EADDRNOTAVAIL = libc::EADDRNOTAVAIL, +- ENETDOWN = libc::ENETDOWN, +- ENETUNREACH = libc::ENETUNREACH, +- ENETRESET = libc::ENETRESET, +- ECONNABORTED = libc::ECONNABORTED, +- ECONNRESET = libc::ECONNRESET, +- ENOBUFS = libc::ENOBUFS, +- EISCONN = libc::EISCONN, +- ENOTCONN = libc::ENOTCONN, +- ESHUTDOWN = libc::ESHUTDOWN, +- ETOOMANYREFS = libc::ETOOMANYREFS, +- ETIMEDOUT = libc::ETIMEDOUT, +- ECONNREFUSED = libc::ECONNREFUSED, +- EHOSTDOWN = libc::EHOSTDOWN, +- EHOSTUNREACH = libc::EHOSTUNREACH, +- EALREADY = libc::EALREADY, +- EINPROGRESS = libc::EINPROGRESS, +- ESTALE = libc::ESTALE, +- EUCLEAN = libc::EUCLEAN, +- ENOTNAM = libc::ENOTNAM, +- ENAVAIL = libc::ENAVAIL, +- EISNAM = libc::EISNAM, +- EREMOTEIO = libc::EREMOTEIO, +- EDQUOT = libc::EDQUOT, +- ENOMEDIUM = libc::ENOMEDIUM, +- EMEDIUMTYPE = libc::EMEDIUMTYPE, +- ECANCELED = libc::ECANCELED, +- ENOKEY = libc::ENOKEY, +- EKEYEXPIRED = libc::EKEYEXPIRED, +- EKEYREVOKED = libc::EKEYREVOKED, +- EKEYREJECTED = libc::EKEYREJECTED, +- EOWNERDEAD = libc::EOWNERDEAD, ++ EOPNOTSUPP = libc::EOPNOTSUPP, ++ EPFNOSUPPORT = libc::EPFNOSUPPORT, ++ EAFNOSUPPORT = libc::EAFNOSUPPORT, ++ EADDRINUSE = libc::EADDRINUSE, ++ EADDRNOTAVAIL = libc::EADDRNOTAVAIL, ++ ENETDOWN = libc::ENETDOWN, ++ ENETUNREACH = libc::ENETUNREACH, ++ ENETRESET = libc::ENETRESET, ++ ECONNABORTED = libc::ECONNABORTED, ++ ECONNRESET = libc::ECONNRESET, ++ ENOBUFS = libc::ENOBUFS, ++ EISCONN = libc::EISCONN, ++ ENOTCONN = libc::ENOTCONN, ++ ESHUTDOWN = libc::ESHUTDOWN, ++ ETOOMANYREFS = libc::ETOOMANYREFS, ++ ETIMEDOUT = libc::ETIMEDOUT, ++ ECONNREFUSED = libc::ECONNREFUSED, ++ EHOSTDOWN = libc::EHOSTDOWN, ++ EHOSTUNREACH = libc::EHOSTUNREACH, ++ EALREADY = libc::EALREADY, ++ EINPROGRESS = libc::EINPROGRESS, ++ ESTALE = libc::ESTALE, ++ EUCLEAN = libc::EUCLEAN, ++ ENOTNAM = libc::ENOTNAM, ++ ENAVAIL = libc::ENAVAIL, ++ EISNAM = libc::EISNAM, ++ EREMOTEIO = libc::EREMOTEIO, ++ EDQUOT = libc::EDQUOT, ++ ENOMEDIUM = libc::ENOMEDIUM, ++ EMEDIUMTYPE = libc::EMEDIUMTYPE, ++ ECANCELED = libc::ECANCELED, ++ ENOKEY = libc::ENOKEY, ++ EKEYEXPIRED = libc::EKEYEXPIRED, ++ EKEYREVOKED = libc::EKEYREVOKED, ++ EKEYREJECTED = libc::EKEYREJECTED, ++ EOWNERDEAD = libc::EOWNERDEAD, + ENOTRECOVERABLE = libc::ENOTRECOVERABLE, +- #[cfg(not(any(target_os = "android", target_arch="mips")))] +- ERFKILL = libc::ERFKILL, +- #[cfg(not(any(target_os = "android", target_arch="mips")))] +- EHWPOISON = libc::EHWPOISON, ++ #[cfg(not(any(target_os = "android", target_arch = "mips")))] ++ ERFKILL = libc::ERFKILL, ++ #[cfg(not(any(target_os = "android", target_arch = "mips")))] ++ EHWPOISON = libc::EHWPOISON, + } + +- pub const EWOULDBLOCK: Errno = Errno::EAGAIN; +- pub const EDEADLOCK: Errno = Errno::EDEADLK; +- pub const ENOTSUP: Errno = Errno::EOPNOTSUPP; ++ impl Errno { ++ pub const EWOULDBLOCK: Errno = Errno::EAGAIN; ++ pub const EDEADLOCK: Errno = Errno::EDEADLK; ++ pub const ENOTSUP: Errno = Errno::EOPNOTSUPP; ++ } + +- pub fn from_i32(e: i32) -> Errno { ++ pub const fn from_i32(e: i32) -> Errno { + use self::Errno::*; + + match e { +@@ -849,138 +1396,137 @@ mod consts { + libc::EKEYREJECTED => EKEYREJECTED, + libc::EOWNERDEAD => EOWNERDEAD, + libc::ENOTRECOVERABLE => ENOTRECOVERABLE, +- #[cfg(not(any(target_os = "android", target_arch="mips")))] ++ #[cfg(not(any(target_os = "android", target_arch = "mips")))] + libc::ERFKILL => ERFKILL, +- #[cfg(not(any(target_os = "android", target_arch="mips")))] ++ #[cfg(not(any(target_os = "android", target_arch = "mips")))] + libc::EHWPOISON => EHWPOISON, +- _ => UnknownErrno, ++ _ => UnknownErrno, + } + } + } + + #[cfg(any(target_os = "macos", target_os = "ios"))] + mod consts { +- use libc; +- + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + #[repr(i32)] ++ #[non_exhaustive] + pub enum Errno { +- UnknownErrno = 0, +- EPERM = libc::EPERM, +- ENOENT = libc::ENOENT, +- ESRCH = libc::ESRCH, +- EINTR = libc::EINTR, +- EIO = libc::EIO, +- ENXIO = libc::ENXIO, +- E2BIG = libc::E2BIG, +- ENOEXEC = libc::ENOEXEC, +- EBADF = libc::EBADF, +- ECHILD = libc::ECHILD, +- EDEADLK = libc::EDEADLK, +- ENOMEM = libc::ENOMEM, +- EACCES = libc::EACCES, +- EFAULT = libc::EFAULT, +- ENOTBLK = libc::ENOTBLK, +- EBUSY = libc::EBUSY, +- EEXIST = libc::EEXIST, +- EXDEV = libc::EXDEV, +- ENODEV = libc::ENODEV, +- ENOTDIR = libc::ENOTDIR, +- EISDIR = libc::EISDIR, +- EINVAL = libc::EINVAL, +- ENFILE = libc::ENFILE, +- EMFILE = libc::EMFILE, +- ENOTTY = libc::ENOTTY, +- ETXTBSY = libc::ETXTBSY, +- EFBIG = libc::EFBIG, +- ENOSPC = libc::ENOSPC, +- ESPIPE = libc::ESPIPE, +- EROFS = libc::EROFS, +- EMLINK = libc::EMLINK, +- EPIPE = libc::EPIPE, +- EDOM = libc::EDOM, +- ERANGE = libc::ERANGE, +- EAGAIN = libc::EAGAIN, +- EINPROGRESS = libc::EINPROGRESS, +- EALREADY = libc::EALREADY, +- ENOTSOCK = libc::ENOTSOCK, +- EDESTADDRREQ = libc::EDESTADDRREQ, +- EMSGSIZE = libc::EMSGSIZE, +- EPROTOTYPE = libc::EPROTOTYPE, +- ENOPROTOOPT = libc::ENOPROTOOPT, ++ UnknownErrno = 0, ++ EPERM = libc::EPERM, ++ ENOENT = libc::ENOENT, ++ ESRCH = libc::ESRCH, ++ EINTR = libc::EINTR, ++ EIO = libc::EIO, ++ ENXIO = libc::ENXIO, ++ E2BIG = libc::E2BIG, ++ ENOEXEC = libc::ENOEXEC, ++ EBADF = libc::EBADF, ++ ECHILD = libc::ECHILD, ++ EDEADLK = libc::EDEADLK, ++ ENOMEM = libc::ENOMEM, ++ EACCES = libc::EACCES, ++ EFAULT = libc::EFAULT, ++ ENOTBLK = libc::ENOTBLK, ++ EBUSY = libc::EBUSY, ++ EEXIST = libc::EEXIST, ++ EXDEV = libc::EXDEV, ++ ENODEV = libc::ENODEV, ++ ENOTDIR = libc::ENOTDIR, ++ EISDIR = libc::EISDIR, ++ EINVAL = libc::EINVAL, ++ ENFILE = libc::ENFILE, ++ EMFILE = libc::EMFILE, ++ ENOTTY = libc::ENOTTY, ++ ETXTBSY = libc::ETXTBSY, ++ EFBIG = libc::EFBIG, ++ ENOSPC = libc::ENOSPC, ++ ESPIPE = libc::ESPIPE, ++ EROFS = libc::EROFS, ++ EMLINK = libc::EMLINK, ++ EPIPE = libc::EPIPE, ++ EDOM = libc::EDOM, ++ ERANGE = libc::ERANGE, ++ EAGAIN = libc::EAGAIN, ++ EINPROGRESS = libc::EINPROGRESS, ++ EALREADY = libc::EALREADY, ++ ENOTSOCK = libc::ENOTSOCK, ++ EDESTADDRREQ = libc::EDESTADDRREQ, ++ EMSGSIZE = libc::EMSGSIZE, ++ EPROTOTYPE = libc::EPROTOTYPE, ++ ENOPROTOOPT = libc::ENOPROTOOPT, + EPROTONOSUPPORT = libc::EPROTONOSUPPORT, + ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT, +- ENOTSUP = libc::ENOTSUP, +- EPFNOSUPPORT = libc::EPFNOSUPPORT, +- EAFNOSUPPORT = libc::EAFNOSUPPORT, +- EADDRINUSE = libc::EADDRINUSE, +- EADDRNOTAVAIL = libc::EADDRNOTAVAIL, +- ENETDOWN = libc::ENETDOWN, +- ENETUNREACH = libc::ENETUNREACH, +- ENETRESET = libc::ENETRESET, +- ECONNABORTED = libc::ECONNABORTED, +- ECONNRESET = libc::ECONNRESET, +- ENOBUFS = libc::ENOBUFS, +- EISCONN = libc::EISCONN, +- ENOTCONN = libc::ENOTCONN, +- ESHUTDOWN = libc::ESHUTDOWN, +- ETOOMANYREFS = libc::ETOOMANYREFS, +- ETIMEDOUT = libc::ETIMEDOUT, +- ECONNREFUSED = libc::ECONNREFUSED, +- ELOOP = libc::ELOOP, +- ENAMETOOLONG = libc::ENAMETOOLONG, +- EHOSTDOWN = libc::EHOSTDOWN, +- EHOSTUNREACH = libc::EHOSTUNREACH, +- ENOTEMPTY = libc::ENOTEMPTY, +- EPROCLIM = libc::EPROCLIM, +- EUSERS = libc::EUSERS, +- EDQUOT = libc::EDQUOT, +- ESTALE = libc::ESTALE, +- EREMOTE = libc::EREMOTE, +- EBADRPC = libc::EBADRPC, +- ERPCMISMATCH = libc::ERPCMISMATCH, +- EPROGUNAVAIL = libc::EPROGUNAVAIL, +- EPROGMISMATCH = libc::EPROGMISMATCH, +- EPROCUNAVAIL = libc::EPROCUNAVAIL, +- ENOLCK = libc::ENOLCK, +- ENOSYS = libc::ENOSYS, +- EFTYPE = libc::EFTYPE, +- EAUTH = libc::EAUTH, +- ENEEDAUTH = libc::ENEEDAUTH, +- EPWROFF = libc::EPWROFF, +- EDEVERR = libc::EDEVERR, +- EOVERFLOW = libc::EOVERFLOW, +- EBADEXEC = libc::EBADEXEC, +- EBADARCH = libc::EBADARCH, +- ESHLIBVERS = libc::ESHLIBVERS, +- EBADMACHO = libc::EBADMACHO, +- ECANCELED = libc::ECANCELED, +- EIDRM = libc::EIDRM, +- ENOMSG = libc::ENOMSG, +- EILSEQ = libc::EILSEQ, +- ENOATTR = libc::ENOATTR, +- EBADMSG = libc::EBADMSG, +- EMULTIHOP = libc::EMULTIHOP, +- ENODATA = libc::ENODATA, +- ENOLINK = libc::ENOLINK, +- ENOSR = libc::ENOSR, +- ENOSTR = libc::ENOSTR, +- EPROTO = libc::EPROTO, +- ETIME = libc::ETIME, +- EOPNOTSUPP = libc::EOPNOTSUPP, +- ENOPOLICY = libc::ENOPOLICY, ++ ENOTSUP = libc::ENOTSUP, ++ EPFNOSUPPORT = libc::EPFNOSUPPORT, ++ EAFNOSUPPORT = libc::EAFNOSUPPORT, ++ EADDRINUSE = libc::EADDRINUSE, ++ EADDRNOTAVAIL = libc::EADDRNOTAVAIL, ++ ENETDOWN = libc::ENETDOWN, ++ ENETUNREACH = libc::ENETUNREACH, ++ ENETRESET = libc::ENETRESET, ++ ECONNABORTED = libc::ECONNABORTED, ++ ECONNRESET = libc::ECONNRESET, ++ ENOBUFS = libc::ENOBUFS, ++ EISCONN = libc::EISCONN, ++ ENOTCONN = libc::ENOTCONN, ++ ESHUTDOWN = libc::ESHUTDOWN, ++ ETOOMANYREFS = libc::ETOOMANYREFS, ++ ETIMEDOUT = libc::ETIMEDOUT, ++ ECONNREFUSED = libc::ECONNREFUSED, ++ ELOOP = libc::ELOOP, ++ ENAMETOOLONG = libc::ENAMETOOLONG, ++ EHOSTDOWN = libc::EHOSTDOWN, ++ EHOSTUNREACH = libc::EHOSTUNREACH, ++ ENOTEMPTY = libc::ENOTEMPTY, ++ EPROCLIM = libc::EPROCLIM, ++ EUSERS = libc::EUSERS, ++ EDQUOT = libc::EDQUOT, ++ ESTALE = libc::ESTALE, ++ EREMOTE = libc::EREMOTE, ++ EBADRPC = libc::EBADRPC, ++ ERPCMISMATCH = libc::ERPCMISMATCH, ++ EPROGUNAVAIL = libc::EPROGUNAVAIL, ++ EPROGMISMATCH = libc::EPROGMISMATCH, ++ EPROCUNAVAIL = libc::EPROCUNAVAIL, ++ ENOLCK = libc::ENOLCK, ++ ENOSYS = libc::ENOSYS, ++ EFTYPE = libc::EFTYPE, ++ EAUTH = libc::EAUTH, ++ ENEEDAUTH = libc::ENEEDAUTH, ++ EPWROFF = libc::EPWROFF, ++ EDEVERR = libc::EDEVERR, ++ EOVERFLOW = libc::EOVERFLOW, ++ EBADEXEC = libc::EBADEXEC, ++ EBADARCH = libc::EBADARCH, ++ ESHLIBVERS = libc::ESHLIBVERS, ++ EBADMACHO = libc::EBADMACHO, ++ ECANCELED = libc::ECANCELED, ++ EIDRM = libc::EIDRM, ++ ENOMSG = libc::ENOMSG, ++ EILSEQ = libc::EILSEQ, ++ ENOATTR = libc::ENOATTR, ++ EBADMSG = libc::EBADMSG, ++ EMULTIHOP = libc::EMULTIHOP, ++ ENODATA = libc::ENODATA, ++ ENOLINK = libc::ENOLINK, ++ ENOSR = libc::ENOSR, ++ ENOSTR = libc::ENOSTR, ++ EPROTO = libc::EPROTO, ++ ETIME = libc::ETIME, ++ EOPNOTSUPP = libc::EOPNOTSUPP, ++ ENOPOLICY = libc::ENOPOLICY, + ENOTRECOVERABLE = libc::ENOTRECOVERABLE, +- EOWNERDEAD = libc::EOWNERDEAD, +- EQFULL = libc::EQFULL, ++ EOWNERDEAD = libc::EOWNERDEAD, ++ EQFULL = libc::EQFULL, + } + +- pub const ELAST: Errno = Errno::EQFULL; +- pub const EWOULDBLOCK: Errno = Errno::EAGAIN; +- pub const EDEADLOCK: Errno = Errno::EDEADLK; +- +- pub const EL2NSYNC: Errno = Errno::UnknownErrno; ++ impl Errno { ++ pub const ELAST: Errno = Errno::EQFULL; ++ pub const EWOULDBLOCK: Errno = Errno::EAGAIN; ++ pub const EDEADLOCK: Errno = Errno::EDEADLK; ++ } + +- pub fn from_i32(e: i32) -> Errno { ++ pub const fn from_i32(e: i32) -> Errno { + use self::Errno::*; + + match e { +@@ -1090,124 +1636,124 @@ mod consts { + libc::ENOTRECOVERABLE => ENOTRECOVERABLE, + libc::EOWNERDEAD => EOWNERDEAD, + libc::EQFULL => EQFULL, +- _ => UnknownErrno, ++ _ => UnknownErrno, + } + } + } + + #[cfg(target_os = "freebsd")] + mod consts { +- use libc; +- + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + #[repr(i32)] ++ #[non_exhaustive] + pub enum Errno { +- UnknownErrno = 0, +- EPERM = libc::EPERM, +- ENOENT = libc::ENOENT, +- ESRCH = libc::ESRCH, +- EINTR = libc::EINTR, +- EIO = libc::EIO, +- ENXIO = libc::ENXIO, +- E2BIG = libc::E2BIG, +- ENOEXEC = libc::ENOEXEC, +- EBADF = libc::EBADF, +- ECHILD = libc::ECHILD, +- EDEADLK = libc::EDEADLK, +- ENOMEM = libc::ENOMEM, +- EACCES = libc::EACCES, +- EFAULT = libc::EFAULT, +- ENOTBLK = libc::ENOTBLK, +- EBUSY = libc::EBUSY, +- EEXIST = libc::EEXIST, +- EXDEV = libc::EXDEV, +- ENODEV = libc::ENODEV, +- ENOTDIR = libc::ENOTDIR, +- EISDIR = libc::EISDIR, +- EINVAL = libc::EINVAL, +- ENFILE = libc::ENFILE, +- EMFILE = libc::EMFILE, +- ENOTTY = libc::ENOTTY, +- ETXTBSY = libc::ETXTBSY, +- EFBIG = libc::EFBIG, +- ENOSPC = libc::ENOSPC, +- ESPIPE = libc::ESPIPE, +- EROFS = libc::EROFS, +- EMLINK = libc::EMLINK, +- EPIPE = libc::EPIPE, +- EDOM = libc::EDOM, +- ERANGE = libc::ERANGE, +- EAGAIN = libc::EAGAIN, +- EINPROGRESS = libc::EINPROGRESS, +- EALREADY = libc::EALREADY, +- ENOTSOCK = libc::ENOTSOCK, +- EDESTADDRREQ = libc::EDESTADDRREQ, +- EMSGSIZE = libc::EMSGSIZE, +- EPROTOTYPE = libc::EPROTOTYPE, +- ENOPROTOOPT = libc::ENOPROTOOPT, ++ UnknownErrno = 0, ++ EPERM = libc::EPERM, ++ ENOENT = libc::ENOENT, ++ ESRCH = libc::ESRCH, ++ EINTR = libc::EINTR, ++ EIO = libc::EIO, ++ ENXIO = libc::ENXIO, ++ E2BIG = libc::E2BIG, ++ ENOEXEC = libc::ENOEXEC, ++ EBADF = libc::EBADF, ++ ECHILD = libc::ECHILD, ++ EDEADLK = libc::EDEADLK, ++ ENOMEM = libc::ENOMEM, ++ EACCES = libc::EACCES, ++ EFAULT = libc::EFAULT, ++ ENOTBLK = libc::ENOTBLK, ++ EBUSY = libc::EBUSY, ++ EEXIST = libc::EEXIST, ++ EXDEV = libc::EXDEV, ++ ENODEV = libc::ENODEV, ++ ENOTDIR = libc::ENOTDIR, ++ EISDIR = libc::EISDIR, ++ EINVAL = libc::EINVAL, ++ ENFILE = libc::ENFILE, ++ EMFILE = libc::EMFILE, ++ ENOTTY = libc::ENOTTY, ++ ETXTBSY = libc::ETXTBSY, ++ EFBIG = libc::EFBIG, ++ ENOSPC = libc::ENOSPC, ++ ESPIPE = libc::ESPIPE, ++ EROFS = libc::EROFS, ++ EMLINK = libc::EMLINK, ++ EPIPE = libc::EPIPE, ++ EDOM = libc::EDOM, ++ ERANGE = libc::ERANGE, ++ EAGAIN = libc::EAGAIN, ++ EINPROGRESS = libc::EINPROGRESS, ++ EALREADY = libc::EALREADY, ++ ENOTSOCK = libc::ENOTSOCK, ++ EDESTADDRREQ = libc::EDESTADDRREQ, ++ EMSGSIZE = libc::EMSGSIZE, ++ EPROTOTYPE = libc::EPROTOTYPE, ++ ENOPROTOOPT = libc::ENOPROTOOPT, + EPROTONOSUPPORT = libc::EPROTONOSUPPORT, + ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT, +- ENOTSUP = libc::ENOTSUP, +- EPFNOSUPPORT = libc::EPFNOSUPPORT, +- EAFNOSUPPORT = libc::EAFNOSUPPORT, +- EADDRINUSE = libc::EADDRINUSE, +- EADDRNOTAVAIL = libc::EADDRNOTAVAIL, +- ENETDOWN = libc::ENETDOWN, +- ENETUNREACH = libc::ENETUNREACH, +- ENETRESET = libc::ENETRESET, +- ECONNABORTED = libc::ECONNABORTED, +- ECONNRESET = libc::ECONNRESET, +- ENOBUFS = libc::ENOBUFS, +- EISCONN = libc::EISCONN, +- ENOTCONN = libc::ENOTCONN, +- ESHUTDOWN = libc::ESHUTDOWN, +- ETOOMANYREFS = libc::ETOOMANYREFS, +- ETIMEDOUT = libc::ETIMEDOUT, +- ECONNREFUSED = libc::ECONNREFUSED, +- ELOOP = libc::ELOOP, +- ENAMETOOLONG = libc::ENAMETOOLONG, +- EHOSTDOWN = libc::EHOSTDOWN, +- EHOSTUNREACH = libc::EHOSTUNREACH, +- ENOTEMPTY = libc::ENOTEMPTY, +- EPROCLIM = libc::EPROCLIM, +- EUSERS = libc::EUSERS, +- EDQUOT = libc::EDQUOT, +- ESTALE = libc::ESTALE, +- EREMOTE = libc::EREMOTE, +- EBADRPC = libc::EBADRPC, +- ERPCMISMATCH = libc::ERPCMISMATCH, +- EPROGUNAVAIL = libc::EPROGUNAVAIL, +- EPROGMISMATCH = libc::EPROGMISMATCH, +- EPROCUNAVAIL = libc::EPROCUNAVAIL, +- ENOLCK = libc::ENOLCK, +- ENOSYS = libc::ENOSYS, +- EFTYPE = libc::EFTYPE, +- EAUTH = libc::EAUTH, +- ENEEDAUTH = libc::ENEEDAUTH, +- EIDRM = libc::EIDRM, +- ENOMSG = libc::ENOMSG, +- EOVERFLOW = libc::EOVERFLOW, +- ECANCELED = libc::ECANCELED, +- EILSEQ = libc::EILSEQ, +- ENOATTR = libc::ENOATTR, +- EDOOFUS = libc::EDOOFUS, +- EBADMSG = libc::EBADMSG, +- EMULTIHOP = libc::EMULTIHOP, +- ENOLINK = libc::ENOLINK, +- EPROTO = libc::EPROTO, +- ENOTCAPABLE = libc::ENOTCAPABLE, +- ECAPMODE = libc::ECAPMODE, ++ ENOTSUP = libc::ENOTSUP, ++ EPFNOSUPPORT = libc::EPFNOSUPPORT, ++ EAFNOSUPPORT = libc::EAFNOSUPPORT, ++ EADDRINUSE = libc::EADDRINUSE, ++ EADDRNOTAVAIL = libc::EADDRNOTAVAIL, ++ ENETDOWN = libc::ENETDOWN, ++ ENETUNREACH = libc::ENETUNREACH, ++ ENETRESET = libc::ENETRESET, ++ ECONNABORTED = libc::ECONNABORTED, ++ ECONNRESET = libc::ECONNRESET, ++ ENOBUFS = libc::ENOBUFS, ++ EISCONN = libc::EISCONN, ++ ENOTCONN = libc::ENOTCONN, ++ ESHUTDOWN = libc::ESHUTDOWN, ++ ETOOMANYREFS = libc::ETOOMANYREFS, ++ ETIMEDOUT = libc::ETIMEDOUT, ++ ECONNREFUSED = libc::ECONNREFUSED, ++ ELOOP = libc::ELOOP, ++ ENAMETOOLONG = libc::ENAMETOOLONG, ++ EHOSTDOWN = libc::EHOSTDOWN, ++ EHOSTUNREACH = libc::EHOSTUNREACH, ++ ENOTEMPTY = libc::ENOTEMPTY, ++ EPROCLIM = libc::EPROCLIM, ++ EUSERS = libc::EUSERS, ++ EDQUOT = libc::EDQUOT, ++ ESTALE = libc::ESTALE, ++ EREMOTE = libc::EREMOTE, ++ EBADRPC = libc::EBADRPC, ++ ERPCMISMATCH = libc::ERPCMISMATCH, ++ EPROGUNAVAIL = libc::EPROGUNAVAIL, ++ EPROGMISMATCH = libc::EPROGMISMATCH, ++ EPROCUNAVAIL = libc::EPROCUNAVAIL, ++ ENOLCK = libc::ENOLCK, ++ ENOSYS = libc::ENOSYS, ++ EFTYPE = libc::EFTYPE, ++ EAUTH = libc::EAUTH, ++ ENEEDAUTH = libc::ENEEDAUTH, ++ EIDRM = libc::EIDRM, ++ ENOMSG = libc::ENOMSG, ++ EOVERFLOW = libc::EOVERFLOW, ++ ECANCELED = libc::ECANCELED, ++ EILSEQ = libc::EILSEQ, ++ ENOATTR = libc::ENOATTR, ++ EDOOFUS = libc::EDOOFUS, ++ EBADMSG = libc::EBADMSG, ++ EMULTIHOP = libc::EMULTIHOP, ++ ENOLINK = libc::ENOLINK, ++ EPROTO = libc::EPROTO, ++ ENOTCAPABLE = libc::ENOTCAPABLE, ++ ECAPMODE = libc::ECAPMODE, + ENOTRECOVERABLE = libc::ENOTRECOVERABLE, +- EOWNERDEAD = libc::EOWNERDEAD, ++ EOWNERDEAD = libc::EOWNERDEAD, + } + +- pub const ELAST: Errno = Errno::EOWNERDEAD; +- pub const EWOULDBLOCK: Errno = Errno::EAGAIN; +- pub const EDEADLOCK: Errno = Errno::EDEADLK; +- +- pub const EL2NSYNC: Errno = Errno::UnknownErrno; ++ impl Errno { ++ pub const ELAST: Errno = Errno::EOWNERDEAD; ++ pub const EWOULDBLOCK: Errno = Errno::EAGAIN; ++ pub const EDEADLOCK: Errno = Errno::EDEADLK; ++ pub const EOPNOTSUPP: Errno = Errno::ENOTSUP; ++ } + +- pub fn from_i32(e: i32) -> Errno { ++ pub const fn from_i32(e: i32) -> Errno { + use self::Errno::*; + + match e { +@@ -1307,124 +1853,124 @@ mod consts { + libc::ECAPMODE => ECAPMODE, + libc::ENOTRECOVERABLE => ENOTRECOVERABLE, + libc::EOWNERDEAD => EOWNERDEAD, +- _ => UnknownErrno, ++ _ => UnknownErrno, + } + } + } + +- + #[cfg(target_os = "dragonfly")] + mod consts { +- use libc; +- + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + #[repr(i32)] ++ #[non_exhaustive] + pub enum Errno { +- UnknownErrno = 0, +- EPERM = libc::EPERM, +- ENOENT = libc::ENOENT, +- ESRCH = libc::ESRCH, +- EINTR = libc::EINTR, +- EIO = libc::EIO, +- ENXIO = libc::ENXIO, +- E2BIG = libc::E2BIG, +- ENOEXEC = libc::ENOEXEC, +- EBADF = libc::EBADF, +- ECHILD = libc::ECHILD, +- EDEADLK = libc::EDEADLK, +- ENOMEM = libc::ENOMEM, +- EACCES = libc::EACCES, +- EFAULT = libc::EFAULT, +- ENOTBLK = libc::ENOTBLK, +- EBUSY = libc::EBUSY, +- EEXIST = libc::EEXIST, +- EXDEV = libc::EXDEV, +- ENODEV = libc::ENODEV, +- ENOTDIR = libc::ENOTDIR, +- EISDIR = libc::EISDIR, +- EINVAL = libc::EINVAL, +- ENFILE = libc::ENFILE, +- EMFILE = libc::EMFILE, +- ENOTTY = libc::ENOTTY, +- ETXTBSY = libc::ETXTBSY, +- EFBIG = libc::EFBIG, +- ENOSPC = libc::ENOSPC, +- ESPIPE = libc::ESPIPE, +- EROFS = libc::EROFS, +- EMLINK = libc::EMLINK, +- EPIPE = libc::EPIPE, +- EDOM = libc::EDOM, +- ERANGE = libc::ERANGE, +- EAGAIN = libc::EAGAIN, +- EINPROGRESS = libc::EINPROGRESS, +- EALREADY = libc::EALREADY, +- ENOTSOCK = libc::ENOTSOCK, +- EDESTADDRREQ = libc::EDESTADDRREQ, +- EMSGSIZE = libc::EMSGSIZE, +- EPROTOTYPE = libc::EPROTOTYPE, +- ENOPROTOOPT = libc::ENOPROTOOPT, ++ UnknownErrno = 0, ++ EPERM = libc::EPERM, ++ ENOENT = libc::ENOENT, ++ ESRCH = libc::ESRCH, ++ EINTR = libc::EINTR, ++ EIO = libc::EIO, ++ ENXIO = libc::ENXIO, ++ E2BIG = libc::E2BIG, ++ ENOEXEC = libc::ENOEXEC, ++ EBADF = libc::EBADF, ++ ECHILD = libc::ECHILD, ++ EDEADLK = libc::EDEADLK, ++ ENOMEM = libc::ENOMEM, ++ EACCES = libc::EACCES, ++ EFAULT = libc::EFAULT, ++ ENOTBLK = libc::ENOTBLK, ++ EBUSY = libc::EBUSY, ++ EEXIST = libc::EEXIST, ++ EXDEV = libc::EXDEV, ++ ENODEV = libc::ENODEV, ++ ENOTDIR = libc::ENOTDIR, ++ EISDIR = libc::EISDIR, ++ EINVAL = libc::EINVAL, ++ ENFILE = libc::ENFILE, ++ EMFILE = libc::EMFILE, ++ ENOTTY = libc::ENOTTY, ++ ETXTBSY = libc::ETXTBSY, ++ EFBIG = libc::EFBIG, ++ ENOSPC = libc::ENOSPC, ++ ESPIPE = libc::ESPIPE, ++ EROFS = libc::EROFS, ++ EMLINK = libc::EMLINK, ++ EPIPE = libc::EPIPE, ++ EDOM = libc::EDOM, ++ ERANGE = libc::ERANGE, ++ EAGAIN = libc::EAGAIN, ++ EINPROGRESS = libc::EINPROGRESS, ++ EALREADY = libc::EALREADY, ++ ENOTSOCK = libc::ENOTSOCK, ++ EDESTADDRREQ = libc::EDESTADDRREQ, ++ EMSGSIZE = libc::EMSGSIZE, ++ EPROTOTYPE = libc::EPROTOTYPE, ++ ENOPROTOOPT = libc::ENOPROTOOPT, + EPROTONOSUPPORT = libc::EPROTONOSUPPORT, + ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT, +- ENOTSUP = libc::ENOTSUP, +- EPFNOSUPPORT = libc::EPFNOSUPPORT, +- EAFNOSUPPORT = libc::EAFNOSUPPORT, +- EADDRINUSE = libc::EADDRINUSE, +- EADDRNOTAVAIL = libc::EADDRNOTAVAIL, +- ENETDOWN = libc::ENETDOWN, +- ENETUNREACH = libc::ENETUNREACH, +- ENETRESET = libc::ENETRESET, +- ECONNABORTED = libc::ECONNABORTED, +- ECONNRESET = libc::ECONNRESET, +- ENOBUFS = libc::ENOBUFS, +- EISCONN = libc::EISCONN, +- ENOTCONN = libc::ENOTCONN, +- ESHUTDOWN = libc::ESHUTDOWN, +- ETOOMANYREFS = libc::ETOOMANYREFS, +- ETIMEDOUT = libc::ETIMEDOUT, +- ECONNREFUSED = libc::ECONNREFUSED, +- ELOOP = libc::ELOOP, +- ENAMETOOLONG = libc::ENAMETOOLONG, +- EHOSTDOWN = libc::EHOSTDOWN, +- EHOSTUNREACH = libc::EHOSTUNREACH, +- ENOTEMPTY = libc::ENOTEMPTY, +- EPROCLIM = libc::EPROCLIM, +- EUSERS = libc::EUSERS, +- EDQUOT = libc::EDQUOT, +- ESTALE = libc::ESTALE, +- EREMOTE = libc::EREMOTE, +- EBADRPC = libc::EBADRPC, +- ERPCMISMATCH = libc::ERPCMISMATCH, +- EPROGUNAVAIL = libc::EPROGUNAVAIL, +- EPROGMISMATCH = libc::EPROGMISMATCH, +- EPROCUNAVAIL = libc::EPROCUNAVAIL, +- ENOLCK = libc::ENOLCK, +- ENOSYS = libc::ENOSYS, +- EFTYPE = libc::EFTYPE, +- EAUTH = libc::EAUTH, +- ENEEDAUTH = libc::ENEEDAUTH, +- EIDRM = libc::EIDRM, +- ENOMSG = libc::ENOMSG, +- EOVERFLOW = libc::EOVERFLOW, +- ECANCELED = libc::ECANCELED, +- EILSEQ = libc::EILSEQ, +- ENOATTR = libc::ENOATTR, +- EDOOFUS = libc::EDOOFUS, +- EBADMSG = libc::EBADMSG, +- EMULTIHOP = libc::EMULTIHOP, +- ENOLINK = libc::ENOLINK, +- EPROTO = libc::EPROTO, +- ENOMEDIUM = libc::ENOMEDIUM, +- EASYNC = libc::EASYNC, ++ ENOTSUP = libc::ENOTSUP, ++ EPFNOSUPPORT = libc::EPFNOSUPPORT, ++ EAFNOSUPPORT = libc::EAFNOSUPPORT, ++ EADDRINUSE = libc::EADDRINUSE, ++ EADDRNOTAVAIL = libc::EADDRNOTAVAIL, ++ ENETDOWN = libc::ENETDOWN, ++ ENETUNREACH = libc::ENETUNREACH, ++ ENETRESET = libc::ENETRESET, ++ ECONNABORTED = libc::ECONNABORTED, ++ ECONNRESET = libc::ECONNRESET, ++ ENOBUFS = libc::ENOBUFS, ++ EISCONN = libc::EISCONN, ++ ENOTCONN = libc::ENOTCONN, ++ ESHUTDOWN = libc::ESHUTDOWN, ++ ETOOMANYREFS = libc::ETOOMANYREFS, ++ ETIMEDOUT = libc::ETIMEDOUT, ++ ECONNREFUSED = libc::ECONNREFUSED, ++ ELOOP = libc::ELOOP, ++ ENAMETOOLONG = libc::ENAMETOOLONG, ++ EHOSTDOWN = libc::EHOSTDOWN, ++ EHOSTUNREACH = libc::EHOSTUNREACH, ++ ENOTEMPTY = libc::ENOTEMPTY, ++ EPROCLIM = libc::EPROCLIM, ++ EUSERS = libc::EUSERS, ++ EDQUOT = libc::EDQUOT, ++ ESTALE = libc::ESTALE, ++ EREMOTE = libc::EREMOTE, ++ EBADRPC = libc::EBADRPC, ++ ERPCMISMATCH = libc::ERPCMISMATCH, ++ EPROGUNAVAIL = libc::EPROGUNAVAIL, ++ EPROGMISMATCH = libc::EPROGMISMATCH, ++ EPROCUNAVAIL = libc::EPROCUNAVAIL, ++ ENOLCK = libc::ENOLCK, ++ ENOSYS = libc::ENOSYS, ++ EFTYPE = libc::EFTYPE, ++ EAUTH = libc::EAUTH, ++ ENEEDAUTH = libc::ENEEDAUTH, ++ EIDRM = libc::EIDRM, ++ ENOMSG = libc::ENOMSG, ++ EOVERFLOW = libc::EOVERFLOW, ++ ECANCELED = libc::ECANCELED, ++ EILSEQ = libc::EILSEQ, ++ ENOATTR = libc::ENOATTR, ++ EDOOFUS = libc::EDOOFUS, ++ EBADMSG = libc::EBADMSG, ++ EMULTIHOP = libc::EMULTIHOP, ++ ENOLINK = libc::ENOLINK, ++ EPROTO = libc::EPROTO, ++ ENOMEDIUM = libc::ENOMEDIUM, ++ ENOTRECOVERABLE = libc::ENOTRECOVERABLE, ++ EOWNERDEAD = libc::EOWNERDEAD, ++ EASYNC = libc::EASYNC, + } + +- pub const ELAST: Errno = Errno::EASYNC; +- pub const EWOULDBLOCK: Errno = Errno::EAGAIN; +- pub const EDEADLOCK: Errno = Errno::EDEADLK; +- pub const EOPNOTSUPP: Errno = Errno::ENOTSUP; +- +- pub const EL2NSYNC: Errno = Errno::UnknownErrno; ++ impl Errno { ++ pub const ELAST: Errno = Errno::EASYNC; ++ pub const EWOULDBLOCK: Errno = Errno::EAGAIN; ++ pub const EDEADLOCK: Errno = Errno::EDEADLK; ++ pub const EOPNOTSUPP: Errno = Errno::ENOTSUP; ++ } + +- pub fn from_i32(e: i32) -> Errno { ++ pub const fn from_i32(e: i32) -> Errno { + use self::Errno::*; + + match e { +@@ -1448,7 +1994,7 @@ mod consts { + libc::EXDEV => EXDEV, + libc::ENODEV => ENODEV, + libc::ENOTDIR => ENOTDIR, +- libc::EISDIR=> EISDIR, ++ libc::EISDIR => EISDIR, + libc::EINVAL => EINVAL, + libc::ENFILE => ENFILE, + libc::EMFILE => EMFILE, +@@ -1522,123 +2068,121 @@ mod consts { + libc::EPROTO => EPROTO, + libc::ENOMEDIUM => ENOMEDIUM, + libc::EASYNC => EASYNC, +- _ => UnknownErrno, ++ _ => UnknownErrno, + } + } + } + +- + #[cfg(target_os = "openbsd")] + mod consts { +- use libc; +- + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + #[repr(i32)] ++ #[non_exhaustive] + pub enum Errno { +- UnknownErrno = 0, +- EPERM = libc::EPERM, +- ENOENT = libc::ENOENT, +- ESRCH = libc::ESRCH, +- EINTR = libc::EINTR, +- EIO = libc::EIO, +- ENXIO = libc::ENXIO, +- E2BIG = libc::E2BIG, +- ENOEXEC = libc::ENOEXEC, +- EBADF = libc::EBADF, +- ECHILD = libc::ECHILD, +- EDEADLK = libc::EDEADLK, +- ENOMEM = libc::ENOMEM, +- EACCES = libc::EACCES, +- EFAULT = libc::EFAULT, +- ENOTBLK = libc::ENOTBLK, +- EBUSY = libc::EBUSY, +- EEXIST = libc::EEXIST, +- EXDEV = libc::EXDEV, +- ENODEV = libc::ENODEV, +- ENOTDIR = libc::ENOTDIR, +- EISDIR = libc::EISDIR, +- EINVAL = libc::EINVAL, +- ENFILE = libc::ENFILE, +- EMFILE = libc::EMFILE, +- ENOTTY = libc::ENOTTY, +- ETXTBSY = libc::ETXTBSY, +- EFBIG = libc::EFBIG, +- ENOSPC = libc::ENOSPC, +- ESPIPE = libc::ESPIPE, +- EROFS = libc::EROFS, +- EMLINK = libc::EMLINK, +- EPIPE = libc::EPIPE, +- EDOM = libc::EDOM, +- ERANGE = libc::ERANGE, +- EAGAIN = libc::EAGAIN, +- EINPROGRESS = libc::EINPROGRESS, +- EALREADY = libc::EALREADY, +- ENOTSOCK = libc::ENOTSOCK, +- EDESTADDRREQ = libc::EDESTADDRREQ, +- EMSGSIZE = libc::EMSGSIZE, +- EPROTOTYPE = libc::EPROTOTYPE, +- ENOPROTOOPT = libc::ENOPROTOOPT, ++ UnknownErrno = 0, ++ EPERM = libc::EPERM, ++ ENOENT = libc::ENOENT, ++ ESRCH = libc::ESRCH, ++ EINTR = libc::EINTR, ++ EIO = libc::EIO, ++ ENXIO = libc::ENXIO, ++ E2BIG = libc::E2BIG, ++ ENOEXEC = libc::ENOEXEC, ++ EBADF = libc::EBADF, ++ ECHILD = libc::ECHILD, ++ EDEADLK = libc::EDEADLK, ++ ENOMEM = libc::ENOMEM, ++ EACCES = libc::EACCES, ++ EFAULT = libc::EFAULT, ++ ENOTBLK = libc::ENOTBLK, ++ EBUSY = libc::EBUSY, ++ EEXIST = libc::EEXIST, ++ EXDEV = libc::EXDEV, ++ ENODEV = libc::ENODEV, ++ ENOTDIR = libc::ENOTDIR, ++ EISDIR = libc::EISDIR, ++ EINVAL = libc::EINVAL, ++ ENFILE = libc::ENFILE, ++ EMFILE = libc::EMFILE, ++ ENOTTY = libc::ENOTTY, ++ ETXTBSY = libc::ETXTBSY, ++ EFBIG = libc::EFBIG, ++ ENOSPC = libc::ENOSPC, ++ ESPIPE = libc::ESPIPE, ++ EROFS = libc::EROFS, ++ EMLINK = libc::EMLINK, ++ EPIPE = libc::EPIPE, ++ EDOM = libc::EDOM, ++ ERANGE = libc::ERANGE, ++ EAGAIN = libc::EAGAIN, ++ EINPROGRESS = libc::EINPROGRESS, ++ EALREADY = libc::EALREADY, ++ ENOTSOCK = libc::ENOTSOCK, ++ EDESTADDRREQ = libc::EDESTADDRREQ, ++ EMSGSIZE = libc::EMSGSIZE, ++ EPROTOTYPE = libc::EPROTOTYPE, ++ ENOPROTOOPT = libc::ENOPROTOOPT, + EPROTONOSUPPORT = libc::EPROTONOSUPPORT, + ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT, +- EOPNOTSUPP = libc::EOPNOTSUPP, +- EPFNOSUPPORT = libc::EPFNOSUPPORT, +- EAFNOSUPPORT = libc::EAFNOSUPPORT, +- EADDRINUSE = libc::EADDRINUSE, +- EADDRNOTAVAIL = libc::EADDRNOTAVAIL, +- ENETDOWN = libc::ENETDOWN, +- ENETUNREACH = libc::ENETUNREACH, +- ENETRESET = libc::ENETRESET, +- ECONNABORTED = libc::ECONNABORTED, +- ECONNRESET = libc::ECONNRESET, +- ENOBUFS = libc::ENOBUFS, +- EISCONN = libc::EISCONN, +- ENOTCONN = libc::ENOTCONN, +- ESHUTDOWN = libc::ESHUTDOWN, +- ETOOMANYREFS = libc::ETOOMANYREFS, +- ETIMEDOUT = libc::ETIMEDOUT, +- ECONNREFUSED = libc::ECONNREFUSED, +- ELOOP = libc::ELOOP, +- ENAMETOOLONG = libc::ENAMETOOLONG, +- EHOSTDOWN = libc::EHOSTDOWN, +- EHOSTUNREACH = libc::EHOSTUNREACH, +- ENOTEMPTY = libc::ENOTEMPTY, +- EPROCLIM = libc::EPROCLIM, +- EUSERS = libc::EUSERS, +- EDQUOT = libc::EDQUOT, +- ESTALE = libc::ESTALE, +- EREMOTE = libc::EREMOTE, +- EBADRPC = libc::EBADRPC, +- ERPCMISMATCH = libc::ERPCMISMATCH, +- EPROGUNAVAIL = libc::EPROGUNAVAIL, +- EPROGMISMATCH = libc::EPROGMISMATCH, +- EPROCUNAVAIL = libc::EPROCUNAVAIL, +- ENOLCK = libc::ENOLCK, +- ENOSYS = libc::ENOSYS, +- EFTYPE = libc::EFTYPE, +- EAUTH = libc::EAUTH, +- ENEEDAUTH = libc::ENEEDAUTH, +- EIPSEC = libc::EIPSEC, +- ENOATTR = libc::ENOATTR, +- EILSEQ = libc::EILSEQ, +- ENOMEDIUM = libc::ENOMEDIUM, +- EMEDIUMTYPE = libc::EMEDIUMTYPE, +- EOVERFLOW = libc::EOVERFLOW, +- ECANCELED = libc::ECANCELED, +- EIDRM = libc::EIDRM, +- ENOMSG = libc::ENOMSG, +- ENOTSUP = libc::ENOTSUP, +- EBADMSG = libc::EBADMSG, ++ EOPNOTSUPP = libc::EOPNOTSUPP, ++ EPFNOSUPPORT = libc::EPFNOSUPPORT, ++ EAFNOSUPPORT = libc::EAFNOSUPPORT, ++ EADDRINUSE = libc::EADDRINUSE, ++ EADDRNOTAVAIL = libc::EADDRNOTAVAIL, ++ ENETDOWN = libc::ENETDOWN, ++ ENETUNREACH = libc::ENETUNREACH, ++ ENETRESET = libc::ENETRESET, ++ ECONNABORTED = libc::ECONNABORTED, ++ ECONNRESET = libc::ECONNRESET, ++ ENOBUFS = libc::ENOBUFS, ++ EISCONN = libc::EISCONN, ++ ENOTCONN = libc::ENOTCONN, ++ ESHUTDOWN = libc::ESHUTDOWN, ++ ETOOMANYREFS = libc::ETOOMANYREFS, ++ ETIMEDOUT = libc::ETIMEDOUT, ++ ECONNREFUSED = libc::ECONNREFUSED, ++ ELOOP = libc::ELOOP, ++ ENAMETOOLONG = libc::ENAMETOOLONG, ++ EHOSTDOWN = libc::EHOSTDOWN, ++ EHOSTUNREACH = libc::EHOSTUNREACH, ++ ENOTEMPTY = libc::ENOTEMPTY, ++ EPROCLIM = libc::EPROCLIM, ++ EUSERS = libc::EUSERS, ++ EDQUOT = libc::EDQUOT, ++ ESTALE = libc::ESTALE, ++ EREMOTE = libc::EREMOTE, ++ EBADRPC = libc::EBADRPC, ++ ERPCMISMATCH = libc::ERPCMISMATCH, ++ EPROGUNAVAIL = libc::EPROGUNAVAIL, ++ EPROGMISMATCH = libc::EPROGMISMATCH, ++ EPROCUNAVAIL = libc::EPROCUNAVAIL, ++ ENOLCK = libc::ENOLCK, ++ ENOSYS = libc::ENOSYS, ++ EFTYPE = libc::EFTYPE, ++ EAUTH = libc::EAUTH, ++ ENEEDAUTH = libc::ENEEDAUTH, ++ EIPSEC = libc::EIPSEC, ++ ENOATTR = libc::ENOATTR, ++ EILSEQ = libc::EILSEQ, ++ ENOMEDIUM = libc::ENOMEDIUM, ++ EMEDIUMTYPE = libc::EMEDIUMTYPE, ++ EOVERFLOW = libc::EOVERFLOW, ++ ECANCELED = libc::ECANCELED, ++ EIDRM = libc::EIDRM, ++ ENOMSG = libc::ENOMSG, ++ ENOTSUP = libc::ENOTSUP, ++ EBADMSG = libc::EBADMSG, + ENOTRECOVERABLE = libc::ENOTRECOVERABLE, +- EOWNERDEAD = libc::EOWNERDEAD, +- EPROTO = libc::EPROTO, ++ EOWNERDEAD = libc::EOWNERDEAD, ++ EPROTO = libc::EPROTO, + } + +- pub const ELAST: Errno = Errno::ENOTSUP; +- pub const EWOULDBLOCK: Errno = Errno::EAGAIN; +- +- pub const EL2NSYNC: Errno = Errno::UnknownErrno; ++ impl Errno { ++ pub const ELAST: Errno = Errno::ENOTSUP; ++ pub const EWOULDBLOCK: Errno = Errno::EAGAIN; ++ } + +- pub fn from_i32(e: i32) -> Errno { ++ pub const fn from_i32(e: i32) -> Errno { + use self::Errno::*; + + match e { +@@ -1737,123 +2281,122 @@ mod consts { + libc::ENOTRECOVERABLE => ENOTRECOVERABLE, + libc::EOWNERDEAD => EOWNERDEAD, + libc::EPROTO => EPROTO, +- _ => UnknownErrno, ++ _ => UnknownErrno, + } + } + } + + #[cfg(target_os = "netbsd")] + mod consts { +- use libc; +- + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + #[repr(i32)] ++ #[non_exhaustive] + pub enum Errno { +- UnknownErrno = 0, +- EPERM = libc::EPERM, +- ENOENT = libc::ENOENT, +- ESRCH = libc::ESRCH, +- EINTR = libc::EINTR, +- EIO = libc::EIO, +- ENXIO = libc::ENXIO, +- E2BIG = libc::E2BIG, +- ENOEXEC = libc::ENOEXEC, +- EBADF = libc::EBADF, +- ECHILD = libc::ECHILD, +- EDEADLK = libc::EDEADLK, +- ENOMEM = libc::ENOMEM, +- EACCES = libc::EACCES, +- EFAULT = libc::EFAULT, +- ENOTBLK = libc::ENOTBLK, +- EBUSY = libc::EBUSY, +- EEXIST = libc::EEXIST, +- EXDEV = libc::EXDEV, +- ENODEV = libc::ENODEV, +- ENOTDIR = libc::ENOTDIR, +- EISDIR = libc::EISDIR, +- EINVAL = libc::EINVAL, +- ENFILE = libc::ENFILE, +- EMFILE = libc::EMFILE, +- ENOTTY = libc::ENOTTY, +- ETXTBSY = libc::ETXTBSY, +- EFBIG = libc::EFBIG, +- ENOSPC = libc::ENOSPC, +- ESPIPE = libc::ESPIPE, +- EROFS = libc::EROFS, +- EMLINK = libc::EMLINK, +- EPIPE = libc::EPIPE, +- EDOM = libc::EDOM, +- ERANGE = libc::ERANGE, +- EAGAIN = libc::EAGAIN, +- EINPROGRESS = libc::EINPROGRESS, +- EALREADY = libc::EALREADY, +- ENOTSOCK = libc::ENOTSOCK, +- EDESTADDRREQ = libc::EDESTADDRREQ, +- EMSGSIZE = libc::EMSGSIZE, +- EPROTOTYPE = libc::EPROTOTYPE, +- ENOPROTOOPT = libc::ENOPROTOOPT, ++ UnknownErrno = 0, ++ EPERM = libc::EPERM, ++ ENOENT = libc::ENOENT, ++ ESRCH = libc::ESRCH, ++ EINTR = libc::EINTR, ++ EIO = libc::EIO, ++ ENXIO = libc::ENXIO, ++ E2BIG = libc::E2BIG, ++ ENOEXEC = libc::ENOEXEC, ++ EBADF = libc::EBADF, ++ ECHILD = libc::ECHILD, ++ EDEADLK = libc::EDEADLK, ++ ENOMEM = libc::ENOMEM, ++ EACCES = libc::EACCES, ++ EFAULT = libc::EFAULT, ++ ENOTBLK = libc::ENOTBLK, ++ EBUSY = libc::EBUSY, ++ EEXIST = libc::EEXIST, ++ EXDEV = libc::EXDEV, ++ ENODEV = libc::ENODEV, ++ ENOTDIR = libc::ENOTDIR, ++ EISDIR = libc::EISDIR, ++ EINVAL = libc::EINVAL, ++ ENFILE = libc::ENFILE, ++ EMFILE = libc::EMFILE, ++ ENOTTY = libc::ENOTTY, ++ ETXTBSY = libc::ETXTBSY, ++ EFBIG = libc::EFBIG, ++ ENOSPC = libc::ENOSPC, ++ ESPIPE = libc::ESPIPE, ++ EROFS = libc::EROFS, ++ EMLINK = libc::EMLINK, ++ EPIPE = libc::EPIPE, ++ EDOM = libc::EDOM, ++ ERANGE = libc::ERANGE, ++ EAGAIN = libc::EAGAIN, ++ EINPROGRESS = libc::EINPROGRESS, ++ EALREADY = libc::EALREADY, ++ ENOTSOCK = libc::ENOTSOCK, ++ EDESTADDRREQ = libc::EDESTADDRREQ, ++ EMSGSIZE = libc::EMSGSIZE, ++ EPROTOTYPE = libc::EPROTOTYPE, ++ ENOPROTOOPT = libc::ENOPROTOOPT, + EPROTONOSUPPORT = libc::EPROTONOSUPPORT, + ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT, +- EOPNOTSUPP = libc::EOPNOTSUPP, +- EPFNOSUPPORT = libc::EPFNOSUPPORT, +- EAFNOSUPPORT = libc::EAFNOSUPPORT, +- EADDRINUSE = libc::EADDRINUSE, +- EADDRNOTAVAIL = libc::EADDRNOTAVAIL, +- ENETDOWN = libc::ENETDOWN, +- ENETUNREACH = libc::ENETUNREACH, +- ENETRESET = libc::ENETRESET, +- ECONNABORTED = libc::ECONNABORTED, +- ECONNRESET = libc::ECONNRESET, +- ENOBUFS = libc::ENOBUFS, +- EISCONN = libc::EISCONN, +- ENOTCONN = libc::ENOTCONN, +- ESHUTDOWN = libc::ESHUTDOWN, +- ETOOMANYREFS = libc::ETOOMANYREFS, +- ETIMEDOUT = libc::ETIMEDOUT, +- ECONNREFUSED = libc::ECONNREFUSED, +- ELOOP = libc::ELOOP, +- ENAMETOOLONG = libc::ENAMETOOLONG, +- EHOSTDOWN = libc::EHOSTDOWN, +- EHOSTUNREACH = libc::EHOSTUNREACH, +- ENOTEMPTY = libc::ENOTEMPTY, +- EPROCLIM = libc::EPROCLIM, +- EUSERS = libc::EUSERS, +- EDQUOT = libc::EDQUOT, +- ESTALE = libc::ESTALE, +- EREMOTE = libc::EREMOTE, +- EBADRPC = libc::EBADRPC, +- ERPCMISMATCH = libc::ERPCMISMATCH, +- EPROGUNAVAIL = libc::EPROGUNAVAIL, +- EPROGMISMATCH = libc::EPROGMISMATCH, +- EPROCUNAVAIL = libc::EPROCUNAVAIL, +- ENOLCK = libc::ENOLCK, +- ENOSYS = libc::ENOSYS, +- EFTYPE = libc::EFTYPE, +- EAUTH = libc::EAUTH, +- ENEEDAUTH = libc::ENEEDAUTH, +- EIDRM = libc::EIDRM, +- ENOMSG = libc::ENOMSG, +- EOVERFLOW = libc::EOVERFLOW, +- EILSEQ = libc::EILSEQ, +- ENOTSUP = libc::ENOTSUP, +- ECANCELED = libc::ECANCELED, +- EBADMSG = libc::EBADMSG, +- ENODATA = libc::ENODATA, +- ENOSR = libc::ENOSR, +- ENOSTR = libc::ENOSTR, +- ETIME = libc::ETIME, +- ENOATTR = libc::ENOATTR, +- EMULTIHOP = libc::EMULTIHOP, +- ENOLINK = libc::ENOLINK, +- EPROTO = libc::EPROTO, ++ EOPNOTSUPP = libc::EOPNOTSUPP, ++ EPFNOSUPPORT = libc::EPFNOSUPPORT, ++ EAFNOSUPPORT = libc::EAFNOSUPPORT, ++ EADDRINUSE = libc::EADDRINUSE, ++ EADDRNOTAVAIL = libc::EADDRNOTAVAIL, ++ ENETDOWN = libc::ENETDOWN, ++ ENETUNREACH = libc::ENETUNREACH, ++ ENETRESET = libc::ENETRESET, ++ ECONNABORTED = libc::ECONNABORTED, ++ ECONNRESET = libc::ECONNRESET, ++ ENOBUFS = libc::ENOBUFS, ++ EISCONN = libc::EISCONN, ++ ENOTCONN = libc::ENOTCONN, ++ ESHUTDOWN = libc::ESHUTDOWN, ++ ETOOMANYREFS = libc::ETOOMANYREFS, ++ ETIMEDOUT = libc::ETIMEDOUT, ++ ECONNREFUSED = libc::ECONNREFUSED, ++ ELOOP = libc::ELOOP, ++ ENAMETOOLONG = libc::ENAMETOOLONG, ++ EHOSTDOWN = libc::EHOSTDOWN, ++ EHOSTUNREACH = libc::EHOSTUNREACH, ++ ENOTEMPTY = libc::ENOTEMPTY, ++ EPROCLIM = libc::EPROCLIM, ++ EUSERS = libc::EUSERS, ++ EDQUOT = libc::EDQUOT, ++ ESTALE = libc::ESTALE, ++ EREMOTE = libc::EREMOTE, ++ EBADRPC = libc::EBADRPC, ++ ERPCMISMATCH = libc::ERPCMISMATCH, ++ EPROGUNAVAIL = libc::EPROGUNAVAIL, ++ EPROGMISMATCH = libc::EPROGMISMATCH, ++ EPROCUNAVAIL = libc::EPROCUNAVAIL, ++ ENOLCK = libc::ENOLCK, ++ ENOSYS = libc::ENOSYS, ++ EFTYPE = libc::EFTYPE, ++ EAUTH = libc::EAUTH, ++ ENEEDAUTH = libc::ENEEDAUTH, ++ EIDRM = libc::EIDRM, ++ ENOMSG = libc::ENOMSG, ++ EOVERFLOW = libc::EOVERFLOW, ++ EILSEQ = libc::EILSEQ, ++ ENOTSUP = libc::ENOTSUP, ++ ECANCELED = libc::ECANCELED, ++ EBADMSG = libc::EBADMSG, ++ ENODATA = libc::ENODATA, ++ ENOSR = libc::ENOSR, ++ ENOSTR = libc::ENOSTR, ++ ETIME = libc::ETIME, ++ ENOATTR = libc::ENOATTR, ++ EMULTIHOP = libc::EMULTIHOP, ++ ENOLINK = libc::ENOLINK, ++ EPROTO = libc::EPROTO, + } + +- pub const ELAST: Errno = Errno::ENOTSUP; +- pub const EWOULDBLOCK: Errno = Errno::EAGAIN; +- +- pub const EL2NSYNC: Errno = Errno::UnknownErrno; ++ impl Errno { ++ pub const ELAST: Errno = Errno::ENOTSUP; ++ pub const EWOULDBLOCK: Errno = Errno::EAGAIN; ++ } + +- pub fn from_i32(e: i32) -> Errno { ++ pub const fn from_i32(e: i32) -> Errno { + use self::Errno::*; + + match e { +@@ -1953,7 +2496,638 @@ mod consts { + libc::EMULTIHOP => EMULTIHOP, + libc::ENOLINK => ENOLINK, + libc::EPROTO => EPROTO, +- _ => UnknownErrno, ++ _ => UnknownErrno, ++ } ++ } ++} ++ ++#[cfg(target_os = "redox")] ++mod consts { ++ #[derive(Clone, Copy, Debug, Eq, PartialEq)] ++ #[repr(i32)] ++ #[non_exhaustive] ++ pub enum Errno { ++ UnknownErrno = 0, ++ EPERM = libc::EPERM, ++ ENOENT = libc::ENOENT, ++ ESRCH = libc::ESRCH, ++ EINTR = libc::EINTR, ++ EIO = libc::EIO, ++ ENXIO = libc::ENXIO, ++ E2BIG = libc::E2BIG, ++ ENOEXEC = libc::ENOEXEC, ++ EBADF = libc::EBADF, ++ ECHILD = libc::ECHILD, ++ EDEADLK = libc::EDEADLK, ++ ENOMEM = libc::ENOMEM, ++ EACCES = libc::EACCES, ++ EFAULT = libc::EFAULT, ++ ENOTBLK = libc::ENOTBLK, ++ EBUSY = libc::EBUSY, ++ EEXIST = libc::EEXIST, ++ EXDEV = libc::EXDEV, ++ ENODEV = libc::ENODEV, ++ ENOTDIR = libc::ENOTDIR, ++ EISDIR = libc::EISDIR, ++ EINVAL = libc::EINVAL, ++ ENFILE = libc::ENFILE, ++ EMFILE = libc::EMFILE, ++ ENOTTY = libc::ENOTTY, ++ ETXTBSY = libc::ETXTBSY, ++ EFBIG = libc::EFBIG, ++ ENOSPC = libc::ENOSPC, ++ ESPIPE = libc::ESPIPE, ++ EROFS = libc::EROFS, ++ EMLINK = libc::EMLINK, ++ EPIPE = libc::EPIPE, ++ EDOM = libc::EDOM, ++ ERANGE = libc::ERANGE, ++ EAGAIN = libc::EAGAIN, ++ EINPROGRESS = libc::EINPROGRESS, ++ EALREADY = libc::EALREADY, ++ ENOTSOCK = libc::ENOTSOCK, ++ EDESTADDRREQ = libc::EDESTADDRREQ, ++ EMSGSIZE = libc::EMSGSIZE, ++ EPROTOTYPE = libc::EPROTOTYPE, ++ ENOPROTOOPT = libc::ENOPROTOOPT, ++ EPROTONOSUPPORT = libc::EPROTONOSUPPORT, ++ ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT, ++ EOPNOTSUPP = libc::EOPNOTSUPP, ++ EPFNOSUPPORT = libc::EPFNOSUPPORT, ++ EAFNOSUPPORT = libc::EAFNOSUPPORT, ++ EADDRINUSE = libc::EADDRINUSE, ++ EADDRNOTAVAIL = libc::EADDRNOTAVAIL, ++ ENETDOWN = libc::ENETDOWN, ++ ENETUNREACH = libc::ENETUNREACH, ++ ENETRESET = libc::ENETRESET, ++ ECONNABORTED = libc::ECONNABORTED, ++ ECONNRESET = libc::ECONNRESET, ++ ENOBUFS = libc::ENOBUFS, ++ EISCONN = libc::EISCONN, ++ ENOTCONN = libc::ENOTCONN, ++ ESHUTDOWN = libc::ESHUTDOWN, ++ ETOOMANYREFS = libc::ETOOMANYREFS, ++ ETIMEDOUT = libc::ETIMEDOUT, ++ ECONNREFUSED = libc::ECONNREFUSED, ++ ELOOP = libc::ELOOP, ++ ENAMETOOLONG = libc::ENAMETOOLONG, ++ EHOSTDOWN = libc::EHOSTDOWN, ++ EHOSTUNREACH = libc::EHOSTUNREACH, ++ ENOTEMPTY = libc::ENOTEMPTY, ++ EUSERS = libc::EUSERS, ++ EDQUOT = libc::EDQUOT, ++ ESTALE = libc::ESTALE, ++ EREMOTE = libc::EREMOTE, ++ ENOLCK = libc::ENOLCK, ++ ENOSYS = libc::ENOSYS, ++ EIDRM = libc::EIDRM, ++ ENOMSG = libc::ENOMSG, ++ EOVERFLOW = libc::EOVERFLOW, ++ EILSEQ = libc::EILSEQ, ++ ECANCELED = libc::ECANCELED, ++ EBADMSG = libc::EBADMSG, ++ ENODATA = libc::ENODATA, ++ ENOSR = libc::ENOSR, ++ ENOSTR = libc::ENOSTR, ++ ETIME = libc::ETIME, ++ EMULTIHOP = libc::EMULTIHOP, ++ ENOLINK = libc::ENOLINK, ++ EPROTO = libc::EPROTO, ++ } ++ ++ impl Errno { ++ pub const EWOULDBLOCK: Errno = Errno::EAGAIN; ++ } ++ ++ pub const fn from_i32(e: i32) -> Errno { ++ use self::Errno::*; ++ ++ match e { ++ libc::EPERM => EPERM, ++ libc::ENOENT => ENOENT, ++ libc::ESRCH => ESRCH, ++ libc::EINTR => EINTR, ++ libc::EIO => EIO, ++ libc::ENXIO => ENXIO, ++ libc::E2BIG => E2BIG, ++ libc::ENOEXEC => ENOEXEC, ++ libc::EBADF => EBADF, ++ libc::ECHILD => ECHILD, ++ libc::EDEADLK => EDEADLK, ++ libc::ENOMEM => ENOMEM, ++ libc::EACCES => EACCES, ++ libc::EFAULT => EFAULT, ++ libc::ENOTBLK => ENOTBLK, ++ libc::EBUSY => EBUSY, ++ libc::EEXIST => EEXIST, ++ libc::EXDEV => EXDEV, ++ libc::ENODEV => ENODEV, ++ libc::ENOTDIR => ENOTDIR, ++ libc::EISDIR => EISDIR, ++ libc::EINVAL => EINVAL, ++ libc::ENFILE => ENFILE, ++ libc::EMFILE => EMFILE, ++ libc::ENOTTY => ENOTTY, ++ libc::ETXTBSY => ETXTBSY, ++ libc::EFBIG => EFBIG, ++ libc::ENOSPC => ENOSPC, ++ libc::ESPIPE => ESPIPE, ++ libc::EROFS => EROFS, ++ libc::EMLINK => EMLINK, ++ libc::EPIPE => EPIPE, ++ libc::EDOM => EDOM, ++ libc::ERANGE => ERANGE, ++ libc::EAGAIN => EAGAIN, ++ libc::EINPROGRESS => EINPROGRESS, ++ libc::EALREADY => EALREADY, ++ libc::ENOTSOCK => ENOTSOCK, ++ libc::EDESTADDRREQ => EDESTADDRREQ, ++ libc::EMSGSIZE => EMSGSIZE, ++ libc::EPROTOTYPE => EPROTOTYPE, ++ libc::ENOPROTOOPT => ENOPROTOOPT, ++ libc::EPROTONOSUPPORT => EPROTONOSUPPORT, ++ libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT, ++ libc::EOPNOTSUPP => EOPNOTSUPP, ++ libc::EPFNOSUPPORT => EPFNOSUPPORT, ++ libc::EAFNOSUPPORT => EAFNOSUPPORT, ++ libc::EADDRINUSE => EADDRINUSE, ++ libc::EADDRNOTAVAIL => EADDRNOTAVAIL, ++ libc::ENETDOWN => ENETDOWN, ++ libc::ENETUNREACH => ENETUNREACH, ++ libc::ENETRESET => ENETRESET, ++ libc::ECONNABORTED => ECONNABORTED, ++ libc::ECONNRESET => ECONNRESET, ++ libc::ENOBUFS => ENOBUFS, ++ libc::EISCONN => EISCONN, ++ libc::ENOTCONN => ENOTCONN, ++ libc::ESHUTDOWN => ESHUTDOWN, ++ libc::ETOOMANYREFS => ETOOMANYREFS, ++ libc::ETIMEDOUT => ETIMEDOUT, ++ libc::ECONNREFUSED => ECONNREFUSED, ++ libc::ELOOP => ELOOP, ++ libc::ENAMETOOLONG => ENAMETOOLONG, ++ libc::EHOSTDOWN => EHOSTDOWN, ++ libc::EHOSTUNREACH => EHOSTUNREACH, ++ libc::ENOTEMPTY => ENOTEMPTY, ++ libc::EUSERS => EUSERS, ++ libc::EDQUOT => EDQUOT, ++ libc::ESTALE => ESTALE, ++ libc::EREMOTE => EREMOTE, ++ libc::ENOLCK => ENOLCK, ++ libc::ENOSYS => ENOSYS, ++ libc::EIDRM => EIDRM, ++ libc::ENOMSG => ENOMSG, ++ libc::EOVERFLOW => EOVERFLOW, ++ libc::EILSEQ => EILSEQ, ++ libc::ECANCELED => ECANCELED, ++ libc::EBADMSG => EBADMSG, ++ libc::ENODATA => ENODATA, ++ libc::ENOSR => ENOSR, ++ libc::ENOSTR => ENOSTR, ++ libc::ETIME => ETIME, ++ libc::EMULTIHOP => EMULTIHOP, ++ libc::ENOLINK => ENOLINK, ++ libc::EPROTO => EPROTO, ++ _ => UnknownErrno, ++ } ++ } ++} ++ ++#[cfg(any(target_os = "illumos", target_os = "solaris"))] ++mod consts { ++ #[derive(Clone, Copy, Debug, Eq, PartialEq)] ++ #[repr(i32)] ++ #[non_exhaustive] ++ pub enum Errno { ++ UnknownErrno = 0, ++ EPERM = libc::EPERM, ++ ENOENT = libc::ENOENT, ++ ESRCH = libc::ESRCH, ++ EINTR = libc::EINTR, ++ EIO = libc::EIO, ++ ENXIO = libc::ENXIO, ++ E2BIG = libc::E2BIG, ++ ENOEXEC = libc::ENOEXEC, ++ EBADF = libc::EBADF, ++ ECHILD = libc::ECHILD, ++ EAGAIN = libc::EAGAIN, ++ ENOMEM = libc::ENOMEM, ++ EACCES = libc::EACCES, ++ EFAULT = libc::EFAULT, ++ ENOTBLK = libc::ENOTBLK, ++ EBUSY = libc::EBUSY, ++ EEXIST = libc::EEXIST, ++ EXDEV = libc::EXDEV, ++ ENODEV = libc::ENODEV, ++ ENOTDIR = libc::ENOTDIR, ++ EISDIR = libc::EISDIR, ++ EINVAL = libc::EINVAL, ++ ENFILE = libc::ENFILE, ++ EMFILE = libc::EMFILE, ++ ENOTTY = libc::ENOTTY, ++ ETXTBSY = libc::ETXTBSY, ++ EFBIG = libc::EFBIG, ++ ENOSPC = libc::ENOSPC, ++ ESPIPE = libc::ESPIPE, ++ EROFS = libc::EROFS, ++ EMLINK = libc::EMLINK, ++ EPIPE = libc::EPIPE, ++ EDOM = libc::EDOM, ++ ERANGE = libc::ERANGE, ++ ENOMSG = libc::ENOMSG, ++ EIDRM = libc::EIDRM, ++ ECHRNG = libc::ECHRNG, ++ EL2NSYNC = libc::EL2NSYNC, ++ EL3HLT = libc::EL3HLT, ++ EL3RST = libc::EL3RST, ++ ELNRNG = libc::ELNRNG, ++ EUNATCH = libc::EUNATCH, ++ ENOCSI = libc::ENOCSI, ++ EL2HLT = libc::EL2HLT, ++ EDEADLK = libc::EDEADLK, ++ ENOLCK = libc::ENOLCK, ++ ECANCELED = libc::ECANCELED, ++ ENOTSUP = libc::ENOTSUP, ++ EDQUOT = libc::EDQUOT, ++ EBADE = libc::EBADE, ++ EBADR = libc::EBADR, ++ EXFULL = libc::EXFULL, ++ ENOANO = libc::ENOANO, ++ EBADRQC = libc::EBADRQC, ++ EBADSLT = libc::EBADSLT, ++ EDEADLOCK = libc::EDEADLOCK, ++ EBFONT = libc::EBFONT, ++ EOWNERDEAD = libc::EOWNERDEAD, ++ ENOTRECOVERABLE = libc::ENOTRECOVERABLE, ++ ENOSTR = libc::ENOSTR, ++ ENODATA = libc::ENODATA, ++ ETIME = libc::ETIME, ++ ENOSR = libc::ENOSR, ++ ENONET = libc::ENONET, ++ ENOPKG = libc::ENOPKG, ++ EREMOTE = libc::EREMOTE, ++ ENOLINK = libc::ENOLINK, ++ EADV = libc::EADV, ++ ESRMNT = libc::ESRMNT, ++ ECOMM = libc::ECOMM, ++ EPROTO = libc::EPROTO, ++ ELOCKUNMAPPED = libc::ELOCKUNMAPPED, ++ ENOTACTIVE = libc::ENOTACTIVE, ++ EMULTIHOP = libc::EMULTIHOP, ++ EBADMSG = libc::EBADMSG, ++ ENAMETOOLONG = libc::ENAMETOOLONG, ++ EOVERFLOW = libc::EOVERFLOW, ++ ENOTUNIQ = libc::ENOTUNIQ, ++ EBADFD = libc::EBADFD, ++ EREMCHG = libc::EREMCHG, ++ ELIBACC = libc::ELIBACC, ++ ELIBBAD = libc::ELIBBAD, ++ ELIBSCN = libc::ELIBSCN, ++ ELIBMAX = libc::ELIBMAX, ++ ELIBEXEC = libc::ELIBEXEC, ++ EILSEQ = libc::EILSEQ, ++ ENOSYS = libc::ENOSYS, ++ ELOOP = libc::ELOOP, ++ ERESTART = libc::ERESTART, ++ ESTRPIPE = libc::ESTRPIPE, ++ ENOTEMPTY = libc::ENOTEMPTY, ++ EUSERS = libc::EUSERS, ++ ENOTSOCK = libc::ENOTSOCK, ++ EDESTADDRREQ = libc::EDESTADDRREQ, ++ EMSGSIZE = libc::EMSGSIZE, ++ EPROTOTYPE = libc::EPROTOTYPE, ++ ENOPROTOOPT = libc::ENOPROTOOPT, ++ EPROTONOSUPPORT = libc::EPROTONOSUPPORT, ++ ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT, ++ EOPNOTSUPP = libc::EOPNOTSUPP, ++ EPFNOSUPPORT = libc::EPFNOSUPPORT, ++ EAFNOSUPPORT = libc::EAFNOSUPPORT, ++ EADDRINUSE = libc::EADDRINUSE, ++ EADDRNOTAVAIL = libc::EADDRNOTAVAIL, ++ ENETDOWN = libc::ENETDOWN, ++ ENETUNREACH = libc::ENETUNREACH, ++ ENETRESET = libc::ENETRESET, ++ ECONNABORTED = libc::ECONNABORTED, ++ ECONNRESET = libc::ECONNRESET, ++ ENOBUFS = libc::ENOBUFS, ++ EISCONN = libc::EISCONN, ++ ENOTCONN = libc::ENOTCONN, ++ ESHUTDOWN = libc::ESHUTDOWN, ++ ETOOMANYREFS = libc::ETOOMANYREFS, ++ ETIMEDOUT = libc::ETIMEDOUT, ++ ECONNREFUSED = libc::ECONNREFUSED, ++ EHOSTDOWN = libc::EHOSTDOWN, ++ EHOSTUNREACH = libc::EHOSTUNREACH, ++ EALREADY = libc::EALREADY, ++ EINPROGRESS = libc::EINPROGRESS, ++ ESTALE = libc::ESTALE, ++ } ++ ++ impl Errno { ++ pub const ELAST: Errno = Errno::ESTALE; ++ pub const EWOULDBLOCK: Errno = Errno::EAGAIN; ++ } ++ ++ pub const fn from_i32(e: i32) -> Errno { ++ use self::Errno::*; ++ ++ match e { ++ libc::EPERM => EPERM, ++ libc::ENOENT => ENOENT, ++ libc::ESRCH => ESRCH, ++ libc::EINTR => EINTR, ++ libc::EIO => EIO, ++ libc::ENXIO => ENXIO, ++ libc::E2BIG => E2BIG, ++ libc::ENOEXEC => ENOEXEC, ++ libc::EBADF => EBADF, ++ libc::ECHILD => ECHILD, ++ libc::EAGAIN => EAGAIN, ++ libc::ENOMEM => ENOMEM, ++ libc::EACCES => EACCES, ++ libc::EFAULT => EFAULT, ++ libc::ENOTBLK => ENOTBLK, ++ libc::EBUSY => EBUSY, ++ libc::EEXIST => EEXIST, ++ libc::EXDEV => EXDEV, ++ libc::ENODEV => ENODEV, ++ libc::ENOTDIR => ENOTDIR, ++ libc::EISDIR => EISDIR, ++ libc::EINVAL => EINVAL, ++ libc::ENFILE => ENFILE, ++ libc::EMFILE => EMFILE, ++ libc::ENOTTY => ENOTTY, ++ libc::ETXTBSY => ETXTBSY, ++ libc::EFBIG => EFBIG, ++ libc::ENOSPC => ENOSPC, ++ libc::ESPIPE => ESPIPE, ++ libc::EROFS => EROFS, ++ libc::EMLINK => EMLINK, ++ libc::EPIPE => EPIPE, ++ libc::EDOM => EDOM, ++ libc::ERANGE => ERANGE, ++ libc::ENOMSG => ENOMSG, ++ libc::EIDRM => EIDRM, ++ libc::ECHRNG => ECHRNG, ++ libc::EL2NSYNC => EL2NSYNC, ++ libc::EL3HLT => EL3HLT, ++ libc::EL3RST => EL3RST, ++ libc::ELNRNG => ELNRNG, ++ libc::EUNATCH => EUNATCH, ++ libc::ENOCSI => ENOCSI, ++ libc::EL2HLT => EL2HLT, ++ libc::EDEADLK => EDEADLK, ++ libc::ENOLCK => ENOLCK, ++ libc::ECANCELED => ECANCELED, ++ libc::ENOTSUP => ENOTSUP, ++ libc::EDQUOT => EDQUOT, ++ libc::EBADE => EBADE, ++ libc::EBADR => EBADR, ++ libc::EXFULL => EXFULL, ++ libc::ENOANO => ENOANO, ++ libc::EBADRQC => EBADRQC, ++ libc::EBADSLT => EBADSLT, ++ libc::EDEADLOCK => EDEADLOCK, ++ libc::EBFONT => EBFONT, ++ libc::EOWNERDEAD => EOWNERDEAD, ++ libc::ENOTRECOVERABLE => ENOTRECOVERABLE, ++ libc::ENOSTR => ENOSTR, ++ libc::ENODATA => ENODATA, ++ libc::ETIME => ETIME, ++ libc::ENOSR => ENOSR, ++ libc::ENONET => ENONET, ++ libc::ENOPKG => ENOPKG, ++ libc::EREMOTE => EREMOTE, ++ libc::ENOLINK => ENOLINK, ++ libc::EADV => EADV, ++ libc::ESRMNT => ESRMNT, ++ libc::ECOMM => ECOMM, ++ libc::EPROTO => EPROTO, ++ libc::ELOCKUNMAPPED => ELOCKUNMAPPED, ++ libc::ENOTACTIVE => ENOTACTIVE, ++ libc::EMULTIHOP => EMULTIHOP, ++ libc::EBADMSG => EBADMSG, ++ libc::ENAMETOOLONG => ENAMETOOLONG, ++ libc::EOVERFLOW => EOVERFLOW, ++ libc::ENOTUNIQ => ENOTUNIQ, ++ libc::EBADFD => EBADFD, ++ libc::EREMCHG => EREMCHG, ++ libc::ELIBACC => ELIBACC, ++ libc::ELIBBAD => ELIBBAD, ++ libc::ELIBSCN => ELIBSCN, ++ libc::ELIBMAX => ELIBMAX, ++ libc::ELIBEXEC => ELIBEXEC, ++ libc::EILSEQ => EILSEQ, ++ libc::ENOSYS => ENOSYS, ++ libc::ELOOP => ELOOP, ++ libc::ERESTART => ERESTART, ++ libc::ESTRPIPE => ESTRPIPE, ++ libc::ENOTEMPTY => ENOTEMPTY, ++ libc::EUSERS => EUSERS, ++ libc::ENOTSOCK => ENOTSOCK, ++ libc::EDESTADDRREQ => EDESTADDRREQ, ++ libc::EMSGSIZE => EMSGSIZE, ++ libc::EPROTOTYPE => EPROTOTYPE, ++ libc::ENOPROTOOPT => ENOPROTOOPT, ++ libc::EPROTONOSUPPORT => EPROTONOSUPPORT, ++ libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT, ++ libc::EOPNOTSUPP => EOPNOTSUPP, ++ libc::EPFNOSUPPORT => EPFNOSUPPORT, ++ libc::EAFNOSUPPORT => EAFNOSUPPORT, ++ libc::EADDRINUSE => EADDRINUSE, ++ libc::EADDRNOTAVAIL => EADDRNOTAVAIL, ++ libc::ENETDOWN => ENETDOWN, ++ libc::ENETUNREACH => ENETUNREACH, ++ libc::ENETRESET => ENETRESET, ++ libc::ECONNABORTED => ECONNABORTED, ++ libc::ECONNRESET => ECONNRESET, ++ libc::ENOBUFS => ENOBUFS, ++ libc::EISCONN => EISCONN, ++ libc::ENOTCONN => ENOTCONN, ++ libc::ESHUTDOWN => ESHUTDOWN, ++ libc::ETOOMANYREFS => ETOOMANYREFS, ++ libc::ETIMEDOUT => ETIMEDOUT, ++ libc::ECONNREFUSED => ECONNREFUSED, ++ libc::EHOSTDOWN => EHOSTDOWN, ++ libc::EHOSTUNREACH => EHOSTUNREACH, ++ libc::EALREADY => EALREADY, ++ libc::EINPROGRESS => EINPROGRESS, ++ libc::ESTALE => ESTALE, ++ _ => UnknownErrno, ++ } ++ } ++} ++ ++#[cfg(target_os = "haiku")] ++mod consts { ++ #[derive(Clone, Copy, Debug, Eq, PartialEq)] ++ #[repr(i32)] ++ #[non_exhaustive] ++ pub enum Errno { ++ UnknownErrno = 0, ++ EPERM = libc::EPERM, ++ ENOENT = libc::ENOENT, ++ ESRCH = libc::ESRCH, ++ EINTR = libc::EINTR, ++ EIO = libc::EIO, ++ ENXIO = libc::ENXIO, ++ E2BIG = libc::E2BIG, ++ ENOEXEC = libc::ENOEXEC, ++ EBADF = libc::EBADF, ++ ECHILD = libc::ECHILD, ++ EDEADLK = libc::EDEADLK, ++ ENOMEM = libc::ENOMEM, ++ EACCES = libc::EACCES, ++ EFAULT = libc::EFAULT, ++ EBUSY = libc::EBUSY, ++ EEXIST = libc::EEXIST, ++ EXDEV = libc::EXDEV, ++ ENODEV = libc::ENODEV, ++ ENOTDIR = libc::ENOTDIR, ++ EISDIR = libc::EISDIR, ++ EINVAL = libc::EINVAL, ++ ENFILE = libc::ENFILE, ++ EMFILE = libc::EMFILE, ++ ENOTTY = libc::ENOTTY, ++ ETXTBSY = libc::ETXTBSY, ++ EFBIG = libc::EFBIG, ++ ENOSPC = libc::ENOSPC, ++ ESPIPE = libc::ESPIPE, ++ EROFS = libc::EROFS, ++ EMLINK = libc::EMLINK, ++ EPIPE = libc::EPIPE, ++ EDOM = libc::EDOM, ++ ERANGE = libc::ERANGE, ++ EAGAIN = libc::EAGAIN, ++ EINPROGRESS = libc::EINPROGRESS, ++ EALREADY = libc::EALREADY, ++ ENOTSOCK = libc::ENOTSOCK, ++ EDESTADDRREQ = libc::EDESTADDRREQ, ++ EMSGSIZE = libc::EMSGSIZE, ++ EPROTOTYPE = libc::EPROTOTYPE, ++ ENOPROTOOPT = libc::ENOPROTOOPT, ++ EPROTONOSUPPORT = libc::EPROTONOSUPPORT, ++ ENOTSUP = libc::ENOTSUP, ++ EADDRINUSE = libc::EADDRINUSE, ++ EADDRNOTAVAIL = libc::EADDRNOTAVAIL, ++ ENETDOWN = libc::ENETDOWN, ++ ENETUNREACH = libc::ENETUNREACH, ++ ENETRESET = libc::ENETRESET, ++ ECONNABORTED = libc::ECONNABORTED, ++ ECONNRESET = libc::ECONNRESET, ++ ENOBUFS = libc::ENOBUFS, ++ EISCONN = libc::EISCONN, ++ ENOTCONN = libc::ENOTCONN, ++ ESHUTDOWN = libc::ESHUTDOWN, ++ ETIMEDOUT = libc::ETIMEDOUT, ++ ECONNREFUSED = libc::ECONNREFUSED, ++ ELOOP = libc::ELOOP, ++ ENAMETOOLONG = libc::ENAMETOOLONG, ++ EHOSTDOWN = libc::EHOSTDOWN, ++ EHOSTUNREACH = libc::EHOSTUNREACH, ++ ENOTEMPTY = libc::ENOTEMPTY, ++ EDQUOT = libc::EDQUOT, ++ ESTALE = libc::ESTALE, ++ ENOLCK = libc::ENOLCK, ++ ENOSYS = libc::ENOSYS, ++ EIDRM = libc::EIDRM, ++ ENOMSG = libc::ENOMSG, ++ EOVERFLOW = libc::EOVERFLOW, ++ ECANCELED = libc::ECANCELED, ++ EILSEQ = libc::EILSEQ, ++ ENOATTR = libc::ENOATTR, ++ EBADMSG = libc::EBADMSG, ++ EMULTIHOP = libc::EMULTIHOP, ++ ENOLINK = libc::ENOLINK, ++ EPROTO = libc::EPROTO, ++ } ++ ++ impl Errno { ++ pub const EWOULDBLOCK: Errno = Errno::EAGAIN; ++ pub const EDEADLOCK: Errno = Errno::EDEADLK; ++ pub const EOPNOTSUPP: Errno = Errno::ENOTSUP; ++ } ++ ++ pub const fn from_i32(e: i32) -> Errno { ++ use self::Errno::*; ++ ++ match e { ++ libc::EPERM => EPERM, ++ libc::ENOENT => ENOENT, ++ libc::ESRCH => ESRCH, ++ libc::EINTR => EINTR, ++ libc::EIO => EIO, ++ libc::ENXIO => ENXIO, ++ libc::E2BIG => E2BIG, ++ libc::ENOEXEC => ENOEXEC, ++ libc::EBADF => EBADF, ++ libc::ECHILD => ECHILD, ++ libc::EDEADLK => EDEADLK, ++ libc::ENOMEM => ENOMEM, ++ libc::EACCES => EACCES, ++ libc::EFAULT => EFAULT, ++ libc::EBUSY => EBUSY, ++ libc::EEXIST => EEXIST, ++ libc::EXDEV => EXDEV, ++ libc::ENODEV => ENODEV, ++ libc::ENOTDIR => ENOTDIR, ++ libc::EISDIR => EISDIR, ++ libc::EINVAL => EINVAL, ++ libc::ENFILE => ENFILE, ++ libc::EMFILE => EMFILE, ++ libc::ENOTTY => ENOTTY, ++ libc::ETXTBSY => ETXTBSY, ++ libc::EFBIG => EFBIG, ++ libc::ENOSPC => ENOSPC, ++ libc::ESPIPE => ESPIPE, ++ libc::EROFS => EROFS, ++ libc::EMLINK => EMLINK, ++ libc::EPIPE => EPIPE, ++ libc::EDOM => EDOM, ++ libc::ERANGE => ERANGE, ++ libc::EAGAIN => EAGAIN, ++ libc::EINPROGRESS => EINPROGRESS, ++ libc::EALREADY => EALREADY, ++ libc::ENOTSOCK => ENOTSOCK, ++ libc::EDESTADDRREQ => EDESTADDRREQ, ++ libc::EMSGSIZE => EMSGSIZE, ++ libc::EPROTOTYPE => EPROTOTYPE, ++ libc::ENOPROTOOPT => ENOPROTOOPT, ++ libc::EPROTONOSUPPORT => EPROTONOSUPPORT, ++ libc::ENOTSUP => ENOTSUP, ++ libc::EADDRINUSE => EADDRINUSE, ++ libc::EADDRNOTAVAIL => EADDRNOTAVAIL, ++ libc::ENETDOWN => ENETDOWN, ++ libc::ENETUNREACH => ENETUNREACH, ++ libc::ENETRESET => ENETRESET, ++ libc::ECONNABORTED => ECONNABORTED, ++ libc::ECONNRESET => ECONNRESET, ++ libc::ENOBUFS => ENOBUFS, ++ libc::EISCONN => EISCONN, ++ libc::ENOTCONN => ENOTCONN, ++ libc::ESHUTDOWN => ESHUTDOWN, ++ libc::ETIMEDOUT => ETIMEDOUT, ++ libc::ECONNREFUSED => ECONNREFUSED, ++ libc::ELOOP => ELOOP, ++ libc::ENAMETOOLONG => ENAMETOOLONG, ++ libc::EHOSTDOWN => EHOSTDOWN, ++ libc::EHOSTUNREACH => EHOSTUNREACH, ++ libc::ENOTEMPTY => ENOTEMPTY, ++ libc::EDQUOT => EDQUOT, ++ libc::ESTALE => ESTALE, ++ libc::ENOLCK => ENOLCK, ++ libc::ENOSYS => ENOSYS, ++ libc::EIDRM => EIDRM, ++ libc::ENOMSG => ENOMSG, ++ libc::EOVERFLOW => EOVERFLOW, ++ libc::ECANCELED => ECANCELED, ++ libc::EILSEQ => EILSEQ, ++ libc::ENOATTR => ENOATTR, ++ libc::EBADMSG => EBADMSG, ++ libc::EMULTIHOP => EMULTIHOP, ++ libc::ENOLINK => ENOLINK, ++ libc::EPROTO => EPROTO, ++ _ => UnknownErrno, + } + } + } +diff --git a/vendor/nix/src/errno_dragonfly.c b/vendor/nix/src/errno_dragonfly.c +deleted file mode 100644 +index 32fb4da..0000000 +--- a/vendor/nix/src/errno_dragonfly.c ++++ /dev/null +@@ -1,3 +0,0 @@ +-#include +- +-int *errno_location() { return &errno; } +diff --git a/vendor/nix/src/fcntl.rs b/vendor/nix/src/fcntl.rs +index 1d66eb7..6508283 100644 +--- a/vendor/nix/src/fcntl.rs ++++ b/vendor/nix/src/fcntl.rs +@@ -1,27 +1,32 @@ +-use {Result, NixPath}; +-use errno::Errno; +-use libc::{self, c_int, c_uint, c_char, size_t, ssize_t}; +-use sys::stat::Mode; +-use std::os::raw; +-use std::os::unix::io::RawFd; ++use crate::errno::Errno; ++use libc::{self, c_char, c_int, c_uint, size_t, ssize_t}; + use std::ffi::OsString; ++#[cfg(not(target_os = "redox"))] ++use std::os::raw; + use std::os::unix::ffi::OsStringExt; ++use std::os::unix::io::RawFd; + ++#[cfg(feature = "fs")] ++use crate::{sys::stat::Mode, NixPath, Result}; + #[cfg(any(target_os = "android", target_os = "linux"))] + use std::ptr; // For splice and copy_file_range +-#[cfg(any(target_os = "android", target_os = "linux"))] +-use sys::uio::IoVec; // For vmsplice +- +-#[cfg(any(target_os = "linux", +- target_os = "android", +- target_os = "emscripten", +- target_os = "fuchsia", +- any(target_os = "wasi", target_env = "wasi"), +- target_env = "uclibc", +- target_env = "freebsd"))] +-pub use self::posix_fadvise::*; +- +-libc_bitflags!{ ++ ++#[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "wasi", ++ target_env = "uclibc", ++ target_os = "freebsd" ++))] ++#[cfg(feature = "fs")] ++pub use self::posix_fadvise::{posix_fadvise, PosixFadviseAdvice}; ++ ++#[cfg(not(target_os = "redox"))] ++#[cfg(any(feature = "fs", feature = "process"))] ++libc_bitflags! { ++ #[cfg_attr(docsrs, doc(cfg(any(feature = "fs", feature = "process"))))] + pub struct AtFlags: c_int { + AT_REMOVEDIR; + AT_SYMLINK_FOLLOW; +@@ -30,20 +35,27 @@ libc_bitflags!{ + AT_NO_AUTOMOUNT; + #[cfg(any(target_os = "android", target_os = "linux"))] + AT_EMPTY_PATH; ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ AT_EACCESS; + } + } + ++#[cfg(any(feature = "fs", feature = "term"))] + libc_bitflags!( + /// Configuration options for opened files. ++ #[cfg_attr(docsrs, doc(cfg(any(feature = "fs", feature = "term"))))] + pub struct OFlag: c_int { + /// Mask for the access mode of the file. + O_ACCMODE; + /// Use alternate I/O semantics. + #[cfg(target_os = "netbsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_ALT_IO; + /// Open the file in append-only mode. + O_APPEND; + /// Generate a signal when input or output becomes possible. ++ #[cfg(not(any(target_os = "illumos", target_os = "solaris", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_ASYNC; + /// Closes the file descriptor once an `execve` call is made. + /// +@@ -57,8 +69,11 @@ libc_bitflags!( + target_os = "freebsd", + target_os = "linux", + target_os = "netbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_DIRECT; + /// If the specified path isn't a directory, fail. ++ #[cfg(not(any(target_os = "illumos", target_os = "solaris")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_DIRECTORY; + /// Implicitly follow each `write()` with an `fdatasync()`. + #[cfg(any(target_os = "android", +@@ -67,11 +82,13 @@ libc_bitflags!( + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_DSYNC; + /// Error out if a file was not created. + O_EXCL; + /// Open for execute only. + #[cfg(target_os = "freebsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_EXEC; + /// Open with an exclusive file lock. + #[cfg(any(target_os = "dragonfly", +@@ -79,7 +96,9 @@ libc_bitflags!( + target_os = "ios", + target_os = "macos", + target_os = "netbsd", +- target_os = "openbsd"))] ++ target_os = "openbsd", ++ target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_EXLOCK; + /// Same as `O_SYNC`. + #[cfg(any(target_os = "dragonfly", +@@ -88,17 +107,25 @@ libc_bitflags!( + all(target_os = "linux", not(target_env = "musl")), + target_os = "macos", + target_os = "netbsd", +- target_os = "openbsd"))] ++ target_os = "openbsd", ++ target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_FSYNC; + /// Allow files whose sizes can't be represented in an `off_t` to be opened. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_LARGEFILE; + /// Do not update the file last access time during `read(2)`s. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_NOATIME; + /// Don't attach the device as the process' controlling terminal. ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_NOCTTY; + /// Same as `O_NONBLOCK`. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_NDELAY; + /// `open()` will fail if the given path is a symbolic link. + O_NOFOLLOW; +@@ -106,11 +133,13 @@ libc_bitflags!( + O_NONBLOCK; + /// Don't deliver `SIGPIPE`. + #[cfg(target_os = "netbsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_NOSIGPIPE; + /// Obtain a file descriptor for low-level access. + /// + /// The file itself is not opened and other file operations will fail. +- #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_PATH; + /// Only allow reading. + /// +@@ -122,9 +151,11 @@ libc_bitflags!( + O_RDWR; + /// Similar to `O_DSYNC` but applies to `read`s instead. + #[cfg(any(target_os = "linux", target_os = "netbsd", target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_RSYNC; + /// Skip search permission checks. + #[cfg(target_os = "netbsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_SEARCH; + /// Open with a shared file lock. + #[cfg(any(target_os = "dragonfly", +@@ -132,17 +163,23 @@ libc_bitflags!( + target_os = "ios", + target_os = "macos", + target_os = "netbsd", +- target_os = "openbsd"))] ++ target_os = "openbsd", ++ target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_SHLOCK; + /// Implicitly follow each `write()` with an `fsync()`. ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_SYNC; + /// Create an unnamed temporary file. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_TMPFILE; + /// Truncate an existing regular file to 0 length if it allows writing. + O_TRUNC; + /// Restore default TTY attributes. + #[cfg(target_os = "freebsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_TTY_INIT; + /// Only allow writing. + /// +@@ -151,75 +188,201 @@ libc_bitflags!( + } + ); + ++feature! { ++#![feature = "fs"] ++ ++// The conversion is not identical on all operating systems. ++#[allow(clippy::useless_conversion)] + pub fn open(path: &P, oflag: OFlag, mode: Mode) -> Result { + let fd = path.with_nix_path(|cstr| { +- let modebits = c_uint::from(mode.bits()); +- unsafe { libc::open(cstr.as_ptr(), oflag.bits(), modebits) } ++ unsafe { libc::open(cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) } + })?; + + Errno::result(fd) + } + +-pub fn openat(dirfd: RawFd, path: &P, oflag: OFlag, mode: Mode) -> Result { ++// The conversion is not identical on all operating systems. ++#[allow(clippy::useless_conversion)] ++#[cfg(not(target_os = "redox"))] ++pub fn openat( ++ dirfd: RawFd, ++ path: &P, ++ oflag: OFlag, ++ mode: Mode, ++) -> Result { + let fd = path.with_nix_path(|cstr| { +- let modebits = c_uint::from(mode.bits()); +- unsafe { libc::openat(dirfd, cstr.as_ptr(), oflag.bits(), modebits) } ++ unsafe { libc::openat(dirfd, cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) } + })?; + Errno::result(fd) + } + +-pub fn renameat(old_dirfd: Option, old_path: &P1, +- new_dirfd: Option, new_path: &P2) +- -> Result<()> { ++#[cfg(not(target_os = "redox"))] ++pub fn renameat( ++ old_dirfd: Option, ++ old_path: &P1, ++ new_dirfd: Option, ++ new_path: &P2, ++) -> Result<()> { + let res = old_path.with_nix_path(|old_cstr| { + new_path.with_nix_path(|new_cstr| unsafe { +- libc::renameat(at_rawfd(old_dirfd), old_cstr.as_ptr(), +- at_rawfd(new_dirfd), new_cstr.as_ptr()) ++ libc::renameat( ++ at_rawfd(old_dirfd), ++ old_cstr.as_ptr(), ++ at_rawfd(new_dirfd), ++ new_cstr.as_ptr(), ++ ) + }) + })??; + Errno::result(res).map(drop) + } ++} + +-fn wrap_readlink_result(v: &mut Vec, res: ssize_t) -> Result { +- match Errno::result(res) { +- Err(err) => Err(err), +- Ok(len) => { +- unsafe { v.set_len(len as usize) } +- Ok(OsString::from_vec(v.to_vec())) +- } ++#[cfg(all(target_os = "linux", target_env = "gnu",))] ++#[cfg(feature = "fs")] ++libc_bitflags! { ++ #[cfg_attr(docsrs, doc(cfg(feature = "fs")))] ++ pub struct RenameFlags: u32 { ++ RENAME_EXCHANGE; ++ RENAME_NOREPLACE; ++ RENAME_WHITEOUT; + } + } + +-pub fn readlink(path: &P) -> Result { +- let mut v = Vec::with_capacity(libc::PATH_MAX as usize); +- let res = path.with_nix_path(|cstr| { +- unsafe { libc::readlink(cstr.as_ptr(), v.as_mut_ptr() as *mut c_char, v.capacity() as size_t) } +- })?; ++feature! { ++#![feature = "fs"] ++#[cfg(all( ++ target_os = "linux", ++ target_env = "gnu", ++))] ++pub fn renameat2( ++ old_dirfd: Option, ++ old_path: &P1, ++ new_dirfd: Option, ++ new_path: &P2, ++ flags: RenameFlags, ++) -> Result<()> { ++ let res = old_path.with_nix_path(|old_cstr| { ++ new_path.with_nix_path(|new_cstr| unsafe { ++ libc::renameat2( ++ at_rawfd(old_dirfd), ++ old_cstr.as_ptr(), ++ at_rawfd(new_dirfd), ++ new_cstr.as_ptr(), ++ flags.bits(), ++ ) ++ }) ++ })??; ++ Errno::result(res).map(drop) ++} + +- wrap_readlink_result(&mut v, res) ++fn wrap_readlink_result(mut v: Vec, len: ssize_t) -> Result { ++ unsafe { v.set_len(len as usize) } ++ v.shrink_to_fit(); ++ Ok(OsString::from_vec(v.to_vec())) + } + ++fn readlink_maybe_at( ++ dirfd: Option, ++ path: &P, ++ v: &mut Vec, ++) -> Result { ++ path.with_nix_path(|cstr| unsafe { ++ match dirfd { ++ #[cfg(target_os = "redox")] ++ Some(_) => unreachable!(), ++ #[cfg(not(target_os = "redox"))] ++ Some(dirfd) => libc::readlinkat( ++ dirfd, ++ cstr.as_ptr(), ++ v.as_mut_ptr() as *mut c_char, ++ v.capacity() as size_t, ++ ), ++ None => libc::readlink( ++ cstr.as_ptr(), ++ v.as_mut_ptr() as *mut c_char, ++ v.capacity() as size_t, ++ ), ++ } ++ }) ++} + +-pub fn readlinkat(dirfd: RawFd, path: &P) -> Result { ++fn inner_readlink(dirfd: Option, path: &P) -> Result { + let mut v = Vec::with_capacity(libc::PATH_MAX as usize); +- let res = path.with_nix_path(|cstr| { +- unsafe { libc::readlinkat(dirfd, cstr.as_ptr(), v.as_mut_ptr() as *mut c_char, v.capacity() as size_t) } +- })?; ++ // simple case: result is strictly less than `PATH_MAX` ++ let res = readlink_maybe_at(dirfd, path, &mut v)?; ++ let len = Errno::result(res)?; ++ debug_assert!(len >= 0); ++ if (len as usize) < v.capacity() { ++ return wrap_readlink_result(v, res); ++ } ++ // Uh oh, the result is too long... ++ // Let's try to ask lstat how many bytes to allocate. ++ let reported_size = match dirfd { ++ #[cfg(target_os = "redox")] ++ Some(_) => unreachable!(), ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ Some(dirfd) => { ++ let flags = if path.is_empty() { AtFlags::AT_EMPTY_PATH } else { AtFlags::empty() }; ++ super::sys::stat::fstatat(dirfd, path, flags | AtFlags::AT_SYMLINK_NOFOLLOW) ++ }, ++ #[cfg(not(any(target_os = "android", target_os = "linux", target_os = "redox")))] ++ Some(dirfd) => super::sys::stat::fstatat(dirfd, path, AtFlags::AT_SYMLINK_NOFOLLOW), ++ None => super::sys::stat::lstat(path) ++ } ++ .map(|x| x.st_size) ++ .unwrap_or(0); ++ let mut try_size = if reported_size > 0 { ++ // Note: even if `lstat`'s apparently valid answer turns out to be ++ // wrong, we will still read the full symlink no matter what. ++ reported_size as usize + 1 ++ } else { ++ // If lstat doesn't cooperate, or reports an error, be a little less ++ // precise. ++ (libc::PATH_MAX as usize).max(128) << 1 ++ }; ++ loop { ++ v.reserve_exact(try_size); ++ let res = readlink_maybe_at(dirfd, path, &mut v)?; ++ let len = Errno::result(res)?; ++ debug_assert!(len >= 0); ++ if (len as usize) < v.capacity() { ++ break wrap_readlink_result(v, res); ++ } else { ++ // Ugh! Still not big enough! ++ match try_size.checked_shl(1) { ++ Some(next_size) => try_size = next_size, ++ // It's absurd that this would happen, but handle it sanely ++ // anyway. ++ None => break Err(Errno::ENAMETOOLONG), ++ } ++ } ++ } ++} ++ ++pub fn readlink(path: &P) -> Result { ++ inner_readlink(None, path) ++} + +- wrap_readlink_result(&mut v, res) ++#[cfg(not(target_os = "redox"))] ++pub fn readlinkat(dirfd: RawFd, path: &P) -> Result { ++ inner_readlink(Some(dirfd), path) + } + + /// Computes the raw fd consumed by a function of the form `*at`. ++#[cfg(not(target_os = "redox"))] + pub(crate) fn at_rawfd(fd: Option) -> raw::c_int { + match fd { + None => libc::AT_FDCWD, + Some(fd) => fd, + } + } ++} + +-#[cfg(any(target_os = "android", target_os = "linux"))] ++#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))] ++#[cfg(feature = "fs")] + libc_bitflags!( + /// Additional flags for file sealing, which allows for limiting operations on a file. ++ #[cfg_attr(docsrs, doc(cfg(feature = "fs")))] + pub struct SealFlag: c_int { + /// Prevents further calls to `fcntl()` with `F_ADD_SEALS`. + F_SEAL_SEAL; +@@ -232,15 +395,22 @@ libc_bitflags!( + } + ); + ++#[cfg(feature = "fs")] + libc_bitflags!( + /// Additional configuration flags for `fcntl`'s `F_SETFD`. ++ #[cfg_attr(docsrs, doc(cfg(feature = "fs")))] + pub struct FdFlag: c_int { + /// The file descriptor will automatically be closed during a successful `execve(2)`. + FD_CLOEXEC; + } + ); + ++feature! { ++#![feature = "fs"] ++ ++#[cfg(not(target_os = "redox"))] + #[derive(Debug, Eq, Hash, PartialEq)] ++#[non_exhaustive] + pub enum FcntlArg<'a> { + F_DUPFD(RawFd), + F_DUPFD_CLOEXEC(RawFd), +@@ -257,9 +427,9 @@ pub enum FcntlArg<'a> { + F_OFD_SETLKW(&'a libc::flock), + #[cfg(any(target_os = "linux", target_os = "android"))] + F_OFD_GETLK(&'a mut libc::flock), +- #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))] + F_ADD_SEALS(SealFlag), +- #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))] + F_GET_SEALS, + #[cfg(any(target_os = "macos", target_os = "ios"))] + F_FULLFSYNC, +@@ -267,9 +437,20 @@ pub enum FcntlArg<'a> { + F_GETPIPE_SZ, + #[cfg(any(target_os = "linux", target_os = "android"))] + F_SETPIPE_SZ(c_int), +- + // TODO: Rest of flags + } ++ ++#[cfg(target_os = "redox")] ++#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)] ++#[non_exhaustive] ++pub enum FcntlArg { ++ F_DUPFD(RawFd), ++ F_DUPFD_CLOEXEC(RawFd), ++ F_GETFD, ++ F_SETFD(FdFlag), // FD_FLAGS ++ F_GETFL, ++ F_SETFL(OFlag), // O_NONBLOCK ++} + pub use self::FcntlArg::*; + + // TODO: Figure out how to handle value fcntl returns +@@ -282,12 +463,21 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result { + F_SETFD(flag) => libc::fcntl(fd, libc::F_SETFD, flag.bits()), + F_GETFL => libc::fcntl(fd, libc::F_GETFL), + F_SETFL(flag) => libc::fcntl(fd, libc::F_SETFL, flag.bits()), ++ #[cfg(not(target_os = "redox"))] + F_SETLK(flock) => libc::fcntl(fd, libc::F_SETLK, flock), ++ #[cfg(not(target_os = "redox"))] + F_SETLKW(flock) => libc::fcntl(fd, libc::F_SETLKW, flock), ++ #[cfg(not(target_os = "redox"))] + F_GETLK(flock) => libc::fcntl(fd, libc::F_GETLK, flock), + #[cfg(any(target_os = "android", target_os = "linux"))] +- F_ADD_SEALS(flag) => libc::fcntl(fd, libc::F_ADD_SEALS, flag.bits()), ++ F_OFD_SETLK(flock) => libc::fcntl(fd, libc::F_OFD_SETLK, flock), ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ F_OFD_SETLKW(flock) => libc::fcntl(fd, libc::F_OFD_SETLKW, flock), + #[cfg(any(target_os = "android", target_os = "linux"))] ++ F_OFD_GETLK(flock) => libc::fcntl(fd, libc::F_OFD_GETLK, flock), ++ #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))] ++ F_ADD_SEALS(flag) => libc::fcntl(fd, libc::F_ADD_SEALS, flag.bits()), ++ #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))] + F_GET_SEALS => libc::fcntl(fd, libc::F_GET_SEALS), + #[cfg(any(target_os = "macos", target_os = "ios"))] + F_FULLFSYNC => libc::fcntl(fd, libc::F_FULLFSYNC), +@@ -295,15 +485,15 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result { + F_GETPIPE_SZ => libc::fcntl(fd, libc::F_GETPIPE_SZ), + #[cfg(any(target_os = "linux", target_os = "android"))] + F_SETPIPE_SZ(size) => libc::fcntl(fd, libc::F_SETPIPE_SZ, size), +- #[cfg(any(target_os = "linux", target_os = "android"))] +- _ => unimplemented!() + } + }; + + Errno::result(res) + } + ++// TODO: convert to libc_enum + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] ++#[non_exhaustive] + pub enum FlockArg { + LockShared, + LockExclusive, +@@ -313,6 +503,7 @@ pub enum FlockArg { + UnlockNonblock, + } + ++#[cfg(not(target_os = "redox"))] + pub fn flock(fd: RawFd, arg: FlockArg) -> Result<()> { + use self::FlockArg::*; + +@@ -329,10 +520,13 @@ pub fn flock(fd: RawFd, arg: FlockArg) -> Result<()> { + + Errno::result(res).map(drop) + } ++} + + #[cfg(any(target_os = "android", target_os = "linux"))] ++#[cfg(feature = "zerocopy")] + libc_bitflags! { + /// Additional flags to `splice` and friends. ++ #[cfg_attr(docsrs, doc(cfg(feature = "zerocopy")))] + pub struct SpliceFFlags: c_uint { + /// Request that pages be moved instead of copied. + /// +@@ -351,6 +545,9 @@ libc_bitflags! { + } + } + ++feature! { ++#![feature = "zerocopy"] ++ + /// Copy a range of data from one file to another + /// + /// The `copy_file_range` system call performs an in-kernel copy between +@@ -412,9 +609,7 @@ pub fn splice( + .map(|offset| offset as *mut libc::loff_t) + .unwrap_or(ptr::null_mut()); + +- let ret = unsafe { +- libc::splice(fd_in, off_in, fd_out, off_out, len, flags.bits()) +- }; ++ let ret = unsafe { libc::splice(fd_in, off_in, fd_out, off_out, len, flags.bits()) }; + Errno::result(ret).map(|r| r as usize) + } + +@@ -425,16 +620,29 @@ pub fn tee(fd_in: RawFd, fd_out: RawFd, len: usize, flags: SpliceFFlags) -> Resu + } + + #[cfg(any(target_os = "linux", target_os = "android"))] +-pub fn vmsplice(fd: RawFd, iov: &[IoVec<&[u8]>], flags: SpliceFFlags) -> Result { ++pub fn vmsplice( ++ fd: RawFd, ++ iov: &[std::io::IoSlice<'_>], ++ flags: SpliceFFlags ++ ) -> Result ++{ + let ret = unsafe { +- libc::vmsplice(fd, iov.as_ptr() as *const libc::iovec, iov.len(), flags.bits()) ++ libc::vmsplice( ++ fd, ++ iov.as_ptr() as *const libc::iovec, ++ iov.len(), ++ flags.bits(), ++ ) + }; + Errno::result(ret).map(|r| r as usize) + } ++} + + #[cfg(any(target_os = "linux"))] ++#[cfg(feature = "fs")] + libc_bitflags!( + /// Mode argument flags for fallocate determining operation performed on a given range. ++ #[cfg_attr(docsrs, doc(cfg(feature = "fs")))] + pub struct FallocateFlags: c_int { + /// File size is not changed. + /// +@@ -463,31 +671,168 @@ libc_bitflags!( + } + ); + ++feature! { ++#![feature = "fs"] ++ + /// Manipulates file space. + /// + /// Allows the caller to directly manipulate the allocated disk space for the + /// file referred to by fd. + #[cfg(any(target_os = "linux"))] +-pub fn fallocate(fd: RawFd, mode: FallocateFlags, offset: libc::off_t, len: libc::off_t) -> Result { ++#[cfg(feature = "fs")] ++pub fn fallocate( ++ fd: RawFd, ++ mode: FallocateFlags, ++ offset: libc::off_t, ++ len: libc::off_t, ++) -> Result<()> { + let res = unsafe { libc::fallocate(fd, mode.bits(), offset, len) }; +- Errno::result(res) ++ Errno::result(res).map(drop) ++} ++ ++/// Argument to [`fspacectl`] describing the range to zero. The first member is ++/// the file offset, and the second is the length of the region. ++#[cfg(any(target_os = "freebsd"))] ++#[derive(Clone, Copy, Debug, Eq, PartialEq)] ++pub struct SpacectlRange(pub libc::off_t, pub libc::off_t); ++ ++#[cfg(any(target_os = "freebsd"))] ++impl SpacectlRange { ++ #[inline] ++ pub fn is_empty(&self) -> bool { ++ self.1 == 0 ++ } ++ ++ #[inline] ++ pub fn len(&self) -> libc::off_t { ++ self.1 ++ } ++ ++ #[inline] ++ pub fn offset(&self) -> libc::off_t { ++ self.0 ++ } ++} ++ ++/// Punch holes in a file. ++/// ++/// `fspacectl` instructs the file system to deallocate a portion of a file. ++/// After a successful operation, this region of the file will return all zeroes ++/// if read. If the file system supports deallocation, then it may free the ++/// underlying storage, too. ++/// ++/// # Arguments ++/// ++/// - `fd` - File to operate on ++/// - `range.0` - File offset at which to begin deallocation ++/// - `range.1` - Length of the region to deallocate ++/// ++/// # Returns ++/// ++/// The operation may deallocate less than the entire requested region. On ++/// success, it returns the region that still remains to be deallocated. The ++/// caller should loop until the returned region is empty. ++/// ++/// # Example ++/// ++#[cfg_attr(fbsd14, doc = " ```")] ++#[cfg_attr(not(fbsd14), doc = " ```no_run")] ++/// # use std::io::Write; ++/// # use std::os::unix::fs::FileExt; ++/// # use std::os::unix::io::AsRawFd; ++/// # use nix::fcntl::*; ++/// # use tempfile::tempfile; ++/// const INITIAL: &[u8] = b"0123456789abcdef"; ++/// let mut f = tempfile().unwrap(); ++/// f.write_all(INITIAL).unwrap(); ++/// let mut range = SpacectlRange(3, 6); ++/// while (!range.is_empty()) { ++/// range = fspacectl(f.as_raw_fd(), range).unwrap(); ++/// } ++/// let mut buf = vec![0; INITIAL.len()]; ++/// f.read_exact_at(&mut buf, 0).unwrap(); ++/// assert_eq!(buf, b"012\0\0\0\0\0\09abcdef"); ++/// ``` ++#[cfg(target_os = "freebsd")] ++pub fn fspacectl(fd: RawFd, range: SpacectlRange) -> Result { ++ let mut rqsr = libc::spacectl_range{r_offset: range.0, r_len: range.1}; ++ let res = unsafe { libc::fspacectl( ++ fd, ++ libc::SPACECTL_DEALLOC, // Only one command is supported ATM ++ &rqsr, ++ 0, // No flags are currently supported ++ &mut rqsr ++ )}; ++ Errno::result(res).map(|_| SpacectlRange(rqsr.r_offset, rqsr.r_len)) ++} ++ ++/// Like [`fspacectl`], but will never return incomplete. ++/// ++/// # Arguments ++/// ++/// - `fd` - File to operate on ++/// - `offset` - File offset at which to begin deallocation ++/// - `len` - Length of the region to deallocate ++/// ++/// # Returns ++/// ++/// Returns `()` on success. On failure, the region may or may not be partially ++/// deallocated. ++/// ++/// # Example ++/// ++#[cfg_attr(fbsd14, doc = " ```")] ++#[cfg_attr(not(fbsd14), doc = " ```no_run")] ++/// # use std::io::Write; ++/// # use std::os::unix::fs::FileExt; ++/// # use std::os::unix::io::AsRawFd; ++/// # use nix::fcntl::*; ++/// # use tempfile::tempfile; ++/// const INITIAL: &[u8] = b"0123456789abcdef"; ++/// let mut f = tempfile().unwrap(); ++/// f.write_all(INITIAL).unwrap(); ++/// fspacectl_all(f.as_raw_fd(), 3, 6).unwrap(); ++/// let mut buf = vec![0; INITIAL.len()]; ++/// f.read_exact_at(&mut buf, 0).unwrap(); ++/// assert_eq!(buf, b"012\0\0\0\0\0\09abcdef"); ++/// ``` ++#[cfg(target_os = "freebsd")] ++pub fn fspacectl_all(fd: RawFd, offset: libc::off_t, len: libc::off_t) ++ -> Result<()> ++{ ++ let mut rqsr = libc::spacectl_range{r_offset: offset, r_len: len}; ++ while rqsr.r_len > 0 { ++ let res = unsafe { libc::fspacectl( ++ fd, ++ libc::SPACECTL_DEALLOC, // Only one command is supported ATM ++ &rqsr, ++ 0, // No flags are currently supported ++ &mut rqsr ++ )}; ++ Errno::result(res)?; ++ } ++ Ok(()) + } + +-#[cfg(any(target_os = "linux", +- target_os = "android", +- target_os = "emscripten", +- target_os = "fuchsia", +- any(target_os = "wasi", target_env = "wasi"), +- target_env = "uclibc", +- target_env = "freebsd"))] ++#[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "wasi", ++ target_env = "uclibc", ++ target_os = "freebsd" ++))] + mod posix_fadvise { +- use Result; +- use libc; +- use errno::Errno; ++ use crate::errno::Errno; + use std::os::unix::io::RawFd; ++ use crate::Result; + ++ #[cfg(feature = "fs")] + libc_enum! { + #[repr(i32)] ++ #[non_exhaustive] ++ #[cfg_attr(docsrs, doc(cfg(feature = "fs")))] + pub enum PosixFadviseAdvice { + POSIX_FADV_NORMAL, + POSIX_FADV_SEQUENTIAL, +@@ -498,32 +843,40 @@ mod posix_fadvise { + } + } + +- pub fn posix_fadvise(fd: RawFd, +- offset: libc::off_t, +- len: libc::off_t, +- advice: PosixFadviseAdvice) -> Result { ++ feature! { ++ #![feature = "fs"] ++ pub fn posix_fadvise( ++ fd: RawFd, ++ offset: libc::off_t, ++ len: libc::off_t, ++ advice: PosixFadviseAdvice, ++ ) -> Result<()> { + let res = unsafe { libc::posix_fadvise(fd, offset, len, advice as libc::c_int) }; +- Errno::result(res) ++ ++ if res == 0 { ++ Ok(()) ++ } else { ++ Err(Errno::from_i32(res)) ++ } ++ } + } + } + + #[cfg(any( + target_os = "linux", + target_os = "android", ++ target_os = "dragonfly", + target_os = "emscripten", + target_os = "fuchsia", +- any(target_os = "wasi", target_env = "wasi"), ++ target_os = "wasi", + target_os = "freebsd" + ))] +-pub fn posix_fallocate( +- fd: RawFd, +- offset: libc::off_t, +- len: libc::off_t +-) -> Result<()> { ++pub fn posix_fallocate(fd: RawFd, offset: libc::off_t, len: libc::off_t) -> Result<()> { + let res = unsafe { libc::posix_fallocate(fd, offset, len) }; + match Errno::result(res) { + Err(err) => Err(err), + Ok(0) => Ok(()), +- Ok(errno) => Err(crate::Error::Sys(Errno::from_i32(errno))), ++ Ok(errno) => Err(Errno::from_i32(errno)), + } + } ++} +diff --git a/vendor/nix/src/features.rs b/vendor/nix/src/features.rs +index 76cdfd3..39d1760 100644 +--- a/vendor/nix/src/features.rs ++++ b/vendor/nix/src/features.rs +@@ -3,7 +3,9 @@ pub use self::os::*; + + #[cfg(any(target_os = "linux", target_os = "android"))] + mod os { +- use sys::utsname::uname; ++ use crate::sys::utsname::uname; ++ use crate::Result; ++ use std::os::unix::ffi::OsStrExt; + + // Features: + // * atomic cloexec on socket: 2.6.27 +@@ -11,10 +13,10 @@ mod os { + // * accept4: 2.6.28 + + static VERS_UNKNOWN: usize = 1; +- static VERS_2_6_18: usize = 2; +- static VERS_2_6_27: usize = 3; +- static VERS_2_6_28: usize = 4; +- static VERS_3: usize = 5; ++ static VERS_2_6_18: usize = 2; ++ static VERS_2_6_27: usize = 3; ++ static VERS_2_6_28: usize = 4; ++ static VERS_3: usize = 5; + + #[inline] + fn digit(dst: &mut usize, b: u8) { +@@ -22,15 +24,15 @@ mod os { + *dst += (b - b'0') as usize; + } + +- fn parse_kernel_version() -> usize { +- let u = uname(); ++ fn parse_kernel_version() -> Result { ++ let u = uname()?; + +- let mut curr: usize = 0; ++ let mut curr: usize = 0; + let mut major: usize = 0; + let mut minor: usize = 0; + let mut patch: usize = 0; + +- for b in u.release().bytes() { ++ for &b in u.release().as_bytes() { + if curr >= 3 { + break; + } +@@ -39,18 +41,16 @@ mod os { + b'.' | b'-' => { + curr += 1; + } +- b'0'..=b'9' => { +- match curr { +- 0 => digit(&mut major, b), +- 1 => digit(&mut minor, b), +- _ => digit(&mut patch, b), +- } +- } ++ b'0'..=b'9' => match curr { ++ 0 => digit(&mut major, b), ++ 1 => digit(&mut minor, b), ++ _ => digit(&mut patch, b), ++ }, + _ => break, + } + } + +- if major >= 3 { ++ Ok(if major >= 3 { + VERS_3 + } else if major >= 2 { + if minor >= 7 { +@@ -68,36 +68,59 @@ mod os { + } + } else { + VERS_UNKNOWN +- } ++ }) + } + +- fn kernel_version() -> usize { ++ fn kernel_version() -> Result { + static mut KERNEL_VERS: usize = 0; + + unsafe { + if KERNEL_VERS == 0 { +- KERNEL_VERS = parse_kernel_version(); ++ KERNEL_VERS = parse_kernel_version()?; + } + +- KERNEL_VERS ++ Ok(KERNEL_VERS) + } + } + + /// Check if the OS supports atomic close-on-exec for sockets + pub fn socket_atomic_cloexec() -> bool { +- kernel_version() >= VERS_2_6_27 ++ kernel_version() ++ .map(|version| version >= VERS_2_6_27) ++ .unwrap_or(false) + } + + #[test] + pub fn test_parsing_kernel_version() { +- assert!(kernel_version() > 0); ++ assert!(kernel_version().unwrap() > 0); + } + } + +-#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "dragonfly", target_os = "ios", target_os = "openbsd", target_os = "netbsd"))] ++#[cfg(any( ++ target_os = "dragonfly", // Since ??? ++ target_os = "freebsd", // Since 10.0 ++ target_os = "illumos", // Since ??? ++ target_os = "netbsd", // Since 6.0 ++ target_os = "openbsd", // Since 5.7 ++ target_os = "redox", // Since 1-july-2020 ++))] + mod os { + /// Check if the OS supports atomic close-on-exec for sockets +- pub fn socket_atomic_cloexec() -> bool { ++ pub const fn socket_atomic_cloexec() -> bool { ++ true ++ } ++} ++ ++#[cfg(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "fuchsia", ++ target_os = "haiku", ++ target_os = "solaris" ++))] ++mod os { ++ /// Check if the OS supports atomic close-on-exec for sockets ++ pub const fn socket_atomic_cloexec() -> bool { + false + } + } +diff --git a/vendor/nix/src/ifaddrs.rs b/vendor/nix/src/ifaddrs.rs +index 2c226cb..70b50b0 100644 +--- a/vendor/nix/src/ifaddrs.rs ++++ b/vendor/nix/src/ifaddrs.rs +@@ -3,16 +3,17 @@ + //! Uses the Linux and/or BSD specific function `getifaddrs` to query the list + //! of interfaces and their associated addresses. + ++use cfg_if::cfg_if; ++#[cfg(any(target_os = "ios", target_os = "macos"))] ++use std::convert::TryFrom; + use std::ffi; + use std::iter::Iterator; + use std::mem; + use std::option::Option; + +-use libc; +- +-use {Result, Errno}; +-use sys::socket::SockAddr; +-use net::if_::*; ++use crate::net::if_::*; ++use crate::sys::socket::{SockaddrLike, SockaddrStorage}; ++use crate::{Errno, Result}; + + /// Describes a single address for an interface as returned by `getifaddrs`. + #[derive(Clone, Debug, Eq, Hash, PartialEq)] +@@ -22,13 +23,13 @@ pub struct InterfaceAddress { + /// Flags as from `SIOCGIFFLAGS` ioctl + pub flags: InterfaceFlags, + /// Network address of this interface +- pub address: Option, ++ pub address: Option, + /// Netmask of this interface +- pub netmask: Option, ++ pub netmask: Option, + /// Broadcast address of this interface, if applicable +- pub broadcast: Option, ++ pub broadcast: Option, + /// Point-to-point destination address +- pub destination: Option, ++ pub destination: Option, + } + + cfg_if! { +@@ -43,12 +44,52 @@ cfg_if! { + } + } + ++/// Workaround a bug in XNU where netmasks will always have the wrong size in ++/// the sa_len field due to the kernel ignoring trailing zeroes in the structure ++/// when setting the field. See https://github.com/nix-rust/nix/issues/1709#issuecomment-1199304470 ++/// ++/// To fix this, we stack-allocate a new sockaddr_storage, zero it out, and ++/// memcpy sa_len of the netmask to that new storage. Finally, we reset the ++/// ss_len field to sizeof(sockaddr_storage). This is supposedly valid as all ++/// members of the sockaddr_storage are "ok" with being zeroed out (there are ++/// no pointers). ++#[cfg(any(target_os = "ios", target_os = "macos"))] ++unsafe fn workaround_xnu_bug(info: &libc::ifaddrs) -> Option { ++ let src_sock = info.ifa_netmask; ++ if src_sock.is_null() { ++ return None; ++ } ++ ++ let mut dst_sock = mem::MaybeUninit::::zeroed(); ++ ++ // memcpy only sa_len bytes, assume the rest is zero ++ std::ptr::copy_nonoverlapping( ++ src_sock as *const u8, ++ dst_sock.as_mut_ptr() as *mut u8, ++ (*src_sock).sa_len.into(), ++ ); ++ ++ // Initialize ss_len to sizeof(libc::sockaddr_storage). ++ (*dst_sock.as_mut_ptr()).ss_len = ++ u8::try_from(mem::size_of::()).unwrap(); ++ let dst_sock = dst_sock.assume_init(); ++ ++ let dst_sock_ptr = ++ &dst_sock as *const libc::sockaddr_storage as *const libc::sockaddr; ++ ++ SockaddrStorage::from_raw(dst_sock_ptr, None) ++} ++ + impl InterfaceAddress { + /// Create an `InterfaceAddress` from the libc struct. + fn from_libc_ifaddrs(info: &libc::ifaddrs) -> InterfaceAddress { + let ifname = unsafe { ffi::CStr::from_ptr(info.ifa_name) }; +- let address = unsafe { SockAddr::from_libc_sockaddr(info.ifa_addr) }; +- let netmask = unsafe { SockAddr::from_libc_sockaddr(info.ifa_netmask) }; ++ let address = unsafe { SockaddrStorage::from_raw(info.ifa_addr, None) }; ++ #[cfg(any(target_os = "ios", target_os = "macos"))] ++ let netmask = unsafe { workaround_xnu_bug(info) }; ++ #[cfg(not(any(target_os = "ios", target_os = "macos")))] ++ let netmask = ++ unsafe { SockaddrStorage::from_raw(info.ifa_netmask, None) }; + let mut addr = InterfaceAddress { + interface_name: ifname.to_string_lossy().to_string(), + flags: InterfaceFlags::from_bits_truncate(info.ifa_flags as i32), +@@ -60,9 +101,9 @@ impl InterfaceAddress { + + let ifu = get_ifu_from_sockaddr(info); + if addr.flags.contains(InterfaceFlags::IFF_POINTOPOINT) { +- addr.destination = unsafe { SockAddr::from_libc_sockaddr(ifu) }; ++ addr.destination = unsafe { SockaddrStorage::from_raw(ifu, None) }; + } else if addr.flags.contains(InterfaceFlags::IFF_BROADCAST) { +- addr.broadcast = unsafe { SockAddr::from_libc_sockaddr(ifu) }; ++ addr.broadcast = unsafe { SockaddrStorage::from_raw(ifu, None) }; + } + + addr +@@ -104,9 +145,9 @@ impl Iterator for InterfaceAddressIterator { + /// Note that the underlying implementation differs between OSes. Only the + /// most common address families are supported by the nix crate (due to + /// lack of time and complexity of testing). The address family is encoded +-/// in the specific variant of `SockAddr` returned for the fields `address`, +-/// `netmask`, `broadcast`, and `destination`. For any entry not supported, +-/// the returned list will contain a `None` entry. ++/// in the specific variant of `SockaddrStorage` returned for the fields ++/// `address`, `netmask`, `broadcast`, and `destination`. For any entry not ++/// supported, the returned list will contain a `None` entry. + /// + /// # Example + /// ``` +@@ -145,4 +186,28 @@ mod tests { + fn test_getifaddrs() { + let _ = getifaddrs(); + } ++ ++ // Ensures getting the netmask works, and in particular that ++ // `workaround_xnu_bug` works properly. ++ #[test] ++ fn test_getifaddrs_netmask_correct() { ++ let addrs = getifaddrs().unwrap(); ++ for iface in addrs { ++ let sock = if let Some(sock) = iface.netmask { ++ sock ++ } else { ++ continue; ++ }; ++ if sock.family() == Some(crate::sys::socket::AddressFamily::Inet) { ++ let _ = sock.as_sockaddr_in().unwrap(); ++ return; ++ } else if sock.family() ++ == Some(crate::sys::socket::AddressFamily::Inet6) ++ { ++ let _ = sock.as_sockaddr_in6().unwrap(); ++ return; ++ } ++ } ++ panic!("No address?"); ++ } + } +diff --git a/vendor/nix/src/kmod.rs b/vendor/nix/src/kmod.rs +index e853261..1fa6c17 100644 +--- a/vendor/nix/src/kmod.rs ++++ b/vendor/nix/src/kmod.rs +@@ -2,12 +2,11 @@ + //! + //! For more details see + +-use libc; + use std::ffi::CStr; + use std::os::unix::io::AsRawFd; + +-use errno::Errno; +-use Result; ++use crate::errno::Errno; ++use crate::Result; + + /// Loads a kernel module from a buffer. + /// +@@ -42,7 +41,7 @@ use Result; + /// init_module(&mut contents, &CString::new("who=Rust when=Now,12").unwrap()).unwrap(); + /// ``` + /// +-/// See [`man init_module(2)`](http://man7.org/linux/man-pages/man2/init_module.2.html) for more information. ++/// See [`man init_module(2)`](https://man7.org/linux/man-pages/man2/init_module.2.html) for more information. + pub fn init_module(module_image: &[u8], param_values: &CStr) -> Result<()> { + let res = unsafe { + libc::syscall( +@@ -79,8 +78,12 @@ libc_bitflags!( + /// finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()).unwrap(); + /// ``` + /// +-/// See [`man init_module(2)`](http://man7.org/linux/man-pages/man2/init_module.2.html) for more information. +-pub fn finit_module(fd: &T, param_values: &CStr, flags: ModuleInitFlags) -> Result<()> { ++/// See [`man init_module(2)`](https://man7.org/linux/man-pages/man2/init_module.2.html) for more information. ++pub fn finit_module( ++ fd: &T, ++ param_values: &CStr, ++ flags: ModuleInitFlags, ++) -> Result<()> { + let res = unsafe { + libc::syscall( + libc::SYS_finit_module, +@@ -96,7 +99,7 @@ pub fn finit_module(fd: &T, param_values: &CStr, flags: ModuleInitFl + libc_bitflags!( + /// Flags used by `delete_module`. + /// +- /// See [`man delete_module(2)`](http://man7.org/linux/man-pages/man2/delete_module.2.html) ++ /// See [`man delete_module(2)`](https://man7.org/linux/man-pages/man2/delete_module.2.html) + /// for a detailed description how these flags work. + pub struct DeleteModuleFlags: libc::c_int { + O_NONBLOCK; +@@ -115,9 +118,11 @@ libc_bitflags!( + /// delete_module(&CString::new("mymod").unwrap(), DeleteModuleFlags::O_NONBLOCK).unwrap(); + /// ``` + /// +-/// See [`man delete_module(2)`](http://man7.org/linux/man-pages/man2/delete_module.2.html) for more information. ++/// See [`man delete_module(2)`](https://man7.org/linux/man-pages/man2/delete_module.2.html) for more information. + pub fn delete_module(name: &CStr, flags: DeleteModuleFlags) -> Result<()> { +- let res = unsafe { libc::syscall(libc::SYS_delete_module, name.as_ptr(), flags.bits()) }; ++ let res = unsafe { ++ libc::syscall(libc::SYS_delete_module, name.as_ptr(), flags.bits()) ++ }; + + Errno::result(res).map(drop) + } +diff --git a/vendor/nix/src/lib.rs b/vendor/nix/src/lib.rs +index 410db18..6b82125 100644 +--- a/vendor/nix/src/lib.rs ++++ b/vendor/nix/src/lib.rs +@@ -2,176 +2,195 @@ + //! + //! Modules are structured according to the C header file that they would be + //! defined in. ++//! ++//! # Features ++//! ++//! Nix uses the following Cargo features to enable optional functionality. ++//! They may be enabled in any combination. ++//! * `acct` - Process accounting ++//! * `aio` - POSIX AIO ++//! * `dir` - Stuff relating to directory iteration ++//! * `env` - Manipulate environment variables ++//! * `event` - Event-driven APIs, like `kqueue` and `epoll` ++//! * `feature` - Query characteristics of the OS at runtime ++//! * `fs` - File system functionality ++//! * `hostname` - Get and set the system's hostname ++//! * `inotify` - Linux's `inotify` file system notification API ++//! * `ioctl` - The `ioctl` syscall, and wrappers for my specific instances ++//! * `kmod` - Load and unload kernel modules ++//! * `mman` - Stuff relating to memory management ++//! * `mount` - Mount and unmount file systems ++//! * `mqueue` - POSIX message queues ++//! * `net` - Networking-related functionality ++//! * `personality` - Set the process execution domain ++//! * `poll` - APIs like `poll` and `select` ++//! * `process` - Stuff relating to running processes ++//! * `pthread` - POSIX threads ++//! * `ptrace` - Process tracing and debugging ++//! * `quota` - File system quotas ++//! * `reboot` - Reboot the system ++//! * `resource` - Process resource limits ++//! * `sched` - Manipulate process's scheduling ++//! * `socket` - Sockets, whether for networking or local use ++//! * `signal` - Send and receive signals to processes ++//! * `term` - Terminal control APIs ++//! * `time` - Query the operating system's clocks ++//! * `ucontext` - User thread context ++//! * `uio` - Vectored I/O ++//! * `user` - Stuff relating to users and groups ++//! * `zerocopy` - APIs like `sendfile` and `copy_file_range` + #![crate_name = "nix"] + #![cfg(unix)] ++#![cfg_attr(docsrs, doc(cfg(all())))] + #![allow(non_camel_case_types)] +-// latest bitflags triggers a rustc bug with cross-crate macro expansions causing dead_code +-// warnings even though the macro expands into something with allow(dead_code) +-#![allow(dead_code)] + #![cfg_attr(test, deny(warnings))] + #![recursion_limit = "500"] + #![deny(unused)] ++#![allow(unused_macros)] ++#![cfg_attr(not(feature = "default"), allow(unused_imports))] + #![deny(unstable_features)] + #![deny(missing_copy_implementations)] + #![deny(missing_debug_implementations)] +- +-// External crates +-#[macro_use] +-extern crate bitflags; +-#[macro_use] +-extern crate cfg_if; +-extern crate void; ++#![warn(missing_docs)] ++#![cfg_attr(docsrs, feature(doc_cfg))] ++#![deny(clippy::cast_ptr_alignment)] + + // Re-exported external crates +-pub extern crate libc; ++pub use libc; + + // Private internal modules +-#[macro_use] mod macros; ++#[macro_use] ++mod macros; + + // Public crates +-pub mod dir; ++#[cfg(not(target_os = "redox"))] ++feature! { ++ #![feature = "dir"] ++ pub mod dir; ++} ++feature! { ++ #![feature = "env"] ++ pub mod env; ++} ++#[allow(missing_docs)] + pub mod errno; +-#[deny(missing_docs)] +-pub mod features; ++feature! { ++ #![feature = "feature"] ++ ++ #[deny(missing_docs)] ++ pub mod features; ++} ++#[allow(missing_docs)] + pub mod fcntl; +-#[deny(missing_docs)] +-#[cfg(any(target_os = "android", +- target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "linux", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] +-pub mod ifaddrs; +-#[cfg(any(target_os = "android", +- target_os = "linux"))] +-pub mod kmod; +-#[cfg(any(target_os = "android", +- target_os = "linux"))] +-pub mod mount; +-#[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "fushsia", +- target_os = "linux", +- target_os = "netbsd"))] +-pub mod mqueue; +-#[deny(missing_docs)] +-pub mod net; +-#[deny(missing_docs)] +-pub mod poll; +-#[deny(missing_docs)] +-pub mod pty; +-pub mod sched; ++feature! { ++ #![feature = "net"] ++ ++ #[cfg(any(target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "linux", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "illumos", ++ target_os = "openbsd"))] ++ #[deny(missing_docs)] ++ pub mod ifaddrs; ++ #[cfg(not(target_os = "redox"))] ++ #[deny(missing_docs)] ++ pub mod net; ++} ++#[cfg(any(target_os = "android", target_os = "linux"))] ++feature! { ++ #![feature = "kmod"] ++ #[allow(missing_docs)] ++ pub mod kmod; ++} ++feature! { ++ #![feature = "mount"] ++ pub mod mount; ++} ++#[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "linux", ++ target_os = "netbsd" ++))] ++feature! { ++ #![feature = "mqueue"] ++ pub mod mqueue; ++} ++feature! { ++ #![feature = "poll"] ++ pub mod poll; ++} ++#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))] ++feature! { ++ #![feature = "term"] ++ #[deny(missing_docs)] ++ pub mod pty; ++} ++feature! { ++ #![feature = "sched"] ++ pub mod sched; ++} + pub mod sys; ++feature! { ++ #![feature = "time"] ++ #[allow(missing_docs)] ++ pub mod time; ++} + // This can be implemented for other platforms as soon as libc + // provides bindings for them. +-#[cfg(all(target_os = "linux", +- any(target_arch = "x86", target_arch = "x86_64")))] +-pub mod ucontext; ++#[cfg(all( ++ target_os = "linux", ++ any(target_arch = "s390x", target_arch = "x86", target_arch = "x86_64") ++))] ++feature! { ++ #![feature = "ucontext"] ++ #[allow(missing_docs)] ++ pub mod ucontext; ++} ++#[allow(missing_docs)] + pub mod unistd; + +-/* +- * +- * ===== Result / Error ===== +- * +- */ +- +-use libc::{c_char, PATH_MAX}; +- +-use std::{error, fmt, ptr, result}; +-use std::ffi::{CStr, OsStr}; ++use std::ffi::{CStr, CString, OsStr}; ++use std::mem::MaybeUninit; + use std::os::unix::ffi::OsStrExt; + use std::path::{Path, PathBuf}; ++use std::{ptr, result, slice}; + + use errno::Errno; + + /// Nix Result Type +-pub type Result = result::Result; ++pub type Result = result::Result; + +-/// Nix Error Type ++/// Nix's main error type. + /// +-/// The nix error type provides a common way of dealing with +-/// various system system/libc calls that might fail. Each +-/// error has a corresponding errno (usually the one from the +-/// underlying OS) to which it can be mapped in addition to +-/// implementing other common traits. +-#[derive(Clone, Copy, Debug, Eq, PartialEq)] +-pub enum Error { +- Sys(Errno), +- InvalidPath, +- /// The operation involved a conversion to Rust's native String type, which failed because the +- /// string did not contain all valid UTF-8. +- InvalidUtf8, +- /// The operation is not supported by Nix, in this instance either use the libc bindings or +- /// consult the module documentation to see if there is a more appropriate interface available. +- UnsupportedOperation, +-} +- +-impl Error { +- /// Convert this `Error` to an [`Errno`](enum.Errno.html). +- /// +- /// # Example +- /// +- /// ``` +- /// # use nix::Error; +- /// # use nix::errno::Errno; +- /// let e = Error::from(Errno::EPERM); +- /// assert_eq!(Some(Errno::EPERM), e.as_errno()); +- /// ``` +- pub fn as_errno(self) -> Option { +- if let Error::Sys(e) = self { +- Some(e) +- } else { +- None +- } +- } +- +- /// Create a nix Error from a given errno +- pub fn from_errno(errno: Errno) -> Error { +- Error::Sys(errno) +- } +- +- /// Get the current errno and convert it to a nix Error +- pub fn last() -> Error { +- Error::Sys(Errno::last()) +- } +- +- /// Create a new invalid argument error (`EINVAL`) +- pub fn invalid_argument() -> Error { +- Error::Sys(Errno::EINVAL) +- } +- +-} +- +-impl From for Error { +- fn from(errno: Errno) -> Error { Error::from_errno(errno) } +-} +- +-impl From for Error { +- fn from(_: std::string::FromUtf8Error) -> Error { Error::InvalidUtf8 } +-} +- +-impl error::Error for Error {} +- +-impl fmt::Display for Error { +- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +- match *self { +- Error::InvalidPath => write!(f, "Invalid path"), +- Error::InvalidUtf8 => write!(f, "Invalid UTF-8 string"), +- Error::UnsupportedOperation => write!(f, "Unsupported Operation"), +- Error::Sys(errno) => write!(f, "{:?}: {}", errno, errno.desc()), +- } +- } +-} +- ++/// It's a wrapper around Errno. As such, it's very interoperable with ++/// [`std::io::Error`], but it has the advantages of: ++/// * `Clone` ++/// * `Copy` ++/// * `Eq` ++/// * Small size ++/// * Represents all of the system's errnos, instead of just the most common ++/// ones. ++pub type Error = Errno; ++ ++/// Common trait used to represent file system paths by many Nix functions. + pub trait NixPath { ++ /// Is the path empty? + fn is_empty(&self) -> bool; + ++ /// Length of the path in bytes + fn len(&self) -> usize; + ++ /// Execute a function with this path as a `CStr`. ++ /// ++ /// Mostly used internally by Nix. + fn with_nix_path(&self, f: F) -> Result +- where F: FnOnce(&CStr) -> T; ++ where ++ F: FnOnce(&CStr) -> T; + } + + impl NixPath for str { +@@ -184,9 +203,11 @@ impl NixPath for str { + } + + fn with_nix_path(&self, f: F) -> Result +- where F: FnOnce(&CStr) -> T { +- OsStr::new(self).with_nix_path(f) +- } ++ where ++ F: FnOnce(&CStr) -> T, ++ { ++ OsStr::new(self).with_nix_path(f) ++ } + } + + impl NixPath for OsStr { +@@ -199,9 +220,11 @@ impl NixPath for OsStr { + } + + fn with_nix_path(&self, f: F) -> Result +- where F: FnOnce(&CStr) -> T { +- self.as_bytes().with_nix_path(f) +- } ++ where ++ F: FnOnce(&CStr) -> T, ++ { ++ self.as_bytes().with_nix_path(f) ++ } + } + + impl NixPath for CStr { +@@ -214,12 +237,9 @@ impl NixPath for CStr { + } + + fn with_nix_path(&self, f: F) -> Result +- where F: FnOnce(&CStr) -> T { +- // Equivalence with the [u8] impl. +- if self.len() >= PATH_MAX as usize { +- return Err(Error::InvalidPath); +- } +- ++ where ++ F: FnOnce(&CStr) -> T, ++ { + Ok(f(self)) + } + } +@@ -234,24 +254,47 @@ impl NixPath for [u8] { + } + + fn with_nix_path(&self, f: F) -> Result +- where F: FnOnce(&CStr) -> T { +- let mut buf = [0u8; PATH_MAX as usize]; +- +- if self.len() >= PATH_MAX as usize { +- return Err(Error::InvalidPath); ++ where ++ F: FnOnce(&CStr) -> T, ++ { ++ // The real PATH_MAX is typically 4096, but it's statistically unlikely to have a path ++ // longer than ~300 bytes. See the the PR description to get stats for your own machine. ++ // https://github.com/nix-rust/nix/pull/1656 ++ // ++ // By being smaller than a memory page, we also avoid the compiler inserting a probe frame: ++ // https://docs.rs/compiler_builtins/latest/compiler_builtins/probestack/index.html ++ const MAX_STACK_ALLOCATION: usize = 1024; ++ ++ if self.len() >= MAX_STACK_ALLOCATION { ++ return with_nix_path_allocating(self, f); + } + +- match self.iter().position(|b| *b == 0) { +- Some(_) => Err(Error::InvalidPath), +- None => { +- unsafe { +- // TODO: Replace with bytes::copy_memory. rust-lang/rust#24028 +- ptr::copy_nonoverlapping(self.as_ptr(), buf.as_mut_ptr(), self.len()); +- Ok(f(CStr::from_ptr(buf.as_ptr() as *const c_char))) +- } ++ let mut buf = MaybeUninit::<[u8; MAX_STACK_ALLOCATION]>::uninit(); ++ let buf_ptr = buf.as_mut_ptr() as *mut u8; + +- } ++ unsafe { ++ ptr::copy_nonoverlapping(self.as_ptr(), buf_ptr, self.len()); ++ buf_ptr.add(self.len()).write(0); + } ++ ++ match CStr::from_bytes_with_nul(unsafe { ++ slice::from_raw_parts(buf_ptr, self.len() + 1) ++ }) { ++ Ok(s) => Ok(f(s)), ++ Err(_) => Err(Errno::EINVAL), ++ } ++ } ++} ++ ++#[cold] ++#[inline(never)] ++fn with_nix_path_allocating(from: &[u8], f: F) -> Result ++where ++ F: FnOnce(&CStr) -> T, ++{ ++ match CString::new(from) { ++ Ok(s) => Ok(f(&s)), ++ Err(_) => Err(Errno::EINVAL), + } + } + +@@ -264,7 +307,10 @@ impl NixPath for Path { + NixPath::len(self.as_os_str()) + } + +- fn with_nix_path(&self, f: F) -> Result where F: FnOnce(&CStr) -> T { ++ fn with_nix_path(&self, f: F) -> Result ++ where ++ F: FnOnce(&CStr) -> T, ++ { + self.as_os_str().with_nix_path(f) + } + } +@@ -278,26 +324,10 @@ impl NixPath for PathBuf { + NixPath::len(self.as_os_str()) + } + +- fn with_nix_path(&self, f: F) -> Result where F: FnOnce(&CStr) -> T { ++ fn with_nix_path(&self, f: F) -> Result ++ where ++ F: FnOnce(&CStr) -> T, ++ { + self.as_os_str().with_nix_path(f) + } + } +- +-/// Treats `None` as an empty string. +-impl<'a, NP: ?Sized + NixPath> NixPath for Option<&'a NP> { +- fn is_empty(&self) -> bool { +- self.map_or(true, NixPath::is_empty) +- } +- +- fn len(&self) -> usize { +- self.map_or(0, NixPath::len) +- } +- +- fn with_nix_path(&self, f: F) -> Result where F: FnOnce(&CStr) -> T { +- if let Some(nix_path) = *self { +- nix_path.with_nix_path(f) +- } else { +- unsafe { CStr::from_ptr("\0".as_ptr() as *const _).with_nix_path(f) } +- } +- } +-} +diff --git a/vendor/nix/src/macros.rs b/vendor/nix/src/macros.rs +index 5fb49e3..99e0de8 100644 +--- a/vendor/nix/src/macros.rs ++++ b/vendor/nix/src/macros.rs +@@ -1,3 +1,17 @@ ++// Thanks to Tokio for this macro ++macro_rules! feature { ++ ( ++ #![$meta:meta] ++ $($item:item)* ++ ) => { ++ $( ++ #[cfg($meta)] ++ #[cfg_attr(docsrs, doc(cfg($meta)))] ++ $item ++ )* ++ } ++} ++ + /// The `libc_bitflags!` macro helps with a common use case of defining a public bitflags type + /// with values from the libc crate. It is used the same way as the `bitflags!` macro, except + /// that only the name of the flag value has to be given. +@@ -5,7 +19,7 @@ + /// The `libc` crate must be in scope with the name `libc`. + /// + /// # Example +-/// ``` ++/// ```ignore + /// libc_bitflags!{ + /// pub struct ProtFlags: libc::c_int { + /// PROT_NONE; +@@ -25,7 +39,7 @@ + /// various flags have different types, so we cast the broken ones to the right + /// type. + /// +-/// ``` ++/// ```ignore + /// libc_bitflags!{ + /// pub struct SaFlags: libc::c_ulong { + /// SA_NOCLDSTOP as libc::c_ulong; +@@ -48,7 +62,7 @@ macro_rules! libc_bitflags { + )+ + } + ) => { +- bitflags! { ++ ::bitflags::bitflags! { + $(#[$outer])* + pub struct $BitFlags: $T { + $( +@@ -66,7 +80,7 @@ macro_rules! libc_bitflags { + /// The `libc` crate must be in scope with the name `libc`. + /// + /// # Example +-/// ``` ++/// ```ignore + /// libc_enum!{ + /// pub enum ProtFlags { + /// PROT_NONE, +@@ -80,14 +94,35 @@ macro_rules! libc_bitflags { + /// } + /// } + /// ``` ++// Some targets don't use all rules. ++#[allow(unknown_lints)] ++#[allow(unused_macro_rules)] + macro_rules! libc_enum { + // Exit rule. + (@make_enum ++ name: $BitFlags:ident, ++ { ++ $v:vis ++ attrs: [$($attrs:tt)*], ++ entries: [$($entries:tt)*], ++ } ++ ) => { ++ $($attrs)* ++ #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] ++ $v enum $BitFlags { ++ $($entries)* ++ } ++ }; ++ ++ // Exit rule including TryFrom ++ (@make_enum ++ name: $BitFlags:ident, + { + $v:vis +- name: $BitFlags:ident, + attrs: [$($attrs:tt)*], + entries: [$($entries:tt)*], ++ from_type: $repr:path, ++ try_froms: [$($try_froms:tt)*] + } + ) => { + $($attrs)* +@@ -95,40 +130,82 @@ macro_rules! libc_enum { + $v enum $BitFlags { + $($entries)* + } ++ impl ::std::convert::TryFrom<$repr> for $BitFlags { ++ type Error = $crate::Error; ++ #[allow(unused_doc_comments)] ++ fn try_from(x: $repr) -> $crate::Result { ++ match x { ++ $($try_froms)* ++ _ => Err($crate::Error::EINVAL) ++ } ++ } ++ } + }; + + // Done accumulating. + (@accumulate_entries ++ name: $BitFlags:ident, + { + $v:vis +- name: $BitFlags:ident, + attrs: $attrs:tt, + }, +- $entries:tt; ++ $entries:tt, ++ $try_froms:tt; + ) => { + libc_enum! { + @make_enum ++ name: $BitFlags, + { + $v +- name: $BitFlags, + attrs: $attrs, + entries: $entries, + } + } + }; + ++ // Done accumulating and want TryFrom ++ (@accumulate_entries ++ name: $BitFlags:ident, ++ { ++ $v:vis ++ attrs: $attrs:tt, ++ from_type: $repr:path, ++ }, ++ $entries:tt, ++ $try_froms:tt; ++ ) => { ++ libc_enum! { ++ @make_enum ++ name: $BitFlags, ++ { ++ $v ++ attrs: $attrs, ++ entries: $entries, ++ from_type: $repr, ++ try_froms: $try_froms ++ } ++ } ++ }; ++ + // Munch an attr. + (@accumulate_entries ++ name: $BitFlags:ident, + $prefix:tt, +- [$($entries:tt)*]; ++ [$($entries:tt)*], ++ [$($try_froms:tt)*]; + #[$attr:meta] $($tail:tt)* + ) => { + libc_enum! { + @accumulate_entries ++ name: $BitFlags, + $prefix, + [ + $($entries)* + #[$attr] ++ ], ++ [ ++ $($try_froms)* ++ #[$attr] + ]; + $($tail)* + } +@@ -136,32 +213,47 @@ macro_rules! libc_enum { + + // Munch last ident if not followed by a comma. + (@accumulate_entries ++ name: $BitFlags:ident, + $prefix:tt, +- [$($entries:tt)*]; ++ [$($entries:tt)*], ++ [$($try_froms:tt)*]; + $entry:ident + ) => { + libc_enum! { + @accumulate_entries ++ name: $BitFlags, + $prefix, + [ + $($entries)* + $entry = libc::$entry, ++ ], ++ [ ++ $($try_froms)* ++ libc::$entry => Ok($BitFlags::$entry), + ]; + } + }; + + // Munch an ident; covers terminating comma case. + (@accumulate_entries ++ name: $BitFlags:ident, + $prefix:tt, +- [$($entries:tt)*]; +- $entry:ident, $($tail:tt)* ++ [$($entries:tt)*], ++ [$($try_froms:tt)*]; ++ $entry:ident, ++ $($tail:tt)* + ) => { + libc_enum! { + @accumulate_entries ++ name: $BitFlags, + $prefix, + [ + $($entries)* + $entry = libc::$entry, ++ ], ++ [ ++ $($try_froms)* ++ libc::$entry => Ok($BitFlags::$entry), + ]; + $($tail)* + } +@@ -169,16 +261,24 @@ macro_rules! libc_enum { + + // Munch an ident and cast it to the given type; covers terminating comma. + (@accumulate_entries ++ name: $BitFlags:ident, + $prefix:tt, +- [$($entries:tt)*]; +- $entry:ident as $ty:ty, $($tail:tt)* ++ [$($entries:tt)*], ++ [$($try_froms:tt)*]; ++ $entry:ident as $ty:ty, ++ $($tail:tt)* + ) => { + libc_enum! { + @accumulate_entries ++ name: $BitFlags, + $prefix, + [ + $($entries)* + $entry = libc::$entry as $ty, ++ ], ++ [ ++ $($try_froms)* ++ libc::$entry as $ty => Ok($BitFlags::$entry), + ]; + $($tail)* + } +@@ -193,21 +293,36 @@ macro_rules! libc_enum { + ) => { + libc_enum! { + @accumulate_entries ++ name: $BitFlags, + { + $v +- name: $BitFlags, + attrs: [$(#[$attr])*], + }, ++ [], + []; + $($vals)* + } + }; +-} + +-/// A Rust version of the familiar C `offset_of` macro. It returns the byte +-/// offset of `field` within struct `ty` +-macro_rules! offset_of { +- ($ty:ty, $field:ident) => { +- &(*(ptr::null() as *const $ty)).$field as *const _ as usize +- } ++ // Entry rule including TryFrom ++ ( ++ $(#[$attr:meta])* ++ $v:vis enum $BitFlags:ident { ++ $($vals:tt)* ++ } ++ impl TryFrom<$repr:path> ++ ) => { ++ libc_enum! { ++ @accumulate_entries ++ name: $BitFlags, ++ { ++ $v ++ attrs: [$(#[$attr])*], ++ from_type: $repr, ++ }, ++ [], ++ []; ++ $($vals)* ++ } ++ }; + } +diff --git a/vendor/nix/src/mount/bsd.rs b/vendor/nix/src/mount/bsd.rs +new file mode 100644 +index 0000000..d124f1f +--- /dev/null ++++ b/vendor/nix/src/mount/bsd.rs +@@ -0,0 +1,453 @@ ++#[cfg(target_os = "freebsd")] ++use crate::Error; ++use crate::{Errno, NixPath, Result}; ++use libc::c_int; ++#[cfg(target_os = "freebsd")] ++use libc::{c_char, c_uint, c_void}; ++#[cfg(target_os = "freebsd")] ++use std::{ ++ borrow::Cow, ++ ffi::{CStr, CString}, ++ fmt, io, ++ marker::PhantomData, ++}; ++ ++libc_bitflags!( ++ /// Used with [`Nmount::nmount`]. ++ pub struct MntFlags: c_int { ++ /// ACL support enabled. ++ #[cfg(any(target_os = "netbsd", target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MNT_ACLS; ++ /// All I/O to the file system should be done asynchronously. ++ MNT_ASYNC; ++ /// dir should instead be a file system ID encoded as “FSID:val0:val1”. ++ #[cfg(target_os = "freebsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MNT_BYFSID; ++ /// Force a read-write mount even if the file system appears to be ++ /// unclean. ++ MNT_FORCE; ++ /// GEOM journal support enabled. ++ #[cfg(target_os = "freebsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MNT_GJOURNAL; ++ /// MAC support for objects. ++ #[cfg(any(target_os = "macos", target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MNT_MULTILABEL; ++ /// Disable read clustering. ++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MNT_NOCLUSTERR; ++ /// Disable write clustering. ++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MNT_NOCLUSTERW; ++ /// Enable NFS version 4 ACLs. ++ #[cfg(target_os = "freebsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MNT_NFS4ACLS; ++ /// Do not update access times. ++ MNT_NOATIME; ++ /// Disallow program execution. ++ MNT_NOEXEC; ++ /// Do not honor setuid or setgid bits on files when executing them. ++ MNT_NOSUID; ++ /// Do not follow symlinks. ++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MNT_NOSYMFOLLOW; ++ /// Mount read-only. ++ MNT_RDONLY; ++ /// Causes the vfs subsystem to update its data structures pertaining to ++ /// the specified already mounted file system. ++ MNT_RELOAD; ++ /// Create a snapshot of the file system. ++ /// ++ /// See [mksnap_ffs(8)](https://www.freebsd.org/cgi/man.cgi?query=mksnap_ffs) ++ #[cfg(any(target_os = "macos", target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MNT_SNAPSHOT; ++ /// Using soft updates. ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MNT_SOFTDEP; ++ /// Directories with the SUID bit set chown new files to their own ++ /// owner. ++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MNT_SUIDDIR; ++ /// All I/O to the file system should be done synchronously. ++ MNT_SYNCHRONOUS; ++ /// Union with underlying fs. ++ #[cfg(any( ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "netbsd" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MNT_UNION; ++ /// Indicates that the mount command is being applied to an already ++ /// mounted file system. ++ MNT_UPDATE; ++ /// Check vnode use counts. ++ #[cfg(target_os = "freebsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MNT_NONBUSY; ++ } ++); ++ ++/// The Error type of [`Nmount::nmount`]. ++/// ++/// It wraps an [`Errno`], but also may contain an additional message returned ++/// by `nmount(2)`. ++#[cfg(target_os = "freebsd")] ++#[derive(Debug)] ++pub struct NmountError { ++ errno: Error, ++ errmsg: Option, ++} ++ ++#[cfg(target_os = "freebsd")] ++impl NmountError { ++ /// Returns the additional error string sometimes generated by `nmount(2)`. ++ pub fn errmsg(&self) -> Option<&str> { ++ self.errmsg.as_deref() ++ } ++ ++ /// Returns the inner [`Error`] ++ pub const fn error(&self) -> Error { ++ self.errno ++ } ++ ++ fn new(error: Error, errmsg: Option<&CStr>) -> Self { ++ Self { ++ errno: error, ++ errmsg: errmsg.map(CStr::to_string_lossy).map(Cow::into_owned), ++ } ++ } ++} ++ ++#[cfg(target_os = "freebsd")] ++impl std::error::Error for NmountError {} ++ ++#[cfg(target_os = "freebsd")] ++impl fmt::Display for NmountError { ++ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ++ if let Some(errmsg) = &self.errmsg { ++ write!(f, "{:?}: {}: {}", self.errno, errmsg, self.errno.desc()) ++ } else { ++ write!(f, "{:?}: {}", self.errno, self.errno.desc()) ++ } ++ } ++} ++ ++#[cfg(target_os = "freebsd")] ++impl From for io::Error { ++ fn from(err: NmountError) -> Self { ++ err.errno.into() ++ } ++} ++ ++/// Result type of [`Nmount::nmount`]. ++#[cfg(target_os = "freebsd")] ++pub type NmountResult = std::result::Result<(), NmountError>; ++ ++/// Mount a FreeBSD file system. ++/// ++/// The `nmount(2)` system call works similarly to the `mount(8)` program; it ++/// takes its options as a series of name-value pairs. Most of the values are ++/// strings, as are all of the names. The `Nmount` structure builds up an ++/// argument list and then executes the syscall. ++/// ++/// # Examples ++/// ++/// To mount `target` onto `mountpoint` with `nullfs`: ++/// ``` ++/// # use nix::unistd::Uid; ++/// # use ::sysctl::{CtlValue, Sysctl}; ++/// # let ctl = ::sysctl::Ctl::new("vfs.usermount").unwrap(); ++/// # if !Uid::current().is_root() && CtlValue::Int(0) == ctl.value().unwrap() { ++/// # return; ++/// # }; ++/// use nix::mount::{MntFlags, Nmount, unmount}; ++/// use std::ffi::CString; ++/// use tempfile::tempdir; ++/// ++/// let mountpoint = tempdir().unwrap(); ++/// let target = tempdir().unwrap(); ++/// ++/// let fstype = CString::new("fstype").unwrap(); ++/// let nullfs = CString::new("nullfs").unwrap(); ++/// Nmount::new() ++/// .str_opt(&fstype, &nullfs) ++/// .str_opt_owned("fspath", mountpoint.path().to_str().unwrap()) ++/// .str_opt_owned("target", target.path().to_str().unwrap()) ++/// .nmount(MntFlags::empty()).unwrap(); ++/// ++/// unmount(mountpoint.path(), MntFlags::empty()).unwrap(); ++/// ``` ++/// ++/// # See Also ++/// * [`nmount(2)`](https://www.freebsd.org/cgi/man.cgi?query=nmount) ++/// * [`nullfs(5)`](https://www.freebsd.org/cgi/man.cgi?query=nullfs) ++#[cfg(target_os = "freebsd")] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++#[derive(Debug, Default)] ++pub struct Nmount<'a> { ++ // n.b. notgull: In reality, this is a list that contains ++ // both mutable and immutable pointers. ++ // Be careful using this. ++ iov: Vec, ++ is_owned: Vec, ++ marker: PhantomData<&'a ()>, ++} ++ ++#[cfg(target_os = "freebsd")] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++impl<'a> Nmount<'a> { ++ /// Helper function to push a slice onto the `iov` array. ++ fn push_slice(&mut self, val: &'a [u8], is_owned: bool) { ++ self.iov.push(libc::iovec { ++ iov_base: val.as_ptr() as *mut _, ++ iov_len: val.len(), ++ }); ++ self.is_owned.push(is_owned); ++ } ++ ++ /// Helper function to push a pointer and its length onto the `iov` array. ++ fn push_pointer_and_length( ++ &mut self, ++ val: *const u8, ++ len: usize, ++ is_owned: bool, ++ ) { ++ self.iov.push(libc::iovec { ++ iov_base: val as *mut _, ++ iov_len: len, ++ }); ++ self.is_owned.push(is_owned); ++ } ++ ++ /// Helper function to push a `nix` path as owned. ++ fn push_nix_path(&mut self, val: &P) { ++ val.with_nix_path(|s| { ++ let len = s.to_bytes_with_nul().len(); ++ let ptr = s.to_owned().into_raw() as *const u8; ++ ++ self.push_pointer_and_length(ptr, len, true); ++ }) ++ .unwrap(); ++ } ++ ++ /// Add an opaque mount option. ++ /// ++ /// Some file systems take binary-valued mount options. They can be set ++ /// with this method. ++ /// ++ /// # Safety ++ /// ++ /// Unsafe because it will cause `Nmount::nmount` to dereference a raw ++ /// pointer. The user is responsible for ensuring that `val` is valid and ++ /// its lifetime outlives `self`! An easy way to do that is to give the ++ /// value a larger scope than `name` ++ /// ++ /// # Examples ++ /// ``` ++ /// use libc::c_void; ++ /// use nix::mount::Nmount; ++ /// use std::ffi::CString; ++ /// use std::mem; ++ /// ++ /// // Note that flags outlives name ++ /// let mut flags: u32 = 0xdeadbeef; ++ /// let name = CString::new("flags").unwrap(); ++ /// let p = &mut flags as *mut u32 as *mut c_void; ++ /// let len = mem::size_of_val(&flags); ++ /// let mut nmount = Nmount::new(); ++ /// unsafe { nmount.mut_ptr_opt(&name, p, len) }; ++ /// ``` ++ pub unsafe fn mut_ptr_opt( ++ &mut self, ++ name: &'a CStr, ++ val: *mut c_void, ++ len: usize, ++ ) -> &mut Self { ++ self.push_slice(name.to_bytes_with_nul(), false); ++ self.push_pointer_and_length(val.cast(), len, false); ++ self ++ } ++ ++ /// Add a mount option that does not take a value. ++ /// ++ /// # Examples ++ /// ``` ++ /// use nix::mount::Nmount; ++ /// use std::ffi::CString; ++ /// ++ /// let read_only = CString::new("ro").unwrap(); ++ /// Nmount::new() ++ /// .null_opt(&read_only); ++ /// ``` ++ pub fn null_opt(&mut self, name: &'a CStr) -> &mut Self { ++ self.push_slice(name.to_bytes_with_nul(), false); ++ self.push_slice(&[], false); ++ self ++ } ++ ++ /// Add a mount option that does not take a value, but whose name must be ++ /// owned. ++ /// ++ /// ++ /// This has higher runtime cost than [`Nmount::null_opt`], but is useful ++ /// when the name's lifetime doesn't outlive the `Nmount`, or it's a ++ /// different string type than `CStr`. ++ /// ++ /// # Examples ++ /// ``` ++ /// use nix::mount::Nmount; ++ /// ++ /// let read_only = "ro"; ++ /// let mut nmount: Nmount<'static> = Nmount::new(); ++ /// nmount.null_opt_owned(read_only); ++ /// ``` ++ pub fn null_opt_owned( ++ &mut self, ++ name: &P, ++ ) -> &mut Self { ++ self.push_nix_path(name); ++ self.push_slice(&[], false); ++ self ++ } ++ ++ /// Add a mount option as a [`CStr`]. ++ /// ++ /// # Examples ++ /// ``` ++ /// use nix::mount::Nmount; ++ /// use std::ffi::CString; ++ /// ++ /// let fstype = CString::new("fstype").unwrap(); ++ /// let nullfs = CString::new("nullfs").unwrap(); ++ /// Nmount::new() ++ /// .str_opt(&fstype, &nullfs); ++ /// ``` ++ pub fn str_opt(&mut self, name: &'a CStr, val: &'a CStr) -> &mut Self { ++ self.push_slice(name.to_bytes_with_nul(), false); ++ self.push_slice(val.to_bytes_with_nul(), false); ++ self ++ } ++ ++ /// Add a mount option as an owned string. ++ /// ++ /// This has higher runtime cost than [`Nmount::str_opt`], but is useful ++ /// when the value's lifetime doesn't outlive the `Nmount`, or it's a ++ /// different string type than `CStr`. ++ /// ++ /// # Examples ++ /// ``` ++ /// use nix::mount::Nmount; ++ /// use std::path::Path; ++ /// ++ /// let mountpoint = Path::new("/mnt"); ++ /// Nmount::new() ++ /// .str_opt_owned("fspath", mountpoint.to_str().unwrap()); ++ /// ``` ++ pub fn str_opt_owned(&mut self, name: &P1, val: &P2) -> &mut Self ++ where ++ P1: ?Sized + NixPath, ++ P2: ?Sized + NixPath, ++ { ++ self.push_nix_path(name); ++ self.push_nix_path(val); ++ self ++ } ++ ++ /// Create a new `Nmount` struct with no options ++ pub fn new() -> Self { ++ Self::default() ++ } ++ ++ /// Actually mount the file system. ++ pub fn nmount(&mut self, flags: MntFlags) -> NmountResult { ++ const ERRMSG_NAME: &[u8] = b"errmsg\0"; ++ let mut errmsg = vec![0u8; 255]; ++ ++ // nmount can return extra error information via a "errmsg" return ++ // argument. ++ self.push_slice(ERRMSG_NAME, false); ++ ++ // SAFETY: we are pushing a mutable iovec here, so we can't use ++ // the above method ++ self.iov.push(libc::iovec { ++ iov_base: errmsg.as_mut_ptr() as *mut c_void, ++ iov_len: errmsg.len(), ++ }); ++ ++ let niov = self.iov.len() as c_uint; ++ let iovp = self.iov.as_mut_ptr() as *mut libc::iovec; ++ let res = unsafe { libc::nmount(iovp, niov, flags.bits) }; ++ match Errno::result(res) { ++ Ok(_) => Ok(()), ++ Err(error) => { ++ let errmsg = match errmsg.iter().position(|&x| x == 0) { ++ None => None, ++ Some(0) => None, ++ Some(n) => { ++ let sl = &errmsg[0..n + 1]; ++ Some(CStr::from_bytes_with_nul(sl).unwrap()) ++ } ++ }; ++ Err(NmountError::new(error, errmsg)) ++ } ++ } ++ } ++} ++ ++#[cfg(target_os = "freebsd")] ++impl<'a> Drop for Nmount<'a> { ++ fn drop(&mut self) { ++ for (iov, is_owned) in self.iov.iter().zip(self.is_owned.iter()) { ++ if *is_owned { ++ // Free the owned string. Safe because we recorded ownership, ++ // and Nmount does not implement Clone. ++ unsafe { ++ drop(CString::from_raw(iov.iov_base as *mut c_char)); ++ } ++ } ++ } ++ } ++} ++ ++/// Unmount the file system mounted at `mountpoint`. ++/// ++/// Useful flags include ++/// * `MNT_FORCE` - Unmount even if still in use. ++#[cfg_attr( ++ target_os = "freebsd", ++ doc = " ++* `MNT_BYFSID` - `mountpoint` is not a path, but a file system ID ++ encoded as `FSID:val0:val1`, where `val0` and `val1` ++ are the contents of the `fsid_t val[]` array in decimal. ++ The file system that has the specified file system ID ++ will be unmounted. See ++ [`statfs`](crate::sys::statfs::statfs) to determine the ++ `fsid`. ++" ++)] ++pub fn unmount

(mountpoint: &P, flags: MntFlags) -> Result<()> ++where ++ P: ?Sized + NixPath, ++{ ++ let res = mountpoint.with_nix_path(|cstr| unsafe { ++ libc::unmount(cstr.as_ptr(), flags.bits) ++ })?; ++ ++ Errno::result(res).map(drop) ++} +diff --git a/vendor/nix/src/mount.rs b/vendor/nix/src/mount/linux.rs +similarity index 53% +rename from vendor/nix/src/mount.rs +rename to vendor/nix/src/mount/linux.rs +index a9902b1..cf6a60b 100644 +--- a/vendor/nix/src/mount.rs ++++ b/vendor/nix/src/mount/linux.rs +@@ -1,6 +1,7 @@ +-use libc::{self, c_ulong, c_int}; +-use {Result, NixPath}; +-use errno::Errno; ++#![allow(missing_docs)] ++use crate::errno::Errno; ++use crate::{NixPath, Result}; ++use libc::{self, c_int, c_ulong}; + + libc_bitflags!( + pub struct MsFlags: c_ulong { +@@ -38,6 +39,7 @@ libc_bitflags!( + MS_KERNMOUNT; + MS_I_VERSION; + MS_STRICTATIME; ++ MS_LAZYTIME; + MS_ACTIVE; + MS_NOUSER; + MS_RMT_MASK; +@@ -51,47 +53,62 @@ libc_bitflags!( + MNT_FORCE; + MNT_DETACH; + MNT_EXPIRE; ++ UMOUNT_NOFOLLOW; + } + ); + +-pub fn mount( +- source: Option<&P1>, +- target: &P2, +- fstype: Option<&P3>, +- flags: MsFlags, +- data: Option<&P4>) -> Result<()> { ++pub fn mount< ++ P1: ?Sized + NixPath, ++ P2: ?Sized + NixPath, ++ P3: ?Sized + NixPath, ++ P4: ?Sized + NixPath, ++>( ++ source: Option<&P1>, ++ target: &P2, ++ fstype: Option<&P3>, ++ flags: MsFlags, ++ data: Option<&P4>, ++) -> Result<()> { ++ fn with_opt_nix_path(p: Option<&P>, f: F) -> Result ++ where ++ P: ?Sized + NixPath, ++ F: FnOnce(*const libc::c_char) -> T, ++ { ++ match p { ++ Some(path) => path.with_nix_path(|p_str| f(p_str.as_ptr())), ++ None => Ok(f(std::ptr::null())), ++ } ++ } + +- let res = +- source.with_nix_path(|source| { +- target.with_nix_path(|target| { +- fstype.with_nix_path(|fstype| { +- data.with_nix_path(|data| { +- unsafe { +- libc::mount(source.as_ptr(), +- target.as_ptr(), +- fstype.as_ptr(), +- flags.bits, +- data.as_ptr() as *const libc::c_void) +- } +- }) ++ let res = with_opt_nix_path(source, |s| { ++ target.with_nix_path(|t| { ++ with_opt_nix_path(fstype, |ty| { ++ with_opt_nix_path(data, |d| unsafe { ++ libc::mount( ++ s, ++ t.as_ptr(), ++ ty, ++ flags.bits, ++ d as *const libc::c_void, ++ ) + }) + }) +- })????; ++ }) ++ })????; + + Errno::result(res).map(drop) + } + + pub fn umount(target: &P) -> Result<()> { +- let res = target.with_nix_path(|cstr| { +- unsafe { libc::umount(cstr.as_ptr()) } +- })?; ++ let res = ++ target.with_nix_path(|cstr| unsafe { libc::umount(cstr.as_ptr()) })?; + + Errno::result(res).map(drop) + } + + pub fn umount2(target: &P, flags: MntFlags) -> Result<()> { +- let res = target.with_nix_path(|cstr| { +- unsafe { libc::umount2(cstr.as_ptr(), flags.bits) } ++ let res = target.with_nix_path(|cstr| unsafe { ++ libc::umount2(cstr.as_ptr(), flags.bits) + })?; + + Errno::result(res).map(drop) +diff --git a/vendor/nix/src/mount/mod.rs b/vendor/nix/src/mount/mod.rs +new file mode 100644 +index 0000000..e98b49c +--- /dev/null ++++ b/vendor/nix/src/mount/mod.rs +@@ -0,0 +1,26 @@ ++//! Mount file systems ++#[cfg(any(target_os = "android", target_os = "linux"))] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++mod linux; ++ ++#[cfg(any(target_os = "android", target_os = "linux"))] ++pub use self::linux::*; ++ ++#[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++))] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++mod bsd; ++ ++#[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++))] ++pub use self::bsd::*; +diff --git a/vendor/nix/src/mqueue.rs b/vendor/nix/src/mqueue.rs +index 331bac9..33599bf 100644 +--- a/vendor/nix/src/mqueue.rs ++++ b/vendor/nix/src/mqueue.rs +@@ -1,46 +1,107 @@ + //! Posix Message Queue functions + //! +-//! [Further reading and details on the C API](http://man7.org/linux/man-pages/man7/mq_overview.7.html) ++//! # Example ++//! ++// no_run because a kernel module may be required. ++//! ```no_run ++//! # use std::ffi::CString; ++//! # use nix::mqueue::*; ++//! use nix::sys::stat::Mode; ++//! ++//! const MSG_SIZE: mq_attr_member_t = 32; ++//! let mq_name= CString::new("/a_nix_test_queue").unwrap(); ++//! ++//! let oflag0 = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY; ++//! let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH; ++//! let mqd0 = mq_open(&mq_name, oflag0, mode, None).unwrap(); ++//! let msg_to_send = b"msg_1"; ++//! mq_send(&mqd0, msg_to_send, 1).unwrap(); ++//! ++//! let oflag1 = MQ_OFlag::O_CREAT | MQ_OFlag::O_RDONLY; ++//! let mqd1 = mq_open(&mq_name, oflag1, mode, None).unwrap(); ++//! let mut buf = [0u8; 32]; ++//! let mut prio = 0u32; ++//! let len = mq_receive(&mqd1, &mut buf, &mut prio).unwrap(); ++//! assert_eq!(prio, 1); ++//! assert_eq!(msg_to_send, &buf[0..len]); ++//! ++//! mq_close(mqd1).unwrap(); ++//! mq_close(mqd0).unwrap(); ++//! ``` ++//! [Further reading and details on the C API](https://man7.org/linux/man-pages/man7/mq_overview.7.html) + +-use Result; +-use errno::Errno; ++use crate::errno::Errno; ++use crate::Result; + +-use libc::{self, c_char, c_long, mqd_t, size_t}; +-use std::ffi::CString; +-use sys::stat::Mode; ++use crate::sys::stat::Mode; ++use libc::{self, c_char, mqd_t, size_t}; ++use std::ffi::CStr; + use std::mem; + +-libc_bitflags!{ ++libc_bitflags! { ++ /// Used with [`mq_open`]. + pub struct MQ_OFlag: libc::c_int { ++ /// Open the message queue for receiving messages. + O_RDONLY; ++ /// Open the queue for sending messages. + O_WRONLY; ++ /// Open the queue for both receiving and sending messages + O_RDWR; ++ /// Create a message queue. + O_CREAT; ++ /// If set along with `O_CREAT`, `mq_open` will fail if the message ++ /// queue name exists. + O_EXCL; ++ /// `mq_send` and `mq_receive` should fail with `EAGAIN` rather than ++ /// wait for resources that are not currently available. + O_NONBLOCK; ++ /// Set the close-on-exec flag for the message queue descriptor. + O_CLOEXEC; + } + } + +-libc_bitflags!{ +- pub struct FdFlag: libc::c_int { +- FD_CLOEXEC; +- } +-} +- ++/// A message-queue attribute, optionally used with [`mq_setattr`] and ++/// [`mq_getattr`] and optionally [`mq_open`], + #[repr(C)] + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct MqAttr { + mq_attr: libc::mq_attr, + } + ++/// Identifies an open POSIX Message Queue ++// A safer wrapper around libc::mqd_t, which is a pointer on some platforms ++// Deliberately is not Clone to prevent use-after-close scenarios ++#[repr(transparent)] ++#[derive(Debug)] ++#[allow(missing_copy_implementations)] ++pub struct MqdT(mqd_t); ++ ++// x32 compatibility ++// See https://sourceware.org/bugzilla/show_bug.cgi?id=21279 ++/// Size of a message queue attribute member ++#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++pub type mq_attr_member_t = i64; ++/// Size of a message queue attribute member ++#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++pub type mq_attr_member_t = libc::c_long; ++ + impl MqAttr { +- pub fn new(mq_flags: c_long, +- mq_maxmsg: c_long, +- mq_msgsize: c_long, +- mq_curmsgs: c_long) +- -> MqAttr +- { ++ /// Create a new message queue attribute ++ /// ++ /// # Arguments ++ /// ++ /// - `mq_flags`: Either `0` or `O_NONBLOCK`. ++ /// - `mq_maxmsg`: Maximum number of messages on the queue. ++ /// - `mq_msgsize`: Maximum message size in bytes. ++ /// - `mq_curmsgs`: Number of messages currently in the queue. ++ pub fn new( ++ mq_flags: mq_attr_member_t, ++ mq_maxmsg: mq_attr_member_t, ++ mq_msgsize: mq_attr_member_t, ++ mq_curmsgs: mq_attr_member_t, ++ ) -> MqAttr { + let mut attr = mem::MaybeUninit::::uninit(); + unsafe { + let p = attr.as_mut_ptr(); +@@ -48,123 +109,168 @@ impl MqAttr { + (*p).mq_maxmsg = mq_maxmsg; + (*p).mq_msgsize = mq_msgsize; + (*p).mq_curmsgs = mq_curmsgs; +- MqAttr { mq_attr: attr.assume_init() } ++ MqAttr { ++ mq_attr: attr.assume_init(), ++ } + } + } + +- pub fn flags(&self) -> c_long { ++ /// The current flags, either `0` or `O_NONBLOCK`. ++ pub const fn flags(&self) -> mq_attr_member_t { + self.mq_attr.mq_flags + } +-} + ++ /// The max number of messages that can be held by the queue ++ pub const fn maxmsg(&self) -> mq_attr_member_t { ++ self.mq_attr.mq_maxmsg ++ } ++ ++ /// The maximum size of each message (in bytes) ++ pub const fn msgsize(&self) -> mq_attr_member_t { ++ self.mq_attr.mq_msgsize ++ } ++ ++ /// The number of messages currently held in the queue ++ pub const fn curmsgs(&self) -> mq_attr_member_t { ++ self.mq_attr.mq_curmsgs ++ } ++} + + /// Open a message queue + /// +-/// See also [`mq_open(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_open.html) ++/// See also [`mq_open(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_open.html) + // The mode.bits cast is only lossless on some OSes + #[allow(clippy::cast_lossless)] +-pub fn mq_open(name: &CString, +- oflag: MQ_OFlag, +- mode: Mode, +- attr: Option<&MqAttr>) +- -> Result { ++pub fn mq_open( ++ name: &CStr, ++ oflag: MQ_OFlag, ++ mode: Mode, ++ attr: Option<&MqAttr>, ++) -> Result { + let res = match attr { + Some(mq_attr) => unsafe { +- libc::mq_open(name.as_ptr(), +- oflag.bits(), +- mode.bits() as libc::c_int, +- &mq_attr.mq_attr as *const libc::mq_attr) ++ libc::mq_open( ++ name.as_ptr(), ++ oflag.bits(), ++ mode.bits() as libc::c_int, ++ &mq_attr.mq_attr as *const libc::mq_attr, ++ ) + }, + None => unsafe { libc::mq_open(name.as_ptr(), oflag.bits()) }, + }; +- Errno::result(res) ++ Errno::result(res).map(MqdT) + } + + /// Remove a message queue + /// +-/// See also [`mq_unlink(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_unlink.html) +-pub fn mq_unlink(name: &CString) -> Result<()> { ++/// See also [`mq_unlink(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_unlink.html) ++pub fn mq_unlink(name: &CStr) -> Result<()> { + let res = unsafe { libc::mq_unlink(name.as_ptr()) }; + Errno::result(res).map(drop) + } + + /// Close a message queue + /// +-/// See also [`mq_close(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_close.html) +-pub fn mq_close(mqdes: mqd_t) -> Result<()> { +- let res = unsafe { libc::mq_close(mqdes) }; ++/// See also [`mq_close(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_close.html) ++pub fn mq_close(mqdes: MqdT) -> Result<()> { ++ let res = unsafe { libc::mq_close(mqdes.0) }; + Errno::result(res).map(drop) + } + + /// Receive a message from a message queue + /// +-/// See also [`mq_receive(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html) +-pub fn mq_receive(mqdes: mqd_t, message: &mut [u8], msg_prio: &mut u32) -> Result { ++/// See also [`mq_receive(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html) ++pub fn mq_receive( ++ mqdes: &MqdT, ++ message: &mut [u8], ++ msg_prio: &mut u32, ++) -> Result { + let len = message.len() as size_t; + let res = unsafe { +- libc::mq_receive(mqdes, +- message.as_mut_ptr() as *mut c_char, +- len, +- msg_prio as *mut u32) ++ libc::mq_receive( ++ mqdes.0, ++ message.as_mut_ptr() as *mut c_char, ++ len, ++ msg_prio as *mut u32, ++ ) + }; + Errno::result(res).map(|r| r as usize) + } + + /// Send a message to a message queue + /// +-/// See also [`mq_send(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html) +-pub fn mq_send(mqdes: mqd_t, message: &[u8], msq_prio: u32) -> Result<()> { ++/// See also [`mq_send(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html) ++pub fn mq_send(mqdes: &MqdT, message: &[u8], msq_prio: u32) -> Result<()> { + let res = unsafe { +- libc::mq_send(mqdes, +- message.as_ptr() as *const c_char, +- message.len(), +- msq_prio) ++ libc::mq_send( ++ mqdes.0, ++ message.as_ptr() as *const c_char, ++ message.len(), ++ msq_prio, ++ ) + }; + Errno::result(res).map(drop) + } + + /// Get message queue attributes + /// +-/// See also [`mq_getattr(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_getattr.html) +-pub fn mq_getattr(mqd: mqd_t) -> Result { ++/// See also [`mq_getattr(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_getattr.html) ++pub fn mq_getattr(mqd: &MqdT) -> Result { + let mut attr = mem::MaybeUninit::::uninit(); +- let res = unsafe { libc::mq_getattr(mqd, attr.as_mut_ptr()) }; +- Errno::result(res).map(|_| unsafe{MqAttr { mq_attr: attr.assume_init() }}) ++ let res = unsafe { libc::mq_getattr(mqd.0, attr.as_mut_ptr()) }; ++ Errno::result(res).map(|_| unsafe { ++ MqAttr { ++ mq_attr: attr.assume_init(), ++ } ++ }) + } + + /// Set the attributes of the message queue. Only `O_NONBLOCK` can be set, everything else will be ignored + /// Returns the old attributes + /// It is recommend to use the `mq_set_nonblock()` and `mq_remove_nonblock()` convenience functions as they are easier to use + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_setattr.html) +-pub fn mq_setattr(mqd: mqd_t, newattr: &MqAttr) -> Result { ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_setattr.html) ++pub fn mq_setattr(mqd: &MqdT, newattr: &MqAttr) -> Result { + let mut attr = mem::MaybeUninit::::uninit(); + let res = unsafe { +- libc::mq_setattr(mqd, &newattr.mq_attr as *const libc::mq_attr, attr.as_mut_ptr()) ++ libc::mq_setattr( ++ mqd.0, ++ &newattr.mq_attr as *const libc::mq_attr, ++ attr.as_mut_ptr(), ++ ) + }; +- Errno::result(res).map(|_| unsafe{ MqAttr { mq_attr: attr.assume_init() }}) ++ Errno::result(res).map(|_| unsafe { ++ MqAttr { ++ mq_attr: attr.assume_init(), ++ } ++ }) + } + + /// Convenience function. + /// Sets the `O_NONBLOCK` attribute for a given message queue descriptor + /// Returns the old attributes +-pub fn mq_set_nonblock(mqd: mqd_t) -> Result { ++#[allow(clippy::useless_conversion)] // Not useless on all OSes ++pub fn mq_set_nonblock(mqd: &MqdT) -> Result { + let oldattr = mq_getattr(mqd)?; +- let newattr = MqAttr::new(c_long::from(MQ_OFlag::O_NONBLOCK.bits()), +- oldattr.mq_attr.mq_maxmsg, +- oldattr.mq_attr.mq_msgsize, +- oldattr.mq_attr.mq_curmsgs); ++ let newattr = MqAttr::new( ++ mq_attr_member_t::from(MQ_OFlag::O_NONBLOCK.bits()), ++ oldattr.mq_attr.mq_maxmsg, ++ oldattr.mq_attr.mq_msgsize, ++ oldattr.mq_attr.mq_curmsgs, ++ ); + mq_setattr(mqd, &newattr) + } + + /// Convenience function. + /// Removes `O_NONBLOCK` attribute for a given message queue descriptor + /// Returns the old attributes +-pub fn mq_remove_nonblock(mqd: mqd_t) -> Result { ++pub fn mq_remove_nonblock(mqd: &MqdT) -> Result { + let oldattr = mq_getattr(mqd)?; +- let newattr = MqAttr::new(0, +- oldattr.mq_attr.mq_maxmsg, +- oldattr.mq_attr.mq_msgsize, +- oldattr.mq_attr.mq_curmsgs); ++ let newattr = MqAttr::new( ++ 0, ++ oldattr.mq_attr.mq_maxmsg, ++ oldattr.mq_attr.mq_msgsize, ++ oldattr.mq_attr.mq_curmsgs, ++ ); + mq_setattr(mqd, &newattr) + } +diff --git a/vendor/nix/src/net/if_.rs b/vendor/nix/src/net/if_.rs +index 58d677a..b2423bc 100644 +--- a/vendor/nix/src/net/if_.rs ++++ b/vendor/nix/src/net/if_.rs +@@ -3,13 +3,13 @@ + //! Uses Linux and/or POSIX functions to resolve interface names like "eth0" + //! or "socan1" into device numbers. + +-use libc; ++use crate::{Error, NixPath, Result}; + use libc::c_uint; +-use {Result, Error, NixPath}; + + /// Resolve an interface into a interface number. + pub fn if_nametoindex(name: &P) -> Result { +- let if_index = name.with_nix_path(|name| unsafe { libc::if_nametoindex(name.as_ptr()) })?; ++ let if_index = name ++ .with_nix_path(|name| unsafe { libc::if_nametoindex(name.as_ptr()) })?; + + if if_index == 0 { + Err(Error::last()) +@@ -22,58 +22,65 @@ libc_bitflags!( + /// Standard interface flags, used by `getifaddrs` + pub struct InterfaceFlags: libc::c_int { + /// Interface is running. (see +- /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) ++ /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + IFF_UP; + /// Valid broadcast address set. (see +- /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) ++ /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + IFF_BROADCAST; + /// Internal debugging flag. (see +- /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) ++ /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) ++ #[cfg(not(target_os = "haiku"))] + IFF_DEBUG; + /// Interface is a loopback interface. (see +- /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) ++ /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + IFF_LOOPBACK; + /// Interface is a point-to-point link. (see +- /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) ++ /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + IFF_POINTOPOINT; + /// Avoid use of trailers. (see +- /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) ++ /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + #[cfg(any(target_os = "android", + target_os = "fuchsia", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", ++ target_os = "illumos", + target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_NOTRAILERS; + /// Interface manages own routes. + #[cfg(any(target_os = "dragonfly"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_SMART; + /// Resources allocated. (see +- /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) ++ /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + #[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "fuchsia", ++ target_os = "illumos", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_RUNNING; + /// No arp protocol, L2 destination address not set. (see +- /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) ++ /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + IFF_NOARP; + /// Interface is in promiscuous mode. (see +- /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) ++ /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + IFF_PROMISC; + /// Receive all multicast packets. (see +- /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) ++ /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + IFF_ALLMULTI; + /// Master of a load balancing bundle. (see +- /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) ++ /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_MASTER; + /// transmission in progress, tx hardware queue is full + #[cfg(any(target_os = "freebsd", +@@ -81,24 +88,27 @@ libc_bitflags!( + target_os = "netbsd", + target_os = "openbsd", + target_os = "ios"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_OACTIVE; + /// Protocol code on board. +- #[cfg(target_os = "solaris")] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_INTELLIGENT; + /// Slave of a load balancing bundle. (see +- /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) ++ /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_SLAVE; + /// Can't hear own transmissions. + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "netbsd", +- target_os = "openbsd", +- target_os = "osx"))] ++ target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_SIMPLEX; + /// Supports multicast. (see +- /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) ++ /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + IFF_MULTICAST; + /// Per link layer defined bit. + #[cfg(any(target_os = "dragonfly", +@@ -107,13 +117,16 @@ libc_bitflags!( + target_os = "netbsd", + target_os = "openbsd", + target_os = "ios"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_LINK0; + /// Multicast using broadcast. +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_MULTI_BCAST; + /// Is able to select media type via ifmap. (see +- /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) ++ /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_PORTSEL; + /// Per link layer defined bit. + #[cfg(any(target_os = "dragonfly", +@@ -122,13 +135,16 @@ libc_bitflags!( + target_os = "netbsd", + target_os = "openbsd", + target_os = "ios"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_LINK1; + /// Non-unique address. +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_UNNUMBERED; + /// Auto media selection active. (see +- /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) ++ /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_AUTOMEDIA; + /// Per link layer defined bit. + #[cfg(any(target_os = "dragonfly", +@@ -137,132 +153,317 @@ libc_bitflags!( + target_os = "netbsd", + target_os = "openbsd", + target_os = "ios"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_LINK2; + /// Use alternate physical connection. + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "ios"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_ALTPHYS; +- /// DHCP controlls interface. +- #[cfg(any(target_os = "solaris"))] ++ /// DHCP controls interface. ++ #[cfg(any(target_os = "solaris", target_os = "illumos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_DHCPRUNNING; + /// The addresses are lost when the interface goes down. (see +- /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) ++ /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html)) + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_DYNAMIC; + /// Do not advertise. +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_PRIVATE; + /// Driver signals L1 up. Volatile. + #[cfg(any(target_os = "fuchsia", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_LOWER_UP; + /// Interface is in polling mode. + #[cfg(any(target_os = "dragonfly"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_POLLING_COMPAT; + /// Unconfigurable using ioctl(2). + #[cfg(any(target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_CANTCONFIG; + /// Do not transmit packets. +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_NOXMIT; + /// Driver signals dormant. Volatile. + #[cfg(any(target_os = "fuchsia", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_DORMANT; + /// User-requested promisc mode. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_PPROMISC; + /// Just on-link subnet. +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_NOLOCAL; + /// Echo sent packets. Volatile. + #[cfg(any(target_os = "fuchsia", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_ECHO; + /// User-requested monitor mode. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_MONITOR; + /// Address is deprecated. +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_DEPRECATED; + /// Static ARP. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_STATICARP; + /// Address from stateless addrconf. +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_ADDRCONF; + /// Interface is in polling mode. + #[cfg(any(target_os = "dragonfly"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_NPOLLING; + /// Router on interface. +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_ROUTER; + /// Interface is in polling mode. + #[cfg(any(target_os = "dragonfly"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_IDIRECT; + /// Interface is winding down + #[cfg(any(target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_DYING; + /// No NUD on interface. +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_NONUD; + /// Interface is being renamed + #[cfg(any(target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_RENAMING; + /// Anycast address. +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_ANYCAST; + /// Don't exchange routing info. +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_NORTEXCH; + /// Do not provide packet information + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_NO_PI as libc::c_int; +- /// TUN device (no Ethernet headers) ++ /// TUN device (no Ethernet headers) + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_TUN as libc::c_int; + /// TAP device + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_TAP as libc::c_int; + /// IPv4 interface. +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_IPV4; + /// IPv6 interface. +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_IPV6; + /// in.mpathd test address +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_NOFAILOVER; + /// Interface has failed +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_FAILED; + /// Interface is a hot-spare +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_STANDBY; + /// Functioning but not used +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_INACTIVE; + /// Interface is offline +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_OFFLINE; +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(target_os = "solaris")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_COS_ENABLED; + /// Prefer as source addr. +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(target_os = "solaris")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_PREFERRED; + /// RFC3041 +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(target_os = "solaris")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_TEMPORARY; + /// MTU set with SIOCSLIFMTU +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(target_os = "solaris")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_FIXEDMTU; + /// Cannot send / receive packets +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(target_os = "solaris")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_VIRTUAL; + /// Local address in use +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(target_os = "solaris")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_DUPLICATE; + /// IPMP IP interface +- #[cfg(any(target_os = "solaris"))] ++ #[cfg(target_os = "solaris")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IFF_IPMP; + } + ); ++ ++#[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "fuchsia", ++ target_os = "ios", ++ target_os = "linux", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd", ++))] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++mod if_nameindex { ++ use super::*; ++ ++ use std::ffi::CStr; ++ use std::fmt; ++ use std::marker::PhantomData; ++ use std::ptr::NonNull; ++ ++ /// A network interface. Has a name like "eth0" or "wlp4s0" or "wlan0", as well as an index ++ /// (1, 2, 3, etc) that identifies it in the OS's networking stack. ++ #[allow(missing_copy_implementations)] ++ #[repr(transparent)] ++ pub struct Interface(libc::if_nameindex); ++ ++ impl Interface { ++ /// Obtain the index of this interface. ++ pub fn index(&self) -> c_uint { ++ self.0.if_index ++ } ++ ++ /// Obtain the name of this interface. ++ pub fn name(&self) -> &CStr { ++ unsafe { CStr::from_ptr(self.0.if_name) } ++ } ++ } ++ ++ impl fmt::Debug for Interface { ++ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ++ f.debug_struct("Interface") ++ .field("index", &self.index()) ++ .field("name", &self.name()) ++ .finish() ++ } ++ } ++ ++ /// A list of the network interfaces available on this system. Obtained from [`if_nameindex()`]. ++ pub struct Interfaces { ++ ptr: NonNull, ++ } ++ ++ impl Interfaces { ++ /// Iterate over the interfaces in this list. ++ #[inline] ++ pub fn iter(&self) -> InterfacesIter<'_> { ++ self.into_iter() ++ } ++ ++ /// Convert this to a slice of interfaces. Note that the underlying interfaces list is ++ /// null-terminated, so calling this calculates the length. If random access isn't needed, ++ /// [`Interfaces::iter()`] should be used instead. ++ pub fn to_slice(&self) -> &[Interface] { ++ let ifs = self.ptr.as_ptr() as *const Interface; ++ let len = self.iter().count(); ++ unsafe { std::slice::from_raw_parts(ifs, len) } ++ } ++ } ++ ++ impl Drop for Interfaces { ++ fn drop(&mut self) { ++ unsafe { libc::if_freenameindex(self.ptr.as_ptr()) }; ++ } ++ } ++ ++ impl fmt::Debug for Interfaces { ++ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ++ self.to_slice().fmt(f) ++ } ++ } ++ ++ impl<'a> IntoIterator for &'a Interfaces { ++ type IntoIter = InterfacesIter<'a>; ++ type Item = &'a Interface; ++ #[inline] ++ fn into_iter(self) -> Self::IntoIter { ++ InterfacesIter { ++ ptr: self.ptr.as_ptr(), ++ _marker: PhantomData, ++ } ++ } ++ } ++ ++ /// An iterator over the interfaces in an [`Interfaces`]. ++ #[derive(Debug)] ++ pub struct InterfacesIter<'a> { ++ ptr: *const libc::if_nameindex, ++ _marker: PhantomData<&'a Interfaces>, ++ } ++ ++ impl<'a> Iterator for InterfacesIter<'a> { ++ type Item = &'a Interface; ++ #[inline] ++ fn next(&mut self) -> Option { ++ unsafe { ++ if (*self.ptr).if_index == 0 { ++ None ++ } else { ++ let ret = &*(self.ptr as *const Interface); ++ self.ptr = self.ptr.add(1); ++ Some(ret) ++ } ++ } ++ } ++ } ++ ++ /// Retrieve a list of the network interfaces available on the local system. ++ /// ++ /// ``` ++ /// let interfaces = nix::net::if_::if_nameindex().unwrap(); ++ /// for iface in &interfaces { ++ /// println!("Interface #{} is called {}", iface.index(), iface.name().to_string_lossy()); ++ /// } ++ /// ``` ++ pub fn if_nameindex() -> Result { ++ unsafe { ++ let ifs = libc::if_nameindex(); ++ let ptr = NonNull::new(ifs).ok_or_else(Error::last)?; ++ Ok(Interfaces { ptr }) ++ } ++ } ++} ++#[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "fuchsia", ++ target_os = "ios", ++ target_os = "linux", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd", ++))] ++pub use if_nameindex::*; +diff --git a/vendor/nix/src/poll.rs b/vendor/nix/src/poll.rs +index 15bafe2..6f227fe 100644 +--- a/vendor/nix/src/poll.rs ++++ b/vendor/nix/src/poll.rs +@@ -1,13 +1,8 @@ + //! Wait for events to trigger on specific file descriptors +-#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))] +-use sys::time::TimeSpec; +-#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))] +-use sys::signal::SigSet; +-use std::os::unix::io::RawFd; ++use std::os::unix::io::{AsRawFd, RawFd}; + +-use libc; +-use Result; +-use errno::Errno; ++use crate::errno::Errno; ++use crate::Result; + + /// This is a wrapper around `libc::pollfd`. + /// +@@ -15,9 +10,9 @@ use errno::Errno; + /// [`ppoll`](fn.ppoll.html) functions to specify the events of interest + /// for a specific file descriptor. + /// +-/// After a call to `poll` or `ppoll`, the events that occured can be ++/// After a call to `poll` or `ppoll`, the events that occurred can be + /// retrieved by calling [`revents()`](#method.revents) on the `PollFd`. +-#[repr(C)] ++#[repr(transparent)] + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct PollFd { + pollfd: libc::pollfd, +@@ -26,7 +21,7 @@ pub struct PollFd { + impl PollFd { + /// Creates a new `PollFd` specifying the events of interest + /// for a given file descriptor. +- pub fn new(fd: RawFd, events: PollFlags) -> PollFd { ++ pub const fn new(fd: RawFd, events: PollFlags) -> PollFd { + PollFd { + pollfd: libc::pollfd { + fd, +@@ -36,10 +31,47 @@ impl PollFd { + } + } + +- /// Returns the events that occured in the last call to `poll` or `ppoll`. ++ /// Returns the events that occurred in the last call to `poll` or `ppoll`. Will only return ++ /// `None` if the kernel provides status flags that Nix does not know about. + pub fn revents(self) -> Option { + PollFlags::from_bits(self.pollfd.revents) + } ++ ++ /// Returns if any of the events of interest occured in the last call to `poll` or `ppoll`. Will ++ /// only return `None` if the kernel provides status flags that Nix does not know about. ++ /// ++ /// Equivalent to `x.revents()? != PollFlags::empty()`. ++ /// ++ /// This is marginally more efficient than [`PollFd::all`]. ++ pub fn any(self) -> Option { ++ Some(self.revents()? != PollFlags::empty()) ++ } ++ ++ /// Returns if all the events of interest occured in the last call to `poll` or `ppoll`. Will ++ /// only return `None` if the kernel provides status flags that Nix does not know about. ++ /// ++ /// Equivalent to `x.revents()? & x.events() == x.events()`. ++ /// ++ /// This is marginally less efficient than [`PollFd::any`]. ++ pub fn all(self) -> Option { ++ Some(self.revents()? & self.events() == self.events()) ++ } ++ ++ /// The events of interest for this `PollFd`. ++ pub fn events(self) -> PollFlags { ++ PollFlags::from_bits(self.pollfd.events).unwrap() ++ } ++ ++ /// Modify the events of interest for this `PollFd`. ++ pub fn set_events(&mut self, events: PollFlags) { ++ self.pollfd.events = events.bits(); ++ } ++} ++ ++impl AsRawFd for PollFd { ++ fn as_raw_fd(&self) -> RawFd { ++ self.pollfd.fd ++ } + } + + libc_bitflags! { +@@ -52,24 +84,32 @@ libc_bitflags! { + /// Possibilities include: + /// + /// * There is out-of-band data on a TCP socket (see +- /// [tcp(7)](http://man7.org/linux/man-pages/man7/tcp.7.html)). ++ /// [tcp(7)](https://man7.org/linux/man-pages/man7/tcp.7.html)). + /// * A pseudoterminal master in packet mode has seen a state + /// change on the slave (see +- /// [ioctl_tty(2)](http://man7.org/linux/man-pages/man2/ioctl_tty.2.html)). ++ /// [ioctl_tty(2)](https://man7.org/linux/man-pages/man2/ioctl_tty.2.html)). + /// * A cgroup.events file has been modified (see +- /// [cgroups(7)](http://man7.org/linux/man-pages/man7/cgroups.7.html)). ++ /// [cgroups(7)](https://man7.org/linux/man-pages/man7/cgroups.7.html)). + POLLPRI; + /// Writing is now possible, though a write larger that the + /// available space in a socket or pipe will still block (unless + /// `O_NONBLOCK` is set). + POLLOUT; + /// Equivalent to [`POLLIN`](constant.POLLIN.html) ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + POLLRDNORM; ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// Equivalent to [`POLLOUT`](constant.POLLOUT.html) + POLLWRNORM; + /// Priority band data can be read (generally unused on Linux). ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + POLLRDBAND; + /// Priority data may be written. ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + POLLWRBAND; + /// Error condition (only returned in + /// [`PollFd::revents`](struct.PollFd.html#method.revents); +@@ -93,7 +133,7 @@ libc_bitflags! { + } + + /// `poll` waits for one of a set of file descriptors to become ready to perform I/O. +-/// ([`poll(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html)) ++/// ([`poll(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html)) + /// + /// `fds` contains all [`PollFd`](struct.PollFd.html) to poll. + /// The function will return as soon as any event occur for any of these `PollFd`s. +@@ -114,30 +154,44 @@ libc_bitflags! { + /// ready. + pub fn poll(fds: &mut [PollFd], timeout: libc::c_int) -> Result { + let res = unsafe { +- libc::poll(fds.as_mut_ptr() as *mut libc::pollfd, +- fds.len() as libc::nfds_t, +- timeout) ++ libc::poll( ++ fds.as_mut_ptr() as *mut libc::pollfd, ++ fds.len() as libc::nfds_t, ++ timeout, ++ ) + }; + + Errno::result(res) + } + ++feature! { ++#![feature = "signal"] + /// `ppoll()` allows an application to safely wait until either a file + /// descriptor becomes ready or until a signal is caught. +-/// ([`poll(2)`](http://man7.org/linux/man-pages/man2/poll.2.html)) ++/// ([`poll(2)`](https://man7.org/linux/man-pages/man2/poll.2.html)) + /// + /// `ppoll` behaves like `poll`, but let you specify what signals may interrupt it +-/// with the `sigmask` argument. ++/// with the `sigmask` argument. If you want `ppoll` to block indefinitely, ++/// specify `None` as `timeout` (it is like `timeout = -1` for `poll`). ++/// If `sigmask` is `None`, then no signal mask manipulation is performed, ++/// so in that case `ppoll` differs from `poll` only in the precision of the ++/// timeout argument. + /// + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))] +-pub fn ppoll(fds: &mut [PollFd], timeout: TimeSpec, sigmask: SigSet) -> Result { +- +- ++pub fn ppoll( ++ fds: &mut [PollFd], ++ timeout: Option, ++ sigmask: Option ++ ) -> Result ++{ ++ let timeout = timeout.as_ref().map_or(core::ptr::null(), |r| r.as_ref()); ++ let sigmask = sigmask.as_ref().map_or(core::ptr::null(), |r| r.as_ref()); + let res = unsafe { + libc::ppoll(fds.as_mut_ptr() as *mut libc::pollfd, + fds.len() as libc::nfds_t, +- timeout.as_ref(), +- sigmask.as_ref()) ++ timeout, ++ sigmask) + }; + Errno::result(res) + } ++} +diff --git a/vendor/nix/src/pty.rs b/vendor/nix/src/pty.rs +index b281d75..28ae5e9 100644 +--- a/vendor/nix/src/pty.rs ++++ b/vendor/nix/src/pty.rs +@@ -1,18 +1,18 @@ + //! Create master and slave virtual pseudo-terminals (PTYs) + +-use libc; +- + pub use libc::pid_t as SessionId; + pub use libc::winsize as Winsize; + + use std::ffi::CStr; ++use std::io; + use std::mem; + use std::os::unix::prelude::*; + +-use sys::termios::Termios; +-use unistd::ForkResult; +-use {Result, Error, fcntl}; +-use errno::Errno; ++use crate::errno::Errno; ++use crate::sys::termios::Termios; ++#[cfg(feature = "process")] ++use crate::unistd::{ForkResult, Pid}; ++use crate::{fcntl, unistd, Result}; + + /// Representation of a master/slave pty pair + /// +@@ -26,6 +26,8 @@ pub struct OpenptyResult { + pub slave: RawFd, + } + ++feature! { ++#![feature = "process"] + /// Representation of a master with a forked pty + /// + /// This is returned by `forkpty`. Note that this type does *not* implement `Drop`, so the user +@@ -37,14 +39,14 @@ pub struct ForkptyResult { + /// Metadata about forked process + pub fork_result: ForkResult, + } +- ++} + + /// Representation of the Master device in a master/slave pty pair + /// + /// While this datatype is a thin wrapper around `RawFd`, it enforces that the available PTY + /// functions are given the correct file descriptor. Additionally this type implements `Drop`, + /// so that when it's consumed or goes out of scope, it's automatically cleaned-up. +-#[derive(Clone, Debug, Eq, Hash, PartialEq)] ++#[derive(Debug, Eq, Hash, PartialEq)] + pub struct PtyMaster(RawFd); + + impl AsRawFd for PtyMaster { +@@ -70,31 +72,61 @@ impl Drop for PtyMaster { + // invalid file descriptor. That frequently indicates a double-close + // condition, which can cause confusing errors for future I/O + // operations. +- let e = ::unistd::close(self.0); +- if e == Err(Error::Sys(Errno::EBADF)) { ++ let e = unistd::close(self.0); ++ if e == Err(Errno::EBADF) { + panic!("Closing an invalid file descriptor!"); + }; + } + } + ++impl io::Read for PtyMaster { ++ fn read(&mut self, buf: &mut [u8]) -> io::Result { ++ unistd::read(self.0, buf).map_err(io::Error::from) ++ } ++} ++ ++impl io::Write for PtyMaster { ++ fn write(&mut self, buf: &[u8]) -> io::Result { ++ unistd::write(self.0, buf).map_err(io::Error::from) ++ } ++ fn flush(&mut self) -> io::Result<()> { ++ Ok(()) ++ } ++} ++ ++impl io::Read for &PtyMaster { ++ fn read(&mut self, buf: &mut [u8]) -> io::Result { ++ unistd::read(self.0, buf).map_err(io::Error::from) ++ } ++} ++ ++impl io::Write for &PtyMaster { ++ fn write(&mut self, buf: &[u8]) -> io::Result { ++ unistd::write(self.0, buf).map_err(io::Error::from) ++ } ++ fn flush(&mut self) -> io::Result<()> { ++ Ok(()) ++ } ++} ++ + /// Grant access to a slave pseudoterminal (see +-/// [`grantpt(3)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/grantpt.html)) ++/// [`grantpt(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/grantpt.html)) + /// + /// `grantpt()` changes the mode and owner of the slave pseudoterminal device corresponding to the + /// master pseudoterminal referred to by `fd`. This is a necessary step towards opening the slave. + #[inline] + pub fn grantpt(fd: &PtyMaster) -> Result<()> { + if unsafe { libc::grantpt(fd.as_raw_fd()) } < 0 { +- return Err(Error::last()); ++ return Err(Errno::last()); + } + + Ok(()) + } + + /// Open a pseudoterminal device (see +-/// [`posix_openpt(3)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_openpt.html)) ++/// [`posix_openpt(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_openpt.html)) + /// +-/// `posix_openpt()` returns a file descriptor to an existing unused pseuterminal master device. ++/// `posix_openpt()` returns a file descriptor to an existing unused pseudoterminal master device. + /// + /// # Examples + /// +@@ -126,19 +158,17 @@ pub fn grantpt(fd: &PtyMaster) -> Result<()> { + /// ``` + #[inline] + pub fn posix_openpt(flags: fcntl::OFlag) -> Result { +- let fd = unsafe { +- libc::posix_openpt(flags.bits()) +- }; ++ let fd = unsafe { libc::posix_openpt(flags.bits()) }; + + if fd < 0 { +- return Err(Error::last()); ++ return Err(Errno::last()); + } + + Ok(PtyMaster(fd)) + } + + /// Get the name of the slave pseudoterminal (see +-/// [`ptsname(3)`](http://man7.org/linux/man-pages/man3/ptsname.3.html)) ++/// [`ptsname(3)`](https://man7.org/linux/man-pages/man3/ptsname.3.html)) + /// + /// `ptsname()` returns the name of the slave pseudoterminal device corresponding to the master + /// referred to by `fd`. +@@ -157,7 +187,7 @@ pub fn posix_openpt(flags: fcntl::OFlag) -> Result { + pub unsafe fn ptsname(fd: &PtyMaster) -> Result { + let name_ptr = libc::ptsname(fd.as_raw_fd()); + if name_ptr.is_null() { +- return Err(Error::last()); ++ return Err(Errno::last()); + } + + let name = CStr::from_ptr(name_ptr); +@@ -165,7 +195,7 @@ pub unsafe fn ptsname(fd: &PtyMaster) -> Result { + } + + /// Get the name of the slave pseudoterminal (see +-/// [`ptsname(3)`](http://man7.org/linux/man-pages/man3/ptsname.3.html)) ++/// [`ptsname(3)`](https://man7.org/linux/man-pages/man3/ptsname.3.html)) + /// + /// `ptsname_r()` returns the name of the slave pseudoterminal device corresponding to the master + /// referred to by `fd`. This is the threadsafe version of `ptsname()`, but it is not part of the +@@ -174,48 +204,55 @@ pub unsafe fn ptsname(fd: &PtyMaster) -> Result { + /// This value is useful for opening the slave ptty once the master has already been opened with + /// `posix_openpt()`. + #[cfg(any(target_os = "android", target_os = "linux"))] ++#[cfg_attr(docsrs, doc(cfg(all())))] + #[inline] + pub fn ptsname_r(fd: &PtyMaster) -> Result { +- let mut name_buf = vec![0u8; 64]; +- let name_buf_ptr = name_buf.as_mut_ptr() as *mut libc::c_char; +- if unsafe { libc::ptsname_r(fd.as_raw_fd(), name_buf_ptr, name_buf.capacity()) } != 0 { +- return Err(Error::last()); +- } +- +- // Find the first null-character terminating this string. This is guaranteed to succeed if the +- // return value of `libc::ptsname_r` is 0. +- let null_index = name_buf.iter().position(|c| *c == b'\0').unwrap(); +- name_buf.truncate(null_index); ++ let mut name_buf = Vec::::with_capacity(64); ++ let name_buf_ptr = name_buf.as_mut_ptr(); ++ let cname = unsafe { ++ let cap = name_buf.capacity(); ++ if libc::ptsname_r(fd.as_raw_fd(), name_buf_ptr, cap) != 0 { ++ return Err(crate::Error::last()); ++ } ++ CStr::from_ptr(name_buf.as_ptr()) ++ }; + +- let name = String::from_utf8(name_buf)?; ++ let name = cname.to_string_lossy().into_owned(); + Ok(name) + } + + /// Unlock a pseudoterminal master/slave pseudoterminal pair (see +-/// [`unlockpt(3)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlockpt.html)) ++/// [`unlockpt(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlockpt.html)) + /// + /// `unlockpt()` unlocks the slave pseudoterminal device corresponding to the master pseudoterminal + /// referred to by `fd`. This must be called before trying to open the slave side of a +-/// pseuoterminal. ++/// pseudoterminal. + #[inline] + pub fn unlockpt(fd: &PtyMaster) -> Result<()> { + if unsafe { libc::unlockpt(fd.as_raw_fd()) } < 0 { +- return Err(Error::last()); ++ return Err(Errno::last()); + } + + Ok(()) + } + +- + /// Create a new pseudoterminal, returning the slave and master file descriptors + /// in `OpenptyResult` +-/// (see [`openpty`](http://man7.org/linux/man-pages/man3/openpty.3.html)). ++/// (see [`openpty`](https://man7.org/linux/man-pages/man3/openpty.3.html)). + /// + /// If `winsize` is not `None`, the window size of the slave will be set to + /// the values in `winsize`. If `termios` is not `None`, the pseudoterminal's + /// terminal settings of the slave will be set to the values in `termios`. + #[inline] +-pub fn openpty<'a, 'b, T: Into>, U: Into>>(winsize: T, termios: U) -> Result { ++pub fn openpty< ++ 'a, ++ 'b, ++ T: Into>, ++ U: Into>, ++>( ++ winsize: T, ++ termios: U, ++) -> Result { + use std::ptr; + + let mut slave = mem::MaybeUninit::::uninit(); +@@ -234,17 +271,15 @@ pub fn openpty<'a, 'b, T: Into>, U: Into + ) + } + } +- (None, Some(winsize)) => { +- unsafe { +- libc::openpty( +- master.as_mut_ptr(), +- slave.as_mut_ptr(), +- ptr::null_mut(), +- ptr::null_mut(), +- winsize as *const Winsize as *mut _, +- ) +- } +- } ++ (None, Some(winsize)) => unsafe { ++ libc::openpty( ++ master.as_mut_ptr(), ++ slave.as_mut_ptr(), ++ ptr::null_mut(), ++ ptr::null_mut(), ++ winsize as *const Winsize as *mut _, ++ ) ++ }, + (Some(termios), None) => { + let inner_termios = termios.get_libc_termios(); + unsafe { +@@ -257,17 +292,15 @@ pub fn openpty<'a, 'b, T: Into>, U: Into + ) + } + } +- (None, None) => { +- unsafe { +- libc::openpty( +- master.as_mut_ptr(), +- slave.as_mut_ptr(), +- ptr::null_mut(), +- ptr::null_mut(), +- ptr::null_mut(), +- ) +- } +- } ++ (None, None) => unsafe { ++ libc::openpty( ++ master.as_mut_ptr(), ++ slave.as_mut_ptr(), ++ ptr::null_mut(), ++ ptr::null_mut(), ++ ptr::null_mut(), ++ ) ++ }, + } + }; + +@@ -281,20 +314,32 @@ pub fn openpty<'a, 'b, T: Into>, U: Into + } + } + ++feature! { ++#![feature = "process"] + /// Create a new pseudoterminal, returning the master file descriptor and forked pid. + /// in `ForkptyResult` +-/// (see [`forkpty`](http://man7.org/linux/man-pages/man3/forkpty.3.html)). ++/// (see [`forkpty`](https://man7.org/linux/man-pages/man3/forkpty.3.html)). + /// + /// If `winsize` is not `None`, the window size of the slave will be set to + /// the values in `winsize`. If `termios` is not `None`, the pseudoterminal's + /// terminal settings of the slave will be set to the values in `termios`. +-pub fn forkpty<'a, 'b, T: Into>, U: Into>>( ++/// ++/// # Safety ++/// ++/// In a multithreaded program, only [async-signal-safe] functions like `pause` ++/// and `_exit` may be called by the child (the parent isn't restricted). Note ++/// that memory allocation may **not** be async-signal-safe and thus must be ++/// prevented. ++/// ++/// Those functions are only a small subset of your operating system's API, so ++/// special care must be taken to only invoke code you can control and audit. ++/// ++/// [async-signal-safe]: https://man7.org/linux/man-pages/man7/signal-safety.7.html ++pub unsafe fn forkpty<'a, 'b, T: Into>, U: Into>>( + winsize: T, + termios: U, + ) -> Result { + use std::ptr; +- use unistd::Pid; +- use unistd::ForkResult::*; + + let mut master = mem::MaybeUninit::::uninit(); + +@@ -311,20 +356,16 @@ pub fn forkpty<'a, 'b, T: Into>, U: Into + .map(|ws| ws as *const Winsize as *mut _) + .unwrap_or(ptr::null_mut()); + +- let res = unsafe { +- libc::forkpty(master.as_mut_ptr(), ptr::null_mut(), term, win) +- }; ++ let res = libc::forkpty(master.as_mut_ptr(), ptr::null_mut(), term, win); + + let fork_result = Errno::result(res).map(|res| match res { +- 0 => Child, +- res => Parent { child: Pid::from_raw(res) }, ++ 0 => ForkResult::Child, ++ res => ForkResult::Parent { child: Pid::from_raw(res) }, + })?; + +- unsafe { +- Ok(ForkptyResult { +- master: master.assume_init(), +- fork_result, +- }) +- } ++ Ok(ForkptyResult { ++ master: master.assume_init(), ++ fork_result, ++ }) ++} + } +- +diff --git a/vendor/nix/src/sched.rs b/vendor/nix/src/sched.rs +index 7675dbc..d5b1233 100644 +--- a/vendor/nix/src/sched.rs ++++ b/vendor/nix/src/sched.rs +@@ -1,60 +1,180 @@ +-use libc; +-use {Errno, Result}; ++//! Execution scheduling ++//! ++//! See Also ++//! [sched.h](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sched.h.html) ++use crate::{Errno, Result}; + + #[cfg(any(target_os = "android", target_os = "linux"))] + pub use self::sched_linux_like::*; + + #[cfg(any(target_os = "android", target_os = "linux"))] ++#[cfg_attr(docsrs, doc(cfg(all())))] + mod sched_linux_like { +- use errno::Errno; ++ use crate::errno::Errno; ++ use crate::unistd::Pid; ++ use crate::Result; + use libc::{self, c_int, c_void}; + use std::mem; + use std::option::Option; + use std::os::unix::io::RawFd; +- use unistd::Pid; +- use {Error, Result}; + + // For some functions taking with a parameter of type CloneFlags, + // only a subset of these flags have an effect. + libc_bitflags! { ++ /// Options for use with [`clone`] + pub struct CloneFlags: c_int { ++ /// The calling process and the child process run in the same ++ /// memory space. + CLONE_VM; ++ /// The caller and the child process share the same filesystem ++ /// information. + CLONE_FS; ++ /// The calling process and the child process share the same file ++ /// descriptor table. + CLONE_FILES; ++ /// The calling process and the child process share the same table ++ /// of signal handlers. + CLONE_SIGHAND; ++ /// If the calling process is being traced, then trace the child ++ /// also. + CLONE_PTRACE; ++ /// The execution of the calling process is suspended until the ++ /// child releases its virtual memory resources via a call to ++ /// execve(2) or _exit(2) (as with vfork(2)). + CLONE_VFORK; ++ /// The parent of the new child (as returned by getppid(2)) ++ /// will be the same as that of the calling process. + CLONE_PARENT; ++ /// The child is placed in the same thread group as the calling ++ /// process. + CLONE_THREAD; ++ /// The cloned child is started in a new mount namespace. + CLONE_NEWNS; ++ /// The child and the calling process share a single list of System ++ /// V semaphore adjustment values + CLONE_SYSVSEM; +- CLONE_SETTLS; +- CLONE_PARENT_SETTID; +- CLONE_CHILD_CLEARTID; ++ // Not supported by Nix due to lack of varargs support in Rust FFI ++ // CLONE_SETTLS; ++ // Not supported by Nix due to lack of varargs support in Rust FFI ++ // CLONE_PARENT_SETTID; ++ // Not supported by Nix due to lack of varargs support in Rust FFI ++ // CLONE_CHILD_CLEARTID; ++ /// Unused since Linux 2.6.2 ++ #[deprecated(since = "0.23.0", note = "Deprecated by Linux 2.6.2")] + CLONE_DETACHED; ++ /// A tracing process cannot force `CLONE_PTRACE` on this child ++ /// process. + CLONE_UNTRACED; +- CLONE_CHILD_SETTID; ++ // Not supported by Nix due to lack of varargs support in Rust FFI ++ // CLONE_CHILD_SETTID; ++ /// Create the process in a new cgroup namespace. + CLONE_NEWCGROUP; ++ /// Create the process in a new UTS namespace. + CLONE_NEWUTS; ++ /// Create the process in a new IPC namespace. + CLONE_NEWIPC; ++ /// Create the process in a new user namespace. + CLONE_NEWUSER; ++ /// Create the process in a new PID namespace. + CLONE_NEWPID; ++ /// Create the process in a new network namespace. + CLONE_NEWNET; ++ /// The new process shares an I/O context with the calling process. + CLONE_IO; + } + } + ++ /// Type for the function executed by [`clone`]. + pub type CloneCb<'a> = Box isize + 'a>; + ++ /// `clone` create a child process ++ /// ([`clone(2)`](https://man7.org/linux/man-pages/man2/clone.2.html)) ++ /// ++ /// `stack` is a reference to an array which will hold the stack of the new ++ /// process. Unlike when calling `clone(2)` from C, the provided stack ++ /// address need not be the highest address of the region. Nix will take ++ /// care of that requirement. The user only needs to provide a reference to ++ /// a normally allocated buffer. ++ pub fn clone( ++ mut cb: CloneCb, ++ stack: &mut [u8], ++ flags: CloneFlags, ++ signal: Option, ++ ) -> Result { ++ extern "C" fn callback(data: *mut CloneCb) -> c_int { ++ let cb: &mut CloneCb = unsafe { &mut *data }; ++ (*cb)() as c_int ++ } ++ ++ let res = unsafe { ++ let combined = flags.bits() | signal.unwrap_or(0); ++ let ptr = stack.as_mut_ptr().add(stack.len()); ++ let ptr_aligned = ptr.sub(ptr as usize % 16); ++ libc::clone( ++ mem::transmute( ++ callback ++ as extern "C" fn(*mut Box isize>) -> i32, ++ ), ++ ptr_aligned as *mut c_void, ++ combined, ++ &mut cb as *mut _ as *mut c_void, ++ ) ++ }; ++ ++ Errno::result(res).map(Pid::from_raw) ++ } ++ ++ /// disassociate parts of the process execution context ++ /// ++ /// See also [unshare(2)](https://man7.org/linux/man-pages/man2/unshare.2.html) ++ pub fn unshare(flags: CloneFlags) -> Result<()> { ++ let res = unsafe { libc::unshare(flags.bits()) }; ++ ++ Errno::result(res).map(drop) ++ } ++ ++ /// reassociate thread with a namespace ++ /// ++ /// See also [setns(2)](https://man7.org/linux/man-pages/man2/setns.2.html) ++ pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> { ++ let res = unsafe { libc::setns(fd, nstype.bits()) }; ++ ++ Errno::result(res).map(drop) ++ } ++} ++ ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "linux" ++))] ++pub use self::sched_affinity::*; ++ ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "linux" ++))] ++mod sched_affinity { ++ use crate::errno::Errno; ++ use crate::unistd::Pid; ++ use crate::Result; ++ use std::mem; ++ + /// CpuSet represent a bit-mask of CPUs. + /// CpuSets are used by sched_setaffinity and + /// sched_getaffinity for example. + /// + /// This is a wrapper around `libc::cpu_set_t`. +- #[repr(C)] ++ #[repr(transparent)] + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct CpuSet { ++ #[cfg(not(target_os = "freebsd"))] + cpu_set: libc::cpu_set_t, ++ #[cfg(target_os = "freebsd")] ++ cpu_set: libc::cpuset_t, + } + + impl CpuSet { +@@ -69,7 +189,7 @@ mod sched_linux_like { + /// `field` is the CPU id to test + pub fn is_set(&self, field: usize) -> Result { + if field >= CpuSet::count() { +- Err(Error::Sys(Errno::EINVAL)) ++ Err(Errno::EINVAL) + } else { + Ok(unsafe { libc::CPU_ISSET(field, &self.cpu_set) }) + } +@@ -79,9 +199,12 @@ mod sched_linux_like { + /// `field` is the CPU id to add + pub fn set(&mut self, field: usize) -> Result<()> { + if field >= CpuSet::count() { +- Err(Error::Sys(Errno::EINVAL)) ++ Err(Errno::EINVAL) + } else { +- Ok(unsafe { libc::CPU_SET(field, &mut self.cpu_set) }) ++ unsafe { ++ libc::CPU_SET(field, &mut self.cpu_set); ++ } ++ Ok(()) + } + } + +@@ -89,20 +212,34 @@ mod sched_linux_like { + /// `field` is the CPU id to remove + pub fn unset(&mut self, field: usize) -> Result<()> { + if field >= CpuSet::count() { +- Err(Error::Sys(Errno::EINVAL)) ++ Err(Errno::EINVAL) + } else { +- Ok(unsafe { libc::CPU_CLR(field, &mut self.cpu_set) }) ++ unsafe { ++ libc::CPU_CLR(field, &mut self.cpu_set); ++ } ++ Ok(()) + } + } + + /// Return the maximum number of CPU in CpuSet +- pub fn count() -> usize { +- 8 * mem::size_of::() ++ pub const fn count() -> usize { ++ #[cfg(not(target_os = "freebsd"))] ++ let bytes = mem::size_of::(); ++ #[cfg(target_os = "freebsd")] ++ let bytes = mem::size_of::(); ++ ++ 8 * bytes ++ } ++ } ++ ++ impl Default for CpuSet { ++ fn default() -> Self { ++ Self::new() + } + } + + /// `sched_setaffinity` set a thread's CPU affinity mask +- /// ([`sched_setaffinity(2)`](http://man7.org/linux/man-pages/man2/sched_setaffinity.2.html)) ++ /// ([`sched_setaffinity(2)`](https://man7.org/linux/man-pages/man2/sched_setaffinity.2.html)) + /// + /// `pid` is the thread ID to update. + /// If pid is zero, then the calling thread is updated. +@@ -119,8 +256,8 @@ mod sched_linux_like { + /// use nix::unistd::Pid; + /// + /// let mut cpu_set = CpuSet::new(); +- /// cpu_set.set(0); +- /// sched_setaffinity(Pid::from_raw(0), &cpu_set); ++ /// cpu_set.set(0).unwrap(); ++ /// sched_setaffinity(Pid::from_raw(0), &cpu_set).unwrap(); + /// ``` + pub fn sched_setaffinity(pid: Pid, cpuset: &CpuSet) -> Result<()> { + let res = unsafe { +@@ -135,7 +272,7 @@ mod sched_linux_like { + } + + /// `sched_getaffinity` get a thread's CPU affinity mask +- /// ([`sched_getaffinity(2)`](http://man7.org/linux/man-pages/man2/sched_getaffinity.2.html)) ++ /// ([`sched_getaffinity(2)`](https://man7.org/linux/man-pages/man2/sched_getaffinity.2.html)) + /// + /// `pid` is the thread ID to check. + /// If pid is zero, then the calling thread is checked. +@@ -169,50 +306,17 @@ mod sched_linux_like { + Errno::result(res).and(Ok(cpuset)) + } + +- pub fn clone( +- mut cb: CloneCb, +- stack: &mut [u8], +- flags: CloneFlags, +- signal: Option, +- ) -> Result { +- extern "C" fn callback(data: *mut CloneCb) -> c_int { +- let cb: &mut CloneCb = unsafe { &mut *data }; +- (*cb)() as c_int +- } ++ /// Determines the CPU on which the calling thread is running. ++ pub fn sched_getcpu() -> Result { ++ let res = unsafe { libc::sched_getcpu() }; + +- let res = unsafe { +- let combined = flags.bits() | signal.unwrap_or(0); +- let ptr = stack.as_mut_ptr().offset(stack.len() as isize); +- let ptr_aligned = ptr.offset((ptr as usize % 16) as isize * -1); +- libc::clone( +- mem::transmute( +- callback as extern "C" fn(*mut Box isize>) -> i32, +- ), +- ptr_aligned as *mut c_void, +- combined, +- &mut cb as *mut _ as *mut c_void, +- ) +- }; +- +- Errno::result(res).map(Pid::from_raw) +- } +- +- pub fn unshare(flags: CloneFlags) -> Result<()> { +- let res = unsafe { libc::unshare(flags.bits()) }; +- +- Errno::result(res).map(drop) +- } +- +- pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> { +- let res = unsafe { libc::setns(fd, nstype.bits()) }; +- +- Errno::result(res).map(drop) ++ Errno::result(res).map(|int| int as usize) + } + } + + /// Explicitly yield the processor to other threads. + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_yield.html) ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_yield.html) + pub fn sched_yield() -> Result<()> { + let res = unsafe { libc::sched_yield() }; + +diff --git a/vendor/nix/src/sys/aio.rs b/vendor/nix/src/sys/aio.rs +index c912fc8..e2ce19b 100644 +--- a/vendor/nix/src/sys/aio.rs ++++ b/vendor/nix/src/sys/aio.rs +@@ -2,9 +2,12 @@ + //! POSIX Asynchronous I/O + //! + //! The POSIX AIO interface is used for asynchronous I/O on files and disk-like +-//! devices. It supports [`read`](struct.AioCb.html#method.read), +-//! [`write`](struct.AioCb.html#method.write), and +-//! [`fsync`](struct.AioCb.html#method.fsync) operations. Completion ++//! devices. It supports [`read`](struct.AioRead.html#method.new), ++//! [`write`](struct.AioWrite.html#method.new), ++//! [`fsync`](struct.AioFsync.html#method.new), ++//! [`readv`](struct.AioReadv.html#method.new), and ++//! [`writev`](struct.AioWritev.html#method.new), operations, subject to ++//! platform support. Completion + //! notifications can optionally be delivered via + //! [signals](../signal/enum.SigevNotify.html#variant.SigevSignal), via the + //! [`aio_suspend`](fn.aio_suspend.html) function, or via polling. Some +@@ -17,29 +20,35 @@ + //! that they will be executed atomically. + //! + //! Outstanding operations may be cancelled with +-//! [`cancel`](struct.AioCb.html#method.cancel) or ++//! [`cancel`](trait.Aio.html#method.cancel) or + //! [`aio_cancel_all`](fn.aio_cancel_all.html), though the operating system may + //! not support this for all filesystems and devices. ++#[cfg(target_os = "freebsd")] ++use std::io::{IoSlice, IoSliceMut}; ++use std::{ ++ convert::TryFrom, ++ fmt::{self, Debug}, ++ marker::{PhantomData, PhantomPinned}, ++ mem, ++ os::unix::io::RawFd, ++ pin::Pin, ++ ptr, thread, ++}; + +-use {Error, Result}; +-use errno::Errno; +-use std::os::unix::io::RawFd; +-use libc::{c_void, off_t, size_t}; +-use libc; +-use std::borrow::{Borrow, BorrowMut}; +-use std::fmt; +-use std::fmt::Debug; +-use std::marker::PhantomData; +-use std::mem; +-use std::ptr::{null, null_mut}; +-use sys::signal::*; +-use std::thread; +-use sys::time::TimeSpec; ++use libc::{c_void, off_t}; ++use pin_utils::unsafe_pinned; ++ ++use crate::{ ++ errno::Errno, ++ sys::{signal::*, time::TimeSpec}, ++ Result, ++}; + + libc_enum! { + /// Mode for `AioCb::fsync`. Controls whether only data or both data and + /// metadata are synced. + #[repr(i32)] ++ #[non_exhaustive] + pub enum AioFsyncMode { + /// do it like `fsync` + O_SYNC, +@@ -49,20 +58,10 @@ libc_enum! { + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + O_DSYNC + } +-} +- +-libc_enum! { +- /// When used with [`lio_listio`](fn.lio_listio.html), determines whether a +- /// given `aiocb` should be used for a read operation, a write operation, or +- /// ignored. Has no effect for any other aio functions. +- #[repr(i32)] +- pub enum LioOpcode { +- LIO_NOP, +- LIO_WRITE, +- LIO_READ, +- } ++ impl TryFrom + } + + libc_enum! { +@@ -91,625 +90,140 @@ pub enum AioCancelStat { + AioAllDone = libc::AIO_ALLDONE, + } + +-/// Owns (uniquely or shared) a memory buffer to keep it from `Drop`ing while +-/// the kernel has a pointer to it. +-pub enum Buffer<'a> { +- /// No buffer to own. +- /// +- /// Used for operations like `aio_fsync` that have no data, or for unsafe +- /// operations that work with raw pointers. +- None, +- /// Keeps a reference to a slice +- Phantom(PhantomData<&'a mut [u8]>), +- /// Generic thing that keeps a buffer from dropping +- BoxedSlice(Box>), +- /// Generic thing that keeps a mutable buffer from dropping +- BoxedMutSlice(Box>), +-} ++/// Newtype that adds Send and Sync to libc::aiocb, which contains raw pointers ++#[repr(transparent)] ++struct LibcAiocb(libc::aiocb); + +-impl<'a> Debug for Buffer<'a> { +- // Note: someday it may be possible to Derive Debug for a trait object, but +- // not today. +- // https://github.com/rust-lang/rust/issues/1563 +- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { +- match *self { +- Buffer::None => write!(fmt, "None"), +- Buffer::Phantom(p) => p.fmt(fmt), +- Buffer::BoxedSlice(ref bs) => { +- let borrowed : &dyn Borrow<[u8]> = bs.borrow(); +- write!(fmt, "BoxedSlice({:?})", +- borrowed as *const dyn Borrow<[u8]>) +- }, +- Buffer::BoxedMutSlice(ref bms) => { +- let borrowed : &dyn BorrowMut<[u8]> = bms.borrow(); +- write!(fmt, "BoxedMutSlice({:?})", +- borrowed as *const dyn BorrowMut<[u8]>) +- } +- } +- } +-} ++unsafe impl Send for LibcAiocb {} ++unsafe impl Sync for LibcAiocb {} + +-/// AIO Control Block. +-/// +-/// The basic structure used by all aio functions. Each `AioCb` represents one +-/// I/O request. +-pub struct AioCb<'a> { +- aiocb: libc::aiocb, +- /// Tracks whether the buffer pointed to by `libc::aiocb.aio_buf` is mutable +- mutable: bool, ++/// Base class for all AIO operations. Should only be used directly when ++/// checking for completion. ++// We could create some kind of AsPinnedMut trait, and implement it for all aio ++// ops, allowing the crate's users to get pinned references to `AioCb`. That ++// could save some code for things like polling methods. But IMHO it would ++// provide polymorphism at the wrong level. Instead, the best place for ++// polymorphism is at the level of `Futures`. ++#[repr(C)] ++struct AioCb { ++ aiocb: LibcAiocb, + /// Could this `AioCb` potentially have any in-kernel state? ++ // It would be really nice to perform the in-progress check entirely at ++ // compile time. But I can't figure out how, because: ++ // * Future::poll takes a `Pin<&mut self>` rather than `self`, and ++ // * Rust's lack of an equivalent of C++'s Guaranteed Copy Elision means ++ // that there's no way to write an AioCb constructor that neither boxes ++ // the object itself, nor moves it during return. + in_progress: bool, +- /// Optionally keeps a reference to the data. +- /// +- /// Used to keep buffers from `Drop`'ing, and may be returned once the +- /// `AioCb` is completed by [`buffer`](#method.buffer). +- buffer: Buffer<'a> + } + +-impl<'a> AioCb<'a> { +- /// Remove the inner `Buffer` and return it +- /// +- /// It is an error to call this method while the `AioCb` is still in +- /// progress. +- pub fn buffer(&mut self) -> Buffer<'a> { +- assert!(!self.in_progress); +- let mut x = Buffer::None; +- mem::swap(&mut self.buffer, &mut x); +- x +- } ++impl AioCb { ++ pin_utils::unsafe_unpinned!(aiocb: LibcAiocb); + +- /// Remove the inner boxed slice, if any, and return it. +- /// +- /// The returned value will be the argument that was passed to +- /// `from_boxed_slice` when this `AioCb` was created. +- /// +- /// It is an error to call this method while the `AioCb` is still in +- /// progress. +- pub fn boxed_slice(&mut self) -> Option>> { +- assert!(!self.in_progress, "Can't remove the buffer from an AioCb that's still in-progress. Did you forget to call aio_return?"); +- if let Buffer::BoxedSlice(_) = self.buffer { +- let mut oldbuffer = Buffer::None; +- mem::swap(&mut self.buffer, &mut oldbuffer); +- if let Buffer::BoxedSlice(inner) = oldbuffer { +- Some(inner) +- } else { +- unreachable!(); +- } +- } else { +- None ++ fn aio_return(mut self: Pin<&mut Self>) -> Result { ++ self.in_progress = false; ++ unsafe { ++ let p: *mut libc::aiocb = &mut self.aiocb.0; ++ Errno::result(libc::aio_return(p)) + } ++ .map(|r| r as usize) + } + +- /// Remove the inner boxed mutable slice, if any, and return it. +- /// +- /// The returned value will be the argument that was passed to +- /// `from_boxed_mut_slice` when this `AioCb` was created. +- /// +- /// It is an error to call this method while the `AioCb` is still in +- /// progress. +- pub fn boxed_mut_slice(&mut self) -> Option>> { +- assert!(!self.in_progress, "Can't remove the buffer from an AioCb that's still in-progress. Did you forget to call aio_return?"); +- if let Buffer::BoxedMutSlice(_) = self.buffer { +- let mut oldbuffer = Buffer::None; +- mem::swap(&mut self.buffer, &mut oldbuffer); +- if let Buffer::BoxedMutSlice(inner) = oldbuffer { +- Some(inner) +- } else { +- unreachable!(); +- } +- } else { +- None ++ fn cancel(mut self: Pin<&mut Self>) -> Result { ++ let r = unsafe { ++ libc::aio_cancel(self.aiocb.0.aio_fildes, &mut self.aiocb.0) ++ }; ++ match r { ++ libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled), ++ libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled), ++ libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone), ++ -1 => Err(Errno::last()), ++ _ => panic!("unknown aio_cancel return value"), + } + } + +- /// Returns the underlying file descriptor associated with the `AioCb` +- pub fn fd(&self) -> RawFd { +- self.aiocb.aio_fildes +- } +- +- /// Constructs a new `AioCb` with no associated buffer. +- /// +- /// The resulting `AioCb` structure is suitable for use with `AioCb::fsync`. +- /// +- /// # Parameters +- /// +- /// * `fd`: File descriptor. Required for all aio functions. +- /// * `prio`: If POSIX Prioritized IO is supported, then the +- /// operation will be prioritized at the process's +- /// priority level minus `prio`. +- /// * `sigev_notify`: Determines how you will be notified of event +- /// completion. +- /// +- /// # Examples +- /// +- /// Create an `AioCb` from a raw file descriptor and use it for an +- /// [`fsync`](#method.fsync) operation. +- /// +- /// ``` +- /// # extern crate tempfile; +- /// # extern crate nix; +- /// # use nix::errno::Errno; +- /// # use nix::Error; +- /// # use nix::sys::aio::*; +- /// # use nix::sys::signal::SigevNotify::SigevNone; +- /// # use std::{thread, time}; +- /// # use std::os::unix::io::AsRawFd; +- /// # use tempfile::tempfile; +- /// # fn main() { +- /// let f = tempfile().unwrap(); +- /// let mut aiocb = AioCb::from_fd( f.as_raw_fd(), 0, SigevNone); +- /// aiocb.fsync(AioFsyncMode::O_SYNC).expect("aio_fsync failed early"); +- /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) { +- /// thread::sleep(time::Duration::from_millis(10)); +- /// } +- /// aiocb.aio_return().expect("aio_fsync failed late"); +- /// # } +- /// ``` +- pub fn from_fd(fd: RawFd, prio: libc::c_int, +- sigev_notify: SigevNotify) -> AioCb<'a> { +- let mut a = AioCb::common_init(fd, prio, sigev_notify); +- a.aio_offset = 0; +- a.aio_nbytes = 0; +- a.aio_buf = null_mut(); +- ++ fn common_init(fd: RawFd, prio: i32, sigev_notify: SigevNotify) -> Self { ++ // Use mem::zeroed instead of explicitly zeroing each field, because the ++ // number and name of reserved fields is OS-dependent. On some OSes, ++ // some reserved fields are used the kernel for state, and must be ++ // explicitly zeroed when allocated. ++ let mut a = unsafe { mem::zeroed::() }; ++ a.aio_fildes = fd; ++ a.aio_reqprio = prio; ++ a.aio_sigevent = SigEvent::new(sigev_notify).sigevent(); + AioCb { +- aiocb: a, +- mutable: false, ++ aiocb: LibcAiocb(a), + in_progress: false, +- buffer: Buffer::None + } + } + +- /// Constructs a new `AioCb` from a mutable slice. +- /// +- /// The resulting `AioCb` will be suitable for both read and write +- /// operations, but only if the borrow checker can guarantee that the slice +- /// will outlive the `AioCb`. That will usually be the case if the `AioCb` +- /// is stack-allocated. If the borrow checker gives you trouble, try using +- /// [`from_boxed_mut_slice`](#method.from_boxed_mut_slice) instead. +- /// +- /// # Parameters +- /// +- /// * `fd`: File descriptor. Required for all aio functions. +- /// * `offs`: File offset +- /// * `buf`: A memory buffer +- /// * `prio`: If POSIX Prioritized IO is supported, then the +- /// operation will be prioritized at the process's +- /// priority level minus `prio` +- /// * `sigev_notify`: Determines how you will be notified of event +- /// completion. +- /// * `opcode`: This field is only used for `lio_listio`. It +- /// determines which operation to use for this individual +- /// aiocb +- /// +- /// # Examples +- /// +- /// Create an `AioCb` from a mutable slice and read into it. +- /// +- /// ``` +- /// # extern crate tempfile; +- /// # extern crate nix; +- /// # use nix::errno::Errno; +- /// # use nix::Error; +- /// # use nix::sys::aio::*; +- /// # use nix::sys::signal::SigevNotify; +- /// # use std::{thread, time}; +- /// # use std::io::Write; +- /// # use std::os::unix::io::AsRawFd; +- /// # use tempfile::tempfile; +- /// # fn main() { +- /// const INITIAL: &[u8] = b"abcdef123456"; +- /// const LEN: usize = 4; +- /// let mut rbuf = vec![0; LEN]; +- /// let mut f = tempfile().unwrap(); +- /// f.write_all(INITIAL).unwrap(); +- /// { +- /// let mut aiocb = AioCb::from_mut_slice( f.as_raw_fd(), +- /// 2, //offset +- /// &mut rbuf, +- /// 0, //priority +- /// SigevNotify::SigevNone, +- /// LioOpcode::LIO_NOP); +- /// aiocb.read().unwrap(); +- /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) { +- /// thread::sleep(time::Duration::from_millis(10)); +- /// } +- /// assert_eq!(aiocb.aio_return().unwrap() as usize, LEN); +- /// } +- /// assert_eq!(rbuf, b"cdef"); +- /// # } +- /// ``` +- pub fn from_mut_slice(fd: RawFd, offs: off_t, buf: &'a mut [u8], +- prio: libc::c_int, sigev_notify: SigevNotify, +- opcode: LioOpcode) -> AioCb<'a> { +- let mut a = AioCb::common_init(fd, prio, sigev_notify); +- a.aio_offset = offs; +- a.aio_nbytes = buf.len() as size_t; +- a.aio_buf = buf.as_ptr() as *mut c_void; +- a.aio_lio_opcode = opcode as libc::c_int; +- +- AioCb { +- aiocb: a, +- mutable: true, +- in_progress: false, +- buffer: Buffer::Phantom(PhantomData), ++ fn error(self: Pin<&mut Self>) -> Result<()> { ++ let r = unsafe { libc::aio_error(&self.aiocb().0) }; ++ match r { ++ 0 => Ok(()), ++ num if num > 0 => Err(Errno::from_i32(num)), ++ -1 => Err(Errno::last()), ++ num => panic!("unknown aio_error return value {:?}", num), + } + } + +- /// The safest and most flexible way to create an `AioCb`. +- /// +- /// Unlike [`from_slice`], this method returns a structure suitable for +- /// placement on the heap. It may be used for write operations, but not +- /// read operations. Unlike `from_ptr`, this method will ensure that the +- /// buffer doesn't `drop` while the kernel is still processing it. Any +- /// object that can be borrowed as a boxed slice will work. +- /// +- /// # Parameters +- /// +- /// * `fd`: File descriptor. Required for all aio functions. +- /// * `offs`: File offset +- /// * `buf`: A boxed slice-like object +- /// * `prio`: If POSIX Prioritized IO is supported, then the +- /// operation will be prioritized at the process's +- /// priority level minus `prio` +- /// * `sigev_notify`: Determines how you will be notified of event +- /// completion. +- /// * `opcode`: This field is only used for `lio_listio`. It +- /// determines which operation to use for this individual +- /// aiocb +- /// +- /// # Examples +- /// +- /// Create an `AioCb` from a Vector and use it for writing +- /// +- /// ``` +- /// # extern crate tempfile; +- /// # extern crate nix; +- /// # use nix::errno::Errno; +- /// # use nix::Error; +- /// # use nix::sys::aio::*; +- /// # use nix::sys::signal::SigevNotify; +- /// # use std::{thread, time}; +- /// # use std::io::Write; +- /// # use std::os::unix::io::AsRawFd; +- /// # use tempfile::tempfile; +- /// # fn main() { +- /// let wbuf = Box::new(Vec::from("CDEF")); +- /// let expected_len = wbuf.len(); +- /// let mut f = tempfile().unwrap(); +- /// let mut aiocb = AioCb::from_boxed_slice( f.as_raw_fd(), +- /// 2, //offset +- /// wbuf, +- /// 0, //priority +- /// SigevNotify::SigevNone, +- /// LioOpcode::LIO_NOP); +- /// aiocb.write().unwrap(); +- /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) { +- /// thread::sleep(time::Duration::from_millis(10)); +- /// } +- /// assert_eq!(aiocb.aio_return().unwrap() as usize, expected_len); +- /// # } +- /// ``` +- /// +- /// Create an `AioCb` from a `Bytes` object +- /// +- /// ``` +- /// # extern crate bytes; +- /// # extern crate tempfile; +- /// # extern crate nix; +- /// # use bytes::Bytes; +- /// # use nix::sys::aio::*; +- /// # use nix::sys::signal::SigevNotify; +- /// # use std::os::unix::io::AsRawFd; +- /// # use tempfile::tempfile; +- /// # fn main() { +- /// let wbuf = Box::new(Bytes::from(&b"CDEF"[..])); +- /// let mut f = tempfile().unwrap(); +- /// let mut aiocb = AioCb::from_boxed_slice( f.as_raw_fd(), +- /// 2, //offset +- /// wbuf, +- /// 0, //priority +- /// SigevNotify::SigevNone, +- /// LioOpcode::LIO_NOP); +- /// # } +- /// ``` +- /// +- /// If a library needs to work with buffers that aren't `Box`ed, it can +- /// create a `Box`ed container for use with this method. Here's an example +- /// using an un`Box`ed `Bytes` object. +- /// +- /// ``` +- /// # extern crate bytes; +- /// # extern crate tempfile; +- /// # extern crate nix; +- /// # use bytes::Bytes; +- /// # use nix::sys::aio::*; +- /// # use nix::sys::signal::SigevNotify; +- /// # use std::borrow::Borrow; +- /// # use std::os::unix::io::AsRawFd; +- /// # use tempfile::tempfile; +- /// struct BytesContainer(Bytes); +- /// impl Borrow<[u8]> for BytesContainer { +- /// fn borrow(&self) -> &[u8] { +- /// self.0.as_ref() +- /// } +- /// } +- /// fn main() { +- /// let wbuf = Bytes::from(&b"CDEF"[..]); +- /// let boxed_wbuf = Box::new(BytesContainer(wbuf)); +- /// let mut f = tempfile().unwrap(); +- /// let mut aiocb = AioCb::from_boxed_slice( f.as_raw_fd(), +- /// 2, //offset +- /// boxed_wbuf, +- /// 0, //priority +- /// SigevNotify::SigevNone, +- /// LioOpcode::LIO_NOP); +- /// } +- /// ``` +- /// +- /// [`from_slice`]: #method.from_slice +- pub fn from_boxed_slice(fd: RawFd, offs: off_t, buf: Box>, +- prio: libc::c_int, sigev_notify: SigevNotify, +- opcode: LioOpcode) -> AioCb<'a> { +- let mut a = AioCb::common_init(fd, prio, sigev_notify); +- { +- let borrowed : &dyn Borrow<[u8]> = buf.borrow(); +- let slice : &[u8] = borrowed.borrow(); +- a.aio_nbytes = slice.len() as size_t; +- a.aio_buf = slice.as_ptr() as *mut c_void; +- } +- a.aio_offset = offs; +- a.aio_lio_opcode = opcode as libc::c_int; +- +- AioCb { +- aiocb: a, +- mutable: false, +- in_progress: false, +- buffer: Buffer::BoxedSlice(buf), +- } ++ fn in_progress(&self) -> bool { ++ self.in_progress + } + +- /// The safest and most flexible way to create an `AioCb` for reading. +- /// +- /// Like [`from_boxed_slice`], but the slice is a mutable one. More +- /// flexible than [`from_mut_slice`], because a wide range of objects can be +- /// used. +- /// +- /// # Examples +- /// +- /// Create an `AioCb` from a Vector and use it for reading +- /// +- /// ``` +- /// # extern crate tempfile; +- /// # extern crate nix; +- /// # use nix::errno::Errno; +- /// # use nix::Error; +- /// # use nix::sys::aio::*; +- /// # use nix::sys::signal::SigevNotify; +- /// # use std::{thread, time}; +- /// # use std::io::Write; +- /// # use std::os::unix::io::AsRawFd; +- /// # use tempfile::tempfile; +- /// # fn main() { +- /// const INITIAL: &[u8] = b"abcdef123456"; +- /// const LEN: usize = 4; +- /// let rbuf = Box::new(vec![0; LEN]); +- /// let mut f = tempfile().unwrap(); +- /// f.write_all(INITIAL).unwrap(); +- /// let mut aiocb = AioCb::from_boxed_mut_slice( f.as_raw_fd(), +- /// 2, //offset +- /// rbuf, +- /// 0, //priority +- /// SigevNotify::SigevNone, +- /// LioOpcode::LIO_NOP); +- /// aiocb.read().unwrap(); +- /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) { +- /// thread::sleep(time::Duration::from_millis(10)); +- /// } +- /// assert_eq!(aiocb.aio_return().unwrap() as usize, LEN); +- /// let mut buffer = aiocb.boxed_mut_slice().unwrap(); +- /// const EXPECT: &[u8] = b"cdef"; +- /// assert_eq!(buffer.borrow_mut(), EXPECT); +- /// # } +- /// ``` +- /// +- /// [`from_boxed_slice`]: #method.from_boxed_slice +- /// [`from_mut_slice`]: #method.from_mut_slice +- pub fn from_boxed_mut_slice(fd: RawFd, offs: off_t, +- mut buf: Box>, +- prio: libc::c_int, sigev_notify: SigevNotify, +- opcode: LioOpcode) -> AioCb<'a> { +- let mut a = AioCb::common_init(fd, prio, sigev_notify); +- { +- let borrowed : &mut dyn BorrowMut<[u8]> = buf.borrow_mut(); +- let slice : &mut [u8] = borrowed.borrow_mut(); +- a.aio_nbytes = slice.len() as size_t; +- a.aio_buf = slice.as_mut_ptr() as *mut c_void; +- } +- a.aio_offset = offs; +- a.aio_lio_opcode = opcode as libc::c_int; +- +- AioCb { +- aiocb: a, +- mutable: true, +- in_progress: false, +- buffer: Buffer::BoxedMutSlice(buf), +- } ++ fn set_in_progress(mut self: Pin<&mut Self>) { ++ self.as_mut().in_progress = true; + } + +- /// Constructs a new `AioCb` from a mutable raw pointer +- /// +- /// Unlike `from_mut_slice`, this method returns a structure suitable for +- /// placement on the heap. It may be used for both reads and writes. Due +- /// to its unsafety, this method is not recommended. It is most useful when +- /// heap allocation is required but for some reason the data cannot be +- /// wrapped in a `struct` that implements `BorrowMut<[u8]>` +- /// +- /// # Parameters +- /// +- /// * `fd`: File descriptor. Required for all aio functions. +- /// * `offs`: File offset +- /// * `buf`: Pointer to the memory buffer +- /// * `len`: Length of the buffer pointed to by `buf` +- /// * `prio`: If POSIX Prioritized IO is supported, then the +- /// operation will be prioritized at the process's +- /// priority level minus `prio` +- /// * `sigev_notify`: Determines how you will be notified of event +- /// completion. +- /// * `opcode`: This field is only used for `lio_listio`. It +- /// determines which operation to use for this individual +- /// aiocb +- /// +- /// # Safety +- /// +- /// The caller must ensure that the storage pointed to by `buf` outlives the +- /// `AioCb`. The lifetime checker can't help here. +- pub unsafe fn from_mut_ptr(fd: RawFd, offs: off_t, +- buf: *mut c_void, len: usize, +- prio: libc::c_int, sigev_notify: SigevNotify, +- opcode: LioOpcode) -> AioCb<'a> { +- let mut a = AioCb::common_init(fd, prio, sigev_notify); +- a.aio_offset = offs; +- a.aio_nbytes = len; +- a.aio_buf = buf; +- a.aio_lio_opcode = opcode as libc::c_int; +- +- AioCb { +- aiocb: a, +- mutable: true, +- in_progress: false, +- buffer: Buffer::None +- } ++ /// Update the notification settings for an existing AIO operation that has ++ /// not yet been submitted. ++ // Takes a normal reference rather than a pinned one because this method is ++ // normally called before the object needs to be pinned, that is, before ++ // it's been submitted to the kernel. ++ fn set_sigev_notify(&mut self, sigev_notify: SigevNotify) { ++ assert!( ++ !self.in_progress, ++ "Can't change notification settings for an in-progress operation" ++ ); ++ self.aiocb.0.aio_sigevent = SigEvent::new(sigev_notify).sigevent(); + } ++} + +- /// Constructs a new `AioCb` from a raw pointer. +- /// +- /// Unlike `from_slice`, this method returns a structure suitable for +- /// placement on the heap. Due to its unsafety, this method is not +- /// recommended. It is most useful when heap allocation is required but for +- /// some reason the data cannot be wrapped in a `struct` that implements +- /// `Borrow<[u8]>` +- /// +- /// # Parameters +- /// +- /// * `fd`: File descriptor. Required for all aio functions. +- /// * `offs`: File offset +- /// * `buf`: Pointer to the memory buffer +- /// * `len`: Length of the buffer pointed to by `buf` +- /// * `prio`: If POSIX Prioritized IO is supported, then the +- /// operation will be prioritized at the process's +- /// priority level minus `prio` +- /// * `sigev_notify`: Determines how you will be notified of event +- /// completion. +- /// * `opcode`: This field is only used for `lio_listio`. It +- /// determines which operation to use for this individual +- /// aiocb +- /// +- /// # Safety +- /// +- /// The caller must ensure that the storage pointed to by `buf` outlives the +- /// `AioCb`. The lifetime checker can't help here. +- pub unsafe fn from_ptr(fd: RawFd, offs: off_t, +- buf: *const c_void, len: usize, +- prio: libc::c_int, sigev_notify: SigevNotify, +- opcode: LioOpcode) -> AioCb<'a> { +- let mut a = AioCb::common_init(fd, prio, sigev_notify); +- a.aio_offset = offs; +- a.aio_nbytes = len; +- // casting a const ptr to a mutable ptr here is ok, because we set the +- // AioCb's mutable field to false +- a.aio_buf = buf as *mut c_void; +- a.aio_lio_opcode = opcode as libc::c_int; ++impl Debug for AioCb { ++ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { ++ fmt.debug_struct("AioCb") ++ .field("aiocb", &self.aiocb.0) ++ .field("in_progress", &self.in_progress) ++ .finish() ++ } ++} + +- AioCb { +- aiocb: a, +- mutable: false, +- in_progress: false, +- buffer: Buffer::None +- } ++impl Drop for AioCb { ++ /// If the `AioCb` has no remaining state in the kernel, just drop it. ++ /// Otherwise, dropping constitutes a resource leak, which is an error ++ fn drop(&mut self) { ++ assert!( ++ thread::panicking() || !self.in_progress, ++ "Dropped an in-progress AioCb" ++ ); + } ++} + +- /// Like `from_mut_slice`, but works on constant slices rather than +- /// mutable slices. +- /// +- /// An `AioCb` created this way cannot be used with `read`, and its +- /// `LioOpcode` cannot be set to `LIO_READ`. This method is useful when +- /// writing a const buffer with `AioCb::write`, since `from_mut_slice` can't +- /// work with const buffers. ++/// Methods common to all AIO operations ++pub trait Aio { ++ /// The return type of [`Aio::aio_return`]. ++ type Output; ++ ++ /// Retrieve return status of an asynchronous operation. + /// +- /// # Examples ++ /// Should only be called once for each operation, after [`Aio::error`] ++ /// indicates that it has completed. The result is the same as for the ++ /// synchronous `read(2)`, `write(2)`, of `fsync(2)` functions. + /// +- /// Construct an `AioCb` from a slice and use it for writing. ++ /// # References + /// +- /// ``` +- /// # extern crate tempfile; +- /// # extern crate nix; +- /// # use nix::errno::Errno; +- /// # use nix::Error; +- /// # use nix::sys::aio::*; +- /// # use nix::sys::signal::SigevNotify; +- /// # use std::{thread, time}; +- /// # use std::os::unix::io::AsRawFd; +- /// # use tempfile::tempfile; +- /// # fn main() { +- /// const WBUF: &[u8] = b"abcdef123456"; +- /// let mut f = tempfile().unwrap(); +- /// let mut aiocb = AioCb::from_slice( f.as_raw_fd(), +- /// 2, //offset +- /// WBUF, +- /// 0, //priority +- /// SigevNotify::SigevNone, +- /// LioOpcode::LIO_NOP); +- /// aiocb.write().unwrap(); +- /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) { +- /// thread::sleep(time::Duration::from_millis(10)); +- /// } +- /// assert_eq!(aiocb.aio_return().unwrap() as usize, WBUF.len()); +- /// # } +- /// ``` +- // Note: another solution to the problem of writing const buffers would be +- // to genericize AioCb for both &mut [u8] and &[u8] buffers. AioCb::read +- // could take the former and AioCb::write could take the latter. However, +- // then lio_listio wouldn't work, because that function needs a slice of +- // AioCb, and they must all be of the same type. +- pub fn from_slice(fd: RawFd, offs: off_t, buf: &'a [u8], +- prio: libc::c_int, sigev_notify: SigevNotify, +- opcode: LioOpcode) -> AioCb { +- let mut a = AioCb::common_init(fd, prio, sigev_notify); +- a.aio_offset = offs; +- a.aio_nbytes = buf.len() as size_t; +- // casting an immutable buffer to a mutable pointer looks unsafe, +- // but technically its only unsafe to dereference it, not to create +- // it. +- a.aio_buf = buf.as_ptr() as *mut c_void; +- assert!(opcode != LioOpcode::LIO_READ, "Can't read into an immutable buffer"); +- a.aio_lio_opcode = opcode as libc::c_int; +- +- AioCb { +- aiocb: a, +- mutable: false, +- in_progress: false, +- buffer: Buffer::None, +- } +- } +- +- fn common_init(fd: RawFd, prio: libc::c_int, +- sigev_notify: SigevNotify) -> libc::aiocb { +- // Use mem::zeroed instead of explicitly zeroing each field, because the +- // number and name of reserved fields is OS-dependent. On some OSes, +- // some reserved fields are used the kernel for state, and must be +- // explicitly zeroed when allocated. +- let mut a = unsafe { mem::zeroed::()}; +- a.aio_fildes = fd; +- a.aio_reqprio = prio; +- a.aio_sigevent = SigEvent::new(sigev_notify).sigevent(); +- a +- } +- +- /// Update the notification settings for an existing `aiocb` +- pub fn set_sigev_notify(&mut self, sigev_notify: SigevNotify) { +- self.aiocb.aio_sigevent = SigEvent::new(sigev_notify).sigevent(); +- } ++ /// [aio_return](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_return.html) ++ fn aio_return(self: Pin<&mut Self>) -> Result; + + /// Cancels an outstanding AIO request. + /// +@@ -726,8 +240,6 @@ impl<'a> AioCb<'a> { + /// result. + /// + /// ``` +- /// # extern crate tempfile; +- /// # extern crate nix; + /// # use nix::errno::Errno; + /// # use nix::Error; + /// # use nix::sys::aio::*; +@@ -736,39 +248,28 @@ impl<'a> AioCb<'a> { + /// # use std::io::Write; + /// # use std::os::unix::io::AsRawFd; + /// # use tempfile::tempfile; +- /// # fn main() { + /// let wbuf = b"CDEF"; + /// let mut f = tempfile().unwrap(); +- /// let mut aiocb = AioCb::from_slice( f.as_raw_fd(), ++ /// let mut aiocb = Box::pin(AioWrite::new(f.as_raw_fd(), + /// 2, //offset + /// &wbuf[..], + /// 0, //priority +- /// SigevNotify::SigevNone, +- /// LioOpcode::LIO_NOP); +- /// aiocb.write().unwrap(); +- /// let cs = aiocb.cancel().unwrap(); ++ /// SigevNotify::SigevNone)); ++ /// aiocb.as_mut().submit().unwrap(); ++ /// let cs = aiocb.as_mut().cancel().unwrap(); + /// if cs == AioCancelStat::AioNotCanceled { +- /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) { ++ /// while (aiocb.as_mut().error() == Err(Errno::EINPROGRESS)) { + /// thread::sleep(time::Duration::from_millis(10)); + /// } + /// } + /// // Must call `aio_return`, but ignore the result +- /// let _ = aiocb.aio_return(); +- /// # } ++ /// let _ = aiocb.as_mut().aio_return(); + /// ``` + /// + /// # References + /// +- /// [aio_cancel](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_cancel.html) +- pub fn cancel(&mut self) -> Result { +- match unsafe { libc::aio_cancel(self.aiocb.aio_fildes, &mut self.aiocb) } { +- libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled), +- libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled), +- libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone), +- -1 => Err(Error::last()), +- _ => panic!("unknown aio_cancel return value") +- } +- } ++ /// [aio_cancel](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_cancel.html) ++ fn cancel(self: Pin<&mut Self>) -> Result; + + /// Retrieve error status of an asynchronous operation. + /// +@@ -781,8 +282,6 @@ impl<'a> AioCb<'a> { + /// is an alternative to `aio_suspend`, used by most of the other examples. + /// + /// ``` +- /// # extern crate tempfile; +- /// # extern crate nix; + /// # use nix::errno::Errno; + /// # use nix::Error; + /// # use nix::sys::aio::*; +@@ -790,61 +289,267 @@ impl<'a> AioCb<'a> { + /// # use std::{thread, time}; + /// # use std::os::unix::io::AsRawFd; + /// # use tempfile::tempfile; +- /// # fn main() { + /// const WBUF: &[u8] = b"abcdef123456"; + /// let mut f = tempfile().unwrap(); +- /// let mut aiocb = AioCb::from_slice( f.as_raw_fd(), ++ /// let mut aiocb = Box::pin(AioWrite::new(f.as_raw_fd(), + /// 2, //offset + /// WBUF, + /// 0, //priority +- /// SigevNotify::SigevNone, +- /// LioOpcode::LIO_NOP); +- /// aiocb.write().unwrap(); +- /// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) { ++ /// SigevNotify::SigevNone)); ++ /// aiocb.as_mut().submit().unwrap(); ++ /// while (aiocb.as_mut().error() == Err(Errno::EINPROGRESS)) { + /// thread::sleep(time::Duration::from_millis(10)); + /// } +- /// assert_eq!(aiocb.aio_return().unwrap() as usize, WBUF.len()); +- /// # } ++ /// assert_eq!(aiocb.as_mut().aio_return().unwrap(), WBUF.len()); + /// ``` + /// + /// # References + /// +- /// [aio_error](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_error.html) +- pub fn error(&mut self) -> Result<()> { +- match unsafe { libc::aio_error(&mut self.aiocb as *mut libc::aiocb) } { +- 0 => Ok(()), +- num if num > 0 => Err(Error::from_errno(Errno::from_i32(num))), +- -1 => Err(Error::last()), +- num => panic!("unknown aio_error return value {:?}", num) ++ /// [aio_error](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_error.html) ++ fn error(self: Pin<&mut Self>) -> Result<()>; ++ ++ /// Returns the underlying file descriptor associated with the operation. ++ fn fd(&self) -> RawFd; ++ ++ /// Does this operation currently have any in-kernel state? ++ /// ++ /// Dropping an operation that does have in-kernel state constitutes a ++ /// resource leak. ++ /// ++ /// # Examples ++ /// ++ /// ``` ++ /// # use nix::errno::Errno; ++ /// # use nix::Error; ++ /// # use nix::sys::aio::*; ++ /// # use nix::sys::signal::SigevNotify::SigevNone; ++ /// # use std::{thread, time}; ++ /// # use std::os::unix::io::AsRawFd; ++ /// # use tempfile::tempfile; ++ /// let f = tempfile().unwrap(); ++ /// let mut aiof = Box::pin(AioFsync::new(f.as_raw_fd(), AioFsyncMode::O_SYNC, ++ /// 0, SigevNone)); ++ /// assert!(!aiof.as_mut().in_progress()); ++ /// aiof.as_mut().submit().expect("aio_fsync failed early"); ++ /// assert!(aiof.as_mut().in_progress()); ++ /// while (aiof.as_mut().error() == Err(Errno::EINPROGRESS)) { ++ /// thread::sleep(time::Duration::from_millis(10)); ++ /// } ++ /// aiof.as_mut().aio_return().expect("aio_fsync failed late"); ++ /// assert!(!aiof.as_mut().in_progress()); ++ /// ``` ++ fn in_progress(&self) -> bool; ++ ++ /// Returns the priority of the `AioCb` ++ fn priority(&self) -> i32; ++ ++ /// Update the notification settings for an existing AIO operation that has ++ /// not yet been submitted. ++ fn set_sigev_notify(&mut self, sev: SigevNotify); ++ ++ /// Returns the `SigEvent` that will be used for notification. ++ fn sigevent(&self) -> SigEvent; ++ ++ /// Actually start the I/O operation. ++ /// ++ /// After calling this method and until [`Aio::aio_return`] returns `Ok`, ++ /// the structure may not be moved in memory. ++ fn submit(self: Pin<&mut Self>) -> Result<()>; ++} ++ ++macro_rules! aio_methods { ++ () => { ++ fn cancel(self: Pin<&mut Self>) -> Result { ++ self.aiocb().cancel() ++ } ++ ++ fn error(self: Pin<&mut Self>) -> Result<()> { ++ self.aiocb().error() ++ } ++ ++ fn fd(&self) -> RawFd { ++ self.aiocb.aiocb.0.aio_fildes ++ } ++ ++ fn in_progress(&self) -> bool { ++ self.aiocb.in_progress() ++ } ++ ++ fn priority(&self) -> i32 { ++ self.aiocb.aiocb.0.aio_reqprio ++ } ++ ++ fn set_sigev_notify(&mut self, sev: SigevNotify) { ++ self.aiocb.set_sigev_notify(sev) + } ++ ++ fn sigevent(&self) -> SigEvent { ++ SigEvent::from(&self.aiocb.aiocb.0.aio_sigevent) ++ } ++ }; ++ ($func:ident) => { ++ aio_methods!(); ++ ++ fn aio_return(self: Pin<&mut Self>) -> Result<::Output> { ++ self.aiocb().aio_return() ++ } ++ ++ fn submit(mut self: Pin<&mut Self>) -> Result<()> { ++ let p: *mut libc::aiocb = &mut self.as_mut().aiocb().aiocb.0; ++ Errno::result({ unsafe { libc::$func(p) } }).map(|_| { ++ self.aiocb().set_in_progress(); ++ }) ++ } ++ }; ++} ++ ++/// An asynchronous version of `fsync(2)`. ++/// ++/// # References ++/// ++/// [aio_fsync](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_fsync.html) ++/// # Examples ++/// ++/// ``` ++/// # use nix::errno::Errno; ++/// # use nix::Error; ++/// # use nix::sys::aio::*; ++/// # use nix::sys::signal::SigevNotify::SigevNone; ++/// # use std::{thread, time}; ++/// # use std::os::unix::io::AsRawFd; ++/// # use tempfile::tempfile; ++/// let f = tempfile().unwrap(); ++/// let mut aiof = Box::pin(AioFsync::new(f.as_raw_fd(), AioFsyncMode::O_SYNC, ++/// 0, SigevNone)); ++/// aiof.as_mut().submit().expect("aio_fsync failed early"); ++/// while (aiof.as_mut().error() == Err(Errno::EINPROGRESS)) { ++/// thread::sleep(time::Duration::from_millis(10)); ++/// } ++/// aiof.as_mut().aio_return().expect("aio_fsync failed late"); ++/// ``` ++#[derive(Debug)] ++#[repr(transparent)] ++pub struct AioFsync { ++ aiocb: AioCb, ++ _pin: PhantomPinned, ++} ++ ++impl AioFsync { ++ unsafe_pinned!(aiocb: AioCb); ++ ++ /// Returns the operation's fsync mode: data and metadata or data only? ++ pub fn mode(&self) -> AioFsyncMode { ++ AioFsyncMode::try_from(self.aiocb.aiocb.0.aio_lio_opcode).unwrap() + } + +- /// An asynchronous version of `fsync(2)`. ++ /// Create a new `AioFsync`. + /// +- /// # References ++ /// # Arguments + /// +- /// [aio_fsync](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_fsync.html) +- pub fn fsync(&mut self, mode: AioFsyncMode) -> Result<()> { +- let p: *mut libc::aiocb = &mut self.aiocb; +- Errno::result(unsafe { +- libc::aio_fsync(mode as libc::c_int, p) +- }).map(|_| { +- self.in_progress = true; ++ /// * `fd`: File descriptor to sync. ++ /// * `mode`: Whether to sync file metadata too, or just data. ++ /// * `prio`: If POSIX Prioritized IO is supported, then the ++ /// operation will be prioritized at the process's ++ /// priority level minus `prio`. ++ /// * `sigev_notify`: Determines how you will be notified of event ++ /// completion. ++ pub fn new( ++ fd: RawFd, ++ mode: AioFsyncMode, ++ prio: i32, ++ sigev_notify: SigevNotify, ++ ) -> Self { ++ let mut aiocb = AioCb::common_init(fd, prio, sigev_notify); ++ // To save some memory, store mode in an unused field of the AioCb. ++ // True it isn't very much memory, but downstream creates will likely ++ // create an enum containing this and other AioCb variants and pack ++ // those enums into data structures like Vec, so it adds up. ++ aiocb.aiocb.0.aio_lio_opcode = mode as libc::c_int; ++ AioFsync { ++ aiocb, ++ _pin: PhantomPinned, ++ } ++ } ++} ++ ++impl Aio for AioFsync { ++ type Output = (); ++ ++ aio_methods!(); ++ ++ fn aio_return(self: Pin<&mut Self>) -> Result<()> { ++ self.aiocb().aio_return().map(drop) ++ } ++ ++ fn submit(mut self: Pin<&mut Self>) -> Result<()> { ++ let aiocb = &mut self.as_mut().aiocb().aiocb.0; ++ let mode = mem::replace(&mut aiocb.aio_lio_opcode, 0); ++ let p: *mut libc::aiocb = aiocb; ++ Errno::result(unsafe { libc::aio_fsync(mode, p) }).map(|_| { ++ self.aiocb().set_in_progress(); + }) + } ++} + +- /// Returns the `aiocb`'s `LioOpcode` field +- /// +- /// If the value cannot be represented as an `LioOpcode`, returns `None` +- /// instead. +- pub fn lio_opcode(&self) -> Option { +- match self.aiocb.aio_lio_opcode { +- libc::LIO_READ => Some(LioOpcode::LIO_READ), +- libc::LIO_WRITE => Some(LioOpcode::LIO_WRITE), +- libc::LIO_NOP => Some(LioOpcode::LIO_NOP), +- _ => None +- } ++// AioFsync does not need AsMut, since it can't be used with lio_listio ++ ++impl AsRef for AioFsync { ++ fn as_ref(&self) -> &libc::aiocb { ++ &self.aiocb.aiocb.0 + } ++} ++ ++/// Asynchronously reads from a file descriptor into a buffer ++/// ++/// # References ++/// ++/// [aio_read](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_read.html) ++/// ++/// # Examples ++/// ++/// ++/// ``` ++/// # use nix::errno::Errno; ++/// # use nix::Error; ++/// # use nix::sys::aio::*; ++/// # use nix::sys::signal::SigevNotify; ++/// # use std::{thread, time}; ++/// # use std::io::Write; ++/// # use std::os::unix::io::AsRawFd; ++/// # use tempfile::tempfile; ++/// const INITIAL: &[u8] = b"abcdef123456"; ++/// const LEN: usize = 4; ++/// let mut rbuf = vec![0; LEN]; ++/// let mut f = tempfile().unwrap(); ++/// f.write_all(INITIAL).unwrap(); ++/// { ++/// let mut aior = Box::pin( ++/// AioRead::new( ++/// f.as_raw_fd(), ++/// 2, //offset ++/// &mut rbuf, ++/// 0, //priority ++/// SigevNotify::SigevNone ++/// ) ++/// ); ++/// aior.as_mut().submit().unwrap(); ++/// while (aior.as_mut().error() == Err(Errno::EINPROGRESS)) { ++/// thread::sleep(time::Duration::from_millis(10)); ++/// } ++/// assert_eq!(aior.as_mut().aio_return().unwrap(), LEN); ++/// } ++/// assert_eq!(rbuf, b"cdef"); ++/// ``` ++#[derive(Debug)] ++#[repr(transparent)] ++pub struct AioRead<'a> { ++ aiocb: AioCb, ++ _data: PhantomData<&'a [u8]>, ++ _pin: PhantomPinned, ++} ++ ++impl<'a> AioRead<'a> { ++ unsafe_pinned!(aiocb: AioCb); + + /// Returns the requested length of the aio operation in bytes + /// +@@ -852,69 +557,419 @@ impl<'a> AioCb<'a> { + /// number of bytes actually read or written by a completed operation, use + /// `aio_return` instead. + pub fn nbytes(&self) -> usize { +- self.aiocb.aio_nbytes ++ self.aiocb.aiocb.0.aio_nbytes + } + +- /// Returns the file offset stored in the `AioCb` ++ /// Create a new `AioRead`, placing the data in a mutable slice. ++ /// ++ /// # Arguments ++ /// ++ /// * `fd`: File descriptor to read from ++ /// * `offs`: File offset ++ /// * `buf`: A memory buffer. It must outlive the `AioRead`. ++ /// * `prio`: If POSIX Prioritized IO is supported, then the ++ /// operation will be prioritized at the process's ++ /// priority level minus `prio` ++ /// * `sigev_notify`: Determines how you will be notified of event ++ /// completion. ++ pub fn new( ++ fd: RawFd, ++ offs: off_t, ++ buf: &'a mut [u8], ++ prio: i32, ++ sigev_notify: SigevNotify, ++ ) -> Self { ++ let mut aiocb = AioCb::common_init(fd, prio, sigev_notify); ++ aiocb.aiocb.0.aio_nbytes = buf.len(); ++ aiocb.aiocb.0.aio_buf = buf.as_mut_ptr() as *mut c_void; ++ aiocb.aiocb.0.aio_lio_opcode = libc::LIO_READ; ++ aiocb.aiocb.0.aio_offset = offs; ++ AioRead { ++ aiocb, ++ _data: PhantomData, ++ _pin: PhantomPinned, ++ } ++ } ++ ++ /// Returns the file offset of the operation. + pub fn offset(&self) -> off_t { +- self.aiocb.aio_offset ++ self.aiocb.aiocb.0.aio_offset + } ++} + +- /// Returns the priority of the `AioCb` +- pub fn priority(&self) -> libc::c_int { +- self.aiocb.aio_reqprio ++impl<'a> Aio for AioRead<'a> { ++ type Output = usize; ++ ++ aio_methods!(aio_read); ++} ++ ++impl<'a> AsMut for AioRead<'a> { ++ fn as_mut(&mut self) -> &mut libc::aiocb { ++ &mut self.aiocb.aiocb.0 ++ } ++} ++ ++impl<'a> AsRef for AioRead<'a> { ++ fn as_ref(&self) -> &libc::aiocb { ++ &self.aiocb.aiocb.0 ++ } ++} ++ ++/// Asynchronously reads from a file descriptor into a scatter/gather list of buffers. ++/// ++/// # References ++/// ++/// [aio_readv](https://www.freebsd.org/cgi/man.cgi?query=aio_readv) ++/// ++/// # Examples ++/// ++/// ++#[cfg_attr(fbsd14, doc = " ```")] ++#[cfg_attr(not(fbsd14), doc = " ```no_run")] ++/// # use nix::errno::Errno; ++/// # use nix::Error; ++/// # use nix::sys::aio::*; ++/// # use nix::sys::signal::SigevNotify; ++/// # use std::{thread, time}; ++/// # use std::io::{IoSliceMut, Write}; ++/// # use std::os::unix::io::AsRawFd; ++/// # use tempfile::tempfile; ++/// const INITIAL: &[u8] = b"abcdef123456"; ++/// let mut rbuf0 = vec![0; 4]; ++/// let mut rbuf1 = vec![0; 2]; ++/// let expected_len = rbuf0.len() + rbuf1.len(); ++/// let mut rbufs = [IoSliceMut::new(&mut rbuf0), IoSliceMut::new(&mut rbuf1)]; ++/// let mut f = tempfile().unwrap(); ++/// f.write_all(INITIAL).unwrap(); ++/// { ++/// let mut aior = Box::pin( ++/// AioReadv::new( ++/// f.as_raw_fd(), ++/// 2, //offset ++/// &mut rbufs, ++/// 0, //priority ++/// SigevNotify::SigevNone ++/// ) ++/// ); ++/// aior.as_mut().submit().unwrap(); ++/// while (aior.as_mut().error() == Err(Errno::EINPROGRESS)) { ++/// thread::sleep(time::Duration::from_millis(10)); ++/// } ++/// assert_eq!(aior.as_mut().aio_return().unwrap(), expected_len); ++/// } ++/// assert_eq!(rbuf0, b"cdef"); ++/// assert_eq!(rbuf1, b"12"); ++/// ``` ++#[cfg(target_os = "freebsd")] ++#[derive(Debug)] ++#[repr(transparent)] ++pub struct AioReadv<'a> { ++ aiocb: AioCb, ++ _data: PhantomData<&'a [&'a [u8]]>, ++ _pin: PhantomPinned, ++} ++ ++#[cfg(target_os = "freebsd")] ++impl<'a> AioReadv<'a> { ++ unsafe_pinned!(aiocb: AioCb); ++ ++ /// Returns the number of buffers the operation will read into. ++ pub fn iovlen(&self) -> usize { ++ self.aiocb.aiocb.0.aio_nbytes + } + +- /// Asynchronously reads from a file descriptor into a buffer ++ /// Create a new `AioReadv`, placing the data in a list of mutable slices. + /// +- /// # References ++ /// # Arguments + /// +- /// [aio_read](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_read.html) +- pub fn read(&mut self) -> Result<()> { +- assert!(self.mutable, "Can't read into an immutable buffer"); +- let p: *mut libc::aiocb = &mut self.aiocb; +- Errno::result(unsafe { +- libc::aio_read(p) +- }).map(|_| { +- self.in_progress = true; +- }) ++ /// * `fd`: File descriptor to read from ++ /// * `offs`: File offset ++ /// * `bufs`: A scatter/gather list of memory buffers. They must ++ /// outlive the `AioReadv`. ++ /// * `prio`: If POSIX Prioritized IO is supported, then the ++ /// operation will be prioritized at the process's ++ /// priority level minus `prio` ++ /// * `sigev_notify`: Determines how you will be notified of event ++ /// completion. ++ pub fn new( ++ fd: RawFd, ++ offs: off_t, ++ bufs: &mut [IoSliceMut<'a>], ++ prio: i32, ++ sigev_notify: SigevNotify, ++ ) -> Self { ++ let mut aiocb = AioCb::common_init(fd, prio, sigev_notify); ++ // In vectored mode, aio_nbytes stores the length of the iovec array, ++ // not the byte count. ++ aiocb.aiocb.0.aio_nbytes = bufs.len(); ++ aiocb.aiocb.0.aio_buf = bufs.as_mut_ptr() as *mut c_void; ++ aiocb.aiocb.0.aio_lio_opcode = libc::LIO_READV; ++ aiocb.aiocb.0.aio_offset = offs; ++ AioReadv { ++ aiocb, ++ _data: PhantomData, ++ _pin: PhantomPinned, ++ } + } + +- /// Returns the `SigEvent` stored in the `AioCb` +- pub fn sigevent(&self) -> SigEvent { +- SigEvent::from(&self.aiocb.aio_sigevent) ++ /// Returns the file offset of the operation. ++ pub fn offset(&self) -> off_t { ++ self.aiocb.aiocb.0.aio_offset + } ++} + +- /// Retrieve return status of an asynchronous operation. ++#[cfg(target_os = "freebsd")] ++impl<'a> Aio for AioReadv<'a> { ++ type Output = usize; ++ ++ aio_methods!(aio_readv); ++} ++ ++#[cfg(target_os = "freebsd")] ++impl<'a> AsMut for AioReadv<'a> { ++ fn as_mut(&mut self) -> &mut libc::aiocb { ++ &mut self.aiocb.aiocb.0 ++ } ++} ++ ++#[cfg(target_os = "freebsd")] ++impl<'a> AsRef for AioReadv<'a> { ++ fn as_ref(&self) -> &libc::aiocb { ++ &self.aiocb.aiocb.0 ++ } ++} ++ ++/// Asynchronously writes from a buffer to a file descriptor ++/// ++/// # References ++/// ++/// [aio_write](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_write.html) ++/// ++/// # Examples ++/// ++/// ``` ++/// # use nix::errno::Errno; ++/// # use nix::Error; ++/// # use nix::sys::aio::*; ++/// # use nix::sys::signal::SigevNotify; ++/// # use std::{thread, time}; ++/// # use std::os::unix::io::AsRawFd; ++/// # use tempfile::tempfile; ++/// const WBUF: &[u8] = b"abcdef123456"; ++/// let mut f = tempfile().unwrap(); ++/// let mut aiow = Box::pin( ++/// AioWrite::new( ++/// f.as_raw_fd(), ++/// 2, //offset ++/// WBUF, ++/// 0, //priority ++/// SigevNotify::SigevNone ++/// ) ++/// ); ++/// aiow.as_mut().submit().unwrap(); ++/// while (aiow.as_mut().error() == Err(Errno::EINPROGRESS)) { ++/// thread::sleep(time::Duration::from_millis(10)); ++/// } ++/// assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len()); ++/// ``` ++#[derive(Debug)] ++#[repr(transparent)] ++pub struct AioWrite<'a> { ++ aiocb: AioCb, ++ _data: PhantomData<&'a [u8]>, ++ _pin: PhantomPinned, ++} ++ ++impl<'a> AioWrite<'a> { ++ unsafe_pinned!(aiocb: AioCb); ++ ++ /// Returns the requested length of the aio operation in bytes + /// +- /// Should only be called once for each `AioCb`, after `AioCb::error` +- /// indicates that it has completed. The result is the same as for the +- /// synchronous `read(2)`, `write(2)`, of `fsync(2)` functions. ++ /// This method returns the *requested* length of the operation. To get the ++ /// number of bytes actually read or written by a completed operation, use ++ /// `aio_return` instead. ++ pub fn nbytes(&self) -> usize { ++ self.aiocb.aiocb.0.aio_nbytes ++ } ++ ++ /// Construct a new `AioWrite`. + /// +- /// # References ++ /// # Arguments + /// +- /// [aio_return](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_return.html) +- // Note: this should be just `return`, but that's a reserved word +- pub fn aio_return(&mut self) -> Result { +- let p: *mut libc::aiocb = &mut self.aiocb; +- self.in_progress = false; +- Errno::result(unsafe { libc::aio_return(p) }) ++ /// * `fd`: File descriptor to write to ++ /// * `offs`: File offset ++ /// * `buf`: A memory buffer. It must outlive the `AioWrite`. ++ /// * `prio`: If POSIX Prioritized IO is supported, then the ++ /// operation will be prioritized at the process's ++ /// priority level minus `prio` ++ /// * `sigev_notify`: Determines how you will be notified of event ++ /// completion. ++ pub fn new( ++ fd: RawFd, ++ offs: off_t, ++ buf: &'a [u8], ++ prio: i32, ++ sigev_notify: SigevNotify, ++ ) -> Self { ++ let mut aiocb = AioCb::common_init(fd, prio, sigev_notify); ++ aiocb.aiocb.0.aio_nbytes = buf.len(); ++ // casting an immutable buffer to a mutable pointer looks unsafe, ++ // but technically its only unsafe to dereference it, not to create ++ // it. Type Safety guarantees that we'll never pass aiocb to ++ // aio_read or aio_readv. ++ aiocb.aiocb.0.aio_buf = buf.as_ptr() as *mut c_void; ++ aiocb.aiocb.0.aio_lio_opcode = libc::LIO_WRITE; ++ aiocb.aiocb.0.aio_offset = offs; ++ AioWrite { ++ aiocb, ++ _data: PhantomData, ++ _pin: PhantomPinned, ++ } ++ } ++ ++ /// Returns the file offset of the operation. ++ pub fn offset(&self) -> off_t { ++ self.aiocb.aiocb.0.aio_offset ++ } ++} ++ ++impl<'a> Aio for AioWrite<'a> { ++ type Output = usize; ++ ++ aio_methods!(aio_write); ++} ++ ++impl<'a> AsMut for AioWrite<'a> { ++ fn as_mut(&mut self) -> &mut libc::aiocb { ++ &mut self.aiocb.aiocb.0 ++ } ++} ++ ++impl<'a> AsRef for AioWrite<'a> { ++ fn as_ref(&self) -> &libc::aiocb { ++ &self.aiocb.aiocb.0 ++ } ++} ++ ++/// Asynchronously writes from a scatter/gather list of buffers to a file descriptor. ++/// ++/// # References ++/// ++/// [aio_writev](https://www.freebsd.org/cgi/man.cgi?query=aio_writev) ++/// ++/// # Examples ++/// ++#[cfg_attr(fbsd14, doc = " ```")] ++#[cfg_attr(not(fbsd14), doc = " ```no_run")] ++/// # use nix::errno::Errno; ++/// # use nix::Error; ++/// # use nix::sys::aio::*; ++/// # use nix::sys::signal::SigevNotify; ++/// # use std::{thread, time}; ++/// # use std::io::IoSlice; ++/// # use std::os::unix::io::AsRawFd; ++/// # use tempfile::tempfile; ++/// const wbuf0: &[u8] = b"abcdef"; ++/// const wbuf1: &[u8] = b"123456"; ++/// let len = wbuf0.len() + wbuf1.len(); ++/// let wbufs = [IoSlice::new(wbuf0), IoSlice::new(wbuf1)]; ++/// let mut f = tempfile().unwrap(); ++/// let mut aiow = Box::pin( ++/// AioWritev::new( ++/// f.as_raw_fd(), ++/// 2, //offset ++/// &wbufs, ++/// 0, //priority ++/// SigevNotify::SigevNone ++/// ) ++/// ); ++/// aiow.as_mut().submit().unwrap(); ++/// while (aiow.as_mut().error() == Err(Errno::EINPROGRESS)) { ++/// thread::sleep(time::Duration::from_millis(10)); ++/// } ++/// assert_eq!(aiow.as_mut().aio_return().unwrap(), len); ++/// ``` ++#[cfg(target_os = "freebsd")] ++#[derive(Debug)] ++#[repr(transparent)] ++pub struct AioWritev<'a> { ++ aiocb: AioCb, ++ _data: PhantomData<&'a [&'a [u8]]>, ++ _pin: PhantomPinned, ++} ++ ++#[cfg(target_os = "freebsd")] ++impl<'a> AioWritev<'a> { ++ unsafe_pinned!(aiocb: AioCb); ++ ++ /// Returns the number of buffers the operation will read into. ++ pub fn iovlen(&self) -> usize { ++ self.aiocb.aiocb.0.aio_nbytes + } + +- /// Asynchronously writes from a buffer to a file descriptor ++ /// Construct a new `AioWritev`. + /// +- /// # References ++ /// # Arguments + /// +- /// [aio_write](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_write.html) +- pub fn write(&mut self) -> Result<()> { +- let p: *mut libc::aiocb = &mut self.aiocb; +- Errno::result(unsafe { +- libc::aio_write(p) +- }).map(|_| { +- self.in_progress = true; +- }) ++ /// * `fd`: File descriptor to write to ++ /// * `offs`: File offset ++ /// * `bufs`: A scatter/gather list of memory buffers. They must ++ /// outlive the `AioWritev`. ++ /// * `prio`: If POSIX Prioritized IO is supported, then the ++ /// operation will be prioritized at the process's ++ /// priority level minus `prio` ++ /// * `sigev_notify`: Determines how you will be notified of event ++ /// completion. ++ pub fn new( ++ fd: RawFd, ++ offs: off_t, ++ bufs: &[IoSlice<'a>], ++ prio: i32, ++ sigev_notify: SigevNotify, ++ ) -> Self { ++ let mut aiocb = AioCb::common_init(fd, prio, sigev_notify); ++ // In vectored mode, aio_nbytes stores the length of the iovec array, ++ // not the byte count. ++ aiocb.aiocb.0.aio_nbytes = bufs.len(); ++ // casting an immutable buffer to a mutable pointer looks unsafe, ++ // but technically its only unsafe to dereference it, not to create ++ // it. Type Safety guarantees that we'll never pass aiocb to ++ // aio_read or aio_readv. ++ aiocb.aiocb.0.aio_buf = bufs.as_ptr() as *mut c_void; ++ aiocb.aiocb.0.aio_lio_opcode = libc::LIO_WRITEV; ++ aiocb.aiocb.0.aio_offset = offs; ++ AioWritev { ++ aiocb, ++ _data: PhantomData, ++ _pin: PhantomPinned, ++ } + } + ++ /// Returns the file offset of the operation. ++ pub fn offset(&self) -> off_t { ++ self.aiocb.aiocb.0.aio_offset ++ } ++} ++ ++#[cfg(target_os = "freebsd")] ++impl<'a> Aio for AioWritev<'a> { ++ type Output = usize; ++ ++ aio_methods!(aio_writev); ++} ++ ++#[cfg(target_os = "freebsd")] ++impl<'a> AsMut for AioWritev<'a> { ++ fn as_mut(&mut self) -> &mut libc::aiocb { ++ &mut self.aiocb.aiocb.0 ++ } ++} ++ ++#[cfg(target_os = "freebsd")] ++impl<'a> AsRef for AioWritev<'a> { ++ fn as_ref(&self) -> &libc::aiocb { ++ &self.aiocb.aiocb.0 ++ } + } + + /// Cancels outstanding AIO requests for a given file descriptor. +@@ -925,8 +980,6 @@ impl<'a> AioCb<'a> { + /// descriptor. + /// + /// ``` +-/// # extern crate tempfile; +-/// # extern crate nix; + /// # use nix::errno::Errno; + /// # use nix::Error; + /// # use nix::sys::aio::*; +@@ -935,42 +988,39 @@ impl<'a> AioCb<'a> { + /// # use std::io::Write; + /// # use std::os::unix::io::AsRawFd; + /// # use tempfile::tempfile; +-/// # fn main() { + /// let wbuf = b"CDEF"; + /// let mut f = tempfile().unwrap(); +-/// let mut aiocb = AioCb::from_slice( f.as_raw_fd(), ++/// let mut aiocb = Box::pin(AioWrite::new(f.as_raw_fd(), + /// 2, //offset + /// &wbuf[..], + /// 0, //priority +-/// SigevNotify::SigevNone, +-/// LioOpcode::LIO_NOP); +-/// aiocb.write().unwrap(); ++/// SigevNotify::SigevNone)); ++/// aiocb.as_mut().submit().unwrap(); + /// let cs = aio_cancel_all(f.as_raw_fd()).unwrap(); + /// if cs == AioCancelStat::AioNotCanceled { +-/// while (aiocb.error() == Err(Error::from(Errno::EINPROGRESS))) { ++/// while (aiocb.as_mut().error() == Err(Errno::EINPROGRESS)) { + /// thread::sleep(time::Duration::from_millis(10)); + /// } + /// } + /// // Must call `aio_return`, but ignore the result +-/// let _ = aiocb.aio_return(); +-/// # } ++/// let _ = aiocb.as_mut().aio_return(); + /// ``` + /// + /// # References + /// +-/// [`aio_cancel`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_cancel.html) ++/// [`aio_cancel`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_cancel.html) + pub fn aio_cancel_all(fd: RawFd) -> Result { +- match unsafe { libc::aio_cancel(fd, null_mut()) } { ++ match unsafe { libc::aio_cancel(fd, ptr::null_mut()) } { + libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled), + libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled), + libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone), +- -1 => Err(Error::last()), +- _ => panic!("unknown aio_cancel return value") ++ -1 => Err(Errno::last()), ++ _ => panic!("unknown aio_cancel return value"), + } + } + +-/// Suspends the calling process until at least one of the specified `AioCb`s +-/// has completed, a signal is delivered, or the timeout has passed. ++/// Suspends the calling process until at least one of the specified operations ++/// have completed, a signal is delivered, or the timeout has passed. + /// + /// If `timeout` is `None`, `aio_suspend` will block indefinitely. + /// +@@ -979,297 +1029,213 @@ pub fn aio_cancel_all(fd: RawFd) -> Result { + /// Use `aio_suspend` to block until an aio operation completes. + /// + /// ``` +-/// # extern crate tempfile; +-/// # extern crate nix; + /// # use nix::sys::aio::*; + /// # use nix::sys::signal::SigevNotify; + /// # use std::os::unix::io::AsRawFd; + /// # use tempfile::tempfile; +-/// # fn main() { + /// const WBUF: &[u8] = b"abcdef123456"; + /// let mut f = tempfile().unwrap(); +-/// let mut aiocb = AioCb::from_slice( f.as_raw_fd(), ++/// let mut aiocb = Box::pin(AioWrite::new(f.as_raw_fd(), + /// 2, //offset + /// WBUF, + /// 0, //priority +-/// SigevNotify::SigevNone, +-/// LioOpcode::LIO_NOP); +-/// aiocb.write().unwrap(); +-/// aio_suspend(&[&aiocb], None).expect("aio_suspend failed"); +-/// assert_eq!(aiocb.aio_return().unwrap() as usize, WBUF.len()); +-/// # } ++/// SigevNotify::SigevNone)); ++/// aiocb.as_mut().submit().unwrap(); ++/// aio_suspend(&[&*aiocb], None).expect("aio_suspend failed"); ++/// assert_eq!(aiocb.as_mut().aio_return().unwrap() as usize, WBUF.len()); + /// ``` + /// # References + /// +-/// [`aio_suspend`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_suspend.html) +-pub fn aio_suspend(list: &[&AioCb], timeout: Option) -> Result<()> { +- let plist = list as *const [&AioCb] as *const [*const libc::aiocb]; +- let p = plist as *const *const libc::aiocb; ++/// [`aio_suspend`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_suspend.html) ++pub fn aio_suspend( ++ list: &[&dyn AsRef], ++ timeout: Option, ++) -> Result<()> { ++ let p = list as *const [&dyn AsRef] ++ as *const [*const libc::aiocb] as *const *const libc::aiocb; + let timep = match timeout { +- None => null::(), +- Some(x) => x.as_ref() as *const libc::timespec ++ None => ptr::null::(), ++ Some(x) => x.as_ref() as *const libc::timespec, + }; +- Errno::result(unsafe { +- libc::aio_suspend(p, list.len() as i32, timep) +- }).map(drop) ++ Errno::result(unsafe { libc::aio_suspend(p, list.len() as i32, timep) }) ++ .map(drop) + } + +-impl<'a> Debug for AioCb<'a> { +- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { +- fmt.debug_struct("AioCb") +- .field("aiocb", &self.aiocb) +- .field("mutable", &self.mutable) +- .field("in_progress", &self.in_progress) +- .finish() +- } +-} +- +-impl<'a> Drop for AioCb<'a> { +- /// If the `AioCb` has no remaining state in the kernel, just drop it. +- /// Otherwise, dropping constitutes a resource leak, which is an error +- fn drop(&mut self) { +- assert!(thread::panicking() || !self.in_progress, +- "Dropped an in-progress AioCb"); +- } +-} +- +-/// LIO Control Block. ++/// Submits multiple asynchronous I/O requests with a single system call. + /// +-/// The basic structure used to issue multiple AIO operations simultaneously. +-#[cfg(not(any(target_os = "ios", target_os = "macos")))] +-pub struct LioCb<'a> { +- /// A collection of [`AioCb`]s. All of these will be issued simultaneously +- /// by the [`listio`] method. +- /// +- /// [`AioCb`]: struct.AioCb.html +- /// [`listio`]: #method.listio +- pub aiocbs: Vec>, +- +- /// The actual list passed to `libc::lio_listio`. +- /// +- /// It must live for as long as any of the operations are still being +- /// processesed, because the aio subsystem uses its address as a unique +- /// identifier. +- list: Vec<*mut libc::aiocb>, +- +- /// A partial set of results. This field will get populated by +- /// `listio_resubmit` when an `LioCb` is resubmitted after an error +- results: Vec>> ++/// They are not guaranteed to complete atomically, and the order in which the ++/// requests are carried out is not specified. Reads, and writes may be freely ++/// mixed. ++/// ++/// # Examples ++/// ++/// Use `lio_listio` to submit an aio operation and wait for its completion. In ++/// this case, there is no need to use aio_suspend to wait or `error` to poll. ++/// This mode is useful for otherwise-synchronous programs that want to execute ++/// a handful of I/O operations in parallel. ++/// ``` ++/// # use std::os::unix::io::AsRawFd; ++/// # use nix::sys::aio::*; ++/// # use nix::sys::signal::SigevNotify; ++/// # use tempfile::tempfile; ++/// const WBUF: &[u8] = b"abcdef123456"; ++/// let mut f = tempfile().unwrap(); ++/// let mut aiow = Box::pin(AioWrite::new( ++/// f.as_raw_fd(), ++/// 2, // offset ++/// WBUF, ++/// 0, // priority ++/// SigevNotify::SigevNone ++/// )); ++/// lio_listio(LioMode::LIO_WAIT, &mut[aiow.as_mut()], SigevNotify::SigevNone) ++/// .unwrap(); ++/// // At this point, we are guaranteed that aiow is complete. ++/// assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len()); ++/// ``` ++/// ++/// Use `lio_listio` to submit multiple asynchronous operations with a single ++/// syscall, but receive notification individually. This is an efficient ++/// technique for reducing overall context-switch overhead, especially when ++/// combined with kqueue. ++/// ``` ++/// # use std::os::unix::io::AsRawFd; ++/// # use std::thread; ++/// # use std::time; ++/// # use nix::errno::Errno; ++/// # use nix::sys::aio::*; ++/// # use nix::sys::signal::SigevNotify; ++/// # use tempfile::tempfile; ++/// const WBUF: &[u8] = b"abcdef123456"; ++/// let mut f = tempfile().unwrap(); ++/// let mut aiow = Box::pin(AioWrite::new( ++/// f.as_raw_fd(), ++/// 2, // offset ++/// WBUF, ++/// 0, // priority ++/// SigevNotify::SigevNone ++/// )); ++/// lio_listio(LioMode::LIO_NOWAIT, &mut[aiow.as_mut()], SigevNotify::SigevNone) ++/// .unwrap(); ++/// // We must wait for the completion of each individual operation ++/// while (aiow.as_mut().error() == Err(Errno::EINPROGRESS)) { ++/// thread::sleep(time::Duration::from_millis(10)); ++/// } ++/// assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len()); ++/// ``` ++/// ++/// Use `lio_listio` to submit multiple operations, and receive notification ++/// only when all of them are complete. This can be useful when there is some ++/// logical relationship between the operations. But beware! Errors or system ++/// resource limitations may cause `lio_listio` to return `EIO`, `EAGAIN`, or ++/// `EINTR`, in which case some but not all operations may have been submitted. ++/// In that case, you must check the status of each individual operation, and ++/// possibly resubmit some. ++/// ``` ++/// # use libc::c_int; ++/// # use std::os::unix::io::AsRawFd; ++/// # use std::sync::atomic::{AtomicBool, Ordering}; ++/// # use std::thread; ++/// # use std::time; ++/// # use lazy_static::lazy_static; ++/// # use nix::errno::Errno; ++/// # use nix::sys::aio::*; ++/// # use nix::sys::signal::*; ++/// # use tempfile::tempfile; ++/// lazy_static! { ++/// pub static ref SIGNALED: AtomicBool = AtomicBool::new(false); ++/// } ++/// ++/// extern fn sigfunc(_: c_int) { ++/// SIGNALED.store(true, Ordering::Relaxed); ++/// } ++/// let sa = SigAction::new(SigHandler::Handler(sigfunc), ++/// SaFlags::SA_RESETHAND, ++/// SigSet::empty()); ++/// SIGNALED.store(false, Ordering::Relaxed); ++/// unsafe { sigaction(Signal::SIGUSR2, &sa) }.unwrap(); ++/// ++/// const WBUF: &[u8] = b"abcdef123456"; ++/// let mut f = tempfile().unwrap(); ++/// let mut aiow = Box::pin(AioWrite::new( ++/// f.as_raw_fd(), ++/// 2, // offset ++/// WBUF, ++/// 0, // priority ++/// SigevNotify::SigevNone ++/// )); ++/// let sev = SigevNotify::SigevSignal { signal: Signal::SIGUSR2, si_value: 0 }; ++/// lio_listio(LioMode::LIO_NOWAIT, &mut[aiow.as_mut()], sev).unwrap(); ++/// while !SIGNALED.load(Ordering::Relaxed) { ++/// thread::sleep(time::Duration::from_millis(10)); ++/// } ++/// // At this point, since `lio_listio` returned success and delivered its ++/// // notification, we know that all operations are complete. ++/// assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len()); ++/// ``` ++pub fn lio_listio( ++ mode: LioMode, ++ list: &mut [Pin<&mut dyn AsMut>], ++ sigev_notify: SigevNotify, ++) -> Result<()> { ++ let p = list as *mut [Pin<&mut dyn AsMut>] ++ as *mut [*mut libc::aiocb] as *mut *mut libc::aiocb; ++ let sigev = SigEvent::new(sigev_notify); ++ let sigevp = &mut sigev.sigevent() as *mut libc::sigevent; ++ Errno::result(unsafe { ++ libc::lio_listio(mode as i32, p, list.len() as i32, sigevp) ++ }) ++ .map(drop) + } + +-#[cfg(not(any(target_os = "ios", target_os = "macos")))] +-impl<'a> LioCb<'a> { +- /// Initialize an empty `LioCb` +- pub fn with_capacity(capacity: usize) -> LioCb<'a> { +- LioCb { +- aiocbs: Vec::with_capacity(capacity), +- list: Vec::with_capacity(capacity), +- results: Vec::with_capacity(capacity) +- } +- } ++#[cfg(test)] ++mod t { ++ use super::*; + +- /// Submits multiple asynchronous I/O requests with a single system call. +- /// +- /// They are not guaranteed to complete atomically, and the order in which +- /// the requests are carried out is not specified. Reads, writes, and +- /// fsyncs may be freely mixed. +- /// +- /// This function is useful for reducing the context-switch overhead of +- /// submitting many AIO operations. It can also be used with +- /// `LioMode::LIO_WAIT` to block on the result of several independent +- /// operations. Used that way, it is often useful in programs that +- /// otherwise make little use of AIO. +- /// +- /// # Examples +- /// +- /// Use `listio` to submit an aio operation and wait for its completion. In +- /// this case, there is no need to use [`aio_suspend`] to wait or +- /// [`AioCb::error`] to poll. +- /// +- /// ``` +- /// # extern crate tempfile; +- /// # extern crate nix; +- /// # use nix::sys::aio::*; +- /// # use nix::sys::signal::SigevNotify; +- /// # use std::os::unix::io::AsRawFd; +- /// # use tempfile::tempfile; +- /// # fn main() { +- /// const WBUF: &[u8] = b"abcdef123456"; +- /// let mut f = tempfile().unwrap(); +- /// let mut liocb = LioCb::with_capacity(1); +- /// liocb.aiocbs.push(AioCb::from_slice( f.as_raw_fd(), +- /// 2, //offset +- /// WBUF, +- /// 0, //priority +- /// SigevNotify::SigevNone, +- /// LioOpcode::LIO_WRITE)); +- /// liocb.listio(LioMode::LIO_WAIT, +- /// SigevNotify::SigevNone).unwrap(); +- /// assert_eq!(liocb.aio_return(0).unwrap() as usize, WBUF.len()); +- /// # } +- /// ``` +- /// +- /// # References +- /// +- /// [`lio_listio`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/lio_listio.html) +- /// +- /// [`aio_suspend`]: fn.aio_suspend.html +- /// [`AioCb::error`]: struct.AioCb.html#method.error +- pub fn listio(&mut self, mode: LioMode, +- sigev_notify: SigevNotify) -> Result<()> { +- let sigev = SigEvent::new(sigev_notify); +- let sigevp = &mut sigev.sigevent() as *mut libc::sigevent; +- self.list.clear(); +- for a in &mut self.aiocbs { +- a.in_progress = true; +- self.list.push(a as *mut AioCb<'a> +- as *mut libc::aiocb); +- } +- let p = self.list.as_ptr(); +- Errno::result(unsafe { +- libc::lio_listio(mode as i32, p, self.list.len() as i32, sigevp) +- }).map(drop) +- } +- +- /// Resubmits any incomplete operations with [`lio_listio`]. +- /// +- /// Sometimes, due to system resource limitations, an `lio_listio` call will +- /// return `EIO`, or `EAGAIN`. Or, if a signal is received, it may return +- /// `EINTR`. In any of these cases, only a subset of its constituent +- /// operations will actually have been initiated. `listio_resubmit` will +- /// resubmit any operations that are still uninitiated. +- /// +- /// After calling `listio_resubmit`, results should be collected by +- /// [`LioCb::aio_return`]. +- /// +- /// # Examples +- /// ```no_run +- /// # extern crate tempfile; +- /// # extern crate nix; +- /// # use nix::Error; +- /// # use nix::errno::Errno; +- /// # use nix::sys::aio::*; +- /// # use nix::sys::signal::SigevNotify; +- /// # use std::os::unix::io::AsRawFd; +- /// # use std::{thread, time}; +- /// # use tempfile::tempfile; +- /// # fn main() { +- /// const WBUF: &[u8] = b"abcdef123456"; +- /// let mut f = tempfile().unwrap(); +- /// let mut liocb = LioCb::with_capacity(1); +- /// liocb.aiocbs.push(AioCb::from_slice( f.as_raw_fd(), +- /// 2, //offset +- /// WBUF, +- /// 0, //priority +- /// SigevNotify::SigevNone, +- /// LioOpcode::LIO_WRITE)); +- /// let mut err = liocb.listio(LioMode::LIO_WAIT, SigevNotify::SigevNone); +- /// while err == Err(Error::Sys(Errno::EIO)) || +- /// err == Err(Error::Sys(Errno::EAGAIN)) { +- /// thread::sleep(time::Duration::from_millis(10)); +- /// err = liocb.listio_resubmit(LioMode::LIO_WAIT, SigevNotify::SigevNone); +- /// } +- /// assert_eq!(liocb.aio_return(0).unwrap() as usize, WBUF.len()); +- /// # } +- /// ``` +- /// +- /// # References +- /// +- /// [`lio_listio`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/lio_listio.html) +- /// +- /// [`lio_listio`]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/lio_listio.html +- /// [`LioCb::aio_return`]: struct.LioCb.html#method.aio_return +- // Note: the addresses of any EINPROGRESS or EOK aiocbs _must_ not be +- // changed by this method, because the kernel relies on their addresses +- // being stable. +- // Note: aiocbs that are Ok(()) must be finalized by aio_return, or else the +- // sigev_notify will immediately refire. +- pub fn listio_resubmit(&mut self, mode:LioMode, +- sigev_notify: SigevNotify) -> Result<()> { +- let sigev = SigEvent::new(sigev_notify); +- let sigevp = &mut sigev.sigevent() as *mut libc::sigevent; +- self.list.clear(); +- +- while self.results.len() < self.aiocbs.len() { +- self.results.push(None); +- } ++ /// aio_suspend relies on casting Rust Aio* struct pointers to libc::aiocb ++ /// pointers. This test ensures that such casts are valid. ++ #[test] ++ fn casting() { ++ let sev = SigevNotify::SigevNone; ++ let aiof = AioFsync::new(666, AioFsyncMode::O_SYNC, 0, sev); ++ assert_eq!( ++ aiof.as_ref() as *const libc::aiocb, ++ &aiof as *const AioFsync as *const libc::aiocb ++ ); + +- for (i, a) in self.aiocbs.iter_mut().enumerate() { +- if self.results[i].is_some() { +- // Already collected final status for this operation +- continue; +- } +- match a.error() { +- Ok(()) => { +- // aiocb is complete; collect its status and don't resubmit +- self.results[i] = Some(a.aio_return()); +- }, +- Err(Error::Sys(Errno::EAGAIN)) => { +- self.list.push(a as *mut AioCb<'a> as *mut libc::aiocb); +- }, +- Err(Error::Sys(Errno::EINPROGRESS)) => { +- // aiocb is was successfully queued; no need to do anything +- }, +- Err(Error::Sys(Errno::EINVAL)) => panic!( +- "AioCb was never submitted, or already finalized"), +- _ => unreachable!() +- } +- } +- let p = self.list.as_ptr(); +- Errno::result(unsafe { +- libc::lio_listio(mode as i32, p, self.list.len() as i32, sigevp) +- }).map(drop) +- } ++ let mut rbuf = []; ++ let aior = AioRead::new(666, 0, &mut rbuf, 0, sev); ++ assert_eq!( ++ aior.as_ref() as *const libc::aiocb, ++ &aior as *const AioRead as *const libc::aiocb ++ ); + +- /// Collect final status for an individual `AioCb` submitted as part of an +- /// `LioCb`. +- /// +- /// This is just like [`AioCb::aio_return`], except it takes into account +- /// operations that were restarted by [`LioCb::listio_resubmit`] +- /// +- /// [`AioCb::aio_return`]: struct.AioCb.html#method.aio_return +- /// [`LioCb::listio_resubmit`]: #method.listio_resubmit +- pub fn aio_return(&mut self, i: usize) -> Result { +- if i >= self.results.len() || self.results[i].is_none() { +- self.aiocbs[i].aio_return() +- } else { +- self.results[i].unwrap() +- } ++ let wbuf = []; ++ let aiow = AioWrite::new(666, 0, &wbuf, 0, sev); ++ assert_eq!( ++ aiow.as_ref() as *const libc::aiocb, ++ &aiow as *const AioWrite as *const libc::aiocb ++ ); + } + +- /// Retrieve error status of an individual `AioCb` submitted as part of an +- /// `LioCb`. +- /// +- /// This is just like [`AioCb::error`], except it takes into account +- /// operations that were restarted by [`LioCb::listio_resubmit`] +- /// +- /// [`AioCb::error`]: struct.AioCb.html#method.error +- /// [`LioCb::listio_resubmit`]: #method.listio_resubmit +- pub fn error(&mut self, i: usize) -> Result<()> { +- if i >= self.results.len() || self.results[i].is_none() { +- self.aiocbs[i].error() +- } else { +- Ok(()) +- } +- } +-} ++ #[cfg(target_os = "freebsd")] ++ #[test] ++ fn casting_vectored() { ++ let sev = SigevNotify::SigevNone; + +-#[cfg(not(any(target_os = "ios", target_os = "macos")))] +-impl<'a> Debug for LioCb<'a> { +- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { +- fmt.debug_struct("LioCb") +- .field("aiocbs", &self.aiocbs) +- .finish() +- } +-} ++ let mut rbuf = []; ++ let mut rbufs = [IoSliceMut::new(&mut rbuf)]; ++ let aiorv = AioReadv::new(666, 0, &mut rbufs[..], 0, sev); ++ assert_eq!( ++ aiorv.as_ref() as *const libc::aiocb, ++ &aiorv as *const AioReadv as *const libc::aiocb ++ ); + +-#[cfg(not(any(target_os = "ios", target_os = "macos")))] +-impl<'a> From>> for LioCb<'a> { +- fn from(src: Vec>) -> LioCb<'a> { +- LioCb { +- list: Vec::with_capacity(src.capacity()), +- results: Vec::with_capacity(src.capacity()), +- aiocbs: src, +- } ++ let wbuf = []; ++ let wbufs = [IoSlice::new(&wbuf)]; ++ let aiowv = AioWritev::new(666, 0, &wbufs, 0, sev); ++ assert_eq!( ++ aiowv.as_ref() as *const libc::aiocb, ++ &aiowv as *const AioWritev as *const libc::aiocb ++ ); + } + } +diff --git a/vendor/nix/src/sys/epoll.rs b/vendor/nix/src/sys/epoll.rs +index fef6f4e..58def2e 100644 +--- a/vendor/nix/src/sys/epoll.rs ++++ b/vendor/nix/src/sys/epoll.rs +@@ -1,10 +1,9 @@ +-use Result; +-use errno::Errno; ++use crate::errno::Errno; ++use crate::Result; + use libc::{self, c_int}; ++use std::mem; + use std::os::unix::io::RawFd; + use std::ptr; +-use std::mem; +-use ::Error; + + libc_bitflags!( + pub struct EpollFlags: c_int { +@@ -19,7 +18,6 @@ libc_bitflags!( + EPOLLERR; + EPOLLHUP; + EPOLLRDHUP; +- #[cfg(target_os = "linux")] // Added in 4.5; not in Android. + EPOLLEXCLUSIVE; + #[cfg(not(target_arch = "mips"))] + EPOLLWAKEUP; +@@ -30,27 +28,33 @@ libc_bitflags!( + + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + #[repr(i32)] ++#[non_exhaustive] + pub enum EpollOp { + EpollCtlAdd = libc::EPOLL_CTL_ADD, + EpollCtlDel = libc::EPOLL_CTL_DEL, + EpollCtlMod = libc::EPOLL_CTL_MOD, + } + +-libc_bitflags!{ ++libc_bitflags! { + pub struct EpollCreateFlags: c_int { + EPOLL_CLOEXEC; + } + } + + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +-#[repr(C)] ++#[repr(transparent)] + pub struct EpollEvent { + event: libc::epoll_event, + } + + impl EpollEvent { + pub fn new(events: EpollFlags, data: u64) -> Self { +- EpollEvent { event: libc::epoll_event { events: events.bits() as u32, u64: data } } ++ EpollEvent { ++ event: libc::epoll_event { ++ events: events.bits() as u32, ++ u64: data, ++ }, ++ } + } + + pub fn empty() -> Self { +@@ -81,12 +85,18 @@ pub fn epoll_create1(flags: EpollCreateFlags) -> Result { + } + + #[inline] +-pub fn epoll_ctl<'a, T>(epfd: RawFd, op: EpollOp, fd: RawFd, event: T) -> Result<()> +- where T: Into> ++pub fn epoll_ctl<'a, T>( ++ epfd: RawFd, ++ op: EpollOp, ++ fd: RawFd, ++ event: T, ++) -> Result<()> ++where ++ T: Into>, + { + let mut event: Option<&mut EpollEvent> = event.into(); + if event.is_none() && op != EpollOp::EpollCtlDel { +- Err(Error::Sys(Errno::EINVAL)) ++ Err(Errno::EINVAL) + } else { + let res = unsafe { + if let Some(ref mut event) = event { +@@ -100,9 +110,18 @@ pub fn epoll_ctl<'a, T>(epfd: RawFd, op: EpollOp, fd: RawFd, event: T) -> Result + } + + #[inline] +-pub fn epoll_wait(epfd: RawFd, events: &mut [EpollEvent], timeout_ms: isize) -> Result { ++pub fn epoll_wait( ++ epfd: RawFd, ++ events: &mut [EpollEvent], ++ timeout_ms: isize, ++) -> Result { + let res = unsafe { +- libc::epoll_wait(epfd, events.as_mut_ptr() as *mut libc::epoll_event, events.len() as c_int, timeout_ms as c_int) ++ libc::epoll_wait( ++ epfd, ++ events.as_mut_ptr() as *mut libc::epoll_event, ++ events.len() as c_int, ++ timeout_ms as c_int, ++ ) + }; + + Errno::result(res).map(|r| r as usize) +diff --git a/vendor/nix/src/sys/event.rs b/vendor/nix/src/sys/event.rs +index 7af5ae2..d8ad628 100644 +--- a/vendor/nix/src/sys/event.rs ++++ b/vendor/nix/src/sys/event.rs +@@ -1,15 +1,15 @@ + /* TOOD: Implement for other kqueue based systems + */ + +-use {Errno, Result}; ++use crate::{Errno, Result}; + #[cfg(not(target_os = "netbsd"))] +-use libc::{timespec, time_t, c_int, c_long, intptr_t, uintptr_t}; ++use libc::{c_int, c_long, intptr_t, time_t, timespec, uintptr_t}; + #[cfg(target_os = "netbsd")] +-use libc::{timespec, time_t, c_long, intptr_t, uintptr_t, size_t}; +-use libc; ++use libc::{c_long, intptr_t, size_t, time_t, timespec, uintptr_t}; ++use std::convert::TryInto; ++use std::mem; + use std::os::unix::io::RawFd; + use std::ptr; +-use std::mem; + + // Redefine kevent in terms of programmer-friendly enums and bitfields. + #[repr(C)] +@@ -18,17 +18,16 @@ pub struct KEvent { + kevent: libc::kevent, + } + +-#[cfg(any(target_os = "dragonfly", target_os = "freebsd", +- target_os = "ios", target_os = "macos", +- target_os = "openbsd"))] ++#[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "openbsd" ++))] + type type_of_udata = *mut libc::c_void; +-#[cfg(any(target_os = "dragonfly", target_os = "freebsd", +- target_os = "ios", target_os = "macos"))] +-type type_of_data = intptr_t; + #[cfg(any(target_os = "netbsd"))] + type type_of_udata = intptr_t; +-#[cfg(any(target_os = "netbsd", target_os = "openbsd"))] +-type type_of_data = libc::int64_t; + + #[cfg(target_os = "netbsd")] + type type_of_event_filter = u32; +@@ -37,6 +36,7 @@ type type_of_event_filter = i16; + libc_enum! { + #[cfg_attr(target_os = "netbsd", repr(u32))] + #[cfg_attr(not(target_os = "netbsd"), repr(i16))] ++ #[non_exhaustive] + pub enum EventFilter { + EVFILT_AIO, + /// Returns whenever there is no remaining data in the write buffer +@@ -76,28 +76,28 @@ libc_enum! { + EVFILT_VNODE, + EVFILT_WRITE, + } ++ impl TryFrom + } + +-#[cfg(any(target_os = "dragonfly", target_os = "freebsd", +- target_os = "ios", target_os = "macos", +- target_os = "openbsd"))] ++#[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "openbsd" ++))] + pub type type_of_event_flag = u16; + #[cfg(any(target_os = "netbsd"))] + pub type type_of_event_flag = u32; +-libc_bitflags!{ ++libc_bitflags! { + pub struct EventFlag: type_of_event_flag { + EV_ADD; + EV_CLEAR; + EV_DELETE; + EV_DISABLE; +- // No released version of OpenBSD supports EV_DISPATCH or EV_RECEIPT. +- // These have been commited to the -current branch though and are +- // expected to be part of the OpenBSD 6.2 release in Nov 2017. +- // See: https://marc.info/?l=openbsd-tech&m=149621427511219&w=2 +- // https://github.com/rust-lang/libc/pull/613 + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "ios", target_os = "macos", +- target_os = "netbsd"))] ++ target_os = "netbsd", target_os = "openbsd"))] + EV_DISPATCH; + #[cfg(target_os = "freebsd")] + EV_DROP; +@@ -116,9 +116,8 @@ libc_bitflags!{ + EV_POLL; + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "ios", target_os = "macos", +- target_os = "netbsd"))] ++ target_os = "netbsd", target_os = "openbsd"))] + EV_RECEIPT; +- EV_SYSFLAGS; + } + } + +@@ -134,10 +133,6 @@ libc_bitflags!( + NOTE_EXEC; + NOTE_EXIT; + #[cfg(any(target_os = "macos", target_os = "ios"))] +- #[deprecated( since="0.14.0", note="Deprecated since OSX 10.9")] +- #[allow(deprecated)] +- NOTE_EXIT_REPARENTED; +- #[cfg(any(target_os = "macos", target_os = "ios"))] + NOTE_EXITSTATUS; + NOTE_EXTEND; + #[cfg(any(target_os = "macos", +@@ -183,11 +178,6 @@ libc_bitflags!( + NOTE_OOB; + NOTE_PCTRLMASK; + NOTE_PDATAMASK; +- #[cfg(any(target_os = "macos", target_os = "ios"))] +- #[cfg(any(target_os = "macos", target_os = "ios"))] +- #[deprecated( since="0.14.0", note="Deprecated since OSX 10.9")] +- #[allow(deprecated)] +- NOTE_REAP; + NOTE_RENAME; + NOTE_REVOKE; + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))] +@@ -223,32 +213,41 @@ pub fn kqueue() -> Result { + Errno::result(res) + } + +- + // KEvent can't derive Send because on some operating systems, udata is defined + // as a void*. However, KEvent's public API always treats udata as an intptr_t, + // which is safe to Send. +-unsafe impl Send for KEvent { +-} ++unsafe impl Send for KEvent {} + + impl KEvent { +- pub fn new(ident: uintptr_t, filter: EventFilter, flags: EventFlag, +- fflags:FilterFlag, data: intptr_t, udata: intptr_t) -> KEvent { +- KEvent { kevent: libc::kevent { +- ident, +- filter: filter as type_of_event_filter, +- flags: flags.bits(), +- fflags: fflags.bits(), +- data: data as type_of_data, +- udata: udata as type_of_udata +- } } ++ #[allow(clippy::needless_update)] // Not needless on all platforms. ++ pub fn new( ++ ident: uintptr_t, ++ filter: EventFilter, ++ flags: EventFlag, ++ fflags: FilterFlag, ++ data: intptr_t, ++ udata: intptr_t, ++ ) -> KEvent { ++ KEvent { ++ kevent: libc::kevent { ++ ident, ++ filter: filter as type_of_event_filter, ++ flags: flags.bits(), ++ fflags: fflags.bits(), ++ // data can be either i64 or intptr_t, depending on platform ++ data: data as _, ++ udata: udata as type_of_udata, ++ ..unsafe { mem::zeroed() } ++ }, ++ } + } + + pub fn ident(&self) -> uintptr_t { + self.kevent.ident + } + +- pub fn filter(&self) -> EventFilter { +- unsafe { mem::transmute(self.kevent.filter as type_of_event_filter) } ++ pub fn filter(&self) -> Result { ++ self.kevent.filter.try_into() + } + + pub fn flags(&self) -> EventFlag { +@@ -268,34 +267,38 @@ impl KEvent { + } + } + +-pub fn kevent(kq: RawFd, +- changelist: &[KEvent], +- eventlist: &mut [KEvent], +- timeout_ms: usize) -> Result { +- ++pub fn kevent( ++ kq: RawFd, ++ changelist: &[KEvent], ++ eventlist: &mut [KEvent], ++ timeout_ms: usize, ++) -> Result { + // Convert ms to timespec + let timeout = timespec { + tv_sec: (timeout_ms / 1000) as time_t, +- tv_nsec: ((timeout_ms % 1000) * 1_000_000) as c_long ++ tv_nsec: ((timeout_ms % 1000) * 1_000_000) as c_long, + }; + + kevent_ts(kq, changelist, eventlist, Some(timeout)) + } + +-#[cfg(any(target_os = "macos", +- target_os = "ios", +- target_os = "freebsd", +- target_os = "dragonfly", +- target_os = "openbsd"))] ++#[cfg(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "openbsd" ++))] + type type_of_nchanges = c_int; + #[cfg(target_os = "netbsd")] + type type_of_nchanges = size_t; + +-pub fn kevent_ts(kq: RawFd, +- changelist: &[KEvent], +- eventlist: &mut [KEvent], +- timeout_opt: Option) -> Result { +- ++pub fn kevent_ts( ++ kq: RawFd, ++ changelist: &[KEvent], ++ eventlist: &mut [KEvent], ++ timeout_opt: Option, ++) -> Result { + let res = unsafe { + libc::kevent( + kq, +@@ -303,43 +306,69 @@ pub fn kevent_ts(kq: RawFd, + changelist.len() as type_of_nchanges, + eventlist.as_mut_ptr() as *mut libc::kevent, + eventlist.len() as type_of_nchanges, +- if let Some(ref timeout) = timeout_opt {timeout as *const timespec} else {ptr::null()}) ++ if let Some(ref timeout) = timeout_opt { ++ timeout as *const timespec ++ } else { ++ ptr::null() ++ }, ++ ) + }; + + Errno::result(res).map(|r| r as usize) + } + + #[inline] +-pub fn ev_set(ev: &mut KEvent, +- ident: usize, +- filter: EventFilter, +- flags: EventFlag, +- fflags: FilterFlag, +- udata: intptr_t) { +- +- ev.kevent.ident = ident as uintptr_t; ++pub fn ev_set( ++ ev: &mut KEvent, ++ ident: usize, ++ filter: EventFilter, ++ flags: EventFlag, ++ fflags: FilterFlag, ++ udata: intptr_t, ++) { ++ ev.kevent.ident = ident as uintptr_t; + ev.kevent.filter = filter as type_of_event_filter; +- ev.kevent.flags = flags.bits(); ++ ev.kevent.flags = flags.bits(); + ev.kevent.fflags = fflags.bits(); +- ev.kevent.data = 0; +- ev.kevent.udata = udata as type_of_udata; ++ ev.kevent.data = 0; ++ ev.kevent.udata = udata as type_of_udata; + } + + #[test] + fn test_struct_kevent() { +- let udata : intptr_t = 12345; ++ use std::mem; + +- let actual = KEvent::new(0xdead_beef, +- EventFilter::EVFILT_READ, +- EventFlag::EV_ONESHOT | EventFlag::EV_ADD, +- FilterFlag::NOTE_CHILD | FilterFlag::NOTE_EXIT, +- 0x1337, +- udata); ++ let udata: intptr_t = 12345; ++ ++ let actual = KEvent::new( ++ 0xdead_beef, ++ EventFilter::EVFILT_READ, ++ EventFlag::EV_ONESHOT | EventFlag::EV_ADD, ++ FilterFlag::NOTE_CHILD | FilterFlag::NOTE_EXIT, ++ 0x1337, ++ udata, ++ ); + assert_eq!(0xdead_beef, actual.ident()); +- assert_eq!(libc::EVFILT_READ, actual.filter() as type_of_event_filter); ++ let filter = actual.kevent.filter; ++ assert_eq!(libc::EVFILT_READ, filter); + assert_eq!(libc::EV_ONESHOT | libc::EV_ADD, actual.flags().bits()); + assert_eq!(libc::NOTE_CHILD | libc::NOTE_EXIT, actual.fflags().bits()); +- assert_eq!(0x1337, actual.data() as type_of_data); ++ assert_eq!(0x1337, actual.data()); + assert_eq!(udata as type_of_udata, actual.udata() as type_of_udata); + assert_eq!(mem::size_of::(), mem::size_of::()); + } ++ ++#[test] ++fn test_kevent_filter() { ++ let udata: intptr_t = 12345; ++ ++ let actual = KEvent::new( ++ 0xdead_beef, ++ EventFilter::EVFILT_READ, ++ EventFlag::EV_ONESHOT | EventFlag::EV_ADD, ++ FilterFlag::NOTE_CHILD | FilterFlag::NOTE_EXIT, ++ 0x1337, ++ udata, ++ ); ++ assert_eq!(EventFilter::EVFILT_READ, actual.filter().unwrap()); ++} +diff --git a/vendor/nix/src/sys/eventfd.rs b/vendor/nix/src/sys/eventfd.rs +index c5a54e4..cd90672 100644 +--- a/vendor/nix/src/sys/eventfd.rs ++++ b/vendor/nix/src/sys/eventfd.rs +@@ -1,7 +1,6 @@ +-use libc; ++use crate::errno::Errno; ++use crate::Result; + use std::os::unix::io::RawFd; +-use Result; +-use errno::Errno; + + libc_bitflags! { + pub struct EfdFlags: libc::c_int { +diff --git a/vendor/nix/src/sys/inotify.rs b/vendor/nix/src/sys/inotify.rs +index e6c2cf6..84356ec 100644 +--- a/vendor/nix/src/sys/inotify.rs ++++ b/vendor/nix/src/sys/inotify.rs +@@ -2,8 +2,8 @@ + //! + //! Inotify is a Linux-only API to monitor filesystems events. + //! +-//! For more documentation, please read [inotify(7)](http://man7.org/linux/man-pages/man7/inotify.7.html). +-//! ++//! For more documentation, please read [inotify(7)](https://man7.org/linux/man-pages/man7/inotify.7.html). ++//! + //! # Examples + //! + //! Monitor all events happening in directory "test": +@@ -23,48 +23,68 @@ + //! } + //! ``` + +-use libc; +-use libc::{ +- c_char, +- c_int, +-}; +-use std::ffi::{OsString,OsStr,CStr}; ++use crate::errno::Errno; ++use crate::unistd::read; ++use crate::NixPath; ++use crate::Result; ++use cfg_if::cfg_if; ++use libc::{c_char, c_int}; ++use std::ffi::{CStr, OsStr, OsString}; ++use std::mem::{size_of, MaybeUninit}; + use std::os::unix::ffi::OsStrExt; +-use std::mem::size_of; +-use std::os::unix::io::{RawFd,AsRawFd,FromRawFd}; +-use unistd::read; +-use Result; +-use NixPath; +-use errno::Errno; ++use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; ++use std::ptr; + + libc_bitflags! { + /// Configuration options for [`inotify_add_watch`](fn.inotify_add_watch.html). + pub struct AddWatchFlags: u32 { ++ /// File was accessed. + IN_ACCESS; ++ /// File was modified. + IN_MODIFY; ++ /// Metadata changed. + IN_ATTRIB; ++ /// Writable file was closed. + IN_CLOSE_WRITE; ++ /// Nonwritable file was closed. + IN_CLOSE_NOWRITE; ++ /// File was opened. + IN_OPEN; ++ /// File was moved from X. + IN_MOVED_FROM; ++ /// File was moved to Y. + IN_MOVED_TO; ++ /// Subfile was created. + IN_CREATE; ++ /// Subfile was deleted. + IN_DELETE; ++ /// Self was deleted. + IN_DELETE_SELF; ++ /// Self was moved. + IN_MOVE_SELF; + ++ /// Backing filesystem was unmounted. + IN_UNMOUNT; ++ /// Event queue overflowed. + IN_Q_OVERFLOW; ++ /// File was ignored. + IN_IGNORED; + ++ /// Combination of `IN_CLOSE_WRITE` and `IN_CLOSE_NOWRITE`. + IN_CLOSE; ++ /// Combination of `IN_MOVED_FROM` and `IN_MOVED_TO`. + IN_MOVE; + ++ /// Only watch the path if it is a directory. + IN_ONLYDIR; ++ /// Don't follow symlinks. + IN_DONT_FOLLOW; + ++ /// Event occurred against directory. + IN_ISDIR; ++ /// Only send event once. + IN_ONESHOT; ++ /// All of the events. + IN_ALL_EVENTS; + } + } +@@ -72,7 +92,9 @@ libc_bitflags! { + libc_bitflags! { + /// Configuration options for [`inotify_init1`](fn.inotify_init1.html). + pub struct InitFlags: c_int { ++ /// Set the `FD_CLOEXEC` flag on the file descriptor. + IN_CLOEXEC; ++ /// Set the `O_NONBLOCK` flag on the open file description referred to by the new file descriptor. + IN_NONBLOCK; + } + } +@@ -81,35 +103,35 @@ libc_bitflags! { + /// other interfaces consuming file descriptors, epoll for example. + #[derive(Debug, Clone, Copy)] + pub struct Inotify { +- fd: RawFd ++ fd: RawFd, + } + + /// This object is returned when you create a new watch on an inotify instance. + /// It is then returned as part of an event once triggered. It allows you to +-/// know which watch triggered which event. ++/// know which watch triggered which event. + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd)] + pub struct WatchDescriptor { +- wd: i32 ++ wd: i32, + } + + /// A single inotify event. + /// +-/// For more documentation see, [inotify(7)](http://man7.org/linux/man-pages/man7/inotify.7.html). ++/// For more documentation see, [inotify(7)](https://man7.org/linux/man-pages/man7/inotify.7.html). + #[derive(Debug)] + pub struct InotifyEvent { + /// Watch descriptor. This field corresponds to the watch descriptor you + /// were issued when calling add_watch. It allows you to know which watch +- /// this event comes from. ++ /// this event comes from. + pub wd: WatchDescriptor, + /// Event mask. This field is a bitfield describing the exact event that + /// occured. + pub mask: AddWatchFlags, + /// This cookie is a number that allows you to connect related events. For +- /// now only IN_MOVED_FROM and IN_MOVED_TO can be connected. ++ /// now only IN_MOVED_FROM and IN_MOVED_TO can be connected. + pub cookie: u32, + /// Filename. This field exists only if the event was triggered for a file + /// inside the watched directory. +- pub name: Option ++ pub name: Option, + } + + impl Inotify { +@@ -117,29 +139,25 @@ impl Inotify { + /// + /// Returns a Result containing an inotify instance. + /// +- /// For more information see, [inotify_init(2)](http://man7.org/linux/man-pages/man2/inotify_init.2.html). ++ /// For more information see, [inotify_init(2)](https://man7.org/linux/man-pages/man2/inotify_init.2.html). + pub fn init(flags: InitFlags) -> Result { +- let res = Errno::result(unsafe { +- libc::inotify_init1(flags.bits()) +- }); ++ let res = Errno::result(unsafe { libc::inotify_init1(flags.bits()) }); + + res.map(|fd| Inotify { fd }) + } + +- /// Adds a new watch on the target file or directory. ++ /// Adds a new watch on the target file or directory. + /// +- /// Returns a watch descriptor. This is not a File Descriptor! ++ /// Returns a watch descriptor. This is not a File Descriptor! + /// +- /// For more information see, [inotify_add_watch(2)](http://man7.org/linux/man-pages/man2/inotify_add_watch.2.html). +- pub fn add_watch(&self, +- path: &P, +- mask: AddWatchFlags) +- -> Result +- { +- let res = path.with_nix_path(|cstr| { +- unsafe { +- libc::inotify_add_watch(self.fd, cstr.as_ptr(), mask.bits()) +- } ++ /// For more information see, [inotify_add_watch(2)](https://man7.org/linux/man-pages/man2/inotify_add_watch.2.html). ++ pub fn add_watch( ++ self, ++ path: &P, ++ mask: AddWatchFlags, ++ ) -> Result { ++ let res = path.with_nix_path(|cstr| unsafe { ++ libc::inotify_add_watch(self.fd, cstr.as_ptr(), mask.bits()) + })?; + + Errno::result(res).map(|wd| WatchDescriptor { wd }) +@@ -150,30 +168,30 @@ impl Inotify { + /// + /// Returns an EINVAL error if the watch descriptor is invalid. + /// +- /// For more information see, [inotify_rm_watch(2)](http://man7.org/linux/man-pages/man2/inotify_rm_watch.2.html). +- #[cfg(target_os = "linux")] +- pub fn rm_watch(&self, wd: WatchDescriptor) -> Result<()> { +- let res = unsafe { libc::inotify_rm_watch(self.fd, wd.wd) }; +- +- Errno::result(res).map(drop) +- } +- +- #[cfg(target_os = "android")] +- pub fn rm_watch(&self, wd: WatchDescriptor) -> Result<()> { +- let res = unsafe { libc::inotify_rm_watch(self.fd, wd.wd as u32) }; ++ /// For more information see, [inotify_rm_watch(2)](https://man7.org/linux/man-pages/man2/inotify_rm_watch.2.html). ++ pub fn rm_watch(self, wd: WatchDescriptor) -> Result<()> { ++ cfg_if! { ++ if #[cfg(target_os = "linux")] { ++ let arg = wd.wd; ++ } else if #[cfg(target_os = "android")] { ++ let arg = wd.wd as u32; ++ } ++ } ++ let res = unsafe { libc::inotify_rm_watch(self.fd, arg) }; + + Errno::result(res).map(drop) + } + + /// Reads a collection of events from the inotify file descriptor. This call + /// can either be blocking or non blocking depending on whether IN_NONBLOCK +- /// was set at initialization. +- /// ++ /// was set at initialization. ++ /// + /// Returns as many events as available. If the call was non blocking and no + /// events could be read then the EAGAIN error is returned. +- pub fn read_events(&self) -> Result> { ++ pub fn read_events(self) -> Result> { + let header_size = size_of::(); +- let mut buffer = [0u8; 4096]; ++ const BUFSIZ: usize = 4096; ++ let mut buffer = [0u8; BUFSIZ]; + let mut events = Vec::new(); + let mut offset = 0; + +@@ -181,24 +199,24 @@ impl Inotify { + + while (nread - offset) >= header_size { + let event = unsafe { +- &*( +- buffer +- .as_ptr() +- .offset(offset as isize) as *const libc::inotify_event +- ) ++ let mut event = MaybeUninit::::uninit(); ++ ptr::copy_nonoverlapping( ++ buffer.as_ptr().add(offset), ++ event.as_mut_ptr() as *mut u8, ++ (BUFSIZ - offset).min(header_size), ++ ); ++ event.assume_init() + }; + + let name = match event.len { + 0 => None, + _ => { +- let ptr = unsafe { +- buffer +- .as_ptr() +- .offset(offset as isize + header_size as isize) ++ let ptr = unsafe { ++ buffer.as_ptr().add(offset + header_size) + as *const c_char + }; + let cstr = unsafe { CStr::from_ptr(ptr) }; +- ++ + Some(OsStr::from_bytes(cstr.to_bytes()).to_owned()) + } + }; +@@ -207,7 +225,7 @@ impl Inotify { + wd: WatchDescriptor { wd: event.wd }, + mask: AddWatchFlags::from_bits_truncate(event.mask), + cookie: event.cookie, +- name ++ name, + }); + + offset += header_size + event.len as usize; +diff --git a/vendor/nix/src/sys/ioctl/bsd.rs b/vendor/nix/src/sys/ioctl/bsd.rs +index 9b8b0ff..307994c 100644 +--- a/vendor/nix/src/sys/ioctl/bsd.rs ++++ b/vendor/nix/src/sys/ioctl/bsd.rs +@@ -1,20 +1,27 @@ + /// The datatype used for the ioctl number + #[doc(hidden)] ++#[cfg(not(target_os = "illumos"))] + pub type ioctl_num_type = ::libc::c_ulong; ++ ++#[doc(hidden)] ++#[cfg(target_os = "illumos")] ++pub type ioctl_num_type = ::libc::c_int; ++ + /// The datatype used for the 3rd argument + #[doc(hidden)] + pub type ioctl_param_type = ::libc::c_int; + + mod consts { +- use ::sys::ioctl::ioctl_num_type; ++ use crate::sys::ioctl::ioctl_num_type; + #[doc(hidden)] + pub const VOID: ioctl_num_type = 0x2000_0000; + #[doc(hidden)] + pub const OUT: ioctl_num_type = 0x4000_0000; + #[doc(hidden)] ++ #[allow(overflowing_literals)] + pub const IN: ioctl_num_type = 0x8000_0000; + #[doc(hidden)] +- pub const INOUT: ioctl_num_type = (IN|OUT); ++ pub const INOUT: ioctl_num_type = IN | OUT; + #[doc(hidden)] + pub const IOCPARM_MASK: ioctl_num_type = 0x1fff; + } +@@ -24,9 +31,14 @@ pub use self::consts::*; + #[macro_export] + #[doc(hidden)] + macro_rules! ioc { +- ($inout:expr, $group:expr, $num:expr, $len:expr) => ( +- $inout | (($len as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::IOCPARM_MASK) << 16) | (($group as $crate::sys::ioctl::ioctl_num_type) << 8) | ($num as $crate::sys::ioctl::ioctl_num_type) +- ) ++ ($inout:expr, $group:expr, $num:expr, $len:expr) => { ++ $inout ++ | (($len as $crate::sys::ioctl::ioctl_num_type ++ & $crate::sys::ioctl::IOCPARM_MASK) ++ << 16) ++ | (($group as $crate::sys::ioctl::ioctl_num_type) << 8) ++ | ($num as $crate::sys::ioctl::ioctl_num_type) ++ }; + } + + /// Generate an ioctl request code for a command that passes no data. +@@ -46,7 +58,9 @@ macro_rules! ioc { + /// ``` + #[macro_export(local_inner_macros)] + macro_rules! request_code_none { +- ($g:expr, $n:expr) => (ioc!($crate::sys::ioctl::VOID, $g, $n, 0)) ++ ($g:expr, $n:expr) => { ++ ioc!($crate::sys::ioctl::VOID, $g, $n, 0) ++ }; + } + + /// Generate an ioctl request code for a command that passes an integer +@@ -57,7 +71,14 @@ macro_rules! request_code_none { + /// with is "bad" and you cannot use `ioctl_write_int!()` directly. + #[macro_export(local_inner_macros)] + macro_rules! request_code_write_int { +- ($g:expr, $n:expr) => (ioc!($crate::sys::ioctl::VOID, $g, $n, ::std::mem::size_of::<$crate::libc::c_int>())) ++ ($g:expr, $n:expr) => { ++ ioc!( ++ $crate::sys::ioctl::VOID, ++ $g, ++ $n, ++ ::std::mem::size_of::<$crate::libc::c_int>() ++ ) ++ }; + } + + /// Generate an ioctl request code for a command that reads. +@@ -72,7 +93,9 @@ macro_rules! request_code_write_int { + /// writing. + #[macro_export(local_inner_macros)] + macro_rules! request_code_read { +- ($g:expr, $n:expr, $len:expr) => (ioc!($crate::sys::ioctl::OUT, $g, $n, $len)) ++ ($g:expr, $n:expr, $len:expr) => { ++ ioc!($crate::sys::ioctl::OUT, $g, $n, $len) ++ }; + } + + /// Generate an ioctl request code for a command that writes. +@@ -87,7 +110,9 @@ macro_rules! request_code_read { + /// reading. + #[macro_export(local_inner_macros)] + macro_rules! request_code_write { +- ($g:expr, $n:expr, $len:expr) => (ioc!($crate::sys::ioctl::IN, $g, $n, $len)) ++ ($g:expr, $n:expr, $len:expr) => { ++ ioc!($crate::sys::ioctl::IN, $g, $n, $len) ++ }; + } + + /// Generate an ioctl request code for a command that reads and writes. +@@ -98,5 +123,7 @@ macro_rules! request_code_write { + /// with is "bad" and you cannot use `ioctl_readwrite!()` directly. + #[macro_export(local_inner_macros)] + macro_rules! request_code_readwrite { +- ($g:expr, $n:expr, $len:expr) => (ioc!($crate::sys::ioctl::INOUT, $g, $n, $len)) ++ ($g:expr, $n:expr, $len:expr) => { ++ ioc!($crate::sys::ioctl::INOUT, $g, $n, $len) ++ }; + } +diff --git a/vendor/nix/src/sys/ioctl/linux.rs b/vendor/nix/src/sys/ioctl/linux.rs +index 68ebaba..0c0a209 100644 +--- a/vendor/nix/src/sys/ioctl/linux.rs ++++ b/vendor/nix/src/sys/ioctl/linux.rs +@@ -14,7 +14,13 @@ pub const NRBITS: ioctl_num_type = 8; + #[doc(hidden)] + pub const TYPEBITS: ioctl_num_type = 8; + +-#[cfg(any(target_arch = "mips", target_arch = "mips64", target_arch = "powerpc", target_arch = "powerpc64", target_arch = "sparc64"))] ++#[cfg(any( ++ target_arch = "mips", ++ target_arch = "mips64", ++ target_arch = "powerpc", ++ target_arch = "powerpc64", ++ target_arch = "sparc64" ++))] + mod consts { + #[doc(hidden)] + pub const NONE: u8 = 1; +@@ -29,12 +35,15 @@ mod consts { + } + + // "Generic" ioctl protocol +-#[cfg(any(target_arch = "x86", +- target_arch = "arm", +- target_arch = "s390x", +- target_arch = "x86_64", +- target_arch = "aarch64", +- target_arch = "riscv64"))] ++#[cfg(any( ++ target_arch = "x86", ++ target_arch = "arm", ++ target_arch = "s390x", ++ target_arch = "x86_64", ++ target_arch = "aarch64", ++ target_arch = "riscv32", ++ target_arch = "riscv64" ++))] + mod consts { + #[doc(hidden)] + pub const NONE: u8 = 0; +@@ -72,11 +81,20 @@ pub const DIRMASK: ioctl_num_type = (1 << DIRBITS) - 1; + #[macro_export] + #[doc(hidden)] + macro_rules! ioc { +- ($dir:expr, $ty:expr, $nr:expr, $sz:expr) => ( +- (($dir as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::DIRMASK) << $crate::sys::ioctl::DIRSHIFT) | +- (($ty as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::TYPEMASK) << $crate::sys::ioctl::TYPESHIFT) | +- (($nr as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::NRMASK) << $crate::sys::ioctl::NRSHIFT) | +- (($sz as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::SIZEMASK) << $crate::sys::ioctl::SIZESHIFT)) ++ ($dir:expr, $ty:expr, $nr:expr, $sz:expr) => { ++ (($dir as $crate::sys::ioctl::ioctl_num_type ++ & $crate::sys::ioctl::DIRMASK) ++ << $crate::sys::ioctl::DIRSHIFT) ++ | (($ty as $crate::sys::ioctl::ioctl_num_type ++ & $crate::sys::ioctl::TYPEMASK) ++ << $crate::sys::ioctl::TYPESHIFT) ++ | (($nr as $crate::sys::ioctl::ioctl_num_type ++ & $crate::sys::ioctl::NRMASK) ++ << $crate::sys::ioctl::NRSHIFT) ++ | (($sz as $crate::sys::ioctl::ioctl_num_type ++ & $crate::sys::ioctl::SIZEMASK) ++ << $crate::sys::ioctl::SIZESHIFT) ++ }; + } + + /// Generate an ioctl request code for a command that passes no data. +@@ -96,7 +114,9 @@ macro_rules! ioc { + /// ``` + #[macro_export(local_inner_macros)] + macro_rules! request_code_none { +- ($ty:expr, $nr:expr) => (ioc!($crate::sys::ioctl::NONE, $ty, $nr, 0)) ++ ($ty:expr, $nr:expr) => { ++ ioc!($crate::sys::ioctl::NONE, $ty, $nr, 0) ++ }; + } + + /// Generate an ioctl request code for a command that reads. +@@ -111,7 +131,9 @@ macro_rules! request_code_none { + /// writing. + #[macro_export(local_inner_macros)] + macro_rules! request_code_read { +- ($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::READ, $ty, $nr, $sz)) ++ ($ty:expr, $nr:expr, $sz:expr) => { ++ ioc!($crate::sys::ioctl::READ, $ty, $nr, $sz) ++ }; + } + + /// Generate an ioctl request code for a command that writes. +@@ -126,7 +148,9 @@ macro_rules! request_code_read { + /// reading. + #[macro_export(local_inner_macros)] + macro_rules! request_code_write { +- ($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::WRITE, $ty, $nr, $sz)) ++ ($ty:expr, $nr:expr, $sz:expr) => { ++ ioc!($crate::sys::ioctl::WRITE, $ty, $nr, $sz) ++ }; + } + + /// Generate an ioctl request code for a command that reads and writes. +@@ -137,5 +161,12 @@ macro_rules! request_code_write { + /// with is "bad" and you cannot use `ioctl_readwrite!()` directly. + #[macro_export(local_inner_macros)] + macro_rules! request_code_readwrite { +- ($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::READ | $crate::sys::ioctl::WRITE, $ty, $nr, $sz)) ++ ($ty:expr, $nr:expr, $sz:expr) => { ++ ioc!( ++ $crate::sys::ioctl::READ | $crate::sys::ioctl::WRITE, ++ $ty, ++ $nr, ++ $sz ++ ) ++ }; + } +diff --git a/vendor/nix/src/sys/ioctl/mod.rs b/vendor/nix/src/sys/ioctl/mod.rs +index 2837233..98d6b5c 100644 +--- a/vendor/nix/src/sys/ioctl/mod.rs ++++ b/vendor/nix/src/sys/ioctl/mod.rs +@@ -29,7 +29,7 @@ + //! Historically `ioctl` numbers were arbitrary hard-coded values. In Linux (before 2.6) and some + //! unices this has changed to a more-ordered system where the ioctl numbers are partitioned into + //! subcomponents (For linux this is documented in +-//! [`Documentation/ioctl/ioctl-number.rst`](http://elixir.free-electrons.com/linux/latest/source/Documentation/ioctl/ioctl-number.rst)): ++//! [`Documentation/ioctl/ioctl-number.rst`](https://elixir.bootlin.com/linux/latest/source/Documentation/userspace-api/ioctl/ioctl-number.rst)): + //! + //! * Number: The actual ioctl ID + //! * Type: A grouping of ioctls for a common purpose or driver +@@ -104,7 +104,7 @@ + //! respectively. To determine the specific `write_` variant to use you'll need to find + //! what the argument type is supposed to be. If it's an `int`, then `write_int` should be used, + //! otherwise it should be a pointer and `write_ptr` should be used. On Linux the +-//! [`ioctl_list` man page](http://man7.org/linux/man-pages/man2/ioctl_list.2.html) describes a ++//! [`ioctl_list` man page](https://man7.org/linux/man-pages/man2/ioctl_list.2.html) describes a + //! large number of `ioctl`s and describes their argument data type. + //! + //! Using "bad" `ioctl`s +@@ -221,39 +221,51 @@ + //! + //! # fn main() {} + //! ``` +-#[cfg(any(target_os = "android", target_os = "linux"))] ++use cfg_if::cfg_if; ++ ++#[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))] + #[macro_use] + mod linux; + +-#[cfg(any(target_os = "android", target_os = "linux"))] ++#[cfg(any( ++ target_os = "android", ++ target_os = "linux", ++ target_os = "redox" ++))] + pub use self::linux::*; + +-#[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++#[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "illumos", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "haiku", ++ target_os = "openbsd" ++))] + #[macro_use] + mod bsd; + +-#[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++#[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "illumos", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "haiku", ++ target_os = "openbsd" ++))] + pub use self::bsd::*; + + /// Convert raw ioctl return value to a Nix result + #[macro_export] + #[doc(hidden)] + macro_rules! convert_ioctl_res { +- ($w:expr) => ( +- { +- $crate::errno::Errno::result($w) +- } +- ); ++ ($w:expr) => {{ ++ $crate::errno::Errno::result($w) ++ }}; + } + + /// Generates a wrapper function for an ioctl that passes no data to the kernel. +@@ -317,7 +329,6 @@ macro_rules! ioctl_none { + /// + /// ```no_run + /// # #[macro_use] extern crate nix; +-/// # extern crate libc; + /// # use libc::TIOCNXCL; + /// # use std::fs::File; + /// # use std::os::unix::io::AsRawFd; +@@ -396,7 +407,6 @@ macro_rules! ioctl_read { + /// # Example + /// + /// ``` +-/// # extern crate libc; + /// # #[macro_use] extern crate nix; + /// # #[cfg(any(target_os = "android", target_os = "linux"))] + /// ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios); +@@ -470,7 +480,6 @@ macro_rules! ioctl_write_ptr { + /// # Example + /// + /// ``` +-/// # extern crate libc; + /// # #[macro_use] extern crate nix; + /// # #[cfg(any(target_os = "android", target_os = "linux"))] + /// ioctl_write_ptr_bad!(tcsets, libc::TCSETS, libc::termios); +@@ -488,7 +497,7 @@ macro_rules! ioctl_write_ptr_bad { + ) + } + +-cfg_if!{ ++cfg_if! { + if #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] { + /// Generates a wrapper function for a ioctl that writes an integer to the kernel. + /// +@@ -590,7 +599,6 @@ cfg_if!{ + /// # Examples + /// + /// ``` +-/// # extern crate libc; + /// # #[macro_use] extern crate nix; + /// # #[cfg(any(target_os = "android", target_os = "linux"))] + /// ioctl_write_int_bad!(tcsbrk, libc::TCSBRK); +diff --git a/vendor/nix/src/sys/memfd.rs b/vendor/nix/src/sys/memfd.rs +index 9672429..ad9345e 100644 +--- a/vendor/nix/src/sys/memfd.rs ++++ b/vendor/nix/src/sys/memfd.rs +@@ -1,19 +1,63 @@ +-use libc; ++//! Interfaces for managing memory-backed files. ++ ++use cfg_if::cfg_if; + use std::os::unix::io::RawFd; +-use Result; +-use errno::Errno; ++ ++use crate::errno::Errno; ++use crate::Result; + use std::ffi::CStr; + + libc_bitflags!( ++ /// Options that change the behavior of [`memfd_create`]. + pub struct MemFdCreateFlag: libc::c_uint { ++ /// Set the close-on-exec ([`FD_CLOEXEC`]) flag on the new file descriptor. ++ /// ++ /// By default, the new file descriptor is set to remain open across an [`execve`] ++ /// (the `FD_CLOEXEC` flag is initially disabled). This flag can be used to change ++ /// this default. The file offset is set to the beginning of the file (see [`lseek`]). ++ /// ++ /// See also the description of the `O_CLOEXEC` flag in [`open(2)`]. ++ /// ++ /// [`execve`]: crate::unistd::execve ++ /// [`lseek`]: crate::unistd::lseek ++ /// [`FD_CLOEXEC`]: crate::fcntl::FdFlag::FD_CLOEXEC ++ /// [`open(2)`]: https://man7.org/linux/man-pages/man2/open.2.html + MFD_CLOEXEC; ++ /// Allow sealing operations on this file. ++ /// ++ /// See also the file sealing notes given in [`memfd_create(2)`]. ++ /// ++ /// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html + MFD_ALLOW_SEALING; + } + ); + ++/// Creates an anonymous file that lives in memory, and return a file-descriptor to it. ++/// ++/// The file behaves like a regular file, and so can be modified, truncated, memory-mapped, and so on. ++/// However, unlike a regular file, it lives in RAM and has a volatile backing storage. ++/// ++/// For more information, see [`memfd_create(2)`]. ++/// ++/// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html + pub fn memfd_create(name: &CStr, flags: MemFdCreateFlag) -> Result { + let res = unsafe { +- libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags.bits()) ++ cfg_if! { ++ if #[cfg(all( ++ // Android does not have a memfd_create symbol ++ not(target_os = "android"), ++ any( ++ target_os = "freebsd", ++ // If the OS is Linux, gnu and musl expose a memfd_create symbol but not uclibc ++ target_env = "gnu", ++ target_env = "musl", ++ )))] ++ { ++ libc::memfd_create(name.as_ptr(), flags.bits()) ++ } else { ++ libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags.bits()) ++ } ++ } + }; + + Errno::result(res).map(|r| r as RawFd) +diff --git a/vendor/nix/src/sys/mman.rs b/vendor/nix/src/sys/mman.rs +index 4e25050..2bee091 100644 +--- a/vendor/nix/src/sys/mman.rs ++++ b/vendor/nix/src/sys/mman.rs +@@ -1,15 +1,16 @@ +-use {Error, Result}; +-#[cfg(not(target_os = "android"))] +-use NixPath; +-use errno::Errno; ++//! Memory management declarations. ++ ++use crate::errno::Errno; + #[cfg(not(target_os = "android"))] +-use fcntl::OFlag; +-use libc::{self, c_int, c_void, size_t, off_t}; ++use crate::NixPath; ++use crate::Result; + #[cfg(not(target_os = "android"))] +-use sys::stat::Mode; +-use std::os::unix::io::RawFd; ++#[cfg(feature = "fs")] ++use crate::{fcntl::OFlag, sys::stat::Mode}; ++use libc::{self, c_int, c_void, off_t, size_t}; ++use std::{os::unix::io::RawFd, num::NonZeroUsize}; + +-libc_bitflags!{ ++libc_bitflags! { + /// Desired memory protection of a memory mapping. + pub struct ProtFlags: c_int { + /// Pages cannot be accessed. +@@ -22,15 +23,17 @@ libc_bitflags!{ + PROT_EXEC; + /// Apply protection up to the end of a mapping that grows upwards. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + PROT_GROWSDOWN; + /// Apply protection down to the beginning of a mapping that grows downwards. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + PROT_GROWSUP; + } + } + +-libc_bitflags!{ +- /// Additional parameters for `mmap()`. ++libc_bitflags! { ++ /// Additional parameters for [`mmap`]. + pub struct MapFlags: c_int { + /// Compatibility flag. Ignored. + MAP_FILE; +@@ -40,73 +43,179 @@ libc_bitflags!{ + MAP_PRIVATE; + /// Place the mapping at exactly the address specified in `addr`. + MAP_FIXED; ++ /// Place the mapping at exactly the address specified in `addr`, but never clobber an existing range. ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_FIXED_NOREPLACE; ++ /// To be used with `MAP_FIXED`, to forbid the system ++ /// to select a different address than the one specified. ++ #[cfg(target_os = "freebsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_EXCL; + /// Synonym for `MAP_ANONYMOUS`. + MAP_ANON; + /// The mapping is not backed by any file. +- #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))] + MAP_ANONYMOUS; + /// Put the mapping into the first 2GB of the process address space. + #[cfg(any(all(any(target_os = "android", target_os = "linux"), + any(target_arch = "x86", target_arch = "x86_64")), + all(target_os = "linux", target_env = "musl", any(target_arch = "x86", target_arch = "x86_64")), + all(target_os = "freebsd", target_pointer_width = "64")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_32BIT; + /// Used for stacks; indicates to the kernel that the mapping should extend downward in memory. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_GROWSDOWN; + /// Compatibility flag. Ignored. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_DENYWRITE; + /// Compatibility flag. Ignored. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_EXECUTABLE; + /// Mark the mmaped region to be locked in the same way as `mlock(2)`. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_LOCKED; + /// Do not reserve swap space for this mapping. + /// +- /// This was removed in FreeBSD 11. +- #[cfg(not(target_os = "freebsd"))] ++ /// This was removed in FreeBSD 11 and is unused in DragonFlyBSD. ++ #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_NORESERVE; + /// Populate page tables for a mapping. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_POPULATE; + /// Only meaningful when used with `MAP_POPULATE`. Don't perform read-ahead. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_NONBLOCK; + /// Allocate the mapping using "huge pages." + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_HUGETLB; ++ /// Make use of 64KB huge page (must be supported by the system) ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_HUGE_64KB; ++ /// Make use of 512KB huge page (must be supported by the system) ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_HUGE_512KB; ++ /// Make use of 1MB huge page (must be supported by the system) ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_HUGE_1MB; ++ /// Make use of 2MB huge page (must be supported by the system) ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_HUGE_2MB; ++ /// Make use of 8MB huge page (must be supported by the system) ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_HUGE_8MB; ++ /// Make use of 16MB huge page (must be supported by the system) ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_HUGE_16MB; ++ /// Make use of 32MB huge page (must be supported by the system) ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_HUGE_32MB; ++ /// Make use of 256MB huge page (must be supported by the system) ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_HUGE_256MB; ++ /// Make use of 512MB huge page (must be supported by the system) ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_HUGE_512MB; ++ /// Make use of 1GB huge page (must be supported by the system) ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_HUGE_1GB; ++ /// Make use of 2GB huge page (must be supported by the system) ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_HUGE_2GB; ++ /// Make use of 16GB huge page (must be supported by the system) ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_HUGE_16GB; ++ + /// Lock the mapped region into memory as with `mlock(2)`. + #[cfg(target_os = "netbsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_WIRED; + /// Causes dirtied data in the specified range to be flushed to disk only when necessary. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_NOSYNC; + /// Rename private pages to a file. + /// +- /// This was removed in FreeBSD 11. +- #[cfg(any(target_os = "dragonfly", target_os = "netbsd", target_os = "openbsd"))] ++ /// This was removed in FreeBSD 11 and is unused in DragonFlyBSD. ++ #[cfg(any(target_os = "netbsd", target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_RENAME; + /// Region may contain semaphores. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_HASSEMAPHORE; + /// Region grows down, like a stack. +- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))] ++ #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux", target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_STACK; + /// Pages in this mapping are not retained in the kernel's memory cache. + #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_NOCACHE; ++ /// Allows the W/X bit on the page, it's necessary on aarch64 architecture. + #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MAP_JIT; ++ /// Allows to use large pages, underlying alignment based on size. ++ #[cfg(target_os = "freebsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_ALIGNED_SUPER; ++ /// Pages will be discarded in the core dumps. ++ #[cfg(target_os = "openbsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_CONCEAL; ++ } ++} ++ ++#[cfg(any(target_os = "linux", target_os = "netbsd"))] ++libc_bitflags! { ++ /// Options for [`mremap`]. ++ pub struct MRemapFlags: c_int { ++ /// Permit the kernel to relocate the mapping to a new virtual address, if necessary. ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MREMAP_MAYMOVE; ++ /// Place the mapping at exactly the address specified in `new_address`. ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MREMAP_FIXED; ++ /// Place the mapping at exactly the address specified in `new_address`. ++ #[cfg(target_os = "netbsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_FIXED; ++ /// Allows to duplicate the mapping to be able to apply different flags on the copy. ++ #[cfg(target_os = "netbsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ MAP_REMAPDUP; + } + } + +-libc_enum!{ ++libc_enum! { + /// Usage information for a range of memory to allow for performance optimizations by the kernel. + /// +- /// Used by [`madvise`](./fn.madvise.html). ++ /// Used by [`madvise`]. + #[repr(i32)] ++ #[non_exhaustive] + pub enum MmapAdvise { + /// No further special treatment. This is the default. + MADV_NORMAL, +@@ -120,30 +229,37 @@ libc_enum!{ + MADV_DONTNEED, + /// Free up a given range of pages and its associated backing store. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_REMOVE, + /// Do not make pages in this range available to the child after a `fork(2)`. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_DONTFORK, + /// Undo the effect of `MADV_DONTFORK`. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_DOFORK, + /// Poison the given pages. + /// + /// Subsequent references to those pages are treated like hardware memory corruption. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_HWPOISON, + /// Enable Kernel Samepage Merging (KSM) for the given pages. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_MERGEABLE, + /// Undo the effect of `MADV_MERGEABLE` + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_UNMERGEABLE, + /// Preserve the memory of each page but offline the original page. + #[cfg(any(target_os = "android", + all(target_os = "linux", any( + target_arch = "aarch64", + target_arch = "arm", +- target_arch = "ppc", ++ target_arch = "powerpc", ++ target_arch = "powerpc64", + target_arch = "s390x", + target_arch = "x86", + target_arch = "x86_64", +@@ -151,52 +267,72 @@ libc_enum!{ + MADV_SOFT_OFFLINE, + /// Enable Transparent Huge Pages (THP) for pages in the given range. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_HUGEPAGE, + /// Undo the effect of `MADV_HUGEPAGE`. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_NOHUGEPAGE, + /// Exclude the given range from a core dump. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_DONTDUMP, + /// Undo the effect of an earlier `MADV_DONTDUMP`. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_DODUMP, + /// Specify that the application no longer needs the pages in the given range. + MADV_FREE, + /// Request that the system not flush the current range to disk unless it needs to. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_NOSYNC, + /// Undoes the effects of `MADV_NOSYNC` for any future pages dirtied within the given range. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_AUTOSYNC, + /// Region is not included in a core file. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_NOCORE, + /// Include region in a core file + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_CORE, ++ /// This process should not be killed when swap space is exhausted. + #[cfg(any(target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_PROTECT, + /// Invalidate the hardware page table for the given region. + #[cfg(target_os = "dragonfly")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_INVAL, + /// Set the offset of the page directory page to `value` for the virtual page table. + #[cfg(target_os = "dragonfly")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_SETMAP, + /// Indicates that the application will not need the data in the given range. + #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_ZERO_WIRED_PAGES, ++ /// Pages can be reused (by anyone). + #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_FREE_REUSABLE, ++ /// Caller wants to reuse those pages. + #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MADV_FREE_REUSE, ++ // Darwin doesn't document this flag's behavior. + #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ #[allow(missing_docs)] + MADV_CAN_REUSE, + } + } + +-libc_bitflags!{ +- /// Configuration flags for `msync`. ++libc_bitflags! { ++ /// Configuration flags for [`msync`]. + pub struct MsFlags: c_int { + /// Schedule an update but return immediately. + MS_ASYNC; +@@ -204,17 +340,20 @@ libc_bitflags!{ + MS_INVALIDATE; + /// Invalidate pages, but leave them mapped. + #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MS_KILLPAGES; + /// Deactivate pages, but leave them mapped. + #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MS_DEACTIVATE; + /// Perform an update and wait for it to complete. + MS_SYNC; + } + } + +-libc_bitflags!{ +- /// Flags for `mlockall`. ++#[cfg(not(target_os = "haiku"))] ++libc_bitflags! { ++ /// Flags for [`mlockall`]. + pub struct MlockAllFlags: c_int { + /// Lock pages that are currently mapped into the address space of the process. + MCL_CURRENT; +@@ -223,52 +362,152 @@ libc_bitflags!{ + } + } + +-/// Locks all memory pages that contain part of the address range with `length` bytes starting at +-/// `addr`. Locked pages never move to the swap area. ++/// Locks all memory pages that contain part of the address range with `length` ++/// bytes starting at `addr`. ++/// ++/// Locked pages never move to the swap area. ++/// ++/// # Safety ++/// ++/// `addr` must meet all the requirements described in the [`mlock(2)`] man page. ++/// ++/// [`mlock(2)`]: https://man7.org/linux/man-pages/man2/mlock.2.html + pub unsafe fn mlock(addr: *const c_void, length: size_t) -> Result<()> { + Errno::result(libc::mlock(addr, length)).map(drop) + } + +-/// Unlocks all memory pages that contain part of the address range with `length` bytes starting at +-/// `addr`. ++/// Unlocks all memory pages that contain part of the address range with ++/// `length` bytes starting at `addr`. ++/// ++/// # Safety ++/// ++/// `addr` must meet all the requirements described in the [`munlock(2)`] man ++/// page. ++/// ++/// [`munlock(2)`]: https://man7.org/linux/man-pages/man2/munlock.2.html + pub unsafe fn munlock(addr: *const c_void, length: size_t) -> Result<()> { + Errno::result(libc::munlock(addr, length)).map(drop) + } + +-/// Locks all memory pages mapped into this process' address space. Locked pages never move to the +-/// swap area. ++/// Locks all memory pages mapped into this process' address space. ++/// ++/// Locked pages never move to the swap area. For more information, see [`mlockall(2)`]. ++/// ++/// [`mlockall(2)`]: https://man7.org/linux/man-pages/man2/mlockall.2.html ++#[cfg(not(target_os = "haiku"))] + pub fn mlockall(flags: MlockAllFlags) -> Result<()> { + unsafe { Errno::result(libc::mlockall(flags.bits())) }.map(drop) + } + + /// Unlocks all memory pages mapped into this process' address space. ++/// ++/// For more information, see [`munlockall(2)`]. ++/// ++/// [`munlockall(2)`]: https://man7.org/linux/man-pages/man2/munlockall.2.html ++#[cfg(not(target_os = "haiku"))] + pub fn munlockall() -> Result<()> { + unsafe { Errno::result(libc::munlockall()) }.map(drop) + } + +-/// Calls to mmap are inherently unsafe, so they must be made in an unsafe block. Typically +-/// a higher-level abstraction will hide the unsafe interactions with the mmap'd region. +-pub unsafe fn mmap(addr: *mut c_void, length: size_t, prot: ProtFlags, flags: MapFlags, fd: RawFd, offset: off_t) -> Result<*mut c_void> { +- let ret = libc::mmap(addr, length, prot.bits(), flags.bits(), fd, offset); ++/// allocate memory, or map files or devices into memory ++/// ++/// # Safety ++/// ++/// See the [`mmap(2)`] man page for detailed requirements. ++/// ++/// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html ++pub unsafe fn mmap( ++ addr: Option, ++ length: NonZeroUsize, ++ prot: ProtFlags, ++ flags: MapFlags, ++ fd: RawFd, ++ offset: off_t, ++) -> Result<*mut c_void> { ++ let ptr = addr.map_or( ++ std::ptr::null_mut(), ++ |a| usize::from(a) as *mut c_void ++ ); ++ ++ let ret = libc::mmap(ptr, length.into(), prot.bits(), flags.bits(), fd, offset); + + if ret == libc::MAP_FAILED { +- Err(Error::Sys(Errno::last())) ++ Err(Errno::last()) + } else { + Ok(ret) + } + } + ++/// Expands (or shrinks) an existing memory mapping, potentially moving it at ++/// the same time. ++/// ++/// # Safety ++/// ++/// See the `mremap(2)` [man page](https://man7.org/linux/man-pages/man2/mremap.2.html) for ++/// detailed requirements. ++#[cfg(any(target_os = "linux", target_os = "netbsd"))] ++pub unsafe fn mremap( ++ addr: *mut c_void, ++ old_size: size_t, ++ new_size: size_t, ++ flags: MRemapFlags, ++ new_address: Option<*mut c_void>, ++) -> Result<*mut c_void> { ++ #[cfg(target_os = "linux")] ++ let ret = libc::mremap( ++ addr, ++ old_size, ++ new_size, ++ flags.bits(), ++ new_address.unwrap_or(std::ptr::null_mut()), ++ ); ++ #[cfg(target_os = "netbsd")] ++ let ret = libc::mremap( ++ addr, ++ old_size, ++ new_address.unwrap_or(std::ptr::null_mut()), ++ new_size, ++ flags.bits(), ++ ); ++ ++ if ret == libc::MAP_FAILED { ++ Err(Errno::last()) ++ } else { ++ Ok(ret) ++ } ++} ++ ++/// remove a mapping ++/// ++/// # Safety ++/// ++/// `addr` must meet all the requirements described in the [`munmap(2)`] man ++/// page. ++/// ++/// [`munmap(2)`]: https://man7.org/linux/man-pages/man2/munmap.2.html + pub unsafe fn munmap(addr: *mut c_void, len: size_t) -> Result<()> { + Errno::result(libc::munmap(addr, len)).map(drop) + } + +-pub unsafe fn madvise(addr: *mut c_void, length: size_t, advise: MmapAdvise) -> Result<()> { ++/// give advice about use of memory ++/// ++/// # Safety ++/// ++/// See the [`madvise(2)`] man page. Take special care when using ++/// [`MmapAdvise::MADV_FREE`]. ++/// ++/// [`madvise(2)`]: https://man7.org/linux/man-pages/man2/madvise.2.html ++pub unsafe fn madvise( ++ addr: *mut c_void, ++ length: size_t, ++ advise: MmapAdvise, ++) -> Result<()> { + Errno::result(libc::madvise(addr, length, advise as i32)).map(drop) + } + + /// Set protection of memory mapping. + /// +-/// See [`mprotect(3)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mprotect.html) for ++/// See [`mprotect(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mprotect.html) for + /// details. + /// + /// # Safety +@@ -281,8 +520,9 @@ pub unsafe fn madvise(addr: *mut c_void, length: size_t, advise: MmapAdvise) -> + /// # use nix::sys::mman::{mmap, mprotect, MapFlags, ProtFlags}; + /// # use std::ptr; + /// const ONE_K: size_t = 1024; ++/// let one_k_non_zero = std::num::NonZeroUsize::new(ONE_K).unwrap(); + /// let mut slice: &mut [u8] = unsafe { +-/// let mem = mmap(ptr::null_mut(), ONE_K, ProtFlags::PROT_NONE, ++/// let mem = mmap(None, one_k_non_zero, ProtFlags::PROT_NONE, + /// MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE, -1, 0).unwrap(); + /// mprotect(mem, ONE_K, ProtFlags::PROT_READ | ProtFlags::PROT_WRITE).unwrap(); + /// std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K) +@@ -291,16 +531,45 @@ pub unsafe fn madvise(addr: *mut c_void, length: size_t, advise: MmapAdvise) -> + /// slice[0] = 0xFF; + /// assert_eq!(slice[0], 0xFF); + /// ``` +-pub unsafe fn mprotect(addr: *mut c_void, length: size_t, prot: ProtFlags) -> Result<()> { ++pub unsafe fn mprotect( ++ addr: *mut c_void, ++ length: size_t, ++ prot: ProtFlags, ++) -> Result<()> { + Errno::result(libc::mprotect(addr, length, prot.bits())).map(drop) + } + +-pub unsafe fn msync(addr: *mut c_void, length: size_t, flags: MsFlags) -> Result<()> { ++/// synchronize a mapped region ++/// ++/// # Safety ++/// ++/// `addr` must meet all the requirements described in the [`msync(2)`] man ++/// page. ++/// ++/// [`msync(2)`]: https://man7.org/linux/man-pages/man2/msync.2.html ++pub unsafe fn msync( ++ addr: *mut c_void, ++ length: size_t, ++ flags: MsFlags, ++) -> Result<()> { + Errno::result(libc::msync(addr, length, flags.bits())).map(drop) + } + + #[cfg(not(target_os = "android"))] +-pub fn shm_open(name: &P, flag: OFlag, mode: Mode) -> Result { ++feature! { ++#![feature = "fs"] ++/// Creates and opens a new, or opens an existing, POSIX shared memory object. ++/// ++/// For more information, see [`shm_open(3)`]. ++/// ++/// [`shm_open(3)`]: https://man7.org/linux/man-pages/man3/shm_open.3.html ++pub fn shm_open

( ++ name: &P, ++ flag: OFlag, ++ mode: Mode ++ ) -> Result ++ where P: ?Sized + NixPath ++{ + let ret = name.with_nix_path(|cstr| { + #[cfg(any(target_os = "macos", target_os = "ios"))] + unsafe { +@@ -314,12 +583,17 @@ pub fn shm_open(name: &P, flag: OFlag, mode: Mode) -> Resul + + Errno::result(ret) + } ++} + ++/// Performs the converse of [`shm_open`], removing an object previously created. ++/// ++/// For more information, see [`shm_unlink(3)`]. ++/// ++/// [`shm_unlink(3)`]: https://man7.org/linux/man-pages/man3/shm_unlink.3.html + #[cfg(not(target_os = "android"))] + pub fn shm_unlink(name: &P) -> Result<()> { +- let ret = name.with_nix_path(|cstr| { +- unsafe { libc::shm_unlink(cstr.as_ptr()) } +- })?; ++ let ret = ++ name.with_nix_path(|cstr| unsafe { libc::shm_unlink(cstr.as_ptr()) })?; + + Errno::result(ret).map(drop) + } +diff --git a/vendor/nix/src/sys/mod.rs b/vendor/nix/src/sys/mod.rs +index d3c2f92..2065059 100644 +--- a/vendor/nix/src/sys/mod.rs ++++ b/vendor/nix/src/sys/mod.rs +@@ -1,100 +1,228 @@ +-#[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "linux", +- target_os = "macos", +- target_os = "netbsd"))] +-pub mod aio; +- +-#[cfg(any(target_os = "android", target_os = "linux"))] +-pub mod epoll; +- +-#[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] +-pub mod event; +- +-#[cfg(target_os = "linux")] +-pub mod eventfd; +- +-#[cfg(any(target_os = "android", +- target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "linux", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++//! Mostly platform-specific functionality ++#[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ all(target_os = "linux", not(target_env = "uclibc")), ++ target_os = "macos", ++ target_os = "netbsd" ++))] ++feature! { ++ #![feature = "aio"] ++ pub mod aio; ++} ++ ++feature! { ++ #![feature = "event"] ++ ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[allow(missing_docs)] ++ pub mod epoll; ++ ++ #[cfg(any(target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd"))] ++ #[allow(missing_docs)] ++ pub mod event; ++ ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[allow(missing_docs)] ++ pub mod eventfd; ++} ++ ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "linux", ++ target_os = "redox", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "illumos", ++ target_os = "openbsd" ++))] ++#[cfg(feature = "ioctl")] ++#[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))] + #[macro_use] + pub mod ioctl; + +-#[cfg(target_os = "linux")] +-pub mod memfd; +- +-pub mod mman; ++#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] ++feature! { ++ #![feature = "fs"] ++ pub mod memfd; ++} + +-pub mod pthread; +- +-#[cfg(any(target_os = "android", +- target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "linux", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] +-pub mod ptrace; ++#[cfg(not(target_os = "redox"))] ++feature! { ++ #![feature = "mman"] ++ pub mod mman; ++} + + #[cfg(target_os = "linux")] +-pub mod quota; +- +-#[cfg(any(target_os = "linux"))] +-pub mod reboot; ++feature! { ++ #![feature = "personality"] ++ pub mod personality; ++} ++ ++feature! { ++ #![feature = "pthread"] ++ pub mod pthread; ++} ++ ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "linux", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++))] ++feature! { ++ #![feature = "ptrace"] ++ #[allow(missing_docs)] ++ pub mod ptrace; ++} + +-pub mod select; ++#[cfg(target_os = "linux")] ++feature! { ++ #![feature = "quota"] ++ pub mod quota; ++} + +-#[cfg(any(target_os = "android", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "linux", +- target_os = "macos"))] +-pub mod sendfile; ++#[cfg(target_os = "linux")] ++feature! { ++ #![feature = "reboot"] ++ pub mod reboot; ++} ++ ++#[cfg(not(any( ++ target_os = "redox", ++ target_os = "fuchsia", ++ target_os = "illumos", ++ target_os = "haiku" ++)))] ++feature! { ++ #![feature = "resource"] ++ pub mod resource; ++} ++ ++#[cfg(not(target_os = "redox"))] ++feature! { ++ #![feature = "poll"] ++ pub mod select; ++} ++ ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "linux", ++ target_os = "macos" ++))] ++feature! { ++ #![feature = "zerocopy"] ++ pub mod sendfile; ++} + + pub mod signal; + + #[cfg(any(target_os = "android", target_os = "linux"))] +-pub mod signalfd; +- +-pub mod socket; +- +-pub mod stat; +- +-#[cfg(any(target_os = "android", +- target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "linux", +- target_os = "macos", +- target_os = "openbsd" ++feature! { ++ #![feature = "signal"] ++ #[allow(missing_docs)] ++ pub mod signalfd; ++} ++ ++#[cfg(not(target_os = "redox"))] ++feature! { ++ #![feature = "socket"] ++ #[allow(missing_docs)] ++ pub mod socket; ++} ++ ++feature! { ++ #![feature = "fs"] ++ #[allow(missing_docs)] ++ pub mod stat; ++} ++ ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "linux", ++ target_os = "macos", ++ target_os = "openbsd" + ))] +-pub mod statfs; ++feature! { ++ #![feature = "fs"] ++ pub mod statfs; ++} + +-pub mod statvfs; ++feature! { ++ #![feature = "fs"] ++ pub mod statvfs; ++} + + #[cfg(any(target_os = "android", target_os = "linux"))] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++#[allow(missing_docs)] + pub mod sysinfo; + +-pub mod termios; ++feature! { ++ #![feature = "term"] ++ #[allow(missing_docs)] ++ pub mod termios; ++} + ++#[allow(missing_docs)] + pub mod time; + +-pub mod uio; ++feature! { ++ #![feature = "uio"] ++ pub mod uio; ++} + +-pub mod utsname; ++feature! { ++ #![feature = "feature"] ++ pub mod utsname; ++} + +-pub mod wait; ++feature! { ++ #![feature = "process"] ++ pub mod wait; ++} + + #[cfg(any(target_os = "android", target_os = "linux"))] +-pub mod inotify; ++feature! { ++ #![feature = "inotify"] ++ pub mod inotify; ++} ++ ++#[cfg(any(target_os = "android", target_os = "linux"))] ++feature! { ++ #![feature = "time"] ++ pub mod timerfd; ++} ++ ++#[cfg(all( ++ any( ++ target_os = "freebsd", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "netbsd" ++ ), ++ feature = "time", ++ feature = "signal" ++))] ++feature! { ++ #![feature = "time"] ++ pub mod timer; ++} +diff --git a/vendor/nix/src/sys/personality.rs b/vendor/nix/src/sys/personality.rs +new file mode 100644 +index 0000000..f295a05 +--- /dev/null ++++ b/vendor/nix/src/sys/personality.rs +@@ -0,0 +1,93 @@ ++//! Process execution domains ++use crate::errno::Errno; ++use crate::Result; ++ ++use libc::{self, c_int, c_ulong}; ++ ++libc_bitflags! { ++ /// Flags used and returned by [`get()`](fn.get.html) and ++ /// [`set()`](fn.set.html). ++ pub struct Persona: c_int { ++ /// Provide the legacy virtual address space layout. ++ ADDR_COMPAT_LAYOUT; ++ /// Disable address-space-layout randomization. ++ ADDR_NO_RANDOMIZE; ++ /// Limit the address space to 32 bits. ++ ADDR_LIMIT_32BIT; ++ /// Use `0xc0000000` as the offset at which to search a virtual memory ++ /// chunk on [`mmap(2)`], otherwise use `0xffffe000`. ++ /// ++ /// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html ++ ADDR_LIMIT_3GB; ++ /// User-space function pointers to signal handlers point to descriptors. ++ #[cfg(not(any(target_env = "musl", target_env = "uclibc")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ FDPIC_FUNCPTRS; ++ /// Map page 0 as read-only. ++ MMAP_PAGE_ZERO; ++ /// `PROT_READ` implies `PROT_EXEC` for [`mmap(2)`]. ++ /// ++ /// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html ++ READ_IMPLIES_EXEC; ++ /// No effects. ++ SHORT_INODE; ++ /// [`select(2)`], [`pselect(2)`], and [`ppoll(2)`] do not modify the ++ /// returned timeout argument when interrupted by a signal handler. ++ /// ++ /// [`select(2)`]: https://man7.org/linux/man-pages/man2/select.2.html ++ /// [`pselect(2)`]: https://man7.org/linux/man-pages/man2/pselect.2.html ++ /// [`ppoll(2)`]: https://man7.org/linux/man-pages/man2/ppoll.2.html ++ STICKY_TIMEOUTS; ++ /// Have [`uname(2)`] report a 2.6.40+ version number rather than a 3.x ++ /// version number. ++ /// ++ /// [`uname(2)`]: https://man7.org/linux/man-pages/man2/uname.2.html ++ #[cfg(not(any(target_env = "musl", target_env = "uclibc")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ UNAME26; ++ /// No effects. ++ WHOLE_SECONDS; ++ } ++} ++ ++/// Retrieve the current process personality. ++/// ++/// Returns a Result containing a Persona instance. ++/// ++/// Example: ++/// ++/// ``` ++/// # use nix::sys::personality::{self, Persona}; ++/// let pers = personality::get().unwrap(); ++/// assert!(!pers.contains(Persona::WHOLE_SECONDS)); ++/// ``` ++pub fn get() -> Result { ++ let res = unsafe { libc::personality(0xFFFFFFFF) }; ++ ++ Errno::result(res).map(Persona::from_bits_truncate) ++} ++ ++/// Set the current process personality. ++/// ++/// Returns a Result containing the *previous* personality for the ++/// process, as a Persona. ++/// ++/// For more information, see [personality(2)](https://man7.org/linux/man-pages/man2/personality.2.html) ++/// ++/// **NOTE**: This call **replaces** the current personality entirely. ++/// To **update** the personality, first call `get()` and then `set()` ++/// with the modified persona. ++/// ++/// Example: ++/// ++/// ``` ++/// # use nix::sys::personality::{self, Persona}; ++/// let mut pers = personality::get().unwrap(); ++/// assert!(!pers.contains(Persona::ADDR_NO_RANDOMIZE)); ++/// personality::set(pers | Persona::ADDR_NO_RANDOMIZE).unwrap(); ++/// ``` ++pub fn set(persona: Persona) -> Result { ++ let res = unsafe { libc::personality(persona.bits() as c_ulong) }; ++ ++ Errno::result(res).map(Persona::from_bits_truncate) ++} +diff --git a/vendor/nix/src/sys/pthread.rs b/vendor/nix/src/sys/pthread.rs +index a4d9825..6bad03a 100644 +--- a/vendor/nix/src/sys/pthread.rs ++++ b/vendor/nix/src/sys/pthread.rs +@@ -1,9 +1,16 @@ ++//! Low level threading primitives ++ ++#[cfg(not(target_os = "redox"))] ++use crate::errno::Errno; ++#[cfg(not(target_os = "redox"))] ++use crate::Result; + use libc::{self, pthread_t}; + ++/// Identifies an individual thread. + pub type Pthread = pthread_t; + + /// Obtain ID of the calling thread (see +-/// [`pthread_self(3)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_self.html) ++/// [`pthread_self(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_self.html) + /// + /// The thread ID returned by `pthread_self()` is not the same thing as + /// the kernel thread ID returned by a call to `gettid(2)`. +@@ -11,3 +18,26 @@ pub type Pthread = pthread_t; + pub fn pthread_self() -> Pthread { + unsafe { libc::pthread_self() } + } ++ ++feature! { ++#![feature = "signal"] ++ ++/// Send a signal to a thread (see [`pthread_kill(3)`]). ++/// ++/// If `signal` is `None`, `pthread_kill` will only preform error checking and ++/// won't send any signal. ++/// ++/// [`pthread_kill(3)`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_kill.html ++#[allow(clippy::not_unsafe_ptr_arg_deref)] ++#[cfg(not(target_os = "redox"))] ++pub fn pthread_kill(thread: Pthread, signal: T) -> Result<()> ++ where T: Into> ++{ ++ let sig = match signal.into() { ++ Some(s) => s as libc::c_int, ++ None => 0, ++ }; ++ let res = unsafe { libc::pthread_kill(thread, sig) }; ++ Errno::result(res).map(drop) ++} ++} +diff --git a/vendor/nix/src/sys/ptrace/bsd.rs b/vendor/nix/src/sys/ptrace/bsd.rs +index 18265d3..ba267c6 100644 +--- a/vendor/nix/src/sys/ptrace/bsd.rs ++++ b/vendor/nix/src/sys/ptrace/bsd.rs +@@ -1,15 +1,16 @@ +-use errno::Errno; ++use crate::errno::Errno; ++use crate::sys::signal::Signal; ++use crate::unistd::Pid; ++use crate::Result; ++use cfg_if::cfg_if; + use libc::{self, c_int}; + use std::ptr; +-use sys::signal::Signal; +-use unistd::Pid; +-use Result; + + pub type RequestType = c_int; + + cfg_if! { +- if #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", ++ if #[cfg(any(target_os = "dragonfly", ++ target_os = "freebsd", + target_os = "macos", + target_os = "openbsd"))] { + #[doc(hidden)] +@@ -23,15 +24,18 @@ cfg_if! { + libc_enum! { + #[repr(i32)] + /// Ptrace Request enum defining the action to be taken. ++ #[non_exhaustive] + pub enum Request { + PT_TRACE_ME, + PT_READ_I, + PT_READ_D, + #[cfg(target_os = "macos")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + PT_READ_U, + PT_WRITE_I, + PT_WRITE_D, + #[cfg(target_os = "macos")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + PT_WRITE_U, + PT_CONTINUE, + PT_KILL, +@@ -45,10 +49,13 @@ libc_enum! { + PT_ATTACH, + PT_DETACH, + #[cfg(target_os = "macos")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + PT_SIGEXC, + #[cfg(target_os = "macos")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + PT_THUPDATE, + #[cfg(target_os = "macos")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + PT_ATTACHEXC + } + } +@@ -64,7 +71,8 @@ unsafe fn ptrace_other( + libc::pid_t::from(pid), + addr, + data, +- )).map(|_| 0) ++ )) ++ .map(|_| 0) + } + + /// Sets the process as traceable, as with `ptrace(PT_TRACEME, ...)` +@@ -72,14 +80,19 @@ unsafe fn ptrace_other( + /// Indicates that this process is to be traced by its parent. + /// This is the only ptrace request to be issued by the tracee. + pub fn traceme() -> Result<()> { +- unsafe { ptrace_other(Request::PT_TRACE_ME, Pid::from_raw(0), ptr::null_mut(), 0).map(drop) } ++ unsafe { ++ ptrace_other(Request::PT_TRACE_ME, Pid::from_raw(0), ptr::null_mut(), 0) ++ .map(drop) ++ } + } + + /// Attach to a running process, as with `ptrace(PT_ATTACH, ...)` + /// + /// Attaches to the process specified by `pid`, making it a tracee of the calling process. + pub fn attach(pid: Pid) -> Result<()> { +- unsafe { ptrace_other(Request::PT_ATTACH, pid, ptr::null_mut(), 0).map(drop) } ++ unsafe { ++ ptrace_other(Request::PT_ATTACH, pid, ptr::null_mut(), 0).map(drop) ++ } + } + + /// Detaches the current running process, as with `ptrace(PT_DETACH, ...)` +@@ -107,13 +120,14 @@ pub fn cont>>(pid: Pid, sig: T) -> Result<()> { + }; + unsafe { + // Ignore the useless return value +- ptrace_other(Request::PT_CONTINUE, pid, 1 as AddressType, data).map(drop) ++ ptrace_other(Request::PT_CONTINUE, pid, 1 as AddressType, data) ++ .map(drop) + } + } + + /// Issues a kill request as with `ptrace(PT_KILL, ...)` + /// +-/// This request is equivalent to `ptrace(PT_CONTINUE, ..., SIGKILL);` ++/// This request is equivalent to `ptrace(PT_CONTINUE, ..., SIGKILL);` + pub fn kill(pid: Pid) -> Result<()> { + unsafe { + ptrace_other(Request::PT_KILL, pid, 0 as AddressType, 0).map(drop) +@@ -128,41 +142,42 @@ pub fn kill(pid: Pid) -> Result<()> { + /// + /// # Example + /// ```rust +-/// extern crate nix; + /// use nix::sys::ptrace::step; + /// use nix::unistd::Pid; + /// use nix::sys::signal::Signal; + /// use nix::sys::wait::*; +-/// fn main() { +-/// // If a process changes state to the stopped state because of a SIGUSR1 +-/// // signal, this will step the process forward and forward the user +-/// // signal to the stopped process +-/// match waitpid(Pid::from_raw(-1), None) { +-/// Ok(WaitStatus::Stopped(pid, Signal::SIGUSR1)) => { +-/// let _ = step(pid, Signal::SIGUSR1); +-/// } +-/// _ => {}, ++/// // If a process changes state to the stopped state because of a SIGUSR1 ++/// // signal, this will step the process forward and forward the user ++/// // signal to the stopped process ++/// match waitpid(Pid::from_raw(-1), None) { ++/// Ok(WaitStatus::Stopped(pid, Signal::SIGUSR1)) => { ++/// let _ = step(pid, Signal::SIGUSR1); + /// } ++/// _ => {}, + /// } + /// ``` +-#[cfg( +- any( +- any(target_os = "dragonfly", target_os = "freebsd", target_os = "macos"), +- all(target_os = "openbsd", target_arch = "x86_64"), +- all(target_os = "netbsd", +- any(target_arch = "x86_64", target_arch = "powerpc") +- ) ++#[cfg(any( ++ any(target_os = "dragonfly", target_os = "freebsd", target_os = "macos"), ++ all(target_os = "openbsd", target_arch = "x86_64"), ++ all( ++ target_os = "netbsd", ++ any(target_arch = "x86_64", target_arch = "powerpc") + ) +-)] ++))] + pub fn step>>(pid: Pid, sig: T) -> Result<()> { + let data = match sig.into() { + Some(s) => s as c_int, + None => 0, + }; +- unsafe { ptrace_other(Request::PT_STEP, pid, ptr::null_mut(), data).map(drop) } ++ unsafe { ++ ptrace_other(Request::PT_STEP, pid, ptr::null_mut(), data).map(drop) ++ } + } + + /// Reads a word from a processes memory at the given address ++// Technically, ptrace doesn't dereference the pointer. It passes it directly ++// to the kernel. ++#[allow(clippy::not_unsafe_ptr_arg_deref)] + pub fn read(pid: Pid, addr: AddressType) -> Result { + unsafe { + // Traditionally there was a difference between reading data or +@@ -172,6 +187,9 @@ pub fn read(pid: Pid, addr: AddressType) -> Result { + } + + /// Writes a word into the processes memory at the given address ++// Technically, ptrace doesn't dereference the pointer. It passes it directly ++// to the kernel. ++#[allow(clippy::not_unsafe_ptr_arg_deref)] + pub fn write(pid: Pid, addr: AddressType, data: c_int) -> Result<()> { + unsafe { ptrace_other(Request::PT_WRITE_D, pid, addr, data).map(drop) } + } +diff --git a/vendor/nix/src/sys/ptrace/linux.rs b/vendor/nix/src/sys/ptrace/linux.rs +index ba0e614..9687e05 100644 +--- a/vendor/nix/src/sys/ptrace/linux.rs ++++ b/vendor/nix/src/sys/ptrace/linux.rs +@@ -1,23 +1,31 @@ + //! For detailed description of the ptrace requests, consult `man ptrace`. + ++use crate::errno::Errno; ++use crate::sys::signal::Signal; ++use crate::unistd::Pid; ++use crate::Result; ++use cfg_if::cfg_if; ++use libc::{self, c_long, c_void, siginfo_t}; + use std::{mem, ptr}; +-use {Error, Result}; +-use errno::Errno; +-use libc::{self, c_void, c_long, siginfo_t}; +-use ::unistd::Pid; +-use sys::signal::Signal; + + pub type AddressType = *mut ::libc::c_void; + +-#[cfg(all(target_os = "linux", +- any(target_arch = "x86_64", +- target_arch = "x86"), +- target_env = "gnu"))] ++#[cfg(all( ++ target_os = "linux", ++ any( ++ all( ++ target_arch = "x86_64", ++ any(target_env = "gnu", target_env = "musl") ++ ), ++ all(target_arch = "x86", target_env = "gnu") ++ ) ++))] + use libc::user_regs_struct; + + cfg_if! { + if #[cfg(any(all(target_os = "linux", target_arch = "s390x"), +- all(target_os = "linux", target_env = "gnu")))] { ++ all(target_os = "linux", target_env = "gnu"), ++ target_env = "uclibc"))] { + #[doc(hidden)] + pub type RequestType = ::libc::c_uint; + } else { +@@ -26,10 +34,11 @@ cfg_if! { + } + } + +-libc_enum!{ +- #[cfg_attr(not(any(target_env = "musl", target_os = "android")), repr(u32))] +- #[cfg_attr(any(target_env = "musl", target_os = "android"), repr(i32))] ++libc_enum! { ++ #[cfg_attr(not(any(target_env = "musl", target_env = "uclibc", target_os = "android")), repr(u32))] ++ #[cfg_attr(any(target_env = "musl", target_env = "uclibc", target_os = "android"), repr(i32))] + /// Ptrace Request enum defining the action to be taken. ++ #[non_exhaustive] + pub enum Request { + PTRACE_TRACEME, + PTRACE_PEEKTEXT, +@@ -46,7 +55,6 @@ libc_enum!{ + target_arch = "mips", + target_arch = "mips64", + target_arch = "x86_64", +- target_arch = "riscv64", + target_pointer_width = "32"))))] + PTRACE_GETREGS, + #[cfg(any(all(target_os = "android", target_pointer_width = "32"), +@@ -54,7 +62,6 @@ libc_enum!{ + target_arch = "mips", + target_arch = "mips64", + target_arch = "x86_64", +- target_arch = "riscv64", + target_pointer_width = "32"))))] + PTRACE_SETREGS, + #[cfg(any(all(target_os = "android", target_pointer_width = "32"), +@@ -62,7 +69,6 @@ libc_enum!{ + target_arch = "mips", + target_arch = "mips64", + target_arch = "x86_64", +- target_arch = "riscv64", + target_pointer_width = "32"))))] + PTRACE_GETFPREGS, + #[cfg(any(all(target_os = "android", target_pointer_width = "32"), +@@ -70,7 +76,6 @@ libc_enum!{ + target_arch = "mips", + target_arch = "mips64", + target_arch = "x86_64", +- target_arch = "riscv64", + target_pointer_width = "32"))))] + PTRACE_SETFPREGS, + PTRACE_ATTACH, +@@ -79,15 +84,13 @@ libc_enum!{ + target_arch = "mips", + target_arch = "mips64", + target_arch = "x86", +- target_arch = "x86_64", +- target_arch = "riscv64")))] ++ target_arch = "x86_64")))] + PTRACE_GETFPXREGS, + #[cfg(all(target_os = "linux", any(target_env = "musl", + target_arch = "mips", + target_arch = "mips64", + target_arch = "x86", +- target_arch = "x86_64", +- target_arch = "riscv64")))] ++ target_arch = "x86_64")))] + PTRACE_SETFPXREGS, + PTRACE_SYSCALL, + PTRACE_SETOPTIONS, +@@ -100,11 +103,11 @@ libc_enum!{ + #[cfg(all(target_os = "linux", not(any(target_arch = "mips", + target_arch = "mips64"))))] + PTRACE_SETREGSET, +- #[cfg(all(target_os = "linux", not(any(target_arch = "mips", +- target_arch = "mips64"))))] ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + PTRACE_SEIZE, +- #[cfg(all(target_os = "linux", not(any(target_arch = "mips", +- target_arch = "mips64"))))] ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + PTRACE_INTERRUPT, + #[cfg(all(target_os = "linux", not(any(target_arch = "mips", + target_arch = "mips64"))))] +@@ -112,14 +115,21 @@ libc_enum!{ + #[cfg(all(target_os = "linux", not(any(target_arch = "mips", + target_arch = "mips64"))))] + PTRACE_PEEKSIGINFO, ++ #[cfg(all(target_os = "linux", target_env = "gnu", ++ any(target_arch = "x86", target_arch = "x86_64")))] ++ PTRACE_SYSEMU, ++ #[cfg(all(target_os = "linux", target_env = "gnu", ++ any(target_arch = "x86", target_arch = "x86_64")))] ++ PTRACE_SYSEMU_SINGLESTEP, + } + } + +-libc_enum!{ ++libc_enum! { + #[repr(i32)] + /// Using the ptrace options the tracer can configure the tracee to stop + /// at certain events. This enum is used to define those events as defined + /// in `man ptrace`. ++ #[non_exhaustive] + pub enum Event { + /// Event that stops before a return from fork or clone. + PTRACE_EVENT_FORK, +@@ -134,9 +144,11 @@ libc_enum!{ + /// Event for a stop before an exit. Unlike the waitpid Exit status program. + /// registers can still be examined + PTRACE_EVENT_EXIT, +- /// STop triggered by a seccomp rule on a tracee. ++ /// Stop triggered by a seccomp rule on a tracee. + PTRACE_EVENT_SECCOMP, +- // PTRACE_EVENT_STOP not provided by libc because it's defined in glibc 2.26 ++ /// Stop triggered by the `INTERRUPT` syscall, or a group stop, ++ /// or when a new child is attached. ++ PTRACE_EVENT_STOP, + } + } + +@@ -166,58 +178,60 @@ libc_bitflags! { + PTRACE_O_TRACESECCOMP; + /// Send a SIGKILL to the tracee if the tracer exits. This is useful + /// for ptrace jailers to prevent tracees from escaping their control. +- #[cfg(any(target_os = "android", target_os = "linux"))] + PTRACE_O_EXITKILL; + } + } + +-/// Performs a ptrace request. If the request in question is provided by a specialised function +-/// this function will return an unsupported operation error. +-#[deprecated( +- since="0.10.0", +- note="usages of `ptrace()` should be replaced with the specialized helper functions instead" +-)] +-pub unsafe fn ptrace(request: Request, pid: Pid, addr: AddressType, data: *mut c_void) -> Result { +- use self::Request::*; +- match request { +- PTRACE_PEEKTEXT | PTRACE_PEEKDATA | PTRACE_GETSIGINFO | +- PTRACE_GETEVENTMSG | PTRACE_SETSIGINFO | PTRACE_SETOPTIONS | +- PTRACE_POKETEXT | PTRACE_POKEDATA | PTRACE_KILL => Err(Error::UnsupportedOperation), +- _ => ptrace_other(request, pid, addr, data) +- } +-} +- +-fn ptrace_peek(request: Request, pid: Pid, addr: AddressType, data: *mut c_void) -> Result { ++fn ptrace_peek( ++ request: Request, ++ pid: Pid, ++ addr: AddressType, ++ data: *mut c_void, ++) -> Result { + let ret = unsafe { + Errno::clear(); + libc::ptrace(request as RequestType, libc::pid_t::from(pid), addr, data) + }; + match Errno::result(ret) { +- Ok(..) | Err(Error::Sys(Errno::UnknownErrno)) => Ok(ret), ++ Ok(..) | Err(Errno::UnknownErrno) => Ok(ret), + err @ Err(..) => err, + } + } + + /// Get user registers, as with `ptrace(PTRACE_GETREGS, ...)` +-#[cfg(all(target_os = "linux", +- any(target_arch = "x86_64", +- target_arch = "x86"), +- target_env = "gnu"))] ++#[cfg(all( ++ target_os = "linux", ++ any( ++ all( ++ target_arch = "x86_64", ++ any(target_env = "gnu", target_env = "musl") ++ ), ++ all(target_arch = "x86", target_env = "gnu") ++ ) ++))] + pub fn getregs(pid: Pid) -> Result { + ptrace_get_data::(Request::PTRACE_GETREGS, pid) + } + + /// Set user registers, as with `ptrace(PTRACE_SETREGS, ...)` +-#[cfg(all(target_os = "linux", +- any(target_arch = "x86_64", +- target_arch = "x86"), +- target_env = "gnu"))] ++#[cfg(all( ++ target_os = "linux", ++ any( ++ all( ++ target_arch = "x86_64", ++ any(target_env = "gnu", target_env = "musl") ++ ), ++ all(target_arch = "x86", target_env = "gnu") ++ ) ++))] + pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> { + let res = unsafe { +- libc::ptrace(Request::PTRACE_SETREGS as RequestType, +- libc::pid_t::from(pid), +- ptr::null_mut::(), +- ®s as *const _ as *const c_void) ++ libc::ptrace( ++ Request::PTRACE_SETREGS as RequestType, ++ libc::pid_t::from(pid), ++ ptr::null_mut::(), ++ ®s as *const _ as *const c_void, ++ ) + }; + Errno::result(res).map(drop) + } +@@ -229,26 +243,41 @@ pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> { + fn ptrace_get_data(request: Request, pid: Pid) -> Result { + let mut data = mem::MaybeUninit::uninit(); + let res = unsafe { +- libc::ptrace(request as RequestType, +- libc::pid_t::from(pid), +- ptr::null_mut::(), +- data.as_mut_ptr() as *const _ as *const c_void) ++ libc::ptrace( ++ request as RequestType, ++ libc::pid_t::from(pid), ++ ptr::null_mut::(), ++ data.as_mut_ptr() as *const _ as *const c_void, ++ ) + }; + Errno::result(res)?; +- Ok(unsafe{ data.assume_init() }) ++ Ok(unsafe { data.assume_init() }) + } + +-unsafe fn ptrace_other(request: Request, pid: Pid, addr: AddressType, data: *mut c_void) -> Result { +- Errno::result(libc::ptrace(request as RequestType, libc::pid_t::from(pid), addr, data)).map(|_| 0) ++unsafe fn ptrace_other( ++ request: Request, ++ pid: Pid, ++ addr: AddressType, ++ data: *mut c_void, ++) -> Result { ++ Errno::result(libc::ptrace( ++ request as RequestType, ++ libc::pid_t::from(pid), ++ addr, ++ data, ++ )) ++ .map(|_| 0) + } + + /// Set options, as with `ptrace(PTRACE_SETOPTIONS,...)`. + pub fn setoptions(pid: Pid, options: Options) -> Result<()> { + let res = unsafe { +- libc::ptrace(Request::PTRACE_SETOPTIONS as RequestType, +- libc::pid_t::from(pid), +- ptr::null_mut::(), +- options.bits() as *mut c_void) ++ libc::ptrace( ++ Request::PTRACE_SETOPTIONS as RequestType, ++ libc::pid_t::from(pid), ++ ptr::null_mut::(), ++ options.bits() as *mut c_void, ++ ) + }; + Errno::result(res).map(drop) + } +@@ -265,12 +294,14 @@ pub fn getsiginfo(pid: Pid) -> Result { + + /// Set siginfo as with `ptrace(PTRACE_SETSIGINFO,...)` + pub fn setsiginfo(pid: Pid, sig: &siginfo_t) -> Result<()> { +- let ret = unsafe{ ++ let ret = unsafe { + Errno::clear(); +- libc::ptrace(Request::PTRACE_SETSIGINFO as RequestType, +- libc::pid_t::from(pid), +- ptr::null_mut::(), +- sig as *const _ as *const c_void) ++ libc::ptrace( ++ Request::PTRACE_SETSIGINFO as RequestType, ++ libc::pid_t::from(pid), ++ ptr::null_mut::(), ++ sig as *const _ as *const c_void, ++ ) + }; + match Errno::result(ret) { + Ok(_) => Ok(()), +@@ -289,11 +320,12 @@ pub fn traceme() -> Result<()> { + Pid::from_raw(0), + ptr::null_mut(), + ptr::null_mut(), +- ).map(drop) // ignore the useless return value ++ ) ++ .map(drop) // ignore the useless return value + } + } + +-/// Ask for next syscall, as with `ptrace(PTRACE_SYSCALL, ...)` ++/// Continue execution until the next syscall, as with `ptrace(PTRACE_SYSCALL, ...)` + /// + /// Arranges for the tracee to be stopped at the next entry to or exit from a system call, + /// optionally delivering a signal specified by `sig`. +@@ -303,12 +335,30 @@ pub fn syscall>>(pid: Pid, sig: T) -> Result<()> { + None => ptr::null_mut(), + }; + unsafe { +- ptrace_other( +- Request::PTRACE_SYSCALL, +- pid, +- ptr::null_mut(), +- data, +- ).map(drop) // ignore the useless return value ++ ptrace_other(Request::PTRACE_SYSCALL, pid, ptr::null_mut(), data) ++ .map(drop) // ignore the useless return value ++ } ++} ++ ++/// Continue execution until the next syscall, as with `ptrace(PTRACE_SYSEMU, ...)` ++/// ++/// In contrast to the `syscall` function, the syscall stopped at will not be executed. ++/// Thus the the tracee will only be stopped once per syscall, ++/// optionally delivering a signal specified by `sig`. ++#[cfg(all( ++ target_os = "linux", ++ target_env = "gnu", ++ any(target_arch = "x86", target_arch = "x86_64") ++))] ++pub fn sysemu>>(pid: Pid, sig: T) -> Result<()> { ++ let data = match sig.into() { ++ Some(s) => s as i32 as *mut c_void, ++ None => ptr::null_mut(), ++ }; ++ unsafe { ++ ptrace_other(Request::PTRACE_SYSEMU, pid, ptr::null_mut(), data) ++ .map(drop) ++ // ignore the useless return value + } + } + +@@ -322,14 +372,16 @@ pub fn attach(pid: Pid) -> Result<()> { + pid, + ptr::null_mut(), + ptr::null_mut(), +- ).map(drop) // ignore the useless return value ++ ) ++ .map(drop) // ignore the useless return value + } + } + + /// Attach to a running process, as with `ptrace(PTRACE_SEIZE, ...)` + /// + /// Attaches to the process specified in pid, making it a tracee of the calling process. +-#[cfg(all(target_os = "linux", not(any(target_arch = "mips", target_arch = "mips64"))))] ++#[cfg(target_os = "linux")] ++#[cfg_attr(docsrs, doc(cfg(all())))] + pub fn seize(pid: Pid, options: Options) -> Result<()> { + unsafe { + ptrace_other( +@@ -337,7 +389,8 @@ pub fn seize(pid: Pid, options: Options) -> Result<()> { + pid, + ptr::null_mut(), + options.bits() as *mut c_void, +- ).map(drop) // ignore the useless return value ++ ) ++ .map(drop) // ignore the useless return value + } + } + +@@ -351,12 +404,8 @@ pub fn detach>>(pid: Pid, sig: T) -> Result<()> { + None => ptr::null_mut(), + }; + unsafe { +- ptrace_other( +- Request::PTRACE_DETACH, +- pid, +- ptr::null_mut(), +- data +- ).map(drop) ++ ptrace_other(Request::PTRACE_DETACH, pid, ptr::null_mut(), data) ++ .map(drop) + } + } + +@@ -370,7 +419,25 @@ pub fn cont>>(pid: Pid, sig: T) -> Result<()> { + None => ptr::null_mut(), + }; + unsafe { +- ptrace_other(Request::PTRACE_CONT, pid, ptr::null_mut(), data).map(drop) // ignore the useless return value ++ ptrace_other(Request::PTRACE_CONT, pid, ptr::null_mut(), data).map(drop) ++ // ignore the useless return value ++ } ++} ++ ++/// Stop a tracee, as with `ptrace(PTRACE_INTERRUPT, ...)` ++/// ++/// This request is equivalent to `ptrace(PTRACE_INTERRUPT, ...)` ++#[cfg(target_os = "linux")] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++pub fn interrupt(pid: Pid) -> Result<()> { ++ unsafe { ++ ptrace_other( ++ Request::PTRACE_INTERRUPT, ++ pid, ++ ptr::null_mut(), ++ ptr::null_mut(), ++ ) ++ .map(drop) + } + } + +@@ -379,11 +446,17 @@ pub fn cont>>(pid: Pid, sig: T) -> Result<()> { + /// This request is equivalent to `ptrace(PTRACE_CONT, ..., SIGKILL);` + pub fn kill(pid: Pid) -> Result<()> { + unsafe { +- ptrace_other(Request::PTRACE_KILL, pid, ptr::null_mut(), ptr::null_mut()).map(drop) ++ ptrace_other( ++ Request::PTRACE_KILL, ++ pid, ++ ptr::null_mut(), ++ ptr::null_mut(), ++ ) ++ .map(drop) + } + } + +-/// Move the stopped tracee process forward by a single step as with ++/// Move the stopped tracee process forward by a single step as with + /// `ptrace(PTRACE_SINGLESTEP, ...)` + /// + /// Advances the execution of the process with PID `pid` by a single step optionally delivering a +@@ -391,21 +464,19 @@ pub fn kill(pid: Pid) -> Result<()> { + /// + /// # Example + /// ```rust +-/// extern crate nix; + /// use nix::sys::ptrace::step; + /// use nix::unistd::Pid; +-/// use nix::sys::signal::Signal; ++/// use nix::sys::signal::Signal; + /// use nix::sys::wait::*; +-/// fn main() { +-/// // If a process changes state to the stopped state because of a SIGUSR1 +-/// // signal, this will step the process forward and forward the user +-/// // signal to the stopped process +-/// match waitpid(Pid::from_raw(-1), None) { +-/// Ok(WaitStatus::Stopped(pid, Signal::SIGUSR1)) => { +-/// let _ = step(pid, Signal::SIGUSR1); +-/// } +-/// _ => {}, ++/// ++/// // If a process changes state to the stopped state because of a SIGUSR1 ++/// // signal, this will step the process forward and forward the user ++/// // signal to the stopped process ++/// match waitpid(Pid::from_raw(-1), None) { ++/// Ok(WaitStatus::Stopped(pid, Signal::SIGUSR1)) => { ++/// let _ = step(pid, Signal::SIGUSR1); + /// } ++/// _ => {}, + /// } + /// ``` + pub fn step>>(pid: Pid, sig: T) -> Result<()> { +@@ -414,10 +485,37 @@ pub fn step>>(pid: Pid, sig: T) -> Result<()> { + None => ptr::null_mut(), + }; + unsafe { +- ptrace_other(Request::PTRACE_SINGLESTEP, pid, ptr::null_mut(), data).map(drop) ++ ptrace_other(Request::PTRACE_SINGLESTEP, pid, ptr::null_mut(), data) ++ .map(drop) + } + } + ++/// Move the stopped tracee process forward by a single step or stop at the next syscall ++/// as with `ptrace(PTRACE_SYSEMU_SINGLESTEP, ...)` ++/// ++/// Advances the execution by a single step or until the next syscall. ++/// In case the tracee is stopped at a syscall, the syscall will not be executed. ++/// Optionally, the signal specified by `sig` is delivered to the tracee upon continuation. ++#[cfg(all( ++ target_os = "linux", ++ target_env = "gnu", ++ any(target_arch = "x86", target_arch = "x86_64") ++))] ++pub fn sysemu_step>>(pid: Pid, sig: T) -> Result<()> { ++ let data = match sig.into() { ++ Some(s) => s as i32 as *mut c_void, ++ None => ptr::null_mut(), ++ }; ++ unsafe { ++ ptrace_other( ++ Request::PTRACE_SYSEMU_SINGLESTEP, ++ pid, ++ ptr::null_mut(), ++ data, ++ ) ++ .map(drop) // ignore the useless return value ++ } ++} + + /// Reads a word from a processes memory at the given address + pub fn read(pid: Pid, addr: AddressType) -> Result { +@@ -425,8 +523,36 @@ pub fn read(pid: Pid, addr: AddressType) -> Result { + } + + /// Writes a word into the processes memory at the given address +-pub fn write(pid: Pid, addr: AddressType, data: *mut c_void) -> Result<()> { +- unsafe { +- ptrace_other(Request::PTRACE_POKEDATA, pid, addr, data).map(drop) +- } ++/// ++/// # Safety ++/// ++/// The `data` argument is passed directly to `ptrace(2)`. Read that man page ++/// for guidance. ++pub unsafe fn write( ++ pid: Pid, ++ addr: AddressType, ++ data: *mut c_void, ++) -> Result<()> { ++ ptrace_other(Request::PTRACE_POKEDATA, pid, addr, data).map(drop) ++} ++ ++/// Reads a word from a user area at `offset`. ++/// The user struct definition can be found in `/usr/include/sys/user.h`. ++pub fn read_user(pid: Pid, offset: AddressType) -> Result { ++ ptrace_peek(Request::PTRACE_PEEKUSER, pid, offset, ptr::null_mut()) ++} ++ ++/// Writes a word to a user area at `offset`. ++/// The user struct definition can be found in `/usr/include/sys/user.h`. ++/// ++/// # Safety ++/// ++/// The `data` argument is passed directly to `ptrace(2)`. Read that man page ++/// for guidance. ++pub unsafe fn write_user( ++ pid: Pid, ++ offset: AddressType, ++ data: *mut c_void, ++) -> Result<()> { ++ ptrace_other(Request::PTRACE_POKEUSER, pid, offset, data).map(drop) + } +diff --git a/vendor/nix/src/sys/ptrace/mod.rs b/vendor/nix/src/sys/ptrace/mod.rs +index 782c304..2b121c0 100644 +--- a/vendor/nix/src/sys/ptrace/mod.rs ++++ b/vendor/nix/src/sys/ptrace/mod.rs +@@ -1,4 +1,4 @@ +-///! Provides helpers for making ptrace system calls ++///! Provides helpers for making ptrace system calls + + #[cfg(any(target_os = "android", target_os = "linux"))] + mod linux; +@@ -6,17 +6,20 @@ mod linux; + #[cfg(any(target_os = "android", target_os = "linux"))] + pub use self::linux::*; + +-#[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++#[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++))] + mod bsd; + +-#[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd" +- ))] ++#[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++))] + pub use self::bsd::*; +diff --git a/vendor/nix/src/sys/quota.rs b/vendor/nix/src/sys/quota.rs +index b056c84..b3c44ca 100644 +--- a/vendor/nix/src/sys/quota.rs ++++ b/vendor/nix/src/sys/quota.rs +@@ -6,28 +6,29 @@ + //! + //! ```rust,no_run + //! # use nix::sys::quota::{Dqblk, quotactl_on, quotactl_set, QuotaFmt, QuotaType, QuotaValidFlags}; +-//! quotactl_on(QuotaType::USRQUOTA, "/dev/sda1", QuotaFmt::QFMT_VFS_V1, "aquota.user"); ++//! quotactl_on(QuotaType::USRQUOTA, "/dev/sda1", QuotaFmt::QFMT_VFS_V1, "aquota.user").unwrap(); + //! let mut dqblk: Dqblk = Default::default(); + //! dqblk.set_blocks_hard_limit(10000); + //! dqblk.set_blocks_soft_limit(8000); +-//! quotactl_set(QuotaType::USRQUOTA, "/dev/sda1", 50, &dqblk, QuotaValidFlags::QIF_BLIMITS); ++//! quotactl_set(QuotaType::USRQUOTA, "/dev/sda1", 50, &dqblk, QuotaValidFlags::QIF_BLIMITS).unwrap(); + //! ``` ++use crate::errno::Errno; ++use crate::{NixPath, Result}; ++use libc::{self, c_char, c_int}; + use std::default::Default; + use std::{mem, ptr}; +-use libc::{self, c_int, c_char}; +-use {Result, NixPath}; +-use errno::Errno; + + struct QuotaCmd(QuotaSubCmd, QuotaType); + + impl QuotaCmd { ++ #[allow(unused_unsafe)] + fn as_int(&self) -> c_int { + unsafe { libc::QCMD(self.0 as i32, self.1 as i32) } + } + } + + // linux quota version >= 2 +-libc_enum!{ ++libc_enum! { + #[repr(i32)] + enum QuotaSubCmd { + Q_SYNC, +@@ -38,9 +39,10 @@ libc_enum!{ + } + } + +-libc_enum!{ ++libc_enum! { + /// The scope of the quota. + #[repr(i32)] ++ #[non_exhaustive] + pub enum QuotaType { + /// Specify a user quota + USRQUOTA, +@@ -49,9 +51,10 @@ libc_enum!{ + } + } + +-libc_enum!{ ++libc_enum! { + /// The type of quota format to use. + #[repr(i32)] ++ #[non_exhaustive] + pub enum QuotaFmt { + /// Use the original quota format. + QFMT_VFS_OLD, +@@ -117,7 +120,8 @@ impl Default for Dqblk { + impl Dqblk { + /// The absolute limit on disk quota blocks allocated. + pub fn blocks_hard_limit(&self) -> Option { +- let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); ++ let valid_fields = ++ QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); + if valid_fields.contains(QuotaValidFlags::QIF_BLIMITS) { + Some(self.0.dqb_bhardlimit) + } else { +@@ -132,7 +136,8 @@ impl Dqblk { + + /// Preferred limit on disk quota blocks + pub fn blocks_soft_limit(&self) -> Option { +- let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); ++ let valid_fields = ++ QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); + if valid_fields.contains(QuotaValidFlags::QIF_BLIMITS) { + Some(self.0.dqb_bsoftlimit) + } else { +@@ -147,7 +152,8 @@ impl Dqblk { + + /// Current occupied space (bytes). + pub fn occupied_space(&self) -> Option { +- let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); ++ let valid_fields = ++ QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); + if valid_fields.contains(QuotaValidFlags::QIF_SPACE) { + Some(self.0.dqb_curspace) + } else { +@@ -157,7 +163,8 @@ impl Dqblk { + + /// Maximum number of allocated inodes. + pub fn inodes_hard_limit(&self) -> Option { +- let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); ++ let valid_fields = ++ QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); + if valid_fields.contains(QuotaValidFlags::QIF_ILIMITS) { + Some(self.0.dqb_ihardlimit) + } else { +@@ -172,7 +179,8 @@ impl Dqblk { + + /// Preferred inode limit + pub fn inodes_soft_limit(&self) -> Option { +- let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); ++ let valid_fields = ++ QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); + if valid_fields.contains(QuotaValidFlags::QIF_ILIMITS) { + Some(self.0.dqb_isoftlimit) + } else { +@@ -187,7 +195,8 @@ impl Dqblk { + + /// Current number of allocated inodes. + pub fn allocated_inodes(&self) -> Option { +- let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); ++ let valid_fields = ++ QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); + if valid_fields.contains(QuotaValidFlags::QIF_INODES) { + Some(self.0.dqb_curinodes) + } else { +@@ -197,7 +206,8 @@ impl Dqblk { + + /// Time limit for excessive disk use. + pub fn block_time_limit(&self) -> Option { +- let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); ++ let valid_fields = ++ QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); + if valid_fields.contains(QuotaValidFlags::QIF_BTIME) { + Some(self.0.dqb_btime) + } else { +@@ -212,7 +222,8 @@ impl Dqblk { + + /// Time limit for excessive files. + pub fn inode_time_limit(&self) -> Option { +- let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); ++ let valid_fields = ++ QuotaValidFlags::from_bits_truncate(self.0.dqb_valid); + if valid_fields.contains(QuotaValidFlags::QIF_ITIME) { + Some(self.0.dqb_itime) + } else { +@@ -226,11 +237,18 @@ impl Dqblk { + } + } + +-fn quotactl(cmd: QuotaCmd, special: Option<&P>, id: c_int, addr: *mut c_char) -> Result<()> { ++fn quotactl( ++ cmd: QuotaCmd, ++ special: Option<&P>, ++ id: c_int, ++ addr: *mut c_char, ++) -> Result<()> { + unsafe { + Errno::clear(); + let res = match special { +- Some(dev) => dev.with_nix_path(|path| libc::quotactl(cmd.as_int(), path.as_ptr(), id, addr)), ++ Some(dev) => dev.with_nix_path(|path| { ++ libc::quotactl(cmd.as_int(), path.as_ptr(), id, addr) ++ }), + None => Ok(libc::quotactl(cmd.as_int(), ptr::null(), id, addr)), + }?; + +@@ -239,34 +257,82 @@ fn quotactl(cmd: QuotaCmd, special: Option<&P>, id: c_int, + } + + /// Turn on disk quotas for a block device. +-pub fn quotactl_on(which: QuotaType, special: &P, format: QuotaFmt, quota_file: &P) -> Result<()> { ++pub fn quotactl_on( ++ which: QuotaType, ++ special: &P, ++ format: QuotaFmt, ++ quota_file: &P, ++) -> Result<()> { + quota_file.with_nix_path(|path| { + let mut path_copy = path.to_bytes_with_nul().to_owned(); + let p: *mut c_char = path_copy.as_mut_ptr() as *mut c_char; +- quotactl(QuotaCmd(QuotaSubCmd::Q_QUOTAON, which), Some(special), format as c_int, p) ++ quotactl( ++ QuotaCmd(QuotaSubCmd::Q_QUOTAON, which), ++ Some(special), ++ format as c_int, ++ p, ++ ) + })? + } + + /// Disable disk quotas for a block device. +-pub fn quotactl_off(which: QuotaType, special: &P) -> Result<()> { +- quotactl(QuotaCmd(QuotaSubCmd::Q_QUOTAOFF, which), Some(special), 0, ptr::null_mut()) ++pub fn quotactl_off( ++ which: QuotaType, ++ special: &P, ++) -> Result<()> { ++ quotactl( ++ QuotaCmd(QuotaSubCmd::Q_QUOTAOFF, which), ++ Some(special), ++ 0, ++ ptr::null_mut(), ++ ) + } + + /// Update the on-disk copy of quota usages for a filesystem. +-pub fn quotactl_sync(which: QuotaType, special: Option<&P>) -> Result<()> { +- quotactl(QuotaCmd(QuotaSubCmd::Q_SYNC, which), special, 0, ptr::null_mut()) ++/// ++/// If `special` is `None`, then all file systems with active quotas are sync'd. ++pub fn quotactl_sync( ++ which: QuotaType, ++ special: Option<&P>, ++) -> Result<()> { ++ quotactl( ++ QuotaCmd(QuotaSubCmd::Q_SYNC, which), ++ special, ++ 0, ++ ptr::null_mut(), ++ ) + } + + /// Get disk quota limits and current usage for the given user/group id. +-pub fn quotactl_get(which: QuotaType, special: &P, id: c_int) -> Result { ++pub fn quotactl_get( ++ which: QuotaType, ++ special: &P, ++ id: c_int, ++) -> Result { + let mut dqblk = mem::MaybeUninit::uninit(); +- quotactl(QuotaCmd(QuotaSubCmd::Q_GETQUOTA, which), Some(special), id, dqblk.as_mut_ptr() as *mut c_char)?; +- Ok(unsafe{ Dqblk(dqblk.assume_init())}) ++ quotactl( ++ QuotaCmd(QuotaSubCmd::Q_GETQUOTA, which), ++ Some(special), ++ id, ++ dqblk.as_mut_ptr() as *mut c_char, ++ )?; ++ Ok(unsafe { Dqblk(dqblk.assume_init()) }) + } + + /// Configure quota values for the specified fields for a given user/group id. +-pub fn quotactl_set(which: QuotaType, special: &P, id: c_int, dqblk: &Dqblk, fields: QuotaValidFlags) -> Result<()> { ++pub fn quotactl_set( ++ which: QuotaType, ++ special: &P, ++ id: c_int, ++ dqblk: &Dqblk, ++ fields: QuotaValidFlags, ++) -> Result<()> { + let mut dqblk_copy = *dqblk; + dqblk_copy.0.dqb_valid = fields.bits(); +- quotactl(QuotaCmd(QuotaSubCmd::Q_SETQUOTA, which), Some(special), id, &mut dqblk_copy as *mut _ as *mut c_char) ++ quotactl( ++ QuotaCmd(QuotaSubCmd::Q_SETQUOTA, which), ++ Some(special), ++ id, ++ &mut dqblk_copy as *mut _ as *mut c_char, ++ ) + } +diff --git a/vendor/nix/src/sys/reboot.rs b/vendor/nix/src/sys/reboot.rs +index bafa8fc..02d9816 100644 +--- a/vendor/nix/src/sys/reboot.rs ++++ b/vendor/nix/src/sys/reboot.rs +@@ -1,9 +1,8 @@ + //! Reboot/shutdown or enable/disable Ctrl-Alt-Delete. + +-use {Error, Result}; +-use errno::Errno; +-use libc; +-use void::Void; ++use crate::errno::Errno; ++use crate::Result; ++use std::convert::Infallible; + use std::mem::drop; + + libc_enum! { +@@ -12,21 +11,27 @@ libc_enum! { + /// See [`set_cad_enabled()`](fn.set_cad_enabled.html) for + /// enabling/disabling Ctrl-Alt-Delete. + #[repr(i32)] ++ #[non_exhaustive] + pub enum RebootMode { ++ /// Halt the system. + RB_HALT_SYSTEM, ++ /// Execute a kernel that has been loaded earlier with ++ /// [`kexec_load(2)`](https://man7.org/linux/man-pages/man2/kexec_load.2.html). + RB_KEXEC, ++ /// Stop the system and switch off power, if possible. + RB_POWER_OFF, ++ /// Restart the system. + RB_AUTOBOOT, +- // we do not support Restart2, ++ // we do not support Restart2. ++ /// Suspend the system using software suspend. + RB_SW_SUSPEND, + } + } + +-pub fn reboot(how: RebootMode) -> Result { +- unsafe { +- libc::reboot(how as libc::c_int) +- }; +- Err(Error::Sys(Errno::last())) ++/// Reboots or shuts down the system. ++pub fn reboot(how: RebootMode) -> Result { ++ unsafe { libc::reboot(how as libc::c_int) }; ++ Err(Errno::last()) + } + + /// Enable or disable the reboot keystroke (Ctrl-Alt-Delete). +@@ -38,8 +43,6 @@ pub fn set_cad_enabled(enable: bool) -> Result<()> { + } else { + libc::RB_DISABLE_CAD + }; +- let res = unsafe { +- libc::reboot(cmd) +- }; ++ let res = unsafe { libc::reboot(cmd) }; + Errno::result(res).map(drop) + } +diff --git a/vendor/nix/src/sys/resource.rs b/vendor/nix/src/sys/resource.rs +new file mode 100644 +index 0000000..8927737 +--- /dev/null ++++ b/vendor/nix/src/sys/resource.rs +@@ -0,0 +1,443 @@ ++//! Configure the process resource limits. ++use cfg_if::cfg_if; ++use libc::{c_int, c_long, rusage}; ++ ++use crate::errno::Errno; ++use crate::sys::time::TimeVal; ++use crate::Result; ++pub use libc::rlim_t; ++pub use libc::RLIM_INFINITY; ++use std::mem; ++ ++cfg_if! { ++ if #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))]{ ++ use libc::{__rlimit_resource_t, rlimit}; ++ } else if #[cfg(any( ++ target_os = "freebsd", ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "android", ++ target_os = "dragonfly", ++ all(target_os = "linux", not(target_env = "gnu")) ++ ))]{ ++ use libc::rlimit; ++ } ++} ++ ++libc_enum! { ++ /// Types of process resources. ++ /// ++ /// The Resource enum is platform dependent. Check different platform ++ /// manuals for more details. Some platform links have been provided for ++ /// easier reference (non-exhaustive). ++ /// ++ /// * [Linux](https://man7.org/linux/man-pages/man2/getrlimit.2.html) ++ /// * [FreeBSD](https://www.freebsd.org/cgi/man.cgi?query=setrlimit) ++ /// * [NetBSD](https://man.netbsd.org/setrlimit.2) ++ ++ // linux-gnu uses u_int as resource enum, which is implemented in libc as ++ // well. ++ // ++ // https://gcc.gnu.org/legacy-ml/gcc/2015-08/msg00441.html ++ // https://github.com/rust-lang/libc/blob/master/src/unix/linux_like/linux/gnu/mod.rs ++ #[cfg_attr(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")), repr(u32))] ++ #[cfg_attr(any( ++ target_os = "freebsd", ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "android", ++ target_os = "dragonfly", ++ all(target_os = "linux", not(any(target_env = "gnu", target_env = "uclibc"))) ++ ), repr(i32))] ++ #[non_exhaustive] ++ pub enum Resource { ++ #[cfg(not(any(target_os = "freebsd", target_os = "netbsd", target_os = "openbsd")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// The maximum amount (in bytes) of virtual memory the process is ++ /// allowed to map. ++ RLIMIT_AS, ++ /// The largest size (in bytes) core(5) file that may be created. ++ RLIMIT_CORE, ++ /// The maximum amount of cpu time (in seconds) to be used by each ++ /// process. ++ RLIMIT_CPU, ++ /// The maximum size (in bytes) of the data segment for a process ++ RLIMIT_DATA, ++ /// The largest size (in bytes) file that may be created. ++ RLIMIT_FSIZE, ++ /// The maximum number of open files for this process. ++ RLIMIT_NOFILE, ++ /// The maximum size (in bytes) of the stack segment for a process. ++ RLIMIT_STACK, ++ ++ #[cfg(target_os = "freebsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// The maximum number of kqueues this user id is allowed to create. ++ RLIMIT_KQUEUES, ++ ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// A limit on the combined number of flock locks and fcntl leases that ++ /// this process may establish. ++ RLIMIT_LOCKS, ++ ++ #[cfg(any( ++ target_os = "android", ++ target_os = "freebsd", ++ target_os = "openbsd", ++ target_os = "linux", ++ target_os = "netbsd" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// The maximum size (in bytes) which a process may lock into memory ++ /// using the mlock(2) system call. ++ RLIMIT_MEMLOCK, ++ ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// A limit on the number of bytes that can be allocated for POSIX ++ /// message queues for the real user ID of the calling process. ++ RLIMIT_MSGQUEUE, ++ ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// A ceiling to which the process's nice value can be raised using ++ /// setpriority or nice. ++ RLIMIT_NICE, ++ ++ #[cfg(any( ++ target_os = "android", ++ target_os = "freebsd", ++ target_os = "netbsd", ++ target_os = "openbsd", ++ target_os = "linux", ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// The maximum number of simultaneous processes for this user id. ++ RLIMIT_NPROC, ++ ++ #[cfg(target_os = "freebsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// The maximum number of pseudo-terminals this user id is allowed to ++ /// create. ++ RLIMIT_NPTS, ++ ++ #[cfg(any(target_os = "android", ++ target_os = "freebsd", ++ target_os = "netbsd", ++ target_os = "openbsd", ++ target_os = "linux", ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// When there is memory pressure and swap is available, prioritize ++ /// eviction of a process' resident pages beyond this amount (in bytes). ++ RLIMIT_RSS, ++ ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// A ceiling on the real-time priority that may be set for this process ++ /// using sched_setscheduler and sched_set‐ param. ++ RLIMIT_RTPRIO, ++ ++ #[cfg(any(target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// A limit (in microseconds) on the amount of CPU time that a process ++ /// scheduled under a real-time scheduling policy may con‐ sume without ++ /// making a blocking system call. ++ RLIMIT_RTTIME, ++ ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// A limit on the number of signals that may be queued for the real ++ /// user ID of the calling process. ++ RLIMIT_SIGPENDING, ++ ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// The maximum size (in bytes) of socket buffer usage for this user. ++ RLIMIT_SBSIZE, ++ ++ #[cfg(target_os = "freebsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// The maximum size (in bytes) of the swap space that may be reserved ++ /// or used by all of this user id's processes. ++ RLIMIT_SWAP, ++ ++ #[cfg(target_os = "freebsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// An alias for RLIMIT_AS. ++ RLIMIT_VMEM, ++ } ++} ++ ++/// Get the current processes resource limits ++/// ++/// The special value [`RLIM_INFINITY`] indicates that no limit will be ++/// enforced. ++/// ++/// # Parameters ++/// ++/// * `resource`: The [`Resource`] that we want to get the limits of. ++/// ++/// # Examples ++/// ++/// ``` ++/// # use nix::sys::resource::{getrlimit, Resource}; ++/// ++/// let (soft_limit, hard_limit) = getrlimit(Resource::RLIMIT_NOFILE).unwrap(); ++/// println!("current soft_limit: {}", soft_limit); ++/// println!("current hard_limit: {}", hard_limit); ++/// ``` ++/// ++/// # References ++/// ++/// [getrlimit(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getrlimit.html#tag_16_215) ++/// ++/// [`Resource`]: enum.Resource.html ++pub fn getrlimit(resource: Resource) -> Result<(rlim_t, rlim_t)> { ++ let mut old_rlim = mem::MaybeUninit::::uninit(); ++ ++ cfg_if! { ++ if #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))]{ ++ let res = unsafe { libc::getrlimit(resource as __rlimit_resource_t, old_rlim.as_mut_ptr()) }; ++ } else { ++ let res = unsafe { libc::getrlimit(resource as c_int, old_rlim.as_mut_ptr()) }; ++ } ++ } ++ ++ Errno::result(res).map(|_| { ++ let rlimit { rlim_cur, rlim_max } = unsafe { old_rlim.assume_init() }; ++ (rlim_cur, rlim_max) ++ }) ++} ++ ++/// Set the current processes resource limits ++/// ++/// # Parameters ++/// ++/// * `resource`: The [`Resource`] that we want to set the limits of. ++/// * `soft_limit`: The value that the kernel enforces for the corresponding ++/// resource. ++/// * `hard_limit`: The ceiling for the soft limit. Must be lower or equal to ++/// the current hard limit for non-root users. ++/// ++/// The special value [`RLIM_INFINITY`] indicates that no limit will be ++/// enforced. ++/// ++/// # Examples ++/// ++/// ``` ++/// # use nix::sys::resource::{setrlimit, Resource}; ++/// ++/// let soft_limit = 512; ++/// let hard_limit = 1024; ++/// setrlimit(Resource::RLIMIT_NOFILE, soft_limit, hard_limit).unwrap(); ++/// ``` ++/// ++/// # References ++/// ++/// [setrlimit(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getrlimit.html#tag_16_215) ++/// ++/// [`Resource`]: enum.Resource.html ++/// ++/// Note: `setrlimit` provides a safe wrapper to libc's `setrlimit`. ++pub fn setrlimit( ++ resource: Resource, ++ soft_limit: rlim_t, ++ hard_limit: rlim_t, ++) -> Result<()> { ++ let new_rlim = rlimit { ++ rlim_cur: soft_limit, ++ rlim_max: hard_limit, ++ }; ++ cfg_if! { ++ if #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))]{ ++ let res = unsafe { libc::setrlimit(resource as __rlimit_resource_t, &new_rlim as *const rlimit) }; ++ }else{ ++ let res = unsafe { libc::setrlimit(resource as c_int, &new_rlim as *const rlimit) }; ++ } ++ } ++ ++ Errno::result(res).map(drop) ++} ++ ++libc_enum! { ++ /// Whose resource usage should be returned by [`getrusage`]. ++ #[repr(i32)] ++ #[non_exhaustive] ++ pub enum UsageWho { ++ /// Resource usage for the current process. ++ RUSAGE_SELF, ++ ++ /// Resource usage for all the children that have terminated and been waited for. ++ RUSAGE_CHILDREN, ++ ++ #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// Resource usage for the calling thread. ++ RUSAGE_THREAD, ++ } ++} ++ ++/// Output of `getrusage` with information about resource usage. Some of the fields ++/// may be unused in some platforms, and will be always zeroed out. See their manuals ++/// for details. ++#[repr(transparent)] ++#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] ++pub struct Usage(rusage); ++ ++impl AsRef for Usage { ++ fn as_ref(&self) -> &rusage { ++ &self.0 ++ } ++} ++ ++impl AsMut for Usage { ++ fn as_mut(&mut self) -> &mut rusage { ++ &mut self.0 ++ } ++} ++ ++impl Usage { ++ /// Total amount of time spent executing in user mode. ++ pub fn user_time(&self) -> TimeVal { ++ TimeVal::from(self.0.ru_utime) ++ } ++ ++ /// Total amount of time spent executing in kernel mode. ++ pub fn system_time(&self) -> TimeVal { ++ TimeVal::from(self.0.ru_stime) ++ } ++ ++ /// The resident set size at its peak, in kilobytes. ++ pub fn max_rss(&self) -> c_long { ++ self.0.ru_maxrss ++ } ++ ++ /// Integral value expressed in kilobytes times ticks of execution indicating ++ /// the amount of text memory shared with other processes. ++ pub fn shared_integral(&self) -> c_long { ++ self.0.ru_ixrss ++ } ++ ++ /// Integral value expressed in kilobytes times ticks of execution indicating ++ /// the amount of unshared memory used by data. ++ pub fn unshared_data_integral(&self) -> c_long { ++ self.0.ru_idrss ++ } ++ ++ /// Integral value expressed in kilobytes times ticks of execution indicating ++ /// the amount of unshared memory used for stack space. ++ pub fn unshared_stack_integral(&self) -> c_long { ++ self.0.ru_isrss ++ } ++ ++ /// Number of page faults that were served without resorting to I/O, with pages ++ /// that have been allocated previously by the kernel. ++ pub fn minor_page_faults(&self) -> c_long { ++ self.0.ru_minflt ++ } ++ ++ /// Number of page faults that were served through I/O (i.e. swap). ++ pub fn major_page_faults(&self) -> c_long { ++ self.0.ru_majflt ++ } ++ ++ /// Number of times all of the memory was fully swapped out. ++ pub fn full_swaps(&self) -> c_long { ++ self.0.ru_nswap ++ } ++ ++ /// Number of times a read was done from a block device. ++ pub fn block_reads(&self) -> c_long { ++ self.0.ru_inblock ++ } ++ ++ /// Number of times a write was done to a block device. ++ pub fn block_writes(&self) -> c_long { ++ self.0.ru_oublock ++ } ++ ++ /// Number of IPC messages sent. ++ pub fn ipc_sends(&self) -> c_long { ++ self.0.ru_msgsnd ++ } ++ ++ /// Number of IPC messages received. ++ pub fn ipc_receives(&self) -> c_long { ++ self.0.ru_msgrcv ++ } ++ ++ /// Number of signals received. ++ pub fn signals(&self) -> c_long { ++ self.0.ru_nsignals ++ } ++ ++ /// Number of times a context switch was voluntarily invoked. ++ pub fn voluntary_context_switches(&self) -> c_long { ++ self.0.ru_nvcsw ++ } ++ ++ /// Number of times a context switch was imposed by the kernel (usually due to ++ /// time slice expiring or preemption by a higher priority process). ++ pub fn involuntary_context_switches(&self) -> c_long { ++ self.0.ru_nivcsw ++ } ++} ++ ++/// Get usage information for a process, its children or the current thread ++/// ++/// Real time information can be obtained for either the current process or (in some ++/// systems) thread, but information about children processes is only provided for ++/// those that have terminated and been waited for (see [`super::wait::wait`]). ++/// ++/// Some information may be missing depending on the platform, and the way information ++/// is provided for children may also vary. Check the manuals for details. ++/// ++/// # References ++/// ++/// * [getrusage(2)](https://pubs.opengroup.org/onlinepubs/009696699/functions/getrusage.html) ++/// * [Linux](https://man7.org/linux/man-pages/man2/getrusage.2.html) ++/// * [FreeBSD](https://www.freebsd.org/cgi/man.cgi?query=getrusage) ++/// * [NetBSD](https://man.netbsd.org/getrusage.2) ++/// * [MacOS](https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getrusage.2.html) ++/// ++/// [`UsageWho`]: enum.UsageWho.html ++/// ++/// Note: `getrusage` provides a safe wrapper to libc's [`libc::getrusage`]. ++pub fn getrusage(who: UsageWho) -> Result { ++ unsafe { ++ let mut rusage = mem::MaybeUninit::::uninit(); ++ let res = libc::getrusage(who as c_int, rusage.as_mut_ptr()); ++ Errno::result(res).map(|_| Usage(rusage.assume_init())) ++ } ++} ++ ++#[cfg(test)] ++mod test { ++ use super::{getrusage, UsageWho}; ++ ++ #[test] ++ pub fn test_self_cpu_time() { ++ // Make sure some CPU time is used. ++ let mut numbers: Vec = (1..1_000_000).collect(); ++ numbers.iter_mut().for_each(|item| *item *= 2); ++ ++ // FIXME: this is here to help ensure the compiler does not optimize the whole ++ // thing away. Replace the assert with test::black_box once stabilized. ++ assert_eq!(numbers[100..200].iter().sum::(), 30_100); ++ ++ let usage = getrusage(UsageWho::RUSAGE_SELF) ++ .expect("Failed to call getrusage for SELF"); ++ let rusage = usage.as_ref(); ++ ++ let user = usage.user_time(); ++ assert!(user.tv_sec() > 0 || user.tv_usec() > 0); ++ assert_eq!(user.tv_sec(), rusage.ru_utime.tv_sec); ++ assert_eq!(user.tv_usec(), rusage.ru_utime.tv_usec); ++ } ++} +diff --git a/vendor/nix/src/sys/select.rs b/vendor/nix/src/sys/select.rs +index 32569ac..7a94cff 100644 +--- a/vendor/nix/src/sys/select.rs ++++ b/vendor/nix/src/sys/select.rs +@@ -1,19 +1,31 @@ ++//! Portably monitor a group of file descriptors for readiness. ++use crate::errno::Errno; ++use crate::sys::time::{TimeSpec, TimeVal}; ++use crate::Result; ++use libc::{self, c_int}; ++use std::convert::TryFrom; ++use std::iter::FusedIterator; + use std::mem; ++use std::ops::Range; + use std::os::unix::io::RawFd; + use std::ptr::{null, null_mut}; +-use libc::{self, c_int}; +-use Result; +-use errno::Errno; +-use sys::signal::SigSet; +-use sys::time::{TimeSpec, TimeVal}; + + pub use libc::FD_SETSIZE; + ++/// Contains a set of file descriptors used by [`select`] + #[repr(transparent)] + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct FdSet(libc::fd_set); + ++fn assert_fd_valid(fd: RawFd) { ++ assert!( ++ usize::try_from(fd).map_or(false, |fd| fd < FD_SETSIZE), ++ "fd must be in the range 0..FD_SETSIZE", ++ ); ++} ++ + impl FdSet { ++ /// Create an empty `FdSet` + pub fn new() -> FdSet { + let mut fdset = mem::MaybeUninit::uninit(); + unsafe { +@@ -22,18 +34,25 @@ impl FdSet { + } + } + ++ /// Add a file descriptor to an `FdSet` + pub fn insert(&mut self, fd: RawFd) { ++ assert_fd_valid(fd); + unsafe { libc::FD_SET(fd, &mut self.0) }; + } + ++ /// Remove a file descriptor from an `FdSet` + pub fn remove(&mut self, fd: RawFd) { ++ assert_fd_valid(fd); + unsafe { libc::FD_CLR(fd, &mut self.0) }; + } + +- pub fn contains(&mut self, fd: RawFd) -> bool { +- unsafe { libc::FD_ISSET(fd, &mut self.0) } ++ /// Test an `FdSet` for the presence of a certain file descriptor. ++ pub fn contains(&self, fd: RawFd) -> bool { ++ assert_fd_valid(fd); ++ unsafe { libc::FD_ISSET(fd, &self.0) } + } + ++ /// Remove all file descriptors from this `FdSet`. + pub fn clear(&mut self) { + unsafe { libc::FD_ZERO(&mut self.0) }; + } +@@ -47,26 +66,41 @@ impl FdSet { + /// # Example + /// + /// ``` +- /// # extern crate nix; + /// # use nix::sys::select::FdSet; +- /// # fn main() { + /// let mut set = FdSet::new(); + /// set.insert(4); + /// set.insert(9); + /// assert_eq!(set.highest(), Some(9)); +- /// # } + /// ``` + /// + /// [`select`]: fn.select.html +- pub fn highest(&mut self) -> Option { +- for i in (0..FD_SETSIZE).rev() { +- let i = i as RawFd; +- if unsafe { libc::FD_ISSET(i, self as *mut _ as *mut libc::fd_set) } { +- return Some(i) +- } +- } ++ pub fn highest(&self) -> Option { ++ self.fds(None).next_back() ++ } + +- None ++ /// Returns an iterator over the file descriptors in the set. ++ /// ++ /// For performance, it takes an optional higher bound: the iterator will ++ /// not return any elements of the set greater than the given file ++ /// descriptor. ++ /// ++ /// # Examples ++ /// ++ /// ``` ++ /// # use nix::sys::select::FdSet; ++ /// # use std::os::unix::io::RawFd; ++ /// let mut set = FdSet::new(); ++ /// set.insert(4); ++ /// set.insert(9); ++ /// let fds: Vec = set.fds(None).collect(); ++ /// assert_eq!(fds, vec![4, 9]); ++ /// ``` ++ #[inline] ++ pub fn fds(&self, highest: Option) -> Fds { ++ Fds { ++ set: self, ++ range: 0..highest.map(|h| h as usize + 1).unwrap_or(FD_SETSIZE), ++ } + } + } + +@@ -76,6 +110,46 @@ impl Default for FdSet { + } + } + ++/// Iterator over `FdSet`. ++#[derive(Debug)] ++pub struct Fds<'a> { ++ set: &'a FdSet, ++ range: Range, ++} ++ ++impl<'a> Iterator for Fds<'a> { ++ type Item = RawFd; ++ ++ fn next(&mut self) -> Option { ++ for i in &mut self.range { ++ if self.set.contains(i as RawFd) { ++ return Some(i as RawFd); ++ } ++ } ++ None ++ } ++ ++ #[inline] ++ fn size_hint(&self) -> (usize, Option) { ++ let (_, upper) = self.range.size_hint(); ++ (0, upper) ++ } ++} ++ ++impl<'a> DoubleEndedIterator for Fds<'a> { ++ #[inline] ++ fn next_back(&mut self) -> Option { ++ while let Some(i) = self.range.next_back() { ++ if self.set.contains(i as RawFd) { ++ return Some(i as RawFd); ++ } ++ } ++ None ++ } ++} ++ ++impl<'a> FusedIterator for Fds<'a> {} ++ + /// Monitors file descriptors for readiness + /// + /// Returns the total number of ready file descriptors in all sets. The sets are changed so that all +@@ -96,14 +170,16 @@ impl Default for FdSet { + /// + /// # References + /// +-/// [select(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html) ++/// [select(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html) + /// + /// [`FdSet::highest`]: struct.FdSet.html#method.highest +-pub fn select<'a, N, R, W, E, T>(nfds: N, +- readfds: R, +- writefds: W, +- errorfds: E, +- timeout: T) -> Result ++pub fn select<'a, N, R, W, E, T>( ++ nfds: N, ++ readfds: R, ++ writefds: W, ++ errorfds: E, ++ timeout: T, ++) -> Result + where + N: Into>, + R: Into>, +@@ -117,27 +193,40 @@ where + let timeout = timeout.into(); + + let nfds = nfds.into().unwrap_or_else(|| { +- readfds.iter_mut() ++ readfds ++ .iter_mut() + .chain(writefds.iter_mut()) + .chain(errorfds.iter_mut()) + .map(|set| set.highest().unwrap_or(-1)) + .max() +- .unwrap_or(-1) + 1 ++ .unwrap_or(-1) ++ + 1 + }); + +- let readfds = readfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut()); +- let writefds = writefds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut()); +- let errorfds = errorfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut()); +- let timeout = timeout.map(|tv| tv as *mut _ as *mut libc::timeval) +- .unwrap_or(null_mut()); +- +- let res = unsafe { +- libc::select(nfds, readfds, writefds, errorfds, timeout) +- }; ++ let readfds = readfds ++ .map(|set| set as *mut _ as *mut libc::fd_set) ++ .unwrap_or(null_mut()); ++ let writefds = writefds ++ .map(|set| set as *mut _ as *mut libc::fd_set) ++ .unwrap_or(null_mut()); ++ let errorfds = errorfds ++ .map(|set| set as *mut _ as *mut libc::fd_set) ++ .unwrap_or(null_mut()); ++ let timeout = timeout ++ .map(|tv| tv as *mut _ as *mut libc::timeval) ++ .unwrap_or(null_mut()); ++ ++ let res = ++ unsafe { libc::select(nfds, readfds, writefds, errorfds, timeout) }; + + Errno::result(res) + } + ++feature! { ++#![feature = "signal"] ++ ++use crate::sys::signal::SigSet; ++ + /// Monitors file descriptors for readiness with an altered signal mask. + /// + /// Returns the total number of ready file descriptors in all sets. The sets are changed so that all +@@ -162,16 +251,16 @@ where + /// + /// # References + /// +-/// [pselect(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pselect.html) ++/// [pselect(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pselect.html) + /// + /// [The new pselect() system call](https://lwn.net/Articles/176911/) + /// + /// [`FdSet::highest`]: struct.FdSet.html#method.highest + pub fn pselect<'a, N, R, W, E, T, S>(nfds: N, +- readfds: R, +- writefds: W, +- errorfds: E, +- timeout: T, ++ readfds: R, ++ writefds: W, ++ errorfds: E, ++ timeout: T, + sigmask: S) -> Result + where + N: Into>, +@@ -208,14 +297,14 @@ where + + Errno::result(res) + } +- ++} + + #[cfg(test)] + mod tests { + use super::*; ++ use crate::sys::time::{TimeVal, TimeValLike}; ++ use crate::unistd::{pipe, write}; + use std::os::unix::io::RawFd; +- use sys::time::{TimeVal, TimeValLike}; +- use unistd::{write, pipe}; + + #[test] + fn fdset_insert() { +@@ -279,6 +368,20 @@ mod tests { + assert_eq!(set.highest(), Some(7)); + } + ++ #[test] ++ fn fdset_fds() { ++ let mut set = FdSet::new(); ++ assert_eq!(set.fds(None).collect::>(), vec![]); ++ set.insert(0); ++ assert_eq!(set.fds(None).collect::>(), vec![0]); ++ set.insert(90); ++ assert_eq!(set.fds(None).collect::>(), vec![0, 90]); ++ ++ // highest limit ++ assert_eq!(set.fds(Some(89)).collect::>(), vec![0]); ++ assert_eq!(set.fds(Some(90)).collect::>(), vec![0, 90]); ++ } ++ + #[test] + fn test_select() { + let (r1, w1) = pipe().unwrap(); +@@ -290,11 +393,10 @@ mod tests { + fd_set.insert(r2); + + let mut timeout = TimeVal::seconds(10); +- assert_eq!(1, select(None, +- &mut fd_set, +- None, +- None, +- &mut timeout).unwrap()); ++ assert_eq!( ++ 1, ++ select(None, &mut fd_set, None, None, &mut timeout).unwrap() ++ ); + assert!(fd_set.contains(r1)); + assert!(!fd_set.contains(r2)); + } +@@ -310,11 +412,17 @@ mod tests { + fd_set.insert(r2); + + let mut timeout = TimeVal::seconds(10); +- assert_eq!(1, select(Some(fd_set.highest().unwrap() + 1), +- &mut fd_set, +- None, +- None, +- &mut timeout).unwrap()); ++ assert_eq!( ++ 1, ++ select( ++ Some(fd_set.highest().unwrap() + 1), ++ &mut fd_set, ++ None, ++ None, ++ &mut timeout ++ ) ++ .unwrap() ++ ); + assert!(fd_set.contains(r1)); + assert!(!fd_set.contains(r2)); + } +@@ -330,11 +438,17 @@ mod tests { + fd_set.insert(r2); + + let mut timeout = TimeVal::seconds(10); +- assert_eq!(1, select(::std::cmp::max(r1, r2) + 1, +- &mut fd_set, +- None, +- None, +- &mut timeout).unwrap()); ++ assert_eq!( ++ 1, ++ select( ++ ::std::cmp::max(r1, r2) + 1, ++ &mut fd_set, ++ None, ++ None, ++ &mut timeout ++ ) ++ .unwrap() ++ ); + assert!(fd_set.contains(r1)); + assert!(!fd_set.contains(r2)); + } +diff --git a/vendor/nix/src/sys/sendfile.rs b/vendor/nix/src/sys/sendfile.rs +index 1618558..fb293a4 100644 +--- a/vendor/nix/src/sys/sendfile.rs ++++ b/vendor/nix/src/sys/sendfile.rs +@@ -1,10 +1,13 @@ ++//! Send data from a file to a socket, bypassing userland. ++ ++use cfg_if::cfg_if; + use std::os::unix::io::RawFd; + use std::ptr; + + use libc::{self, off_t}; + +-use Result; +-use errno::Errno; ++use crate::errno::Errno; ++use crate::Result; + + /// Copy up to `count` bytes to `out_fd` from `in_fd` starting at `offset`. + /// +@@ -17,8 +20,9 @@ use errno::Errno; + /// + /// `in_fd` must support `mmap`-like operations and therefore cannot be a socket. + /// +-/// For more information, see [the sendfile(2) man page.](http://man7.org/linux/man-pages/man2/sendfile.2.html) ++/// For more information, see [the sendfile(2) man page.](https://man7.org/linux/man-pages/man2/sendfile.2.html) + #[cfg(any(target_os = "android", target_os = "linux"))] ++#[cfg_attr(docsrs, doc(cfg(all())))] + pub fn sendfile( + out_fd: RawFd, + in_fd: RawFd, +@@ -32,17 +36,45 @@ pub fn sendfile( + Errno::result(ret).map(|r| r as usize) + } + ++/// Copy up to `count` bytes to `out_fd` from `in_fd` starting at `offset`. ++/// ++/// Returns a `Result` with the number of bytes written. ++/// ++/// If `offset` is `None`, `sendfile` will begin reading at the current offset of `in_fd`and will ++/// update the offset of `in_fd`. If `offset` is `Some`, `sendfile` will begin at the specified ++/// offset and will not update the offset of `in_fd`. Instead, it will mutate `offset` to point to ++/// the byte after the last byte copied. ++/// ++/// `in_fd` must support `mmap`-like operations and therefore cannot be a socket. ++/// ++/// For more information, see [the sendfile(2) man page.](https://man7.org/linux/man-pages/man2/sendfile.2.html) ++#[cfg(target_os = "linux")] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++pub fn sendfile64( ++ out_fd: RawFd, ++ in_fd: RawFd, ++ offset: Option<&mut libc::off64_t>, ++ count: usize, ++) -> Result { ++ let offset = offset ++ .map(|offset| offset as *mut _) ++ .unwrap_or(ptr::null_mut()); ++ let ret = unsafe { libc::sendfile64(out_fd, in_fd, offset, count) }; ++ Errno::result(ret).map(|r| r as usize) ++} ++ + cfg_if! { +- if #[cfg(any(target_os = "freebsd", ++ if #[cfg(any(target_os = "dragonfly", ++ target_os = "freebsd", + target_os = "ios", + target_os = "macos"))] { +- use sys::uio::IoVec; ++ use std::io::IoSlice; + +- #[derive(Clone, Debug, Eq, Hash, PartialEq)] ++ #[derive(Clone, Debug)] + struct SendfileHeaderTrailer<'a>( + libc::sf_hdtr, +- Option>>, +- Option>>, ++ Option>>, ++ Option>>, + ); + + impl<'a> SendfileHeaderTrailer<'a> { +@@ -50,10 +82,10 @@ cfg_if! { + headers: Option<&'a [&'a [u8]]>, + trailers: Option<&'a [&'a [u8]]> + ) -> SendfileHeaderTrailer<'a> { +- let header_iovecs: Option>> = +- headers.map(|s| s.iter().map(|b| IoVec::from_slice(b)).collect()); +- let trailer_iovecs: Option>> = +- trailers.map(|s| s.iter().map(|b| IoVec::from_slice(b)).collect()); ++ let header_iovecs: Option>> = ++ headers.map(|s| s.iter().map(|b| IoSlice::new(b)).collect()); ++ let trailer_iovecs: Option>> = ++ trailers.map(|s| s.iter().map(|b| IoSlice::new(b)).collect()); + SendfileHeaderTrailer( + libc::sf_hdtr { + headers: { +@@ -153,6 +185,49 @@ cfg_if! { + }; + (Errno::result(return_code).and(Ok(())), bytes_sent) + } ++ } else if #[cfg(target_os = "dragonfly")] { ++ /// Read up to `count` bytes from `in_fd` starting at `offset` and write to `out_sock`. ++ /// ++ /// Returns a `Result` and a count of bytes written. Bytes written may be non-zero even if ++ /// an error occurs. ++ /// ++ /// `in_fd` must describe a regular file. `out_sock` must describe a stream socket. ++ /// ++ /// If `offset` falls past the end of the file, the function returns success and zero bytes ++ /// written. ++ /// ++ /// If `count` is `None` or 0, bytes will be read from `in_fd` until reaching the end of ++ /// file (EOF). ++ /// ++ /// `headers` and `trailers` specify optional slices of byte slices to be sent before and ++ /// after the data read from `in_fd`, respectively. The length of headers and trailers sent ++ /// is included in the returned count of bytes written. The values of `offset` and `count` ++ /// do not apply to headers or trailers. ++ /// ++ /// For more information, see ++ /// [the sendfile(2) man page.](https://leaf.dragonflybsd.org/cgi/web-man?command=sendfile§ion=2) ++ pub fn sendfile( ++ in_fd: RawFd, ++ out_sock: RawFd, ++ offset: off_t, ++ count: Option, ++ headers: Option<&[&[u8]]>, ++ trailers: Option<&[&[u8]]>, ++ ) -> (Result<()>, off_t) { ++ let mut bytes_sent: off_t = 0; ++ let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers)); ++ let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr); ++ let return_code = unsafe { ++ libc::sendfile(in_fd, ++ out_sock, ++ offset, ++ count.unwrap_or(0), ++ hdtr_ptr as *mut libc::sf_hdtr, ++ &mut bytes_sent as *mut off_t, ++ 0) ++ }; ++ (Errno::result(return_code).and(Ok(())), bytes_sent) ++ } + } else if #[cfg(any(target_os = "ios", target_os = "macos"))] { + /// Read bytes from `in_fd` starting at `offset` and write up to `count` bytes to + /// `out_sock`. +diff --git a/vendor/nix/src/sys/signal.rs b/vendor/nix/src/sys/signal.rs +index b746b3d..d3746e6 100644 +--- a/vendor/nix/src/sys/signal.rs ++++ b/vendor/nix/src/sys/signal.rs +@@ -1,70 +1,121 @@ + // Portions of this file are Copyright 2014 The Rust Project Developers. +-// See http://rust-lang.org/COPYRIGHT. ++// See https://www.rust-lang.org/policies/licenses. + +-///! Operating system signals. ++//! Operating system signals. + +-use libc; +-use {Error, Result}; +-use errno::Errno; +-use std::convert::TryFrom; +-use std::mem; ++use crate::errno::Errno; ++use crate::{Error, Result}; ++use cfg_if::cfg_if; + use std::fmt; +-use std::str::FromStr; ++use std::mem; + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + use std::os::unix::io::RawFd; + use std::ptr; ++use std::str::FromStr; + +-#[cfg(not(target_os = "openbsd"))] ++#[cfg(not(any(target_os = "openbsd", target_os = "redox")))] ++#[cfg(any(feature = "aio", feature = "signal"))] + pub use self::sigevent::*; + +-libc_enum!{ ++#[cfg(any(feature = "aio", feature = "process", feature = "signal"))] ++libc_enum! { ++ /// Types of operating system signals + // Currently there is only one definition of c_int in libc, as well as only one + // type for signal constants. + // We would prefer to use the libc::c_int alias in the repr attribute. Unfortunately + // this is not (yet) possible. + #[repr(i32)] ++ #[non_exhaustive] ++ #[cfg_attr(docsrs, doc(cfg(any(feature = "aio", feature = "signal"))))] + pub enum Signal { ++ /// Hangup + SIGHUP, ++ /// Interrupt + SIGINT, ++ /// Quit + SIGQUIT, ++ /// Illegal instruction (not reset when caught) + SIGILL, ++ /// Trace trap (not reset when caught) + SIGTRAP, ++ /// Abort + SIGABRT, ++ /// Bus error + SIGBUS, ++ /// Floating point exception + SIGFPE, ++ /// Kill (cannot be caught or ignored) + SIGKILL, ++ /// User defined signal 1 + SIGUSR1, ++ /// Segmentation violation + SIGSEGV, ++ /// User defined signal 2 + SIGUSR2, ++ /// Write on a pipe with no one to read it + SIGPIPE, ++ /// Alarm clock + SIGALRM, ++ /// Software termination signal from kill + SIGTERM, +- #[cfg(all(any(target_os = "android", target_os = "emscripten", target_os = "linux"), +- not(any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64"))))] ++ /// Stack fault (obsolete) ++ #[cfg(all(any(target_os = "android", target_os = "emscripten", ++ target_os = "fuchsia", target_os = "linux"), ++ not(any(target_arch = "mips", target_arch = "mips64", ++ target_arch = "sparc64"))))] + SIGSTKFLT, ++ /// To parent on child stop or exit + SIGCHLD, ++ /// Continue a stopped process + SIGCONT, ++ /// Sendable stop signal not from tty + SIGSTOP, ++ /// Stop signal from tty + SIGTSTP, ++ /// To readers pgrp upon background tty read + SIGTTIN, ++ /// Like TTIN if (tp->t_local<OSTOP) + SIGTTOU, ++ /// Urgent condition on IO channel + SIGURG, ++ /// Exceeded CPU time limit + SIGXCPU, ++ /// Exceeded file size limit + SIGXFSZ, ++ /// Virtual time alarm + SIGVTALRM, ++ /// Profiling time alarm + SIGPROF, ++ /// Window size changes + SIGWINCH, ++ /// Input/output possible signal ++ #[cfg(not(target_os = "haiku"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + SIGIO, +- #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux"))] ++ #[cfg(any(target_os = "android", target_os = "emscripten", ++ target_os = "fuchsia", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// Power failure imminent. + SIGPWR, ++ /// Bad system call + SIGSYS, +- #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))] ++ #[cfg(not(any(target_os = "android", target_os = "emscripten", ++ target_os = "fuchsia", target_os = "linux", ++ target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// Emulator trap + SIGEMT, +- #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))] ++ #[cfg(not(any(target_os = "android", target_os = "emscripten", ++ target_os = "fuchsia", target_os = "linux", ++ target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ /// Information request + SIGINFO, + } ++ impl TryFrom + } + ++#[cfg(feature = "signal")] + impl FromStr for Signal { + type Err = Error; + fn from_str(s: &str) -> Result { +@@ -84,8 +135,19 @@ impl FromStr for Signal { + "SIGPIPE" => Signal::SIGPIPE, + "SIGALRM" => Signal::SIGALRM, + "SIGTERM" => Signal::SIGTERM, +- #[cfg(all(any(target_os = "android", target_os = "emscripten", target_os = "linux"), +- not(any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64"))))] ++ #[cfg(all( ++ any( ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "linux" ++ ), ++ not(any( ++ target_arch = "mips", ++ target_arch = "mips64", ++ target_arch = "sparc64" ++ )) ++ ))] + "SIGSTKFLT" => Signal::SIGSTKFLT, + "SIGCHLD" => Signal::SIGCHLD, + "SIGCONT" => Signal::SIGCONT, +@@ -99,26 +161,47 @@ impl FromStr for Signal { + "SIGVTALRM" => Signal::SIGVTALRM, + "SIGPROF" => Signal::SIGPROF, + "SIGWINCH" => Signal::SIGWINCH, ++ #[cfg(not(target_os = "haiku"))] + "SIGIO" => Signal::SIGIO, +- #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux"))] ++ #[cfg(any( ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "linux" ++ ))] + "SIGPWR" => Signal::SIGPWR, + "SIGSYS" => Signal::SIGSYS, +- #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))] ++ #[cfg(not(any( ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "linux", ++ target_os = "redox", ++ target_os = "haiku" ++ )))] + "SIGEMT" => Signal::SIGEMT, +- #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))] ++ #[cfg(not(any( ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "linux", ++ target_os = "redox", ++ target_os = "haiku" ++ )))] + "SIGINFO" => Signal::SIGINFO, +- _ => return Err(Error::invalid_argument()), ++ _ => return Err(Errno::EINVAL), + }) + } + } + ++#[cfg(feature = "signal")] + impl Signal { + /// Returns name of signal. + /// + /// This function is equivalent to `>::as_ref()`, + /// with difference that returned string is `'static` + /// and not bound to `self`'s lifetime. +- pub fn as_str(self) -> &'static str { ++ pub const fn as_str(self) -> &'static str { + match self { + Signal::SIGHUP => "SIGHUP", + Signal::SIGINT => "SIGINT", +@@ -135,8 +218,19 @@ impl Signal { + Signal::SIGPIPE => "SIGPIPE", + Signal::SIGALRM => "SIGALRM", + Signal::SIGTERM => "SIGTERM", +- #[cfg(all(any(target_os = "android", target_os = "emscripten", target_os = "linux"), +- not(any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64"))))] ++ #[cfg(all( ++ any( ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "linux" ++ ), ++ not(any( ++ target_arch = "mips", ++ target_arch = "mips64", ++ target_arch = "sparc64" ++ )) ++ ))] + Signal::SIGSTKFLT => "SIGSTKFLT", + Signal::SIGCHLD => "SIGCHLD", + Signal::SIGCONT => "SIGCONT", +@@ -150,134 +244,128 @@ impl Signal { + Signal::SIGVTALRM => "SIGVTALRM", + Signal::SIGPROF => "SIGPROF", + Signal::SIGWINCH => "SIGWINCH", ++ #[cfg(not(target_os = "haiku"))] + Signal::SIGIO => "SIGIO", +- #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux"))] ++ #[cfg(any( ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "linux" ++ ))] + Signal::SIGPWR => "SIGPWR", + Signal::SIGSYS => "SIGSYS", +- #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))] ++ #[cfg(not(any( ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "linux", ++ target_os = "redox", ++ target_os = "haiku" ++ )))] + Signal::SIGEMT => "SIGEMT", +- #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))] ++ #[cfg(not(any( ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "linux", ++ target_os = "redox", ++ target_os = "haiku" ++ )))] + Signal::SIGINFO => "SIGINFO", + } + } + } + ++#[cfg(feature = "signal")] + impl AsRef for Signal { + fn as_ref(&self) -> &str { + self.as_str() + } + } + ++#[cfg(feature = "signal")] + impl fmt::Display for Signal { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(self.as_ref()) + } + } + ++#[cfg(feature = "signal")] + pub use self::Signal::*; + +-#[cfg(all(any(target_os = "linux", target_os = "android", target_os = "emscripten"), not(any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64"))))] ++#[cfg(target_os = "redox")] ++#[cfg(feature = "signal")] ++const SIGNALS: [Signal; 29] = [ ++ SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL, ++ SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGCONT, ++ SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, ++ SIGPROF, SIGWINCH, SIGIO, SIGSYS, ++]; ++#[cfg(target_os = "haiku")] ++#[cfg(feature = "signal")] ++const SIGNALS: [Signal; 28] = [ ++ SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL, ++ SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGCONT, ++ SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, ++ SIGPROF, SIGWINCH, SIGSYS, ++]; ++#[cfg(all( ++ any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia" ++ ), ++ not(any( ++ target_arch = "mips", ++ target_arch = "mips64", ++ target_arch = "sparc64" ++ )) ++))] ++#[cfg(feature = "signal")] + const SIGNALS: [Signal; 31] = [ +- SIGHUP, +- SIGINT, +- SIGQUIT, +- SIGILL, +- SIGTRAP, +- SIGABRT, +- SIGBUS, +- SIGFPE, +- SIGKILL, +- SIGUSR1, +- SIGSEGV, +- SIGUSR2, +- SIGPIPE, +- SIGALRM, +- SIGTERM, +- SIGSTKFLT, +- SIGCHLD, +- SIGCONT, +- SIGSTOP, +- SIGTSTP, +- SIGTTIN, +- SIGTTOU, +- SIGURG, +- SIGXCPU, +- SIGXFSZ, +- SIGVTALRM, +- SIGPROF, +- SIGWINCH, +- SIGIO, +- SIGPWR, +- SIGSYS]; +-#[cfg(all(any(target_os = "linux", target_os = "android", target_os = "emscripten"), any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64")))] ++ SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL, ++ SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGSTKFLT, SIGCHLD, ++ SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, ++ SIGVTALRM, SIGPROF, SIGWINCH, SIGIO, SIGPWR, SIGSYS, ++]; ++#[cfg(all( ++ any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia" ++ ), ++ any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64") ++))] ++#[cfg(feature = "signal")] + const SIGNALS: [Signal; 30] = [ +- SIGHUP, +- SIGINT, +- SIGQUIT, +- SIGILL, +- SIGTRAP, +- SIGABRT, +- SIGBUS, +- SIGFPE, +- SIGKILL, +- SIGUSR1, +- SIGSEGV, +- SIGUSR2, +- SIGPIPE, +- SIGALRM, +- SIGTERM, +- SIGCHLD, +- SIGCONT, +- SIGSTOP, +- SIGTSTP, +- SIGTTIN, +- SIGTTOU, +- SIGURG, +- SIGXCPU, +- SIGXFSZ, +- SIGVTALRM, +- SIGPROF, +- SIGWINCH, +- SIGIO, +- SIGPWR, +- SIGSYS]; +-#[cfg(not(any(target_os = "linux", target_os = "android", target_os = "emscripten")))] ++ SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL, ++ SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGCONT, ++ SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, ++ SIGPROF, SIGWINCH, SIGIO, SIGPWR, SIGSYS, ++]; ++#[cfg(not(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "fuchsia", ++ target_os = "emscripten", ++ target_os = "redox", ++ target_os = "haiku" ++)))] ++#[cfg(feature = "signal")] + const SIGNALS: [Signal; 31] = [ +- SIGHUP, +- SIGINT, +- SIGQUIT, +- SIGILL, +- SIGTRAP, +- SIGABRT, +- SIGBUS, +- SIGFPE, +- SIGKILL, +- SIGUSR1, +- SIGSEGV, +- SIGUSR2, +- SIGPIPE, +- SIGALRM, +- SIGTERM, +- SIGCHLD, +- SIGCONT, +- SIGSTOP, +- SIGTSTP, +- SIGTTIN, +- SIGTTOU, +- SIGURG, +- SIGXCPU, +- SIGXFSZ, +- SIGVTALRM, +- SIGPROF, +- SIGWINCH, +- SIGIO, +- SIGSYS, +- SIGEMT, +- SIGINFO]; +- +-pub const NSIG: libc::c_int = 32; ++ SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL, ++ SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGCONT, ++ SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, ++ SIGPROF, SIGWINCH, SIGIO, SIGSYS, SIGEMT, SIGINFO, ++]; ++ ++feature! { ++#![feature = "signal"] + + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] ++/// Iterate through all signals defined by this operating system + pub struct SignalIterator { + next: usize, + } +@@ -297,55 +385,97 @@ impl Iterator for SignalIterator { + } + + impl Signal { +- pub fn iterator() -> SignalIterator { ++ /// Iterate through all signals defined by this OS ++ pub const fn iterator() -> SignalIterator { + SignalIterator{next: 0} + } + } + +-impl TryFrom for Signal { +- type Error = Error; +- +- fn try_from(signum: libc::c_int) -> Result { +- if 0 < signum && signum < NSIG { +- Ok(unsafe { mem::transmute(signum) }) +- } else { +- Err(Error::invalid_argument()) +- } +- } +-} +- ++/// Alias for [`SIGABRT`] + pub const SIGIOT : Signal = SIGABRT; ++/// Alias for [`SIGIO`] ++#[cfg(not(target_os = "haiku"))] + pub const SIGPOLL : Signal = SIGIO; ++/// Alias for [`SIGSYS`] + pub const SIGUNUSED : Signal = SIGSYS; + +-libc_bitflags!{ +- pub struct SaFlags: libc::c_int { ++cfg_if! { ++ if #[cfg(target_os = "redox")] { ++ type SaFlags_t = libc::c_ulong; ++ } else if #[cfg(target_env = "uclibc")] { ++ type SaFlags_t = libc::c_ulong; ++ } else { ++ type SaFlags_t = libc::c_int; ++ } ++} ++} ++ ++#[cfg(feature = "signal")] ++libc_bitflags! { ++ /// Controls the behavior of a [`SigAction`] ++ #[cfg_attr(docsrs, doc(cfg(feature = "signal")))] ++ pub struct SaFlags: SaFlags_t { ++ /// When catching a [`Signal::SIGCHLD`] signal, the signal will be ++ /// generated only when a child process exits, not when a child process ++ /// stops. + SA_NOCLDSTOP; ++ /// When catching a [`Signal::SIGCHLD`] signal, the system will not ++ /// create zombie processes when children of the calling process exit. + SA_NOCLDWAIT; ++ /// Further occurrences of the delivered signal are not masked during ++ /// the execution of the handler. + SA_NODEFER; ++ /// The system will deliver the signal to the process on a signal stack, ++ /// specified by each thread with sigaltstack(2). + SA_ONSTACK; ++ /// The handler is reset back to the default at the moment the signal is ++ /// delivered. + SA_RESETHAND; ++ /// Requests that certain system calls restart if interrupted by this ++ /// signal. See the man page for complete details. + SA_RESTART; ++ /// This flag is controlled internally by Nix. + SA_SIGINFO; + } + } + ++#[cfg(feature = "signal")] + libc_enum! { ++ /// Specifies how certain functions should manipulate a signal mask + #[repr(i32)] ++ #[non_exhaustive] ++ #[cfg_attr(docsrs, doc(cfg(feature = "signal")))] + pub enum SigmaskHow { ++ /// The new mask is the union of the current mask and the specified set. + SIG_BLOCK, ++ /// The new mask is the intersection of the current mask and the ++ /// complement of the specified set. + SIG_UNBLOCK, ++ /// The current mask is replaced by the specified set. + SIG_SETMASK, + } + } + ++feature! { ++#![feature = "signal"] ++ ++use crate::unistd::Pid; ++use std::iter::Extend; ++use std::iter::FromIterator; ++use std::iter::IntoIterator; ++ ++/// Specifies a set of [`Signal`]s that may be blocked, waited for, etc. ++// We are using `transparent` here to be super sure that `SigSet` ++// is represented exactly like the `sigset_t` struct from C. ++#[repr(transparent)] + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct SigSet { + sigset: libc::sigset_t + } + +- + impl SigSet { ++ /// Initialize to include all signals. ++ #[doc(alias("sigfillset"))] + pub fn all() -> SigSet { + let mut sigset = mem::MaybeUninit::uninit(); + let _ = unsafe { libc::sigfillset(sigset.as_mut_ptr()) }; +@@ -353,6 +483,8 @@ impl SigSet { + unsafe{ SigSet { sigset: sigset.assume_init() } } + } + ++ /// Initialize to include nothing. ++ #[doc(alias("sigemptyset"))] + pub fn empty() -> SigSet { + let mut sigset = mem::MaybeUninit::uninit(); + let _ = unsafe { libc::sigemptyset(sigset.as_mut_ptr()) }; +@@ -360,18 +492,26 @@ impl SigSet { + unsafe{ SigSet { sigset: sigset.assume_init() } } + } + ++ /// Add the specified signal to the set. ++ #[doc(alias("sigaddset"))] + pub fn add(&mut self, signal: Signal) { + unsafe { libc::sigaddset(&mut self.sigset as *mut libc::sigset_t, signal as libc::c_int) }; + } + ++ /// Remove all signals from this set. ++ #[doc(alias("sigemptyset"))] + pub fn clear(&mut self) { + unsafe { libc::sigemptyset(&mut self.sigset as *mut libc::sigset_t) }; + } + ++ /// Remove the specified signal from this set. ++ #[doc(alias("sigdelset"))] + pub fn remove(&mut self, signal: Signal) { + unsafe { libc::sigdelset(&mut self.sigset as *mut libc::sigset_t, signal as libc::c_int) }; + } + ++ /// Return whether this set includes the specified signal. ++ #[doc(alias("sigismember"))] + pub fn contains(&self, signal: Signal) -> bool { + let res = unsafe { libc::sigismember(&self.sigset as *const libc::sigset_t, signal as libc::c_int) }; + +@@ -382,12 +522,9 @@ impl SigSet { + } + } + +- pub fn extend(&mut self, other: &SigSet) { +- for signal in Signal::iterator() { +- if other.contains(signal) { +- self.add(signal); +- } +- } ++ /// Returns an iterator that yields the signals contained in this set. ++ pub fn iter(&self) -> SigSetIter<'_> { ++ self.into_iter() + } + + /// Gets the currently blocked (masked) set of signals for the calling thread. +@@ -421,7 +558,11 @@ impl SigSet { + + /// Suspends execution of the calling thread until one of the signals in the + /// signal mask becomes pending, and returns the accepted signal. ++ #[cfg(not(target_os = "redox"))] // RedoxFS does not yet support sigwait ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn wait(&self) -> Result { ++ use std::convert::TryFrom; ++ + let mut signum = mem::MaybeUninit::uninit(); + let res = unsafe { libc::sigwait(&self.sigset as *const libc::sigset_t, signum.as_mut_ptr()) }; + +@@ -429,6 +570,19 @@ impl SigSet { + Signal::try_from(signum.assume_init()).unwrap() + }) + } ++ ++ /// Converts a `libc::sigset_t` object to a [`SigSet`] without checking whether the ++ /// `libc::sigset_t` is already initialized. ++ /// ++ /// # Safety ++ /// ++ /// The `sigset` passed in must be a valid an initialized `libc::sigset_t` by calling either ++ /// [`sigemptyset(3)`](https://man7.org/linux/man-pages/man3/sigemptyset.3p.html) or ++ /// [`sigfillset(3)`](https://man7.org/linux/man-pages/man3/sigfillset.3p.html). ++ /// Otherwise, the results are undefined. ++ pub unsafe fn from_sigset_t_unchecked(sigset: libc::sigset_t) -> SigSet { ++ SigSet { sigset } ++ } + } + + impl AsRef for SigSet { +@@ -437,6 +591,55 @@ impl AsRef for SigSet { + } + } + ++// TODO: Consider specialization for the case where T is &SigSet and libc::sigorset is available. ++impl Extend for SigSet { ++ fn extend(&mut self, iter: T) ++ where T: IntoIterator { ++ for signal in iter { ++ self.add(signal); ++ } ++ } ++} ++ ++impl FromIterator for SigSet { ++ fn from_iter(iter: T) -> Self ++ where T: IntoIterator { ++ let mut sigset = SigSet::empty(); ++ sigset.extend(iter); ++ sigset ++ } ++} ++ ++/// Iterator for a [`SigSet`]. ++/// ++/// Call [`SigSet::iter`] to create an iterator. ++#[derive(Clone, Debug)] ++pub struct SigSetIter<'a> { ++ sigset: &'a SigSet, ++ inner: SignalIterator, ++} ++ ++impl Iterator for SigSetIter<'_> { ++ type Item = Signal; ++ fn next(&mut self) -> Option { ++ loop { ++ match self.inner.next() { ++ None => return None, ++ Some(signal) if self.sigset.contains(signal) => return Some(signal), ++ Some(_signal) => continue, ++ } ++ } ++ } ++} ++ ++impl<'a> IntoIterator for &'a SigSet { ++ type Item = Signal; ++ type IntoIter = SigSetIter<'a>; ++ fn into_iter(self) -> Self::IntoIter { ++ SigSetIter { sigset: self, inner: Signal::iterator() } ++ } ++} ++ + /// A signal handler. + #[allow(unknown_lints)] + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +@@ -449,6 +652,8 @@ pub enum SigHandler { + Handler(extern fn(libc::c_int)), + /// Use the given signal-catching function, which takes in the signal, information about how + /// the signal was generated, and a pointer to the threads `ucontext_t`. ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + SigAction(extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void)) + } + +@@ -465,16 +670,22 @@ impl SigAction { + /// is the `SigAction` variant). `mask` specifies other signals to block during execution of + /// the signal-catching function. + pub fn new(handler: SigHandler, flags: SaFlags, mask: SigSet) -> SigAction { +- let mut s = mem::MaybeUninit::::uninit(); +- unsafe { +- let p = s.as_mut_ptr(); ++ unsafe fn install_sig(p: *mut libc::sigaction, handler: SigHandler) { + (*p).sa_sigaction = match handler { + SigHandler::SigDfl => libc::SIG_DFL, + SigHandler::SigIgn => libc::SIG_IGN, + SigHandler::Handler(f) => f as *const extern fn(libc::c_int) as usize, ++ #[cfg(not(target_os = "redox"))] + SigHandler::SigAction(f) => f as *const extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void) as usize, + }; ++ } ++ ++ let mut s = mem::MaybeUninit::::uninit(); ++ unsafe { ++ let p = s.as_mut_ptr(); ++ install_sig(p, handler); + (*p).sa_flags = match handler { ++ #[cfg(not(target_os = "redox"))] + SigHandler::SigAction(_) => (flags | SaFlags::SA_SIGINFO).bits(), + _ => (flags - SaFlags::SA_SIGINFO).bits(), + }; +@@ -500,9 +711,32 @@ impl SigAction { + match self.sigaction.sa_sigaction { + libc::SIG_DFL => SigHandler::SigDfl, + libc::SIG_IGN => SigHandler::SigIgn, +- f if self.flags().contains(SaFlags::SA_SIGINFO) => +- SigHandler::SigAction( unsafe { mem::transmute(f) } ), +- f => SigHandler::Handler( unsafe { mem::transmute(f) } ), ++ #[cfg(not(target_os = "redox"))] ++ p if self.flags().contains(SaFlags::SA_SIGINFO) => ++ SigHandler::SigAction( ++ // Safe for one of two reasons: ++ // * The SigHandler was created by SigHandler::new, in which ++ // case the pointer is correct, or ++ // * The SigHandler was created by signal or sigaction, which ++ // are unsafe functions, so the caller should've somehow ++ // ensured that it is correctly initialized. ++ unsafe{ ++ *(&p as *const usize ++ as *const extern fn(_, _, _)) ++ } ++ as extern fn(_, _, _)), ++ p => SigHandler::Handler( ++ // Safe for one of two reasons: ++ // * The SigHandler was created by SigHandler::new, in which ++ // case the pointer is correct, or ++ // * The SigHandler was created by signal or sigaction, which ++ // are unsafe functions, so the caller should've somehow ++ // ensured that it is correctly initialized. ++ unsafe{ ++ *(&p as *const usize ++ as *const extern fn(libc::c_int)) ++ } ++ as extern fn(libc::c_int)), + } + } + } +@@ -514,9 +748,16 @@ impl SigAction { + /// + /// # Safety + /// +-/// Signal handlers may be called at any point during execution, which limits what is safe to do in +-/// the body of the signal-catching function. Be certain to only make syscalls that are explicitly +-/// marked safe for signal handlers and only share global data using atomics. ++/// * Signal handlers may be called at any point during execution, which limits ++/// what is safe to do in the body of the signal-catching function. Be certain ++/// to only make syscalls that are explicitly marked safe for signal handlers ++/// and only share global data using atomics. ++/// ++/// * There is also no guarantee that the old signal handler was installed ++/// correctly. If it was installed by this crate, it will be. But if it was ++/// installed by, for example, C code, then there is no guarantee its function ++/// pointer is valid. In that case, this function effectively dereferences a ++/// raw pointer of unknown provenance. + pub unsafe fn sigaction(signal: Signal, sigaction: &SigAction) -> Result { + let mut oldact = mem::MaybeUninit::::uninit(); + +@@ -527,7 +768,7 @@ pub unsafe fn sigaction(signal: Signal, sigaction: &SigAction) -> Result Result Result Result + SigHandler::SigDfl => libc::signal(signal, libc::SIG_DFL), + SigHandler::SigIgn => libc::signal(signal, libc::SIG_IGN), + SigHandler::Handler(handler) => libc::signal(signal, handler as libc::sighandler_t), +- SigHandler::SigAction(_) => return Err(Error::UnsupportedOperation), ++ #[cfg(not(target_os = "redox"))] ++ SigHandler::SigAction(_) => return Err(Errno::ENOTSUP), + }; + Errno::result(res).map(|oldhandler| { + match oldhandler { + libc::SIG_DFL => SigHandler::SigDfl, + libc::SIG_IGN => SigHandler::SigIgn, +- f => SigHandler::Handler(mem::transmute(f)), ++ p => SigHandler::Handler( ++ *(&p as *const usize ++ as *const extern fn(libc::c_int)) ++ as extern fn(libc::c_int)), + } + }) + } +@@ -633,8 +876,8 @@ fn do_pthread_sigmask(how: SigmaskHow, + /// + /// If both `set` and `oldset` is None, this function is a no-op. + /// +-/// For more information, visit the [`pthread_sigmask`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_sigmask.html), +-/// or [`sigprocmask`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html) man pages. ++/// For more information, visit the [`pthread_sigmask`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_sigmask.html), ++/// or [`sigprocmask`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html) man pages. + pub fn pthread_sigmask(how: SigmaskHow, + set: Option<&SigSet>, + oldset: Option<&mut SigSet>) -> Result<()> +@@ -644,8 +887,8 @@ pub fn pthread_sigmask(how: SigmaskHow, + + /// Examine and change blocked signals. + /// +-/// For more informations see the [`sigprocmask` man +-/// pages](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html). ++/// For more information see the [`sigprocmask` man ++/// pages](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html). + pub fn sigprocmask(how: SigmaskHow, set: Option<&SigSet>, oldset: Option<&mut SigSet>) -> Result<()> { + if set.is_none() && oldset.is_none() { + return Ok(()) +@@ -663,7 +906,26 @@ pub fn sigprocmask(how: SigmaskHow, set: Option<&SigSet>, oldset: Option<&mut Si + Errno::result(res).map(drop) + } + +-pub fn kill>>(pid: ::unistd::Pid, signal: T) -> Result<()> { ++/// Send a signal to a process ++/// ++/// # Arguments ++/// ++/// * `pid` - Specifies which processes should receive the signal. ++/// - If positive, specifies an individual process. ++/// - If zero, the signal will be sent to all processes whose group ++/// ID is equal to the process group ID of the sender. This is a ++#[cfg_attr(target_os = "fuchsia", doc = "variant of `killpg`.")] ++#[cfg_attr(not(target_os = "fuchsia"), doc = "variant of [`killpg`].")] ++/// - If `-1` and the process has super-user privileges, the signal ++/// is sent to all processes exclusing system processes. ++/// - If less than `-1`, the signal is sent to all processes whose ++/// process group ID is equal to the absolute value of `pid`. ++/// * `signal` - Signal to send. If `None`, error checking is performed ++/// but no signal is actually sent. ++/// ++/// See Also ++/// [`kill(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/kill.html) ++pub fn kill>>(pid: Pid, signal: T) -> Result<()> { + let res = unsafe { libc::kill(pid.into(), + match signal.into() { + Some(s) => s as libc::c_int, +@@ -673,13 +935,18 @@ pub fn kill>>(pid: ::unistd::Pid, signal: T) -> Result<() + Errno::result(res).map(drop) + } + +-/// Send a signal to a process group [(see +-/// killpg(3))](http://pubs.opengroup.org/onlinepubs/9699919799/functions/killpg.html). ++/// Send a signal to a process group ++/// ++/// # Arguments ++/// ++/// * `pgrp` - Process group to signal. If less then or equal 1, the behavior ++/// is platform-specific. ++/// * `signal` - Signal to send. If `None`, `killpg` will only preform error ++/// checking and won't send any signal. + /// +-/// If `pgrp` less then or equal 1, the behavior is platform-specific. +-/// If `signal` is `None`, `killpg` will only preform error checking and won't +-/// send any signal. +-pub fn killpg>>(pgrp: ::unistd::Pid, signal: T) -> Result<()> { ++/// See Also [killpg(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/killpg.html). ++#[cfg(not(target_os = "fuchsia"))] ++pub fn killpg>>(pgrp: Pid, signal: T) -> Result<()> { + let res = unsafe { libc::killpg(pgrp.into(), + match signal.into() { + Some(s) => s as libc::c_int, +@@ -689,48 +956,75 @@ pub fn killpg>>(pgrp: ::unistd::Pid, signal: T) -> Result + Errno::result(res).map(drop) + } + ++/// Send a signal to the current thread ++/// ++/// See Also [raise(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/raise.html) + pub fn raise(signal: Signal) -> Result<()> { + let res = unsafe { libc::raise(signal as libc::c_int) }; + + Errno::result(res).map(drop) + } ++} + ++feature! { ++#![any(feature = "aio", feature = "signal")] + ++/// Identifies a thread for [`SigevNotify::SigevThreadId`] + #[cfg(target_os = "freebsd")] + pub type type_of_thread_id = libc::lwpid_t; ++/// Identifies a thread for [`SigevNotify::SigevThreadId`] + #[cfg(target_os = "linux")] + pub type type_of_thread_id = libc::pid_t; + +-/// Used to request asynchronous notification of certain events, for example, +-/// with POSIX AIO, POSIX message queues, and POSIX timers. ++/// Specifies the notification method used by a [`SigEvent`] + // sigval is actually a union of a int and a void*. But it's never really used + // as a pointer, because neither libc nor the kernel ever dereference it. nix + // therefore presents it as an intptr_t, which is how kevent uses it. ++#[cfg(not(any(target_os = "openbsd", target_os = "redox")))] + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub enum SigevNotify { + /// No notification will be delivered + SigevNone, +- /// The signal given by `signal` will be delivered to the process. The +- /// value in `si_value` will be present in the `si_value` field of the +- /// `siginfo_t` structure of the queued signal. +- SigevSignal { signal: Signal, si_value: libc::intptr_t }, ++ /// Notify by delivering a signal to the process. ++ SigevSignal { ++ /// Signal to deliver ++ signal: Signal, ++ /// Will be present in the `si_value` field of the [`libc::siginfo_t`] ++ /// structure of the queued signal. ++ si_value: libc::intptr_t ++ }, + // Note: SIGEV_THREAD is not implemented because libc::sigevent does not + // expose a way to set the union members needed by SIGEV_THREAD. +- /// A new `kevent` is posted to the kqueue `kq`. The `kevent`'s `udata` +- /// field will contain the value in `udata`. ++ /// Notify by delivering an event to a kqueue. + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] +- SigevKevent { kq: RawFd, udata: libc::intptr_t }, +- /// The signal `signal` is queued to the thread whose LWP ID is given in +- /// `thread_id`. The value stored in `si_value` will be present in the +- /// `si_value` of the `siginfo_t` structure of the queued signal. ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ SigevKevent { ++ /// File descriptor of the kqueue to notify. ++ kq: RawFd, ++ /// Will be contained in the kevent's `udata` field. ++ udata: libc::intptr_t ++ }, ++ /// Notify by delivering a signal to a thread. + #[cfg(any(target_os = "freebsd", target_os = "linux"))] +- SigevThreadId { signal: Signal, thread_id: type_of_thread_id, +- si_value: libc::intptr_t }, ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ SigevThreadId { ++ /// Signal to send ++ signal: Signal, ++ /// LWP ID of the thread to notify ++ thread_id: type_of_thread_id, ++ /// Will be present in the `si_value` field of the [`libc::siginfo_t`] ++ /// structure of the queued signal. ++ si_value: libc::intptr_t ++ }, ++} + } + +-#[cfg(not(target_os = "openbsd"))] ++#[cfg(not(any(target_os = "openbsd", target_os = "redox")))] ++#[cfg_attr(docsrs, doc(cfg(all())))] + mod sigevent { +- use libc; ++ feature! { ++ #![any(feature = "aio", feature = "signal")] ++ + use std::mem; + use std::ptr; + use super::SigevNotify; +@@ -759,8 +1053,11 @@ mod sigevent { + /// Linux, Solaris, and portable programs should prefer `SIGEV_THREAD_ID` or + /// `SIGEV_SIGNAL`. That field is part of a union that shares space with the + /// more genuinely useful `sigev_notify_thread_id` ++ // Allow invalid_value warning on Fuchsia only. ++ // See https://github.com/nix-rust/nix/issues/1441 ++ #[cfg_attr(target_os = "fuchsia", allow(invalid_value))] + pub fn new(sigev_notify: SigevNotify) -> SigEvent { +- let mut sev = unsafe { mem::zeroed::()}; ++ let mut sev = unsafe { mem::MaybeUninit::::zeroed().assume_init() }; + sev.sigev_notify = match sigev_notify { + SigevNotify::SigevNone => libc::SIGEV_NONE, + SigevNotify::SigevSignal{..} => libc::SIGEV_SIGNAL, +@@ -770,6 +1067,8 @@ mod sigevent { + SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID, + #[cfg(all(target_os = "linux", target_env = "gnu", not(target_arch = "mips")))] + SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID, ++ #[cfg(all(target_os = "linux", target_env = "uclibc"))] ++ SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID, + #[cfg(any(all(target_os = "linux", target_env = "musl"), target_arch = "mips"))] + SigevNotify::SigevThreadId{..} => 4 // No SIGEV_THREAD_ID defined + }; +@@ -805,9 +1104,15 @@ mod sigevent { + fn set_tid(_sev: &mut libc::sigevent, _sigev_notify: &SigevNotify) { + } + ++ /// Return a copy of the inner structure + pub fn sigevent(&self) -> libc::sigevent { + self.sigevent + } ++ ++ /// Returns a mutable pointer to the `sigevent` wrapped by `self` ++ pub fn as_mut_ptr(&mut self) -> *mut libc::sigevent { ++ &mut self.sigevent ++ } + } + + impl<'a> From<&'a libc::sigevent> for SigEvent { +@@ -815,12 +1120,14 @@ mod sigevent { + SigEvent{ sigevent: *sigevent } + } + } ++ } + } + + #[cfg(test)] + mod tests { +- use std::thread; + use super::*; ++ #[cfg(not(target_os = "redox"))] ++ use std::thread; + + #[test] + fn test_contains() { +@@ -854,7 +1161,7 @@ mod tests { + + #[test] + fn test_from_str_invalid_value() { +- let errval = Err(Error::Sys(Errno::EINVAL)); ++ let errval = Err(Errno::EINVAL); + assert_eq!("NOSIGNAL".parse::(), errval); + assert_eq!("kill".parse::(), errval); + assert_eq!("9".parse::(), errval); +@@ -874,6 +1181,7 @@ mod tests { + } + + #[test] ++ #[cfg(not(target_os = "redox"))] + fn test_thread_signal_set_mask() { + thread::spawn(|| { + let prev_mask = SigSet::thread_get_mask() +@@ -882,42 +1190,53 @@ mod tests { + let mut test_mask = prev_mask; + test_mask.add(SIGUSR1); + +- assert!(test_mask.thread_set_mask().is_ok()); +- let new_mask = SigSet::thread_get_mask() +- .expect("Failed to get new mask!"); ++ test_mask.thread_set_mask().expect("assertion failed"); ++ let new_mask = ++ SigSet::thread_get_mask().expect("Failed to get new mask!"); + + assert!(new_mask.contains(SIGUSR1)); + assert!(!new_mask.contains(SIGUSR2)); + +- prev_mask.thread_set_mask().expect("Failed to revert signal mask!"); +- }).join().unwrap(); ++ prev_mask ++ .thread_set_mask() ++ .expect("Failed to revert signal mask!"); ++ }) ++ .join() ++ .unwrap(); + } + + #[test] ++ #[cfg(not(target_os = "redox"))] + fn test_thread_signal_block() { + thread::spawn(|| { + let mut mask = SigSet::empty(); + mask.add(SIGUSR1); + +- assert!(mask.thread_block().is_ok()); ++ mask.thread_block().expect("assertion failed"); + + assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR1)); +- }).join().unwrap(); ++ }) ++ .join() ++ .unwrap(); + } + + #[test] ++ #[cfg(not(target_os = "redox"))] + fn test_thread_signal_unblock() { + thread::spawn(|| { + let mut mask = SigSet::empty(); + mask.add(SIGUSR1); + +- assert!(mask.thread_unblock().is_ok()); ++ mask.thread_unblock().expect("assertion failed"); + + assert!(!SigSet::thread_get_mask().unwrap().contains(SIGUSR1)); +- }).join().unwrap(); ++ }) ++ .join() ++ .unwrap(); + } + + #[test] ++ #[cfg(not(target_os = "redox"))] + fn test_thread_signal_swap() { + thread::spawn(|| { + let mut mask = SigSet::empty(); +@@ -929,36 +1248,51 @@ mod tests { + let mut mask2 = SigSet::empty(); + mask2.add(SIGUSR2); + +- let oldmask = mask2.thread_swap_mask(SigmaskHow::SIG_SETMASK) +- .unwrap(); ++ let oldmask = ++ mask2.thread_swap_mask(SigmaskHow::SIG_SETMASK).unwrap(); + + assert!(oldmask.contains(SIGUSR1)); + assert!(!oldmask.contains(SIGUSR2)); + + assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR2)); +- }).join().unwrap(); ++ }) ++ .join() ++ .unwrap(); + } + + #[test] ++ fn test_from_and_into_iterator() { ++ let sigset = SigSet::from_iter(vec![Signal::SIGUSR1, Signal::SIGUSR2]); ++ let signals = sigset.into_iter().collect::>(); ++ assert_eq!(signals, [Signal::SIGUSR1, Signal::SIGUSR2]); ++ } ++ ++ #[test] ++ #[cfg(not(target_os = "redox"))] + fn test_sigaction() { +- use libc; + thread::spawn(|| { +- extern fn test_sigaction_handler(_: libc::c_int) {} +- extern fn test_sigaction_action(_: libc::c_int, +- _: *mut libc::siginfo_t, _: *mut libc::c_void) {} ++ extern "C" fn test_sigaction_handler(_: libc::c_int) {} ++ extern "C" fn test_sigaction_action( ++ _: libc::c_int, ++ _: *mut libc::siginfo_t, ++ _: *mut libc::c_void, ++ ) { ++ } + + let handler_sig = SigHandler::Handler(test_sigaction_handler); + +- let flags = SaFlags::SA_ONSTACK | SaFlags::SA_RESTART | +- SaFlags::SA_SIGINFO; ++ let flags = ++ SaFlags::SA_ONSTACK | SaFlags::SA_RESTART | SaFlags::SA_SIGINFO; + + let mut mask = SigSet::empty(); + mask.add(SIGUSR1); + + let action_sig = SigAction::new(handler_sig, flags, mask); + +- assert_eq!(action_sig.flags(), +- SaFlags::SA_ONSTACK | SaFlags::SA_RESTART); ++ assert_eq!( ++ action_sig.flags(), ++ SaFlags::SA_ONSTACK | SaFlags::SA_RESTART ++ ); + assert_eq!(action_sig.handler(), handler_sig); + + mask = action_sig.mask(); +@@ -974,10 +1308,13 @@ mod tests { + + let action_ign = SigAction::new(SigHandler::SigIgn, flags, mask); + assert_eq!(action_ign.handler(), SigHandler::SigIgn); +- }).join().unwrap(); ++ }) ++ .join() ++ .unwrap(); + } + + #[test] ++ #[cfg(not(target_os = "redox"))] + fn test_sigwait() { + thread::spawn(|| { + let mut mask = SigSet::empty(); +@@ -987,6 +1324,25 @@ mod tests { + + raise(SIGUSR1).unwrap(); + assert_eq!(mask.wait().unwrap(), SIGUSR1); +- }).join().unwrap(); ++ }) ++ .join() ++ .unwrap(); ++ } ++ ++ #[test] ++ fn test_from_sigset_t_unchecked() { ++ let src_set = SigSet::empty(); ++ let set = unsafe { SigSet::from_sigset_t_unchecked(src_set.sigset) }; ++ ++ for signal in Signal::iterator() { ++ assert!(!set.contains(signal)); ++ } ++ ++ let src_set = SigSet::all(); ++ let set = unsafe { SigSet::from_sigset_t_unchecked(src_set.sigset) }; ++ ++ for signal in Signal::iterator() { ++ assert!(set.contains(signal)); ++ } + } + } +diff --git a/vendor/nix/src/sys/signalfd.rs b/vendor/nix/src/sys/signalfd.rs +index 6482eeb..095e590 100644 +--- a/vendor/nix/src/sys/signalfd.rs ++++ b/vendor/nix/src/sys/signalfd.rs +@@ -15,18 +15,16 @@ + //! + //! Please note that signal discarding is not specific to `signalfd`, but also happens with regular + //! signal handlers. +-use libc; +-use unistd; +-use {Error, Result}; +-use errno::Errno; +-pub use sys::signal::{self, SigSet}; ++use crate::errno::Errno; ++pub use crate::sys::signal::{self, SigSet}; ++use crate::unistd; ++use crate::Result; + pub use libc::signalfd_siginfo as siginfo; + +-use std::os::unix::io::{RawFd, AsRawFd}; + use std::mem; ++use std::os::unix::io::{AsRawFd, RawFd}; + +- +-libc_bitflags!{ ++libc_bitflags! { + pub struct SfdFlags: libc::c_int { + SFD_NONBLOCK; + SFD_CLOEXEC; +@@ -34,7 +32,8 @@ libc_bitflags!{ + } + + pub const SIGNALFD_NEW: RawFd = -1; +-pub const SIGNALFD_SIGINFO_SIZE: usize = 128; ++#[deprecated(since = "0.23.0", note = "use mem::size_of::() instead")] ++pub const SIGNALFD_SIGINFO_SIZE: usize = mem::size_of::(); + + /// Creates a new file descriptor for reading signals. + /// +@@ -46,10 +45,14 @@ pub const SIGNALFD_SIGINFO_SIZE: usize = 128; + /// A signal must be blocked on every thread in a process, otherwise it won't be visible from + /// signalfd (the default handler will be invoked instead). + /// +-/// See [the signalfd man page for more information](http://man7.org/linux/man-pages/man2/signalfd.2.html) ++/// See [the signalfd man page for more information](https://man7.org/linux/man-pages/man2/signalfd.2.html) + pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result { + unsafe { +- Errno::result(libc::signalfd(fd as libc::c_int, mask.as_ref(), flags.bits())) ++ Errno::result(libc::signalfd( ++ fd as libc::c_int, ++ mask.as_ref(), ++ flags.bits(), ++ )) + } + } + +@@ -79,7 +82,7 @@ pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result { + /// Err(err) => (), // some error happend + /// } + /// ``` +-#[derive(Clone, Debug, Eq, Hash, PartialEq)] ++#[derive(Debug, Eq, Hash, PartialEq)] + pub struct SignalFd(RawFd); + + impl SignalFd { +@@ -98,25 +101,28 @@ impl SignalFd { + } + + pub fn read_signal(&mut self) -> Result> { +- let mut buffer = mem::MaybeUninit::<[u8; SIGNALFD_SIGINFO_SIZE]>::uninit(); ++ let mut buffer = mem::MaybeUninit::::uninit(); + ++ let size = mem::size_of_val(&buffer); + let res = Errno::result(unsafe { +- libc::read(self.0, +- buffer.as_mut_ptr() as *mut libc::c_void, +- SIGNALFD_SIGINFO_SIZE as libc::size_t) +- }).map(|r| r as usize); ++ libc::read(self.0, buffer.as_mut_ptr() as *mut libc::c_void, size) ++ }) ++ .map(|r| r as usize); + match res { +- Ok(SIGNALFD_SIGINFO_SIZE) => Ok(Some(unsafe { mem::transmute(buffer.assume_init()) })), ++ Ok(x) if x == size => Ok(Some(unsafe { buffer.assume_init() })), + Ok(_) => unreachable!("partial read on signalfd"), +- Err(Error::Sys(Errno::EAGAIN)) => Ok(None), +- Err(error) => Err(error) ++ Err(Errno::EAGAIN) => Ok(None), ++ Err(error) => Err(error), + } + } + } + + impl Drop for SignalFd { + fn drop(&mut self) { +- let _ = unistd::close(self.0); ++ let e = unistd::close(self.0); ++ if !std::thread::panicking() && e == Err(Errno::EBADF) { ++ panic!("Closing an invalid file descriptor!"); ++ }; + } + } + +@@ -137,37 +143,31 @@ impl Iterator for SignalFd { + } + } + +- + #[cfg(test)] + mod tests { + use super::*; +- use std::mem; +- use libc; +- +- +- #[test] +- fn check_siginfo_size() { +- assert_eq!(mem::size_of::(), SIGNALFD_SIGINFO_SIZE); +- } + + #[test] + fn create_signalfd() { + let mask = SigSet::empty(); +- let fd = SignalFd::new(&mask); +- assert!(fd.is_ok()); ++ SignalFd::new(&mask).unwrap(); + } + + #[test] + fn create_signalfd_with_opts() { + let mask = SigSet::empty(); +- let fd = SignalFd::with_flags(&mask, SfdFlags::SFD_CLOEXEC | SfdFlags::SFD_NONBLOCK); +- assert!(fd.is_ok()); ++ SignalFd::with_flags( ++ &mask, ++ SfdFlags::SFD_CLOEXEC | SfdFlags::SFD_NONBLOCK, ++ ) ++ .unwrap(); + } + + #[test] + fn read_empty_signalfd() { + let mask = SigSet::empty(); +- let mut fd = SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap(); ++ let mut fd = ++ SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap(); + + let res = fd.read_signal(); + assert!(res.unwrap().is_none()); +diff --git a/vendor/nix/src/sys/socket/addr.rs b/vendor/nix/src/sys/socket/addr.rs +index 7037ae4..4e565a5 100644 +--- a/vendor/nix/src/sys/socket/addr.rs ++++ b/vendor/nix/src/sys/socket/addr.rs +@@ -1,221 +1,408 @@ ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "linux", ++ target_os = "macos", ++ target_os = "illumos", ++ target_os = "netbsd", ++ target_os = "openbsd", ++ target_os = "haiku", ++ target_os = "fuchsia" ++))] ++#[cfg(feature = "net")] ++pub use self::datalink::LinkAddr; ++#[cfg(any(target_os = "android", target_os = "linux"))] ++pub use self::vsock::VsockAddr; + use super::sa_family_t; +-use {Error, Result, NixPath}; +-use errno::Errno; +-use libc; +-use std::{fmt, mem, net, ptr, slice}; ++use crate::errno::Errno; ++#[cfg(any(target_os = "android", target_os = "linux"))] ++use crate::sys::socket::addr::alg::AlgAddr; ++#[cfg(any(target_os = "android", target_os = "linux"))] ++use crate::sys::socket::addr::netlink::NetlinkAddr; ++#[cfg(all( ++ feature = "ioctl", ++ any(target_os = "ios", target_os = "macos") ++))] ++use crate::sys::socket::addr::sys_control::SysControlAddr; ++use crate::{NixPath, Result}; ++use cfg_if::cfg_if; ++use memoffset::offset_of; ++use std::convert::TryInto; + use std::ffi::OsStr; + use std::hash::{Hash, Hasher}; +-use std::path::Path; + use std::os::unix::ffi::OsStrExt; +-#[cfg(any(target_os = "android", target_os = "linux"))] +-use ::sys::socket::addr::netlink::NetlinkAddr; +-#[cfg(any(target_os = "android", target_os = "linux"))] +-use ::sys::socket::addr::alg::AlgAddr; + #[cfg(any(target_os = "ios", target_os = "macos"))] + use std::os::unix::io::RawFd; +-#[cfg(any(target_os = "ios", target_os = "macos"))] +-use ::sys::socket::addr::sys_control::SysControlAddr; +-#[cfg(any(target_os = "android", +- target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "linux", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] +-pub use self::datalink::LinkAddr; +-#[cfg(target_os = "linux")] +-pub use self::vsock::VsockAddr; ++use std::path::Path; ++use std::{fmt, mem, net, ptr, slice}; ++ ++/// Convert a std::net::Ipv4Addr into the libc form. ++#[cfg(feature = "net")] ++pub(crate) const fn ipv4addr_to_libc(addr: net::Ipv4Addr) -> libc::in_addr { ++ static_assertions::assert_eq_size!(net::Ipv4Addr, libc::in_addr); ++ // Safe because both types have the same memory layout, and no fancy Drop ++ // impls. ++ unsafe { ++ mem::transmute(addr) ++ } ++} ++ ++/// Convert a std::net::Ipv6Addr into the libc form. ++#[cfg(feature = "net")] ++pub(crate) const fn ipv6addr_to_libc(addr: &net::Ipv6Addr) -> libc::in6_addr { ++ static_assertions::assert_eq_size!(net::Ipv6Addr, libc::in6_addr); ++ // Safe because both are Newtype wrappers around the same libc type ++ unsafe { ++ mem::transmute(*addr) ++ } ++} + + /// These constants specify the protocol family to be used + /// in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html) ++/// ++/// # References ++/// ++/// [address_families(7)](https://man7.org/linux/man-pages/man7/address_families.7.html) ++// Should this be u8? + #[repr(i32)] ++#[non_exhaustive] + #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] + pub enum AddressFamily { +- /// Local communication (see [`unix(7)`](http://man7.org/linux/man-pages/man7/unix.7.html)) ++ /// Local communication (see [`unix(7)`](https://man7.org/linux/man-pages/man7/unix.7.html)) + Unix = libc::AF_UNIX, +- /// IPv4 Internet protocols (see [`ip(7)`](http://man7.org/linux/man-pages/man7/ip.7.html)) ++ /// IPv4 Internet protocols (see [`ip(7)`](https://man7.org/linux/man-pages/man7/ip.7.html)) + Inet = libc::AF_INET, +- /// IPv6 Internet protocols (see [`ipv6(7)`](http://man7.org/linux/man-pages/man7/ipv6.7.html)) ++ /// IPv6 Internet protocols (see [`ipv6(7)`](https://man7.org/linux/man-pages/man7/ipv6.7.html)) + Inet6 = libc::AF_INET6, +- /// Kernel user interface device (see [`netlink(7)`](http://man7.org/linux/man-pages/man7/netlink.7.html)) ++ /// Kernel user interface device (see [`netlink(7)`](https://man7.org/linux/man-pages/man7/netlink.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Netlink = libc::AF_NETLINK, +- /// Low level packet interface (see [`packet(7)`](http://man7.org/linux/man-pages/man7/packet.7.html)) +- #[cfg(any(target_os = "android", target_os = "linux"))] ++ /// Low level packet interface (see [`packet(7)`](https://man7.org/linux/man-pages/man7/packet.7.html)) ++ #[cfg(any( ++ target_os = "android", ++ target_os = "linux", ++ target_os = "illumos", ++ target_os = "fuchsia", ++ target_os = "solaris" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Packet = libc::AF_PACKET, + /// KEXT Controls and Notifications + #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + System = libc::AF_SYSTEM, + /// Amateur radio AX.25 protocol + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Ax25 = libc::AF_AX25, + /// IPX - Novell protocols + Ipx = libc::AF_IPX, + /// AppleTalk + AppleTalk = libc::AF_APPLETALK, ++ /// AX.25 packet layer protocol. ++ /// (see [netrom(4)](https://www.unix.com/man-page/linux/4/netrom/)) + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + NetRom = libc::AF_NETROM, ++ /// Can't be used for creating sockets; mostly used for bridge ++ /// links in ++ /// [rtnetlink(7)](https://man7.org/linux/man-pages/man7/rtnetlink.7.html) ++ /// protocol commands. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Bridge = libc::AF_BRIDGE, + /// Access to raw ATM PVCs + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + AtmPvc = libc::AF_ATMPVC, +- /// ITU-T X.25 / ISO-8208 protocol (see [`x25(7)`](http://man7.org/linux/man-pages/man7/x25.7.html)) ++ /// ITU-T X.25 / ISO-8208 protocol (see [`x25(7)`](https://man7.org/linux/man-pages/man7/x25.7.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + X25 = libc::AF_X25, ++ /// RATS (Radio Amateur Telecommunications Society) Open ++ /// Systems environment (ROSE) AX.25 packet layer protocol. ++ /// (see [netrom(4)](https://www.unix.com/man-page/linux/4/netrom/)) + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Rose = libc::AF_ROSE, ++ /// DECet protocol sockets. ++ #[cfg(not(target_os = "haiku"))] + Decnet = libc::AF_DECnet, ++ /// Reserved for "802.2LLC project"; never used. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + NetBeui = libc::AF_NETBEUI, ++ /// This was a short-lived (between Linux 2.1.30 and ++ /// 2.1.99pre2) protocol family for firewall upcalls. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Security = libc::AF_SECURITY, ++ /// Key management protocol. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Key = libc::AF_KEY, ++ #[allow(missing_docs)] // Not documented anywhere that I can find + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Ash = libc::AF_ASH, ++ /// Acorn Econet protocol + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Econet = libc::AF_ECONET, ++ /// Access to ATM Switched Virtual Circuits + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + AtmSvc = libc::AF_ATMSVC, ++ /// Reliable Datagram Sockets (RDS) protocol + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Rds = libc::AF_RDS, ++ /// IBM SNA ++ #[cfg(not(target_os = "haiku"))] + Sna = libc::AF_SNA, ++ /// Socket interface over IrDA + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Irda = libc::AF_IRDA, ++ /// Generic PPP transport layer, for setting up L2 tunnels (L2TP and PPPoE) + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Pppox = libc::AF_PPPOX, ++ /// Legacy protocol for wide area network (WAN) connectivity that was used ++ /// by Sangoma WAN cards + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Wanpipe = libc::AF_WANPIPE, ++ /// Logical link control (IEEE 802.2 LLC) protocol + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Llc = libc::AF_LLC, +- #[cfg(target_os = "linux")] ++ /// InfiniBand native addressing ++ #[cfg(all(target_os = "linux", not(target_env = "uclibc")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Ib = libc::AF_IB, +- #[cfg(target_os = "linux")] ++ /// Multiprotocol Label Switching ++ #[cfg(all(target_os = "linux", not(target_env = "uclibc")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Mpls = libc::AF_MPLS, ++ /// Controller Area Network automotive bus protocol + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Can = libc::AF_CAN, ++ /// TIPC, "cluster domain sockets" protocol + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Tipc = libc::AF_TIPC, +- #[cfg(not(any(target_os = "ios", target_os = "macos")))] ++ /// Bluetooth low-level socket protocol ++ #[cfg(not(any( ++ target_os = "illumos", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "solaris" ++ )))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Bluetooth = libc::AF_BLUETOOTH, ++ /// IUCV (inter-user communication vehicle) z/VM protocol for ++ /// hypervisor-guest interaction + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Iucv = libc::AF_IUCV, ++ /// Rx, Andrew File System remote procedure call protocol + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + RxRpc = libc::AF_RXRPC, ++ /// New "modular ISDN" driver interface protocol ++ #[cfg(not(any( ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "haiku" ++ )))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Isdn = libc::AF_ISDN, ++ /// Nokia cellular modem IPC/RPC interface + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Phonet = libc::AF_PHONET, ++ /// IEEE 802.15.4 WPAN (wireless personal area network) raw packet protocol + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Ieee802154 = libc::AF_IEEE802154, ++ /// Ericsson's Communication CPU to Application CPU interface (CAIF) ++ /// protocol. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Caif = libc::AF_CAIF, + /// Interface to kernel crypto API + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Alg = libc::AF_ALG, ++ /// Near field communication + #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Nfc = libc::AF_NFC, +- #[cfg(target_os = "linux")] ++ /// VMWare VSockets protocol for hypervisor-guest interaction. ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Vsock = libc::AF_VSOCK, +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ /// ARPANet IMP addresses ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ImpLink = libc::AF_IMPLINK, +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ /// PUP protocols, e.g. BSP ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Pup = libc::AF_PUP, +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ /// MIT CHAOS protocols ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Chaos = libc::AF_CHAOS, +- #[cfg(any(target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ /// Novell and Xerox protocol ++ #[cfg(any( ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Ns = libc::AF_NS, +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ #[allow(missing_docs)] // Not documented anywhere that I can find ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Iso = libc::AF_ISO, +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ /// Bell Labs virtual circuit switch ? ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Datakit = libc::AF_DATAKIT, +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ /// CCITT protocols, X.25 etc ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Ccitt = libc::AF_CCITT, +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ /// DEC Direct data link interface ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Dli = libc::AF_DLI, +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ #[allow(missing_docs)] // Not documented anywhere that I can find ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Lat = libc::AF_LAT, +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ /// NSC Hyperchannel ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Hylink = libc::AF_HYLINK, +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ /// Link layer interface ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "illumos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Link = libc::AF_LINK, +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ /// connection-oriented IP, aka ST II ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Coip = libc::AF_COIP, +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ /// Computer Network Technology ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Cnt = libc::AF_CNT, +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ /// Native ATM access ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Natm = libc::AF_NATM, +- /// Unspecified address family, (see [`getaddrinfo(3)`](http://man7.org/linux/man-pages/man3/getaddrinfo.3.html)) ++ /// Unspecified address family, (see [`getaddrinfo(3)`](https://man7.org/linux/man-pages/man3/getaddrinfo.3.html)) + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Unspec = libc::AF_UNSPEC, + } + +@@ -225,7 +412,7 @@ impl AddressFamily { + /// + /// Currently only supports these address families: Unix, Inet (v4 & v6), Netlink, Link/Packet + /// and System. Returns None for unsupported or unknown address families. +- pub fn from_i32(family: i32) -> Option { ++ pub const fn from_i32(family: i32) -> Option { + match family { + libc::AF_UNIX => Some(AddressFamily::Unix), + libc::AF_INET => Some(AddressFamily::Inet), +@@ -236,31 +423,50 @@ impl AddressFamily { + libc::AF_SYSTEM => Some(AddressFamily::System), + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_PACKET => Some(AddressFamily::Packet), +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "illumos", ++ target_os = "openbsd" ++ ))] + libc::AF_LINK => Some(AddressFamily::Link), +- #[cfg(target_os = "linux")] ++ #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_VSOCK => Some(AddressFamily::Vsock), +- _ => None ++ _ => None, + } + } + } + ++feature! { ++#![feature = "net"] ++ ++#[deprecated( ++ since = "0.24.0", ++ note = "use SockaddrIn, SockaddrIn6, or SockaddrStorage instead" ++)] ++#[allow(missing_docs)] // Since they're all deprecated anyway + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub enum InetAddr { + V4(libc::sockaddr_in), + V6(libc::sockaddr_in6), + } + ++#[allow(missing_docs)] // It's deprecated anyway ++#[allow(deprecated)] + impl InetAddr { ++ #[allow(clippy::needless_update)] // It isn't needless on all OSes + pub fn from_std(std: &net::SocketAddr) -> InetAddr { + match *std { + net::SocketAddr::V4(ref addr) => { + InetAddr::V4(libc::sockaddr_in { ++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd", ++ target_os = "haiku", target_os = "hermit", ++ target_os = "ios", target_os = "macos", ++ target_os = "netbsd", target_os = "openbsd"))] ++ sin_len: mem::size_of::() as u8, + sin_family: AddressFamily::Inet as sa_family_t, + sin_port: addr.port().to_be(), // network byte order + sin_addr: Ipv4Addr::from_std(addr.ip()).0, +@@ -269,6 +475,11 @@ impl InetAddr { + } + net::SocketAddr::V6(ref addr) => { + InetAddr::V6(libc::sockaddr_in6 { ++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd", ++ target_os = "haiku", target_os = "hermit", ++ target_os = "ios", target_os = "macos", ++ target_os = "netbsd", target_os = "openbsd"))] ++ sin6_len: mem::size_of::() as u8, + sin6_family: AddressFamily::Inet6 as sa_family_t, + sin6_port: addr.port().to_be(), // network byte order + sin6_addr: Ipv6Addr::from_std(addr.ip()).0, +@@ -280,6 +491,7 @@ impl InetAddr { + } + } + ++ #[allow(clippy::needless_update)] // It isn't needless on all OSes + pub fn new(ip: IpAddr, port: u16) -> InetAddr { + match ip { + IpAddr::V4(ref ip) => { +@@ -301,7 +513,7 @@ impl InetAddr { + } + } + /// Gets the IP address associated with this socket address. +- pub fn ip(&self) -> IpAddr { ++ pub const fn ip(&self) -> IpAddr { + match *self { + InetAddr::V4(ref sa) => IpAddr::V4(Ipv4Addr(sa.sin_addr)), + InetAddr::V6(ref sa) => IpAddr::V6(Ipv6Addr(sa.sin6_addr)), +@@ -309,7 +521,7 @@ impl InetAddr { + } + + /// Gets the port number associated with this socket address +- pub fn port(&self) -> u16 { ++ pub const fn port(&self) -> u16 { + match *self { + InetAddr::V6(ref sa) => u16::from_be(sa.sin6_port), + InetAddr::V4(ref sa) => u16::from_be(sa.sin_port), +@@ -331,11 +543,13 @@ impl InetAddr { + } + } + ++ #[deprecated(since = "0.23.0", note = "use .to_string() instead")] + pub fn to_str(&self) -> String { + format!("{}", self) + } + } + ++#[allow(deprecated)] + impl fmt::Display for InetAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { +@@ -350,17 +564,25 @@ impl fmt::Display for InetAddr { + * ===== IpAddr ===== + * + */ ++#[allow(missing_docs)] // Since they're all deprecated anyway ++#[allow(deprecated)] + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] ++#[deprecated( ++ since = "0.24.0", ++ note = "Use std::net::IpAddr instead" ++)] + pub enum IpAddr { + V4(Ipv4Addr), + V6(Ipv6Addr), + } + ++#[allow(deprecated)] ++#[allow(missing_docs)] // Since they're all deprecated anyway + impl IpAddr { + /// Create a new IpAddr that contains an IPv4 address. + /// + /// The result will represent the IP address a.b.c.d +- pub fn new_v4(a: u8, b: u8, c: u8, d: u8) -> IpAddr { ++ pub const fn new_v4(a: u8, b: u8, c: u8, d: u8) -> IpAddr { + IpAddr::V4(Ipv4Addr::new(a, b, c, d)) + } + +@@ -369,7 +591,7 @@ impl IpAddr { + /// The result will represent the IP address a:b:c:d:e:f + #[allow(clippy::many_single_char_names)] + #[allow(clippy::too_many_arguments)] +- pub fn new_v6(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> IpAddr { ++ pub const fn new_v6(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> IpAddr { + IpAddr::V6(Ipv6Addr::new(a, b, c, d, e, f, g, h)) + } + +@@ -380,7 +602,7 @@ impl IpAddr { + } + } + +- pub fn to_std(&self) -> net::IpAddr { ++ pub const fn to_std(&self) -> net::IpAddr { + match *self { + IpAddr::V4(ref ip) => net::IpAddr::V4(ip.to_std()), + IpAddr::V6(ref ip) => net::IpAddr::V6(ip.to_std()), +@@ -388,6 +610,7 @@ impl IpAddr { + } + } + ++#[allow(deprecated)] + impl fmt::Display for IpAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { +@@ -403,16 +626,24 @@ impl fmt::Display for IpAddr { + * + */ + ++#[deprecated( ++ since = "0.24.0", ++ note = "Use std::net::Ipv4Addr instead" ++)] ++#[allow(missing_docs)] // Since they're all deprecated anyway + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] ++#[repr(transparent)] + pub struct Ipv4Addr(pub libc::in_addr); + ++#[allow(deprecated)] ++#[allow(missing_docs)] // Since they're all deprecated anyway + impl Ipv4Addr { + #[allow(clippy::identity_op)] // More readable this way +- pub fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr { +- let ip = ((u32::from(a) << 24) | +- (u32::from(b) << 16) | +- (u32::from(c) << 8) | +- (u32::from(d) << 0)).to_be(); ++ pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr { ++ let ip = (((a as u32) << 24) | ++ ((b as u32) << 16) | ++ ((c as u32) << 8) | ++ ((d as u32) << 0)).to_be(); + + Ipv4Addr(libc::in_addr { s_addr: ip }) + } +@@ -424,21 +655,22 @@ impl Ipv4Addr { + Ipv4Addr::new(bits[0], bits[1], bits[2], bits[3]) + } + +- pub fn any() -> Ipv4Addr { ++ pub const fn any() -> Ipv4Addr { + Ipv4Addr(libc::in_addr { s_addr: libc::INADDR_ANY }) + } + +- pub fn octets(self) -> [u8; 4] { ++ pub const fn octets(self) -> [u8; 4] { + let bits = u32::from_be(self.0.s_addr); + [(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8] + } + +- pub fn to_std(self) -> net::Ipv4Addr { ++ pub const fn to_std(self) -> net::Ipv4Addr { + let bits = self.octets(); + net::Ipv4Addr::new(bits[0], bits[1], bits[2], bits[3]) + } + } + ++#[allow(deprecated)] + impl fmt::Display for Ipv4Addr { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let octets = self.octets(); +@@ -452,7 +684,13 @@ impl fmt::Display for Ipv4Addr { + * + */ + ++#[deprecated( ++ since = "0.24.0", ++ note = "Use std::net::Ipv6Addr instead" ++)] ++#[allow(missing_docs)] // Since they're all deprecated anyway + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] ++#[repr(transparent)] + pub struct Ipv6Addr(pub libc::in6_addr); + + // Note that IPv6 addresses are stored in big endian order on all architectures. +@@ -471,10 +709,12 @@ macro_rules! to_u16_array { + } + } + ++#[allow(deprecated)] ++#[allow(missing_docs)] // Since they're all deprecated anyway + impl Ipv6Addr { + #[allow(clippy::many_single_char_names)] + #[allow(clippy::too_many_arguments)] +- pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr { ++ pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr { + Ipv6Addr(libc::in6_addr{s6_addr: to_u8_array!(a,b,c,d,e,f,g,h)}) + } + +@@ -484,138 +724,365 @@ impl Ipv6Addr { + } + + /// Return the eight 16-bit segments that make up this address +- pub fn segments(&self) -> [u16; 8] { ++ pub const fn segments(&self) -> [u16; 8] { + to_u16_array!(self, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) + } + +- pub fn to_std(&self) -> net::Ipv6Addr { ++ pub const fn to_std(&self) -> net::Ipv6Addr { + let s = self.segments(); + net::Ipv6Addr::new(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]) + } + } + ++#[allow(deprecated)] + impl fmt::Display for Ipv6Addr { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + self.to_std().fmt(fmt) + } + } ++} + + /// A wrapper around `sockaddr_un`. +-/// +-/// This also tracks the length of `sun_path` address (excluding +-/// a terminating null), because it may not be null-terminated. For example, +-/// unconnected and Linux abstract sockets are never null-terminated, and POSIX +-/// does not require that `sun_len` include the terminating null even for normal +-/// sockets. Note that the actual sockaddr length is greater by +-/// `offset_of!(libc::sockaddr_un, sun_path)` + #[derive(Clone, Copy, Debug)] +-pub struct UnixAddr(pub libc::sockaddr_un, pub usize); ++#[repr(C)] ++pub struct UnixAddr { ++ // INVARIANT: sun & sun_len are valid as defined by docs for from_raw_parts ++ sun: libc::sockaddr_un, ++ /// The length of the valid part of `sun`, including the sun_family field ++ /// but excluding any trailing nul. ++ // On the BSDs, this field is built into sun ++ #[cfg(any( ++ target_os = "android", ++ target_os = "fuchsia", ++ target_os = "illumos", ++ target_os = "linux" ++ ))] ++ sun_len: u8, ++} ++ ++// linux man page unix(7) says there are 3 kinds of unix socket: ++// pathname: addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(sun_path) + 1 ++// unnamed: addrlen = sizeof(sa_family_t) ++// abstract: addren > sizeof(sa_family_t), name = sun_path[..(addrlen - sizeof(sa_family_t))] ++// ++// what we call path_len = addrlen - offsetof(struct sockaddr_un, sun_path) ++#[derive(PartialEq, Eq, Hash)] ++enum UnixAddrKind<'a> { ++ Pathname(&'a Path), ++ Unnamed, ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ Abstract(&'a [u8]), ++} ++impl<'a> UnixAddrKind<'a> { ++ /// Safety: sun & sun_len must be valid ++ unsafe fn get(sun: &'a libc::sockaddr_un, sun_len: u8) -> Self { ++ assert!(sun_len as usize >= offset_of!(libc::sockaddr_un, sun_path)); ++ let path_len = ++ sun_len as usize - offset_of!(libc::sockaddr_un, sun_path); ++ if path_len == 0 { ++ return Self::Unnamed; ++ } ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ if sun.sun_path[0] == 0 { ++ let name = slice::from_raw_parts( ++ sun.sun_path.as_ptr().add(1) as *const u8, ++ path_len - 1, ++ ); ++ return Self::Abstract(name); ++ } ++ let pathname = ++ slice::from_raw_parts(sun.sun_path.as_ptr() as *const u8, path_len); ++ if pathname.last() == Some(&0) { ++ // A trailing NUL is not considered part of the path, and it does ++ // not need to be included in the addrlen passed to functions like ++ // bind(). However, Linux adds a trailing NUL, even if one was not ++ // originally present, when returning addrs from functions like ++ // getsockname() (the BSDs do not do that). So we need to filter ++ // out any trailing NUL here, so sockaddrs can round-trip through ++ // the kernel and still compare equal. ++ Self::Pathname(Path::new(OsStr::from_bytes( ++ &pathname[0..pathname.len() - 1], ++ ))) ++ } else { ++ Self::Pathname(Path::new(OsStr::from_bytes(pathname))) ++ } ++ } ++} + + impl UnixAddr { + /// Create a new sockaddr_un representing a filesystem path. + pub fn new(path: &P) -> Result { +- path.with_nix_path(|cstr| { +- unsafe { +- let mut ret = libc::sockaddr_un { +- sun_family: AddressFamily::Unix as sa_family_t, +- .. mem::zeroed() +- }; +- +- let bytes = cstr.to_bytes(); ++ path.with_nix_path(|cstr| unsafe { ++ let mut ret = libc::sockaddr_un { ++ sun_family: AddressFamily::Unix as sa_family_t, ++ ..mem::zeroed() ++ }; + +- if bytes.len() > ret.sun_path.len() { +- return Err(Error::Sys(Errno::ENAMETOOLONG)); +- } ++ let bytes = cstr.to_bytes(); + +- ptr::copy_nonoverlapping(bytes.as_ptr(), +- ret.sun_path.as_mut_ptr() as *mut u8, +- bytes.len()); ++ if bytes.len() >= ret.sun_path.len() { ++ return Err(Errno::ENAMETOOLONG); ++ } + +- Ok(UnixAddr(ret, bytes.len())) ++ let sun_len = (bytes.len() ++ + offset_of!(libc::sockaddr_un, sun_path)) ++ .try_into() ++ .unwrap(); ++ ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ { ++ ret.sun_len = sun_len; + } ++ ptr::copy_nonoverlapping( ++ bytes.as_ptr(), ++ ret.sun_path.as_mut_ptr() as *mut u8, ++ bytes.len(), ++ ); ++ ++ Ok(UnixAddr::from_raw_parts(ret, sun_len)) + })? + } + + /// Create a new `sockaddr_un` representing an address in the "abstract namespace". + /// +- /// The leading null byte for the abstract namespace is automatically added; +- /// thus the input `path` is expected to be the bare name, not null-prefixed. ++ /// The leading nul byte for the abstract namespace is automatically added; ++ /// thus the input `path` is expected to be the bare name, not NUL-prefixed. + /// This is a Linux-specific extension, primarily used to allow chrooted + /// processes to communicate with processes having a different filesystem view. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn new_abstract(path: &[u8]) -> Result { + unsafe { + let mut ret = libc::sockaddr_un { + sun_family: AddressFamily::Unix as sa_family_t, +- .. mem::zeroed() ++ ..mem::zeroed() + }; + +- if path.len() + 1 > ret.sun_path.len() { +- return Err(Error::Sys(Errno::ENAMETOOLONG)); ++ if path.len() >= ret.sun_path.len() { ++ return Err(Errno::ENAMETOOLONG); + } ++ let sun_len = ++ (path.len() + 1 + offset_of!(libc::sockaddr_un, sun_path)) ++ .try_into() ++ .unwrap(); + + // Abstract addresses are represented by sun_path[0] == + // b'\0', so copy starting one byte in. +- ptr::copy_nonoverlapping(path.as_ptr(), +- ret.sun_path.as_mut_ptr().offset(1) as *mut u8, +- path.len()); ++ ptr::copy_nonoverlapping( ++ path.as_ptr(), ++ ret.sun_path.as_mut_ptr().offset(1) as *mut u8, ++ path.len(), ++ ); ++ ++ Ok(UnixAddr::from_raw_parts(ret, sun_len)) ++ } ++ } ++ ++ /// Create a new `sockaddr_un` representing an "unnamed" unix socket address. ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub fn new_unnamed() -> UnixAddr { ++ let ret = libc::sockaddr_un { ++ sun_family: AddressFamily::Unix as sa_family_t, ++ .. unsafe { mem::zeroed() } ++ }; ++ ++ let sun_len: u8 = offset_of!(libc::sockaddr_un, sun_path).try_into().unwrap(); ++ ++ unsafe { UnixAddr::from_raw_parts(ret, sun_len) } ++ } + +- Ok(UnixAddr(ret, path.len() + 1)) ++ /// Create a UnixAddr from a raw `sockaddr_un` struct and a size. `sun_len` ++ /// is the size of the valid portion of the struct, excluding any trailing ++ /// NUL. ++ /// ++ /// # Safety ++ /// This pair of sockaddr_un & sun_len must be a valid unix addr, which ++ /// means: ++ /// - sun_len >= offset_of(sockaddr_un, sun_path) ++ /// - sun_len <= sockaddr_un.sun_path.len() - offset_of(sockaddr_un, sun_path) ++ /// - if this is a unix addr with a pathname, sun.sun_path is a ++ /// fs path, not necessarily nul-terminated. ++ pub(crate) unsafe fn from_raw_parts( ++ sun: libc::sockaddr_un, ++ sun_len: u8, ++ ) -> UnixAddr { ++ cfg_if! { ++ if #[cfg(any(target_os = "android", ++ target_os = "fuchsia", ++ target_os = "illumos", ++ target_os = "linux" ++ ))] ++ { ++ UnixAddr { sun, sun_len } ++ } else { ++ assert_eq!(sun_len, sun.sun_len); ++ UnixAddr {sun} ++ } + } + } + +- fn sun_path(&self) -> &[u8] { +- unsafe { slice::from_raw_parts(self.0.sun_path.as_ptr() as *const u8, self.1) } ++ fn kind(&self) -> UnixAddrKind<'_> { ++ // SAFETY: our sockaddr is always valid because of the invariant on the struct ++ unsafe { UnixAddrKind::get(&self.sun, self.sun_len()) } + } + + /// If this address represents a filesystem path, return that path. + pub fn path(&self) -> Option<&Path> { +- if self.1 == 0 || self.0.sun_path[0] == 0 { +- // unnamed or abstract +- None +- } else { +- let p = self.sun_path(); +- // POSIX only requires that `sun_len` be at least long enough to +- // contain the pathname, and it need not be null-terminated. So we +- // need to create a string that is the shorter of the +- // null-terminated length or the full length. +- let ptr = &self.0.sun_path as *const libc::c_char; +- let reallen = unsafe { libc::strnlen(ptr, p.len()) }; +- Some(Path::new(::from_bytes(&p[..reallen]))) ++ match self.kind() { ++ UnixAddrKind::Pathname(path) => Some(path), ++ _ => None, + } + } + + /// If this address represents an abstract socket, return its name. + /// + /// For abstract sockets only the bare name is returned, without the +- /// leading null byte. `None` is returned for unnamed or path-backed sockets. ++ /// leading NUL byte. `None` is returned for unnamed or path-backed sockets. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn as_abstract(&self) -> Option<&[u8]> { +- if self.1 >= 1 && self.0.sun_path[0] == 0 { +- Some(&self.sun_path()[1..]) +- } else { +- // unnamed or filesystem path +- None ++ match self.kind() { ++ UnixAddrKind::Abstract(name) => Some(name), ++ _ => None, ++ } ++ } ++ ++ /// Check if this address is an "unnamed" unix socket address. ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ #[inline] ++ pub fn is_unnamed(&self) -> bool { ++ matches!(self.kind(), UnixAddrKind::Unnamed) ++ } ++ ++ /// Returns the addrlen of this socket - `offsetof(struct sockaddr_un, sun_path)` ++ #[inline] ++ pub fn path_len(&self) -> usize { ++ self.sun_len() as usize - offset_of!(libc::sockaddr_un, sun_path) ++ } ++ /// Returns a pointer to the raw `sockaddr_un` struct ++ #[inline] ++ pub fn as_ptr(&self) -> *const libc::sockaddr_un { ++ &self.sun ++ } ++ /// Returns a mutable pointer to the raw `sockaddr_un` struct ++ #[inline] ++ pub fn as_mut_ptr(&mut self) -> *mut libc::sockaddr_un { ++ &mut self.sun ++ } ++ ++ fn sun_len(&self) -> u8 { ++ cfg_if! { ++ if #[cfg(any(target_os = "android", ++ target_os = "fuchsia", ++ target_os = "illumos", ++ target_os = "linux" ++ ))] ++ { ++ self.sun_len ++ } else { ++ self.sun.sun_len ++ } ++ } ++ } ++} ++ ++impl private::SockaddrLikePriv for UnixAddr {} ++impl SockaddrLike for UnixAddr { ++ #[cfg(any( ++ target_os = "android", ++ target_os = "fuchsia", ++ target_os = "illumos", ++ target_os = "linux" ++ ))] ++ fn len(&self) -> libc::socklen_t { ++ self.sun_len.into() ++ } ++ ++ unsafe fn from_raw( ++ addr: *const libc::sockaddr, ++ len: Option, ++ ) -> Option ++ where ++ Self: Sized, ++ { ++ if let Some(l) = len { ++ if (l as usize) < offset_of!(libc::sockaddr_un, sun_path) ++ || l > u8::MAX as libc::socklen_t ++ { ++ return None; ++ } ++ } ++ if (*addr).sa_family as i32 != libc::AF_UNIX { ++ return None; + } ++ let mut su: libc::sockaddr_un = mem::zeroed(); ++ let sup = &mut su as *mut libc::sockaddr_un as *mut u8; ++ cfg_if! { ++ if #[cfg(any(target_os = "android", ++ target_os = "fuchsia", ++ target_os = "illumos", ++ target_os = "linux" ++ ))] { ++ let su_len = len.unwrap_or( ++ mem::size_of::() as libc::socklen_t ++ ); ++ } else { ++ let su_len = len.unwrap_or((*addr).sa_len as libc::socklen_t); ++ } ++ }; ++ ptr::copy(addr as *const u8, sup, su_len as usize); ++ Some(Self::from_raw_parts(su, su_len as u8)) ++ } ++ ++ fn size() -> libc::socklen_t ++ where ++ Self: Sized, ++ { ++ mem::size_of::() as libc::socklen_t + } + } + ++impl AsRef for UnixAddr { ++ fn as_ref(&self) -> &libc::sockaddr_un { ++ &self.sun ++ } ++} ++ ++#[cfg(any(target_os = "android", target_os = "linux"))] ++fn fmt_abstract(abs: &[u8], f: &mut fmt::Formatter) -> fmt::Result { ++ use fmt::Write; ++ f.write_str("@\"")?; ++ for &b in abs { ++ use fmt::Display; ++ char::from(b).escape_default().fmt(f)?; ++ } ++ f.write_char('"')?; ++ Ok(()) ++} ++ + impl fmt::Display for UnixAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +- if self.1 == 0 { +- f.write_str("") +- } else if let Some(path) = self.path() { +- path.display().fmt(f) +- } else { +- let display = String::from_utf8_lossy(&self.sun_path()[1..]); +- write!(f, "@{}", display) ++ match self.kind() { ++ UnixAddrKind::Pathname(path) => path.display().fmt(f), ++ UnixAddrKind::Unnamed => f.pad(""), ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ UnixAddrKind::Abstract(name) => fmt_abstract(name, f), + } + } + } + + impl PartialEq for UnixAddr { + fn eq(&self, other: &UnixAddr) -> bool { +- self.sun_path() == other.sun_path() ++ self.kind() == other.kind() + } + } + +@@ -623,89 +1090,1015 @@ impl Eq for UnixAddr {} + + impl Hash for UnixAddr { + fn hash(&self, s: &mut H) { +- ( self.0.sun_family, self.sun_path() ).hash(s) ++ self.kind().hash(s) ++ } ++} ++ ++/// Anything that, in C, can be cast back and forth to `sockaddr`. ++/// ++/// Most implementors also implement `AsRef` to access their ++/// inner type read-only. ++#[allow(clippy::len_without_is_empty)] ++pub trait SockaddrLike: private::SockaddrLikePriv { ++ /// Returns a raw pointer to the inner structure. Useful for FFI. ++ fn as_ptr(&self) -> *const libc::sockaddr { ++ self as *const Self as *const libc::sockaddr ++ } ++ ++ /// Unsafe constructor from a variable length source ++ /// ++ /// Some C APIs from provide `len`, and others do not. If it's provided it ++ /// will be validated. If not, it will be guessed based on the family. ++ /// ++ /// # Arguments ++ /// ++ /// - `addr`: raw pointer to something that can be cast to a ++ /// `libc::sockaddr`. For example, `libc::sockaddr_in`, ++ /// `libc::sockaddr_in6`, etc. ++ /// - `len`: For fixed-width types like `sockaddr_in`, it will be ++ /// validated if present and ignored if not. For variable-width ++ /// types it is required and must be the total length of valid ++ /// data. For example, if `addr` points to a ++ /// named `sockaddr_un`, then `len` must be the length of the ++ /// structure up to but not including the trailing NUL. ++ /// ++ /// # Safety ++ /// ++ /// `addr` must be valid for the specific type of sockaddr. `len`, if ++ /// present, must not exceed the length of valid data in `addr`. ++ unsafe fn from_raw( ++ addr: *const libc::sockaddr, ++ len: Option, ++ ) -> Option ++ where ++ Self: Sized; ++ ++ /// Return the address family of this socket ++ /// ++ /// # Examples ++ /// One common use is to match on the family of a union type, like this: ++ /// ``` ++ /// # use nix::sys::socket::*; ++ /// let fd = socket(AddressFamily::Inet, SockType::Stream, ++ /// SockFlag::empty(), None).unwrap(); ++ /// let ss: SockaddrStorage = getsockname(fd).unwrap(); ++ /// match ss.family().unwrap() { ++ /// AddressFamily::Inet => println!("{}", ss.as_sockaddr_in().unwrap()), ++ /// AddressFamily::Inet6 => println!("{}", ss.as_sockaddr_in6().unwrap()), ++ /// _ => println!("Unexpected address family") ++ /// } ++ /// ``` ++ fn family(&self) -> Option { ++ // Safe since all implementors have a sa_family field at the same ++ // address, and they're all repr(C) ++ AddressFamily::from_i32(unsafe { ++ (*(self as *const Self as *const libc::sockaddr)).sa_family as i32 ++ }) ++ } ++ ++ cfg_if! { ++ if #[cfg(any(target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd"))] { ++ /// Return the length of valid data in the sockaddr structure. ++ /// ++ /// For fixed-size sockaddrs, this should be the size of the ++ /// structure. But for variable-sized types like [`UnixAddr`] it ++ /// may be less. ++ fn len(&self) -> libc::socklen_t { ++ // Safe since all implementors have a sa_len field at the same ++ // address, and they're all repr(transparent). ++ // Robust for all implementors. ++ unsafe { ++ (*(self as *const Self as *const libc::sockaddr)).sa_len ++ }.into() ++ } ++ } else { ++ /// Return the length of valid data in the sockaddr structure. ++ /// ++ /// For fixed-size sockaddrs, this should be the size of the ++ /// structure. But for variable-sized types like [`UnixAddr`] it ++ /// may be less. ++ fn len(&self) -> libc::socklen_t { ++ // No robust default implementation is possible without an ++ // sa_len field. Implementors with a variable size must ++ // override this method. ++ mem::size_of_val(self) as libc::socklen_t ++ } ++ } ++ } ++ ++ /// Return the available space in the structure ++ fn size() -> libc::socklen_t ++ where ++ Self: Sized, ++ { ++ mem::size_of::() as libc::socklen_t ++ } ++} ++ ++impl private::SockaddrLikePriv for () { ++ fn as_mut_ptr(&mut self) -> *mut libc::sockaddr { ++ ptr::null_mut() ++ } ++} ++ ++/// `()` can be used in place of a real Sockaddr when no address is expected, ++/// for example for a field of `Option where S: SockaddrLike`. ++// If this RFC ever stabilizes, then ! will be a better choice. ++// https://github.com/rust-lang/rust/issues/35121 ++impl SockaddrLike for () { ++ fn as_ptr(&self) -> *const libc::sockaddr { ++ ptr::null() ++ } ++ ++ unsafe fn from_raw( ++ _: *const libc::sockaddr, ++ _: Option, ++ ) -> Option ++ where ++ Self: Sized, ++ { ++ None ++ } ++ ++ fn family(&self) -> Option { ++ None ++ } ++ ++ fn len(&self) -> libc::socklen_t { ++ 0 ++ } ++} ++ ++/// An IPv4 socket address ++// This is identical to net::SocketAddrV4. But the standard library ++// doesn't allow direct access to the libc fields, which we need. So we ++// reimplement it here. ++#[cfg(feature = "net")] ++#[repr(transparent)] ++#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] ++pub struct SockaddrIn(libc::sockaddr_in); ++ ++#[cfg(feature = "net")] ++impl SockaddrIn { ++ /// Returns the IP address associated with this socket address, in native ++ /// endian. ++ pub const fn ip(&self) -> libc::in_addr_t { ++ u32::from_be(self.0.sin_addr.s_addr) ++ } ++ ++ /// Creates a new socket address from IPv4 octets and a port number. ++ pub fn new(a: u8, b: u8, c: u8, d: u8, port: u16) -> Self { ++ Self(libc::sockaddr_in { ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "haiku", ++ target_os = "openbsd" ++ ))] ++ sin_len: Self::size() as u8, ++ sin_family: AddressFamily::Inet as sa_family_t, ++ sin_port: u16::to_be(port), ++ sin_addr: libc::in_addr { ++ s_addr: u32::from_ne_bytes([a, b, c, d]), ++ }, ++ sin_zero: unsafe { mem::zeroed() }, ++ }) ++ } ++ ++ /// Returns the port number associated with this socket address, in native ++ /// endian. ++ pub const fn port(&self) -> u16 { ++ u16::from_be(self.0.sin_port) ++ } ++} ++ ++#[cfg(feature = "net")] ++impl private::SockaddrLikePriv for SockaddrIn {} ++#[cfg(feature = "net")] ++impl SockaddrLike for SockaddrIn { ++ unsafe fn from_raw( ++ addr: *const libc::sockaddr, ++ len: Option, ++ ) -> Option ++ where ++ Self: Sized, ++ { ++ if let Some(l) = len { ++ if l != mem::size_of::() as libc::socklen_t { ++ return None; ++ } ++ } ++ if (*addr).sa_family as i32 != libc::AF_INET { ++ return None; ++ } ++ Some(Self(ptr::read_unaligned(addr as *const _))) ++ } ++} ++ ++#[cfg(feature = "net")] ++impl AsRef for SockaddrIn { ++ fn as_ref(&self) -> &libc::sockaddr_in { ++ &self.0 ++ } ++} ++ ++#[cfg(feature = "net")] ++impl fmt::Display for SockaddrIn { ++ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ++ let ne = u32::from_be(self.0.sin_addr.s_addr); ++ let port = u16::from_be(self.0.sin_port); ++ write!( ++ f, ++ "{}.{}.{}.{}:{}", ++ ne >> 24, ++ (ne >> 16) & 0xFF, ++ (ne >> 8) & 0xFF, ++ ne & 0xFF, ++ port ++ ) ++ } ++} ++ ++#[cfg(feature = "net")] ++impl From for SockaddrIn { ++ fn from(addr: net::SocketAddrV4) -> Self { ++ Self(libc::sockaddr_in { ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "haiku", ++ target_os = "hermit", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ sin_len: mem::size_of::() as u8, ++ sin_family: AddressFamily::Inet as sa_family_t, ++ sin_port: addr.port().to_be(), // network byte order ++ sin_addr: ipv4addr_to_libc(*addr.ip()), ++ ..unsafe { mem::zeroed() } ++ }) ++ } ++} ++ ++#[cfg(feature = "net")] ++impl From for net::SocketAddrV4 { ++ fn from(addr: SockaddrIn) -> Self { ++ net::SocketAddrV4::new( ++ net::Ipv4Addr::from(addr.0.sin_addr.s_addr.to_ne_bytes()), ++ u16::from_be(addr.0.sin_port), ++ ) ++ } ++} ++ ++#[cfg(feature = "net")] ++impl std::str::FromStr for SockaddrIn { ++ type Err = net::AddrParseError; ++ ++ fn from_str(s: &str) -> std::result::Result { ++ net::SocketAddrV4::from_str(s).map(SockaddrIn::from) ++ } ++} ++ ++/// An IPv6 socket address ++#[cfg(feature = "net")] ++#[repr(transparent)] ++#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] ++pub struct SockaddrIn6(libc::sockaddr_in6); ++ ++#[cfg(feature = "net")] ++impl SockaddrIn6 { ++ /// Returns the flow information associated with this address. ++ pub const fn flowinfo(&self) -> u32 { ++ self.0.sin6_flowinfo ++ } ++ ++ /// Returns the IP address associated with this socket address. ++ pub fn ip(&self) -> net::Ipv6Addr { ++ net::Ipv6Addr::from(self.0.sin6_addr.s6_addr) ++ } ++ ++ /// Returns the port number associated with this socket address, in native ++ /// endian. ++ pub const fn port(&self) -> u16 { ++ u16::from_be(self.0.sin6_port) ++ } ++ ++ /// Returns the scope ID associated with this address. ++ pub const fn scope_id(&self) -> u32 { ++ self.0.sin6_scope_id ++ } ++} ++ ++#[cfg(feature = "net")] ++impl private::SockaddrLikePriv for SockaddrIn6 {} ++#[cfg(feature = "net")] ++impl SockaddrLike for SockaddrIn6 { ++ unsafe fn from_raw( ++ addr: *const libc::sockaddr, ++ len: Option, ++ ) -> Option ++ where ++ Self: Sized, ++ { ++ if let Some(l) = len { ++ if l != mem::size_of::() as libc::socklen_t { ++ return None; ++ } ++ } ++ if (*addr).sa_family as i32 != libc::AF_INET6 { ++ return None; ++ } ++ Some(Self(ptr::read_unaligned(addr as *const _))) ++ } ++} ++ ++#[cfg(feature = "net")] ++impl AsRef for SockaddrIn6 { ++ fn as_ref(&self) -> &libc::sockaddr_in6 { ++ &self.0 ++ } ++} ++ ++#[cfg(feature = "net")] ++impl fmt::Display for SockaddrIn6 { ++ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ++ // These things are really hard to display properly. Easier to let std ++ // do it. ++ let std = net::SocketAddrV6::new( ++ self.ip(), ++ self.port(), ++ self.flowinfo(), ++ self.scope_id(), ++ ); ++ std.fmt(f) ++ } ++} ++ ++#[cfg(feature = "net")] ++impl From for SockaddrIn6 { ++ fn from(addr: net::SocketAddrV6) -> Self { ++ #[allow(clippy::needless_update)] // It isn't needless on Illumos ++ Self(libc::sockaddr_in6 { ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "haiku", ++ target_os = "hermit", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ sin6_len: mem::size_of::() as u8, ++ sin6_family: AddressFamily::Inet6 as sa_family_t, ++ sin6_port: addr.port().to_be(), // network byte order ++ sin6_addr: ipv6addr_to_libc(addr.ip()), ++ sin6_flowinfo: addr.flowinfo(), // host byte order ++ sin6_scope_id: addr.scope_id(), // host byte order ++ ..unsafe { mem::zeroed() } ++ }) ++ } ++} ++ ++#[cfg(feature = "net")] ++impl From for net::SocketAddrV6 { ++ fn from(addr: SockaddrIn6) -> Self { ++ net::SocketAddrV6::new( ++ net::Ipv6Addr::from(addr.0.sin6_addr.s6_addr), ++ u16::from_be(addr.0.sin6_port), ++ addr.0.sin6_flowinfo, ++ addr.0.sin6_scope_id, ++ ) ++ } ++} ++ ++#[cfg(feature = "net")] ++impl std::str::FromStr for SockaddrIn6 { ++ type Err = net::AddrParseError; ++ ++ fn from_str(s: &str) -> std::result::Result { ++ net::SocketAddrV6::from_str(s).map(SockaddrIn6::from) ++ } ++} ++ ++/// A container for any sockaddr type ++/// ++/// Just like C's `sockaddr_storage`, this type is large enough to hold any type ++/// of sockaddr. It can be used as an argument with functions like ++/// [`bind`](super::bind) and [`getsockname`](super::getsockname). Though it is ++/// a union, it can be safely accessed through the `as_*` methods. ++/// ++/// # Example ++/// ``` ++/// # use nix::sys::socket::*; ++/// # use std::str::FromStr; ++/// let localhost = SockaddrIn::from_str("127.0.0.1:8081").unwrap(); ++/// let fd = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), ++/// None).unwrap(); ++/// bind(fd, &localhost).expect("bind"); ++/// let ss: SockaddrStorage = getsockname(fd).expect("getsockname"); ++/// assert_eq!(&localhost, ss.as_sockaddr_in().unwrap()); ++/// ``` ++#[derive(Clone, Copy, Eq)] ++#[repr(C)] ++pub union SockaddrStorage { ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ alg: AlgAddr, ++ #[cfg(feature = "net")] ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ dl: LinkAddr, ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ nl: NetlinkAddr, ++ #[cfg(all( ++ feature = "ioctl", ++ any(target_os = "ios", target_os = "macos") ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))] ++ sctl: SysControlAddr, ++ #[cfg(feature = "net")] ++ sin: SockaddrIn, ++ #[cfg(feature = "net")] ++ sin6: SockaddrIn6, ++ ss: libc::sockaddr_storage, ++ su: UnixAddr, ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ vsock: VsockAddr, ++} ++impl private::SockaddrLikePriv for SockaddrStorage {} ++impl SockaddrLike for SockaddrStorage { ++ unsafe fn from_raw( ++ addr: *const libc::sockaddr, ++ l: Option, ++ ) -> Option ++ where ++ Self: Sized, ++ { ++ if addr.is_null() { ++ return None; ++ } ++ if let Some(len) = l { ++ let ulen = len as usize; ++ if ulen < offset_of!(libc::sockaddr, sa_data) ++ || ulen > mem::size_of::() ++ { ++ None ++ } else { ++ let mut ss: libc::sockaddr_storage = mem::zeroed(); ++ let ssp = &mut ss as *mut libc::sockaddr_storage as *mut u8; ++ ptr::copy(addr as *const u8, ssp, len as usize); ++ #[cfg(any( ++ target_os = "android", ++ target_os = "fuchsia", ++ target_os = "illumos", ++ target_os = "linux" ++ ))] ++ if i32::from(ss.ss_family) == libc::AF_UNIX { ++ // Safe because we UnixAddr is strictly smaller than ++ // SockaddrStorage, and we just initialized the structure. ++ (*(&mut ss as *mut libc::sockaddr_storage as *mut UnixAddr)).sun_len = len as u8; ++ } ++ Some(Self { ss }) ++ } ++ } else { ++ // If length is not available and addr is of a fixed-length type, ++ // copy it. If addr is of a variable length type and len is not ++ // available, then there's nothing we can do. ++ match (*addr).sa_family as i32 { ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ libc::AF_ALG => { ++ AlgAddr::from_raw(addr, l).map(|alg| Self { alg }) ++ } ++ #[cfg(feature = "net")] ++ libc::AF_INET => { ++ SockaddrIn::from_raw(addr, l).map(|sin| Self { sin }) ++ } ++ #[cfg(feature = "net")] ++ libc::AF_INET6 => { ++ SockaddrIn6::from_raw(addr, l).map(|sin6| Self { sin6 }) ++ } ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "illumos", ++ target_os = "netbsd", ++ target_os = "haiku", ++ target_os = "openbsd" ++ ))] ++ #[cfg(feature = "net")] ++ libc::AF_LINK => { ++ LinkAddr::from_raw(addr, l).map(|dl| Self { dl }) ++ } ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ libc::AF_NETLINK => { ++ NetlinkAddr::from_raw(addr, l).map(|nl| Self { nl }) ++ } ++ #[cfg(any( ++ target_os = "android", ++ target_os = "fuchsia", ++ target_os = "linux" ++ ))] ++ #[cfg(feature = "net")] ++ libc::AF_PACKET => { ++ LinkAddr::from_raw(addr, l).map(|dl| Self { dl }) ++ } ++ #[cfg(all( ++ feature = "ioctl", ++ any(target_os = "ios", target_os = "macos") ++ ))] ++ libc::AF_SYSTEM => { ++ SysControlAddr::from_raw(addr, l).map(|sctl| Self { sctl }) ++ } ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ libc::AF_VSOCK => { ++ VsockAddr::from_raw(addr, l).map(|vsock| Self { vsock }) ++ } ++ _ => None, ++ } ++ } ++ } ++ ++ #[cfg(any( ++ target_os = "android", ++ target_os = "fuchsia", ++ target_os = "illumos", ++ target_os = "linux" ++ ))] ++ fn len(&self) -> libc::socklen_t { ++ match self.as_unix_addr() { ++ // The UnixAddr type knows its own length ++ Some(ua) => ua.len(), ++ // For all else, we're just a boring SockaddrStorage ++ None => mem::size_of_val(self) as libc::socklen_t ++ } ++ } ++} ++ ++macro_rules! accessors { ++ ( ++ $fname:ident, ++ $fname_mut:ident, ++ $sockty:ty, ++ $family:expr, ++ $libc_ty:ty, ++ $field:ident) => { ++ /// Safely and falliably downcast to an immutable reference ++ pub fn $fname(&self) -> Option<&$sockty> { ++ if self.family() == Some($family) ++ && self.len() >= mem::size_of::<$libc_ty>() as libc::socklen_t ++ { ++ // Safe because family and len are validated ++ Some(unsafe { &self.$field }) ++ } else { ++ None ++ } ++ } ++ ++ /// Safely and falliably downcast to a mutable reference ++ pub fn $fname_mut(&mut self) -> Option<&mut $sockty> { ++ if self.family() == Some($family) ++ && self.len() >= mem::size_of::<$libc_ty>() as libc::socklen_t ++ { ++ // Safe because family and len are validated ++ Some(unsafe { &mut self.$field }) ++ } else { ++ None ++ } ++ } ++ }; ++} ++ ++impl SockaddrStorage { ++ /// Downcast to an immutable `[UnixAddr]` reference. ++ pub fn as_unix_addr(&self) -> Option<&UnixAddr> { ++ cfg_if! { ++ if #[cfg(any(target_os = "android", ++ target_os = "fuchsia", ++ target_os = "illumos", ++ target_os = "linux" ++ ))] ++ { ++ let p = unsafe{ &self.ss as *const libc::sockaddr_storage }; ++ // Safe because UnixAddr is strictly smaller than ++ // sockaddr_storage, and we're fully initialized ++ let len = unsafe { ++ (*(p as *const UnixAddr )).sun_len as usize ++ }; ++ } else { ++ let len = self.len() as usize; ++ } ++ } ++ // Sanity checks ++ if self.family() != Some(AddressFamily::Unix) || ++ len < offset_of!(libc::sockaddr_un, sun_path) || ++ len > mem::size_of::() { ++ None ++ } else { ++ Some(unsafe{&self.su}) ++ } ++ } ++ ++ /// Downcast to a mutable `[UnixAddr]` reference. ++ pub fn as_unix_addr_mut(&mut self) -> Option<&mut UnixAddr> { ++ cfg_if! { ++ if #[cfg(any(target_os = "android", ++ target_os = "fuchsia", ++ target_os = "illumos", ++ target_os = "linux" ++ ))] ++ { ++ let p = unsafe{ &self.ss as *const libc::sockaddr_storage }; ++ // Safe because UnixAddr is strictly smaller than ++ // sockaddr_storage, and we're fully initialized ++ let len = unsafe { ++ (*(p as *const UnixAddr )).sun_len as usize ++ }; ++ } else { ++ let len = self.len() as usize; ++ } ++ } ++ // Sanity checks ++ if self.family() != Some(AddressFamily::Unix) || ++ len < offset_of!(libc::sockaddr_un, sun_path) || ++ len > mem::size_of::() { ++ None ++ } else { ++ Some(unsafe{&mut self.su}) ++ } ++ } ++ ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ accessors! {as_alg_addr, as_alg_addr_mut, AlgAddr, ++ AddressFamily::Alg, libc::sockaddr_alg, alg} ++ ++ #[cfg(any( ++ target_os = "android", ++ target_os = "fuchsia", ++ target_os = "linux" ++ ))] ++ #[cfg(feature = "net")] ++ accessors! { ++ as_link_addr, as_link_addr_mut, LinkAddr, ++ AddressFamily::Packet, libc::sockaddr_ll, dl} ++ ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "illumos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg(feature = "net")] ++ accessors! { ++ as_link_addr, as_link_addr_mut, LinkAddr, ++ AddressFamily::Link, libc::sockaddr_dl, dl} ++ ++ #[cfg(feature = "net")] ++ accessors! { ++ as_sockaddr_in, as_sockaddr_in_mut, SockaddrIn, ++ AddressFamily::Inet, libc::sockaddr_in, sin} ++ ++ #[cfg(feature = "net")] ++ accessors! { ++ as_sockaddr_in6, as_sockaddr_in6_mut, SockaddrIn6, ++ AddressFamily::Inet6, libc::sockaddr_in6, sin6} ++ ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ accessors! {as_netlink_addr, as_netlink_addr_mut, NetlinkAddr, ++ AddressFamily::Netlink, libc::sockaddr_nl, nl} ++ ++ #[cfg(all(feature = "ioctl", any(target_os = "ios", target_os = "macos")))] ++ #[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))] ++ accessors! {as_sys_control_addr, as_sys_control_addr_mut, SysControlAddr, ++ AddressFamily::System, libc::sockaddr_ctl, sctl} ++ ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ accessors! {as_vsock_addr, as_vsock_addr_mut, VsockAddr, ++ AddressFamily::Vsock, libc::sockaddr_vm, vsock} ++} ++ ++impl fmt::Debug for SockaddrStorage { ++ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ++ f.debug_struct("SockaddrStorage") ++ // Safe because sockaddr_storage has the least specific ++ // field types ++ .field("ss", unsafe { &self.ss }) ++ .finish() ++ } ++} ++ ++impl fmt::Display for SockaddrStorage { ++ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ++ unsafe { ++ match self.ss.ss_family as i32 { ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ libc::AF_ALG => self.alg.fmt(f), ++ #[cfg(feature = "net")] ++ libc::AF_INET => self.sin.fmt(f), ++ #[cfg(feature = "net")] ++ libc::AF_INET6 => self.sin6.fmt(f), ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "illumos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg(feature = "net")] ++ libc::AF_LINK => self.dl.fmt(f), ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ libc::AF_NETLINK => self.nl.fmt(f), ++ #[cfg(any( ++ target_os = "android", ++ target_os = "linux", ++ target_os = "fuchsia" ++ ))] ++ #[cfg(feature = "net")] ++ libc::AF_PACKET => self.dl.fmt(f), ++ #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg(feature = "ioctl")] ++ libc::AF_SYSTEM => self.sctl.fmt(f), ++ libc::AF_UNIX => self.su.fmt(f), ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ libc::AF_VSOCK => self.vsock.fmt(f), ++ _ => "

".fmt(f), ++ } ++ } ++ } ++} ++ ++#[cfg(feature = "net")] ++impl From for SockaddrStorage { ++ fn from(s: net::SocketAddrV4) -> Self { ++ unsafe { ++ let mut ss: Self = mem::zeroed(); ++ ss.sin = SockaddrIn::from(s); ++ ss ++ } ++ } ++} ++ ++#[cfg(feature = "net")] ++impl From for SockaddrStorage { ++ fn from(s: net::SocketAddrV6) -> Self { ++ unsafe { ++ let mut ss: Self = mem::zeroed(); ++ ss.sin6 = SockaddrIn6::from(s); ++ ss ++ } ++ } ++} ++ ++#[cfg(feature = "net")] ++impl From for SockaddrStorage { ++ fn from(s: net::SocketAddr) -> Self { ++ match s { ++ net::SocketAddr::V4(sa4) => Self::from(sa4), ++ net::SocketAddr::V6(sa6) => Self::from(sa6), ++ } ++ } ++} ++ ++impl Hash for SockaddrStorage { ++ fn hash(&self, s: &mut H) { ++ unsafe { ++ match self.ss.ss_family as i32 { ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ libc::AF_ALG => self.alg.hash(s), ++ #[cfg(feature = "net")] ++ libc::AF_INET => self.sin.hash(s), ++ #[cfg(feature = "net")] ++ libc::AF_INET6 => self.sin6.hash(s), ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "illumos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg(feature = "net")] ++ libc::AF_LINK => self.dl.hash(s), ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ libc::AF_NETLINK => self.nl.hash(s), ++ #[cfg(any( ++ target_os = "android", ++ target_os = "linux", ++ target_os = "fuchsia" ++ ))] ++ #[cfg(feature = "net")] ++ libc::AF_PACKET => self.dl.hash(s), ++ #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg(feature = "ioctl")] ++ libc::AF_SYSTEM => self.sctl.hash(s), ++ libc::AF_UNIX => self.su.hash(s), ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ libc::AF_VSOCK => self.vsock.hash(s), ++ _ => self.ss.hash(s), ++ } ++ } ++ } ++} ++ ++impl PartialEq for SockaddrStorage { ++ fn eq(&self, other: &Self) -> bool { ++ unsafe { ++ match (self.ss.ss_family as i32, other.ss.ss_family as i32) { ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ (libc::AF_ALG, libc::AF_ALG) => self.alg == other.alg, ++ #[cfg(feature = "net")] ++ (libc::AF_INET, libc::AF_INET) => self.sin == other.sin, ++ #[cfg(feature = "net")] ++ (libc::AF_INET6, libc::AF_INET6) => self.sin6 == other.sin6, ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "illumos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg(feature = "net")] ++ (libc::AF_LINK, libc::AF_LINK) => self.dl == other.dl, ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ (libc::AF_NETLINK, libc::AF_NETLINK) => self.nl == other.nl, ++ #[cfg(any( ++ target_os = "android", ++ target_os = "fuchsia", ++ target_os = "linux" ++ ))] ++ #[cfg(feature = "net")] ++ (libc::AF_PACKET, libc::AF_PACKET) => self.dl == other.dl, ++ #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg(feature = "ioctl")] ++ (libc::AF_SYSTEM, libc::AF_SYSTEM) => self.sctl == other.sctl, ++ (libc::AF_UNIX, libc::AF_UNIX) => self.su == other.su, ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ (libc::AF_VSOCK, libc::AF_VSOCK) => self.vsock == other.vsock, ++ _ => false, ++ } ++ } ++ } ++} ++ ++mod private { ++ pub trait SockaddrLikePriv { ++ /// Returns a mutable raw pointer to the inner structure. ++ /// ++ /// # Safety ++ /// ++ /// This method is technically safe, but modifying the inner structure's ++ /// `family` or `len` fields may result in violating Nix's invariants. ++ /// It is best to use this method only with foreign functions that do ++ /// not change the sockaddr type. ++ fn as_mut_ptr(&mut self) -> *mut libc::sockaddr { ++ self as *mut Self as *mut libc::sockaddr ++ } + } + } + + /// Represents a socket address + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] ++#[deprecated( ++ since = "0.24.0", ++ note = "use SockaddrLike or SockaddrStorage instead" ++)] ++#[allow(missing_docs)] // Since they're all deprecated anyway ++#[allow(deprecated)] ++#[non_exhaustive] + pub enum SockAddr { ++ #[cfg(feature = "net")] ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Inet(InetAddr), + Unix(UnixAddr), + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Netlink(NetlinkAddr), + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Alg(AlgAddr), +- #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg(all( ++ feature = "ioctl", ++ any(target_os = "ios", target_os = "macos") ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))] + SysControl(SysControlAddr), + /// Datalink address (MAC) +- #[cfg(any(target_os = "android", +- target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "linux", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ #[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "linux", ++ target_os = "macos", ++ target_os = "illumos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg(feature = "net")] ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Link(LinkAddr), +- #[cfg(target_os = "linux")] ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + Vsock(VsockAddr), + } + ++#[allow(missing_docs)] // Since they're all deprecated anyway ++#[allow(deprecated)] + impl SockAddr { ++ feature! { ++ #![feature = "net"] + pub fn new_inet(addr: InetAddr) -> SockAddr { + SockAddr::Inet(addr) + } ++ } + + pub fn new_unix(path: &P) -> Result { + Ok(SockAddr::Unix(UnixAddr::new(path)?)) + } + + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn new_netlink(pid: u32, groups: u32) -> SockAddr { + SockAddr::Netlink(NetlinkAddr::new(pid, groups)) + } + + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn new_alg(alg_type: &str, alg_name: &str) -> SockAddr { + SockAddr::Alg(AlgAddr::new(alg_type, alg_name)) + } + ++ feature! { ++ #![feature = "ioctl"] + #[cfg(any(target_os = "ios", target_os = "macos"))] + pub fn new_sys_control(sockfd: RawFd, name: &str, unit: u32) -> Result { +- SysControlAddr::from_name(sockfd, name, unit).map(|a| SockAddr::SysControl(a)) ++ SysControlAddr::from_name(sockfd, name, unit).map(SockAddr::SysControl) ++ } + } + +- #[cfg(target_os = "linux")] ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn new_vsock(cid: u32, port: u32) -> SockAddr { + SockAddr::Vsock(VsockAddr::new(cid, port)) + } + + pub fn family(&self) -> AddressFamily { + match *self { ++ #[cfg(feature = "net")] + SockAddr::Inet(InetAddr::V4(..)) => AddressFamily::Inet, ++ #[cfg(feature = "net")] + SockAddr::Inet(InetAddr::V6(..)) => AddressFamily::Inet6, + SockAddr::Unix(..) => AddressFamily::Unix, + #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Netlink(..) => AddressFamily::Netlink, + #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Alg(..) => AddressFamily::Alg, +- #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg(all( ++ feature = "ioctl", ++ any(target_os = "ios", target_os = "macos") ++ ))] + SockAddr::SysControl(..) => AddressFamily::System, + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg(feature = "net")] + SockAddr::Link(..) => AddressFamily::Packet, +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "illumos", ++ target_os = "openbsd" ++ ))] ++ #[cfg(feature = "net")] + SockAddr::Link(..) => AddressFamily::Link, +- #[cfg(target_os = "linux")] ++ #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Vsock(..) => AddressFamily::Vsock, + } + } + ++ #[deprecated(since = "0.23.0", note = "use .to_string() instead")] + pub fn to_str(&self) -> String { + format!("{}", self) + } +@@ -714,42 +2107,68 @@ impl SockAddr { + /// + /// Supports only the following address families: Unix, Inet (v4 & v6), Netlink and System. + /// Returns None for unsupported families. +- pub unsafe fn from_libc_sockaddr(addr: *const libc::sockaddr) -> Option { ++ /// ++ /// # Safety ++ /// ++ /// unsafe because it takes a raw pointer as argument. The caller must ++ /// ensure that the pointer is valid. ++ #[cfg(not(target_os = "fuchsia"))] ++ #[cfg(feature = "net")] ++ pub(crate) unsafe fn from_libc_sockaddr( ++ addr: *const libc::sockaddr, ++ ) -> Option { + if addr.is_null() { + None + } else { + match AddressFamily::from_i32(i32::from((*addr).sa_family)) { + Some(AddressFamily::Unix) => None, ++ #[cfg(feature = "net")] + Some(AddressFamily::Inet) => Some(SockAddr::Inet( +- InetAddr::V4(*(addr as *const libc::sockaddr_in)))), ++ InetAddr::V4(ptr::read_unaligned(addr as *const _)), ++ )), ++ #[cfg(feature = "net")] + Some(AddressFamily::Inet6) => Some(SockAddr::Inet( +- InetAddr::V6(*(addr as *const libc::sockaddr_in6)))), ++ InetAddr::V6(ptr::read_unaligned(addr as *const _)), ++ )), + #[cfg(any(target_os = "android", target_os = "linux"))] + Some(AddressFamily::Netlink) => Some(SockAddr::Netlink( +- NetlinkAddr(*(addr as *const libc::sockaddr_nl)))), +- #[cfg(any(target_os = "ios", target_os = "macos"))] ++ NetlinkAddr(ptr::read_unaligned(addr as *const _)), ++ )), ++ #[cfg(all( ++ feature = "ioctl", ++ any(target_os = "ios", target_os = "macos") ++ ))] + Some(AddressFamily::System) => Some(SockAddr::SysControl( +- SysControlAddr(*(addr as *const libc::sockaddr_ctl)))), ++ SysControlAddr(ptr::read_unaligned(addr as *const _)), ++ )), + #[cfg(any(target_os = "android", target_os = "linux"))] +- Some(AddressFamily::Packet) => Some(SockAddr::Link( +- LinkAddr(*(addr as *const libc::sockaddr_ll)))), +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ #[cfg(feature = "net")] ++ Some(AddressFamily::Packet) => Some(SockAddr::Link(LinkAddr( ++ ptr::read_unaligned(addr as *const _), ++ ))), ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "illumos", ++ target_os = "openbsd" ++ ))] ++ #[cfg(feature = "net")] + Some(AddressFamily::Link) => { +- let ether_addr = LinkAddr(*(addr as *const libc::sockaddr_dl)); ++ let ether_addr = ++ LinkAddr(ptr::read_unaligned(addr as *const _)); + if ether_addr.is_empty() { + None + } else { + Some(SockAddr::Link(ether_addr)) + } +- }, +- #[cfg(target_os = "linux")] +- Some(AddressFamily::Vsock) => Some(SockAddr::Vsock( +- VsockAddr(*(addr as *const libc::sockaddr_vm)))), ++ } ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ Some(AddressFamily::Vsock) => Some(SockAddr::Vsock(VsockAddr( ++ ptr::read_unaligned(addr as *const _), ++ ))), + // Other address families are currently not supported and simply yield a None + // entry instead of a proper conversion to a `SockAddr`. + Some(_) | None => None, +@@ -764,96 +2183,172 @@ impl SockAddr { + /// with the size of the actual data type. sockaddr is commonly used as a proxy for + /// a superclass as C doesn't support inheritance, so many functions that take + /// a sockaddr * need to take the size of the underlying type as well and then internally cast it back. +- pub unsafe fn as_ffi_pair(&self) -> (&libc::sockaddr, libc::socklen_t) { ++ pub fn as_ffi_pair(&self) -> (&libc::sockaddr, libc::socklen_t) { + match *self { ++ #[cfg(feature = "net")] + SockAddr::Inet(InetAddr::V4(ref addr)) => ( +- &*(addr as *const libc::sockaddr_in as *const libc::sockaddr), +- mem::size_of_val(addr) as libc::socklen_t ++ // This cast is always allowed in C ++ unsafe { ++ &*(addr as *const libc::sockaddr_in ++ as *const libc::sockaddr) ++ }, ++ mem::size_of_val(addr) as libc::socklen_t, + ), ++ #[cfg(feature = "net")] + SockAddr::Inet(InetAddr::V6(ref addr)) => ( +- &*(addr as *const libc::sockaddr_in6 as *const libc::sockaddr), +- mem::size_of_val(addr) as libc::socklen_t ++ // This cast is always allowed in C ++ unsafe { ++ &*(addr as *const libc::sockaddr_in6 ++ as *const libc::sockaddr) ++ }, ++ mem::size_of_val(addr) as libc::socklen_t, + ), +- SockAddr::Unix(UnixAddr(ref addr, len)) => ( +- &*(addr as *const libc::sockaddr_un as *const libc::sockaddr), +- (len + offset_of!(libc::sockaddr_un, sun_path)) as libc::socklen_t ++ SockAddr::Unix(ref unix_addr) => ( ++ // This cast is always allowed in C ++ unsafe { ++ &*(&unix_addr.sun as *const libc::sockaddr_un ++ as *const libc::sockaddr) ++ }, ++ unix_addr.sun_len() as libc::socklen_t, + ), + #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Netlink(NetlinkAddr(ref sa)) => ( +- &*(sa as *const libc::sockaddr_nl as *const libc::sockaddr), +- mem::size_of_val(sa) as libc::socklen_t ++ // This cast is always allowed in C ++ unsafe { ++ &*(sa as *const libc::sockaddr_nl as *const libc::sockaddr) ++ }, ++ mem::size_of_val(sa) as libc::socklen_t, + ), + #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Alg(AlgAddr(ref sa)) => ( +- &*(sa as *const libc::sockaddr_alg as *const libc::sockaddr), +- mem::size_of_val(sa) as libc::socklen_t ++ // This cast is always allowed in C ++ unsafe { ++ &*(sa as *const libc::sockaddr_alg as *const libc::sockaddr) ++ }, ++ mem::size_of_val(sa) as libc::socklen_t, + ), +- #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg(all( ++ feature = "ioctl", ++ any(target_os = "ios", target_os = "macos") ++ ))] + SockAddr::SysControl(SysControlAddr(ref sa)) => ( +- &*(sa as *const libc::sockaddr_ctl as *const libc::sockaddr), +- mem::size_of_val(sa) as libc::socklen_t +- ++ // This cast is always allowed in C ++ unsafe { ++ &*(sa as *const libc::sockaddr_ctl as *const libc::sockaddr) ++ }, ++ mem::size_of_val(sa) as libc::socklen_t, + ), + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg(feature = "net")] + SockAddr::Link(LinkAddr(ref addr)) => ( +- &*(addr as *const libc::sockaddr_ll as *const libc::sockaddr), +- mem::size_of_val(addr) as libc::socklen_t ++ // This cast is always allowed in C ++ unsafe { ++ &*(addr as *const libc::sockaddr_ll ++ as *const libc::sockaddr) ++ }, ++ mem::size_of_val(addr) as libc::socklen_t, + ), +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "illumos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[cfg(feature = "net")] + SockAddr::Link(LinkAddr(ref addr)) => ( +- &*(addr as *const libc::sockaddr_dl as *const libc::sockaddr), +- mem::size_of_val(addr) as libc::socklen_t ++ // This cast is always allowed in C ++ unsafe { ++ &*(addr as *const libc::sockaddr_dl ++ as *const libc::sockaddr) ++ }, ++ mem::size_of_val(addr) as libc::socklen_t, + ), +- #[cfg(target_os = "linux")] ++ #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Vsock(VsockAddr(ref sa)) => ( +- &*(sa as *const libc::sockaddr_vm as *const libc::sockaddr), +- mem::size_of_val(sa) as libc::socklen_t ++ // This cast is always allowed in C ++ unsafe { ++ &*(sa as *const libc::sockaddr_vm as *const libc::sockaddr) ++ }, ++ mem::size_of_val(sa) as libc::socklen_t, + ), + } + } + } + ++#[allow(deprecated)] + impl fmt::Display for SockAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { ++ #[cfg(feature = "net")] + SockAddr::Inet(ref inet) => inet.fmt(f), + SockAddr::Unix(ref unix) => unix.fmt(f), + #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Netlink(ref nl) => nl.fmt(f), + #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Alg(ref nl) => nl.fmt(f), +- #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg(all( ++ feature = "ioctl", ++ any(target_os = "ios", target_os = "macos") ++ ))] + SockAddr::SysControl(ref sc) => sc.fmt(f), +- #[cfg(any(target_os = "android", +- target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "linux", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++ #[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "linux", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "illumos", ++ target_os = "openbsd" ++ ))] ++ #[cfg(feature = "net")] + SockAddr::Link(ref ether_addr) => ether_addr.fmt(f), +- #[cfg(target_os = "linux")] ++ #[cfg(any(target_os = "android", target_os = "linux"))] + SockAddr::Vsock(ref svm) => svm.fmt(f), + } + } + } + ++#[cfg(not(target_os = "fuchsia"))] ++#[cfg(feature = "net")] ++#[allow(deprecated)] ++impl private::SockaddrLikePriv for SockAddr {} ++#[cfg(not(target_os = "fuchsia"))] ++#[cfg(feature = "net")] ++#[allow(deprecated)] ++impl SockaddrLike for SockAddr { ++ unsafe fn from_raw( ++ addr: *const libc::sockaddr, ++ _len: Option, ++ ) -> Option { ++ Self::from_libc_sockaddr(addr) ++ } ++} ++ + #[cfg(any(target_os = "android", target_os = "linux"))] ++#[cfg_attr(docsrs, doc(cfg(all())))] + pub mod netlink { +- use ::sys::socket::addr::AddressFamily; ++ use super::*; ++ use crate::sys::socket::addr::AddressFamily; + use libc::{sa_family_t, sockaddr_nl}; + use std::{fmt, mem}; + ++ /// Address for the Linux kernel user interface device. ++ /// ++ /// # References ++ /// ++ /// [netlink(7)](https://man7.org/linux/man-pages/man7/netlink.7.html) + #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] +- pub struct NetlinkAddr(pub sockaddr_nl); ++ #[repr(transparent)] ++ pub struct NetlinkAddr(pub(in super::super) sockaddr_nl); + + impl NetlinkAddr { ++ /// Construct a new socket address from its port ID and multicast groups ++ /// mask. + pub fn new(pid: u32, groups: u32) -> NetlinkAddr { + let mut addr: sockaddr_nl = unsafe { mem::zeroed() }; + addr.nl_family = AddressFamily::Netlink as sa_family_t; +@@ -863,15 +2358,44 @@ pub mod netlink { + NetlinkAddr(addr) + } + +- pub fn pid(&self) -> u32 { ++ /// Return the socket's port ID. ++ pub const fn pid(&self) -> u32 { + self.0.nl_pid + } + +- pub fn groups(&self) -> u32 { ++ /// Return the socket's multicast groups mask ++ pub const fn groups(&self) -> u32 { + self.0.nl_groups + } + } + ++ impl private::SockaddrLikePriv for NetlinkAddr {} ++ impl SockaddrLike for NetlinkAddr { ++ unsafe fn from_raw( ++ addr: *const libc::sockaddr, ++ len: Option, ++ ) -> Option ++ where ++ Self: Sized, ++ { ++ if let Some(l) = len { ++ if l != mem::size_of::() as libc::socklen_t { ++ return None; ++ } ++ } ++ if (*addr).sa_family as i32 != libc::AF_NETLINK { ++ return None; ++ } ++ Some(Self(ptr::read_unaligned(addr as *const _))) ++ } ++ } ++ ++ impl AsRef for NetlinkAddr { ++ fn as_ref(&self) -> &libc::sockaddr_nl { ++ &self.0 ++ } ++ } ++ + impl fmt::Display for NetlinkAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "pid: {} groups: {}", self.pid(), self.groups()) +@@ -880,21 +2404,64 @@ pub mod netlink { + } + + #[cfg(any(target_os = "android", target_os = "linux"))] ++#[cfg_attr(docsrs, doc(cfg(all())))] + pub mod alg { +- use libc::{AF_ALG, sockaddr_alg, c_char}; +- use std::{fmt, mem, str}; +- use std::hash::{Hash, Hasher}; ++ use super::*; ++ use libc::{c_char, sockaddr_alg, AF_ALG}; + use std::ffi::CStr; ++ use std::hash::{Hash, Hasher}; ++ use std::{fmt, mem, str}; + ++ /// Socket address for the Linux kernel crypto API + #[derive(Copy, Clone)] +- pub struct AlgAddr(pub sockaddr_alg); ++ #[repr(transparent)] ++ pub struct AlgAddr(pub(in super::super) sockaddr_alg); ++ ++ impl private::SockaddrLikePriv for AlgAddr {} ++ impl SockaddrLike for AlgAddr { ++ unsafe fn from_raw( ++ addr: *const libc::sockaddr, ++ l: Option, ++ ) -> Option ++ where ++ Self: Sized, ++ { ++ if let Some(l) = l { ++ if l != mem::size_of::() as libc::socklen_t ++ { ++ return None; ++ } ++ } ++ if (*addr).sa_family as i32 != libc::AF_ALG { ++ return None; ++ } ++ Some(Self(ptr::read_unaligned(addr as *const _))) ++ } ++ } ++ ++ impl AsRef for AlgAddr { ++ fn as_ref(&self) -> &libc::sockaddr_alg { ++ &self.0 ++ } ++ } + + // , PartialEq, Eq, Debug, Hash + impl PartialEq for AlgAddr { + fn eq(&self, other: &Self) -> bool { + let (inner, other) = (self.0, other.0); +- (inner.salg_family, &inner.salg_type[..], inner.salg_feat, inner.salg_mask, &inner.salg_name[..]) == +- (other.salg_family, &other.salg_type[..], other.salg_feat, other.salg_mask, &other.salg_name[..]) ++ ( ++ inner.salg_family, ++ &inner.salg_type[..], ++ inner.salg_feat, ++ inner.salg_mask, ++ &inner.salg_name[..], ++ ) == ( ++ other.salg_family, ++ &other.salg_type[..], ++ other.salg_feat, ++ other.salg_mask, ++ &other.salg_name[..], ++ ) + } + } + +@@ -903,35 +2470,53 @@ pub mod alg { + impl Hash for AlgAddr { + fn hash(&self, s: &mut H) { + let inner = self.0; +- (inner.salg_family, &inner.salg_type[..], inner.salg_feat, inner.salg_mask, &inner.salg_name[..]).hash(s); ++ ( ++ inner.salg_family, ++ &inner.salg_type[..], ++ inner.salg_feat, ++ inner.salg_mask, ++ &inner.salg_name[..], ++ ) ++ .hash(s); + } + } + + impl AlgAddr { ++ /// Construct an `AF_ALG` socket from its cipher name and type. + pub fn new(alg_type: &str, alg_name: &str) -> AlgAddr { + let mut addr: sockaddr_alg = unsafe { mem::zeroed() }; + addr.salg_family = AF_ALG as u16; +- addr.salg_type[..alg_type.len()].copy_from_slice(alg_type.to_string().as_bytes()); +- addr.salg_name[..alg_name.len()].copy_from_slice(alg_name.to_string().as_bytes()); ++ addr.salg_type[..alg_type.len()] ++ .copy_from_slice(alg_type.to_string().as_bytes()); ++ addr.salg_name[..alg_name.len()] ++ .copy_from_slice(alg_name.to_string().as_bytes()); + + AlgAddr(addr) + } + +- ++ /// Return the socket's cipher type, for example `hash` or `aead`. + pub fn alg_type(&self) -> &CStr { +- unsafe { CStr::from_ptr(self.0.salg_type.as_ptr() as *const c_char) } ++ unsafe { ++ CStr::from_ptr(self.0.salg_type.as_ptr() as *const c_char) ++ } + } + ++ /// Return the socket's cipher name, for example `sha1`. + pub fn alg_name(&self) -> &CStr { +- unsafe { CStr::from_ptr(self.0.salg_name.as_ptr() as *const c_char) } ++ unsafe { ++ CStr::from_ptr(self.0.salg_name.as_ptr() as *const c_char) ++ } + } + } + + impl fmt::Display for AlgAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +- write!(f, "type: {} alg: {}", +- self.alg_name().to_string_lossy(), +- self.alg_type().to_string_lossy()) ++ write!( ++ f, ++ "type: {} alg: {}", ++ self.alg_name().to_string_lossy(), ++ self.alg_type().to_string_lossy() ++ ) + } + } + +@@ -942,13 +2527,16 @@ pub mod alg { + } + } + ++feature! { ++#![feature = "ioctl"] + #[cfg(any(target_os = "ios", target_os = "macos"))] + pub mod sys_control { +- use ::sys::socket::addr::AddressFamily; ++ use crate::sys::socket::addr::AddressFamily; + use libc::{self, c_uchar}; +- use std::{fmt, mem}; ++ use std::{fmt, mem, ptr}; + use std::os::unix::io::RawFd; +- use {Errno, Error, Result}; ++ use crate::{Errno, Result}; ++ use super::{private, SockaddrLike}; + + // FIXME: Move type into `libc` + #[repr(C)] +@@ -959,18 +2547,48 @@ pub mod sys_control { + pub ctl_name: [c_uchar; MAX_KCTL_NAME], + } + +- const CTL_IOC_MAGIC: u8 = 'N' as u8; ++ const CTL_IOC_MAGIC: u8 = b'N'; + const CTL_IOC_INFO: u8 = 3; + const MAX_KCTL_NAME: usize = 96; + + ioctl_readwrite!(ctl_info, CTL_IOC_MAGIC, CTL_IOC_INFO, ctl_ioc_info); + +- #[repr(C)] ++ /// Apple system control socket ++ /// ++ /// # References ++ /// ++ /// + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +- pub struct SysControlAddr(pub libc::sockaddr_ctl); ++ #[repr(transparent)] ++ pub struct SysControlAddr(pub(in super::super) libc::sockaddr_ctl); ++ ++ impl private::SockaddrLikePriv for SysControlAddr {} ++ impl SockaddrLike for SysControlAddr { ++ unsafe fn from_raw(addr: *const libc::sockaddr, len: Option) ++ -> Option where Self: Sized ++ { ++ if let Some(l) = len { ++ if l != mem::size_of::() as libc::socklen_t { ++ return None; ++ } ++ } ++ if (*addr).sa_family as i32 != libc::AF_SYSTEM { ++ return None; ++ } ++ Some(Self(ptr::read_unaligned(addr as *const _))) ++ } ++ } ++ ++ impl AsRef for SysControlAddr { ++ fn as_ref(&self) -> &libc::sockaddr_ctl { ++ &self.0 ++ } ++ } + + impl SysControlAddr { +- pub fn new(id: u32, unit: u32) -> SysControlAddr { ++ /// Construct a new `SysControlAddr` from its kernel unique identifier ++ /// and unit number. ++ pub const fn new(id: u32, unit: u32) -> SysControlAddr { + let addr = libc::sockaddr_ctl { + sc_len: mem::size_of::() as c_uchar, + sc_family: AddressFamily::System as c_uchar, +@@ -983,9 +2601,11 @@ pub mod sys_control { + SysControlAddr(addr) + } + ++ /// Construct a new `SysControlAddr` from its human readable name and ++ /// unit number. + pub fn from_name(sockfd: RawFd, name: &str, unit: u32) -> Result { + if name.len() > MAX_KCTL_NAME { +- return Err(Error::Sys(Errno::ENAMETOOLONG)); ++ return Err(Errno::ENAMETOOLONG); + } + + let mut ctl_name = [0; MAX_KCTL_NAME]; +@@ -997,11 +2617,13 @@ pub mod sys_control { + Ok(SysControlAddr::new(info.ctl_id, unit)) + } + +- pub fn id(&self) -> u32 { ++ /// Return the kernel unique identifier ++ pub const fn id(&self) -> u32 { + self.0.sc_id + } + +- pub fn unit(&self) -> u32 { ++ /// Return the kernel controller private unit number. ++ pub const fn unit(&self) -> u32 { + self.0.sc_unit + } + } +@@ -1012,23 +2634,21 @@ pub mod sys_control { + } + } + } ++} + +- +-#[cfg(any(target_os = "android", target_os = "linux"))] ++#[cfg(any(target_os = "android", target_os = "linux", target_os = "fuchsia"))] ++#[cfg_attr(docsrs, doc(cfg(all())))] + mod datalink { +- use super::{libc, fmt, AddressFamily}; ++ feature! { ++ #![feature = "net"] ++ use super::{fmt, mem, private, ptr, SockaddrLike}; + + /// Hardware Address + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +- pub struct LinkAddr(pub libc::sockaddr_ll); ++ #[repr(transparent)] ++ pub struct LinkAddr(pub(in super::super) libc::sockaddr_ll); + + impl LinkAddr { +- /// Always AF_PACKET +- pub fn family(&self) -> AddressFamily { +- assert_eq!(self.0.sll_family as i32, libc::AF_PACKET); +- AddressFamily::Packet +- } +- + /// Physical-layer protocol + pub fn protocol(&self) -> u16 { + self.0.sll_protocol +@@ -1055,68 +2675,96 @@ mod datalink { + } + + /// Physical-layer address (MAC) +- pub fn addr(&self) -> [u8; 6] { +- [ +- self.0.sll_addr[0] as u8, +- self.0.sll_addr[1] as u8, +- self.0.sll_addr[2] as u8, +- self.0.sll_addr[3] as u8, +- self.0.sll_addr[4] as u8, +- self.0.sll_addr[5] as u8, +- ] ++ // Returns an Option just for cross-platform compatibility ++ pub fn addr(&self) -> Option<[u8; 6]> { ++ Some([ ++ self.0.sll_addr[0], ++ self.0.sll_addr[1], ++ self.0.sll_addr[2], ++ self.0.sll_addr[3], ++ self.0.sll_addr[4], ++ self.0.sll_addr[5], ++ ]) + } + } + + impl fmt::Display for LinkAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +- let addr = self.addr(); +- write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", +- addr[0], +- addr[1], +- addr[2], +- addr[3], +- addr[4], +- addr[5]) ++ if let Some(addr) = self.addr() { ++ write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", ++ addr[0], ++ addr[1], ++ addr[2], ++ addr[3], ++ addr[4], ++ addr[5]) ++ } else { ++ Ok(()) ++ } + } + } ++ impl private::SockaddrLikePriv for LinkAddr {} ++ impl SockaddrLike for LinkAddr { ++ unsafe fn from_raw(addr: *const libc::sockaddr, ++ len: Option) ++ -> Option where Self: Sized ++ { ++ if let Some(l) = len { ++ if l != mem::size_of::() as libc::socklen_t { ++ return None; ++ } ++ } ++ if (*addr).sa_family as i32 != libc::AF_PACKET { ++ return None; ++ } ++ Some(Self(ptr::read_unaligned(addr as *const _))) ++ } ++ } ++ ++ impl AsRef for LinkAddr { ++ fn as_ref(&self) -> &libc::sockaddr_ll { ++ &self.0 ++ } ++ } ++ ++ } + } + +-#[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++#[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "illumos", ++ target_os = "netbsd", ++ target_os = "haiku", ++ target_os = "openbsd" ++))] ++#[cfg_attr(docsrs, doc(cfg(all())))] + mod datalink { +- use super::{libc, fmt, AddressFamily}; ++ feature! { ++ #![feature = "net"] ++ use super::{fmt, mem, private, ptr, SockaddrLike}; + + /// Hardware Address + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +- pub struct LinkAddr(pub libc::sockaddr_dl); ++ #[repr(transparent)] ++ pub struct LinkAddr(pub(in super::super) libc::sockaddr_dl); + + impl LinkAddr { +- /// Total length of sockaddr +- pub fn len(&self) -> usize { +- self.0.sdl_len as usize +- } +- +- /// always == AF_LINK +- pub fn family(&self) -> AddressFamily { +- assert_eq!(i32::from(self.0.sdl_family), libc::AF_LINK); +- AddressFamily::Link +- } +- + /// interface index, if != 0, system given index for interface ++ #[cfg(not(target_os = "haiku"))] + pub fn ifindex(&self) -> usize { + self.0.sdl_index as usize + } + + /// Datalink type ++ #[cfg(not(target_os = "haiku"))] + pub fn datalink_type(&self) -> u8 { + self.0.sdl_type + } + +- // MAC address start position ++ /// MAC address start position + pub fn nlen(&self) -> usize { + self.0.sdl_nlen as usize + } +@@ -1127,6 +2775,7 @@ mod datalink { + } + + /// link layer selector length ++ #[cfg(not(target_os = "haiku"))] + pub fn slen(&self) -> usize { + self.0.sdl_slen as usize + } +@@ -1142,52 +2791,119 @@ mod datalink { + } + + /// Physical-layer address (MAC) +- pub fn addr(&self) -> [u8; 6] { ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] ++ pub fn addr(&self) -> Option<[u8; 6]> { + let nlen = self.nlen(); + let data = self.0.sdl_data; + +- assert!(!self.is_empty()); +- +- [ +- data[nlen] as u8, +- data[nlen + 1] as u8, +- data[nlen + 2] as u8, +- data[nlen + 3] as u8, +- data[nlen + 4] as u8, +- data[nlen + 5] as u8, +- ] ++ if self.is_empty() { ++ None ++ } else { ++ Some([ ++ data[nlen] as u8, ++ data[nlen + 1] as u8, ++ data[nlen + 2] as u8, ++ data[nlen + 3] as u8, ++ data[nlen + 4] as u8, ++ data[nlen + 5] as u8, ++ ]) ++ } + } + } + + impl fmt::Display for LinkAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +- let addr = self.addr(); +- write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", +- addr[0], +- addr[1], +- addr[2], +- addr[3], +- addr[4], +- addr[5]) ++ if let Some(addr) = self.addr() { ++ write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", ++ addr[0], ++ addr[1], ++ addr[2], ++ addr[3], ++ addr[4], ++ addr[5]) ++ } else { ++ Ok(()) ++ } ++ } ++ } ++ impl private::SockaddrLikePriv for LinkAddr {} ++ impl SockaddrLike for LinkAddr { ++ unsafe fn from_raw(addr: *const libc::sockaddr, ++ len: Option) ++ -> Option where Self: Sized ++ { ++ if let Some(l) = len { ++ if l != mem::size_of::() as libc::socklen_t { ++ return None; ++ } ++ } ++ if (*addr).sa_family as i32 != libc::AF_LINK { ++ return None; ++ } ++ Some(Self(ptr::read_unaligned(addr as *const _))) ++ } ++ } ++ ++ impl AsRef for LinkAddr { ++ fn as_ref(&self) -> &libc::sockaddr_dl { ++ &self.0 + } + } ++ ++ } + } + +-#[cfg(target_os = "linux")] ++#[cfg(any(target_os = "android", target_os = "linux"))] ++#[cfg_attr(docsrs, doc(cfg(all())))] + pub mod vsock { +- use ::sys::socket::addr::AddressFamily; ++ use super::*; ++ use crate::sys::socket::addr::AddressFamily; + use libc::{sa_family_t, sockaddr_vm}; +- use std::{fmt, mem}; + use std::hash::{Hash, Hasher}; ++ use std::{fmt, mem}; + ++ /// Socket address for VMWare VSockets protocol ++ /// ++ /// # References ++ /// ++ /// [vsock(7)](https://man7.org/linux/man-pages/man7/vsock.7.html) + #[derive(Copy, Clone)] +- pub struct VsockAddr(pub sockaddr_vm); ++ #[repr(transparent)] ++ pub struct VsockAddr(pub(in super::super) sockaddr_vm); ++ ++ impl private::SockaddrLikePriv for VsockAddr {} ++ impl SockaddrLike for VsockAddr { ++ unsafe fn from_raw( ++ addr: *const libc::sockaddr, ++ len: Option, ++ ) -> Option ++ where ++ Self: Sized, ++ { ++ if let Some(l) = len { ++ if l != mem::size_of::() as libc::socklen_t { ++ return None; ++ } ++ } ++ if (*addr).sa_family as i32 != libc::AF_VSOCK { ++ return None; ++ } ++ Some(Self(ptr::read_unaligned(addr as *const _))) ++ } ++ } ++ ++ impl AsRef for VsockAddr { ++ fn as_ref(&self) -> &libc::sockaddr_vm { ++ &self.0 ++ } ++ } + + impl PartialEq for VsockAddr { + fn eq(&self, other: &Self) -> bool { + let (inner, other) = (self.0, other.0); +- (inner.svm_family, inner.svm_cid, inner.svm_port) == +- (other.svm_family, other.svm_cid, other.svm_port) ++ (inner.svm_family, inner.svm_cid, inner.svm_port) ++ == (other.svm_family, other.svm_cid, other.svm_port) + } + } + +@@ -1205,6 +2921,7 @@ pub mod vsock { + /// The address for AF_VSOCK socket is defined as a combination of a + /// 32-bit Context Identifier (CID) and a 32-bit port number. + impl VsockAddr { ++ /// Construct a `VsockAddr` from its raw fields. + pub fn new(cid: u32, port: u32) -> VsockAddr { + let mut addr: sockaddr_vm = unsafe { mem::zeroed() }; + addr.svm_family = AddressFamily::Vsock as sa_family_t; +@@ -1240,68 +2957,291 @@ pub mod vsock { + + #[cfg(test)] + mod tests { +- #[cfg(any(target_os = "android", +- target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "linux", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] + use super::*; + +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] +- #[test] +- fn test_macos_loopback_datalink_addr() { +- let bytes = [20i8, 18, 1, 0, 24, 3, 0, 0, 108, 111, 48, 0, 0, 0, 0, 0]; +- let sa = bytes.as_ptr() as *const libc::sockaddr; +- let _sock_addr = unsafe { SockAddr::from_libc_sockaddr(sa) }; +- assert!(_sock_addr.is_none()); +- } +- +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] +- #[test] +- fn test_macos_tap_datalink_addr() { +- let bytes = [20i8, 18, 7, 0, 6, 3, 6, 0, 101, 110, 48, 24, 101, -112, -35, 76, -80]; +- let ptr = bytes.as_ptr(); +- let sa = ptr as *const libc::sockaddr; +- let _sock_addr = unsafe { SockAddr::from_libc_sockaddr(sa) }; +- +- assert!(_sock_addr.is_some()); +- +- let sock_addr = _sock_addr.unwrap(); +- +- assert_eq!(sock_addr.family(), AddressFamily::Link); +- +- match sock_addr { +- SockAddr::Link(ether_addr) => { +- assert_eq!(ether_addr.addr(), [24u8, 101, 144, 221, 76, 176]); +- }, +- _ => { unreachable!() } +- }; ++ mod types { ++ use super::*; ++ ++ #[test] ++ fn test_ipv4addr_to_libc() { ++ let s = std::net::Ipv4Addr::new(1, 2, 3, 4); ++ let l = ipv4addr_to_libc(s); ++ assert_eq!(l.s_addr, u32::to_be(0x01020304)); ++ } ++ ++ #[test] ++ fn test_ipv6addr_to_libc() { ++ let s = std::net::Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8); ++ let l = ipv6addr_to_libc(&s); ++ assert_eq!( ++ l.s6_addr, ++ [0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8] ++ ); ++ } + } + +- #[cfg(any(target_os = "android", target_os = "linux"))] +- #[test] +- fn test_abstract_sun_path() { +- let name = String::from("nix\0abstract\0test"); +- let addr = UnixAddr::new_abstract(name.as_bytes()).unwrap(); +- +- let sun_path1 = addr.sun_path(); +- let sun_path2 = [0u8, 110, 105, 120, 0, 97, 98, 115, 116, 114, 97, 99, 116, 0, 116, 101, 115, 116]; +- assert_eq!(sun_path1.len(), sun_path2.len()); +- for i in 0..sun_path1.len() { +- assert_eq!(sun_path1[i], sun_path2[i]); ++ mod link { ++ #![allow(clippy::cast_ptr_alignment)] ++ ++ #[cfg(any( ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "illumos" ++ ))] ++ use super::super::super::socklen_t; ++ use super::*; ++ ++ /// Don't panic when trying to display an empty datalink address ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ))] ++ #[test] ++ fn test_datalink_display() { ++ use super::super::LinkAddr; ++ use std::mem; ++ ++ let la = LinkAddr(libc::sockaddr_dl { ++ sdl_len: 56, ++ sdl_family: 18, ++ sdl_index: 5, ++ sdl_type: 24, ++ sdl_nlen: 3, ++ sdl_alen: 0, ++ sdl_slen: 0, ++ ..unsafe { mem::zeroed() } ++ }); ++ format!("{}", la); ++ } ++ ++ #[cfg(all( ++ any( ++ target_os = "android", ++ target_os = "fuchsia", ++ target_os = "linux" ++ ), ++ target_endian = "little" ++ ))] ++ #[test] ++ fn linux_loopback() { ++ #[repr(align(2))] ++ struct Raw([u8; 20]); ++ ++ let bytes = Raw([ ++ 17u8, 0, 0, 0, 1, 0, 0, 0, 4, 3, 0, 6, 1, 2, 3, 4, 5, 6, 0, 0, ++ ]); ++ let sa = bytes.0.as_ptr() as *const libc::sockaddr; ++ let len = None; ++ let sock_addr = ++ unsafe { SockaddrStorage::from_raw(sa, len) }.unwrap(); ++ assert_eq!(sock_addr.family(), Some(AddressFamily::Packet)); ++ match sock_addr.as_link_addr() { ++ Some(dl) => assert_eq!(dl.addr(), Some([1, 2, 3, 4, 5, 6])), ++ None => panic!("Can't unwrap sockaddr storage"), ++ } ++ } ++ ++ #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[test] ++ fn macos_loopback() { ++ let bytes = ++ [20i8, 18, 1, 0, 24, 3, 0, 0, 108, 111, 48, 0, 0, 0, 0, 0]; ++ let sa = bytes.as_ptr() as *const libc::sockaddr; ++ let len = Some(bytes.len() as socklen_t); ++ let sock_addr = ++ unsafe { SockaddrStorage::from_raw(sa, len) }.unwrap(); ++ assert_eq!(sock_addr.family(), Some(AddressFamily::Link)); ++ match sock_addr.as_link_addr() { ++ Some(dl) => { ++ assert!(dl.addr().is_none()); ++ } ++ None => panic!("Can't unwrap sockaddr storage"), ++ } ++ } ++ ++ #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[test] ++ fn macos_tap() { ++ let bytes = [ ++ 20i8, 18, 7, 0, 6, 3, 6, 0, 101, 110, 48, 24, 101, -112, -35, ++ 76, -80, ++ ]; ++ let ptr = bytes.as_ptr(); ++ let sa = ptr as *const libc::sockaddr; ++ let len = Some(bytes.len() as socklen_t); ++ ++ let sock_addr = ++ unsafe { SockaddrStorage::from_raw(sa, len).unwrap() }; ++ assert_eq!(sock_addr.family(), Some(AddressFamily::Link)); ++ match sock_addr.as_link_addr() { ++ Some(dl) => { ++ assert_eq!(dl.addr(), Some([24u8, 101, 144, 221, 76, 176])) ++ } ++ None => panic!("Can't unwrap sockaddr storage"), ++ } ++ } ++ ++ #[cfg(target_os = "illumos")] ++ #[test] ++ fn illumos_tap() { ++ let bytes = [25u8, 0, 0, 0, 6, 0, 6, 0, 24, 101, 144, 221, 76, 176]; ++ let ptr = bytes.as_ptr(); ++ let sa = ptr as *const libc::sockaddr; ++ let len = Some(bytes.len() as socklen_t); ++ let _sock_addr = unsafe { SockaddrStorage::from_raw(sa, len) }; ++ ++ assert!(_sock_addr.is_some()); ++ ++ let sock_addr = _sock_addr.unwrap(); ++ ++ assert_eq!(sock_addr.family().unwrap(), AddressFamily::Link); ++ ++ assert_eq!( ++ sock_addr.as_link_addr().unwrap().addr(), ++ Some([24u8, 101, 144, 221, 76, 176]) ++ ); ++ } ++ ++ #[test] ++ fn size() { ++ #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "illumos", ++ target_os = "openbsd", ++ target_os = "haiku" ++ ))] ++ let l = mem::size_of::(); ++ #[cfg(any( ++ target_os = "android", ++ target_os = "fuchsia", ++ target_os = "linux" ++ ))] ++ let l = mem::size_of::(); ++ assert_eq!(LinkAddr::size() as usize, l); ++ } ++ } ++ ++ mod sockaddr_in { ++ use super::*; ++ use std::str::FromStr; ++ ++ #[test] ++ fn display() { ++ let s = "127.0.0.1:8080"; ++ let addr = SockaddrIn::from_str(s).unwrap(); ++ assert_eq!(s, format!("{}", addr)); ++ } ++ ++ #[test] ++ fn size() { ++ assert_eq!( ++ mem::size_of::(), ++ SockaddrIn::size() as usize ++ ); ++ } ++ } ++ ++ mod sockaddr_in6 { ++ use super::*; ++ use std::str::FromStr; ++ ++ #[test] ++ fn display() { ++ let s = "[1234:5678:90ab:cdef::1111:2222]:8080"; ++ let addr = SockaddrIn6::from_str(s).unwrap(); ++ assert_eq!(s, format!("{}", addr)); ++ } ++ ++ #[test] ++ fn size() { ++ assert_eq!( ++ mem::size_of::(), ++ SockaddrIn6::size() as usize ++ ); ++ } ++ ++ #[test] ++ // Ensure that we can convert to-and-from std::net variants without change. ++ fn to_and_from() { ++ let s = "[1234:5678:90ab:cdef::1111:2222]:8080"; ++ let mut nix_sin6 = SockaddrIn6::from_str(s).unwrap(); ++ nix_sin6.0.sin6_flowinfo = 0x12345678; ++ nix_sin6.0.sin6_scope_id = 0x9abcdef0; ++ ++ let std_sin6 : std::net::SocketAddrV6 = nix_sin6.into(); ++ assert_eq!(nix_sin6, std_sin6.into()); ++ } ++ } ++ ++ mod sockaddr_storage { ++ use super::*; ++ ++ #[test] ++ fn from_sockaddr_un_named() { ++ let ua = UnixAddr::new("/var/run/mysock").unwrap(); ++ let ptr = ua.as_ptr() as *const libc::sockaddr; ++ let ss = unsafe { ++ SockaddrStorage::from_raw(ptr, Some(ua.len())) ++ }.unwrap(); ++ assert_eq!(ss.len(), ua.len()); ++ } ++ ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[test] ++ fn from_sockaddr_un_abstract_named() { ++ let name = String::from("nix\0abstract\0test"); ++ let ua = UnixAddr::new_abstract(name.as_bytes()).unwrap(); ++ let ptr = ua.as_ptr() as *const libc::sockaddr; ++ let ss = unsafe { ++ SockaddrStorage::from_raw(ptr, Some(ua.len())) ++ }.unwrap(); ++ assert_eq!(ss.len(), ua.len()); ++ } ++ ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[test] ++ fn from_sockaddr_un_abstract_unnamed() { ++ let ua = UnixAddr::new_unnamed(); ++ let ptr = ua.as_ptr() as *const libc::sockaddr; ++ let ss = unsafe { ++ SockaddrStorage::from_raw(ptr, Some(ua.len())) ++ }.unwrap(); ++ assert_eq!(ss.len(), ua.len()); ++ } ++ } ++ ++ mod unixaddr { ++ use super::*; ++ ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[test] ++ fn abstract_sun_path() { ++ let name = String::from("nix\0abstract\0test"); ++ let addr = UnixAddr::new_abstract(name.as_bytes()).unwrap(); ++ ++ let sun_path1 = ++ unsafe { &(*addr.as_ptr()).sun_path[..addr.path_len()] }; ++ let sun_path2 = [ ++ 0, 110, 105, 120, 0, 97, 98, 115, 116, 114, 97, 99, 116, 0, ++ 116, 101, 115, 116, ++ ]; ++ assert_eq!(sun_path1, sun_path2); ++ } ++ ++ #[test] ++ fn size() { ++ assert_eq!( ++ mem::size_of::(), ++ UnixAddr::size() as usize ++ ); + } + } + } +diff --git a/vendor/nix/src/sys/socket/mod.rs b/vendor/nix/src/sys/socket/mod.rs +index aa28074..8513b6f 100644 +--- a/vendor/nix/src/sys/socket/mod.rs ++++ b/vendor/nix/src/sys/socket/mod.rs +@@ -1,16 +1,27 @@ + //! Socket interface functions + //! +-//! [Further reading](http://man7.org/linux/man-pages/man7/socket.7.html) +-use {Error, Result}; +-use errno::Errno; +-use libc::{self, c_void, c_int, iovec, socklen_t, size_t, +- CMSG_FIRSTHDR, CMSG_NXTHDR, CMSG_DATA, CMSG_LEN}; +-use std::{mem, ptr, slice}; ++//! [Further reading](https://man7.org/linux/man-pages/man7/socket.7.html) ++#[cfg(target_os = "linux")] ++#[cfg(feature = "uio")] ++use crate::sys::time::TimeSpec; ++#[cfg(feature = "uio")] ++use crate::sys::time::TimeVal; ++use crate::{errno::Errno, Result}; ++use cfg_if::cfg_if; ++use libc::{ ++ self, c_int, c_void, iovec, size_t, socklen_t, CMSG_DATA, CMSG_FIRSTHDR, ++ CMSG_LEN, CMSG_NXTHDR, ++}; ++use std::convert::{TryFrom, TryInto}; ++use std::io::{IoSlice, IoSliceMut}; ++#[cfg(feature = "net")] ++use std::net; + use std::os::unix::io::RawFd; +-use sys::time::TimeVal; +-use sys::uio::IoVec; ++use std::{mem, ptr, slice}; + ++#[deny(missing_docs)] + mod addr; ++#[deny(missing_docs)] + pub mod sockopt; + + /* +@@ -19,42 +30,63 @@ pub mod sockopt; + * + */ + ++pub use self::addr::{SockaddrLike, SockaddrStorage}; ++ ++#[cfg(not(any(target_os = "illumos", target_os = "solaris")))] ++#[allow(deprecated)] ++pub use self::addr::{AddressFamily, SockAddr, UnixAddr}; ++#[cfg(any(target_os = "illumos", target_os = "solaris"))] ++#[allow(deprecated)] ++pub use self::addr::{AddressFamily, SockAddr, UnixAddr}; ++#[allow(deprecated)] ++#[cfg(not(any( ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "haiku" ++)))] ++#[cfg(feature = "net")] ++pub use self::addr::{ ++ InetAddr, IpAddr, Ipv4Addr, Ipv6Addr, LinkAddr, SockaddrIn, SockaddrIn6, ++}; ++#[allow(deprecated)] ++#[cfg(any( ++ target_os = "illumos", ++ target_os = "solaris", ++ target_os = "haiku" ++))] ++#[cfg(feature = "net")] + pub use self::addr::{ +- AddressFamily, +- SockAddr, +- InetAddr, +- UnixAddr, +- IpAddr, +- Ipv4Addr, +- Ipv6Addr, +- LinkAddr, ++ InetAddr, IpAddr, Ipv4Addr, Ipv6Addr, SockaddrIn, SockaddrIn6, + }; ++ + #[cfg(any(target_os = "android", target_os = "linux"))] +-pub use ::sys::socket::addr::netlink::NetlinkAddr; ++pub use crate::sys::socket::addr::alg::AlgAddr; + #[cfg(any(target_os = "android", target_os = "linux"))] +-pub use sys::socket::addr::alg::AlgAddr; +-#[cfg(target_os = "linux")] +-pub use sys::socket::addr::vsock::VsockAddr; +- +-pub use libc::{ +- cmsghdr, +- msghdr, +- sa_family_t, +- sockaddr, +- sockaddr_in, +- sockaddr_in6, +- sockaddr_storage, +- sockaddr_un, +-}; ++pub use crate::sys::socket::addr::netlink::NetlinkAddr; ++#[cfg(any(target_os = "ios", target_os = "macos"))] ++#[cfg(feature = "ioctl")] ++pub use crate::sys::socket::addr::sys_control::SysControlAddr; ++#[cfg(any(target_os = "android", target_os = "linux"))] ++pub use crate::sys::socket::addr::vsock::VsockAddr; ++ ++#[cfg(feature = "uio")] ++pub use libc::{cmsghdr, msghdr}; ++pub use libc::{sa_family_t, sockaddr, sockaddr_storage, sockaddr_un}; ++#[cfg(feature = "net")] ++pub use libc::{sockaddr_in, sockaddr_in6}; + + // Needed by the cmsg_space macro + #[doc(hidden)] + pub use libc::{c_uint, CMSG_SPACE}; + ++#[cfg(feature = "net")] ++use crate::sys::socket::addr::{ipv4addr_to_libc, ipv6addr_to_libc}; ++ + /// These constants are used to specify the communication semantics + /// when creating a socket with [`socket()`](fn.socket.html) + #[derive(Clone, Copy, PartialEq, Eq, Debug)] + #[repr(i32)] ++#[non_exhaustive] + pub enum SockType { + /// Provides sequenced, reliable, two-way, connection- + /// based byte streams. An out-of-band data transmission +@@ -72,71 +104,205 @@ pub enum SockType { + Raw = libc::SOCK_RAW, + /// Provides a reliable datagram layer that does not + /// guarantee ordering. ++ #[cfg(not(any(target_os = "haiku")))] + Rdm = libc::SOCK_RDM, + } ++// The TryFrom impl could've been derived using libc_enum!. But for ++// backwards-compatibility with Nix-0.25.0 we manually implement it, so as to ++// keep the old variant names. ++impl TryFrom for SockType { ++ type Error = crate::Error; ++ ++ fn try_from(x: i32) -> Result { ++ match x { ++ libc::SOCK_STREAM => Ok(Self::Stream), ++ libc::SOCK_DGRAM => Ok(Self::Datagram), ++ libc::SOCK_SEQPACKET => Ok(Self::SeqPacket), ++ libc::SOCK_RAW => Ok(Self::Raw), ++ #[cfg(not(any(target_os = "haiku")))] ++ libc::SOCK_RDM => Ok(Self::Rdm), ++ _ => Err(Errno::EINVAL) ++ } ++ } ++} + + /// Constants used in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html) + /// to specify the protocol to use. + #[repr(i32)] + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] ++#[non_exhaustive] + pub enum SockProtocol { +- /// TCP protocol ([ip(7)](http://man7.org/linux/man-pages/man7/ip.7.html)) ++ /// TCP protocol ([ip(7)](https://man7.org/linux/man-pages/man7/ip.7.html)) + Tcp = libc::IPPROTO_TCP, +- /// UDP protocol ([ip(7)](http://man7.org/linux/man-pages/man7/ip.7.html)) ++ /// UDP protocol ([ip(7)](https://man7.org/linux/man-pages/man7/ip.7.html)) + Udp = libc::IPPROTO_UDP, ++ /// Raw sockets ([raw(7)](https://man7.org/linux/man-pages/man7/raw.7.html)) ++ Raw = libc::IPPROTO_RAW, + /// Allows applications and other KEXTs to be notified when certain kernel events occur + /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html)) + #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + KextEvent = libc::SYSPROTO_EVENT, + /// Allows applications to configure and control a KEXT + /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html)) + #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + KextControl = libc::SYSPROTO_CONTROL, ++ /// Receives routing and link updates and may be used to modify the routing tables (both IPv4 and IPv6), IP addresses, link ++ // parameters, neighbor setups, queueing disciplines, traffic classes and packet classifiers ++ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ NetlinkRoute = libc::NETLINK_ROUTE, ++ /// Reserved for user-mode socket protocols ++ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ NetlinkUserSock = libc::NETLINK_USERSOCK, ++ /// Query information about sockets of various protocol families from the kernel ++ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ NetlinkSockDiag = libc::NETLINK_SOCK_DIAG, ++ /// SELinux event notifications. ++ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ NetlinkSELinux = libc::NETLINK_SELINUX, ++ /// Open-iSCSI ++ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ NetlinkISCSI = libc::NETLINK_ISCSI, ++ /// Auditing ++ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ NetlinkAudit = libc::NETLINK_AUDIT, ++ /// Access to FIB lookup from user space ++ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ NetlinkFIBLookup = libc::NETLINK_FIB_LOOKUP, ++ /// Netfilter subsystem ++ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ NetlinkNetFilter = libc::NETLINK_NETFILTER, ++ /// SCSI Transports ++ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ NetlinkSCSITransport = libc::NETLINK_SCSITRANSPORT, ++ /// Infiniband RDMA ++ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ NetlinkRDMA = libc::NETLINK_RDMA, ++ /// Transport IPv6 packets from netfilter to user space. Used by ip6_queue kernel module. ++ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ NetlinkIPv6Firewall = libc::NETLINK_IP6_FW, ++ /// DECnet routing messages ++ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ NetlinkDECNetRoutingMessage = libc::NETLINK_DNRTMSG, ++ /// Kernel messages to user space ++ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ NetlinkKObjectUEvent = libc::NETLINK_KOBJECT_UEVENT, ++ /// Netlink interface to request information about ciphers registered with the kernel crypto API as well as allow ++ /// configuration of the kernel crypto API. ++ /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html)) ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ NetlinkCrypto = libc::NETLINK_CRYPTO, ++ /// Non-DIX type protocol number defined for the Ethernet IEEE 802.3 interface that allows packets of all protocols ++ /// defined in the interface to be received. ++ /// ([ref](https://man7.org/linux/man-pages/man7/packet.7.html)) ++ // The protocol number is fed into the socket syscall in network byte order. ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ EthAll = libc::ETH_P_ALL.to_be(), + } + +-libc_bitflags!{ ++#[cfg(any(target_os = "linux"))] ++libc_bitflags! { ++ /// Configuration flags for `SO_TIMESTAMPING` interface ++ /// ++ /// For use with [`Timestamping`][sockopt::Timestamping]. ++ /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html) ++ pub struct TimestampingFlag: c_uint { ++ /// Report any software timestamps when available. ++ SOF_TIMESTAMPING_SOFTWARE; ++ /// Report hardware timestamps as generated by SOF_TIMESTAMPING_TX_HARDWARE when available. ++ SOF_TIMESTAMPING_RAW_HARDWARE; ++ /// Collect transmiting timestamps as reported by hardware ++ SOF_TIMESTAMPING_TX_HARDWARE; ++ /// Collect transmiting timestamps as reported by software ++ SOF_TIMESTAMPING_TX_SOFTWARE; ++ /// Collect receiving timestamps as reported by hardware ++ SOF_TIMESTAMPING_RX_HARDWARE; ++ /// Collect receiving timestamps as reported by software ++ SOF_TIMESTAMPING_RX_SOFTWARE; ++ } ++} ++ ++libc_bitflags! { + /// Additional socket options + pub struct SockFlag: c_int { + /// Set non-blocking mode on the new socket + #[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", ++ target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + SOCK_NONBLOCK; + /// Set close-on-exec on the new descriptor + #[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", ++ target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + SOCK_CLOEXEC; + /// Return `EPIPE` instead of raising `SIGPIPE` + #[cfg(target_os = "netbsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + SOCK_NOSIGPIPE; + /// For domains `AF_INET(6)`, only allow `connect(2)`, `sendto(2)`, or `sendmsg(2)` + /// to the DNS port (typically 53) + #[cfg(target_os = "openbsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + SOCK_DNS; + } + } + +-libc_bitflags!{ ++libc_bitflags! { + /// Flags for send/recv and their relatives + pub struct MsgFlags: c_int { + /// Sends or requests out-of-band data on sockets that support this notion + /// (e.g., of type [`Stream`](enum.SockType.html)); the underlying protocol must also + /// support out-of-band data. ++ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963 + MSG_OOB; + /// Peeks at an incoming message. The data is treated as unread and the next + /// [`recv()`](fn.recv.html) + /// or similar function shall still return this data. ++ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963 + MSG_PEEK; + /// Receive operation blocks until the full amount of data can be + /// returned. The function may return smaller amount of data if a signal + /// is caught, an error or disconnect occurs. ++ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963 + MSG_WAITALL; + /// Enables nonblocking operation; if the operation would block, + /// `EAGAIN` or `EWOULDBLOCK` is returned. This provides similar +@@ -144,12 +310,14 @@ libc_bitflags!{ + /// (via the [`fcntl`](../../fcntl/fn.fcntl.html) + /// `F_SETFL` operation), but differs in that `MSG_DONTWAIT` is a per- + /// call option, whereas `O_NONBLOCK` is a setting on the open file +- /// description (see [open(2)](http://man7.org/linux/man-pages/man2/open.2.html)), ++ /// description (see [open(2)](https://man7.org/linux/man-pages/man2/open.2.html)), + /// which will affect all threads in + /// the calling process and as well as other processes that hold + /// file descriptors referring to the same open file description. ++ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963 + MSG_DONTWAIT; + /// Receive flags: Control Data was discarded (buffer too small) ++ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963 + MSG_CTRUNC; + /// For raw ([`Packet`](addr/enum.AddressFamily.html)), Internet datagram + /// (since Linux 2.4.27/2.6.8), +@@ -159,20 +327,24 @@ libc_bitflags!{ + /// domain ([unix(7)](https://linux.die.net/man/7/unix)) sockets. + /// + /// For use with Internet stream sockets, see [tcp(7)](https://linux.die.net/man/7/tcp). ++ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963 + MSG_TRUNC; + /// Terminates a record (when this notion is supported, as for + /// sockets of type [`SeqPacket`](enum.SockType.html)). ++ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963 + MSG_EOR; + /// This flag specifies that queued errors should be received from + /// the socket error queue. (For more details, see + /// [recvfrom(2)](https://linux.die.net/man/2/recvfrom)) + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963 + MSG_ERRQUEUE; + /// Set the `close-on-exec` flag for the file descriptor received via a UNIX domain + /// file descriptor using the `SCM_RIGHTS` operation (described in + /// [unix(7)](https://linux.die.net/man/7/unix)). + /// This flag is useful for the same reasons as the `O_CLOEXEC` flag of +- /// [open(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html). ++ /// [open(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html). + /// + /// Only used in [`recvmsg`](fn.recvmsg.html) function. + #[cfg(any(target_os = "android", +@@ -181,7 +353,24 @@ libc_bitflags!{ + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963 + MSG_CMSG_CLOEXEC; ++ /// Requests not to send `SIGPIPE` errors when the other end breaks the connection. ++ /// (For more details, see [send(2)](https://linux.die.net/man/2/send)). ++ #[cfg(any(target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "fuchsia", ++ target_os = "haiku", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "netbsd", ++ target_os = "openbsd", ++ target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ #[allow(deprecated)] // Suppress useless warnings from libc PR 2963 ++ MSG_NOSIGNAL; + } + } + +@@ -189,12 +378,25 @@ cfg_if! { + if #[cfg(any(target_os = "android", target_os = "linux"))] { + /// Unix credentials of the sending process. + /// +- /// This struct is used with the `SO_PEERCRED` ancillary message for UNIX sockets. ++ /// This struct is used with the `SO_PEERCRED` ancillary message ++ /// and the `SCM_CREDENTIALS` control message for UNIX sockets. + #[repr(transparent)] + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + pub struct UnixCredentials(libc::ucred); + + impl UnixCredentials { ++ /// Creates a new instance with the credentials of the current process ++ pub fn new() -> Self { ++ // Safe because these FFI functions are inherently safe ++ unsafe { ++ UnixCredentials(libc::ucred { ++ pid: libc::getpid(), ++ uid: libc::getuid(), ++ gid: libc::getgid() ++ }) ++ } ++ } ++ + /// Returns the process identifier + pub fn pid(&self) -> libc::pid_t { + self.0.pid +@@ -211,24 +413,109 @@ cfg_if! { + } + } + ++ impl Default for UnixCredentials { ++ fn default() -> Self { ++ Self::new() ++ } ++ } ++ + impl From for UnixCredentials { + fn from(cred: libc::ucred) -> Self { + UnixCredentials(cred) + } + } + +- impl Into for UnixCredentials { +- fn into(self) -> libc::ucred { +- self.0 ++ impl From for libc::ucred { ++ fn from(uc: UnixCredentials) -> Self { ++ uc.0 ++ } ++ } ++ } else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] { ++ /// Unix credentials of the sending process. ++ /// ++ /// This struct is used with the `SCM_CREDS` ancillary message for UNIX sockets. ++ #[repr(transparent)] ++ #[derive(Clone, Copy, Debug, Eq, PartialEq)] ++ pub struct UnixCredentials(libc::cmsgcred); ++ ++ impl UnixCredentials { ++ /// Returns the process identifier ++ pub fn pid(&self) -> libc::pid_t { ++ self.0.cmcred_pid ++ } ++ ++ /// Returns the real user identifier ++ pub fn uid(&self) -> libc::uid_t { ++ self.0.cmcred_uid ++ } ++ ++ /// Returns the effective user identifier ++ pub fn euid(&self) -> libc::uid_t { ++ self.0.cmcred_euid ++ } ++ ++ /// Returns the real group identifier ++ pub fn gid(&self) -> libc::gid_t { ++ self.0.cmcred_gid ++ } ++ ++ /// Returns a list group identifiers (the first one being the effective GID) ++ pub fn groups(&self) -> &[libc::gid_t] { ++ unsafe { ++ slice::from_raw_parts( ++ self.0.cmcred_groups.as_ptr() as *const libc::gid_t, ++ self.0.cmcred_ngroups as _ ++ ) ++ } ++ } ++ } ++ ++ impl From for UnixCredentials { ++ fn from(cred: libc::cmsgcred) -> Self { ++ UnixCredentials(cred) + } + } + } + } + ++cfg_if! { ++ if #[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "macos", ++ target_os = "ios" ++ ))] { ++ /// Return type of [`LocalPeerCred`](crate::sys::socket::sockopt::LocalPeerCred) ++ #[repr(transparent)] ++ #[derive(Clone, Copy, Debug, Eq, PartialEq)] ++ pub struct XuCred(libc::xucred); ++ ++ impl XuCred { ++ /// Structure layout version ++ pub fn version(&self) -> u32 { ++ self.0.cr_version ++ } ++ ++ /// Effective user ID ++ pub fn uid(&self) -> libc::uid_t { ++ self.0.cr_uid ++ } ++ ++ /// Returns a list of group identifiers (the first one being the ++ /// effective GID) ++ pub fn groups(&self) -> &[libc::gid_t] { ++ &self.0.cr_groups ++ } ++ } ++ } ++} ++ ++feature! { ++#![feature = "net"] + /// Request for multicast socket operations + /// + /// This is a wrapper type around `ip_mreq`. +-#[repr(C)] ++#[repr(transparent)] + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + pub struct IpMembershipRequest(libc::ip_mreq); + +@@ -236,10 +523,16 @@ impl IpMembershipRequest { + /// Instantiate a new `IpMembershipRequest` + /// + /// If `interface` is `None`, then `Ipv4Addr::any()` will be used for the interface. +- pub fn new(group: Ipv4Addr, interface: Option) -> Self { ++ pub fn new(group: net::Ipv4Addr, interface: Option) ++ -> Self ++ { ++ let imr_addr = match interface { ++ None => net::Ipv4Addr::UNSPECIFIED, ++ Some(addr) => addr ++ }; + IpMembershipRequest(libc::ip_mreq { +- imr_multiaddr: group.0, +- imr_interface: interface.unwrap_or_else(Ipv4Addr::any).0, ++ imr_multiaddr: ipv4addr_to_libc(group), ++ imr_interface: ipv4addr_to_libc(imr_addr) + }) + } + } +@@ -247,19 +540,23 @@ impl IpMembershipRequest { + /// Request for ipv6 multicast socket operations + /// + /// This is a wrapper type around `ipv6_mreq`. +-#[repr(C)] ++#[repr(transparent)] + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + pub struct Ipv6MembershipRequest(libc::ipv6_mreq); + + impl Ipv6MembershipRequest { + /// Instantiate a new `Ipv6MembershipRequest` +- pub fn new(group: Ipv6Addr) -> Self { ++ pub const fn new(group: net::Ipv6Addr) -> Self { + Ipv6MembershipRequest(libc::ipv6_mreq { +- ipv6mr_multiaddr: group.0, ++ ipv6mr_multiaddr: ipv6addr_to_libc(&group), + ipv6mr_interface: 0, + }) + } + } ++} ++ ++feature! { ++#![feature = "uio"] + + /// Create a buffer large enough for storing some control messages as returned + /// by [`recvmsg`](fn.recvmsg.html). +@@ -287,13 +584,11 @@ impl Ipv6MembershipRequest { + macro_rules! cmsg_space { + ( $( $x:ty ),* ) => { + { +- use nix::sys::socket::{c_uint, CMSG_SPACE}; +- use std::mem; + let mut space = 0; + $( + // CMSG_SPACE is always safe + space += unsafe { +- CMSG_SPACE(mem::size_of::<$x>() as c_uint) ++ $crate::sys::socket::CMSG_SPACE(::std::mem::size_of::<$x>() as $crate::sys::socket::c_uint) + } as usize; + )* + Vec::::with_capacity(space) +@@ -302,15 +597,20 @@ macro_rules! cmsg_space { + } + + #[derive(Clone, Copy, Debug, Eq, PartialEq)] +-pub struct RecvMsg<'a> { ++/// Contains outcome of sending or receiving a message ++/// ++/// Use [`cmsgs`][RecvMsg::cmsgs] to access all the control messages present, and ++/// [`iovs`][RecvMsg::iovs`] to access underlying io slices. ++pub struct RecvMsg<'a, 's, S> { + pub bytes: usize, + cmsghdr: Option<&'a cmsghdr>, +- pub address: Option, ++ pub address: Option, + pub flags: MsgFlags, ++ iobufs: std::marker::PhantomData<& 's()>, + mhdr: msghdr, + } + +-impl<'a> RecvMsg<'a> { ++impl<'a, S> RecvMsg<'a, '_, S> { + /// Iterate over the valid control messages pointed to by this + /// msghdr. + pub fn cmsgs(&self) -> CmsgIterator { +@@ -353,7 +653,7 @@ impl<'a> Iterator for CmsgIterator<'a> { + /// A type-safe wrapper around a single control message, as used with + /// [`recvmsg`](#fn.recvmsg). + /// +-/// [Further reading](http://man7.org/linux/man-pages/man3/cmsg.3.html) ++/// [Further reading](https://man7.org/linux/man-pages/man3/cmsg.3.html) + // Nix version 0.13.0 and earlier used ControlMessage for both recvmsg and + // sendmsg. However, on some platforms the messages returned by recvmsg may be + // unaligned. ControlMessageOwned takes those messages by copy, obviating any +@@ -361,14 +661,18 @@ impl<'a> Iterator for CmsgIterator<'a> { + // + // See https://github.com/nix-rust/nix/issues/999 + #[derive(Clone, Debug, Eq, PartialEq)] ++#[non_exhaustive] + pub enum ControlMessageOwned { +- /// Received version of +- /// [`ControlMessage::ScmRights`][#enum.ControlMessage.html#variant.ScmRights] ++ /// Received version of [`ControlMessage::ScmRights`] + ScmRights(Vec), +- /// Received version of +- /// [`ControlMessage::ScmCredentials`][#enum.ControlMessage.html#variant.ScmCredentials] ++ /// Received version of [`ControlMessage::ScmCredentials`] + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ScmCredentials(UnixCredentials), ++ /// Received version of [`ControlMessage::ScmCreds`] ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ ScmCreds(UnixCredentials), + /// A message of type `SCM_TIMESTAMP`, containing the time the + /// packet was received by the kernel. + /// +@@ -377,15 +681,13 @@ pub enum ControlMessageOwned { + /// + /// # Examples + /// +- // Disable this test on FreeBSD i386 +- // https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=222039 +- #[cfg_attr(not(all(target_os = "freebsd", target_arch = "x86")), doc = " ```")] +- #[cfg_attr(all(target_os = "freebsd", target_arch = "x86"), doc = " ```no_run")] ++ /// ``` + /// # #[macro_use] extern crate nix; + /// # use nix::sys::socket::*; +- /// # use nix::sys::uio::IoVec; + /// # use nix::sys::time::*; ++ /// # use std::io::{IoSlice, IoSliceMut}; + /// # use std::time::*; ++ /// # use std::str::FromStr; + /// # fn main() { + /// // Set up + /// let message = "Ohayō!".as_bytes(); +@@ -395,21 +697,22 @@ pub enum ControlMessageOwned { + /// SockFlag::empty(), + /// None).unwrap(); + /// setsockopt(in_socket, sockopt::ReceiveTimestamp, &true).unwrap(); +- /// let localhost = InetAddr::new(IpAddr::new_v4(127, 0, 0, 1), 0); +- /// bind(in_socket, &SockAddr::new_inet(localhost)).unwrap(); +- /// let address = getsockname(in_socket).unwrap(); ++ /// let localhost = SockaddrIn::from_str("127.0.0.1:0").unwrap(); ++ /// bind(in_socket, &localhost).unwrap(); ++ /// let address: SockaddrIn = getsockname(in_socket).unwrap(); + /// // Get initial time + /// let time0 = SystemTime::now(); + /// // Send the message +- /// let iov = [IoVec::from_slice(message)]; ++ /// let iov = [IoSlice::new(message)]; + /// let flags = MsgFlags::empty(); + /// let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap(); + /// assert_eq!(message.len(), l); + /// // Receive the message + /// let mut buffer = vec![0u8; message.len()]; + /// let mut cmsgspace = cmsg_space!(TimeVal); +- /// let iov = [IoVec::from_mut_slice(&mut buffer)]; +- /// let r = recvmsg(in_socket, &iov, Some(&mut cmsgspace), flags).unwrap(); ++ /// let mut iov = [IoSliceMut::new(&mut buffer)]; ++ /// let r = recvmsg::(in_socket, &mut iov, Some(&mut cmsgspace), flags) ++ /// .unwrap(); + /// let rtime = match r.cmsgs().next() { + /// Some(ControlMessageOwned::ScmTimestamp(rtime)) => rtime, + /// Some(_) => panic!("Unexpected control message"), +@@ -428,6 +731,17 @@ pub enum ControlMessageOwned { + /// # } + /// ``` + ScmTimestamp(TimeVal), ++ /// A set of nanosecond resolution timestamps ++ /// ++ /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html) ++ #[cfg(all(target_os = "linux"))] ++ ScmTimestampsns(Timestamps), ++ /// Nanoseconds resolution timestamp ++ /// ++ /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html) ++ #[cfg(all(target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ ScmTimestampns(TimeSpec), + #[cfg(any( + target_os = "android", + target_os = "ios", +@@ -435,6 +749,8 @@ pub enum ControlMessageOwned { + target_os = "macos", + target_os = "netbsd", + ))] ++ #[cfg(feature = "net")] ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv4PacketInfo(libc::in_pktinfo), + #[cfg(any( + target_os = "android", +@@ -446,6 +762,8 @@ pub enum ControlMessageOwned { + target_os = "openbsd", + target_os = "netbsd", + ))] ++ #[cfg(feature = "net")] ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv6PacketInfo(libc::in6_pktinfo), + #[cfg(any( + target_os = "freebsd", +@@ -454,6 +772,8 @@ pub enum ControlMessageOwned { + target_os = "netbsd", + target_os = "openbsd", + ))] ++ #[cfg(feature = "net")] ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv4RecvIf(libc::sockaddr_dl), + #[cfg(any( + target_os = "freebsd", +@@ -462,12 +782,71 @@ pub enum ControlMessageOwned { + target_os = "netbsd", + target_os = "openbsd", + ))] ++ #[cfg(feature = "net")] ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + Ipv4RecvDstAddr(libc::in_addr), ++ #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] ++ #[cfg(feature = "net")] ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ Ipv4OrigDstAddr(libc::sockaddr_in), ++ #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] ++ #[cfg(feature = "net")] ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ Ipv6OrigDstAddr(libc::sockaddr_in6), ++ ++ /// UDP Generic Receive Offload (GRO) allows receiving multiple UDP ++ /// packets from a single sender. ++ /// Fixed-size payloads are following one by one in a receive buffer. ++ /// This Control Message indicates the size of all smaller packets, ++ /// except, maybe, the last one. ++ /// ++ /// `UdpGroSegment` socket option should be enabled on a socket ++ /// to allow receiving GRO packets. ++ #[cfg(target_os = "linux")] ++ #[cfg(feature = "net")] ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ UdpGroSegments(u16), ++ ++ /// SO_RXQ_OVFL indicates that an unsigned 32 bit value ++ /// ancilliary msg (cmsg) should be attached to recieved ++ /// skbs indicating the number of packets dropped by the ++ /// socket between the last recieved packet and this ++ /// received packet. ++ /// ++ /// `RxqOvfl` socket option should be enabled on a socket ++ /// to allow receiving the drop counter. ++ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ RxqOvfl(u32), ++ ++ /// Socket error queue control messages read with the `MSG_ERRQUEUE` flag. ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg(feature = "net")] ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ Ipv4RecvErr(libc::sock_extended_err, Option), ++ /// Socket error queue control messages read with the `MSG_ERRQUEUE` flag. ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg(feature = "net")] ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ Ipv6RecvErr(libc::sock_extended_err, Option), ++ + /// Catch-all variant for unimplemented cmsg types. + #[doc(hidden)] + Unknown(UnknownCmsg), + } + ++/// For representing packet timestamps via `SO_TIMESTAMPING` interface ++#[cfg(all(target_os = "linux"))] ++#[derive(Copy, Clone, Debug, Eq, PartialEq)] ++pub struct Timestamps { ++ /// software based timestamp, usually one containing data ++ pub system: TimeSpec, ++ /// legacy timestamp, usually empty ++ pub hw_trans: TimeSpec, ++ /// hardware based timestamp ++ pub hw_raw: TimeSpec, ++} ++ + impl ControlMessageOwned { + /// Decodes a `ControlMessageOwned` from raw bytes. + /// +@@ -481,6 +860,8 @@ impl ControlMessageOwned { + unsafe fn decode_from(header: &cmsghdr) -> ControlMessageOwned + { + let p = CMSG_DATA(header); ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] + let len = header as *const _ as usize + header.cmsg_len as usize + - p as usize; + match (header.cmsg_level, header.cmsg_type) { +@@ -498,10 +879,33 @@ impl ControlMessageOwned { + let cred: libc::ucred = ptr::read_unaligned(p as *const _); + ControlMessageOwned::ScmCredentials(cred.into()) + } ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ (libc::SOL_SOCKET, libc::SCM_CREDS) => { ++ let cred: libc::cmsgcred = ptr::read_unaligned(p as *const _); ++ ControlMessageOwned::ScmCreds(cred.into()) ++ } ++ #[cfg(not(target_os = "haiku"))] + (libc::SOL_SOCKET, libc::SCM_TIMESTAMP) => { + let tv: libc::timeval = ptr::read_unaligned(p as *const _); + ControlMessageOwned::ScmTimestamp(TimeVal::from(tv)) + }, ++ #[cfg(all(target_os = "linux"))] ++ (libc::SOL_SOCKET, libc::SCM_TIMESTAMPNS) => { ++ let ts: libc::timespec = ptr::read_unaligned(p as *const _); ++ ControlMessageOwned::ScmTimestampns(TimeSpec::from(ts)) ++ } ++ #[cfg(all(target_os = "linux"))] ++ (libc::SOL_SOCKET, libc::SCM_TIMESTAMPING) => { ++ let tp = p as *const libc::timespec; ++ let ts: libc::timespec = ptr::read_unaligned(tp); ++ let system = TimeSpec::from(ts); ++ let ts: libc::timespec = ptr::read_unaligned(tp.add(1)); ++ let hw_trans = TimeSpec::from(ts); ++ let ts: libc::timespec = ptr::read_unaligned(tp.add(2)); ++ let hw_raw = TimeSpec::from(ts); ++ let timestamping = Timestamps { system, hw_trans, hw_raw }; ++ ControlMessageOwned::ScmTimestampsns(timestamping) ++ } + #[cfg(any( + target_os = "android", + target_os = "freebsd", +@@ -509,6 +913,7 @@ impl ControlMessageOwned { + target_os = "linux", + target_os = "macos" + ))] ++ #[cfg(feature = "net")] + (libc::IPPROTO_IPV6, libc::IPV6_PKTINFO) => { + let info = ptr::read_unaligned(p as *const libc::in6_pktinfo); + ControlMessageOwned::Ipv6PacketInfo(info) +@@ -520,6 +925,7 @@ impl ControlMessageOwned { + target_os = "macos", + target_os = "netbsd", + ))] ++ #[cfg(feature = "net")] + (libc::IPPROTO_IP, libc::IP_PKTINFO) => { + let info = ptr::read_unaligned(p as *const libc::in_pktinfo); + ControlMessageOwned::Ipv4PacketInfo(info) +@@ -531,6 +937,7 @@ impl ControlMessageOwned { + target_os = "netbsd", + target_os = "openbsd", + ))] ++ #[cfg(feature = "net")] + (libc::IPPROTO_IP, libc::IP_RECVIF) => { + let dl = ptr::read_unaligned(p as *const libc::sockaddr_dl); + ControlMessageOwned::Ipv4RecvIf(dl) +@@ -542,31 +949,88 @@ impl ControlMessageOwned { + target_os = "netbsd", + target_os = "openbsd", + ))] ++ #[cfg(feature = "net")] + (libc::IPPROTO_IP, libc::IP_RECVDSTADDR) => { + let dl = ptr::read_unaligned(p as *const libc::in_addr); + ControlMessageOwned::Ipv4RecvDstAddr(dl) + }, ++ #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] ++ #[cfg(feature = "net")] ++ (libc::IPPROTO_IP, libc::IP_ORIGDSTADDR) => { ++ let dl = ptr::read_unaligned(p as *const libc::sockaddr_in); ++ ControlMessageOwned::Ipv4OrigDstAddr(dl) ++ }, ++ #[cfg(target_os = "linux")] ++ #[cfg(feature = "net")] ++ (libc::SOL_UDP, libc::UDP_GRO) => { ++ let gso_size: u16 = ptr::read_unaligned(p as *const _); ++ ControlMessageOwned::UdpGroSegments(gso_size) ++ }, ++ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++ (libc::SOL_SOCKET, libc::SO_RXQ_OVFL) => { ++ let drop_counter = ptr::read_unaligned(p as *const u32); ++ ControlMessageOwned::RxqOvfl(drop_counter) ++ }, ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg(feature = "net")] ++ (libc::IPPROTO_IP, libc::IP_RECVERR) => { ++ let (err, addr) = Self::recv_err_helper::(p, len); ++ ControlMessageOwned::Ipv4RecvErr(err, addr) ++ }, ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg(feature = "net")] ++ (libc::IPPROTO_IPV6, libc::IPV6_RECVERR) => { ++ let (err, addr) = Self::recv_err_helper::(p, len); ++ ControlMessageOwned::Ipv6RecvErr(err, addr) ++ }, ++ #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] ++ #[cfg(feature = "net")] ++ (libc::IPPROTO_IPV6, libc::IPV6_ORIGDSTADDR) => { ++ let dl = ptr::read_unaligned(p as *const libc::sockaddr_in6); ++ ControlMessageOwned::Ipv6OrigDstAddr(dl) ++ }, + (_, _) => { + let sl = slice::from_raw_parts(p, len); +- let ucmsg = UnknownCmsg(*header, Vec::::from(&sl[..])); ++ let ucmsg = UnknownCmsg(*header, Vec::::from(sl)); + ControlMessageOwned::Unknown(ucmsg) + } + } + } ++ ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg(feature = "net")] ++ #[allow(clippy::cast_ptr_alignment)] // False positive ++ unsafe fn recv_err_helper(p: *mut libc::c_uchar, len: usize) -> (libc::sock_extended_err, Option) { ++ let ee = p as *const libc::sock_extended_err; ++ let err = ptr::read_unaligned(ee); ++ ++ // For errors originating on the network, SO_EE_OFFENDER(ee) points inside the p[..len] ++ // CMSG_DATA buffer. For local errors, there is no address included in the control ++ // message, and SO_EE_OFFENDER(ee) points beyond the end of the buffer. So, we need to ++ // validate that the address object is in-bounds before we attempt to copy it. ++ let addrp = libc::SO_EE_OFFENDER(ee) as *const T; ++ ++ if addrp.offset(1) as usize - (p as usize) > len { ++ (err, None) ++ } else { ++ (err, Some(ptr::read_unaligned(addrp))) ++ } ++ } + } + + /// A type-safe zero-copy wrapper around a single control message, as used wih + /// [`sendmsg`](#fn.sendmsg). More types may be added to this enum; do not + /// exhaustively pattern-match it. + /// +-/// [Further reading](http://man7.org/linux/man-pages/man3/cmsg.3.html) ++/// [Further reading](https://man7.org/linux/man-pages/man3/cmsg.3.html) + #[derive(Clone, Copy, Debug, Eq, PartialEq)] ++#[non_exhaustive] + pub enum ControlMessage<'a> { + /// A message of type `SCM_RIGHTS`, containing an array of file + /// descriptors passed between processes. + /// + /// See the description in the "Ancillary messages" section of the +- /// [unix(7) man page](http://man7.org/linux/man-pages/man7/unix.7.html). ++ /// [unix(7) man page](https://man7.org/linux/man-pages/man7/unix.7.html). + /// + /// Using multiple `ScmRights` messages for a single `sendmsg` call isn't + /// recommended since it causes platform-dependent behaviour: It might +@@ -583,9 +1047,25 @@ pub enum ControlMessage<'a> { + /// processes are verified by the kernel. + /// + /// For further information, please refer to the +- /// [`unix(7)`](http://man7.org/linux/man-pages/man7/unix.7.html) man page. ++ /// [`unix(7)`](https://man7.org/linux/man-pages/man7/unix.7.html) man page. + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ScmCredentials(&'a UnixCredentials), ++ /// A message of type `SCM_CREDS`, containing the pid, uid, euid, gid and groups of ++ /// a process connected to the socket. ++ /// ++ /// This is similar to the socket options `LOCAL_CREDS` and `LOCAL_PEERCRED`, but ++ /// requires a process to explicitly send its credentials. ++ /// ++ /// Credentials are always overwritten by the kernel, so this variant does have ++ /// any data, unlike the receive-side ++ /// [`ControlMessageOwned::ScmCreds`]. ++ /// ++ /// For further information, please refer to the ++ /// [`unix(4)`](https://www.freebsd.org/cgi/man.cgi?query=unix) man page. ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ ScmCreds, + + /// Set IV for `AF_ALG` crypto API. + /// +@@ -595,6 +1075,7 @@ pub enum ControlMessage<'a> { + target_os = "android", + target_os = "linux", + ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + AlgSetIv(&'a [u8]), + /// Set crypto operation for `AF_ALG` crypto API. It may be one of + /// `ALG_OP_ENCRYPT` or `ALG_OP_DECRYPT` +@@ -605,6 +1086,7 @@ pub enum ControlMessage<'a> { + target_os = "android", + target_os = "linux", + ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + AlgSetOp(&'a libc::c_int), + /// Set the length of associated authentication data (AAD) (applicable only to AEAD algorithms) + /// for `AF_ALG` crypto API. +@@ -615,8 +1097,76 @@ pub enum ControlMessage<'a> { + target_os = "android", + target_os = "linux", + ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + AlgSetAeadAssoclen(&'a u32), + ++ /// UDP GSO makes it possible for applications to generate network packets ++ /// for a virtual MTU much greater than the real one. ++ /// The length of the send data no longer matches the expected length on ++ /// the wire. ++ /// The size of the datagram payload as it should appear on the wire may be ++ /// passed through this control message. ++ /// Send buffer should consist of multiple fixed-size wire payloads ++ /// following one by one, and the last, possibly smaller one. ++ #[cfg(target_os = "linux")] ++ #[cfg(feature = "net")] ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ UdpGsoSegments(&'a u16), ++ ++ /// Configure the sending addressing and interface for v4 ++ /// ++ /// For further information, please refer to the ++ /// [`ip(7)`](https://man7.org/linux/man-pages/man7/ip.7.html) man page. ++ #[cfg(any(target_os = "linux", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "android", ++ target_os = "ios",))] ++ #[cfg(feature = "net")] ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ Ipv4PacketInfo(&'a libc::in_pktinfo), ++ ++ /// Configure the sending addressing and interface for v6 ++ /// ++ /// For further information, please refer to the ++ /// [`ipv6(7)`](https://man7.org/linux/man-pages/man7/ipv6.7.html) man page. ++ #[cfg(any(target_os = "linux", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "freebsd", ++ target_os = "android", ++ target_os = "ios",))] ++ #[cfg(feature = "net")] ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ Ipv6PacketInfo(&'a libc::in6_pktinfo), ++ ++ /// Configure the IPv4 source address with `IP_SENDSRCADDR`. ++ #[cfg(any( ++ target_os = "netbsd", ++ target_os = "freebsd", ++ target_os = "openbsd", ++ target_os = "dragonfly", ++ ))] ++ #[cfg(feature = "net")] ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ Ipv4SendSrcAddr(&'a libc::in_addr), ++ ++ /// SO_RXQ_OVFL indicates that an unsigned 32 bit value ++ /// ancilliary msg (cmsg) should be attached to recieved ++ /// skbs indicating the number of packets dropped by the ++ /// socket between the last recieved packet and this ++ /// received packet. ++ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ RxqOvfl(&'a u32), ++ ++ /// Configure the transmission time of packets. ++ /// ++ /// For further information, please refer to the ++ /// [`tc-etf(8)`](https://man7.org/linux/man-pages/man8/tc-etf.8.html) man ++ /// page. ++ #[cfg(target_os = "linux")] ++ TxTime(&'a u64), + } + + // An opaque structure used to prevent cmsghdr from being a public type +@@ -655,17 +1205,36 @@ impl<'a> ControlMessage<'a> { + ControlMessage::ScmCredentials(creds) => { + &creds.0 as *const libc::ucred as *const u8 + } ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ ControlMessage::ScmCreds => { ++ // The kernel overwrites the data, we just zero it ++ // to make sure it's not uninitialized memory ++ unsafe { ptr::write_bytes(cmsg_data, 0, self.len()) }; ++ return ++ } + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::AlgSetIv(iv) => { ++ #[allow(deprecated)] // https://github.com/rust-lang/libc/issues/1501 ++ let af_alg_iv = libc::af_alg_iv { ++ ivlen: iv.len() as u32, ++ iv: [0u8; 0], ++ }; ++ ++ let size = mem::size_of_val(&af_alg_iv); ++ + unsafe { +- let alg_iv = cmsg_data as *mut libc::af_alg_iv; +- (*alg_iv).ivlen = iv.len() as u32; ++ ptr::copy_nonoverlapping( ++ &af_alg_iv as *const _ as *const u8, ++ cmsg_data, ++ size, ++ ); + ptr::copy_nonoverlapping( + iv.as_ptr(), +- (*alg_iv).iv.as_mut_ptr(), ++ cmsg_data.add(size), + iv.len() + ); + }; ++ + return + }, + #[cfg(any(target_os = "android", target_os = "linux"))] +@@ -676,6 +1245,33 @@ impl<'a> ControlMessage<'a> { + ControlMessage::AlgSetAeadAssoclen(len) => { + len as *const _ as *const u8 + }, ++ #[cfg(target_os = "linux")] ++ #[cfg(feature = "net")] ++ ControlMessage::UdpGsoSegments(gso_size) => { ++ gso_size as *const _ as *const u8 ++ }, ++ #[cfg(any(target_os = "linux", target_os = "macos", ++ target_os = "netbsd", target_os = "android", ++ target_os = "ios",))] ++ #[cfg(feature = "net")] ++ ControlMessage::Ipv4PacketInfo(info) => info as *const _ as *const u8, ++ #[cfg(any(target_os = "linux", target_os = "macos", ++ target_os = "netbsd", target_os = "freebsd", ++ target_os = "android", target_os = "ios",))] ++ #[cfg(feature = "net")] ++ ControlMessage::Ipv6PacketInfo(info) => info as *const _ as *const u8, ++ #[cfg(any(target_os = "netbsd", target_os = "freebsd", ++ target_os = "openbsd", target_os = "dragonfly"))] ++ #[cfg(feature = "net")] ++ ControlMessage::Ipv4SendSrcAddr(addr) => addr as *const _ as *const u8, ++ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++ ControlMessage::RxqOvfl(drop_count) => { ++ drop_count as *const _ as *const u8 ++ }, ++ #[cfg(target_os = "linux")] ++ ControlMessage::TxTime(tx_time) => { ++ tx_time as *const _ as *const u8 ++ }, + }; + unsafe { + ptr::copy_nonoverlapping( +@@ -696,9 +1292,13 @@ impl<'a> ControlMessage<'a> { + ControlMessage::ScmCredentials(creds) => { + mem::size_of_val(creds) + } ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ ControlMessage::ScmCreds => { ++ mem::size_of::() ++ } + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::AlgSetIv(iv) => { +- mem::size_of::() + iv.len() ++ mem::size_of::<&[u8]>() + iv.len() + }, + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::AlgSetOp(op) => { +@@ -708,6 +1308,33 @@ impl<'a> ControlMessage<'a> { + ControlMessage::AlgSetAeadAssoclen(len) => { + mem::size_of_val(len) + }, ++ #[cfg(target_os = "linux")] ++ #[cfg(feature = "net")] ++ ControlMessage::UdpGsoSegments(gso_size) => { ++ mem::size_of_val(gso_size) ++ }, ++ #[cfg(any(target_os = "linux", target_os = "macos", ++ target_os = "netbsd", target_os = "android", ++ target_os = "ios",))] ++ #[cfg(feature = "net")] ++ ControlMessage::Ipv4PacketInfo(info) => mem::size_of_val(info), ++ #[cfg(any(target_os = "linux", target_os = "macos", ++ target_os = "netbsd", target_os = "freebsd", ++ target_os = "android", target_os = "ios",))] ++ #[cfg(feature = "net")] ++ ControlMessage::Ipv6PacketInfo(info) => mem::size_of_val(info), ++ #[cfg(any(target_os = "netbsd", target_os = "freebsd", ++ target_os = "openbsd", target_os = "dragonfly"))] ++ #[cfg(feature = "net")] ++ ControlMessage::Ipv4SendSrcAddr(addr) => mem::size_of_val(addr), ++ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++ ControlMessage::RxqOvfl(drop_count) => { ++ mem::size_of_val(drop_count) ++ }, ++ #[cfg(target_os = "linux")] ++ ControlMessage::TxTime(tx_time) => { ++ mem::size_of_val(tx_time) ++ }, + } + } + +@@ -717,9 +1344,32 @@ impl<'a> ControlMessage<'a> { + ControlMessage::ScmRights(_) => libc::SOL_SOCKET, + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::ScmCredentials(_) => libc::SOL_SOCKET, ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ ControlMessage::ScmCreds => libc::SOL_SOCKET, + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::AlgSetIv(_) | ControlMessage::AlgSetOp(_) | +- ControlMessage::AlgSetAeadAssoclen(_) => libc::SOL_ALG , ++ ControlMessage::AlgSetAeadAssoclen(_) => libc::SOL_ALG, ++ #[cfg(target_os = "linux")] ++ #[cfg(feature = "net")] ++ ControlMessage::UdpGsoSegments(_) => libc::SOL_UDP, ++ #[cfg(any(target_os = "linux", target_os = "macos", ++ target_os = "netbsd", target_os = "android", ++ target_os = "ios",))] ++ #[cfg(feature = "net")] ++ ControlMessage::Ipv4PacketInfo(_) => libc::IPPROTO_IP, ++ #[cfg(any(target_os = "linux", target_os = "macos", ++ target_os = "netbsd", target_os = "freebsd", ++ target_os = "android", target_os = "ios",))] ++ #[cfg(feature = "net")] ++ ControlMessage::Ipv6PacketInfo(_) => libc::IPPROTO_IPV6, ++ #[cfg(any(target_os = "netbsd", target_os = "freebsd", ++ target_os = "openbsd", target_os = "dragonfly"))] ++ #[cfg(feature = "net")] ++ ControlMessage::Ipv4SendSrcAddr(_) => libc::IPPROTO_IP, ++ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++ ControlMessage::RxqOvfl(_) => libc::SOL_SOCKET, ++ #[cfg(target_os = "linux")] ++ ControlMessage::TxTime(_) => libc::SOL_SOCKET, + } + } + +@@ -729,6 +1379,8 @@ impl<'a> ControlMessage<'a> { + ControlMessage::ScmRights(_) => libc::SCM_RIGHTS, + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::ScmCredentials(_) => libc::SCM_CREDENTIALS, ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ ControlMessage::ScmCreds => libc::SCM_CREDS, + #[cfg(any(target_os = "android", target_os = "linux"))] + ControlMessage::AlgSetIv(_) => { + libc::ALG_SET_IV +@@ -741,6 +1393,33 @@ impl<'a> ControlMessage<'a> { + ControlMessage::AlgSetAeadAssoclen(_) => { + libc::ALG_SET_AEAD_ASSOCLEN + }, ++ #[cfg(target_os = "linux")] ++ #[cfg(feature = "net")] ++ ControlMessage::UdpGsoSegments(_) => { ++ libc::UDP_SEGMENT ++ }, ++ #[cfg(any(target_os = "linux", target_os = "macos", ++ target_os = "netbsd", target_os = "android", ++ target_os = "ios",))] ++ #[cfg(feature = "net")] ++ ControlMessage::Ipv4PacketInfo(_) => libc::IP_PKTINFO, ++ #[cfg(any(target_os = "linux", target_os = "macos", ++ target_os = "netbsd", target_os = "freebsd", ++ target_os = "android", target_os = "ios",))] ++ #[cfg(feature = "net")] ++ ControlMessage::Ipv6PacketInfo(_) => libc::IPV6_PKTINFO, ++ #[cfg(any(target_os = "netbsd", target_os = "freebsd", ++ target_os = "openbsd", target_os = "dragonfly"))] ++ #[cfg(feature = "net")] ++ ControlMessage::Ipv4SendSrcAddr(_) => libc::IP_SENDSRCADDR, ++ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++ ControlMessage::RxqOvfl(_) => { ++ libc::SO_RXQ_OVFL ++ }, ++ #[cfg(target_os = "linux")] ++ ControlMessage::TxTime(_) => { ++ libc::SCM_TXTIME ++ }, + } + } + +@@ -760,24 +1439,557 @@ impl<'a> ControlMessage<'a> { + /// as with sendto. + /// + /// Allocates if cmsgs is nonempty. +-pub fn sendmsg(fd: RawFd, iov: &[IoVec<&[u8]>], cmsgs: &[ControlMessage], +- flags: MsgFlags, addr: Option<&SockAddr>) -> Result ++/// ++/// # Examples ++/// When not directing to any specific address, use `()` for the generic type ++/// ``` ++/// # use nix::sys::socket::*; ++/// # use nix::unistd::pipe; ++/// # use std::io::IoSlice; ++/// let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, ++/// SockFlag::empty()) ++/// .unwrap(); ++/// let (r, w) = pipe().unwrap(); ++/// ++/// let iov = [IoSlice::new(b"hello")]; ++/// let fds = [r]; ++/// let cmsg = ControlMessage::ScmRights(&fds); ++/// sendmsg::<()>(fd1, &iov, &[cmsg], MsgFlags::empty(), None).unwrap(); ++/// ``` ++/// When directing to a specific address, the generic type will be inferred. ++/// ``` ++/// # use nix::sys::socket::*; ++/// # use nix::unistd::pipe; ++/// # use std::io::IoSlice; ++/// # use std::str::FromStr; ++/// let localhost = SockaddrIn::from_str("1.2.3.4:8080").unwrap(); ++/// let fd = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), ++/// None).unwrap(); ++/// let (r, w) = pipe().unwrap(); ++/// ++/// let iov = [IoSlice::new(b"hello")]; ++/// let fds = [r]; ++/// let cmsg = ControlMessage::ScmRights(&fds); ++/// sendmsg(fd, &iov, &[cmsg], MsgFlags::empty(), Some(&localhost)).unwrap(); ++/// ``` ++pub fn sendmsg(fd: RawFd, iov: &[IoSlice<'_>], cmsgs: &[ControlMessage], ++ flags: MsgFlags, addr: Option<&S>) -> Result ++ where S: SockaddrLike + { + let capacity = cmsgs.iter().map(|c| c.space()).sum(); + + // First size the buffer needed to hold the cmsgs. It must be zeroed, + // because subsequent code will not clear the padding bytes. +- let cmsg_buffer = vec![0u8; capacity]; ++ let mut cmsg_buffer = vec![0u8; capacity]; + +- // Next encode the sending address, if provided +- let (name, namelen) = match addr { +- Some(addr) => { +- let (x, y) = unsafe { addr.as_ffi_pair() }; +- (x as *const _, y) +- }, +- None => (ptr::null(), 0), ++ let mhdr = pack_mhdr_to_send(&mut cmsg_buffer[..], iov, cmsgs, addr); ++ ++ let ret = unsafe { libc::sendmsg(fd, &mhdr, flags.bits()) }; ++ ++ Errno::result(ret).map(|r| r as usize) ++} ++ ++ ++/// An extension of `sendmsg` that allows the caller to transmit multiple ++/// messages on a socket using a single system call. This has performance ++/// benefits for some applications. ++/// ++/// Allocations are performed for cmsgs and to build `msghdr` buffer ++/// ++/// # Arguments ++/// ++/// * `fd`: Socket file descriptor ++/// * `data`: Struct that implements `IntoIterator` with `SendMmsgData` items ++/// * `flags`: Optional flags passed directly to the operating system. ++/// ++/// # Returns ++/// `Vec` with numbers of sent bytes on each sent message. ++/// ++/// # References ++/// [`sendmsg`](fn.sendmsg.html) ++#[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "freebsd", ++ target_os = "netbsd", ++))] ++pub fn sendmmsg<'a, XS, AS, C, I, S>( ++ fd: RawFd, ++ data: &'a mut MultiHeaders, ++ slices: XS, ++ // one address per group of slices ++ addrs: AS, ++ // shared across all the messages ++ cmsgs: C, ++ flags: MsgFlags ++) -> crate::Result> ++ where ++ XS: IntoIterator, ++ AS: AsRef<[Option]>, ++ I: AsRef<[IoSlice<'a>]> + 'a, ++ C: AsRef<[ControlMessage<'a>]> + 'a, ++ S: SockaddrLike + 'a ++{ ++ ++ let mut count = 0; ++ ++ ++ for (i, ((slice, addr), mmsghdr)) in slices.into_iter().zip(addrs.as_ref()).zip(data.items.iter_mut() ).enumerate() { ++ let mut p = &mut mmsghdr.msg_hdr; ++ p.msg_iov = slice.as_ref().as_ptr() as *mut libc::iovec; ++ p.msg_iovlen = slice.as_ref().len() as _; ++ ++ p.msg_namelen = addr.as_ref().map_or(0, S::len); ++ p.msg_name = addr.as_ref().map_or(ptr::null(), S::as_ptr) as _; ++ ++ // Encode each cmsg. This must happen after initializing the header because ++ // CMSG_NEXT_HDR and friends read the msg_control and msg_controllen fields. ++ // CMSG_FIRSTHDR is always safe ++ let mut pmhdr: *mut cmsghdr = unsafe { CMSG_FIRSTHDR(p) }; ++ for cmsg in cmsgs.as_ref() { ++ assert_ne!(pmhdr, ptr::null_mut()); ++ // Safe because we know that pmhdr is valid, and we initialized it with ++ // sufficient space ++ unsafe { cmsg.encode_into(pmhdr) }; ++ // Safe because mhdr is valid ++ pmhdr = unsafe { CMSG_NXTHDR(p, pmhdr) }; ++ } ++ ++ count = i+1; ++ } ++ ++ let sent = Errno::result(unsafe { ++ libc::sendmmsg( ++ fd, ++ data.items.as_mut_ptr(), ++ count as _, ++ flags.bits() as _ ++ ) ++ })? as usize; ++ ++ Ok(MultiResults { ++ rmm: data, ++ current_index: 0, ++ received: sent ++ }) ++ ++} ++ ++ ++#[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "freebsd", ++ target_os = "netbsd", ++))] ++#[derive(Debug)] ++/// Preallocated structures needed for [`recvmmsg`] and [`sendmmsg`] functions ++pub struct MultiHeaders { ++ // preallocated boxed slice of mmsghdr ++ items: Box<[libc::mmsghdr]>, ++ addresses: Box<[mem::MaybeUninit]>, ++ // while we are not using it directly - this is used to store control messages ++ // and we retain pointers to them inside items array ++ #[allow(dead_code)] ++ cmsg_buffers: Option>, ++ msg_controllen: usize, ++} ++ ++#[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "freebsd", ++ target_os = "netbsd", ++))] ++impl MultiHeaders { ++ /// Preallocate structure used by [`recvmmsg`] and [`sendmmsg`] takes number of headers to preallocate ++ /// ++ /// `cmsg_buffer` should be created with [`cmsg_space!`] if needed ++ pub fn preallocate(num_slices: usize, cmsg_buffer: Option>) -> Self ++ where ++ S: Copy + SockaddrLike, ++ { ++ // we will be storing pointers to addresses inside mhdr - convert it into boxed ++ // slice so it can'be changed later by pushing anything into self.addresses ++ let mut addresses = vec![std::mem::MaybeUninit::uninit(); num_slices].into_boxed_slice(); ++ ++ let msg_controllen = cmsg_buffer.as_ref().map_or(0, |v| v.capacity()); ++ ++ // we'll need a cmsg_buffer for each slice, we preallocate a vector and split ++ // it into "slices" parts ++ let cmsg_buffers = ++ cmsg_buffer.map(|v| vec![0u8; v.capacity() * num_slices].into_boxed_slice()); ++ ++ let items = addresses ++ .iter_mut() ++ .enumerate() ++ .map(|(ix, address)| { ++ let (ptr, cap) = match &cmsg_buffers { ++ Some(v) => ((&v[ix * msg_controllen] as *const u8), msg_controllen), ++ None => (std::ptr::null(), 0), ++ }; ++ let msg_hdr = unsafe { pack_mhdr_to_receive(std::ptr::null(), 0, ptr, cap, address.as_mut_ptr()) }; ++ libc::mmsghdr { ++ msg_hdr, ++ msg_len: 0, ++ } ++ }) ++ .collect::>(); ++ ++ Self { ++ items: items.into_boxed_slice(), ++ addresses, ++ cmsg_buffers, ++ msg_controllen, ++ } ++ } ++} ++ ++/// An extension of recvmsg that allows the caller to receive multiple messages from a socket using a single system call. ++/// ++/// This has performance benefits for some applications. ++/// ++/// This method performs no allocations. ++/// ++/// Returns an iterator producing [`RecvMsg`], one per received messages. Each `RecvMsg` can produce ++/// iterators over [`IoSlice`] with [`iovs`][RecvMsg::iovs`] and ++/// `ControlMessageOwned` with [`cmsgs`][RecvMsg::cmsgs]. ++/// ++/// # Bugs (in underlying implementation, at least in Linux) ++/// The timeout argument does not work as intended. The timeout is checked only after the receipt ++/// of each datagram, so that if up to `vlen`-1 datagrams are received before the timeout expires, ++/// but then no further datagrams are received, the call will block forever. ++/// ++/// If an error occurs after at least one message has been received, the call succeeds, and returns ++/// the number of messages received. The error code is expected to be returned on a subsequent ++/// call to recvmmsg(). In the current implementation, however, the error code can be ++/// overwritten in the meantime by an unrelated network event on a socket, for example an ++/// incoming ICMP packet. ++ ++// On aarch64 linux using recvmmsg and trying to get hardware/kernel timestamps might not ++// always produce the desired results - see https://github.com/nix-rust/nix/pull/1744 for more ++// details ++ ++#[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "freebsd", ++ target_os = "netbsd", ++))] ++pub fn recvmmsg<'a, XS, S, I>( ++ fd: RawFd, ++ data: &'a mut MultiHeaders, ++ slices: XS, ++ flags: MsgFlags, ++ mut timeout: Option, ++) -> crate::Result> ++where ++ XS: IntoIterator, ++ I: AsRef<[IoSliceMut<'a>]> + 'a, ++{ ++ let mut count = 0; ++ for (i, (slice, mmsghdr)) in slices.into_iter().zip(data.items.iter_mut()).enumerate() { ++ let mut p = &mut mmsghdr.msg_hdr; ++ p.msg_iov = slice.as_ref().as_ptr() as *mut libc::iovec; ++ p.msg_iovlen = slice.as_ref().len() as _; ++ count = i + 1; ++ } ++ ++ let timeout_ptr = timeout ++ .as_mut() ++ .map_or_else(std::ptr::null_mut, |t| t as *mut _ as *mut libc::timespec); ++ ++ let received = Errno::result(unsafe { ++ libc::recvmmsg( ++ fd, ++ data.items.as_mut_ptr(), ++ count as _, ++ flags.bits() as _, ++ timeout_ptr, ++ ) ++ })? as usize; ++ ++ Ok(MultiResults { ++ rmm: data, ++ current_index: 0, ++ received, ++ }) ++} ++ ++#[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "freebsd", ++ target_os = "netbsd", ++))] ++#[derive(Debug)] ++/// Iterator over results of [`recvmmsg`]/[`sendmmsg`] ++/// ++/// ++pub struct MultiResults<'a, S> { ++ // preallocated structures ++ rmm: &'a MultiHeaders, ++ current_index: usize, ++ received: usize, ++} ++ ++#[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "freebsd", ++ target_os = "netbsd", ++))] ++impl<'a, S> Iterator for MultiResults<'a, S> ++where ++ S: Copy + SockaddrLike, ++{ ++ type Item = RecvMsg<'a, 'a, S>; ++ ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] ++ fn next(&mut self) -> Option { ++ if self.current_index >= self.received { ++ return None; ++ } ++ let mmsghdr = self.rmm.items[self.current_index]; ++ ++ // as long as we are not reading past the index writen by recvmmsg - address ++ // will be initialized ++ let address = unsafe { self.rmm.addresses[self.current_index].assume_init() }; ++ ++ self.current_index += 1; ++ Some(unsafe { ++ read_mhdr( ++ mmsghdr.msg_hdr, ++ mmsghdr.msg_len as isize, ++ self.rmm.msg_controllen, ++ address, ++ ) ++ }) ++ } ++} ++ ++impl<'a, S> RecvMsg<'_, 'a, S> { ++ /// Iterate over the filled io slices pointed by this msghdr ++ pub fn iovs(&self) -> IoSliceIterator<'a> { ++ IoSliceIterator { ++ index: 0, ++ remaining: self.bytes, ++ slices: unsafe { ++ // safe for as long as mgdr is properly initialized and references are valid. ++ // for multi messages API we initialize it with an empty ++ // slice and replace with a concrete buffer ++ // for single message API we hold a lifetime reference to ioslices ++ std::slice::from_raw_parts(self.mhdr.msg_iov as *const _, self.mhdr.msg_iovlen as _) ++ }, ++ } ++ } ++} ++ ++#[derive(Debug)] ++pub struct IoSliceIterator<'a> { ++ index: usize, ++ remaining: usize, ++ slices: &'a [IoSlice<'a>], ++} ++ ++impl<'a> Iterator for IoSliceIterator<'a> { ++ type Item = &'a [u8]; ++ ++ fn next(&mut self) -> Option { ++ if self.index >= self.slices.len() { ++ return None; ++ } ++ let slice = &self.slices[self.index][..self.remaining.min(self.slices[self.index].len())]; ++ self.remaining -= slice.len(); ++ self.index += 1; ++ if slice.is_empty() { ++ return None; ++ } ++ ++ Some(slice) ++ } ++} ++ ++// test contains both recvmmsg and timestaping which is linux only ++// there are existing tests for recvmmsg only in tests/ ++#[cfg(target_os = "linux")] ++#[cfg(test)] ++mod test { ++ use crate::sys::socket::{AddressFamily, ControlMessageOwned}; ++ use crate::*; ++ use std::str::FromStr; ++ ++ #[cfg_attr(qemu, ignore)] ++ #[test] ++ fn test_recvmm2() -> crate::Result<()> { ++ use crate::sys::socket::{ ++ sendmsg, setsockopt, socket, sockopt::Timestamping, MsgFlags, SockFlag, SockType, ++ SockaddrIn, TimestampingFlag, ++ }; ++ use std::io::{IoSlice, IoSliceMut}; ++ ++ let sock_addr = SockaddrIn::from_str("127.0.0.1:6790").unwrap(); ++ ++ let ssock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ )?; ++ ++ let rsock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::SOCK_NONBLOCK, ++ None, ++ )?; ++ ++ crate::sys::socket::bind(rsock, &sock_addr)?; ++ ++ setsockopt(rsock, Timestamping, &TimestampingFlag::all())?; ++ ++ let sbuf = (0..400).map(|i| i as u8).collect::>(); ++ ++ let mut recv_buf = vec![0; 1024]; ++ ++ let mut recv_iovs = Vec::new(); ++ let mut pkt_iovs = Vec::new(); ++ ++ for (ix, chunk) in recv_buf.chunks_mut(256).enumerate() { ++ pkt_iovs.push(IoSliceMut::new(chunk)); ++ if ix % 2 == 1 { ++ recv_iovs.push(pkt_iovs); ++ pkt_iovs = Vec::new(); ++ } ++ } ++ drop(pkt_iovs); ++ ++ let flags = MsgFlags::empty(); ++ let iov1 = [IoSlice::new(&sbuf)]; ++ ++ let cmsg = cmsg_space!(crate::sys::socket::Timestamps); ++ sendmsg(ssock, &iov1, &[], flags, Some(&sock_addr)).unwrap(); ++ ++ let mut data = super::MultiHeaders::<()>::preallocate(recv_iovs.len(), Some(cmsg)); ++ ++ let t = sys::time::TimeSpec::from_duration(std::time::Duration::from_secs(10)); ++ ++ let recv = super::recvmmsg(rsock, &mut data, recv_iovs.iter(), flags, Some(t))?; ++ ++ for rmsg in recv { ++ #[cfg(not(any(qemu, target_arch = "aarch64")))] ++ let mut saw_time = false; ++ let mut recvd = 0; ++ for cmsg in rmsg.cmsgs() { ++ if let ControlMessageOwned::ScmTimestampsns(timestamps) = cmsg { ++ let ts = timestamps.system; ++ ++ let sys_time = ++ crate::time::clock_gettime(crate::time::ClockId::CLOCK_REALTIME)?; ++ let diff = if ts > sys_time { ++ ts - sys_time ++ } else { ++ sys_time - ts ++ }; ++ assert!(std::time::Duration::from(diff).as_secs() < 60); ++ #[cfg(not(any(qemu, target_arch = "aarch64")))] ++ { ++ saw_time = true; ++ } ++ } ++ } ++ ++ #[cfg(not(any(qemu, target_arch = "aarch64")))] ++ assert!(saw_time); ++ ++ for iov in rmsg.iovs() { ++ recvd += iov.len(); ++ } ++ assert_eq!(recvd, 400); ++ } ++ ++ Ok(()) ++ } ++} ++unsafe fn read_mhdr<'a, 'i, S>( ++ mhdr: msghdr, ++ r: isize, ++ msg_controllen: usize, ++ address: S, ++) -> RecvMsg<'a, 'i, S> ++ where S: SockaddrLike ++{ ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] ++ let cmsghdr = { ++ if mhdr.msg_controllen > 0 { ++ debug_assert!(!mhdr.msg_control.is_null()); ++ debug_assert!(msg_controllen >= mhdr.msg_controllen as usize); ++ CMSG_FIRSTHDR(&mhdr as *const msghdr) ++ } else { ++ ptr::null() ++ }.as_ref() + }; + ++ RecvMsg { ++ bytes: r as usize, ++ cmsghdr, ++ address: Some(address), ++ flags: MsgFlags::from_bits_truncate(mhdr.msg_flags), ++ mhdr, ++ iobufs: std::marker::PhantomData, ++ } ++} ++ ++/// Pack pointers to various structures into into msghdr ++/// ++/// # Safety ++/// `iov_buffer` and `iov_buffer_len` must point to a slice ++/// of `IoSliceMut` and number of available elements or be a null pointer and 0 ++/// ++/// `cmsg_buffer` and `cmsg_capacity` must point to a byte buffer used ++/// to store control headers later or be a null pointer and 0 if control ++/// headers are not used ++/// ++/// Buffers must remain valid for the whole lifetime of msghdr ++unsafe fn pack_mhdr_to_receive( ++ iov_buffer: *const IoSliceMut, ++ iov_buffer_len: usize, ++ cmsg_buffer: *const u8, ++ cmsg_capacity: usize, ++ address: *mut S, ++) -> msghdr ++ where ++ S: SockaddrLike ++{ ++ // Musl's msghdr has private fields, so this is the only way to ++ // initialize it. ++ let mut mhdr = mem::MaybeUninit::::zeroed(); ++ let p = mhdr.as_mut_ptr(); ++ (*p).msg_name = (*address).as_mut_ptr() as *mut c_void; ++ (*p).msg_namelen = S::size(); ++ (*p).msg_iov = iov_buffer as *mut iovec; ++ (*p).msg_iovlen = iov_buffer_len as _; ++ (*p).msg_control = cmsg_buffer as *mut c_void; ++ (*p).msg_controllen = cmsg_capacity as _; ++ (*p).msg_flags = 0; ++ mhdr.assume_init() ++} ++ ++fn pack_mhdr_to_send<'a, I, C, S>( ++ cmsg_buffer: &mut [u8], ++ iov: I, ++ cmsgs: C, ++ addr: Option<&S> ++) -> msghdr ++ where ++ I: AsRef<[IoSlice<'a>]>, ++ C: AsRef<[ControlMessage<'a>]>, ++ S: SockaddrLike + 'a ++{ ++ let capacity = cmsg_buffer.len(); ++ + // The message header must be initialized before the individual cmsgs. + let cmsg_ptr = if capacity > 0 { + cmsg_buffer.as_ptr() as *mut c_void +@@ -790,12 +2002,12 @@ pub fn sendmsg(fd: RawFd, iov: &[IoVec<&[u8]>], cmsgs: &[ControlMessage], + // initialize it. + let mut mhdr = mem::MaybeUninit::::zeroed(); + let p = mhdr.as_mut_ptr(); +- (*p).msg_name = name as *mut _; +- (*p).msg_namelen = namelen; ++ (*p).msg_name = addr.map(S::as_ptr).unwrap_or(ptr::null()) as *mut _; ++ (*p).msg_namelen = addr.map(S::len).unwrap_or(0); + // transmute iov into a mutable pointer. sendmsg doesn't really mutate + // the buffer, but the standard says that it takes a mutable pointer +- (*p).msg_iov = iov.as_ptr() as *mut _; +- (*p).msg_iovlen = iov.len() as _; ++ (*p).msg_iov = iov.as_ref().as_ptr() as *mut _; ++ (*p).msg_iovlen = iov.as_ref().len() as _; + (*p).msg_control = cmsg_ptr; + (*p).msg_controllen = capacity as _; + (*p).msg_flags = 0; +@@ -805,19 +2017,17 @@ pub fn sendmsg(fd: RawFd, iov: &[IoVec<&[u8]>], cmsgs: &[ControlMessage], + // Encode each cmsg. This must happen after initializing the header because + // CMSG_NEXT_HDR and friends read the msg_control and msg_controllen fields. + // CMSG_FIRSTHDR is always safe +- let mut pmhdr: *mut cmsghdr = unsafe{CMSG_FIRSTHDR(&mhdr as *const msghdr)}; +- for cmsg in cmsgs { ++ let mut pmhdr: *mut cmsghdr = unsafe { CMSG_FIRSTHDR(&mhdr as *const msghdr) }; ++ for cmsg in cmsgs.as_ref() { + assert_ne!(pmhdr, ptr::null_mut()); + // Safe because we know that pmhdr is valid, and we initialized it with + // sufficient space + unsafe { cmsg.encode_into(pmhdr) }; + // Safe because mhdr is valid +- pmhdr = unsafe{CMSG_NXTHDR(&mhdr as *const msghdr, pmhdr)}; ++ pmhdr = unsafe { CMSG_NXTHDR(&mhdr as *const msghdr, pmhdr) }; + } + +- let ret = unsafe { libc::sendmsg(fd, &mhdr, flags.bits()) }; +- +- Errno::result(ret).map(|r| r as usize) ++ mhdr + } + + /// Receive message in scatter-gather vectors from a socket, and +@@ -829,69 +2039,33 @@ pub fn sendmsg(fd: RawFd, iov: &[IoVec<&[u8]>], cmsgs: &[ControlMessage], + /// * `fd`: Socket file descriptor + /// * `iov`: Scatter-gather list of buffers to receive the message + /// * `cmsg_buffer`: Space to receive ancillary data. Should be created by +-/// [`cmsg_space!`](macro.cmsg_space.html) ++/// [`cmsg_space!`](../../macro.cmsg_space.html) + /// * `flags`: Optional flags passed directly to the operating system. + /// + /// # References +-/// [recvmsg(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html) +-pub fn recvmsg<'a>(fd: RawFd, iov: &[IoVec<&mut [u8]>], ++/// [recvmsg(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html) ++pub fn recvmsg<'a, 'outer, 'inner, S>(fd: RawFd, iov: &'outer mut [IoSliceMut<'inner>], + mut cmsg_buffer: Option<&'a mut Vec>, +- flags: MsgFlags) -> Result> ++ flags: MsgFlags) -> Result> ++ where S: SockaddrLike + 'a, ++ 'inner: 'outer + { + let mut address = mem::MaybeUninit::uninit(); ++ + let (msg_control, msg_controllen) = cmsg_buffer.as_mut() + .map(|v| (v.as_mut_ptr(), v.capacity())) + .unwrap_or((ptr::null_mut(), 0)); +- let mut mhdr = { +- unsafe { +- // Musl's msghdr has private fields, so this is the only way to +- // initialize it. +- let mut mhdr = mem::MaybeUninit::::zeroed(); +- let p = mhdr.as_mut_ptr(); +- (*p).msg_name = address.as_mut_ptr() as *mut c_void; +- (*p).msg_namelen = mem::size_of::() as socklen_t; +- (*p).msg_iov = iov.as_ptr() as *mut iovec; +- (*p).msg_iovlen = iov.len() as _; +- (*p).msg_control = msg_control as *mut c_void; +- (*p).msg_controllen = msg_controllen as _; +- (*p).msg_flags = 0; +- mhdr.assume_init() +- } ++ let mut mhdr = unsafe { ++ pack_mhdr_to_receive(iov.as_ref().as_ptr(), iov.len(), msg_control, msg_controllen, address.as_mut_ptr()) + }; + + let ret = unsafe { libc::recvmsg(fd, &mut mhdr, flags.bits()) }; + +- Errno::result(ret).map(|r| { +- let cmsghdr = unsafe { +- if mhdr.msg_controllen > 0 { +- // got control message(s) +- cmsg_buffer +- .as_mut() +- .unwrap() +- .set_len(mhdr.msg_controllen as usize); +- debug_assert!(!mhdr.msg_control.is_null()); +- debug_assert!(msg_controllen >= mhdr.msg_controllen as usize); +- CMSG_FIRSTHDR(&mhdr as *const msghdr) +- } else { +- ptr::null() +- }.as_ref() +- }; ++ let r = Errno::result(ret)?; + +- let address = unsafe { +- sockaddr_storage_to_addr(&address.assume_init(), +- mhdr.msg_namelen as usize +- ).ok() +- }; +- RecvMsg { +- bytes: r as usize, +- cmsghdr, +- address, +- flags: MsgFlags::from_bits_truncate(mhdr.msg_flags), +- mhdr, +- } +- }) ++ Ok(unsafe { read_mhdr(mhdr, r, msg_controllen, address.assume_init()) }) ++} + } +- + + /// Create an endpoint for communication + /// +@@ -902,8 +2076,13 @@ pub fn recvmsg<'a>(fd: RawFd, iov: &[IoVec<&mut [u8]>], + /// protocols may exist, in which case a particular protocol must be + /// specified in this manner. + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html) +-pub fn socket>>(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: T) -> Result { ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html) ++pub fn socket>>( ++ domain: AddressFamily, ++ ty: SockType, ++ flags: SockFlag, ++ protocol: T, ++) -> Result { + let protocol = match protocol.into() { + None => 0, + Some(p) => p as c_int, +@@ -922,9 +2101,13 @@ pub fn socket>>(domain: AddressFamily, ty: SockType + + /// Create a pair of connected sockets + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/socketpair.html) +-pub fn socketpair>>(domain: AddressFamily, ty: SockType, protocol: T, +- flags: SockFlag) -> Result<(RawFd, RawFd)> { ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/socketpair.html) ++pub fn socketpair>>( ++ domain: AddressFamily, ++ ty: SockType, ++ protocol: T, ++ flags: SockFlag, ++) -> Result<(RawFd, RawFd)> { + let protocol = match protocol.into() { + None => 0, + Some(p) => p as c_int, +@@ -938,7 +2121,9 @@ pub fn socketpair>>(domain: AddressFamily, ty: Sock + + let mut fds = [-1, -1]; + +- let res = unsafe { libc::socketpair(domain as c_int, ty, protocol, fds.as_mut_ptr()) }; ++ let res = unsafe { ++ libc::socketpair(domain as c_int, ty, protocol, fds.as_mut_ptr()) ++ }; + Errno::result(res)?; + + Ok((fds[0], fds[1])) +@@ -946,7 +2131,7 @@ pub fn socketpair>>(domain: AddressFamily, ty: Sock + + /// Listen for connections on a socket + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html) ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html) + pub fn listen(sockfd: RawFd, backlog: usize) -> Result<()> { + let res = unsafe { libc::listen(sockfd, backlog as c_int) }; + +@@ -955,19 +2140,16 @@ pub fn listen(sockfd: RawFd, backlog: usize) -> Result<()> { + + /// Bind a name to a socket + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html) +-pub fn bind(fd: RawFd, addr: &SockAddr) -> Result<()> { +- let res = unsafe { +- let (ptr, len) = addr.as_ffi_pair(); +- libc::bind(fd, ptr, len) +- }; ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html) ++pub fn bind(fd: RawFd, addr: &dyn SockaddrLike) -> Result<()> { ++ let res = unsafe { libc::bind(fd, addr.as_ptr(), addr.len()) }; + + Errno::result(res).map(drop) + } + + /// Accept a connection on a socket + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html) ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html) + pub fn accept(sockfd: RawFd) -> Result { + let res = unsafe { libc::accept(sockfd, ptr::null_mut(), ptr::null_mut()) }; + +@@ -976,25 +2158,38 @@ pub fn accept(sockfd: RawFd) -> Result { + + /// Accept a connection on a socket + /// +-/// [Further reading](http://man7.org/linux/man-pages/man2/accept.2.html) +-#[cfg(any(target_os = "android", +- target_os = "freebsd", +- target_os = "linux", +- target_os = "openbsd"))] ++/// [Further reading](https://man7.org/linux/man-pages/man2/accept.2.html) ++#[cfg(any( ++ all( ++ target_os = "android", ++ any( ++ target_arch = "aarch64", ++ target_arch = "x86", ++ target_arch = "x86_64" ++ ) ++ ), ++ target_os = "dragonfly", ++ target_os = "emscripten", ++ target_os = "freebsd", ++ target_os = "fuchsia", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "netbsd", ++ target_os = "openbsd" ++))] + pub fn accept4(sockfd: RawFd, flags: SockFlag) -> Result { +- let res = unsafe { libc::accept4(sockfd, ptr::null_mut(), ptr::null_mut(), flags.bits()) }; ++ let res = unsafe { ++ libc::accept4(sockfd, ptr::null_mut(), ptr::null_mut(), flags.bits()) ++ }; + + Errno::result(res) + } + + /// Initiate a connection on a socket + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html) +-pub fn connect(fd: RawFd, addr: &SockAddr) -> Result<()> { +- let res = unsafe { +- let (ptr, len) = addr.as_ffi_pair(); +- libc::connect(fd, ptr, len) +- }; ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html) ++pub fn connect(fd: RawFd, addr: &dyn SockaddrLike) -> Result<()> { ++ let res = unsafe { libc::connect(fd, addr.as_ptr(), addr.len()) }; + + Errno::result(res).map(drop) + } +@@ -1002,14 +2197,15 @@ pub fn connect(fd: RawFd, addr: &SockAddr) -> Result<()> { + /// Receive data from a connection-oriented socket. Returns the number of + /// bytes read + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html) ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html) + pub fn recv(sockfd: RawFd, buf: &mut [u8], flags: MsgFlags) -> Result { + unsafe { + let ret = libc::recv( + sockfd, + buf.as_ptr() as *mut c_void, + buf.len() as size_t, +- flags.bits()); ++ flags.bits(), ++ ); + + Errno::result(ret).map(|r| r as usize) + } +@@ -1019,37 +2215,52 @@ pub fn recv(sockfd: RawFd, buf: &mut [u8], flags: MsgFlags) -> Result { + /// the number of bytes read and, for connectionless sockets, the socket + /// address of the sender. + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html) +-pub fn recvfrom(sockfd: RawFd, buf: &mut [u8]) +- -> Result<(usize, Option)> +-{ ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html) ++pub fn recvfrom( ++ sockfd: RawFd, ++ buf: &mut [u8], ++) -> Result<(usize, Option)> { + unsafe { +- let mut addr: sockaddr_storage = mem::zeroed(); +- let mut len = mem::size_of::() as socklen_t; ++ let mut addr = mem::MaybeUninit::::uninit(); ++ let mut len = mem::size_of_val(&addr) as socklen_t; + + let ret = Errno::result(libc::recvfrom( + sockfd, + buf.as_ptr() as *mut c_void, + buf.len() as size_t, + 0, +- &mut addr as *mut libc::sockaddr_storage as *mut libc::sockaddr, +- &mut len as *mut socklen_t))? as usize; +- +- match sockaddr_storage_to_addr(&addr, len as usize) { +- Err(Error::Sys(Errno::ENOTCONN)) => Ok((ret, None)), +- Ok(addr) => Ok((ret, Some(addr))), +- Err(e) => Err(e) +- } ++ addr.as_mut_ptr() as *mut libc::sockaddr, ++ &mut len as *mut socklen_t, ++ ))? as usize; ++ ++ Ok(( ++ ret, ++ T::from_raw( ++ addr.assume_init().as_ptr() as *const libc::sockaddr, ++ Some(len), ++ ), ++ )) + } + } + + /// Send a message to a socket + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html) +-pub fn sendto(fd: RawFd, buf: &[u8], addr: &SockAddr, flags: MsgFlags) -> Result { ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html) ++pub fn sendto( ++ fd: RawFd, ++ buf: &[u8], ++ addr: &dyn SockaddrLike, ++ flags: MsgFlags, ++) -> Result { + let ret = unsafe { +- let (ptr, len) = addr.as_ffi_pair(); +- libc::sendto(fd, buf.as_ptr() as *const c_void, buf.len() as size_t, flags.bits(), ptr, len) ++ libc::sendto( ++ fd, ++ buf.as_ptr() as *const c_void, ++ buf.len() as size_t, ++ flags.bits(), ++ addr.as_ptr(), ++ addr.len(), ++ ) + }; + + Errno::result(ret).map(|r| r as usize) +@@ -1057,10 +2268,15 @@ pub fn sendto(fd: RawFd, buf: &[u8], addr: &SockAddr, flags: MsgFlags) -> Result + + /// Send data to a connection-oriented socket. Returns the number of bytes read + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html) ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html) + pub fn send(fd: RawFd, buf: &[u8], flags: MsgFlags) -> Result { + let ret = unsafe { +- libc::send(fd, buf.as_ptr() as *const c_void, buf.len() as size_t, flags.bits()) ++ libc::send( ++ fd, ++ buf.as_ptr() as *const c_void, ++ buf.len() as size_t, ++ flags.bits(), ++ ) + }; + + Errno::result(ret).map(|r| r as usize) +@@ -1072,52 +2288,32 @@ pub fn send(fd: RawFd, buf: &[u8], flags: MsgFlags) -> Result { + * + */ + +-/// The protocol level at which to get / set socket options. Used as an +-/// argument to `getsockopt` and `setsockopt`. +-/// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html) +-#[repr(i32)] +-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +-pub enum SockLevel { +- Socket = libc::SOL_SOCKET, +- Tcp = libc::IPPROTO_TCP, +- Ip = libc::IPPROTO_IP, +- Ipv6 = libc::IPPROTO_IPV6, +- Udp = libc::IPPROTO_UDP, +- #[cfg(any(target_os = "android", target_os = "linux"))] +- Netlink = libc::SOL_NETLINK, +- #[cfg(any(target_os = "android", target_os = "linux"))] +- Alg = libc::SOL_ALG, +-} +- +-/// Represents a socket option that can be accessed or set. Used as an argument +-/// to `getsockopt` +-pub trait GetSockOpt : Copy { ++/// Represents a socket option that can be retrieved. ++pub trait GetSockOpt: Copy { + type Val; + +- #[doc(hidden)] ++ /// Look up the value of this socket option on the given socket. + fn get(&self, fd: RawFd) -> Result; + } + +-/// Represents a socket option that can be accessed or set. Used as an argument +-/// to `setsockopt` +-pub trait SetSockOpt : Clone { ++/// Represents a socket option that can be set. ++pub trait SetSockOpt: Clone { + type Val; + +- #[doc(hidden)] ++ /// Set the value of this socket option on the given socket. + fn set(&self, fd: RawFd, val: &Self::Val) -> Result<()>; + } + + /// Get the current value for the requested socket option + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html) ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html) + pub fn getsockopt(fd: RawFd, opt: O) -> Result { + opt.get(fd) + } + + /// Sets the value for the requested socket option + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html) ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html) + /// + /// # Examples + /// +@@ -1132,99 +2328,129 @@ pub fn getsockopt(fd: RawFd, opt: O) -> Result { + /// let res = setsockopt(fd, KeepAlive, &true); + /// assert!(res.is_ok()); + /// ``` +-pub fn setsockopt(fd: RawFd, opt: O, val: &O::Val) -> Result<()> { ++pub fn setsockopt( ++ fd: RawFd, ++ opt: O, ++ val: &O::Val, ++) -> Result<()> { + opt.set(fd, val) + } + + /// Get the address of the peer connected to the socket `fd`. + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html) +-pub fn getpeername(fd: RawFd) -> Result { ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html) ++pub fn getpeername(fd: RawFd) -> Result { + unsafe { +- let mut addr = mem::MaybeUninit::uninit(); +- let mut len = mem::size_of::() as socklen_t; ++ let mut addr = mem::MaybeUninit::::uninit(); ++ let mut len = T::size(); + + let ret = libc::getpeername( + fd, + addr.as_mut_ptr() as *mut libc::sockaddr, +- &mut len ++ &mut len, + ); + + Errno::result(ret)?; + +- sockaddr_storage_to_addr(&addr.assume_init(), len as usize) ++ T::from_raw(addr.assume_init().as_ptr(), Some(len)).ok_or(Errno::EINVAL) + } + } + + /// Get the current address to which the socket `fd` is bound. + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html) +-pub fn getsockname(fd: RawFd) -> Result { ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html) ++pub fn getsockname(fd: RawFd) -> Result { + unsafe { +- let mut addr = mem::MaybeUninit::uninit(); +- let mut len = mem::size_of::() as socklen_t; ++ let mut addr = mem::MaybeUninit::::uninit(); ++ let mut len = T::size(); + + let ret = libc::getsockname( + fd, + addr.as_mut_ptr() as *mut libc::sockaddr, +- &mut len ++ &mut len, + ); + + Errno::result(ret)?; + +- sockaddr_storage_to_addr(&addr.assume_init(), len as usize) ++ T::from_raw(addr.assume_init().as_ptr(), Some(len)).ok_or(Errno::EINVAL) + } + } + +-/// Return the appropriate `SockAddr` type from a `sockaddr_storage` of a certain +-/// size. In C this would usually be done by casting. The `len` argument ++/// Return the appropriate `SockAddr` type from a `sockaddr_storage` of a ++/// certain size. ++/// ++/// In C this would usually be done by casting. The `len` argument + /// should be the number of bytes in the `sockaddr_storage` that are actually + /// allocated and valid. It must be at least as large as all the useful parts + /// of the structure. Note that in the case of a `sockaddr_un`, `len` need not + /// include the terminating null. +-pub unsafe fn sockaddr_storage_to_addr( ++#[deprecated( ++ since = "0.24.0", ++ note = "use SockaddrLike or SockaddrStorage instead" ++)] ++#[allow(deprecated)] ++pub fn sockaddr_storage_to_addr( + addr: &sockaddr_storage, +- len: usize) -> Result { +- ++ len: usize, ++) -> Result { ++ assert!(len <= mem::size_of::()); + if len < mem::size_of_val(&addr.ss_family) { +- return Err(Error::Sys(Errno::ENOTCONN)); ++ return Err(Errno::ENOTCONN); + } + + match c_int::from(addr.ss_family) { ++ #[cfg(feature = "net")] + libc::AF_INET => { +- assert_eq!(len as usize, mem::size_of::()); +- let ret = *(addr as *const _ as *const sockaddr_in); +- Ok(SockAddr::Inet(InetAddr::V4(ret))) ++ assert!(len >= mem::size_of::()); ++ let sin = unsafe { ++ *(addr as *const sockaddr_storage as *const sockaddr_in) ++ }; ++ Ok(SockAddr::Inet(InetAddr::V4(sin))) + } ++ #[cfg(feature = "net")] + libc::AF_INET6 => { +- assert_eq!(len as usize, mem::size_of::()); +- Ok(SockAddr::Inet(InetAddr::V6(*(addr as *const _ as *const sockaddr_in6)))) ++ assert!(len >= mem::size_of::()); ++ let sin6 = unsafe { *(addr as *const _ as *const sockaddr_in6) }; ++ Ok(SockAddr::Inet(InetAddr::V6(sin6))) + } +- libc::AF_UNIX => { ++ libc::AF_UNIX => unsafe { + let sun = *(addr as *const _ as *const sockaddr_un); +- let pathlen = len - offset_of!(sockaddr_un, sun_path); +- Ok(SockAddr::Unix(UnixAddr(sun, pathlen))) ++ let sun_len = len.try_into().unwrap(); ++ Ok(SockAddr::Unix(UnixAddr::from_raw_parts(sun, sun_len))) ++ }, ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg(feature = "net")] ++ libc::AF_PACKET => { ++ use libc::sockaddr_ll; ++ // Don't assert anything about the size. ++ // Apparently the Linux kernel can return smaller sizes when ++ // the value in the last element of sockaddr_ll (`sll_addr`) is ++ // smaller than the declared size of that field ++ let sll = unsafe { *(addr as *const _ as *const sockaddr_ll) }; ++ Ok(SockAddr::Link(LinkAddr(sll))) + } + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_NETLINK => { + use libc::sockaddr_nl; +- Ok(SockAddr::Netlink(NetlinkAddr(*(addr as *const _ as *const sockaddr_nl)))) ++ let snl = unsafe { *(addr as *const _ as *const sockaddr_nl) }; ++ Ok(SockAddr::Netlink(NetlinkAddr(snl))) + } + #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_ALG => { + use libc::sockaddr_alg; +- Ok(SockAddr::Alg(AlgAddr(*(addr as *const _ as *const sockaddr_alg)))) ++ let salg = unsafe { *(addr as *const _ as *const sockaddr_alg) }; ++ Ok(SockAddr::Alg(AlgAddr(salg))) + } +- #[cfg(target_os = "linux")] ++ #[cfg(any(target_os = "android", target_os = "linux"))] + libc::AF_VSOCK => { + use libc::sockaddr_vm; +- Ok(SockAddr::Vsock(VsockAddr(*(addr as *const _ as *const sockaddr_vm)))) ++ let svm = unsafe { *(addr as *const _ as *const sockaddr_vm) }; ++ Ok(SockAddr::Vsock(VsockAddr(svm))) + } + af => panic!("unexpected address family {}", af), + } + } + +- + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub enum Shutdown { + /// Further receptions will be disallowed. +@@ -1237,17 +2463,25 @@ pub enum Shutdown { + + /// Shut down part of a full-duplex connection. + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html) ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html) + pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> { + unsafe { + use libc::shutdown; + + let how = match how { +- Shutdown::Read => libc::SHUT_RD, ++ Shutdown::Read => libc::SHUT_RD, + Shutdown::Write => libc::SHUT_WR, +- Shutdown::Both => libc::SHUT_RDWR, ++ Shutdown::Both => libc::SHUT_RDWR, + }; + + Errno::result(shutdown(df, how)).map(drop) + } + } ++ ++#[cfg(test)] ++mod tests { ++ #[test] ++ fn can_use_cmsg_space() { ++ let _ = cmsg_space!(u8); ++ } ++} +diff --git a/vendor/nix/src/sys/socket/sockopt.rs b/vendor/nix/src/sys/socket/sockopt.rs +index 691f66d..06e9ee4 100644 +--- a/vendor/nix/src/sys/socket/sockopt.rs ++++ b/vendor/nix/src/sys/socket/sockopt.rs +@@ -1,17 +1,23 @@ ++//! Socket options as used by `setsockopt` and `getsockopt`. + use super::{GetSockOpt, SetSockOpt}; +-use Result; +-use errno::Errno; +-use sys::time::TimeVal; ++use crate::errno::Errno; ++use crate::sys::time::TimeVal; ++use crate::Result; ++use cfg_if::cfg_if; + use libc::{self, c_int, c_void, socklen_t}; +-use std::mem; +-use std::os::unix::io::RawFd; + use std::ffi::{OsStr, OsString}; ++use std::{ ++ convert::TryFrom, ++ mem::{self, MaybeUninit} ++}; + #[cfg(target_family = "unix")] + use std::os::unix::ffi::OsStrExt; ++use std::os::unix::io::RawFd; + + // Constants + // TCP_CA_NAME_MAX isn't defined in user space include files +-#[cfg(any(target_os = "freebsd", target_os = "linux"))] ++#[cfg(any(target_os = "freebsd", target_os = "linux"))] ++#[cfg(feature = "net")] + const TCP_CA_NAME_MAX: usize = 16; + + /// Helper for implementing `SetSockOpt` for a given socket option. See +@@ -26,7 +32,7 @@ const TCP_CA_NAME_MAX: usize = 16; + /// # Arguments + /// + /// * `$name:ident`: name of the type you want to implement `SetSockOpt` for. +-/// * `$level:path` : socket layer, or a `protocol level`: could be *raw sockets* ++/// * `$level:expr` : socket layer, or a `protocol level`: could be *raw sockets* + /// (`libc::SOL_SOCKET`), *ip protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`), + /// and more. Please refer to your system manual for more options. Will be passed as the second + /// argument (`level`) to the `setsockopt` call. +@@ -37,7 +43,7 @@ const TCP_CA_NAME_MAX: usize = 16; + /// * Type that implements the `Set` trait for the type from the previous item (like `SetBool` for + /// `bool`, `SetUsize` for `usize`, etc.). + macro_rules! setsockopt_impl { +- ($name:ident, $level:path, $flag:path, $ty:ty, $setter:ty) => { ++ ($name:ident, $level:expr, $flag:path, $ty:ty, $setter:ty) => { + impl SetSockOpt for $name { + type Val = $ty; + +@@ -45,14 +51,18 @@ macro_rules! setsockopt_impl { + unsafe { + let setter: $setter = Set::new(val); + +- let res = libc::setsockopt(fd, $level, $flag, +- setter.ffi_ptr(), +- setter.ffi_len()); ++ let res = libc::setsockopt( ++ fd, ++ $level, ++ $flag, ++ setter.ffi_ptr(), ++ setter.ffi_len(), ++ ); + Errno::result(res).map(drop) + } + } + } +- } ++ }; + } + + /// Helper for implementing `GetSockOpt` for a given socket option. See +@@ -78,24 +88,31 @@ macro_rules! setsockopt_impl { + /// * Type that implements the `Get` trait for the type from the previous item (`GetBool` for + /// `bool`, `GetUsize` for `usize`, etc.). + macro_rules! getsockopt_impl { +- ($name:ident, $level:path, $flag:path, $ty:ty, $getter:ty) => { ++ ($name:ident, $level:expr, $flag:path, $ty:ty, $getter:ty) => { + impl GetSockOpt for $name { + type Val = $ty; + + fn get(&self, fd: RawFd) -> Result<$ty> { + unsafe { +- let mut getter: $getter = Get::blank(); +- +- let res = libc::getsockopt(fd, $level, $flag, +- getter.ffi_ptr(), +- getter.ffi_len()); ++ let mut getter: $getter = Get::uninit(); ++ ++ let res = libc::getsockopt( ++ fd, ++ $level, ++ $flag, ++ getter.ffi_ptr(), ++ getter.ffi_len(), ++ ); + Errno::result(res)?; + +- Ok(getter.unwrap()) ++ match <$ty>::try_from(getter.assume_init()) { ++ Err(_) => Err(Errno::EINVAL), ++ Ok(r) => Ok(r) ++ } + } + } + } +- } ++ }; + } + + /// Helper to generate the sockopt accessors. See +@@ -113,7 +130,7 @@ macro_rules! getsockopt_impl { + /// * `GetOnly`, `SetOnly` or `Both`: whether you want to implement only getter, only setter or + /// both of them. + /// * `$name:ident`: name of type `GetSockOpt`/`SetSockOpt` will be implemented for. +-/// * `$level:path` : socket layer, or a `protocol level`: could be *raw sockets* ++/// * `$level:expr` : socket layer, or a `protocol level`: could be *raw sockets* + /// (`lic::SOL_SOCKET`), *ip protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`), + /// and more. Please refer to your system manual for more options. Will be passed as the second + /// argument (`level`) to the `getsockopt`/`setsockopt` call. +@@ -123,74 +140,103 @@ macro_rules! getsockopt_impl { + /// * `$ty:ty`: type of the value that will be get/set. + /// * `$getter:ty`: `Get` implementation; optional; only for `GetOnly` and `Both`. + /// * `$setter:ty`: `Set` implementation; optional; only for `SetOnly` and `Both`. ++// Some targets don't use all rules. ++#[allow(unknown_lints)] ++#[allow(unused_macro_rules)] + macro_rules! sockopt_impl { +- (GetOnly, $name:ident, $level:path, $flag:path, bool) => { +- sockopt_impl!(GetOnly, $name, $level, $flag, bool, GetBool); ++ ($(#[$attr:meta])* $name:ident, GetOnly, $level:expr, $flag:path, bool) => { ++ sockopt_impl!($(#[$attr])* ++ $name, GetOnly, $level, $flag, bool, GetBool); + }; + +- (GetOnly, $name:ident, $level:path, $flag:path, u8) => { +- sockopt_impl!(GetOnly, $name, $level, $flag, u8, GetU8); ++ ($(#[$attr:meta])* $name:ident, GetOnly, $level:expr, $flag:path, u8) => { ++ sockopt_impl!($(#[$attr])* $name, GetOnly, $level, $flag, u8, GetU8); + }; + +- (GetOnly, $name:ident, $level:path, $flag:path, usize) => { +- sockopt_impl!(GetOnly, $name, $level, $flag, usize, GetUsize); ++ ($(#[$attr:meta])* $name:ident, GetOnly, $level:expr, $flag:path, usize) => ++ { ++ sockopt_impl!($(#[$attr])* ++ $name, GetOnly, $level, $flag, usize, GetUsize); + }; + +- (SetOnly, $name:ident, $level:path, $flag:path, bool) => { +- sockopt_impl!(SetOnly, $name, $level, $flag, bool, SetBool); ++ ($(#[$attr:meta])* $name:ident, SetOnly, $level:expr, $flag:path, bool) => { ++ sockopt_impl!($(#[$attr])* ++ $name, SetOnly, $level, $flag, bool, SetBool); + }; + +- (SetOnly, $name:ident, $level:path, $flag:path, u8) => { +- sockopt_impl!(SetOnly, $name, $level, $flag, u8, SetU8); ++ ($(#[$attr:meta])* $name:ident, SetOnly, $level:expr, $flag:path, u8) => { ++ sockopt_impl!($(#[$attr])* $name, SetOnly, $level, $flag, u8, SetU8); + }; + +- (SetOnly, $name:ident, $level:path, $flag:path, usize) => { +- sockopt_impl!(SetOnly, $name, $level, $flag, usize, SetUsize); ++ ($(#[$attr:meta])* $name:ident, SetOnly, $level:expr, $flag:path, usize) => ++ { ++ sockopt_impl!($(#[$attr])* ++ $name, SetOnly, $level, $flag, usize, SetUsize); + }; + +- (Both, $name:ident, $level:path, $flag:path, bool) => { +- sockopt_impl!(Both, $name, $level, $flag, bool, GetBool, SetBool); ++ ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path, bool) => { ++ sockopt_impl!($(#[$attr])* ++ $name, Both, $level, $flag, bool, GetBool, SetBool); + }; + +- (Both, $name:ident, $level:path, $flag:path, u8) => { +- sockopt_impl!(Both, $name, $level, $flag, u8, GetU8, SetU8); ++ ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path, u8) => { ++ sockopt_impl!($(#[$attr])* ++ $name, Both, $level, $flag, u8, GetU8, SetU8); + }; + +- (Both, $name:ident, $level:path, $flag:path, usize) => { +- sockopt_impl!(Both, $name, $level, $flag, usize, GetUsize, SetUsize); ++ ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path, usize) => { ++ sockopt_impl!($(#[$attr])* ++ $name, Both, $level, $flag, usize, GetUsize, SetUsize); + }; + +- (Both, $name:ident, $level:path, $flag:path, OsString<$array:ty>) => { +- sockopt_impl!(Both, $name, $level, $flag, OsString, GetOsString<$array>, SetOsString); ++ ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path, ++ OsString<$array:ty>) => ++ { ++ sockopt_impl!($(#[$attr])* ++ $name, Both, $level, $flag, OsString, GetOsString<$array>, ++ SetOsString); + }; + + /* + * Matchers with generic getter types must be placed at the end, so + * they'll only match _after_ specialized matchers fail + */ +- (GetOnly, $name:ident, $level:path, $flag:path, $ty:ty) => { +- sockopt_impl!(GetOnly, $name, $level, $flag, $ty, GetStruct<$ty>); ++ ($(#[$attr:meta])* $name:ident, GetOnly, $level:expr, $flag:path, $ty:ty) => ++ { ++ sockopt_impl!($(#[$attr])* ++ $name, GetOnly, $level, $flag, $ty, GetStruct<$ty>); + }; + +- (GetOnly, $name:ident, $level:path, $flag:path, $ty:ty, $getter:ty) => { ++ ($(#[$attr:meta])* $name:ident, GetOnly, $level:expr, $flag:path, $ty:ty, ++ $getter:ty) => ++ { ++ $(#[$attr])* + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct $name; + + getsockopt_impl!($name, $level, $flag, $ty, $getter); + }; + +- (SetOnly, $name:ident, $level:path, $flag:path, $ty:ty) => { +- sockopt_impl!(SetOnly, $name, $level, $flag, $ty, SetStruct<$ty>); ++ ($(#[$attr:meta])* $name:ident, SetOnly, $level:expr, $flag:path, $ty:ty) => ++ { ++ sockopt_impl!($(#[$attr])* ++ $name, SetOnly, $level, $flag, $ty, SetStruct<$ty>); + }; + +- (SetOnly, $name:ident, $level:path, $flag:path, $ty:ty, $setter:ty) => { ++ ($(#[$attr:meta])* $name:ident, SetOnly, $level:expr, $flag:path, $ty:ty, ++ $setter:ty) => ++ { ++ $(#[$attr])* + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct $name; + + setsockopt_impl!($name, $level, $flag, $ty, $setter); + }; + +- (Both, $name:ident, $level:path, $flag:path, $ty:ty, $getter:ty, $setter:ty) => { ++ ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path, $ty:ty, ++ $getter:ty, $setter:ty) => ++ { ++ $(#[$attr])* + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct $name; + +@@ -198,8 +244,10 @@ macro_rules! sockopt_impl { + getsockopt_impl!($name, $level, $flag, $ty, $getter); + }; + +- (Both, $name:ident, $level:path, $flag:path, $ty:ty) => { +- sockopt_impl!(Both, $name, $level, $flag, $ty, GetStruct<$ty>, SetStruct<$ty>); ++ ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path, $ty:ty) => { ++ sockopt_impl!($(#[$attr])* ++ $name, Both, $level, $flag, $ty, GetStruct<$ty>, ++ SetStruct<$ty>); + }; + } + +@@ -209,68 +257,522 @@ macro_rules! sockopt_impl { + * + */ + +-sockopt_impl!(Both, ReuseAddr, libc::SOL_SOCKET, libc::SO_REUSEADDR, bool); +-sockopt_impl!(Both, ReusePort, libc::SOL_SOCKET, libc::SO_REUSEPORT, bool); +-sockopt_impl!(Both, TcpNoDelay, libc::IPPROTO_TCP, libc::TCP_NODELAY, bool); +-sockopt_impl!(Both, Linger, libc::SOL_SOCKET, libc::SO_LINGER, libc::linger); +-sockopt_impl!(SetOnly, IpAddMembership, libc::IPPROTO_IP, libc::IP_ADD_MEMBERSHIP, super::IpMembershipRequest); +-sockopt_impl!(SetOnly, IpDropMembership, libc::IPPROTO_IP, libc::IP_DROP_MEMBERSHIP, super::IpMembershipRequest); ++sockopt_impl!( ++ /// Enables local address reuse ++ ReuseAddr, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_REUSEADDR, ++ bool ++); ++#[cfg(not(any(target_os = "illumos", target_os = "solaris")))] ++sockopt_impl!( ++ /// Permits multiple AF_INET or AF_INET6 sockets to be bound to an ++ /// identical socket address. ++ ReusePort, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_REUSEPORT, ++ bool ++); ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Under most circumstances, TCP sends data when it is presented; when ++ /// outstanding data has not yet been acknowledged, it gathers small amounts ++ /// of output to be sent in a single packet once an acknowledgement is ++ /// received. For a small number of clients, such as window systems that ++ /// send a stream of mouse events which receive no replies, this ++ /// packetization may cause significant delays. The boolean option ++ /// TCP_NODELAY defeats this algorithm. ++ TcpNoDelay, ++ Both, ++ libc::IPPROTO_TCP, ++ libc::TCP_NODELAY, ++ bool ++); ++sockopt_impl!( ++ /// When enabled, a close(2) or shutdown(2) will not return until all ++ /// queued messages for the socket have been successfully sent or the ++ /// linger timeout has been reached. ++ Linger, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_LINGER, ++ libc::linger ++); ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Join a multicast group ++ IpAddMembership, ++ SetOnly, ++ libc::IPPROTO_IP, ++ libc::IP_ADD_MEMBERSHIP, ++ super::IpMembershipRequest ++); ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Leave a multicast group. ++ IpDropMembership, ++ SetOnly, ++ libc::IPPROTO_IP, ++ libc::IP_DROP_MEMBERSHIP, ++ super::IpMembershipRequest ++); + cfg_if! { + if #[cfg(any(target_os = "android", target_os = "linux"))] { +- sockopt_impl!(SetOnly, Ipv6AddMembership, libc::IPPROTO_IPV6, libc::IPV6_ADD_MEMBERSHIP, super::Ipv6MembershipRequest); +- sockopt_impl!(SetOnly, Ipv6DropMembership, libc::IPPROTO_IPV6, libc::IPV6_DROP_MEMBERSHIP, super::Ipv6MembershipRequest); ++ #[cfg(feature = "net")] ++ sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Join an IPv6 multicast group. ++ Ipv6AddMembership, SetOnly, libc::IPPROTO_IPV6, libc::IPV6_ADD_MEMBERSHIP, super::Ipv6MembershipRequest); ++ #[cfg(feature = "net")] ++ sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Leave an IPv6 multicast group. ++ Ipv6DropMembership, SetOnly, libc::IPPROTO_IPV6, libc::IPV6_DROP_MEMBERSHIP, super::Ipv6MembershipRequest); + } else if #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", ++ target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", +- target_os = "openbsd"))] { +- sockopt_impl!(SetOnly, Ipv6AddMembership, libc::IPPROTO_IPV6, libc::IPV6_JOIN_GROUP, super::Ipv6MembershipRequest); +- sockopt_impl!(SetOnly, Ipv6DropMembership, libc::IPPROTO_IPV6, libc::IPV6_LEAVE_GROUP, super::Ipv6MembershipRequest); ++ target_os = "openbsd", ++ target_os = "solaris"))] { ++ #[cfg(feature = "net")] ++ sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Join an IPv6 multicast group. ++ Ipv6AddMembership, SetOnly, libc::IPPROTO_IPV6, ++ libc::IPV6_JOIN_GROUP, super::Ipv6MembershipRequest); ++ #[cfg(feature = "net")] ++ sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Leave an IPv6 multicast group. ++ Ipv6DropMembership, SetOnly, libc::IPPROTO_IPV6, ++ libc::IPV6_LEAVE_GROUP, super::Ipv6MembershipRequest); ++ } ++} ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Set or read the time-to-live value of outgoing multicast packets for ++ /// this socket. ++ IpMulticastTtl, ++ Both, ++ libc::IPPROTO_IP, ++ libc::IP_MULTICAST_TTL, ++ u8 ++); ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Set or read a boolean integer argument that determines whether sent ++ /// multicast packets should be looped back to the local sockets. ++ IpMulticastLoop, ++ Both, ++ libc::IPPROTO_IP, ++ libc::IP_MULTICAST_LOOP, ++ bool ++); ++#[cfg(target_os = "linux")] ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Set the protocol-defined priority for all packets to be ++ /// sent on this socket ++ Priority, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_PRIORITY, ++ libc::c_int ++); ++#[cfg(target_os = "linux")] ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Set or receive the Type-Of-Service (TOS) field that is ++ /// sent with every IP packet originating from this socket ++ IpTos, ++ Both, ++ libc::IPPROTO_IP, ++ libc::IP_TOS, ++ libc::c_int ++); ++#[cfg(target_os = "linux")] ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Traffic class associated with outgoing packets ++ Ipv6TClass, ++ Both, ++ libc::IPPROTO_IPV6, ++ libc::IPV6_TCLASS, ++ libc::c_int ++); ++#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// If enabled, this boolean option allows binding to an IP address that ++ /// is nonlocal or does not (yet) exist. ++ IpFreebind, ++ Both, ++ libc::IPPROTO_IP, ++ libc::IP_FREEBIND, ++ bool ++); ++sockopt_impl!( ++ /// Specify the receiving timeout until reporting an error. ++ ReceiveTimeout, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_RCVTIMEO, ++ TimeVal ++); ++sockopt_impl!( ++ /// Specify the sending timeout until reporting an error. ++ SendTimeout, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_SNDTIMEO, ++ TimeVal ++); ++sockopt_impl!( ++ /// Set or get the broadcast flag. ++ Broadcast, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_BROADCAST, ++ bool ++); ++sockopt_impl!( ++ /// If this option is enabled, out-of-band data is directly placed into ++ /// the receive data stream. ++ OobInline, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_OOBINLINE, ++ bool ++); ++sockopt_impl!( ++ /// Get and clear the pending socket error. ++ SocketError, ++ GetOnly, ++ libc::SOL_SOCKET, ++ libc::SO_ERROR, ++ i32 ++); ++sockopt_impl!( ++ /// Set or get the don't route flag. ++ DontRoute, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_DONTROUTE, ++ bool ++); ++sockopt_impl!( ++ /// Enable sending of keep-alive messages on connection-oriented sockets. ++ KeepAlive, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_KEEPALIVE, ++ bool ++); ++#[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "macos", ++ target_os = "ios" ++))] ++sockopt_impl!( ++ /// Get the credentials of the peer process of a connected unix domain ++ /// socket. ++ LocalPeerCred, ++ GetOnly, ++ 0, ++ libc::LOCAL_PEERCRED, ++ super::XuCred ++); ++#[cfg(any(target_os = "android", target_os = "linux"))] ++sockopt_impl!( ++ /// Return the credentials of the foreign process connected to this socket. ++ PeerCredentials, ++ GetOnly, ++ libc::SOL_SOCKET, ++ libc::SO_PEERCRED, ++ super::UnixCredentials ++); ++#[cfg(any(target_os = "ios", target_os = "macos"))] ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Specify the amount of time, in seconds, that the connection must be idle ++ /// before keepalive probes (if enabled) are sent. ++ TcpKeepAlive, ++ Both, ++ libc::IPPROTO_TCP, ++ libc::TCP_KEEPALIVE, ++ u32 ++); ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "linux" ++))] ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// The time (in seconds) the connection needs to remain idle before TCP ++ /// starts sending keepalive probes ++ TcpKeepIdle, ++ Both, ++ libc::IPPROTO_TCP, ++ libc::TCP_KEEPIDLE, ++ u32 ++); ++cfg_if! { ++ if #[cfg(any(target_os = "android", target_os = "linux"))] { ++ sockopt_impl!( ++ /// The maximum segment size for outgoing TCP packets. ++ TcpMaxSeg, Both, libc::IPPROTO_TCP, libc::TCP_MAXSEG, u32); ++ } else { ++ sockopt_impl!( ++ /// The maximum segment size for outgoing TCP packets. ++ TcpMaxSeg, GetOnly, libc::IPPROTO_TCP, libc::TCP_MAXSEG, u32); + } + } +-sockopt_impl!(Both, IpMulticastTtl, libc::IPPROTO_IP, libc::IP_MULTICAST_TTL, u8); +-sockopt_impl!(Both, IpMulticastLoop, libc::IPPROTO_IP, libc::IP_MULTICAST_LOOP, bool); +-sockopt_impl!(Both, ReceiveTimeout, libc::SOL_SOCKET, libc::SO_RCVTIMEO, TimeVal); +-sockopt_impl!(Both, SendTimeout, libc::SOL_SOCKET, libc::SO_SNDTIMEO, TimeVal); +-sockopt_impl!(Both, Broadcast, libc::SOL_SOCKET, libc::SO_BROADCAST, bool); +-sockopt_impl!(Both, OobInline, libc::SOL_SOCKET, libc::SO_OOBINLINE, bool); +-sockopt_impl!(GetOnly, SocketError, libc::SOL_SOCKET, libc::SO_ERROR, i32); +-sockopt_impl!(Both, KeepAlive, libc::SOL_SOCKET, libc::SO_KEEPALIVE, bool); ++#[cfg(not(any(target_os = "openbsd", target_os = "haiku")))] ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// The maximum number of keepalive probes TCP should send before ++ /// dropping the connection. ++ TcpKeepCount, ++ Both, ++ libc::IPPROTO_TCP, ++ libc::TCP_KEEPCNT, ++ u32 ++); ++#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++sockopt_impl!( ++ #[allow(missing_docs)] ++ // Not documented by Linux! ++ TcpRepair, ++ Both, ++ libc::IPPROTO_TCP, ++ libc::TCP_REPAIR, ++ u32 ++); ++#[cfg(not(any(target_os = "openbsd", target_os = "haiku")))] ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// The time (in seconds) between individual keepalive probes. ++ TcpKeepInterval, ++ Both, ++ libc::IPPROTO_TCP, ++ libc::TCP_KEEPINTVL, ++ u32 ++); ++#[cfg(any(target_os = "fuchsia", target_os = "linux"))] ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Specifies the maximum amount of time in milliseconds that transmitted ++ /// data may remain unacknowledged before TCP will forcibly close the ++ /// corresponding connection ++ TcpUserTimeout, ++ Both, ++ libc::IPPROTO_TCP, ++ libc::TCP_USER_TIMEOUT, ++ u32 ++); ++sockopt_impl!( ++ /// Sets or gets the maximum socket receive buffer in bytes. ++ RcvBuf, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_RCVBUF, ++ usize ++); ++sockopt_impl!( ++ /// Sets or gets the maximum socket send buffer in bytes. ++ SndBuf, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_SNDBUF, ++ usize ++); ++#[cfg(any(target_os = "android", target_os = "linux"))] ++sockopt_impl!( ++ /// Using this socket option, a privileged (`CAP_NET_ADMIN`) process can ++ /// perform the same task as `SO_RCVBUF`, but the `rmem_max limit` can be ++ /// overridden. ++ RcvBufForce, ++ SetOnly, ++ libc::SOL_SOCKET, ++ libc::SO_RCVBUFFORCE, ++ usize ++); + #[cfg(any(target_os = "android", target_os = "linux"))] +-sockopt_impl!(GetOnly, PeerCredentials, libc::SOL_SOCKET, libc::SO_PEERCRED, super::UnixCredentials); +-#[cfg(any(target_os = "ios", +- target_os = "macos"))] +-sockopt_impl!(Both, TcpKeepAlive, libc::IPPROTO_TCP, libc::TCP_KEEPALIVE, u32); +-#[cfg(any(target_os = "android", +- target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "linux", +- target_os = "nacl"))] +-sockopt_impl!(Both, TcpKeepIdle, libc::IPPROTO_TCP, libc::TCP_KEEPIDLE, u32); +-sockopt_impl!(Both, RcvBuf, libc::SOL_SOCKET, libc::SO_RCVBUF, usize); +-sockopt_impl!(Both, SndBuf, libc::SOL_SOCKET, libc::SO_SNDBUF, usize); ++sockopt_impl!( ++ /// Using this socket option, a privileged (`CAP_NET_ADMIN`) process can ++ /// perform the same task as `SO_SNDBUF`, but the `wmem_max` limit can be ++ /// overridden. ++ SndBufForce, ++ SetOnly, ++ libc::SOL_SOCKET, ++ libc::SO_SNDBUFFORCE, ++ usize ++); ++sockopt_impl!( ++ /// Gets the socket type as an integer. ++ SockType, ++ GetOnly, ++ libc::SOL_SOCKET, ++ libc::SO_TYPE, ++ super::SockType, ++ GetStruct ++); ++sockopt_impl!( ++ /// Returns a value indicating whether or not this socket has been marked to ++ /// accept connections with `listen(2)`. ++ AcceptConn, ++ GetOnly, ++ libc::SOL_SOCKET, ++ libc::SO_ACCEPTCONN, ++ bool ++); + #[cfg(any(target_os = "android", target_os = "linux"))] +-sockopt_impl!(SetOnly, RcvBufForce, libc::SOL_SOCKET, libc::SO_RCVBUFFORCE, usize); ++sockopt_impl!( ++ /// Bind this socket to a particular device like “eth0”. ++ BindToDevice, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_BINDTODEVICE, ++ OsString<[u8; libc::IFNAMSIZ]> ++); + #[cfg(any(target_os = "android", target_os = "linux"))] +-sockopt_impl!(SetOnly, SndBufForce, libc::SOL_SOCKET, libc::SO_SNDBUFFORCE, usize); +-sockopt_impl!(GetOnly, SockType, libc::SOL_SOCKET, libc::SO_TYPE, super::SockType); +-sockopt_impl!(GetOnly, AcceptConn, libc::SOL_SOCKET, libc::SO_ACCEPTCONN, bool); ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ #[allow(missing_docs)] ++ // Not documented by Linux! ++ OriginalDst, ++ GetOnly, ++ libc::SOL_IP, ++ libc::SO_ORIGINAL_DST, ++ libc::sockaddr_in ++); + #[cfg(any(target_os = "android", target_os = "linux"))] +-sockopt_impl!(GetOnly, OriginalDst, libc::SOL_IP, libc::SO_ORIGINAL_DST, libc::sockaddr_in); +-sockopt_impl!(Both, ReceiveTimestamp, libc::SOL_SOCKET, libc::SO_TIMESTAMP, bool); ++sockopt_impl!( ++ #[allow(missing_docs)] ++ // Not documented by Linux! ++ Ip6tOriginalDst, ++ GetOnly, ++ libc::SOL_IPV6, ++ libc::IP6T_SO_ORIGINAL_DST, ++ libc::sockaddr_in6 ++); ++#[cfg(any(target_os = "linux"))] ++sockopt_impl!( ++ /// Specifies exact type of timestamping information collected by the kernel ++ /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html) ++ Timestamping, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_TIMESTAMPING, ++ super::TimestampingFlag ++); ++#[cfg(not(target_os = "haiku"))] ++sockopt_impl!( ++ /// Enable or disable the receiving of the `SO_TIMESTAMP` control message. ++ ReceiveTimestamp, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_TIMESTAMP, ++ bool ++); ++#[cfg(all(target_os = "linux"))] ++sockopt_impl!( ++ /// Enable or disable the receiving of the `SO_TIMESTAMPNS` control message. ++ ReceiveTimestampns, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_TIMESTAMPNS, ++ bool ++); + #[cfg(any(target_os = "android", target_os = "linux"))] +-sockopt_impl!(Both, IpTransparent, libc::SOL_IP, libc::IP_TRANSPARENT, bool); ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Setting this boolean option enables transparent proxying on this socket. ++ IpTransparent, ++ Both, ++ libc::SOL_IP, ++ libc::IP_TRANSPARENT, ++ bool ++); + #[cfg(target_os = "openbsd")] +-sockopt_impl!(Both, BindAny, libc::SOL_SOCKET, libc::SO_BINDANY, bool); ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Allows the socket to be bound to addresses which are not local to the ++ /// machine, so it can be used to make a transparent proxy. ++ BindAny, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_BINDANY, ++ bool ++); + #[cfg(target_os = "freebsd")] +-sockopt_impl!(Both, BindAny, libc::IPPROTO_IP, libc::IP_BINDANY, bool); ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Can `bind(2)` to any address, even one not bound to any available ++ /// network interface in the system. ++ BindAny, ++ Both, ++ libc::IPPROTO_IP, ++ libc::IP_BINDANY, ++ bool ++); + #[cfg(target_os = "linux")] +-sockopt_impl!(Both, Mark, libc::SOL_SOCKET, libc::SO_MARK, u32); ++sockopt_impl!( ++ /// Set the mark for each packet sent through this socket (similar to the ++ /// netfilter MARK target but socket-based). ++ Mark, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_MARK, ++ u32 ++); + #[cfg(any(target_os = "android", target_os = "linux"))] +-sockopt_impl!(Both, PassCred, libc::SOL_SOCKET, libc::SO_PASSCRED, bool); +-#[cfg(any(target_os = "freebsd", target_os = "linux"))] +-sockopt_impl!(Both, TcpCongestion, libc::IPPROTO_TCP, libc::TCP_CONGESTION, OsString<[u8; TCP_CA_NAME_MAX]>); ++sockopt_impl!( ++ /// Enable or disable the receiving of the `SCM_CREDENTIALS` control ++ /// message. ++ PassCred, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_PASSCRED, ++ bool ++); ++#[cfg(any(target_os = "freebsd", target_os = "linux"))] ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// This option allows the caller to set the TCP congestion control ++ /// algorithm to be used, on a per-socket basis. ++ TcpCongestion, ++ Both, ++ libc::IPPROTO_TCP, ++ libc::TCP_CONGESTION, ++ OsString<[u8; TCP_CA_NAME_MAX]> ++); + #[cfg(any( + target_os = "android", + target_os = "ios", +@@ -278,7 +780,17 @@ sockopt_impl!(Both, TcpCongestion, libc::IPPROTO_TCP, libc::TCP_CONGESTION, OsSt + target_os = "macos", + target_os = "netbsd", + ))] +-sockopt_impl!(Both, Ipv4PacketInfo, libc::IPPROTO_IP, libc::IP_PKTINFO, bool); ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Pass an `IP_PKTINFO` ancillary message that contains a pktinfo ++ /// structure that supplies some information about the incoming packet. ++ Ipv4PacketInfo, ++ Both, ++ libc::IPPROTO_IP, ++ libc::IP_PKTINFO, ++ bool ++); + #[cfg(any( + target_os = "android", + target_os = "freebsd", +@@ -288,7 +800,17 @@ sockopt_impl!(Both, Ipv4PacketInfo, libc::IPPROTO_IP, libc::IP_PKTINFO, bool); + target_os = "netbsd", + target_os = "openbsd", + ))] +-sockopt_impl!(Both, Ipv6RecvPacketInfo, libc::IPPROTO_IPV6, libc::IPV6_RECVPKTINFO, bool); ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// Set delivery of the `IPV6_PKTINFO` control message on incoming ++ /// datagrams. ++ Ipv6RecvPacketInfo, ++ Both, ++ libc::IPPROTO_IPV6, ++ libc::IPV6_RECVPKTINFO, ++ bool ++); + #[cfg(any( + target_os = "freebsd", + target_os = "ios", +@@ -296,7 +818,17 @@ sockopt_impl!(Both, Ipv6RecvPacketInfo, libc::IPPROTO_IPV6, libc::IPV6_RECVPKTIN + target_os = "netbsd", + target_os = "openbsd", + ))] +-sockopt_impl!(Both, Ipv4RecvIf, libc::IPPROTO_IP, libc::IP_RECVIF, bool); ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// The `recvmsg(2)` call returns a `struct sockaddr_dl` corresponding to ++ /// the interface on which the packet was received. ++ Ipv4RecvIf, ++ Both, ++ libc::IPPROTO_IP, ++ libc::IP_RECVIF, ++ bool ++); + #[cfg(any( + target_os = "freebsd", + target_os = "ios", +@@ -304,9 +836,168 @@ sockopt_impl!(Both, Ipv4RecvIf, libc::IPPROTO_IP, libc::IP_RECVIF, bool); + target_os = "netbsd", + target_os = "openbsd", + ))] +-sockopt_impl!(Both, Ipv4RecvDstAddr, libc::IPPROTO_IP, libc::IP_RECVDSTADDR, bool); +- +- ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// The `recvmsg(2)` call will return the destination IP address for a UDP ++ /// datagram. ++ Ipv4RecvDstAddr, ++ Both, ++ libc::IPPROTO_IP, ++ libc::IP_RECVDSTADDR, ++ bool ++); ++#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// The `recvmsg(2)` call will return the destination IP address for a UDP ++ /// datagram. ++ Ipv4OrigDstAddr, ++ Both, ++ libc::IPPROTO_IP, ++ libc::IP_ORIGDSTADDR, ++ bool ++); ++#[cfg(target_os = "linux")] ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ #[allow(missing_docs)] ++ // Not documented by Linux! ++ UdpGsoSegment, ++ Both, ++ libc::SOL_UDP, ++ libc::UDP_SEGMENT, ++ libc::c_int ++); ++#[cfg(target_os = "linux")] ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ #[allow(missing_docs)] ++ // Not documented by Linux! ++ UdpGroSegment, ++ Both, ++ libc::IPPROTO_UDP, ++ libc::UDP_GRO, ++ bool ++); ++#[cfg(target_os = "linux")] ++sockopt_impl!( ++ /// Configures the behavior of time-based transmission of packets, for use ++ /// with the `TxTime` control message. ++ TxTime, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_TXTIME, ++ libc::sock_txtime ++); ++#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++sockopt_impl!( ++ /// Indicates that an unsigned 32-bit value ancillary message (cmsg) should ++ /// be attached to received skbs indicating the number of packets dropped by ++ /// the socket since its creation. ++ RxqOvfl, ++ Both, ++ libc::SOL_SOCKET, ++ libc::SO_RXQ_OVFL, ++ libc::c_int ++); ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// The socket is restricted to sending and receiving IPv6 packets only. ++ Ipv6V6Only, ++ Both, ++ libc::IPPROTO_IPV6, ++ libc::IPV6_V6ONLY, ++ bool ++); ++#[cfg(any(target_os = "android", target_os = "linux"))] ++sockopt_impl!( ++ /// Enable extended reliable error message passing. ++ Ipv4RecvErr, ++ Both, ++ libc::IPPROTO_IP, ++ libc::IP_RECVERR, ++ bool ++); ++#[cfg(any(target_os = "android", target_os = "linux"))] ++sockopt_impl!( ++ /// Control receiving of asynchronous error options. ++ Ipv6RecvErr, ++ Both, ++ libc::IPPROTO_IPV6, ++ libc::IPV6_RECVERR, ++ bool ++); ++#[cfg(any(target_os = "android", target_os = "linux"))] ++sockopt_impl!( ++ /// Fetch the current system-estimated Path MTU. ++ IpMtu, ++ GetOnly, ++ libc::IPPROTO_IP, ++ libc::IP_MTU, ++ libc::c_int ++); ++#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] ++sockopt_impl!( ++ /// Set or retrieve the current time-to-live field that is used in every ++ /// packet sent from this socket. ++ Ipv4Ttl, ++ Both, ++ libc::IPPROTO_IP, ++ libc::IP_TTL, ++ libc::c_int ++); ++#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] ++sockopt_impl!( ++ /// Set the unicast hop limit for the socket. ++ Ipv6Ttl, ++ Both, ++ libc::IPPROTO_IPV6, ++ libc::IPV6_UNICAST_HOPS, ++ libc::c_int ++); ++#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] ++#[cfg(feature = "net")] ++sockopt_impl!( ++ #[cfg_attr(docsrs, doc(cfg(feature = "net")))] ++ /// The `recvmsg(2)` call will return the destination IP address for a UDP ++ /// datagram. ++ Ipv6OrigDstAddr, ++ Both, ++ libc::IPPROTO_IPV6, ++ libc::IPV6_ORIGDSTADDR, ++ bool ++); ++#[cfg(any(target_os = "ios", target_os = "macos"))] ++sockopt_impl!( ++ /// Set "don't fragment packet" flag on the IP packet. ++ IpDontFrag, ++ Both, ++ libc::IPPROTO_IP, ++ libc::IP_DONTFRAG, ++ bool ++); ++#[cfg(any( ++ target_os = "android", ++ target_os = "ios", ++ target_os = "linux", ++ target_os = "macos", ++))] ++sockopt_impl!( ++ /// Set "don't fragment packet" flag on the IPv6 packet. ++ Ipv6DontFrag, ++ Both, ++ libc::IPPROTO_IPV6, ++ libc::IPV6_DONTFRAG, ++ bool ++); ++ ++#[allow(missing_docs)] ++// Not documented by Linux! + #[cfg(any(target_os = "android", target_os = "linux"))] + #[derive(Copy, Clone, Debug)] + pub struct AlgSetAeadAuthSize; +@@ -319,16 +1010,20 @@ impl SetSockOpt for AlgSetAeadAuthSize { + + fn set(&self, fd: RawFd, val: &usize) -> Result<()> { + unsafe { +- let res = libc::setsockopt(fd, +- libc::SOL_ALG, +- libc::ALG_SET_AEAD_AUTHSIZE, +- ::std::ptr::null(), +- *val as libc::socklen_t); ++ let res = libc::setsockopt( ++ fd, ++ libc::SOL_ALG, ++ libc::ALG_SET_AEAD_AUTHSIZE, ++ ::std::ptr::null(), ++ *val as libc::socklen_t, ++ ); + Errno::result(res).map(drop) + } + } + } + ++#[allow(missing_docs)] ++// Not documented by Linux! + #[cfg(any(target_os = "android", target_os = "linux"))] + #[derive(Clone, Debug)] + pub struct AlgSetKey(::std::marker::PhantomData); +@@ -341,16 +1036,21 @@ impl Default for AlgSetKey { + } + + #[cfg(any(target_os = "android", target_os = "linux"))] +-impl SetSockOpt for AlgSetKey where T: AsRef<[u8]> + Clone { ++impl SetSockOpt for AlgSetKey ++where ++ T: AsRef<[u8]> + Clone, ++{ + type Val = T; + + fn set(&self, fd: RawFd, val: &T) -> Result<()> { + unsafe { +- let res = libc::setsockopt(fd, +- libc::SOL_ALG, +- libc::ALG_SET_KEY, +- val.as_ref().as_ptr() as *const _, +- val.as_ref().len() as libc::socklen_t); ++ let res = libc::setsockopt( ++ fd, ++ libc::SOL_ALG, ++ libc::ALG_SET_KEY, ++ val.as_ref().as_ptr() as *const _, ++ val.as_ref().len() as libc::socklen_t, ++ ); + Errno::result(res).map(drop) + } + } +@@ -363,21 +1063,21 @@ impl SetSockOpt for AlgSetKey where T: AsRef<[u8]> + Clone { + */ + + /// Helper trait that describes what is expected from a `GetSockOpt` getter. +-unsafe trait Get { +- /// Returns an empty value. +- unsafe fn blank() -> Self; ++trait Get { ++ /// Returns an uninitialized value. ++ fn uninit() -> Self; + /// Returns a pointer to the stored value. This pointer will be passed to the system's + /// `getsockopt` call (`man 3p getsockopt`, argument `option_value`). + fn ffi_ptr(&mut self) -> *mut c_void; + /// Returns length of the stored value. This pointer will be passed to the system's + /// `getsockopt` call (`man 3p getsockopt`, argument `option_len`). + fn ffi_len(&mut self) -> *mut socklen_t; +- /// Returns the stored value. +- unsafe fn unwrap(self) -> T; ++ /// Returns the hopefully initialized inner value. ++ unsafe fn assume_init(self) -> T; + } + + /// Helper trait that describes what is expected from a `SetSockOpt` setter. +-unsafe trait Set<'a, T> { ++trait Set<'a, T> { + /// Initialize the setter with a given value. + fn new(val: &'a T) -> Self; + /// Returns a pointer to the stored value. This pointer will be passed to the system's +@@ -391,28 +1091,32 @@ unsafe trait Set<'a, T> { + /// Getter for an arbitrary `struct`. + struct GetStruct { + len: socklen_t, +- val: T, ++ val: MaybeUninit, + } + +-unsafe impl Get for GetStruct { +- unsafe fn blank() -> Self { ++impl Get for GetStruct { ++ fn uninit() -> Self { + GetStruct { + len: mem::size_of::() as socklen_t, +- val: mem::zeroed(), ++ val: MaybeUninit::uninit(), + } + } + + fn ffi_ptr(&mut self) -> *mut c_void { +- &mut self.val as *mut T as *mut c_void ++ self.val.as_mut_ptr() as *mut c_void + } + + fn ffi_len(&mut self) -> *mut socklen_t { + &mut self.len + } + +- unsafe fn unwrap(self) -> T { +- assert_eq!(self.len as usize, mem::size_of::(), "invalid getsockopt implementation"); +- self.val ++ unsafe fn assume_init(self) -> T { ++ assert_eq!( ++ self.len as usize, ++ mem::size_of::(), ++ "invalid getsockopt implementation" ++ ); ++ self.val.assume_init() + } + } + +@@ -421,7 +1125,7 @@ struct SetStruct<'a, T: 'static> { + ptr: &'a T, + } + +-unsafe impl<'a, T> Set<'a, T> for SetStruct<'a, T> { ++impl<'a, T> Set<'a, T> for SetStruct<'a, T> { + fn new(ptr: &'a T) -> SetStruct<'a, T> { + SetStruct { ptr } + } +@@ -438,28 +1142,32 @@ unsafe impl<'a, T> Set<'a, T> for SetStruct<'a, T> { + /// Getter for a boolean value. + struct GetBool { + len: socklen_t, +- val: c_int, ++ val: MaybeUninit, + } + +-unsafe impl Get for GetBool { +- unsafe fn blank() -> Self { ++impl Get for GetBool { ++ fn uninit() -> Self { + GetBool { + len: mem::size_of::() as socklen_t, +- val: mem::zeroed(), ++ val: MaybeUninit::uninit(), + } + } + + fn ffi_ptr(&mut self) -> *mut c_void { +- &mut self.val as *mut c_int as *mut c_void ++ self.val.as_mut_ptr() as *mut c_void + } + + fn ffi_len(&mut self) -> *mut socklen_t { + &mut self.len + } + +- unsafe fn unwrap(self) -> bool { +- assert_eq!(self.len as usize, mem::size_of::(), "invalid getsockopt implementation"); +- self.val != 0 ++ unsafe fn assume_init(self) -> bool { ++ assert_eq!( ++ self.len as usize, ++ mem::size_of::(), ++ "invalid getsockopt implementation" ++ ); ++ self.val.assume_init() != 0 + } + } + +@@ -468,9 +1176,11 @@ struct SetBool { + val: c_int, + } + +-unsafe impl<'a> Set<'a, bool> for SetBool { ++impl<'a> Set<'a, bool> for SetBool { + fn new(val: &'a bool) -> SetBool { +- SetBool { val: if *val { 1 } else { 0 } } ++ SetBool { ++ val: i32::from(*val), ++ } + } + + fn ffi_ptr(&self) -> *const c_void { +@@ -485,28 +1195,32 @@ unsafe impl<'a> Set<'a, bool> for SetBool { + /// Getter for an `u8` value. + struct GetU8 { + len: socklen_t, +- val: u8, ++ val: MaybeUninit, + } + +-unsafe impl Get for GetU8 { +- unsafe fn blank() -> Self { ++impl Get for GetU8 { ++ fn uninit() -> Self { + GetU8 { + len: mem::size_of::() as socklen_t, +- val: mem::zeroed(), ++ val: MaybeUninit::uninit(), + } + } + + fn ffi_ptr(&mut self) -> *mut c_void { +- &mut self.val as *mut u8 as *mut c_void ++ self.val.as_mut_ptr() as *mut c_void + } + + fn ffi_len(&mut self) -> *mut socklen_t { + &mut self.len + } + +- unsafe fn unwrap(self) -> u8 { +- assert_eq!(self.len as usize, mem::size_of::(), "invalid getsockopt implementation"); +- self.val as u8 ++ unsafe fn assume_init(self) -> u8 { ++ assert_eq!( ++ self.len as usize, ++ mem::size_of::(), ++ "invalid getsockopt implementation" ++ ); ++ self.val.assume_init() + } + } + +@@ -515,9 +1229,9 @@ struct SetU8 { + val: u8, + } + +-unsafe impl<'a> Set<'a, u8> for SetU8 { ++impl<'a> Set<'a, u8> for SetU8 { + fn new(val: &'a u8) -> SetU8 { +- SetU8 { val: *val as u8 } ++ SetU8 { val: *val } + } + + fn ffi_ptr(&self) -> *const c_void { +@@ -532,28 +1246,32 @@ unsafe impl<'a> Set<'a, u8> for SetU8 { + /// Getter for an `usize` value. + struct GetUsize { + len: socklen_t, +- val: c_int, ++ val: MaybeUninit, + } + +-unsafe impl Get for GetUsize { +- unsafe fn blank() -> Self { ++impl Get for GetUsize { ++ fn uninit() -> Self { + GetUsize { + len: mem::size_of::() as socklen_t, +- val: mem::zeroed(), ++ val: MaybeUninit::uninit(), + } + } + + fn ffi_ptr(&mut self) -> *mut c_void { +- &mut self.val as *mut c_int as *mut c_void ++ self.val.as_mut_ptr() as *mut c_void + } + + fn ffi_len(&mut self) -> *mut socklen_t { + &mut self.len + } + +- unsafe fn unwrap(self) -> usize { +- assert_eq!(self.len as usize, mem::size_of::(), "invalid getsockopt implementation"); +- self.val as usize ++ unsafe fn assume_init(self) -> usize { ++ assert_eq!( ++ self.len as usize, ++ mem::size_of::(), ++ "invalid getsockopt implementation" ++ ); ++ self.val.assume_init() as usize + } + } + +@@ -562,7 +1280,7 @@ struct SetUsize { + val: c_int, + } + +-unsafe impl<'a> Set<'a, usize> for SetUsize { ++impl<'a> Set<'a, usize> for SetUsize { + fn new(val: &'a usize) -> SetUsize { + SetUsize { val: *val as c_int } + } +@@ -579,27 +1297,29 @@ unsafe impl<'a> Set<'a, usize> for SetUsize { + /// Getter for a `OsString` value. + struct GetOsString> { + len: socklen_t, +- val: T, ++ val: MaybeUninit, + } + +-unsafe impl> Get for GetOsString { +- unsafe fn blank() -> Self { ++impl> Get for GetOsString { ++ fn uninit() -> Self { + GetOsString { + len: mem::size_of::() as socklen_t, +- val: mem::zeroed(), ++ val: MaybeUninit::uninit(), + } + } + + fn ffi_ptr(&mut self) -> *mut c_void { +- &mut self.val as *mut T as *mut c_void ++ self.val.as_mut_ptr() as *mut c_void + } + + fn ffi_len(&mut self) -> *mut socklen_t { + &mut self.len + } + +- unsafe fn unwrap(mut self) -> OsString { +- OsStr::from_bytes(self.val.as_mut()).to_owned() ++ unsafe fn assume_init(self) -> OsString { ++ let len = self.len as usize; ++ let mut v = self.val.assume_init(); ++ OsStr::from_bytes(&v.as_mut()[0..len]).to_owned() + } + } + +@@ -608,9 +1328,11 @@ struct SetOsString<'a> { + val: &'a OsStr, + } + +-unsafe impl<'a> Set<'a, OsString> for SetOsString<'a> { ++impl<'a> Set<'a, OsString> for SetOsString<'a> { + fn new(val: &'a OsString) -> SetOsString { +- SetOsString { val: val.as_os_str() } ++ SetOsString { ++ val: val.as_os_str(), ++ } + } + + fn ffi_ptr(&self) -> *const c_void { +@@ -622,7 +1344,6 @@ unsafe impl<'a> Set<'a, OsString> for SetOsString<'a> { + } + } + +- + #[cfg(test)] + mod test { + #[cfg(any(target_os = "android", target_os = "linux"))] +@@ -630,19 +1351,31 @@ mod test { + fn can_get_peercred_on_unix_socket() { + use super::super::*; + +- let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap(); ++ let (a, b) = socketpair( ++ AddressFamily::Unix, ++ SockType::Stream, ++ None, ++ SockFlag::empty(), ++ ) ++ .unwrap(); + let a_cred = getsockopt(a, super::PeerCredentials).unwrap(); + let b_cred = getsockopt(b, super::PeerCredentials).unwrap(); + assert_eq!(a_cred, b_cred); +- assert!(a_cred.pid() != 0); ++ assert_ne!(a_cred.pid(), 0); + } + + #[test] + fn is_socket_type_unix() { + use super::super::*; +- use ::unistd::close; +- +- let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap(); ++ use crate::unistd::close; ++ ++ let (a, b) = socketpair( ++ AddressFamily::Unix, ++ SockType::Stream, ++ None, ++ SockFlag::empty(), ++ ) ++ .unwrap(); + let a_type = getsockopt(a, super::SockType).unwrap(); + assert_eq!(a_type, SockType::Stream); + close(a).unwrap(); +@@ -652,23 +1385,33 @@ mod test { + #[test] + fn is_socket_type_dgram() { + use super::super::*; +- use ::unistd::close; +- +- let s = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), None).unwrap(); ++ use crate::unistd::close; ++ ++ let s = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); + let s_type = getsockopt(s, super::SockType).unwrap(); + assert_eq!(s_type, SockType::Datagram); + close(s).unwrap(); + } + +- #[cfg(any(target_os = "freebsd", +- target_os = "linux", +- target_os = "nacl"))] ++ #[cfg(any(target_os = "freebsd", target_os = "linux"))] + #[test] + fn can_get_listen_on_tcp_socket() { + use super::super::*; +- use ::unistd::close; +- +- let s = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), None).unwrap(); ++ use crate::unistd::close; ++ ++ let s = socket( ++ AddressFamily::Inet, ++ SockType::Stream, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); + let s_listening = getsockopt(s, super::AcceptConn).unwrap(); + assert!(!s_listening); + listen(s, 10).unwrap(); +@@ -676,5 +1419,4 @@ mod test { + assert!(s_listening2); + close(s).unwrap(); + } +- + } +diff --git a/vendor/nix/src/sys/stat.rs b/vendor/nix/src/sys/stat.rs +index 2958225..78203bf 100644 +--- a/vendor/nix/src/sys/stat.rs ++++ b/vendor/nix/src/sys/stat.rs +@@ -1,15 +1,23 @@ +-pub use libc::{dev_t, mode_t}; ++#[cfg(any(target_os = "macos", target_os = "ios", target_os = "openbsd"))] ++pub use libc::c_uint; ++#[cfg(any( ++ target_os = "netbsd", ++ target_os = "freebsd", ++ target_os = "dragonfly" ++))] ++pub use libc::c_ulong; + pub use libc::stat as FileStat; ++pub use libc::{dev_t, mode_t}; + +-use {Result, NixPath}; +-use errno::Errno; +-use fcntl::{AtFlags, at_rawfd}; +-use libc; ++#[cfg(not(target_os = "redox"))] ++use crate::fcntl::{at_rawfd, AtFlags}; ++use crate::sys::time::{TimeSpec, TimeVal}; ++use crate::{errno::Errno, NixPath, Result}; + use std::mem; + use std::os::unix::io::RawFd; +-use sys::time::{TimeSpec, TimeVal}; + + libc_bitflags!( ++ /// "File type" flags for `mknod` and related functions. + pub struct SFlag: mode_t { + S_IFIFO; + S_IFCHR; +@@ -23,53 +31,204 @@ libc_bitflags!( + ); + + libc_bitflags! { ++ /// "File mode / permissions" flags. + pub struct Mode: mode_t { ++ /// Read, write and execute for owner. + S_IRWXU; ++ /// Read for owner. + S_IRUSR; ++ /// Write for owner. + S_IWUSR; ++ /// Execute for owner. + S_IXUSR; ++ /// Read write and execute for group. + S_IRWXG; ++ /// Read fr group. + S_IRGRP; ++ /// Write for group. + S_IWGRP; ++ /// Execute for group. + S_IXGRP; ++ /// Read, write and execute for other. + S_IRWXO; ++ /// Read for other. + S_IROTH; ++ /// Write for other. + S_IWOTH; ++ /// Execute for other. + S_IXOTH; ++ /// Set user id on execution. + S_ISUID as mode_t; ++ /// Set group id on execution. + S_ISGID as mode_t; + S_ISVTX as mode_t; + } + } + +-pub fn mknod(path: &P, kind: SFlag, perm: Mode, dev: dev_t) -> Result<()> { +- let res = path.with_nix_path(|cstr| { +- unsafe { +- libc::mknod(cstr.as_ptr(), kind.bits | perm.bits() as mode_t, dev) +- } ++#[cfg(any(target_os = "macos", target_os = "ios", target_os = "openbsd"))] ++pub type type_of_file_flag = c_uint; ++#[cfg(any( ++ target_os = "netbsd", ++ target_os = "freebsd", ++ target_os = "dragonfly" ++))] ++pub type type_of_file_flag = c_ulong; ++ ++#[cfg(any( ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "macos", ++ target_os = "ios" ++))] ++libc_bitflags! { ++ /// File flags. ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub struct FileFlag: type_of_file_flag { ++ /// The file may only be appended to. ++ SF_APPEND; ++ /// The file has been archived. ++ SF_ARCHIVED; ++ #[cfg(any(target_os = "dragonfly"))] ++ SF_CACHE; ++ /// The file may not be changed. ++ SF_IMMUTABLE; ++ /// Indicates a WAPBL journal file. ++ #[cfg(any(target_os = "netbsd"))] ++ SF_LOG; ++ /// Do not retain history for file ++ #[cfg(any(target_os = "dragonfly"))] ++ SF_NOHISTORY; ++ /// The file may not be renamed or deleted. ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ SF_NOUNLINK; ++ /// Mask of superuser changeable flags ++ SF_SETTABLE; ++ /// Snapshot is invalid. ++ #[cfg(any(target_os = "netbsd"))] ++ SF_SNAPINVAL; ++ /// The file is a snapshot file. ++ #[cfg(any(target_os = "netbsd", target_os = "freebsd"))] ++ SF_SNAPSHOT; ++ #[cfg(any(target_os = "dragonfly"))] ++ SF_XLINK; ++ /// The file may only be appended to. ++ UF_APPEND; ++ /// The file needs to be archived. ++ #[cfg(any(target_os = "freebsd"))] ++ UF_ARCHIVE; ++ #[cfg(any(target_os = "dragonfly"))] ++ UF_CACHE; ++ /// File is compressed at the file system level. ++ #[cfg(any(target_os = "macos", target_os = "ios"))] ++ UF_COMPRESSED; ++ /// The file may be hidden from directory listings at the application's ++ /// discretion. ++ #[cfg(any( ++ target_os = "freebsd", ++ target_os = "macos", ++ target_os = "ios", ++ ))] ++ UF_HIDDEN; ++ /// The file may not be changed. ++ UF_IMMUTABLE; ++ /// Do not dump the file. ++ UF_NODUMP; ++ #[cfg(any(target_os = "dragonfly"))] ++ UF_NOHISTORY; ++ /// The file may not be renamed or deleted. ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ UF_NOUNLINK; ++ /// The file is offline, or has the Windows and CIFS ++ /// `FILE_ATTRIBUTE_OFFLINE` attribute. ++ #[cfg(any(target_os = "freebsd"))] ++ UF_OFFLINE; ++ /// The directory is opaque when viewed through a union stack. ++ UF_OPAQUE; ++ /// The file is read only, and may not be written or appended. ++ #[cfg(any(target_os = "freebsd"))] ++ UF_READONLY; ++ /// The file contains a Windows reparse point. ++ #[cfg(any(target_os = "freebsd"))] ++ UF_REPARSE; ++ /// Mask of owner changeable flags. ++ UF_SETTABLE; ++ /// The file has the Windows `FILE_ATTRIBUTE_SPARSE_FILE` attribute. ++ #[cfg(any(target_os = "freebsd"))] ++ UF_SPARSE; ++ /// The file has the DOS, Windows and CIFS `FILE_ATTRIBUTE_SYSTEM` ++ /// attribute. ++ #[cfg(any(target_os = "freebsd"))] ++ UF_SYSTEM; ++ /// File renames and deletes are tracked. ++ #[cfg(any(target_os = "macos", target_os = "ios"))] ++ UF_TRACKED; ++ #[cfg(any(target_os = "dragonfly"))] ++ UF_XLINK; ++ } ++} ++ ++/// Create a special or ordinary file, by pathname. ++pub fn mknod( ++ path: &P, ++ kind: SFlag, ++ perm: Mode, ++ dev: dev_t, ++) -> Result<()> { ++ let res = path.with_nix_path(|cstr| unsafe { ++ libc::mknod(cstr.as_ptr(), kind.bits | perm.bits() as mode_t, dev) ++ })?; ++ ++ Errno::result(res).map(drop) ++} ++ ++/// Create a special or ordinary file, relative to a given directory. ++#[cfg(not(any( ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "redox", ++ target_os = "haiku" ++)))] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++pub fn mknodat( ++ dirfd: RawFd, ++ path: &P, ++ kind: SFlag, ++ perm: Mode, ++ dev: dev_t, ++) -> Result<()> { ++ let res = path.with_nix_path(|cstr| unsafe { ++ libc::mknodat( ++ dirfd, ++ cstr.as_ptr(), ++ kind.bits | perm.bits() as mode_t, ++ dev, ++ ) + })?; + + Errno::result(res).map(drop) + } + + #[cfg(target_os = "linux")] +-pub fn major(dev: dev_t) -> u64 { +- ((dev >> 32) & 0xffff_f000) | +- ((dev >> 8) & 0x0000_0fff) ++#[cfg_attr(docsrs, doc(cfg(all())))] ++pub const fn major(dev: dev_t) -> u64 { ++ ((dev >> 32) & 0xffff_f000) | ((dev >> 8) & 0x0000_0fff) + } + + #[cfg(target_os = "linux")] +-pub fn minor(dev: dev_t) -> u64 { +- ((dev >> 12) & 0xffff_ff00) | +- ((dev ) & 0x0000_00ff) ++#[cfg_attr(docsrs, doc(cfg(all())))] ++pub const fn minor(dev: dev_t) -> u64 { ++ ((dev >> 12) & 0xffff_ff00) | ((dev) & 0x0000_00ff) + } + + #[cfg(target_os = "linux")] +-pub fn makedev(major: u64, minor: u64) -> dev_t { +- ((major & 0xffff_f000) << 32) | +- ((major & 0x0000_0fff) << 8) | +- ((minor & 0xffff_ff00) << 12) | +- (minor & 0x0000_00ff) ++#[cfg_attr(docsrs, doc(cfg(all())))] ++pub const fn makedev(major: u64, minor: u64) -> dev_t { ++ ((major & 0xffff_f000) << 32) ++ | ((major & 0x0000_0fff) << 8) ++ | ((minor & 0xffff_ff00) << 12) ++ | (minor & 0x0000_00ff) + } + + pub fn umask(mode: Mode) -> Mode { +@@ -79,28 +238,24 @@ pub fn umask(mode: Mode) -> Mode { + + pub fn stat(path: &P) -> Result { + let mut dst = mem::MaybeUninit::uninit(); +- let res = path.with_nix_path(|cstr| { +- unsafe { +- libc::stat(cstr.as_ptr(), dst.as_mut_ptr()) +- } ++ let res = path.with_nix_path(|cstr| unsafe { ++ libc::stat(cstr.as_ptr(), dst.as_mut_ptr()) + })?; + + Errno::result(res)?; + +- Ok(unsafe{dst.assume_init()}) ++ Ok(unsafe { dst.assume_init() }) + } + + pub fn lstat(path: &P) -> Result { + let mut dst = mem::MaybeUninit::uninit(); +- let res = path.with_nix_path(|cstr| { +- unsafe { +- libc::lstat(cstr.as_ptr(), dst.as_mut_ptr()) +- } ++ let res = path.with_nix_path(|cstr| unsafe { ++ libc::lstat(cstr.as_ptr(), dst.as_mut_ptr()) + })?; + + Errno::result(res)?; + +- Ok(unsafe{dst.assume_init()}) ++ Ok(unsafe { dst.assume_init() }) + } + + pub fn fstat(fd: RawFd) -> Result { +@@ -109,25 +264,36 @@ pub fn fstat(fd: RawFd) -> Result { + + Errno::result(res)?; + +- Ok(unsafe{dst.assume_init()}) ++ Ok(unsafe { dst.assume_init() }) + } + +-pub fn fstatat(dirfd: RawFd, pathname: &P, f: AtFlags) -> Result { ++#[cfg(not(target_os = "redox"))] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++pub fn fstatat( ++ dirfd: RawFd, ++ pathname: &P, ++ f: AtFlags, ++) -> Result { + let mut dst = mem::MaybeUninit::uninit(); +- let res = pathname.with_nix_path(|cstr| { +- unsafe { libc::fstatat(dirfd, cstr.as_ptr(), dst.as_mut_ptr(), f.bits() as libc::c_int) } ++ let res = pathname.with_nix_path(|cstr| unsafe { ++ libc::fstatat( ++ dirfd, ++ cstr.as_ptr(), ++ dst.as_mut_ptr(), ++ f.bits() as libc::c_int, ++ ) + })?; + + Errno::result(res)?; + +- Ok(unsafe{dst.assume_init()}) ++ Ok(unsafe { dst.assume_init() }) + } + + /// Change the file permission bits of the file specified by a file descriptor. + /// + /// # References + /// +-/// [fchmod(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmod.html). ++/// [fchmod(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmod.html). + pub fn fchmod(fd: RawFd, mode: Mode) -> Result<()> { + let res = unsafe { libc::fchmod(fd, mode.bits() as mode_t) }; + +@@ -150,24 +316,25 @@ pub enum FchmodatFlags { + /// If `flag` is `FchmodatFlags::NoFollowSymlink` and `path` names a symbolic link, + /// then the mode of the symbolic link is changed. + /// +-/// `fchmod(None, path, mode, FchmodatFlags::FollowSymlink)` is identical to ++/// `fchmodat(None, path, mode, FchmodatFlags::FollowSymlink)` is identical to + /// a call `libc::chmod(path, mode)`. That's why `chmod` is unimplemented + /// in the `nix` crate. + /// + /// # References + /// +-/// [fchmodat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmodat.html). ++/// [fchmodat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmodat.html). ++#[cfg(not(target_os = "redox"))] ++#[cfg_attr(docsrs, doc(cfg(all())))] + pub fn fchmodat( + dirfd: Option, + path: &P, + mode: Mode, + flag: FchmodatFlags, + ) -> Result<()> { +- let atflag = +- match flag { +- FchmodatFlags::FollowSymlink => AtFlags::empty(), +- FchmodatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW, +- }; ++ let atflag = match flag { ++ FchmodatFlags::FollowSymlink => AtFlags::empty(), ++ FchmodatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW, ++ }; + let res = path.with_nix_path(|cstr| unsafe { + libc::fchmodat( + at_rawfd(dirfd), +@@ -189,8 +356,12 @@ pub fn fchmodat( + /// + /// # References + /// +-/// [utimes(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/utimes.html). +-pub fn utimes(path: &P, atime: &TimeVal, mtime: &TimeVal) -> Result<()> { ++/// [utimes(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/utimes.html). ++pub fn utimes( ++ path: &P, ++ atime: &TimeVal, ++ mtime: &TimeVal, ++) -> Result<()> { + let times: [libc::timeval; 2] = [*atime.as_ref(), *mtime.as_ref()]; + let res = path.with_nix_path(|cstr| unsafe { + libc::utimes(cstr.as_ptr(), ×[0]) +@@ -208,14 +379,21 @@ pub fn utimes(path: &P, atime: &TimeVal, mtime: &TimeVal) - + /// + /// # References + /// +-/// [lutimes(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/lutimes.html). +-#[cfg(any(target_os = "linux", +- target_os = "haiku", +- target_os = "ios", +- target_os = "macos", +- target_os = "freebsd", +- target_os = "netbsd"))] +-pub fn lutimes(path: &P, atime: &TimeVal, mtime: &TimeVal) -> Result<()> { ++/// [lutimes(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/lutimes.html). ++#[cfg(any( ++ target_os = "linux", ++ target_os = "haiku", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "netbsd" ++))] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++pub fn lutimes( ++ path: &P, ++ atime: &TimeVal, ++ mtime: &TimeVal, ++) -> Result<()> { + let times: [libc::timeval; 2] = [*atime.as_ref(), *mtime.as_ref()]; + let res = path.with_nix_path(|cstr| unsafe { + libc::lutimes(cstr.as_ptr(), ×[0]) +@@ -228,7 +406,7 @@ pub fn lutimes(path: &P, atime: &TimeVal, mtime: &TimeVal) + /// + /// # References + /// +-/// [futimens(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html). ++/// [futimens(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html). + #[inline] + pub fn futimens(fd: RawFd, atime: &TimeSpec, mtime: &TimeSpec) -> Result<()> { + let times: [libc::timespec; 2] = [*atime.as_ref(), *mtime.as_ref()]; +@@ -238,6 +416,7 @@ pub fn futimens(fd: RawFd, atime: &TimeSpec, mtime: &TimeSpec) -> Result<()> { + } + + /// Flags for `utimensat` function. ++// TODO: replace with fcntl::AtFlags + #[derive(Clone, Copy, Debug)] + pub enum UtimensatFlags { + FollowSymlink, +@@ -259,19 +438,20 @@ pub enum UtimensatFlags { + /// + /// # References + /// +-/// [utimensat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/utimens.html). ++/// [utimensat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/utimens.html). ++#[cfg(not(target_os = "redox"))] ++#[cfg_attr(docsrs, doc(cfg(all())))] + pub fn utimensat( + dirfd: Option, + path: &P, + atime: &TimeSpec, + mtime: &TimeSpec, +- flag: UtimensatFlags ++ flag: UtimensatFlags, + ) -> Result<()> { +- let atflag = +- match flag { +- UtimensatFlags::FollowSymlink => AtFlags::empty(), +- UtimensatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW, +- }; ++ let atflag = match flag { ++ UtimensatFlags::FollowSymlink => AtFlags::empty(), ++ UtimensatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW, ++ }; + let times: [libc::timespec; 2] = [*atime.as_ref(), *mtime.as_ref()]; + let res = path.with_nix_path(|cstr| unsafe { + libc::utimensat( +@@ -285,9 +465,15 @@ pub fn utimensat( + Errno::result(res).map(drop) + } + +-pub fn mkdirat(fd: RawFd, path: &P, mode: Mode) -> Result<()> { +- let res = path.with_nix_path(|cstr| { +- unsafe { libc::mkdirat(fd, cstr.as_ptr(), mode.bits() as mode_t) } ++#[cfg(not(target_os = "redox"))] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++pub fn mkdirat( ++ fd: RawFd, ++ path: &P, ++ mode: Mode, ++) -> Result<()> { ++ let res = path.with_nix_path(|cstr| unsafe { ++ libc::mkdirat(fd, cstr.as_ptr(), mode.bits() as mode_t) + })?; + + Errno::result(res).map(drop) +diff --git a/vendor/nix/src/sys/statfs.rs b/vendor/nix/src/sys/statfs.rs +index f463400..9be8ca6 100644 +--- a/vendor/nix/src/sys/statfs.rs ++++ b/vendor/nix/src/sys/statfs.rs +@@ -1,105 +1,318 @@ ++//! Get filesystem statistics, non-portably ++//! ++//! See [`statvfs`](crate::sys::statvfs) for a portable alternative. ++#[cfg(not(any(target_os = "linux", target_os = "android")))] ++use std::ffi::CStr; + use std::fmt::{self, Debug}; + use std::mem; + use std::os::unix::io::AsRawFd; +-#[cfg(not(any(target_os = "linux", target_os = "android")))] +-use std::ffi::CStr; + +-use libc; +- +-use {NixPath, Result}; +-use errno::Errno; ++use cfg_if::cfg_if; + ++#[cfg(all( ++ feature = "mount", ++ any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ) ++))] ++use crate::mount::MntFlags; ++#[cfg(target_os = "linux")] ++use crate::sys::statvfs::FsFlags; ++use crate::{errno::Errno, NixPath, Result}; ++ ++/// Identifies a mounted file system + #[cfg(target_os = "android")] ++#[cfg_attr(docsrs, doc(cfg(all())))] + pub type fsid_t = libc::__fsid_t; ++/// Identifies a mounted file system + #[cfg(not(target_os = "android"))] ++#[cfg_attr(docsrs, doc(cfg(all())))] + pub type fsid_t = libc::fsid_t; + ++cfg_if! { ++ if #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] { ++ type type_of_statfs = libc::statfs64; ++ const LIBC_FSTATFS: unsafe extern fn ++ (fd: libc::c_int, buf: *mut type_of_statfs) -> libc::c_int ++ = libc::fstatfs64; ++ const LIBC_STATFS: unsafe extern fn ++ (path: *const libc::c_char, buf: *mut type_of_statfs) -> libc::c_int ++ = libc::statfs64; ++ } else { ++ type type_of_statfs = libc::statfs; ++ const LIBC_FSTATFS: unsafe extern fn ++ (fd: libc::c_int, buf: *mut type_of_statfs) -> libc::c_int ++ = libc::fstatfs; ++ const LIBC_STATFS: unsafe extern fn ++ (path: *const libc::c_char, buf: *mut type_of_statfs) -> libc::c_int ++ = libc::statfs; ++ } ++} ++ ++/// Describes a mounted file system + #[derive(Clone, Copy)] + #[repr(transparent)] +-pub struct Statfs(libc::statfs); ++pub struct Statfs(type_of_statfs); + + #[cfg(target_os = "freebsd")] +-#[derive(Eq, Copy, Clone, PartialEq, Debug)] +-pub struct FsType(u32); ++type fs_type_t = u32; + #[cfg(target_os = "android")] +-#[derive(Eq, Copy, Clone, PartialEq, Debug)] +-pub struct FsType(libc::c_ulong); ++type fs_type_t = libc::c_ulong; + #[cfg(all(target_os = "linux", target_arch = "s390x"))] +-#[derive(Eq, Copy, Clone, PartialEq, Debug)] +-pub struct FsType(u32); ++type fs_type_t = libc::c_uint; + #[cfg(all(target_os = "linux", target_env = "musl"))] ++type fs_type_t = libc::c_ulong; ++#[cfg(all(target_os = "linux", target_env = "uclibc"))] ++type fs_type_t = libc::c_int; ++#[cfg(all( ++ target_os = "linux", ++ not(any( ++ target_arch = "s390x", ++ target_env = "musl", ++ target_env = "uclibc" ++ )) ++))] ++type fs_type_t = libc::__fsword_t; ++ ++/// Describes the file system type as known by the operating system. ++#[cfg(any( ++ target_os = "freebsd", ++ target_os = "android", ++ all(target_os = "linux", target_arch = "s390x"), ++ all(target_os = "linux", target_env = "musl"), ++ all( ++ target_os = "linux", ++ not(any(target_arch = "s390x", target_env = "musl")) ++ ), ++))] + #[derive(Eq, Copy, Clone, PartialEq, Debug)] +-pub struct FsType(libc::c_ulong); +-#[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))] +-#[derive(Eq, Copy, Clone, PartialEq, Debug)] +-pub struct FsType(libc::c_long); +- +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const ADFS_SUPER_MAGIC: FsType = FsType(libc::ADFS_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const AFFS_SUPER_MAGIC: FsType = FsType(libc::AFFS_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const CODA_SUPER_MAGIC: FsType = FsType(libc::CODA_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const CRAMFS_MAGIC: FsType = FsType(libc::CRAMFS_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const EFS_SUPER_MAGIC: FsType = FsType(libc::EFS_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const EXT2_SUPER_MAGIC: FsType = FsType(libc::EXT2_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const EXT3_SUPER_MAGIC: FsType = FsType(libc::EXT3_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const EXT4_SUPER_MAGIC: FsType = FsType(libc::EXT4_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const HPFS_SUPER_MAGIC: FsType = FsType(libc::HPFS_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const HUGETLBFS_MAGIC: FsType = FsType(libc::HUGETLBFS_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const ISOFS_SUPER_MAGIC: FsType = FsType(libc::ISOFS_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const JFFS2_SUPER_MAGIC: FsType = FsType(libc::JFFS2_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const MINIX_SUPER_MAGIC: FsType = FsType(libc::MINIX_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const MINIX_SUPER_MAGIC2: FsType = FsType(libc::MINIX_SUPER_MAGIC2); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const MINIX2_SUPER_MAGIC: FsType = FsType(libc::MINIX2_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const MINIX2_SUPER_MAGIC2: FsType = FsType(libc::MINIX2_SUPER_MAGIC2); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const MSDOS_SUPER_MAGIC: FsType = FsType(libc::MSDOS_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const NCP_SUPER_MAGIC: FsType = FsType(libc::NCP_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const NFS_SUPER_MAGIC: FsType = FsType(libc::NFS_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const OPENPROM_SUPER_MAGIC: FsType = FsType(libc::OPENPROM_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const PROC_SUPER_MAGIC: FsType = FsType(libc::PROC_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const QNX4_SUPER_MAGIC: FsType = FsType(libc::QNX4_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const REISERFS_SUPER_MAGIC: FsType = FsType(libc::REISERFS_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const SMB_SUPER_MAGIC: FsType = FsType(libc::SMB_SUPER_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const TMPFS_MAGIC: FsType = FsType(libc::TMPFS_MAGIC); +-#[cfg(all(target_os = "linux", not(target_env = "musl"), not(target_arch = "s390x")))] +-pub const USBDEVICE_SUPER_MAGIC: FsType = FsType(libc::USBDEVICE_SUPER_MAGIC); ++pub struct FsType(pub fs_type_t); ++ ++// These constants are defined without documentation in the Linux headers, so we ++// can't very well document them here. ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const ADFS_SUPER_MAGIC: FsType = ++ FsType(libc::ADFS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const AFFS_SUPER_MAGIC: FsType = ++ FsType(libc::AFFS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const AFS_SUPER_MAGIC: FsType = FsType(libc::AFS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const AUTOFS_SUPER_MAGIC: FsType = ++ FsType(libc::AUTOFS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const BPF_FS_MAGIC: FsType = FsType(libc::BPF_FS_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const BTRFS_SUPER_MAGIC: FsType = ++ FsType(libc::BTRFS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const CGROUP2_SUPER_MAGIC: FsType = ++ FsType(libc::CGROUP2_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const CGROUP_SUPER_MAGIC: FsType = ++ FsType(libc::CGROUP_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const CODA_SUPER_MAGIC: FsType = ++ FsType(libc::CODA_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const CRAMFS_MAGIC: FsType = FsType(libc::CRAMFS_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const DEBUGFS_MAGIC: FsType = FsType(libc::DEBUGFS_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const DEVPTS_SUPER_MAGIC: FsType = ++ FsType(libc::DEVPTS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const ECRYPTFS_SUPER_MAGIC: FsType = ++ FsType(libc::ECRYPTFS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const EFS_SUPER_MAGIC: FsType = FsType(libc::EFS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const EXT2_SUPER_MAGIC: FsType = ++ FsType(libc::EXT2_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const EXT3_SUPER_MAGIC: FsType = ++ FsType(libc::EXT3_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const EXT4_SUPER_MAGIC: FsType = ++ FsType(libc::EXT4_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const F2FS_SUPER_MAGIC: FsType = ++ FsType(libc::F2FS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const FUSE_SUPER_MAGIC: FsType = ++ FsType(libc::FUSE_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const FUTEXFS_SUPER_MAGIC: FsType = ++ FsType(libc::FUTEXFS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const HOSTFS_SUPER_MAGIC: FsType = ++ FsType(libc::HOSTFS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const HPFS_SUPER_MAGIC: FsType = ++ FsType(libc::HPFS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const HUGETLBFS_MAGIC: FsType = FsType(libc::HUGETLBFS_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const ISOFS_SUPER_MAGIC: FsType = ++ FsType(libc::ISOFS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const JFFS2_SUPER_MAGIC: FsType = ++ FsType(libc::JFFS2_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const MINIX2_SUPER_MAGIC2: FsType = ++ FsType(libc::MINIX2_SUPER_MAGIC2 as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const MINIX2_SUPER_MAGIC: FsType = ++ FsType(libc::MINIX2_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const MINIX3_SUPER_MAGIC: FsType = ++ FsType(libc::MINIX3_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const MINIX_SUPER_MAGIC2: FsType = ++ FsType(libc::MINIX_SUPER_MAGIC2 as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const MINIX_SUPER_MAGIC: FsType = ++ FsType(libc::MINIX_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const MSDOS_SUPER_MAGIC: FsType = ++ FsType(libc::MSDOS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const NCP_SUPER_MAGIC: FsType = FsType(libc::NCP_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const NFS_SUPER_MAGIC: FsType = FsType(libc::NFS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const NILFS_SUPER_MAGIC: FsType = ++ FsType(libc::NILFS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const OCFS2_SUPER_MAGIC: FsType = ++ FsType(libc::OCFS2_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const OPENPROM_SUPER_MAGIC: FsType = ++ FsType(libc::OPENPROM_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const OVERLAYFS_SUPER_MAGIC: FsType = ++ FsType(libc::OVERLAYFS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const PROC_SUPER_MAGIC: FsType = ++ FsType(libc::PROC_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const QNX4_SUPER_MAGIC: FsType = ++ FsType(libc::QNX4_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const QNX6_SUPER_MAGIC: FsType = ++ FsType(libc::QNX6_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const RDTGROUP_SUPER_MAGIC: FsType = ++ FsType(libc::RDTGROUP_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const REISERFS_SUPER_MAGIC: FsType = ++ FsType(libc::REISERFS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const SECURITYFS_MAGIC: FsType = ++ FsType(libc::SECURITYFS_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const SELINUX_MAGIC: FsType = FsType(libc::SELINUX_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const SMACK_MAGIC: FsType = FsType(libc::SMACK_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const SMB_SUPER_MAGIC: FsType = FsType(libc::SMB_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const SYSFS_MAGIC: FsType = FsType(libc::SYSFS_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const TMPFS_MAGIC: FsType = FsType(libc::TMPFS_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const TRACEFS_MAGIC: FsType = FsType(libc::TRACEFS_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const UDF_SUPER_MAGIC: FsType = FsType(libc::UDF_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const USBDEVICE_SUPER_MAGIC: FsType = ++ FsType(libc::USBDEVICE_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const XENFS_SUPER_MAGIC: FsType = ++ FsType(libc::XENFS_SUPER_MAGIC as fs_type_t); ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[allow(missing_docs)] ++pub const NSFS_MAGIC: FsType = FsType(libc::NSFS_MAGIC as fs_type_t); ++#[cfg(all( ++ any(target_os = "linux", target_os = "android"), ++ not(target_env = "musl") ++))] ++#[allow(missing_docs)] ++pub const XFS_SUPER_MAGIC: FsType = FsType(libc::XFS_SUPER_MAGIC as fs_type_t); + + impl Statfs { + /// Magic code defining system type + #[cfg(not(any( + target_os = "openbsd", ++ target_os = "dragonfly", + target_os = "ios", + target_os = "macos" + )))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn filesystem_type(&self) -> FsType { + FsType(self.0.f_type) + } + + /// Magic code defining system type + #[cfg(not(any(target_os = "linux", target_os = "android")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn filesystem_type_name(&self) -> &str { + let c_str = unsafe { CStr::from_ptr(self.0.f_fstypename.as_ptr()) }; + c_str.to_str().unwrap() +@@ -107,18 +320,21 @@ impl Statfs { + + /// Optimal transfer block size + #[cfg(any(target_os = "ios", target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn optimal_transfer_size(&self) -> i32 { + self.0.f_iosize + } + + /// Optimal transfer block size + #[cfg(target_os = "openbsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn optimal_transfer_size(&self) -> u32 { + self.0.f_iosize + } + + /// Optimal transfer block size + #[cfg(all(target_os = "linux", target_arch = "s390x"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn optimal_transfer_size(&self) -> u32 { + self.0.f_bsize + } +@@ -128,30 +344,49 @@ impl Statfs { + target_os = "android", + all(target_os = "linux", target_env = "musl") + ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn optimal_transfer_size(&self) -> libc::c_ulong { + self.0.f_bsize + } + + /// Optimal transfer block size +- #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))] +- pub fn optimal_transfer_size(&self) -> libc::c_long { ++ #[cfg(all( ++ target_os = "linux", ++ not(any( ++ target_arch = "s390x", ++ target_env = "musl", ++ target_env = "uclibc" ++ )) ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub fn optimal_transfer_size(&self) -> libc::__fsword_t { ++ self.0.f_bsize ++ } ++ ++ /// Optimal transfer block size ++ #[cfg(all(target_os = "linux", target_env = "uclibc"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub fn optimal_transfer_size(&self) -> libc::c_int { + self.0.f_bsize + } + + /// Optimal transfer block size + #[cfg(target_os = "dragonfly")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn optimal_transfer_size(&self) -> libc::c_long { + self.0.f_iosize + } + + /// Optimal transfer block size + #[cfg(target_os = "freebsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn optimal_transfer_size(&self) -> u64 { + self.0.f_iosize + } + + /// Size of a block + #[cfg(any(target_os = "ios", target_os = "macos", target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn block_size(&self) -> u32 { + self.0.f_bsize + } +@@ -159,6 +394,7 @@ impl Statfs { + /// Size of a block + // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471 + #[cfg(all(target_os = "linux", target_arch = "s390x"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn block_size(&self) -> u32 { + self.0.f_bsize + } +@@ -166,61 +402,126 @@ impl Statfs { + /// Size of a block + // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471 + #[cfg(all(target_os = "linux", target_env = "musl"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn block_size(&self) -> libc::c_ulong { + self.0.f_bsize + } + + /// Size of a block + // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471 +- #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))] +- pub fn block_size(&self) -> libc::c_long { ++ #[cfg(all(target_os = "linux", target_env = "uclibc"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub fn block_size(&self) -> libc::c_int { ++ self.0.f_bsize ++ } ++ ++ /// Size of a block ++ // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471 ++ #[cfg(all( ++ target_os = "linux", ++ not(any( ++ target_arch = "s390x", ++ target_env = "musl", ++ target_env = "uclibc" ++ )) ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub fn block_size(&self) -> libc::__fsword_t { + self.0.f_bsize + } + + /// Size of a block + #[cfg(target_os = "freebsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn block_size(&self) -> u64 { + self.0.f_bsize + } + + /// Size of a block + #[cfg(target_os = "android")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn block_size(&self) -> libc::c_ulong { + self.0.f_bsize + } + + /// Size of a block + #[cfg(target_os = "dragonfly")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn block_size(&self) -> libc::c_long { + self.0.f_bsize + } + ++ /// Get the mount flags ++ #[cfg(all( ++ feature = "mount", ++ any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ) ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ #[allow(clippy::unnecessary_cast)] // Not unnecessary on all arches ++ pub fn flags(&self) -> MntFlags { ++ MntFlags::from_bits_truncate(self.0.f_flags as i32) ++ } ++ ++ /// Get the mount flags ++ // The f_flags field exists on Android and Fuchsia too, but without man ++ // pages I can't tell if it can be cast to FsFlags. ++ #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub fn flags(&self) -> FsFlags { ++ FsFlags::from_bits_truncate(self.0.f_flags as libc::c_ulong) ++ } ++ + /// Maximum length of filenames + #[cfg(any(target_os = "freebsd", target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn maximum_name_length(&self) -> u32 { + self.0.f_namemax + } + + /// Maximum length of filenames + #[cfg(all(target_os = "linux", target_arch = "s390x"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn maximum_name_length(&self) -> u32 { + self.0.f_namelen + } + + /// Maximum length of filenames + #[cfg(all(target_os = "linux", target_env = "musl"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn maximum_name_length(&self) -> libc::c_ulong { + self.0.f_namelen + } + + /// Maximum length of filenames +- #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))] +- pub fn maximum_name_length(&self) -> libc::c_long { ++ #[cfg(all(target_os = "linux", target_env = "uclibc"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub fn maximum_name_length(&self) -> libc::c_int { ++ self.0.f_namelen ++ } ++ ++ /// Maximum length of filenames ++ #[cfg(all( ++ target_os = "linux", ++ not(any( ++ target_arch = "s390x", ++ target_env = "musl", ++ target_env = "uclibc" ++ )) ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub fn maximum_name_length(&self) -> libc::__fsword_t { + self.0.f_namelen + } + + /// Maximum length of filenames + #[cfg(target_os = "android")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn maximum_name_length(&self) -> libc::c_ulong { + self.0.f_namelen + } +@@ -231,35 +532,26 @@ impl Statfs { + target_os = "macos", + target_os = "android", + target_os = "freebsd", ++ target_os = "fuchsia", + target_os = "openbsd", ++ target_os = "linux", + ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks(&self) -> u64 { + self.0.f_blocks + } + + /// Total data blocks in filesystem + #[cfg(target_os = "dragonfly")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks(&self) -> libc::c_long { + self.0.f_blocks + } + + /// Total data blocks in filesystem +- #[cfg(all(target_os = "linux", target_env = "musl"))] +- pub fn blocks(&self) -> u64 { +- self.0.f_blocks +- } +- +- /// Total data blocks in filesystem +- #[cfg(not(any( +- target_os = "ios", +- target_os = "macos", +- target_os = "android", +- target_os = "freebsd", +- target_os = "openbsd", +- target_os = "dragonfly", +- all(target_os = "linux", target_env = "musl") +- )))] +- pub fn blocks(&self) -> libc::c_ulong { ++ #[cfg(target_os = "emscripten")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub fn blocks(&self) -> u32 { + self.0.f_blocks + } + +@@ -269,73 +561,60 @@ impl Statfs { + target_os = "macos", + target_os = "android", + target_os = "freebsd", ++ target_os = "fuchsia", + target_os = "openbsd", ++ target_os = "linux", + ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks_free(&self) -> u64 { + self.0.f_bfree + } + + /// Free blocks in filesystem + #[cfg(target_os = "dragonfly")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks_free(&self) -> libc::c_long { + self.0.f_bfree + } + + /// Free blocks in filesystem +- #[cfg(all(target_os = "linux", target_env = "musl"))] +- pub fn blocks_free(&self) -> u64 { ++ #[cfg(target_os = "emscripten")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub fn blocks_free(&self) -> u32 { + self.0.f_bfree + } + +- /// Free blocks in filesystem +- #[cfg(not(any( ++ /// Free blocks available to unprivileged user ++ #[cfg(any( + target_os = "ios", + target_os = "macos", + target_os = "android", +- target_os = "freebsd", +- target_os = "openbsd", +- target_os = "dragonfly", +- all(target_os = "linux", target_env = "musl") +- )))] +- pub fn blocks_free(&self) -> libc::c_ulong { +- self.0.f_bfree +- } +- +- /// Free blocks available to unprivileged user +- #[cfg(any(target_os = "ios", target_os = "macos", target_os = "android"))] ++ target_os = "fuchsia", ++ target_os = "linux", ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks_available(&self) -> u64 { + self.0.f_bavail + } + + /// Free blocks available to unprivileged user + #[cfg(target_os = "dragonfly")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks_available(&self) -> libc::c_long { + self.0.f_bavail + } + + /// Free blocks available to unprivileged user + #[cfg(any(target_os = "freebsd", target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn blocks_available(&self) -> i64 { + self.0.f_bavail + } + + /// Free blocks available to unprivileged user +- #[cfg(all(target_os = "linux", target_env = "musl"))] +- pub fn blocks_available(&self) -> u64 { +- self.0.f_bavail +- } +- +- /// Free blocks available to unprivileged user +- #[cfg(not(any( +- target_os = "ios", +- target_os = "macos", +- target_os = "android", +- target_os = "freebsd", +- target_os = "openbsd", +- target_os = "dragonfly", +- all(target_os = "linux", target_env = "musl") +- )))] +- pub fn blocks_available(&self) -> libc::c_ulong { ++ #[cfg(target_os = "emscripten")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub fn blocks_available(&self) -> u32 { + self.0.f_bavail + } + +@@ -345,73 +624,61 @@ impl Statfs { + target_os = "macos", + target_os = "android", + target_os = "freebsd", ++ target_os = "fuchsia", + target_os = "openbsd", ++ target_os = "linux", + ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn files(&self) -> u64 { + self.0.f_files + } + + /// Total file nodes in filesystem + #[cfg(target_os = "dragonfly")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn files(&self) -> libc::c_long { + self.0.f_files + } + + /// Total file nodes in filesystem +- #[cfg(all(target_os = "linux", target_env = "musl"))] +- pub fn files(&self) -> u64 { ++ #[cfg(target_os = "emscripten")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub fn files(&self) -> u32 { + self.0.f_files + } + +- /// Total file nodes in filesystem +- #[cfg(not(any( ++ /// Free file nodes in filesystem ++ #[cfg(any( + target_os = "ios", + target_os = "macos", + target_os = "android", +- target_os = "freebsd", ++ target_os = "fuchsia", + target_os = "openbsd", +- target_os = "dragonfly", +- all(target_os = "linux", target_env = "musl") +- )))] +- pub fn files(&self) -> libc::c_ulong { +- self.0.f_files +- } +- +- /// Free file nodes in filesystem +- #[cfg(any( +- target_os = "android", +- target_os = "ios", +- all(target_os = "linux", target_env = "musl"), +- target_os = "macos", +- target_os = "openbsd" ++ target_os = "linux", + ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn files_free(&self) -> u64 { + self.0.f_ffree + } + + /// Free file nodes in filesystem + #[cfg(target_os = "dragonfly")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn files_free(&self) -> libc::c_long { + self.0.f_ffree + } + + /// Free file nodes in filesystem + #[cfg(target_os = "freebsd")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn files_free(&self) -> i64 { + self.0.f_ffree + } + + /// Free file nodes in filesystem +- #[cfg(not(any( +- target_os = "ios", +- target_os = "macos", +- target_os = "android", +- target_os = "freebsd", +- target_os = "openbsd", +- target_os = "dragonfly", +- all(target_os = "linux", target_env = "musl") +- )))] +- pub fn files_free(&self) -> libc::c_ulong { ++ #[cfg(target_os = "emscripten")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub fn files_free(&self) -> u32 { + self.0.f_ffree + } + +@@ -423,31 +690,60 @@ impl Statfs { + + impl Debug for Statfs { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +- f.debug_struct("Statfs") +- .field("optimal_transfer_size", &self.optimal_transfer_size()) +- .field("block_size", &self.block_size()) +- .field("blocks", &self.blocks()) +- .field("blocks_free", &self.blocks_free()) +- .field("blocks_available", &self.blocks_available()) +- .field("files", &self.files()) +- .field("files_free", &self.files_free()) +- .field("filesystem_id", &self.filesystem_id()) +- .finish() ++ let mut ds = f.debug_struct("Statfs"); ++ ds.field("optimal_transfer_size", &self.optimal_transfer_size()); ++ ds.field("block_size", &self.block_size()); ++ ds.field("blocks", &self.blocks()); ++ ds.field("blocks_free", &self.blocks_free()); ++ ds.field("blocks_available", &self.blocks_available()); ++ ds.field("files", &self.files()); ++ ds.field("files_free", &self.files_free()); ++ ds.field("filesystem_id", &self.filesystem_id()); ++ #[cfg(all( ++ feature = "mount", ++ any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ) ++ ))] ++ ds.field("flags", &self.flags()); ++ ds.finish() + } + } + ++/// Describes a mounted file system. ++/// ++/// The result is OS-dependent. For a portable alternative, see ++/// [`statvfs`](crate::sys::statvfs::statvfs). ++/// ++/// # Arguments ++/// ++/// `path` - Path to any file within the file system to describe + pub fn statfs(path: &P) -> Result { + unsafe { +- let mut stat = mem::MaybeUninit::::uninit(); +- let res = path.with_nix_path(|path| libc::statfs(path.as_ptr(), stat.as_mut_ptr()))?; ++ let mut stat = mem::MaybeUninit::::uninit(); ++ let res = path.with_nix_path(|path| { ++ LIBC_STATFS(path.as_ptr(), stat.as_mut_ptr()) ++ })?; + Errno::result(res).map(|_| Statfs(stat.assume_init())) + } + } + ++/// Describes a mounted file system. ++/// ++/// The result is OS-dependent. For a portable alternative, see ++/// [`fstatvfs`](crate::sys::statvfs::fstatvfs). ++/// ++/// # Arguments ++/// ++/// `fd` - File descriptor of any open file within the file system to describe + pub fn fstatfs(fd: &T) -> Result { + unsafe { +- let mut stat = mem::MaybeUninit::::uninit(); +- Errno::result(libc::fstatfs(fd.as_raw_fd(), stat.as_mut_ptr())) ++ let mut stat = mem::MaybeUninit::::uninit(); ++ Errno::result(LIBC_FSTATFS(fd.as_raw_fd(), stat.as_mut_ptr())) + .map(|_| Statfs(stat.assume_init())) + } + } +@@ -456,8 +752,8 @@ pub fn fstatfs(fd: &T) -> Result { + mod test { + use std::fs::File; + +- use sys::statfs::*; +- use sys::statvfs::*; ++ use crate::sys::statfs::*; ++ use crate::sys::statvfs::*; + use std::path::Path; + + #[test] +@@ -495,6 +791,8 @@ mod test { + assert_fs_equals(fs, vfs); + } + ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] + fn assert_fs_equals(fs: Statfs, vfs: Statvfs) { + assert_eq!(fs.files() as u64, vfs.files() as u64); + assert_eq!(fs.blocks() as u64, vfs.blocks() as u64); +@@ -542,6 +840,8 @@ mod test { + assert_fs_equals_strict(fs.unwrap(), vfs.unwrap()) + } + ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] + fn assert_fs_equals_strict(fs: Statfs, vfs: Statvfs) { + assert_eq!(fs.files_free() as u64, vfs.files_free() as u64); + assert_eq!(fs.blocks_free() as u64, vfs.blocks_free() as u64); +diff --git a/vendor/nix/src/sys/statvfs.rs b/vendor/nix/src/sys/statvfs.rs +index 2614780..8de369f 100644 +--- a/vendor/nix/src/sys/statvfs.rs ++++ b/vendor/nix/src/sys/statvfs.rs +@@ -1,60 +1,72 @@ + //! Get filesystem statistics + //! +-//! See [the man pages](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatvfs.html) ++//! See [the man pages](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatvfs.html) + //! for more details. + use std::mem; + use std::os::unix::io::AsRawFd; + + use libc::{self, c_ulong}; + +-use {Result, NixPath}; +-use errno::Errno; ++use crate::{errno::Errno, NixPath, Result}; + ++#[cfg(not(target_os = "redox"))] + libc_bitflags!( + /// File system mount Flags + #[repr(C)] + #[derive(Default)] + pub struct FsFlags: c_ulong { + /// Read Only ++ #[cfg(not(target_os = "haiku"))] + ST_RDONLY; + /// Do not allow the set-uid bits to have an effect ++ #[cfg(not(target_os = "haiku"))] + ST_NOSUID; + /// Do not interpret character or block-special devices + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ST_NODEV; + /// Do not allow execution of binaries on the filesystem + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ST_NOEXEC; + /// All IO should be done synchronously + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ST_SYNCHRONOUS; + /// Allow mandatory locks on the filesystem + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ST_MANDLOCK; + /// Write on file/directory/symlink + #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ST_WRITE; + /// Append-only file + #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ST_APPEND; + /// Immutable file + #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ST_IMMUTABLE; + /// Do not update access times on files + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ST_NOATIME; + /// Do not update access times on files + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ST_NODIRATIME; + /// Update access time relative to modify/change time + #[cfg(any(target_os = "android", all(target_os = "linux", not(target_env = "musl"))))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ST_RELATIME; + } + ); + + /// Wrapper around the POSIX `statvfs` struct + /// +-/// For more information see the [`statvfs(3)` man pages](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_statvfs.h.html). ++/// For more information see the [`statvfs(3)` man pages](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_statvfs.h.html). + #[repr(transparent)] + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct Statvfs(libc::statvfs); +@@ -108,6 +120,8 @@ impl Statvfs { + } + + /// Get the mount flags ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub fn flags(&self) -> FsFlags { + FsFlags::from_bits_truncate(self.0.f_flag) + } +@@ -116,7 +130,6 @@ impl Statvfs { + pub fn name_max(&self) -> c_ulong { + self.0.f_namemax + } +- + } + + /// Return a `Statvfs` object with information about the `path` +@@ -124,9 +137,9 @@ pub fn statvfs(path: &P) -> Result { + unsafe { + Errno::clear(); + let mut stat = mem::MaybeUninit::::uninit(); +- let res = path.with_nix_path(|path| ++ let res = path.with_nix_path(|path| { + libc::statvfs(path.as_ptr(), stat.as_mut_ptr()) +- )?; ++ })?; + + Errno::result(res).map(|_| Statvfs(stat.assume_init())) + } +@@ -144,12 +157,12 @@ pub fn fstatvfs(fd: &T) -> Result { + + #[cfg(test)] + mod test { ++ use crate::sys::statvfs::*; + use std::fs::File; +- use sys::statvfs::*; + + #[test] + fn statvfs_call() { +- statvfs("/".as_bytes()).unwrap(); ++ statvfs(&b"/"[..]).unwrap(); + } + + #[test] +diff --git a/vendor/nix/src/sys/sysinfo.rs b/vendor/nix/src/sys/sysinfo.rs +index 9807b44..e8aa00b 100644 +--- a/vendor/nix/src/sys/sysinfo.rs ++++ b/vendor/nix/src/sys/sysinfo.rs +@@ -1,15 +1,21 @@ + use libc::{self, SI_LOAD_SHIFT}; +-use std::{cmp, mem}; + use std::time::Duration; ++use std::{cmp, mem}; + +-use Result; +-use errno::Errno; ++use crate::errno::Errno; ++use crate::Result; + + /// System info structure returned by `sysinfo`. + #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] + #[repr(transparent)] + pub struct SysInfo(libc::sysinfo); + ++// The fields are c_ulong on 32-bit linux, u64 on 64-bit linux; x32's ulong is u32 ++#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] ++type mem_blocks_t = u64; ++#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] ++type mem_blocks_t = libc::c_ulong; ++ + impl SysInfo { + /// Returns the load average tuple. + /// +@@ -24,6 +30,8 @@ impl SysInfo { + } + + /// Returns the time since system boot. ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] + pub fn uptime(&self) -> Duration { + // Truncate negative values to 0 + Duration::from_secs(cmp::max(self.0.uptime, 0) as u64) +@@ -58,16 +66,18 @@ impl SysInfo { + self.scale_mem(self.0.freeram) + } + +- fn scale_mem(&self, units: libc::c_ulong) -> u64 { ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] ++ fn scale_mem(&self, units: mem_blocks_t) -> u64 { + units as u64 * self.0.mem_unit as u64 + } + } + + /// Returns system information. + /// +-/// [See `sysinfo(2)`](http://man7.org/linux/man-pages/man2/sysinfo.2.html). ++/// [See `sysinfo(2)`](https://man7.org/linux/man-pages/man2/sysinfo.2.html). + pub fn sysinfo() -> Result { + let mut info = mem::MaybeUninit::uninit(); + let res = unsafe { libc::sysinfo(info.as_mut_ptr()) }; +- Errno::result(res).map(|_| unsafe{ SysInfo(info.assume_init()) }) ++ Errno::result(res).map(|_| unsafe { SysInfo(info.assume_init()) }) + } +diff --git a/vendor/nix/src/sys/termios.rs b/vendor/nix/src/sys/termios.rs +index 68b0dbc..fba2cd8 100644 +--- a/vendor/nix/src/sys/termios.rs ++++ b/vendor/nix/src/sys/termios.rs +@@ -5,7 +5,7 @@ + //! types here or exported directly. + //! + //! If you are unfamiliar with the `termios` API, you should first read the +-//! [API documentation](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/termios.h.html) and ++//! [API documentation](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/termios.h.html) and + //! then come back to understand how `nix` safely wraps it. + //! + //! It should be noted that this API incurs some runtime overhead above the base `libc` definitions. +@@ -25,7 +25,7 @@ + //! ``` + //! # use self::nix::sys::termios::SpecialCharacterIndices::VEOF; + //! # use self::nix::sys::termios::{_POSIX_VDISABLE, Termios}; +-//! # let mut termios = unsafe { Termios::default_uninit() }; ++//! # let mut termios: Termios = unsafe { std::mem::zeroed() }; + //! termios.control_chars[VEOF as usize] = _POSIX_VDISABLE; + //! ``` + //! +@@ -38,7 +38,7 @@ + //! + //! ``` + //! # use self::nix::sys::termios::{ControlFlags, Termios}; +-//! # let mut termios = unsafe { Termios::default_uninit() }; ++//! # let mut termios: Termios = unsafe { std::mem::zeroed() }; + //! termios.control_flags & ControlFlags::CSIZE == ControlFlags::CS5; + //! termios.control_flags |= ControlFlags::CS5; + //! ``` +@@ -61,42 +61,55 @@ + //! platforms: + //! + //! ```rust +-//! # #[macro_use] extern crate nix; + //! # use nix::sys::termios::{BaudRate, cfsetispeed, cfsetospeed, cfsetspeed, Termios}; + //! # fn main() { +-//! # let mut t = unsafe { Termios::default_uninit() }; +-//! cfsetispeed(&mut t, BaudRate::B9600); +-//! cfsetospeed(&mut t, BaudRate::B9600); +-//! cfsetspeed(&mut t, BaudRate::B9600); ++//! # let mut t: Termios = unsafe { std::mem::zeroed() }; ++//! cfsetispeed(&mut t, BaudRate::B9600).unwrap(); ++//! cfsetospeed(&mut t, BaudRate::B9600).unwrap(); ++//! cfsetspeed(&mut t, BaudRate::B9600).unwrap(); + //! # } + //! ``` + //! + //! Additionally round-tripping baud rates is consistent across platforms: + //! + //! ```rust +-//! # extern crate nix; + //! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetispeed, cfsetspeed, Termios}; + //! # fn main() { +-//! # let mut t = unsafe { Termios::default_uninit() }; +-//! # cfsetspeed(&mut t, BaudRate::B9600); ++//! # let mut t: Termios = unsafe { std::mem::zeroed() }; ++//! # cfsetspeed(&mut t, BaudRate::B9600).unwrap(); + //! let speed = cfgetispeed(&t); + //! assert_eq!(speed, cfgetospeed(&t)); +-//! cfsetispeed(&mut t, speed); ++//! cfsetispeed(&mut t, speed).unwrap(); + //! # } + //! ``` + //! + //! On non-BSDs, `cfgetispeed()` and `cfgetospeed()` both return a `BaudRate`: + //! +-#![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios", +- target_os = "macos", target_os = "netbsd", target_os = "openbsd"), +- doc = " ```rust,ignore")] +-#![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios", +- target_os = "macos", target_os = "netbsd", target_os = "openbsd")), +- doc = " ```rust")] +-//! # extern crate nix; ++#![cfg_attr( ++ any( ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ), ++ doc = " ```rust,ignore" ++)] ++#![cfg_attr( ++ not(any( ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ )), ++ doc = " ```rust" ++)] + //! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetspeed, Termios}; + //! # fn main() { +-//! # let mut t = unsafe { Termios::default_uninit() }; ++//! # let mut t: Termios = unsafe { std::mem::zeroed() }; + //! # cfsetspeed(&mut t, BaudRate::B9600); + //! assert_eq!(cfgetispeed(&t), BaudRate::B9600); + //! assert_eq!(cfgetospeed(&t), BaudRate::B9600); +@@ -105,16 +118,31 @@ + //! + //! But on the BSDs, `cfgetispeed()` and `cfgetospeed()` both return `u32`s: + //! +-#![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios", +- target_os = "macos", target_os = "netbsd", target_os = "openbsd"), +- doc = " ```rust")] +-#![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios", +- target_os = "macos", target_os = "netbsd", target_os = "openbsd")), +- doc = " ```rust,ignore")] +-//! # extern crate nix; ++#![cfg_attr( ++ any( ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ), ++ doc = " ```rust" ++)] ++#![cfg_attr( ++ not(any( ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ )), ++ doc = " ```rust,ignore" ++)] + //! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetspeed, Termios}; + //! # fn main() { +-//! # let mut t = unsafe { Termios::default_uninit() }; ++//! # let mut t: Termios = unsafe { std::mem::zeroed() }; + //! # cfsetspeed(&mut t, 9600u32); + //! assert_eq!(cfgetispeed(&t), 9600u32); + //! assert_eq!(cfgetospeed(&t), 9600u32); +@@ -123,16 +151,31 @@ + //! + //! It's trivial to convert from a `BaudRate` to a `u32` on BSDs: + //! +-#![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios", +- target_os = "macos", target_os = "netbsd", target_os = "openbsd"), +- doc = " ```rust")] +-#![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios", +- target_os = "macos", target_os = "netbsd", target_os = "openbsd")), +- doc = " ```rust,ignore")] +-//! # extern crate nix; ++#![cfg_attr( ++ any( ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ), ++ doc = " ```rust" ++)] ++#![cfg_attr( ++ not(any( ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ )), ++ doc = " ```rust,ignore" ++)] + //! # use nix::sys::termios::{BaudRate, cfgetispeed, cfsetspeed, Termios}; + //! # fn main() { +-//! # let mut t = unsafe { Termios::default_uninit() }; ++//! # let mut t: Termios = unsafe { std::mem::zeroed() }; + //! # cfsetspeed(&mut t, 9600u32); + //! assert_eq!(cfgetispeed(&t), BaudRate::B9600.into()); + //! assert_eq!(u32::from(BaudRate::B9600), 9600u32); +@@ -142,30 +185,47 @@ + //! And on BSDs you can specify arbitrary baud rates (**note** this depends on hardware support) + //! by specifying baud rates directly using `u32`s: + //! +-#![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios", +- target_os = "macos", target_os = "netbsd", target_os = "openbsd"), +- doc = " ```rust")] +-#![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios", +- target_os = "macos", target_os = "netbsd", target_os = "openbsd")), +- doc = " ```rust,ignore")] +-//! # extern crate nix; ++#![cfg_attr( ++ any( ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ ), ++ doc = " ```rust" ++)] ++#![cfg_attr( ++ not(any( ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++ )), ++ doc = " ```rust,ignore" ++)] + //! # use nix::sys::termios::{cfsetispeed, cfsetospeed, cfsetspeed, Termios}; + //! # fn main() { +-//! # let mut t = unsafe { Termios::default_uninit() }; ++//! # let mut t: Termios = unsafe { std::mem::zeroed() }; + //! cfsetispeed(&mut t, 9600u32); + //! cfsetospeed(&mut t, 9600u32); + //! cfsetspeed(&mut t, 9600u32); + //! # } + //! ``` +-use {Error, Result}; +-use errno::Errno; ++use crate::errno::Errno; ++use crate::Result; ++use cfg_if::cfg_if; + use libc::{self, c_int, tcflag_t}; + use std::cell::{Ref, RefCell}; +-use std::convert::{From, TryFrom}; ++use std::convert::From; + use std::mem; + use std::os::unix::io::RawFd; + +-use ::unistd::Pid; ++#[cfg(feature = "process")] ++use crate::unistd::Pid; + + /// Stores settings for the termios API + /// +@@ -185,29 +245,20 @@ pub struct Termios { + pub local_flags: LocalFlags, + /// Control characters (see `termios.c_cc` documentation) + pub control_chars: [libc::cc_t; NCCS], ++ /// Line discipline (see `termios.c_line` documentation) ++ #[cfg(any(target_os = "linux", target_os = "android",))] ++ pub line_discipline: libc::cc_t, ++ /// Line discipline (see `termios.c_line` documentation) ++ #[cfg(target_os = "haiku")] ++ pub line_discipline: libc::c_char, + } + + impl Termios { + /// Exposes an immutable reference to the underlying `libc::termios` data structure. + /// +- /// This can be used for interfacing with other FFI functions like: +- /// +- /// ```rust +- /// # extern crate libc; +- /// # extern crate nix; +- /// # fn main() { +- /// # use nix::sys::termios::Termios; +- /// # let mut termios = unsafe { Termios::default_uninit() }; +- /// let inner_termios = termios.get_libc_termios(); +- /// unsafe { libc::cfgetispeed(&*inner_termios) }; +- /// # } +- /// ``` +- /// +- /// There is no public API exposed for functions that modify the underlying `libc::termios` +- /// data because it requires additional work to maintain type safety. +- // FIXME: Switch this over to use pub(crate) +- #[doc(hidden)] +- pub fn get_libc_termios(&self) -> Ref { ++ /// This is not part of `nix`'s public API because it requires additional work to maintain type ++ /// safety. ++ pub(crate) fn get_libc_termios(&self) -> Ref { + { + let mut termios = self.inner.borrow_mut(); + termios.c_iflag = self.input_flags.bits(); +@@ -215,18 +266,25 @@ impl Termios { + termios.c_cflag = self.control_flags.bits(); + termios.c_lflag = self.local_flags.bits(); + termios.c_cc = self.control_chars; ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "haiku", ++ ))] ++ { ++ termios.c_line = self.line_discipline; ++ } + } + self.inner.borrow() + } + + /// Exposes the inner `libc::termios` datastore within `Termios`. + /// +- /// This is unsafe because if this is used to modify the inner libc::termios struct, it will not +- /// automatically update the safe wrapper type around it. Therefore we disable docs to +- /// effectively limit its use to nix internals. In this case it should also be paired with a +- /// call to `update_wrapper()` so that the wrapper-type and internal representation stay +- /// consistent. +- unsafe fn get_libc_termios_mut(&mut self) -> *mut libc::termios { ++ /// This is unsafe because if this is used to modify the inner `libc::termios` struct, it will ++ /// not automatically update the safe wrapper type around it. In this case it should also be ++ /// paired with a call to `update_wrapper()` so that the wrapper-type and internal ++ /// representation stay consistent. ++ pub(crate) unsafe fn get_libc_termios_mut(&mut self) -> *mut libc::termios { + { + let mut termios = self.inner.borrow_mut(); + termios.c_iflag = self.input_flags.bits(); +@@ -234,36 +292,34 @@ impl Termios { + termios.c_cflag = self.control_flags.bits(); + termios.c_lflag = self.local_flags.bits(); + termios.c_cc = self.control_chars; ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "haiku", ++ ))] ++ { ++ termios.c_line = self.line_discipline; ++ } + } + self.inner.as_ptr() + } + +- /// Allows for easily creating new `Termios` structs that will be overwritten with real data. +- /// +- /// This should only be used when the inner libc::termios struct will be overwritten before it's +- /// read. +- // FIXME: Switch this over to use pub(crate) +- #[doc(hidden)] +- pub unsafe fn default_uninit() -> Self { +- Termios { +- inner: RefCell::new(mem::zeroed()), +- input_flags: InputFlags::empty(), +- output_flags: OutputFlags::empty(), +- control_flags: ControlFlags::empty(), +- local_flags: LocalFlags::empty(), +- control_chars: [0 as libc::cc_t; NCCS], +- } +- } +- + /// Updates the wrapper values from the internal `libc::termios` data structure. +- #[doc(hidden)] +- pub fn update_wrapper(&mut self) { ++ pub(crate) fn update_wrapper(&mut self) { + let termios = *self.inner.borrow_mut(); + self.input_flags = InputFlags::from_bits_truncate(termios.c_iflag); + self.output_flags = OutputFlags::from_bits_truncate(termios.c_oflag); + self.control_flags = ControlFlags::from_bits_truncate(termios.c_cflag); + self.local_flags = LocalFlags::from_bits_truncate(termios.c_lflag); + self.control_chars = termios.c_cc; ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "haiku", ++ ))] ++ { ++ self.line_discipline = termios.c_line; ++ } + } + } + +@@ -276,6 +332,12 @@ impl From for Termios { + control_flags: ControlFlags::from_bits_truncate(termios.c_cflag), + local_flags: LocalFlags::from_bits_truncate(termios.c_lflag), + control_chars: termios.c_cc, ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "haiku", ++ ))] ++ line_discipline: termios.c_line, + } + } + } +@@ -286,15 +348,17 @@ impl From for libc::termios { + } + } + +-libc_enum!{ ++libc_enum! { + /// Baud rates supported by the system. + /// + /// For the BSDs, arbitrary baud rates can be specified by using `u32`s directly instead of this + /// enum. + /// + /// B0 is special and will disable the port. ++ #[cfg_attr(all(any(target_os = "haiku"), target_pointer_width = "64"), repr(u8))] + #[cfg_attr(all(any(target_os = "ios", target_os = "macos"), target_pointer_width = "64"), repr(u64))] +- #[cfg_attr(not(all(any(target_os = "ios", target_os = "macos"), target_pointer_width = "64")), repr(u32))] ++ #[cfg_attr(not(all(any(target_os = "ios", target_os = "macos", target_os = "haiku"), target_pointer_width = "64")), repr(u32))] ++ #[non_exhaustive] + pub enum BaudRate { + B0, + B50, +@@ -314,6 +378,7 @@ libc_enum!{ + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + B7200, + B9600, + #[cfg(any(target_os = "dragonfly", +@@ -321,6 +386,7 @@ libc_enum!{ + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + B14400, + B19200, + #[cfg(any(target_os = "dragonfly", +@@ -328,6 +394,7 @@ libc_enum!{ + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + B28800, + B38400, + B57600, +@@ -336,161 +403,94 @@ libc_enum!{ + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + B76800, + B115200, ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ B153600, + B230400, ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ B307200, + #[cfg(any(target_os = "android", + target_os = "freebsd", ++ target_os = "illumos", + target_os = "linux", +- target_os = "netbsd"))] ++ target_os = "netbsd", ++ target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + B460800, + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + B500000, + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + B576000, + #[cfg(any(target_os = "android", + target_os = "freebsd", ++ target_os = "illumos", + target_os = "linux", +- target_os = "netbsd"))] ++ target_os = "netbsd", ++ target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + B921600, + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + B1000000, + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + B1152000, + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + B1500000, + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + B2000000, + #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + B2500000, + #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + B3000000, + #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + B3500000, + #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + B4000000, + } ++ impl TryFrom + } + +-impl TryFrom for BaudRate { +- type Error = Error; +- +- fn try_from(s: libc::speed_t) -> Result { +- use libc::{B0, B50, B75, B110, B134, B150, B200, B300, B600, B1200, B1800, B2400, B4800, +- B9600, B19200, B38400, B57600, B115200, B230400}; +- #[cfg(any(target_os = "android", target_os = "linux"))] +- use libc::{B500000, B576000, B1000000, B1152000, B1500000, B2000000}; +- #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))] +- use libc::{B2500000, B3000000, B3500000, B4000000}; +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] +- use libc::{B7200, B14400, B28800, B76800}; +- #[cfg(any(target_os = "android", +- target_os = "freebsd", +- target_os = "linux", +- target_os = "netbsd"))] +- use libc::{B460800, B921600}; +- +- match s { +- B0 => Ok(BaudRate::B0), +- B50 => Ok(BaudRate::B50), +- B75 => Ok(BaudRate::B75), +- B110 => Ok(BaudRate::B110), +- B134 => Ok(BaudRate::B134), +- B150 => Ok(BaudRate::B150), +- B200 => Ok(BaudRate::B200), +- B300 => Ok(BaudRate::B300), +- B600 => Ok(BaudRate::B600), +- B1200 => Ok(BaudRate::B1200), +- B1800 => Ok(BaudRate::B1800), +- B2400 => Ok(BaudRate::B2400), +- B4800 => Ok(BaudRate::B4800), +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] +- B7200 => Ok(BaudRate::B7200), +- B9600 => Ok(BaudRate::B9600), +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] +- B14400 => Ok(BaudRate::B14400), +- B19200 => Ok(BaudRate::B19200), +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] +- B28800 => Ok(BaudRate::B28800), +- B38400 => Ok(BaudRate::B38400), +- B57600 => Ok(BaudRate::B57600), +- #[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] +- B76800 => Ok(BaudRate::B76800), +- B115200 => Ok(BaudRate::B115200), +- B230400 => Ok(BaudRate::B230400), +- #[cfg(any(target_os = "android", +- target_os = "freebsd", +- target_os = "linux", +- target_os = "netbsd"))] +- B460800 => Ok(BaudRate::B460800), +- #[cfg(any(target_os = "android", target_os = "linux"))] +- B500000 => Ok(BaudRate::B500000), +- #[cfg(any(target_os = "android", target_os = "linux"))] +- B576000 => Ok(BaudRate::B576000), +- #[cfg(any(target_os = "android", +- target_os = "freebsd", +- target_os = "linux", +- target_os = "netbsd"))] +- B921600 => Ok(BaudRate::B921600), +- #[cfg(any(target_os = "android", target_os = "linux"))] +- B1000000 => Ok(BaudRate::B1000000), +- #[cfg(any(target_os = "android", target_os = "linux"))] +- B1152000 => Ok(BaudRate::B1152000), +- #[cfg(any(target_os = "android", target_os = "linux"))] +- B1500000 => Ok(BaudRate::B1500000), +- #[cfg(any(target_os = "android", target_os = "linux"))] +- B2000000 => Ok(BaudRate::B2000000), +- #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))] +- B2500000 => Ok(BaudRate::B2500000), +- #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))] +- B3000000 => Ok(BaudRate::B3000000), +- #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))] +- B3500000 => Ok(BaudRate::B3500000), +- #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))] +- B4000000 => Ok(BaudRate::B4000000), +- _ => Err(Error::invalid_argument()) +- } +- } +-} +- +-#[cfg(any(target_os = "freebsd", +- target_os = "dragonfly", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++#[cfg(any( ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++))] + impl From for u32 { + fn from(b: BaudRate) -> u32 { + b as u32 + } + } + ++#[cfg(target_os = "haiku")] ++impl From for u8 { ++ fn from(b: BaudRate) -> u8 { ++ b as u8 ++ } ++} ++ + // TODO: Add TCSASOFT, which will require treating this as a bitfield. + libc_enum! { + /// Specify when a port configuration change should occur. + /// + /// Used as an argument to `tcsetattr()` + #[repr(i32)] ++ #[non_exhaustive] + pub enum SetArg { + /// The change will occur immediately + TCSANOW, +@@ -506,6 +506,7 @@ libc_enum! { + /// + /// Used as an argument to `tcflush()`. + #[repr(i32)] ++ #[non_exhaustive] + pub enum FlushArg { + /// Flush data that was received but not read + TCIFLUSH, +@@ -521,6 +522,7 @@ libc_enum! { + /// + /// Used as an argument to `tcflow()`. + #[repr(i32)] ++ #[non_exhaustive] + pub enum FlowArg { + /// Suspend transmission + TCOOFF, +@@ -534,64 +536,91 @@ libc_enum! { + } + + // TODO: Make this usable directly as a slice index. ++#[cfg(not(target_os = "haiku"))] + libc_enum! { + /// Indices into the `termios.c_cc` array for special characters. + #[repr(usize)] ++ #[non_exhaustive] + pub enum SpecialCharacterIndices { + VDISCARD, + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", ++ target_os = "illumos", + target_os = "macos", + target_os = "netbsd", +- target_os = "openbsd"))] ++ target_os = "openbsd", ++ target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + VDSUSP, + VEOF, + VEOL, + VEOL2, + VERASE, +- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] ++ #[cfg(any(target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "illumos", ++ target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + VERASE2, + VINTR, + VKILL, + VLNEXT, +- #[cfg(not(all(target_os = "linux", target_arch = "sparc64")))] ++ #[cfg(not(any(all(target_os = "linux", target_arch = "sparc64"), ++ target_os = "illumos", target_os = "solaris")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + VMIN, + VQUIT, + VREPRINT, + VSTART, + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", ++ target_os = "illumos", + target_os = "macos", + target_os = "netbsd", +- target_os = "openbsd"))] ++ target_os = "openbsd", ++ target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + VSTATUS, + VSTOP, + VSUSP, + #[cfg(target_os = "linux")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + VSWTC, +- #[cfg(target_os = "haiku")] ++ #[cfg(any(target_os = "haiku", target_os = "illumos", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + VSWTCH, +- #[cfg(not(all(target_os = "linux", target_arch = "sparc64")))] ++ #[cfg(not(any(all(target_os = "linux", target_arch = "sparc64"), ++ target_os = "illumos", target_os = "solaris")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + VTIME, + VWERASE, + #[cfg(target_os = "dragonfly")] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + VCHECKPT, + } + } + +-#[cfg(all(target_os = "linux", target_arch = "sparc64"))] ++#[cfg(any( ++ all(target_os = "linux", target_arch = "sparc64"), ++ target_os = "illumos", ++ target_os = "solaris" ++))] + impl SpecialCharacterIndices { + pub const VMIN: SpecialCharacterIndices = SpecialCharacterIndices::VEOF; + pub const VTIME: SpecialCharacterIndices = SpecialCharacterIndices::VEOL; + } + + pub use libc::NCCS; +-#[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "linux", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "linux", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++))] ++#[cfg_attr(docsrs, doc(cfg(all())))] + pub use libc::_POSIX_VDISABLE; + + libc_bitflags! { +@@ -608,9 +637,14 @@ libc_bitflags! { + ICRNL; + IXON; + IXOFF; ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IXANY; ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IMAXBEL; + #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + IUTF8; + } + } +@@ -623,6 +657,7 @@ libc_bitflags! { + target_os = "haiku", + target_os = "linux", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + OLCUC; + ONLCR; + OCRNL as tcflag_t; +@@ -633,48 +668,56 @@ libc_bitflags! { + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + OFILL as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + OFDEL as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + NL0 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + NL1 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + CR0 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + CR1 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + CR2 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + CR3 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "freebsd", +@@ -682,18 +725,21 @@ libc_bitflags! { + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + TAB0 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + TAB1 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + TAB2 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "freebsd", +@@ -701,44 +747,52 @@ libc_bitflags! { + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + TAB3 as tcflag_t; + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + XTABS; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + BS0 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + BS1 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + VT0 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + VT1 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + FF0 as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + FF1 as tcflag_t; + #[cfg(any(target_os = "freebsd", + target_os = "dragonfly", +@@ -746,12 +800,14 @@ libc_bitflags! { + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + OXTABS; + #[cfg(any(target_os = "freebsd", + target_os = "dragonfly", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ONOEOT as tcflag_t; + + // Bitmasks for use with OutputFlags to select specific settings +@@ -763,12 +819,14 @@ libc_bitflags! { + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + NLDLY as tcflag_t; // FIXME: Datatype needs to be corrected in libc for mac + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + CRDLY as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "freebsd", +@@ -776,24 +834,28 @@ libc_bitflags! { + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + TABDLY as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + BSDLY as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + VTDLY as tcflag_t; + #[cfg(any(target_os = "android", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + FFDLY as tcflag_t; + } + } +@@ -807,6 +869,7 @@ libc_bitflags! { + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + CIGNORE; + CS5; + CS6; +@@ -818,43 +881,55 @@ libc_bitflags! { + PARODD; + HUPCL; + CLOCAL; ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + CRTSCTS; + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + CBAUD; + #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "mips"))))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + CMSPAR; + #[cfg(any(target_os = "android", + all(target_os = "linux", + not(any(target_arch = "powerpc", target_arch = "powerpc64")))))] + CIBAUD; + #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + CBAUDEX; + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MDMBUF; + #[cfg(any(target_os = "netbsd", target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + CHWFLOW; + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + CCTS_OFLOW; + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + CRTS_IFLOW; + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + CDTR_IFLOW; + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + CDSR_OFLOW; + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + CCAR_OFLOW; + + // Bitmasks for use with ControlFlags to select specific settings +@@ -868,12 +943,18 @@ libc_bitflags! { + libc_bitflags! { + /// Flags for setting any local modes + pub struct LocalFlags: tcflag_t { ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ECHOKE; + ECHOE; + ECHOK; + ECHO; + ECHONL; ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ECHOPRT; ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ECHOCTL; + ISIG; + ICANON; +@@ -883,10 +964,15 @@ libc_bitflags! { + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + ALTWERASE; + IEXTEN; ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + EXTPROC; + TOSTOP; ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + FLUSHO; + #[cfg(any(target_os = "freebsd", + target_os = "dragonfly", +@@ -894,13 +980,16 @@ libc_bitflags! { + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + NOKERNINFO; ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + PENDIN; + NOFLSH; + } + } + +-cfg_if!{ ++cfg_if! { + if #[cfg(any(target_os = "freebsd", + target_os = "dragonfly", + target_os = "ios", +@@ -908,25 +997,29 @@ cfg_if!{ + target_os = "netbsd", + target_os = "openbsd"))] { + /// Get input baud rate (see +- /// [cfgetispeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetispeed.html)). ++ /// [cfgetispeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetispeed.html)). + /// + /// `cfgetispeed()` extracts the input baud rate from the given `Termios` structure. ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] + pub fn cfgetispeed(termios: &Termios) -> u32 { + let inner_termios = termios.get_libc_termios(); + unsafe { libc::cfgetispeed(&*inner_termios) as u32 } + } + + /// Get output baud rate (see +- /// [cfgetospeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetospeed.html)). ++ /// [cfgetospeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetospeed.html)). + /// + /// `cfgetospeed()` extracts the output baud rate from the given `Termios` structure. ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] + pub fn cfgetospeed(termios: &Termios) -> u32 { + let inner_termios = termios.get_libc_termios(); + unsafe { libc::cfgetospeed(&*inner_termios) as u32 } + } + + /// Set input baud rate (see +- /// [cfsetispeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetispeed.html)). ++ /// [cfsetispeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetispeed.html)). + /// + /// `cfsetispeed()` sets the intput baud rate in the given `Termios` structure. + pub fn cfsetispeed>(termios: &mut Termios, baud: T) -> Result<()> { +@@ -937,7 +1030,7 @@ cfg_if!{ + } + + /// Set output baud rate (see +- /// [cfsetospeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetospeed.html)). ++ /// [cfsetospeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetospeed.html)). + /// + /// `cfsetospeed()` sets the output baud rate in the given termios structure. + pub fn cfsetospeed>(termios: &mut Termios, baud: T) -> Result<()> { +@@ -962,7 +1055,7 @@ cfg_if!{ + use std::convert::TryInto; + + /// Get input baud rate (see +- /// [cfgetispeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetispeed.html)). ++ /// [cfgetispeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetispeed.html)). + /// + /// `cfgetispeed()` extracts the input baud rate from the given `Termios` structure. + pub fn cfgetispeed(termios: &Termios) -> BaudRate { +@@ -971,7 +1064,7 @@ cfg_if!{ + } + + /// Get output baud rate (see +- /// [cfgetospeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetospeed.html)). ++ /// [cfgetospeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetospeed.html)). + /// + /// `cfgetospeed()` extracts the output baud rate from the given `Termios` structure. + pub fn cfgetospeed(termios: &Termios) -> BaudRate { +@@ -980,7 +1073,7 @@ cfg_if!{ + } + + /// Set input baud rate (see +- /// [cfsetispeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetispeed.html)). ++ /// [cfsetispeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetispeed.html)). + /// + /// `cfsetispeed()` sets the intput baud rate in the given `Termios` structure. + pub fn cfsetispeed(termios: &mut Termios, baud: BaudRate) -> Result<()> { +@@ -991,7 +1084,7 @@ cfg_if!{ + } + + /// Set output baud rate (see +- /// [cfsetospeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetospeed.html)). ++ /// [cfsetospeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetospeed.html)). + /// + /// `cfsetospeed()` sets the output baud rate in the given `Termios` structure. + pub fn cfsetospeed(termios: &mut Termios, baud: BaudRate) -> Result<()> { +@@ -1006,6 +1099,7 @@ cfg_if!{ + /// + /// `cfsetspeed()` sets the input and output baud rate in the given `Termios` structure. Note that + /// this is part of the 4.4BSD standard and not part of POSIX. ++ #[cfg(not(target_os = "haiku"))] + pub fn cfsetspeed(termios: &mut Termios, baud: BaudRate) -> Result<()> { + let inner_termios = unsafe { termios.get_libc_termios_mut() }; + let res = unsafe { libc::cfsetspeed(inner_termios, baud as libc::speed_t) }; +@@ -1016,7 +1110,7 @@ cfg_if!{ + } + + /// Configures the port to something like the "raw" mode of the old Version 7 terminal driver (see +-/// [termios(3)](http://man7.org/linux/man-pages/man3/termios.3.html)). ++/// [termios(3)](https://man7.org/linux/man-pages/man3/termios.3.html)). + /// + /// `cfmakeraw()` configures the termios structure such that input is available character-by- + /// character, echoing is disabled, and all special input and output processing is disabled. Note +@@ -1034,6 +1128,7 @@ pub fn cfmakeraw(termios: &mut Termios) { + /// + /// Note that this is a non-standard function, available on FreeBSD. + #[cfg(target_os = "freebsd")] ++#[cfg_attr(docsrs, doc(cfg(all())))] + pub fn cfmakesane(termios: &mut Termios) { + let inner_termios = unsafe { termios.get_libc_termios_mut() }; + unsafe { +@@ -1043,7 +1138,7 @@ pub fn cfmakesane(termios: &mut Termios) { + } + + /// Return the configuration of a port +-/// [tcgetattr(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetattr.html)). ++/// [tcgetattr(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetattr.html)). + /// + /// `tcgetattr()` returns a `Termios` structure with the current configuration for a port. Modifying + /// this structure *will not* reconfigure the port, instead the modifications should be done to +@@ -1059,24 +1154,27 @@ pub fn tcgetattr(fd: RawFd) -> Result { + } + + /// Set the configuration for a terminal (see +-/// [tcsetattr(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsetattr.html)). ++/// [tcsetattr(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsetattr.html)). + /// + /// `tcsetattr()` reconfigures the given port based on a given `Termios` structure. This change + /// takes affect at a time specified by `actions`. Note that this function may return success if + /// *any* of the parameters were successfully set, not only if all were set successfully. + pub fn tcsetattr(fd: RawFd, actions: SetArg, termios: &Termios) -> Result<()> { + let inner_termios = termios.get_libc_termios(); +- Errno::result(unsafe { libc::tcsetattr(fd, actions as c_int, &*inner_termios) }).map(drop) ++ Errno::result(unsafe { ++ libc::tcsetattr(fd, actions as c_int, &*inner_termios) ++ }) ++ .map(drop) + } + + /// Block until all output data is written (see +-/// [tcdrain(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcdrain.html)). ++/// [tcdrain(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcdrain.html)). + pub fn tcdrain(fd: RawFd) -> Result<()> { + Errno::result(unsafe { libc::tcdrain(fd) }).map(drop) + } + + /// Suspend or resume the transmission or reception of data (see +-/// [tcflow(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcflow.html)). ++/// [tcflow(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcflow.html)). + /// + /// `tcflow()` suspends of resumes the transmission or reception of data for the given port + /// depending on the value of `action`. +@@ -1085,7 +1183,7 @@ pub fn tcflow(fd: RawFd, action: FlowArg) -> Result<()> { + } + + /// Discard data in the output or input queue (see +-/// [tcflush(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcflush.html)). ++/// [tcflush(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcflush.html)). + /// + /// `tcflush()` will discard data for a terminal port in the input queue, output queue, or both + /// depending on the value of `action`. +@@ -1094,7 +1192,7 @@ pub fn tcflush(fd: RawFd, action: FlushArg) -> Result<()> { + } + + /// Send a break for a specific duration (see +-/// [tcsendbreak(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsendbreak.html)). ++/// [tcsendbreak(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsendbreak.html)). + /// + /// When using asynchronous data transmission `tcsendbreak()` will transmit a continuous stream + /// of zero-valued bits for an implementation-defined duration. +@@ -1102,21 +1200,28 @@ pub fn tcsendbreak(fd: RawFd, duration: c_int) -> Result<()> { + Errno::result(unsafe { libc::tcsendbreak(fd, duration) }).map(drop) + } + ++feature! { ++#![feature = "process"] + /// Get the session controlled by the given terminal (see +-/// [tcgetsid(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetsid.html)). ++/// [tcgetsid(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetsid.html)). + pub fn tcgetsid(fd: RawFd) -> Result { + let res = unsafe { libc::tcgetsid(fd) }; + + Errno::result(res).map(Pid::from_raw) + } ++} + + #[cfg(test)] + mod test { + use super::*; ++ use std::convert::TryFrom; + + #[test] + fn try_from() { + assert_eq!(Ok(BaudRate::B0), BaudRate::try_from(libc::B0)); +- assert!(BaudRate::try_from(999999999).is_err()); ++ #[cfg(not(target_os = "haiku"))] ++ BaudRate::try_from(999999999).expect_err("assertion failed"); ++ #[cfg(target_os = "haiku")] ++ BaudRate::try_from(99).expect_err("assertion failed"); + } + } +diff --git a/vendor/nix/src/sys/time.rs b/vendor/nix/src/sys/time.rs +index 606bbd9..0042c45 100644 +--- a/vendor/nix/src/sys/time.rs ++++ b/vendor/nix/src/sys/time.rs +@@ -1,7 +1,144 @@ +-use std::{cmp, fmt, ops}; ++#[cfg_attr(target_env = "musl", allow(deprecated))] ++// https://github.com/rust-lang/libc/issues/1848 ++pub use libc::{suseconds_t, time_t}; ++use libc::{timespec, timeval}; + use std::convert::From; +-use libc::{c_long, timespec, timeval}; +-pub use libc::{time_t, suseconds_t}; ++use std::time::Duration; ++use std::{cmp, fmt, ops}; ++ ++const fn zero_init_timespec() -> timespec { ++ // `std::mem::MaybeUninit::zeroed()` is not yet a const fn ++ // (https://github.com/rust-lang/rust/issues/91850) so we will instead initialize an array of ++ // the appropriate size to zero and then transmute it to a timespec value. ++ unsafe { std::mem::transmute([0u8; std::mem::size_of::()]) } ++} ++ ++#[cfg(any( ++ all(feature = "time", any(target_os = "android", target_os = "linux")), ++ all( ++ any( ++ target_os = "freebsd", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "netbsd" ++ ), ++ feature = "time", ++ feature = "signal" ++ ) ++))] ++pub(crate) mod timer { ++ use crate::sys::time::{zero_init_timespec, TimeSpec}; ++ use bitflags::bitflags; ++ ++ #[derive(Debug, Clone, Copy)] ++ pub(crate) struct TimerSpec(libc::itimerspec); ++ ++ impl TimerSpec { ++ pub const fn none() -> Self { ++ Self(libc::itimerspec { ++ it_interval: zero_init_timespec(), ++ it_value: zero_init_timespec(), ++ }) ++ } ++ } ++ ++ impl AsMut for TimerSpec { ++ fn as_mut(&mut self) -> &mut libc::itimerspec { ++ &mut self.0 ++ } ++ } ++ ++ impl AsRef for TimerSpec { ++ fn as_ref(&self) -> &libc::itimerspec { ++ &self.0 ++ } ++ } ++ ++ impl From for TimerSpec { ++ fn from(expiration: Expiration) -> TimerSpec { ++ match expiration { ++ Expiration::OneShot(t) => TimerSpec(libc::itimerspec { ++ it_interval: zero_init_timespec(), ++ it_value: *t.as_ref(), ++ }), ++ Expiration::IntervalDelayed(start, interval) => { ++ TimerSpec(libc::itimerspec { ++ it_interval: *interval.as_ref(), ++ it_value: *start.as_ref(), ++ }) ++ } ++ Expiration::Interval(t) => TimerSpec(libc::itimerspec { ++ it_interval: *t.as_ref(), ++ it_value: *t.as_ref(), ++ }), ++ } ++ } ++ } ++ ++ /// An enumeration allowing the definition of the expiration time of an alarm, ++ /// recurring or not. ++ #[derive(Debug, Clone, Copy, Eq, PartialEq)] ++ pub enum Expiration { ++ /// Alarm will trigger once after the time given in `TimeSpec` ++ OneShot(TimeSpec), ++ /// Alarm will trigger after a specified delay and then every interval of ++ /// time. ++ IntervalDelayed(TimeSpec, TimeSpec), ++ /// Alarm will trigger every specified interval of time. ++ Interval(TimeSpec), ++ } ++ ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ bitflags! { ++ /// Flags that are used for arming the timer. ++ pub struct TimerSetTimeFlags: libc::c_int { ++ const TFD_TIMER_ABSTIME = libc::TFD_TIMER_ABSTIME; ++ } ++ } ++ #[cfg(any( ++ target_os = "freebsd", ++ target_os = "netbsd", ++ target_os = "dragonfly", ++ target_os = "illumos" ++ ))] ++ bitflags! { ++ /// Flags that are used for arming the timer. ++ pub struct TimerSetTimeFlags: libc::c_int { ++ const TFD_TIMER_ABSTIME = libc::TIMER_ABSTIME; ++ } ++ } ++ ++ impl From for Expiration { ++ fn from(timerspec: TimerSpec) -> Expiration { ++ match timerspec { ++ TimerSpec(libc::itimerspec { ++ it_interval: ++ libc::timespec { ++ tv_sec: 0, ++ tv_nsec: 0, ++ .. ++ }, ++ it_value: ts, ++ }) => Expiration::OneShot(ts.into()), ++ TimerSpec(libc::itimerspec { ++ it_interval: int_ts, ++ it_value: val_ts, ++ }) => { ++ if (int_ts.tv_sec == val_ts.tv_sec) ++ && (int_ts.tv_nsec == val_ts.tv_nsec) ++ { ++ Expiration::Interval(int_ts.into()) ++ } else { ++ Expiration::IntervalDelayed( ++ val_ts.into(), ++ int_ts.into(), ++ ) ++ } ++ } ++ } ++ } ++ } ++} + + pub trait TimeValLike: Sized { + #[inline] +@@ -11,14 +148,16 @@ pub trait TimeValLike: Sized { + + #[inline] + fn hours(hours: i64) -> Self { +- let secs = hours.checked_mul(SECS_PER_HOUR) ++ let secs = hours ++ .checked_mul(SECS_PER_HOUR) + .expect("TimeValLike::hours ouf of bounds"); + Self::seconds(secs) + } + + #[inline] + fn minutes(minutes: i64) -> Self { +- let secs = minutes.checked_mul(SECS_PER_MINUTE) ++ let secs = minutes ++ .checked_mul(SECS_PER_MINUTE) + .expect("TimeValLike::minutes out of bounds"); + Self::seconds(secs) + } +@@ -53,13 +192,37 @@ const SECS_PER_MINUTE: i64 = 60; + const SECS_PER_HOUR: i64 = 3600; + + #[cfg(target_pointer_width = "64")] +-const TS_MAX_SECONDS: i64 = (::std::i64::MAX / NANOS_PER_SEC) - 1; ++const TS_MAX_SECONDS: i64 = (i64::MAX / NANOS_PER_SEC) - 1; + + #[cfg(target_pointer_width = "32")] +-const TS_MAX_SECONDS: i64 = ::std::isize::MAX as i64; ++const TS_MAX_SECONDS: i64 = isize::MAX as i64; + + const TS_MIN_SECONDS: i64 = -TS_MAX_SECONDS; + ++// x32 compatibility ++// See https://sourceware.org/bugzilla/show_bug.cgi?id=16437 ++#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] ++type timespec_tv_nsec_t = i64; ++#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] ++type timespec_tv_nsec_t = libc::c_long; ++ ++impl From for TimeSpec { ++ fn from(ts: timespec) -> Self { ++ Self(ts) ++ } ++} ++ ++impl From for TimeSpec { ++ fn from(duration: Duration) -> Self { ++ Self::from_duration(duration) ++ } ++} ++ ++impl From for Duration { ++ fn from(timespec: TimeSpec) -> Self { ++ Duration::new(timespec.0.tv_sec as u64, timespec.0.tv_nsec as u32) ++ } ++} + + impl AsRef for TimeSpec { + fn as_ref(&self) -> ×pec { +@@ -67,6 +230,12 @@ impl AsRef for TimeSpec { + } + } + ++impl AsMut for TimeSpec { ++ fn as_mut(&mut self) -> &mut timespec { ++ &mut self.0 ++ } ++} ++ + impl Ord for TimeSpec { + // The implementation of cmp is simplified by assuming that the struct is + // normalized. That is, tv_nsec must always be within [0, 1_000_000_000) +@@ -87,15 +256,23 @@ impl PartialOrd for TimeSpec { + + impl TimeValLike for TimeSpec { + #[inline] ++ #[cfg_attr(target_env = "musl", allow(deprecated))] ++ // https://github.com/rust-lang/libc/issues/1848 + fn seconds(seconds: i64) -> TimeSpec { +- assert!(seconds >= TS_MIN_SECONDS && seconds <= TS_MAX_SECONDS, +- "TimeSpec out of bounds; seconds={}", seconds); +- TimeSpec(timespec {tv_sec: seconds as time_t, tv_nsec: 0 }) ++ assert!( ++ (TS_MIN_SECONDS..=TS_MAX_SECONDS).contains(&seconds), ++ "TimeSpec out of bounds; seconds={}", ++ seconds ++ ); ++ let mut ts = zero_init_timespec(); ++ ts.tv_sec = seconds as time_t; ++ TimeSpec(ts) + } + + #[inline] + fn milliseconds(milliseconds: i64) -> TimeSpec { +- let nanoseconds = milliseconds.checked_mul(1_000_000) ++ let nanoseconds = milliseconds ++ .checked_mul(1_000_000) + .expect("TimeSpec::milliseconds out of bounds"); + + TimeSpec::nanoseconds(nanoseconds) +@@ -104,7 +281,8 @@ impl TimeValLike for TimeSpec { + /// Makes a new `TimeSpec` with given number of microseconds. + #[inline] + fn microseconds(microseconds: i64) -> TimeSpec { +- let nanoseconds = microseconds.checked_mul(1_000) ++ let nanoseconds = microseconds ++ .checked_mul(1_000) + .expect("TimeSpec::milliseconds out of bounds"); + + TimeSpec::nanoseconds(nanoseconds) +@@ -112,14 +290,22 @@ impl TimeValLike for TimeSpec { + + /// Makes a new `TimeSpec` with given number of nanoseconds. + #[inline] ++ #[cfg_attr(target_env = "musl", allow(deprecated))] ++ // https://github.com/rust-lang/libc/issues/1848 + fn nanoseconds(nanoseconds: i64) -> TimeSpec { + let (secs, nanos) = div_mod_floor_64(nanoseconds, NANOS_PER_SEC); +- assert!(secs >= TS_MIN_SECONDS && secs <= TS_MAX_SECONDS, +- "TimeSpec out of bounds"); +- TimeSpec(timespec {tv_sec: secs as time_t, +- tv_nsec: nanos as c_long }) +- } +- ++ assert!( ++ (TS_MIN_SECONDS..=TS_MAX_SECONDS).contains(&secs), ++ "TimeSpec out of bounds" ++ ); ++ let mut ts = zero_init_timespec(); ++ ts.tv_sec = secs as time_t; ++ ts.tv_nsec = nanos as timespec_tv_nsec_t; ++ TimeSpec(ts) ++ } ++ ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] + fn num_seconds(&self) -> i64 { + if self.tv_sec() < 0 && self.tv_nsec() > 0 { + (self.tv_sec() + 1) as i64 +@@ -133,9 +319,11 @@ impl TimeValLike for TimeSpec { + } + + fn num_microseconds(&self) -> i64 { +- self.num_nanoseconds() / 1_000_000_000 ++ self.num_nanoseconds() / 1_000 + } + ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] + fn num_nanoseconds(&self) -> i64 { + let secs = self.num_seconds() * 1_000_000_000; + let nsec = self.nanos_mod_sec(); +@@ -144,21 +332,44 @@ impl TimeValLike for TimeSpec { + } + + impl TimeSpec { +- fn nanos_mod_sec(&self) -> c_long { ++ /// Construct a new `TimeSpec` from its components ++ #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 ++ pub const fn new(seconds: time_t, nanoseconds: timespec_tv_nsec_t) -> Self { ++ let mut ts = zero_init_timespec(); ++ ts.tv_sec = seconds; ++ ts.tv_nsec = nanoseconds; ++ Self(ts) ++ } ++ ++ fn nanos_mod_sec(&self) -> timespec_tv_nsec_t { + if self.tv_sec() < 0 && self.tv_nsec() > 0 { +- self.tv_nsec() - NANOS_PER_SEC as c_long ++ self.tv_nsec() - NANOS_PER_SEC as timespec_tv_nsec_t + } else { + self.tv_nsec() + } + } + +- pub fn tv_sec(&self) -> time_t { ++ #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 ++ pub const fn tv_sec(&self) -> time_t { + self.0.tv_sec + } + +- pub fn tv_nsec(&self) -> c_long { ++ pub const fn tv_nsec(&self) -> timespec_tv_nsec_t { + self.0.tv_nsec + } ++ ++ #[cfg_attr(target_env = "musl", allow(deprecated))] ++ // https://github.com/rust-lang/libc/issues/1848 ++ pub const fn from_duration(duration: Duration) -> Self { ++ let mut ts = zero_init_timespec(); ++ ts.tv_sec = duration.as_secs() as time_t; ++ ts.tv_nsec = duration.subsec_nanos() as timespec_tv_nsec_t; ++ TimeSpec(ts) ++ } ++ ++ pub const fn from_timespec(timespec: timespec) -> Self { ++ Self(timespec) ++ } + } + + impl ops::Neg for TimeSpec { +@@ -173,8 +384,7 @@ impl ops::Add for TimeSpec { + type Output = TimeSpec; + + fn add(self, rhs: TimeSpec) -> TimeSpec { +- TimeSpec::nanoseconds( +- self.num_nanoseconds() + rhs.num_nanoseconds()) ++ TimeSpec::nanoseconds(self.num_nanoseconds() + rhs.num_nanoseconds()) + } + } + +@@ -182,8 +392,7 @@ impl ops::Sub for TimeSpec { + type Output = TimeSpec; + + fn sub(self, rhs: TimeSpec) -> TimeSpec { +- TimeSpec::nanoseconds( +- self.num_nanoseconds() - rhs.num_nanoseconds()) ++ TimeSpec::nanoseconds(self.num_nanoseconds() - rhs.num_nanoseconds()) + } + } + +@@ -191,7 +400,9 @@ impl ops::Mul for TimeSpec { + type Output = TimeSpec; + + fn mul(self, rhs: i32) -> TimeSpec { +- let usec = self.num_nanoseconds().checked_mul(i64::from(rhs)) ++ let usec = self ++ .num_nanoseconds() ++ .checked_mul(i64::from(rhs)) + .expect("TimeSpec multiply out of bounds"); + + TimeSpec::nanoseconds(usec) +@@ -237,19 +448,17 @@ impl fmt::Display for TimeSpec { + } + } + +- +- +-#[repr(C)] ++#[repr(transparent)] + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct TimeVal(timeval); + + const MICROS_PER_SEC: i64 = 1_000_000; + + #[cfg(target_pointer_width = "64")] +-const TV_MAX_SECONDS: i64 = (::std::i64::MAX / MICROS_PER_SEC) - 1; ++const TV_MAX_SECONDS: i64 = (i64::MAX / MICROS_PER_SEC) - 1; + + #[cfg(target_pointer_width = "32")] +-const TV_MAX_SECONDS: i64 = ::std::isize::MAX as i64; ++const TV_MAX_SECONDS: i64 = isize::MAX as i64; + + const TV_MIN_SECONDS: i64 = -TV_MAX_SECONDS; + +@@ -259,6 +468,12 @@ impl AsRef for TimeVal { + } + } + ++impl AsMut for TimeVal { ++ fn as_mut(&mut self) -> &mut timeval { ++ &mut self.0 ++ } ++} ++ + impl Ord for TimeVal { + // The implementation of cmp is simplified by assuming that the struct is + // normalized. That is, tv_usec must always be within [0, 1_000_000) +@@ -280,14 +495,23 @@ impl PartialOrd for TimeVal { + impl TimeValLike for TimeVal { + #[inline] + fn seconds(seconds: i64) -> TimeVal { +- assert!(seconds >= TV_MIN_SECONDS && seconds <= TV_MAX_SECONDS, +- "TimeVal out of bounds; seconds={}", seconds); +- TimeVal(timeval {tv_sec: seconds as time_t, tv_usec: 0 }) ++ assert!( ++ (TV_MIN_SECONDS..=TV_MAX_SECONDS).contains(&seconds), ++ "TimeVal out of bounds; seconds={}", ++ seconds ++ ); ++ #[cfg_attr(target_env = "musl", allow(deprecated))] ++ // https://github.com/rust-lang/libc/issues/1848 ++ TimeVal(timeval { ++ tv_sec: seconds as time_t, ++ tv_usec: 0, ++ }) + } + + #[inline] + fn milliseconds(milliseconds: i64) -> TimeVal { +- let microseconds = milliseconds.checked_mul(1_000) ++ let microseconds = milliseconds ++ .checked_mul(1_000) + .expect("TimeVal::milliseconds out of bounds"); + + TimeVal::microseconds(microseconds) +@@ -297,10 +521,16 @@ impl TimeValLike for TimeVal { + #[inline] + fn microseconds(microseconds: i64) -> TimeVal { + let (secs, micros) = div_mod_floor_64(microseconds, MICROS_PER_SEC); +- assert!(secs >= TV_MIN_SECONDS && secs <= TV_MAX_SECONDS, +- "TimeVal out of bounds"); +- TimeVal(timeval {tv_sec: secs as time_t, +- tv_usec: micros as suseconds_t }) ++ assert!( ++ (TV_MIN_SECONDS..=TV_MAX_SECONDS).contains(&secs), ++ "TimeVal out of bounds" ++ ); ++ #[cfg_attr(target_env = "musl", allow(deprecated))] ++ // https://github.com/rust-lang/libc/issues/1848 ++ TimeVal(timeval { ++ tv_sec: secs as time_t, ++ tv_usec: micros as suseconds_t, ++ }) + } + + /// Makes a new `TimeVal` with given number of nanoseconds. Some precision +@@ -309,12 +539,20 @@ impl TimeValLike for TimeVal { + fn nanoseconds(nanoseconds: i64) -> TimeVal { + let microseconds = nanoseconds / 1000; + let (secs, micros) = div_mod_floor_64(microseconds, MICROS_PER_SEC); +- assert!(secs >= TV_MIN_SECONDS && secs <= TV_MAX_SECONDS, +- "TimeVal out of bounds"); +- TimeVal(timeval {tv_sec: secs as time_t, +- tv_usec: micros as suseconds_t }) +- } +- ++ assert!( ++ (TV_MIN_SECONDS..=TV_MAX_SECONDS).contains(&secs), ++ "TimeVal out of bounds" ++ ); ++ #[cfg_attr(target_env = "musl", allow(deprecated))] ++ // https://github.com/rust-lang/libc/issues/1848 ++ TimeVal(timeval { ++ tv_sec: secs as time_t, ++ tv_usec: micros as suseconds_t, ++ }) ++ } ++ ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] + fn num_seconds(&self) -> i64 { + if self.tv_sec() < 0 && self.tv_usec() > 0 { + (self.tv_sec() + 1) as i64 +@@ -327,6 +565,8 @@ impl TimeValLike for TimeVal { + self.num_microseconds() / 1_000 + } + ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] + fn num_microseconds(&self) -> i64 { + let secs = self.num_seconds() * 1_000_000; + let usec = self.micros_mod_sec(); +@@ -339,6 +579,15 @@ impl TimeValLike for TimeVal { + } + + impl TimeVal { ++ /// Construct a new `TimeVal` from its components ++ #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 ++ pub const fn new(seconds: time_t, microseconds: suseconds_t) -> Self { ++ Self(timeval { ++ tv_sec: seconds, ++ tv_usec: microseconds, ++ }) ++ } ++ + fn micros_mod_sec(&self) -> suseconds_t { + if self.tv_sec() < 0 && self.tv_usec() > 0 { + self.tv_usec() - MICROS_PER_SEC as suseconds_t +@@ -347,11 +596,12 @@ impl TimeVal { + } + } + +- pub fn tv_sec(&self) -> time_t { ++ #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 ++ pub const fn tv_sec(&self) -> time_t { + self.0.tv_sec + } + +- pub fn tv_usec(&self) -> suseconds_t { ++ pub const fn tv_usec(&self) -> suseconds_t { + self.0.tv_usec + } + } +@@ -368,8 +618,7 @@ impl ops::Add for TimeVal { + type Output = TimeVal; + + fn add(self, rhs: TimeVal) -> TimeVal { +- TimeVal::microseconds( +- self.num_microseconds() + rhs.num_microseconds()) ++ TimeVal::microseconds(self.num_microseconds() + rhs.num_microseconds()) + } + } + +@@ -377,8 +626,7 @@ impl ops::Sub for TimeVal { + type Output = TimeVal; + + fn sub(self, rhs: TimeVal) -> TimeVal { +- TimeVal::microseconds( +- self.num_microseconds() - rhs.num_microseconds()) ++ TimeVal::microseconds(self.num_microseconds() - rhs.num_microseconds()) + } + } + +@@ -386,7 +634,9 @@ impl ops::Mul for TimeVal { + type Output = TimeVal; + + fn mul(self, rhs: i32) -> TimeVal { +- let usec = self.num_microseconds().checked_mul(i64::from(rhs)) ++ let usec = self ++ .num_microseconds() ++ .checked_mul(i64::from(rhs)) + .expect("TimeVal multiply out of bounds"); + + TimeVal::microseconds(usec) +@@ -444,18 +694,16 @@ fn div_mod_floor_64(this: i64, other: i64) -> (i64, i64) { + #[inline] + fn div_floor_64(this: i64, other: i64) -> i64 { + match div_rem_64(this, other) { +- (d, r) if (r > 0 && other < 0) +- || (r < 0 && other > 0) => d - 1, +- (d, _) => d, ++ (d, r) if (r > 0 && other < 0) || (r < 0 && other > 0) => d - 1, ++ (d, _) => d, + } + } + + #[inline] + fn mod_floor_64(this: i64, other: i64) -> i64 { + match this % other { +- r if (r > 0 && other < 0) +- || (r < 0 && other > 0) => r + other, +- r => r, ++ r if (r > 0 && other < 0) || (r < 0 && other > 0) => r + other, ++ r => r, + } + } + +@@ -467,14 +715,28 @@ fn div_rem_64(this: i64, other: i64) -> (i64, i64) { + #[cfg(test)] + mod test { + use super::{TimeSpec, TimeVal, TimeValLike}; ++ use std::time::Duration; + + #[test] + pub fn test_timespec() { +- assert!(TimeSpec::seconds(1) != TimeSpec::zero()); +- assert_eq!(TimeSpec::seconds(1) + TimeSpec::seconds(2), +- TimeSpec::seconds(3)); +- assert_eq!(TimeSpec::minutes(3) + TimeSpec::seconds(2), +- TimeSpec::seconds(182)); ++ assert_ne!(TimeSpec::seconds(1), TimeSpec::zero()); ++ assert_eq!( ++ TimeSpec::seconds(1) + TimeSpec::seconds(2), ++ TimeSpec::seconds(3) ++ ); ++ assert_eq!( ++ TimeSpec::minutes(3) + TimeSpec::seconds(2), ++ TimeSpec::seconds(182) ++ ); ++ } ++ ++ #[test] ++ pub fn test_timespec_from() { ++ let duration = Duration::new(123, 123_456_789); ++ let timespec = TimeSpec::nanoseconds(123_123_456_789); ++ ++ assert_eq!(TimeSpec::from(duration), timespec); ++ assert_eq!(Duration::from(timespec), duration); + } + + #[test] +@@ -487,7 +749,7 @@ mod test { + + #[test] + pub fn test_timespec_ord() { +- assert!(TimeSpec::seconds(1) == TimeSpec::nanoseconds(1_000_000_000)); ++ assert_eq!(TimeSpec::seconds(1), TimeSpec::nanoseconds(1_000_000_000)); + assert!(TimeSpec::seconds(1) < TimeSpec::nanoseconds(1_000_000_001)); + assert!(TimeSpec::seconds(1) > TimeSpec::nanoseconds(999_999_999)); + assert!(TimeSpec::seconds(-1) < TimeSpec::nanoseconds(-999_999_999)); +@@ -500,22 +762,29 @@ mod test { + assert_eq!(TimeSpec::seconds(42).to_string(), "42 seconds"); + assert_eq!(TimeSpec::milliseconds(42).to_string(), "0.042 seconds"); + assert_eq!(TimeSpec::microseconds(42).to_string(), "0.000042 seconds"); +- assert_eq!(TimeSpec::nanoseconds(42).to_string(), "0.000000042 seconds"); ++ assert_eq!( ++ TimeSpec::nanoseconds(42).to_string(), ++ "0.000000042 seconds" ++ ); + assert_eq!(TimeSpec::seconds(-86401).to_string(), "-86401 seconds"); + } + + #[test] + pub fn test_timeval() { +- assert!(TimeVal::seconds(1) != TimeVal::zero()); +- assert_eq!(TimeVal::seconds(1) + TimeVal::seconds(2), +- TimeVal::seconds(3)); +- assert_eq!(TimeVal::minutes(3) + TimeVal::seconds(2), +- TimeVal::seconds(182)); ++ assert_ne!(TimeVal::seconds(1), TimeVal::zero()); ++ assert_eq!( ++ TimeVal::seconds(1) + TimeVal::seconds(2), ++ TimeVal::seconds(3) ++ ); ++ assert_eq!( ++ TimeVal::minutes(3) + TimeVal::seconds(2), ++ TimeVal::seconds(182) ++ ); + } + + #[test] + pub fn test_timeval_ord() { +- assert!(TimeVal::seconds(1) == TimeVal::microseconds(1_000_000)); ++ assert_eq!(TimeVal::seconds(1), TimeVal::microseconds(1_000_000)); + assert!(TimeVal::seconds(1) < TimeVal::microseconds(1_000_001)); + assert!(TimeVal::seconds(1) > TimeVal::microseconds(999_999)); + assert!(TimeVal::seconds(-1) < TimeVal::microseconds(-999_999)); +diff --git a/vendor/nix/src/sys/timer.rs b/vendor/nix/src/sys/timer.rs +new file mode 100644 +index 0000000..e1a3405 +--- /dev/null ++++ b/vendor/nix/src/sys/timer.rs +@@ -0,0 +1,187 @@ ++//! Timer API via signals. ++//! ++//! Timer is a POSIX API to create timers and get expiration notifications ++//! through queued Unix signals, for the current process. This is similar to ++//! Linux's timerfd mechanism, except that API is specific to Linux and makes ++//! use of file polling. ++//! ++//! For more documentation, please read [timer_create](https://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_create.html). ++//! ++//! # Examples ++//! ++//! Create an interval timer that signals SIGALARM every 250 milliseconds. ++//! ++//! ```no_run ++//! use nix::sys::signal::{self, SigEvent, SigHandler, SigevNotify, Signal}; ++//! use nix::sys::timer::{Expiration, Timer, TimerSetTimeFlags}; ++//! use nix::time::ClockId; ++//! use std::convert::TryFrom; ++//! use std::sync::atomic::{AtomicU64, Ordering}; ++//! use std::thread::yield_now; ++//! use std::time::Duration; ++//! ++//! const SIG: Signal = Signal::SIGALRM; ++//! static ALARMS: AtomicU64 = AtomicU64::new(0); ++//! ++//! extern "C" fn handle_alarm(signal: libc::c_int) { ++//! let signal = Signal::try_from(signal).unwrap(); ++//! if signal == SIG { ++//! ALARMS.fetch_add(1, Ordering::Relaxed); ++//! } ++//! } ++//! ++//! fn main() { ++//! let clockid = ClockId::CLOCK_MONOTONIC; ++//! let sigevent = SigEvent::new(SigevNotify::SigevSignal { ++//! signal: SIG, ++//! si_value: 0, ++//! }); ++//! ++//! let mut timer = Timer::new(clockid, sigevent).unwrap(); ++//! let expiration = Expiration::Interval(Duration::from_millis(250).into()); ++//! let flags = TimerSetTimeFlags::empty(); ++//! timer.set(expiration, flags).expect("could not set timer"); ++//! ++//! let handler = SigHandler::Handler(handle_alarm); ++//! unsafe { signal::signal(SIG, handler) }.unwrap(); ++//! ++//! loop { ++//! let alarms = ALARMS.load(Ordering::Relaxed); ++//! if alarms >= 10 { ++//! println!("total alarms handled: {}", alarms); ++//! break; ++//! } ++//! yield_now() ++//! } ++//! } ++//! ``` ++use crate::sys::signal::SigEvent; ++use crate::sys::time::timer::TimerSpec; ++pub use crate::sys::time::timer::{Expiration, TimerSetTimeFlags}; ++use crate::time::ClockId; ++use crate::{errno::Errno, Result}; ++use core::mem; ++ ++/// A Unix signal per-process timer. ++#[derive(Debug)] ++#[repr(transparent)] ++pub struct Timer(libc::timer_t); ++ ++impl Timer { ++ /// Creates a new timer based on the clock defined by `clockid`. The details ++ /// of the signal and its handler are defined by the passed `sigevent`. ++ #[doc(alias("timer_create"))] ++ pub fn new(clockid: ClockId, mut sigevent: SigEvent) -> Result { ++ let mut timer_id: mem::MaybeUninit = ++ mem::MaybeUninit::uninit(); ++ Errno::result(unsafe { ++ libc::timer_create( ++ clockid.as_raw(), ++ sigevent.as_mut_ptr(), ++ timer_id.as_mut_ptr(), ++ ) ++ }) ++ .map(|_| { ++ // SAFETY: libc::timer_create is responsible for initializing ++ // timer_id. ++ unsafe { Self(timer_id.assume_init()) } ++ }) ++ } ++ ++ /// Set a new alarm on the timer. ++ /// ++ /// # Types of alarm ++ /// ++ /// There are 3 types of alarms you can set: ++ /// ++ /// - one shot: the alarm will trigger once after the specified amount of ++ /// time. ++ /// Example: I want an alarm to go off in 60s and then disable itself. ++ /// ++ /// - interval: the alarm will trigger every specified interval of time. ++ /// Example: I want an alarm to go off every 60s. The alarm will first ++ /// go off 60s after I set it and every 60s after that. The alarm will ++ /// not disable itself. ++ /// ++ /// - interval delayed: the alarm will trigger after a certain amount of ++ /// time and then trigger at a specified interval. ++ /// Example: I want an alarm to go off every 60s but only start in 1h. ++ /// The alarm will first trigger 1h after I set it and then every 60s ++ /// after that. The alarm will not disable itself. ++ /// ++ /// # Relative vs absolute alarm ++ /// ++ /// If you do not set any `TimerSetTimeFlags`, then the `TimeSpec` you pass ++ /// to the `Expiration` you want is relative. If however you want an alarm ++ /// to go off at a certain point in time, you can set `TFD_TIMER_ABSTIME`. ++ /// Then the one shot TimeSpec and the delay TimeSpec of the delayed ++ /// interval are going to be interpreted as absolute. ++ /// ++ /// # Disabling alarms ++ /// ++ /// Note: Only one alarm can be set for any given timer. Setting a new alarm ++ /// actually removes the previous one. ++ /// ++ /// Note: Setting a one shot alarm with a 0s TimeSpec disable the alarm ++ /// altogether. ++ #[doc(alias("timer_settime"))] ++ pub fn set( ++ &mut self, ++ expiration: Expiration, ++ flags: TimerSetTimeFlags, ++ ) -> Result<()> { ++ let timerspec: TimerSpec = expiration.into(); ++ Errno::result(unsafe { ++ libc::timer_settime( ++ self.0, ++ flags.bits(), ++ timerspec.as_ref(), ++ core::ptr::null_mut(), ++ ) ++ }) ++ .map(drop) ++ } ++ ++ /// Get the parameters for the alarm currently set, if any. ++ #[doc(alias("timer_gettime"))] ++ pub fn get(&self) -> Result> { ++ let mut timerspec = TimerSpec::none(); ++ Errno::result(unsafe { ++ libc::timer_gettime(self.0, timerspec.as_mut()) ++ }) ++ .map(|_| { ++ if timerspec.as_ref().it_interval.tv_sec == 0 ++ && timerspec.as_ref().it_interval.tv_nsec == 0 ++ && timerspec.as_ref().it_value.tv_sec == 0 ++ && timerspec.as_ref().it_value.tv_nsec == 0 ++ { ++ None ++ } else { ++ Some(timerspec.into()) ++ } ++ }) ++ } ++ ++ /// Return the number of timers that have overrun ++ /// ++ /// Each timer is able to queue one signal to the process at a time, meaning ++ /// if the signal is not handled before the next expiration the timer has ++ /// 'overrun'. This function returns how many times that has happened to ++ /// this timer, up to `libc::DELAYTIMER_MAX`. If more than the maximum ++ /// number of overruns have happened the return is capped to the maximum. ++ #[doc(alias("timer_getoverrun"))] ++ pub fn overruns(&self) -> i32 { ++ unsafe { libc::timer_getoverrun(self.0) } ++ } ++} ++ ++impl Drop for Timer { ++ fn drop(&mut self) { ++ if !std::thread::panicking() { ++ let result = Errno::result(unsafe { libc::timer_delete(self.0) }); ++ if let Err(Errno::EINVAL) = result { ++ panic!("close of Timer encountered EINVAL"); ++ } ++ } ++ } ++} +diff --git a/vendor/nix/src/sys/timerfd.rs b/vendor/nix/src/sys/timerfd.rs +new file mode 100644 +index 0000000..a35fc92 +--- /dev/null ++++ b/vendor/nix/src/sys/timerfd.rs +@@ -0,0 +1,214 @@ ++//! Timer API via file descriptors. ++//! ++//! Timer FD is a Linux-only API to create timers and get expiration ++//! notifications through file descriptors. ++//! ++//! For more documentation, please read [timerfd_create(2)](https://man7.org/linux/man-pages/man2/timerfd_create.2.html). ++//! ++//! # Examples ++//! ++//! Create a new one-shot timer that expires after 1 second. ++//! ``` ++//! # use std::os::unix::io::AsRawFd; ++//! # use nix::sys::timerfd::{TimerFd, ClockId, TimerFlags, TimerSetTimeFlags, ++//! # Expiration}; ++//! # use nix::sys::time::{TimeSpec, TimeValLike}; ++//! # use nix::unistd::read; ++//! # ++//! // We create a new monotonic timer. ++//! let timer = TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty()) ++//! .unwrap(); ++//! ++//! // We set a new one-shot timer in 1 seconds. ++//! timer.set( ++//! Expiration::OneShot(TimeSpec::seconds(1)), ++//! TimerSetTimeFlags::empty() ++//! ).unwrap(); ++//! ++//! // We wait for the timer to expire. ++//! timer.wait().unwrap(); ++//! ``` ++use crate::sys::time::timer::TimerSpec; ++pub use crate::sys::time::timer::{Expiration, TimerSetTimeFlags}; ++use crate::unistd::read; ++use crate::{errno::Errno, Result}; ++use libc::c_int; ++use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; ++ ++/// A timerfd instance. This is also a file descriptor, you can feed it to ++/// other interfaces consuming file descriptors, epoll for example. ++#[derive(Debug)] ++pub struct TimerFd { ++ fd: RawFd, ++} ++ ++impl AsRawFd for TimerFd { ++ fn as_raw_fd(&self) -> RawFd { ++ self.fd ++ } ++} ++ ++impl FromRawFd for TimerFd { ++ unsafe fn from_raw_fd(fd: RawFd) -> Self { ++ TimerFd { fd } ++ } ++} ++ ++libc_enum! { ++ /// The type of the clock used to mark the progress of the timer. For more ++ /// details on each kind of clock, please refer to [timerfd_create(2)](https://man7.org/linux/man-pages/man2/timerfd_create.2.html). ++ #[repr(i32)] ++ #[non_exhaustive] ++ pub enum ClockId { ++ /// A settable system-wide real-time clock. ++ CLOCK_REALTIME, ++ /// A non-settable monotonically increasing clock. ++ /// ++ /// Does not change after system startup. ++ /// Does not measure time while the system is suspended. ++ CLOCK_MONOTONIC, ++ /// Like `CLOCK_MONOTONIC`, except that `CLOCK_BOOTTIME` includes the time ++ /// that the system was suspended. ++ CLOCK_BOOTTIME, ++ /// Like `CLOCK_REALTIME`, but will wake the system if it is suspended. ++ CLOCK_REALTIME_ALARM, ++ /// Like `CLOCK_BOOTTIME`, but will wake the system if it is suspended. ++ CLOCK_BOOTTIME_ALARM, ++ } ++} ++ ++libc_bitflags! { ++ /// Additional flags to change the behaviour of the file descriptor at the ++ /// time of creation. ++ pub struct TimerFlags: c_int { ++ /// Set the `O_NONBLOCK` flag on the open file description referred to by the new file descriptor. ++ TFD_NONBLOCK; ++ /// Set the `FD_CLOEXEC` flag on the file descriptor. ++ TFD_CLOEXEC; ++ } ++} ++ ++impl TimerFd { ++ /// Creates a new timer based on the clock defined by `clockid`. The ++ /// underlying fd can be assigned specific flags with `flags` (CLOEXEC, ++ /// NONBLOCK). The underlying fd will be closed on drop. ++ #[doc(alias("timerfd_create"))] ++ pub fn new(clockid: ClockId, flags: TimerFlags) -> Result { ++ Errno::result(unsafe { ++ libc::timerfd_create(clockid as i32, flags.bits()) ++ }) ++ .map(|fd| Self { fd }) ++ } ++ ++ /// Sets a new alarm on the timer. ++ /// ++ /// # Types of alarm ++ /// ++ /// There are 3 types of alarms you can set: ++ /// ++ /// - one shot: the alarm will trigger once after the specified amount of ++ /// time. ++ /// Example: I want an alarm to go off in 60s and then disable itself. ++ /// ++ /// - interval: the alarm will trigger every specified interval of time. ++ /// Example: I want an alarm to go off every 60s. The alarm will first ++ /// go off 60s after I set it and every 60s after that. The alarm will ++ /// not disable itself. ++ /// ++ /// - interval delayed: the alarm will trigger after a certain amount of ++ /// time and then trigger at a specified interval. ++ /// Example: I want an alarm to go off every 60s but only start in 1h. ++ /// The alarm will first trigger 1h after I set it and then every 60s ++ /// after that. The alarm will not disable itself. ++ /// ++ /// # Relative vs absolute alarm ++ /// ++ /// If you do not set any `TimerSetTimeFlags`, then the `TimeSpec` you pass ++ /// to the `Expiration` you want is relative. If however you want an alarm ++ /// to go off at a certain point in time, you can set `TFD_TIMER_ABSTIME`. ++ /// Then the one shot TimeSpec and the delay TimeSpec of the delayed ++ /// interval are going to be interpreted as absolute. ++ /// ++ /// # Disabling alarms ++ /// ++ /// Note: Only one alarm can be set for any given timer. Setting a new alarm ++ /// actually removes the previous one. ++ /// ++ /// Note: Setting a one shot alarm with a 0s TimeSpec disables the alarm ++ /// altogether. ++ #[doc(alias("timerfd_settime"))] ++ pub fn set( ++ &self, ++ expiration: Expiration, ++ flags: TimerSetTimeFlags, ++ ) -> Result<()> { ++ let timerspec: TimerSpec = expiration.into(); ++ Errno::result(unsafe { ++ libc::timerfd_settime( ++ self.fd, ++ flags.bits(), ++ timerspec.as_ref(), ++ std::ptr::null_mut(), ++ ) ++ }) ++ .map(drop) ++ } ++ ++ /// Get the parameters for the alarm currently set, if any. ++ #[doc(alias("timerfd_gettime"))] ++ pub fn get(&self) -> Result> { ++ let mut timerspec = TimerSpec::none(); ++ Errno::result(unsafe { ++ libc::timerfd_gettime(self.fd, timerspec.as_mut()) ++ }) ++ .map(|_| { ++ if timerspec.as_ref().it_interval.tv_sec == 0 ++ && timerspec.as_ref().it_interval.tv_nsec == 0 ++ && timerspec.as_ref().it_value.tv_sec == 0 ++ && timerspec.as_ref().it_value.tv_nsec == 0 ++ { ++ None ++ } else { ++ Some(timerspec.into()) ++ } ++ }) ++ } ++ ++ /// Remove the alarm if any is set. ++ #[doc(alias("timerfd_settime"))] ++ pub fn unset(&self) -> Result<()> { ++ Errno::result(unsafe { ++ libc::timerfd_settime( ++ self.fd, ++ TimerSetTimeFlags::empty().bits(), ++ TimerSpec::none().as_ref(), ++ std::ptr::null_mut(), ++ ) ++ }) ++ .map(drop) ++ } ++ ++ /// Wait for the configured alarm to expire. ++ /// ++ /// Note: If the alarm is unset, then you will wait forever. ++ pub fn wait(&self) -> Result<()> { ++ while let Err(e) = read(self.fd, &mut [0u8; 8]) { ++ if e != Errno::EINTR { ++ return Err(e); ++ } ++ } ++ ++ Ok(()) ++ } ++} ++ ++impl Drop for TimerFd { ++ fn drop(&mut self) { ++ if !std::thread::panicking() { ++ let result = Errno::result(unsafe { libc::close(self.fd) }); ++ if let Err(Errno::EBADF) = result { ++ panic!("close of TimerFd encountered EBADF"); ++ } ++ } ++ } ++} +diff --git a/vendor/nix/src/sys/uio.rs b/vendor/nix/src/sys/uio.rs +index d089084..b31c306 100644 +--- a/vendor/nix/src/sys/uio.rs ++++ b/vendor/nix/src/sys/uio.rs +@@ -1,20 +1,38 @@ +-// Silence invalid warnings due to rust-lang/rust#16719 +-#![allow(improper_ctypes)] ++//! Vectored I/O + +-use Result; +-use errno::Errno; +-use libc::{self, c_int, c_void, size_t, off_t}; ++use crate::errno::Errno; ++use crate::Result; ++use libc::{self, c_int, c_void, off_t, size_t}; ++use std::io::{IoSlice, IoSliceMut}; + use std::marker::PhantomData; + use std::os::unix::io::RawFd; + +-pub fn writev(fd: RawFd, iov: &[IoVec<&[u8]>]) -> Result { +- let res = unsafe { libc::writev(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int) }; ++/// Low-level vectored write to a raw file descriptor ++/// ++/// See also [writev(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/writev.html) ++pub fn writev(fd: RawFd, iov: &[IoSlice<'_>]) -> Result { ++ // SAFETY: to quote the documentation for `IoSlice`: ++ // ++ // [IoSlice] is semantically a wrapper around a &[u8], but is ++ // guaranteed to be ABI compatible with the iovec type on Unix ++ // platforms. ++ // ++ // Because it is ABI compatible, a pointer cast here is valid ++ let res = unsafe { ++ libc::writev(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int) ++ }; + + Errno::result(res).map(|r| r as usize) + } + +-pub fn readv(fd: RawFd, iov: &mut [IoVec<&mut [u8]>]) -> Result { +- let res = unsafe { libc::readv(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int) }; ++/// Low-level vectored read from a raw file descriptor ++/// ++/// See also [readv(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/readv.html) ++pub fn readv(fd: RawFd, iov: &mut [IoSliceMut<'_>]) -> Result { ++ // SAFETY: same as in writev(), IoSliceMut is ABI-compatible with iovec ++ let res = unsafe { ++ libc::readv(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int) ++ }; + + Errno::result(res).map(|r| r as usize) + } +@@ -25,15 +43,20 @@ pub fn readv(fd: RawFd, iov: &mut [IoVec<&mut [u8]>]) -> Result { + /// or an error occurs. The file offset is not changed. + /// + /// See also: [`writev`](fn.writev.html) and [`pwrite`](fn.pwrite.html) +-#[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "linux", +- target_os = "netbsd", +- target_os = "openbsd"))] +-pub fn pwritev(fd: RawFd, iov: &[IoVec<&[u8]>], +- offset: off_t) -> Result { ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++pub fn pwritev(fd: RawFd, iov: &[IoSlice<'_>], offset: off_t) -> Result { ++ #[cfg(target_env = "uclibc")] ++ let offset = offset as libc::off64_t; // uclibc doesn't use off_t ++ ++ // SAFETY: same as in writev() + let res = unsafe { +- libc::pwritev(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int, offset) ++ libc::pwritev( ++ fd, ++ iov.as_ptr() as *const libc::iovec, ++ iov.len() as c_int, ++ offset, ++ ) + }; + + Errno::result(res).map(|r| r as usize) +@@ -46,33 +69,58 @@ pub fn pwritev(fd: RawFd, iov: &[IoVec<&[u8]>], + /// changed. + /// + /// See also: [`readv`](fn.readv.html) and [`pread`](fn.pread.html) +-#[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "linux", +- target_os = "netbsd", +- target_os = "openbsd"))] +-pub fn preadv(fd: RawFd, iov: &[IoVec<&mut [u8]>], +- offset: off_t) -> Result { ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++pub fn preadv( ++ fd: RawFd, ++ iov: &mut [IoSliceMut<'_>], ++ offset: off_t, ++) -> Result { ++ #[cfg(target_env = "uclibc")] ++ let offset = offset as libc::off64_t; // uclibc doesn't use off_t ++ ++ // SAFETY: same as in readv() + let res = unsafe { +- libc::preadv(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int, offset) ++ libc::preadv( ++ fd, ++ iov.as_ptr() as *const libc::iovec, ++ iov.len() as c_int, ++ offset, ++ ) + }; + + Errno::result(res).map(|r| r as usize) + } + ++/// Low-level write to a file, with specified offset. ++/// ++/// See also [pwrite(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html) ++// TODO: move to unistd + pub fn pwrite(fd: RawFd, buf: &[u8], offset: off_t) -> Result { + let res = unsafe { +- libc::pwrite(fd, buf.as_ptr() as *const c_void, buf.len() as size_t, +- offset) ++ libc::pwrite( ++ fd, ++ buf.as_ptr() as *const c_void, ++ buf.len() as size_t, ++ offset, ++ ) + }; + + Errno::result(res).map(|r| r as usize) + } + +-pub fn pread(fd: RawFd, buf: &mut [u8], offset: off_t) -> Result{ ++/// Low-level read from a file, with specified offset. ++/// ++/// See also [pread(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html) ++// TODO: move to unistd ++pub fn pread(fd: RawFd, buf: &mut [u8], offset: off_t) -> Result { + let res = unsafe { +- libc::pread(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t, +- offset) ++ libc::pread( ++ fd, ++ buf.as_mut_ptr() as *mut c_void, ++ buf.len() as size_t, ++ offset, ++ ) + }; + + Errno::result(res).map(|r| r as usize) +@@ -81,12 +129,13 @@ pub fn pread(fd: RawFd, buf: &mut [u8], offset: off_t) -> Result{ + /// A slice of memory in a remote process, starting at address `base` + /// and consisting of `len` bytes. + /// +-/// This is the same underlying C structure as [`IoVec`](struct.IoVec.html), ++/// This is the same underlying C structure as `IoSlice`, + /// except that it refers to memory in some other process, and is +-/// therefore not represented in Rust by an actual slice as `IoVec` is. It ++/// therefore not represented in Rust by an actual slice as `IoSlice` is. It + /// is used with [`process_vm_readv`](fn.process_vm_readv.html) + /// and [`process_vm_writev`](fn.process_vm_writev.html). +-#[cfg(target_os = "linux")] ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[cfg_attr(docsrs, doc(cfg(all())))] + #[repr(C)] + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct RemoteIoVec { +@@ -96,10 +145,84 @@ pub struct RemoteIoVec { + pub len: usize, + } + ++/// A vector of buffers. ++/// ++/// Vectored I/O methods like [`writev`] and [`readv`] use this structure for ++/// both reading and writing. Each `IoVec` specifies the base address and ++/// length of an area in memory. ++#[deprecated( ++ since = "0.24.0", ++ note = "`IoVec` is no longer used in the public interface, use `IoSlice` or `IoSliceMut` instead" ++)] ++#[repr(transparent)] ++#[allow(renamed_and_removed_lints)] ++#[allow(clippy::unknown_clippy_lints)] ++// Clippy false positive: https://github.com/rust-lang/rust-clippy/issues/8867 ++#[allow(clippy::derive_partial_eq_without_eq)] ++#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] ++pub struct IoVec(pub(crate) libc::iovec, PhantomData); ++ ++#[allow(deprecated)] ++impl IoVec { ++ /// View the `IoVec` as a Rust slice. ++ #[deprecated( ++ since = "0.24.0", ++ note = "Use the `Deref` impl of `IoSlice` or `IoSliceMut` instead" ++ )] ++ #[inline] ++ pub fn as_slice(&self) -> &[u8] { ++ use std::slice; ++ ++ unsafe { ++ slice::from_raw_parts(self.0.iov_base as *const u8, self.0.iov_len) ++ } ++ } ++} ++ ++#[allow(deprecated)] ++impl<'a> IoVec<&'a [u8]> { ++ /// Create an `IoVec` from a Rust slice. ++ #[deprecated(since = "0.24.0", note = "Use `IoSlice::new` instead")] ++ pub fn from_slice(buf: &'a [u8]) -> IoVec<&'a [u8]> { ++ IoVec( ++ libc::iovec { ++ iov_base: buf.as_ptr() as *mut c_void, ++ iov_len: buf.len() as size_t, ++ }, ++ PhantomData, ++ ) ++ } ++} ++ ++#[allow(deprecated)] ++impl<'a> IoVec<&'a mut [u8]> { ++ /// Create an `IoVec` from a mutable Rust slice. ++ #[deprecated(since = "0.24.0", note = "Use `IoSliceMut::new` instead")] ++ pub fn from_mut_slice(buf: &'a mut [u8]) -> IoVec<&'a mut [u8]> { ++ IoVec( ++ libc::iovec { ++ iov_base: buf.as_ptr() as *mut c_void, ++ iov_len: buf.len() as size_t, ++ }, ++ PhantomData, ++ ) ++ } ++} ++ ++// The only reason IoVec isn't automatically Send+Sync is because libc::iovec ++// contains raw pointers. ++#[allow(deprecated)] ++unsafe impl Send for IoVec where T: Send {} ++#[allow(deprecated)] ++unsafe impl Sync for IoVec where T: Sync {} ++ ++feature! { ++#![feature = "process"] ++ + /// Write data directly to another process's virtual memory + /// (see [`process_vm_writev`(2)]). + /// +-/// `local_iov` is a list of [`IoVec`]s containing the data to be written, ++/// `local_iov` is a list of [`IoSlice`]s containing the data to be written, + /// and `remote_iov` is a list of [`RemoteIoVec`]s identifying where the + /// data should be written in the target process. On success, returns the + /// number of bytes written, which will always be a whole +@@ -110,14 +233,18 @@ pub struct RemoteIoVec { + /// `CAP_SYS_PTRACE`), or you must be running as the same user as the + /// target process and the OS must have unprivileged debugging enabled. + /// +-/// This function is only available on Linux. ++/// This function is only available on Linux and Android(SDK23+). + /// +-/// [`process_vm_writev`(2)]: http://man7.org/linux/man-pages/man2/process_vm_writev.2.html ++/// [`process_vm_writev`(2)]: https://man7.org/linux/man-pages/man2/process_vm_writev.2.html + /// [ptrace]: ../ptrace/index.html +-/// [`IoVec`]: struct.IoVec.html ++/// [`IoSlice`]: https://doc.rust-lang.org/std/io/struct.IoSlice.html + /// [`RemoteIoVec`]: struct.RemoteIoVec.html +-#[cfg(target_os = "linux")] +-pub fn process_vm_writev(pid: ::unistd::Pid, local_iov: &[IoVec<&[u8]>], remote_iov: &[RemoteIoVec]) -> Result { ++#[cfg(all(any(target_os = "linux", target_os = "android"), not(target_env = "uclibc")))] ++pub fn process_vm_writev( ++ pid: crate::unistd::Pid, ++ local_iov: &[IoSlice<'_>], ++ remote_iov: &[RemoteIoVec]) -> Result ++{ + let res = unsafe { + libc::process_vm_writev(pid.into(), + local_iov.as_ptr() as *const libc::iovec, local_iov.len() as libc::c_ulong, +@@ -130,7 +257,7 @@ pub fn process_vm_writev(pid: ::unistd::Pid, local_iov: &[IoVec<&[u8]>], remote_ + /// Read data directly from another process's virtual memory + /// (see [`process_vm_readv`(2)]). + /// +-/// `local_iov` is a list of [`IoVec`]s containing the buffer to copy ++/// `local_iov` is a list of [`IoSliceMut`]s containing the buffer to copy + /// data into, and `remote_iov` is a list of [`RemoteIoVec`]s identifying + /// where the source data is in the target process. On success, + /// returns the number of bytes written, which will always be a whole +@@ -141,14 +268,18 @@ pub fn process_vm_writev(pid: ::unistd::Pid, local_iov: &[IoVec<&[u8]>], remote_ + /// `CAP_SYS_PTRACE`), or you must be running as the same user as the + /// target process and the OS must have unprivileged debugging enabled. + /// +-/// This function is only available on Linux. ++/// This function is only available on Linux and Android(SDK23+). + /// +-/// [`process_vm_readv`(2)]: http://man7.org/linux/man-pages/man2/process_vm_readv.2.html ++/// [`process_vm_readv`(2)]: https://man7.org/linux/man-pages/man2/process_vm_readv.2.html + /// [`ptrace`]: ../ptrace/index.html +-/// [`IoVec`]: struct.IoVec.html ++/// [`IoSliceMut`]: https://doc.rust-lang.org/std/io/struct.IoSliceMut.html + /// [`RemoteIoVec`]: struct.RemoteIoVec.html +-#[cfg(any(target_os = "linux"))] +-pub fn process_vm_readv(pid: ::unistd::Pid, local_iov: &[IoVec<&mut [u8]>], remote_iov: &[RemoteIoVec]) -> Result { ++#[cfg(all(any(target_os = "linux", target_os = "android"), not(target_env = "uclibc")))] ++pub fn process_vm_readv( ++ pid: crate::unistd::Pid, ++ local_iov: &mut [IoSliceMut<'_>], ++ remote_iov: &[RemoteIoVec]) -> Result ++{ + let res = unsafe { + libc::process_vm_readv(pid.into(), + local_iov.as_ptr() as *const libc::iovec, local_iov.len() as libc::c_ulong, +@@ -157,38 +288,4 @@ pub fn process_vm_readv(pid: ::unistd::Pid, local_iov: &[IoVec<&mut [u8]>], remo + + Errno::result(res).map(|r| r as usize) + } +- +-#[repr(C)] +-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +-pub struct IoVec(libc::iovec, PhantomData); +- +-impl IoVec { +- #[inline] +- pub fn as_slice(&self) -> &[u8] { +- use std::slice; +- +- unsafe { +- slice::from_raw_parts( +- self.0.iov_base as *const u8, +- self.0.iov_len as usize) +- } +- } +-} +- +-impl<'a> IoVec<&'a [u8]> { +- pub fn from_slice(buf: &'a [u8]) -> IoVec<&'a [u8]> { +- IoVec(libc::iovec { +- iov_base: buf.as_ptr() as *mut c_void, +- iov_len: buf.len() as size_t, +- }, PhantomData) +- } +-} +- +-impl<'a> IoVec<&'a mut [u8]> { +- pub fn from_mut_slice(buf: &'a mut [u8]) -> IoVec<&'a mut [u8]> { +- IoVec(libc::iovec { +- iov_base: buf.as_ptr() as *mut c_void, +- iov_len: buf.len() as size_t, +- }, PhantomData) +- } + } +diff --git a/vendor/nix/src/sys/utsname.rs b/vendor/nix/src/sys/utsname.rs +index bf1a814..b48ed9f 100644 +--- a/vendor/nix/src/sys/utsname.rs ++++ b/vendor/nix/src/sys/utsname.rs +@@ -1,67 +1,85 @@ ++//! Get system identification ++use crate::{Errno, Result}; ++use libc::c_char; ++use std::ffi::OsStr; + use std::mem; +-use libc::{self, c_char}; +-use std::ffi::CStr; +-use std::str::from_utf8_unchecked; ++use std::os::unix::ffi::OsStrExt; + ++/// Describes the running system. Return type of [`uname`]. + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + #[repr(transparent)] + pub struct UtsName(libc::utsname); + + impl UtsName { +- pub fn sysname(&self) -> &str { +- to_str(&(&self.0.sysname as *const c_char ) as *const *const c_char) ++ /// Name of the operating system implementation. ++ pub fn sysname(&self) -> &OsStr { ++ cast_and_trim(&self.0.sysname) + } + +- pub fn nodename(&self) -> &str { +- to_str(&(&self.0.nodename as *const c_char ) as *const *const c_char) ++ /// Network name of this machine. ++ pub fn nodename(&self) -> &OsStr { ++ cast_and_trim(&self.0.nodename) + } + +- pub fn release(&self) -> &str { +- to_str(&(&self.0.release as *const c_char ) as *const *const c_char) ++ /// Release level of the operating system. ++ pub fn release(&self) -> &OsStr { ++ cast_and_trim(&self.0.release) + } + +- pub fn version(&self) -> &str { +- to_str(&(&self.0.version as *const c_char ) as *const *const c_char) ++ /// Version level of the operating system. ++ pub fn version(&self) -> &OsStr { ++ cast_and_trim(&self.0.version) + } + +- pub fn machine(&self) -> &str { +- to_str(&(&self.0.machine as *const c_char ) as *const *const c_char) ++ /// Machine hardware platform. ++ pub fn machine(&self) -> &OsStr { ++ cast_and_trim(&self.0.machine) + } +-} + +-pub fn uname() -> UtsName { +- unsafe { +- let mut ret = mem::MaybeUninit::uninit(); +- libc::uname(ret.as_mut_ptr()); +- UtsName(ret.assume_init()) ++ /// NIS or YP domain name of this machine. ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ pub fn domainname(&self) -> &OsStr { ++ cast_and_trim(&self.0.domainname) + } + } + +-#[inline] +-fn to_str<'a>(s: *const *const c_char) -> &'a str { ++/// Get system identification ++pub fn uname() -> Result { + unsafe { +- let res = CStr::from_ptr(*s).to_bytes(); +- from_utf8_unchecked(res) ++ let mut ret = mem::MaybeUninit::zeroed(); ++ Errno::result(libc::uname(ret.as_mut_ptr()))?; ++ Ok(UtsName(ret.assume_init())) + } + } + ++fn cast_and_trim(slice: &[c_char]) -> &OsStr { ++ let length = slice ++ .iter() ++ .position(|&byte| byte == 0) ++ .unwrap_or(slice.len()); ++ let bytes = ++ unsafe { std::slice::from_raw_parts(slice.as_ptr().cast(), length) }; ++ ++ OsStr::from_bytes(bytes) ++} ++ + #[cfg(test)] + mod test { + #[cfg(target_os = "linux")] + #[test] + pub fn test_uname_linux() { +- assert_eq!(super::uname().sysname(), "Linux"); ++ assert_eq!(super::uname().unwrap().sysname(), "Linux"); + } + + #[cfg(any(target_os = "macos", target_os = "ios"))] + #[test] + pub fn test_uname_darwin() { +- assert_eq!(super::uname().sysname(), "Darwin"); ++ assert_eq!(super::uname().unwrap().sysname(), "Darwin"); + } + + #[cfg(target_os = "freebsd")] + #[test] + pub fn test_uname_freebsd() { +- assert_eq!(super::uname().sysname(), "FreeBSD"); ++ assert_eq!(super::uname().unwrap().sysname(), "FreeBSD"); + } + } +diff --git a/vendor/nix/src/sys/wait.rs b/vendor/nix/src/sys/wait.rs +index d18c375..b6524e8 100644 +--- a/vendor/nix/src/sys/wait.rs ++++ b/vendor/nix/src/sys/wait.rs +@@ -1,31 +1,53 @@ ++//! Wait for a process to change status ++use crate::errno::Errno; ++use crate::sys::signal::Signal; ++use crate::unistd::Pid; ++use crate::Result; ++use cfg_if::cfg_if; + use libc::{self, c_int}; +-use Result; +-use errno::Errno; + use std::convert::TryFrom; +-use unistd::Pid; +- +-use sys::signal::Signal; ++#[cfg(any( ++ target_os = "android", ++ all(target_os = "linux", not(target_env = "uclibc")), ++))] ++use std::os::unix::io::RawFd; + + libc_bitflags!( ++ /// Controls the behavior of [`waitpid`]. + pub struct WaitPidFlag: c_int { ++ /// Do not block when there are no processes wishing to report status. + WNOHANG; ++ /// Report the status of selected processes which are stopped due to a ++ /// [`SIGTTIN`](crate::sys::signal::Signal::SIGTTIN), ++ /// [`SIGTTOU`](crate::sys::signal::Signal::SIGTTOU), ++ /// [`SIGTSTP`](crate::sys::signal::Signal::SIGTSTP), or ++ /// [`SIGSTOP`](crate::sys::signal::Signal::SIGSTOP) signal. + WUNTRACED; ++ /// Report the status of selected processes which have terminated. + #[cfg(any(target_os = "android", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "linux", ++ target_os = "redox", + target_os = "macos", + target_os = "netbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + WEXITED; ++ /// Report the status of selected processes that have continued from a ++ /// job control stop by receiving a ++ /// [`SIGCONT`](crate::sys::signal::Signal::SIGCONT) signal. + WCONTINUED; ++ /// An alias for WUNTRACED. + #[cfg(any(target_os = "android", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "linux", ++ target_os = "redox", + target_os = "macos", + target_os = "netbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + WSTOPPED; + /// Don't reap, just poll status. + #[cfg(any(target_os = "android", +@@ -33,16 +55,22 @@ libc_bitflags!( + target_os = "haiku", + target_os = "ios", + target_os = "linux", ++ target_os = "redox", + target_os = "macos", + target_os = "netbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + WNOWAIT; + /// Don't wait on children of other threads in this group +- #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + __WNOTHREAD; + /// Wait on all children, regardless of type +- #[cfg(any(target_os = "android", target_os = "linux"))] ++ #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + __WALL; +- #[cfg(any(target_os = "android", target_os = "linux"))] ++ /// Wait for "clone" children only. ++ #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + __WCLONE; + } + ); +@@ -78,15 +106,17 @@ pub enum WaitStatus { + /// field is the `PTRACE_EVENT_*` value of the event. + /// + /// [`nix::sys::ptrace`]: ../ptrace/index.html +- /// [`ptrace`(2)]: http://man7.org/linux/man-pages/man2/ptrace.2.html ++ /// [`ptrace`(2)]: https://man7.org/linux/man-pages/man2/ptrace.2.html + #[cfg(any(target_os = "linux", target_os = "android"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + PtraceEvent(Pid, Signal, c_int), + /// The traced process was stopped by execution of a system call, + /// and `PTRACE_O_TRACESYSGOOD` is in effect. See [`ptrace`(2)] for + /// more information. + /// +- /// [`ptrace`(2)]: http://man7.org/linux/man-pages/man2/ptrace.2.html ++ /// [`ptrace`(2)]: https://man7.org/linux/man-pages/man2/ptrace.2.html + #[cfg(any(target_os = "linux", target_os = "android"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + PtraceSyscall(Pid), + /// The process was previously stopped but has resumed execution + /// after receiving a `SIGCONT` signal. This is only reported if +@@ -105,8 +135,9 @@ impl WaitStatus { + pub fn pid(&self) -> Option { + use self::WaitStatus::*; + match *self { +- Exited(p, _) | Signaled(p, _, _) | +- Stopped(p, _) | Continued(p) => Some(p), ++ Exited(p, _) | Signaled(p, _, _) | Stopped(p, _) | Continued(p) => { ++ Some(p) ++ } + StillAlive => None, + #[cfg(any(target_os = "android", target_os = "linux"))] + PtraceEvent(p, _, _) | PtraceSyscall(p) => Some(p), +@@ -115,31 +146,31 @@ impl WaitStatus { + } + + fn exited(status: i32) -> bool { +- unsafe { libc::WIFEXITED(status) } ++ libc::WIFEXITED(status) + } + + fn exit_status(status: i32) -> i32 { +- unsafe { libc::WEXITSTATUS(status) } ++ libc::WEXITSTATUS(status) + } + + fn signaled(status: i32) -> bool { +- unsafe { libc::WIFSIGNALED(status) } ++ libc::WIFSIGNALED(status) + } + + fn term_signal(status: i32) -> Result { +- Signal::try_from(unsafe { libc::WTERMSIG(status) }) ++ Signal::try_from(libc::WTERMSIG(status)) + } + + fn dumped_core(status: i32) -> bool { +- unsafe { libc::WCOREDUMP(status) } ++ libc::WCOREDUMP(status) + } + + fn stopped(status: i32) -> bool { +- unsafe { libc::WIFSTOPPED(status) } ++ libc::WIFSTOPPED(status) + } + + fn stop_signal(status: i32) -> Result { +- Signal::try_from(unsafe { libc::WSTOPSIG(status) }) ++ Signal::try_from(libc::WSTOPSIG(status)) + } + + #[cfg(any(target_os = "android", target_os = "linux"))] +@@ -148,7 +179,7 @@ fn syscall_stop(status: i32) -> bool { + // of delivering SIGTRAP | 0x80 as the signal number for syscall + // stops. This allows easily distinguishing syscall stops from + // genuine SIGTRAP signals. +- unsafe { libc::WSTOPSIG(status) == libc::SIGTRAP | 0x80 } ++ libc::WSTOPSIG(status) == libc::SIGTRAP | 0x80 + } + + #[cfg(any(target_os = "android", target_os = "linux"))] +@@ -157,7 +188,7 @@ fn stop_additional(status: i32) -> c_int { + } + + fn continued(status: i32) -> bool { +- unsafe { libc::WIFCONTINUED(status) } ++ libc::WIFCONTINUED(status) + } + + impl WaitStatus { +@@ -209,9 +240,72 @@ impl WaitStatus { + WaitStatus::Continued(pid) + }) + } ++ ++ /// Convert a `siginfo_t` as returned by `waitid` to a `WaitStatus` ++ /// ++ /// # Errors ++ /// ++ /// Returns an `Error` corresponding to `EINVAL` for invalid values. ++ /// ++ /// # Safety ++ /// ++ /// siginfo_t is actually a union, not all fields may be initialized. ++ /// The functions si_pid() and si_status() must be valid to call on ++ /// the passed siginfo_t. ++ #[cfg(any( ++ target_os = "android", ++ target_os = "freebsd", ++ target_os = "haiku", ++ all(target_os = "linux", not(target_env = "uclibc")), ++ ))] ++ unsafe fn from_siginfo(siginfo: &libc::siginfo_t) -> Result { ++ let si_pid = siginfo.si_pid(); ++ if si_pid == 0 { ++ return Ok(WaitStatus::StillAlive); ++ } ++ ++ assert_eq!(siginfo.si_signo, libc::SIGCHLD); ++ ++ let pid = Pid::from_raw(si_pid); ++ let si_status = siginfo.si_status(); ++ ++ let status = match siginfo.si_code { ++ libc::CLD_EXITED => WaitStatus::Exited(pid, si_status), ++ libc::CLD_KILLED | libc::CLD_DUMPED => WaitStatus::Signaled( ++ pid, ++ Signal::try_from(si_status)?, ++ siginfo.si_code == libc::CLD_DUMPED, ++ ), ++ libc::CLD_STOPPED => { ++ WaitStatus::Stopped(pid, Signal::try_from(si_status)?) ++ } ++ libc::CLD_CONTINUED => WaitStatus::Continued(pid), ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ libc::CLD_TRAPPED => { ++ if si_status == libc::SIGTRAP | 0x80 { ++ WaitStatus::PtraceSyscall(pid) ++ } else { ++ WaitStatus::PtraceEvent( ++ pid, ++ Signal::try_from(si_status & 0xff)?, ++ (si_status >> 8) as c_int, ++ ) ++ } ++ } ++ _ => return Err(Errno::EINVAL), ++ }; ++ ++ Ok(status) ++ } + } + +-pub fn waitpid>>(pid: P, options: Option) -> Result { ++/// Wait for a process to change status ++/// ++/// See also [waitpid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/waitpid.html) ++pub fn waitpid>>( ++ pid: P, ++ options: Option, ++) -> Result { + use self::WaitStatus::*; + + let mut status: i32 = 0; +@@ -235,6 +329,60 @@ pub fn waitpid>>(pid: P, options: Option) -> Re + } + } + ++/// Wait for any child process to change status or a signal is received. ++/// ++/// See also [wait(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html) + pub fn wait() -> Result { + waitpid(None, None) + } ++ ++/// The ID argument for `waitid` ++#[cfg(any( ++ target_os = "android", ++ target_os = "freebsd", ++ target_os = "haiku", ++ all(target_os = "linux", not(target_env = "uclibc")), ++))] ++#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] ++pub enum Id { ++ /// Wait for any child ++ All, ++ /// Wait for the child whose process ID matches the given PID ++ Pid(Pid), ++ /// Wait for the child whose process group ID matches the given PID ++ /// ++ /// If the PID is zero, the caller's process group is used since Linux 5.4. ++ PGid(Pid), ++ /// Wait for the child referred to by the given PID file descriptor ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ PIDFd(RawFd), ++} ++ ++/// Wait for a process to change status ++/// ++/// See also [waitid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/waitid.html) ++#[cfg(any( ++ target_os = "android", ++ target_os = "freebsd", ++ target_os = "haiku", ++ all(target_os = "linux", not(target_env = "uclibc")), ++))] ++pub fn waitid(id: Id, flags: WaitPidFlag) -> Result { ++ let (idtype, idval) = match id { ++ Id::All => (libc::P_ALL, 0), ++ Id::Pid(pid) => (libc::P_PID, pid.as_raw() as libc::id_t), ++ Id::PGid(pid) => (libc::P_PGID, pid.as_raw() as libc::id_t), ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ Id::PIDFd(fd) => (libc::P_PIDFD, fd as libc::id_t), ++ }; ++ ++ let siginfo = unsafe { ++ // Memory is zeroed rather than uninitialized, as not all platforms ++ // initialize the memory in the StillAlive case ++ let mut siginfo: libc::siginfo_t = std::mem::zeroed(); ++ Errno::result(libc::waitid(idtype, idval, &mut siginfo, flags.bits()))?; ++ siginfo ++ }; ++ ++ unsafe { WaitStatus::from_siginfo(&siginfo) } ++} +diff --git a/vendor/nix/src/time.rs b/vendor/nix/src/time.rs +new file mode 100644 +index 0000000..2e03c46 +--- /dev/null ++++ b/vendor/nix/src/time.rs +@@ -0,0 +1,283 @@ ++use crate::sys::time::TimeSpec; ++#[cfg(any( ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "linux", ++ target_os = "android", ++ target_os = "emscripten", ++))] ++#[cfg(feature = "process")] ++use crate::unistd::Pid; ++use crate::{Errno, Result}; ++use libc::{self, clockid_t}; ++use std::mem::MaybeUninit; ++ ++/// Clock identifier ++/// ++/// Newtype pattern around `clockid_t` (which is just alias). It prevents bugs caused by ++/// accidentally passing wrong value. ++#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] ++pub struct ClockId(clockid_t); ++ ++impl ClockId { ++ /// Creates `ClockId` from raw `clockid_t` ++ pub const fn from_raw(clk_id: clockid_t) -> Self { ++ ClockId(clk_id) ++ } ++ ++ feature! { ++ #![feature = "process"] ++ /// Returns `ClockId` of a `pid` CPU-time clock ++ #[cfg(any( ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "linux", ++ target_os = "android", ++ target_os = "emscripten", ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub fn pid_cpu_clock_id(pid: Pid) -> Result { ++ clock_getcpuclockid(pid) ++ } ++ } ++ ++ /// Returns resolution of the clock id ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub fn res(self) -> Result { ++ clock_getres(self) ++ } ++ ++ /// Returns the current time on the clock id ++ pub fn now(self) -> Result { ++ clock_gettime(self) ++ } ++ ++ /// Sets time to `timespec` on the clock id ++ #[cfg(not(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "redox", ++ target_os = "hermit", ++ )))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub fn set_time(self, timespec: TimeSpec) -> Result<()> { ++ clock_settime(self, timespec) ++ } ++ ++ /// Gets the raw `clockid_t` wrapped by `self` ++ pub const fn as_raw(self) -> clockid_t { ++ self.0 ++ } ++ ++ #[cfg(any( ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "linux" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_BOOTTIME: ClockId = ClockId(libc::CLOCK_BOOTTIME); ++ #[cfg(any( ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "linux" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_BOOTTIME_ALARM: ClockId = ++ ClockId(libc::CLOCK_BOOTTIME_ALARM); ++ pub const CLOCK_MONOTONIC: ClockId = ClockId(libc::CLOCK_MONOTONIC); ++ #[cfg(any( ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "linux" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_MONOTONIC_COARSE: ClockId = ++ ClockId(libc::CLOCK_MONOTONIC_COARSE); ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_MONOTONIC_FAST: ClockId = ++ ClockId(libc::CLOCK_MONOTONIC_FAST); ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_MONOTONIC_PRECISE: ClockId = ++ ClockId(libc::CLOCK_MONOTONIC_PRECISE); ++ #[cfg(any( ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "linux" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_MONOTONIC_RAW: ClockId = ClockId(libc::CLOCK_MONOTONIC_RAW); ++ #[cfg(any( ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "redox", ++ target_os = "linux" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_PROCESS_CPUTIME_ID: ClockId = ++ ClockId(libc::CLOCK_PROCESS_CPUTIME_ID); ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_PROF: ClockId = ClockId(libc::CLOCK_PROF); ++ pub const CLOCK_REALTIME: ClockId = ClockId(libc::CLOCK_REALTIME); ++ #[cfg(any( ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "linux" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_REALTIME_ALARM: ClockId = ++ ClockId(libc::CLOCK_REALTIME_ALARM); ++ #[cfg(any( ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "linux" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_REALTIME_COARSE: ClockId = ++ ClockId(libc::CLOCK_REALTIME_COARSE); ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_REALTIME_FAST: ClockId = ClockId(libc::CLOCK_REALTIME_FAST); ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_REALTIME_PRECISE: ClockId = ++ ClockId(libc::CLOCK_REALTIME_PRECISE); ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_SECOND: ClockId = ClockId(libc::CLOCK_SECOND); ++ #[cfg(any( ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ all(target_os = "linux", target_env = "musl") ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_SGI_CYCLE: ClockId = ClockId(libc::CLOCK_SGI_CYCLE); ++ #[cfg(any( ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "linux" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_TAI: ClockId = ClockId(libc::CLOCK_TAI); ++ #[cfg(any( ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "linux" ++ ))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_THREAD_CPUTIME_ID: ClockId = ++ ClockId(libc::CLOCK_THREAD_CPUTIME_ID); ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_UPTIME: ClockId = ClockId(libc::CLOCK_UPTIME); ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_UPTIME_FAST: ClockId = ClockId(libc::CLOCK_UPTIME_FAST); ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_UPTIME_PRECISE: ClockId = ++ ClockId(libc::CLOCK_UPTIME_PRECISE); ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] ++ pub const CLOCK_VIRTUAL: ClockId = ClockId(libc::CLOCK_VIRTUAL); ++} ++ ++impl From for clockid_t { ++ fn from(clock_id: ClockId) -> Self { ++ clock_id.as_raw() ++ } ++} ++ ++impl From for ClockId { ++ fn from(clk_id: clockid_t) -> Self { ++ ClockId::from_raw(clk_id) ++ } ++} ++ ++impl std::fmt::Display for ClockId { ++ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { ++ std::fmt::Display::fmt(&self.0, f) ++ } ++} ++ ++/// Get the resolution of the specified clock, (see ++/// [clock_getres(2)](https://pubs.opengroup.org/onlinepubs/7908799/xsh/clock_getres.html)). ++#[cfg(not(target_os = "redox"))] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++pub fn clock_getres(clock_id: ClockId) -> Result { ++ let mut c_time: MaybeUninit = MaybeUninit::uninit(); ++ let ret = ++ unsafe { libc::clock_getres(clock_id.as_raw(), c_time.as_mut_ptr()) }; ++ Errno::result(ret)?; ++ let res = unsafe { c_time.assume_init() }; ++ Ok(TimeSpec::from(res)) ++} ++ ++/// Get the time of the specified clock, (see ++/// [clock_gettime(2)](https://pubs.opengroup.org/onlinepubs/7908799/xsh/clock_gettime.html)). ++pub fn clock_gettime(clock_id: ClockId) -> Result { ++ let mut c_time: MaybeUninit = MaybeUninit::uninit(); ++ let ret = ++ unsafe { libc::clock_gettime(clock_id.as_raw(), c_time.as_mut_ptr()) }; ++ Errno::result(ret)?; ++ let res = unsafe { c_time.assume_init() }; ++ Ok(TimeSpec::from(res)) ++} ++ ++/// Set the time of the specified clock, (see ++/// [clock_settime(2)](https://pubs.opengroup.org/onlinepubs/7908799/xsh/clock_settime.html)). ++#[cfg(not(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "redox", ++ target_os = "hermit", ++)))] ++#[cfg_attr(docsrs, doc(cfg(all())))] ++pub fn clock_settime(clock_id: ClockId, timespec: TimeSpec) -> Result<()> { ++ let ret = ++ unsafe { libc::clock_settime(clock_id.as_raw(), timespec.as_ref()) }; ++ Errno::result(ret).map(drop) ++} ++ ++/// Get the clock id of the specified process id, (see ++/// [clock_getcpuclockid(3)](https://pubs.opengroup.org/onlinepubs/009695399/functions/clock_getcpuclockid.html)). ++#[cfg(any( ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "linux", ++ target_os = "android", ++ target_os = "emscripten", ++))] ++#[cfg(feature = "process")] ++#[cfg_attr(docsrs, doc(cfg(feature = "process")))] ++pub fn clock_getcpuclockid(pid: Pid) -> Result { ++ let mut clk_id: MaybeUninit = MaybeUninit::uninit(); ++ let ret = ++ unsafe { libc::clock_getcpuclockid(pid.into(), clk_id.as_mut_ptr()) }; ++ if ret == 0 { ++ let res = unsafe { clk_id.assume_init() }; ++ Ok(ClockId::from(res)) ++ } else { ++ Err(Errno::from_i32(ret)) ++ } ++} +diff --git a/vendor/nix/src/ucontext.rs b/vendor/nix/src/ucontext.rs +index 1bcfdd9..b2a39f7 100644 +--- a/vendor/nix/src/ucontext.rs ++++ b/vendor/nix/src/ucontext.rs +@@ -1,10 +1,10 @@ +-use libc; + #[cfg(not(target_env = "musl"))] +-use Result; ++use crate::errno::Errno; ++use crate::sys::signal::SigSet; ++#[cfg(not(target_env = "musl"))] ++use crate::Result; + #[cfg(not(target_env = "musl"))] +-use errno::Errno; + use std::mem; +-use sys::signal::SigSet; + + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + pub struct UContext { +@@ -17,7 +17,9 @@ impl UContext { + let mut context = mem::MaybeUninit::::uninit(); + let res = unsafe { libc::getcontext(context.as_mut_ptr()) }; + Errno::result(res).map(|_| unsafe { +- UContext { context: context.assume_init()} ++ UContext { ++ context: context.assume_init(), ++ } + }) + } + +@@ -30,10 +32,16 @@ impl UContext { + } + + pub fn sigmask_mut(&mut self) -> &mut SigSet { +- unsafe { mem::transmute(&mut self.context.uc_sigmask) } ++ unsafe { ++ &mut *(&mut self.context.uc_sigmask as *mut libc::sigset_t ++ as *mut SigSet) ++ } + } + + pub fn sigmask(&self) -> &SigSet { +- unsafe { mem::transmute(&self.context.uc_sigmask) } ++ unsafe { ++ &*(&self.context.uc_sigmask as *const libc::sigset_t ++ as *const SigSet) ++ } + } + } +diff --git a/vendor/nix/src/unistd.rs b/vendor/nix/src/unistd.rs +index 2dd5064..ca07b34 100644 +--- a/vendor/nix/src/unistd.rs ++++ b/vendor/nix/src/unistd.rs +@@ -1,26 +1,70 @@ + //! Safe wrappers around functions found in libc "unistd.h" header + +-use errno::{self, Errno}; +-use {Error, Result, NixPath}; +-use fcntl::{AtFlags, at_rawfd, fcntl, FdFlag, OFlag}; +-use fcntl::FcntlArg::F_SETFD; +-use libc::{self, c_char, c_void, c_int, c_long, c_uint, size_t, pid_t, off_t, +- uid_t, gid_t, mode_t, PATH_MAX}; +-use std::{fmt, mem, ptr}; +-use std::ffi::{CString, CStr, OsString, OsStr}; +-use std::os::unix::ffi::{OsStringExt, OsStrExt}; ++use crate::errno::{self, Errno}; ++#[cfg(not(target_os = "redox"))] ++#[cfg(feature = "fs")] ++use crate::fcntl::{at_rawfd, AtFlags}; ++#[cfg(feature = "fs")] ++use crate::fcntl::{fcntl, FcntlArg::F_SETFD, FdFlag, OFlag}; ++#[cfg(all( ++ feature = "fs", ++ any( ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "macos", ++ target_os = "ios" ++ ) ++))] ++use crate::sys::stat::FileFlag; ++#[cfg(feature = "fs")] ++use crate::sys::stat::Mode; ++use crate::{Error, NixPath, Result}; ++#[cfg(not(target_os = "redox"))] ++use cfg_if::cfg_if; ++use libc::{ ++ self, c_char, c_int, c_long, c_uint, c_void, gid_t, mode_t, off_t, pid_t, ++ size_t, uid_t, PATH_MAX, ++}; ++use std::convert::Infallible; ++use std::ffi::{CStr, OsString}; ++#[cfg(not(target_os = "redox"))] ++use std::ffi::{CString, OsStr}; ++#[cfg(not(target_os = "redox"))] ++use std::os::unix::ffi::OsStrExt; ++use std::os::unix::ffi::OsStringExt; + use std::os::unix::io::RawFd; + use std::path::PathBuf; +-use void::Void; +-use sys::stat::Mode; ++use std::{fmt, mem, ptr}; + +-#[cfg(any(target_os = "android", target_os = "linux"))] +-pub use self::pivot_root::*; ++feature! { ++ #![feature = "fs"] ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ pub use self::pivot_root::*; ++} + +-#[cfg(any(target_os = "android", target_os = "freebsd", +- target_os = "linux", target_os = "openbsd"))] ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "linux", ++ target_os = "openbsd" ++))] + pub use self::setres::*; + ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "linux", ++ target_os = "openbsd" ++))] ++pub use self::getres::*; ++ ++feature! { ++#![feature = "user"] ++ + /// User identifier + /// + /// Newtype pattern around `uid_t` (which is just alias). It prevents bugs caused by accidentally +@@ -30,27 +74,29 @@ pub struct Uid(uid_t); + + impl Uid { + /// Creates `Uid` from raw `uid_t`. +- pub fn from_raw(uid: uid_t) -> Self { ++ pub const fn from_raw(uid: uid_t) -> Self { + Uid(uid) + } + + /// Returns Uid of calling process. This is practically a more Rusty alias for `getuid`. ++ #[doc(alias("getuid"))] + pub fn current() -> Self { + getuid() + } + + /// Returns effective Uid of calling process. This is practically a more Rusty alias for `geteuid`. ++ #[doc(alias("geteuid"))] + pub fn effective() -> Self { + geteuid() + } + + /// Returns true if the `Uid` represents privileged user - root. (If it equals zero.) +- pub fn is_root(self) -> bool { +- self == ROOT ++ pub const fn is_root(self) -> bool { ++ self.0 == ROOT.0 + } + + /// Get the raw `uid_t` wrapped by `self`. +- pub fn as_raw(self) -> uid_t { ++ pub const fn as_raw(self) -> uid_t { + self.0 + } + } +@@ -61,6 +107,12 @@ impl From for uid_t { + } + } + ++impl From for Uid { ++ fn from(uid: uid_t) -> Self { ++ Uid(uid) ++ } ++} ++ + impl fmt::Display for Uid { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&self.0, f) +@@ -79,22 +131,24 @@ pub struct Gid(gid_t); + + impl Gid { + /// Creates `Gid` from raw `gid_t`. +- pub fn from_raw(gid: gid_t) -> Self { ++ pub const fn from_raw(gid: gid_t) -> Self { + Gid(gid) + } + + /// Returns Gid of calling process. This is practically a more Rusty alias for `getgid`. ++ #[doc(alias("getgid"))] + pub fn current() -> Self { + getgid() + } + + /// Returns effective Gid of calling process. This is practically a more Rusty alias for `getegid`. ++ #[doc(alias("getegid"))] + pub fn effective() -> Self { + getegid() + } + + /// Get the raw `gid_t` wrapped by `self`. +- pub fn as_raw(self) -> gid_t { ++ pub const fn as_raw(self) -> gid_t { + self.0 + } + } +@@ -105,37 +159,48 @@ impl From for gid_t { + } + } + ++impl From for Gid { ++ fn from(gid: gid_t) -> Self { ++ Gid(gid) ++ } ++} ++ + impl fmt::Display for Gid { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&self.0, f) + } + } ++} + ++feature! { ++#![feature = "process"] + /// Process identifier + /// + /// Newtype pattern around `pid_t` (which is just alias). It prevents bugs caused by accidentally + /// passing wrong value. +-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] ++#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] + pub struct Pid(pid_t); + + impl Pid { + /// Creates `Pid` from raw `pid_t`. +- pub fn from_raw(pid: pid_t) -> Self { ++ pub const fn from_raw(pid: pid_t) -> Self { + Pid(pid) + } + + /// Returns PID of calling process ++ #[doc(alias("getpid"))] + pub fn this() -> Self { + getpid() + } + + /// Returns PID of parent of calling process ++ #[doc(alias("getppid"))] + pub fn parent() -> Self { + getppid() + } + + /// Get the raw `pid_t` wrapped by `self`. +- pub fn as_raw(self) -> pid_t { ++ pub const fn as_raw(self) -> pid_t { + self.0 + } + } +@@ -169,10 +234,7 @@ impl ForkResult { + /// Return `true` if this is the child process of the `fork()` + #[inline] + pub fn is_child(self) -> bool { +- match self { +- ForkResult::Child => true, +- _ => false +- } ++ matches!(self, ForkResult::Child) + } + + /// Returns `true` if this is the parent process of the `fork()` +@@ -183,25 +245,30 @@ impl ForkResult { + } + + /// Create a new child process duplicating the parent process ([see +-/// fork(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html)). ++/// fork(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html)). + /// +-/// After calling the fork system call (successfully) two processes will +-/// be created that are identical with the exception of their pid and the ++/// After successfully calling the fork system call, a second process will ++/// be created which is identical to the original except for the pid and the + /// return value of this function. As an example: + /// +-/// ```no_run +-/// use nix::unistd::{fork, ForkResult}; ++/// ``` ++/// use nix::{sys::wait::waitpid,unistd::{fork, ForkResult, write}}; + /// +-/// match fork() { ++/// match unsafe{fork()} { + /// Ok(ForkResult::Parent { child, .. }) => { + /// println!("Continuing execution in parent process, new child has pid: {}", child); ++/// waitpid(child, None).unwrap(); ++/// } ++/// Ok(ForkResult::Child) => { ++/// // Unsafe to use `println!` (or `unwrap`) here. See Safety. ++/// write(libc::STDOUT_FILENO, "I'm a new child process\n".as_bytes()).ok(); ++/// unsafe { libc::_exit(0) }; + /// } +-/// Ok(ForkResult::Child) => println!("I'm a new child process"), + /// Err(_) => println!("Fork failed"), + /// } + /// ``` + /// +-/// This will print something like the following (order indeterministic). The ++/// This will print something like the following (order nondeterministic). The + /// thing to note is that you end up with two processes continuing execution + /// immediately after the fork call but with different match arms. + /// +@@ -220,11 +287,11 @@ impl ForkResult { + /// Those functions are only a small subset of your operating system's API, so + /// special care must be taken to only invoke code you can control and audit. + /// +-/// [async-signal-safe]: http://man7.org/linux/man-pages/man7/signal-safety.7.html ++/// [async-signal-safe]: https://man7.org/linux/man-pages/man7/signal-safety.7.html + #[inline] +-pub fn fork() -> Result { ++pub unsafe fn fork() -> Result { + use self::ForkResult::*; +- let res = unsafe { libc::fork() }; ++ let res = libc::fork(); + + Errno::result(res).map(|res| match res { + 0 => Child, +@@ -233,7 +300,7 @@ pub fn fork() -> Result { + } + + /// Get the pid of this process (see +-/// [getpid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpid.html)). ++/// [getpid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpid.html)). + /// + /// Since you are running code, there is always a pid to return, so there + /// is no error case that needs to be handled. +@@ -243,7 +310,7 @@ pub fn getpid() -> Pid { + } + + /// Get the pid of this processes' parent (see +-/// [getpid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getppid.html)). ++/// [getpid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getppid.html)). + /// + /// There is always a parent pid to return, so there is no error case that needs + /// to be handled. +@@ -253,7 +320,7 @@ pub fn getppid() -> Pid { + } + + /// Set a process group ID (see +-/// [setpgid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setpgid.html)). ++/// [setpgid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setpgid.html)). + /// + /// Set the process group id (PGID) of a particular process. If a pid of zero + /// is specified, then the pid of the calling process is used. Process groups +@@ -273,26 +340,29 @@ pub fn getpgid(pid: Option) -> Result { + } + + /// Create new session and set process group id (see +-/// [setsid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsid.html)). ++/// [setsid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsid.html)). + #[inline] + pub fn setsid() -> Result { + Errno::result(unsafe { libc::setsid() }).map(Pid) + } + + /// Get the process group ID of a session leader +-/// [getsid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsid.html). ++/// [getsid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsid.html). + /// + /// Obtain the process group ID of the process that is the session leader of the process specified + /// by pid. If pid is zero, it specifies the calling process. + #[inline] ++#[cfg(not(target_os = "redox"))] + pub fn getsid(pid: Option) -> Result { + let res = unsafe { libc::getsid(pid.unwrap_or(Pid(0)).into()) }; + Errno::result(res).map(Pid) + } ++} + +- ++feature! { ++#![all(feature = "process", feature = "term")] + /// Get the terminal foreground process group (see +-/// [tcgetpgrp(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetpgrp.html)). ++/// [tcgetpgrp(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetpgrp.html)). + /// + /// Get the group process id (GPID) of the foreground process group on the + /// terminal associated to file descriptor (FD). +@@ -302,7 +372,7 @@ pub fn tcgetpgrp(fd: c_int) -> Result { + Errno::result(res).map(Pid) + } + /// Set the terminal foreground process group (see +-/// [tcgetpgrp(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsetpgrp.html)). ++/// [tcgetpgrp(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsetpgrp.html)). + /// + /// Get the group process id (PGID) to the foreground process group on the + /// terminal associated to file descriptor (FD). +@@ -311,10 +381,12 @@ pub fn tcsetpgrp(fd: c_int, pgrp: Pid) -> Result<()> { + let res = unsafe { libc::tcsetpgrp(fd, pgrp.into()) }; + Errno::result(res).map(drop) + } ++} + +- ++feature! { ++#![feature = "process"] + /// Get the group id of the calling process (see +-///[getpgrp(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpgrp.html)). ++///[getpgrp(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpgrp.html)). + /// + /// Get the process group id (PGID) of the calling process. + /// According to the man page it is always successful. +@@ -324,7 +396,7 @@ pub fn getpgrp() -> Pid { + } + + /// Get the caller's thread ID (see +-/// [gettid(2)](http://man7.org/linux/man-pages/man2/gettid.2.html). ++/// [gettid(2)](https://man7.org/linux/man-pages/man2/gettid.2.html). + /// + /// This function is only available on Linux based systems. In a single + /// threaded process, the main thread will have the same ID as the process. In +@@ -338,11 +410,14 @@ pub fn getpgrp() -> Pid { + pub fn gettid() -> Pid { + Pid(unsafe { libc::syscall(libc::SYS_gettid) as pid_t }) + } ++} + ++feature! { ++#![feature = "fs"] + /// Create a copy of the specified file descriptor (see +-/// [dup(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.html)). ++/// [dup(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.html)). + /// +-/// The new file descriptor will be have a new index but refer to the same ++/// The new file descriptor will have a new index but refer to the same + /// resource as the old file descriptor and the old and new file descriptors may + /// be used interchangeably. The new and old file descriptor share the same + /// underlying resource, offset, and file status flags. The actual index used +@@ -357,7 +432,7 @@ pub fn dup(oldfd: RawFd) -> Result { + } + + /// Create a copy of the specified file descriptor using the specified fd (see +-/// [dup(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.html)). ++/// [dup(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.html)). + /// + /// This function behaves similar to `dup()` except that it will try to use the + /// specified fd instead of allocating a new one. See the man pages for more +@@ -370,7 +445,7 @@ pub fn dup2(oldfd: RawFd, newfd: RawFd) -> Result { + } + + /// Create a new copy of the specified file descriptor using the specified fd +-/// and flags (see [dup(2)](http://man7.org/linux/man-pages/man2/dup.2.html)). ++/// and flags (see [dup(2)](https://man7.org/linux/man-pages/man2/dup.2.html)). + /// + /// This function behaves similar to `dup2()` but allows for flags to be + /// specified. +@@ -381,7 +456,7 @@ pub fn dup3(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result { + #[inline] + fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result { + if oldfd == newfd { +- return Err(Error::Sys(Errno::EINVAL)); ++ return Err(Errno::EINVAL); + } + + let fd = dup2(oldfd, newfd)?; +@@ -397,7 +472,7 @@ fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result { + } + + /// Change the current working directory of the calling process (see +-/// [chdir(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html)). ++/// [chdir(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html)). + /// + /// This function may fail in a number of different scenarios. See the man + /// pages for additional details on possible failure cases. +@@ -412,18 +487,19 @@ pub fn chdir(path: &P) -> Result<()> { + + /// Change the current working directory of the process to the one + /// given as an open file descriptor (see +-/// [fchdir(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchdir.html)). ++/// [fchdir(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchdir.html)). + /// + /// This function may fail in a number of different scenarios. See the man + /// pages for additional details on possible failure cases. + #[inline] ++#[cfg(not(target_os = "fuchsia"))] + pub fn fchdir(dirfd: RawFd) -> Result<()> { + let res = unsafe { libc::fchdir(dirfd) }; + + Errno::result(res).map(drop) + } + +-/// Creates new directory `path` with access rights `mode`. (see [mkdir(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdir.html)) ++/// Creates new directory `path` with access rights `mode`. (see [mkdir(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdir.html)) + /// + /// # Errors + /// +@@ -436,22 +512,17 @@ pub fn fchdir(dirfd: RawFd) -> Result<()> { + /// # Example + /// + /// ```rust +-/// extern crate tempfile; +-/// extern crate nix; +-/// + /// use nix::unistd; + /// use nix::sys::stat; + /// use tempfile::tempdir; + /// +-/// fn main() { +-/// let tmp_dir1 = tempdir().unwrap(); +-/// let tmp_dir2 = tmp_dir1.path().join("new_dir"); ++/// let tmp_dir1 = tempdir().unwrap(); ++/// let tmp_dir2 = tmp_dir1.path().join("new_dir"); + /// +-/// // create new directory and give read, write and execute rights to the owner +-/// match unistd::mkdir(&tmp_dir2, stat::Mode::S_IRWXU) { +-/// Ok(_) => println!("created {:?}", tmp_dir2), +-/// Err(err) => println!("Error creating directory: {}", err), +-/// } ++/// // create new directory and give read, write and execute rights to the owner ++/// match unistd::mkdir(&tmp_dir2, stat::Mode::S_IRWXU) { ++/// Ok(_) => println!("created {:?}", tmp_dir2), ++/// Err(err) => println!("Error creating directory: {}", err), + /// } + /// ``` + #[inline] +@@ -474,30 +545,26 @@ pub fn mkdir(path: &P, mode: Mode) -> Result<()> { + /// - the path name is too long (longer than `PATH_MAX`, usually 4096 on linux, 1024 on OS X) + /// + /// For a full list consult +-/// [posix specification](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifo.html) ++/// [posix specification](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifo.html) + /// + /// # Example + /// + /// ```rust +-/// extern crate tempfile; +-/// extern crate nix; +-/// + /// use nix::unistd; + /// use nix::sys::stat; + /// use tempfile::tempdir; + /// +-/// fn main() { +-/// let tmp_dir = tempdir().unwrap(); +-/// let fifo_path = tmp_dir.path().join("foo.pipe"); ++/// let tmp_dir = tempdir().unwrap(); ++/// let fifo_path = tmp_dir.path().join("foo.pipe"); + /// +-/// // create new fifo and give read, write and execute rights to the owner +-/// match unistd::mkfifo(&fifo_path, stat::Mode::S_IRWXU) { +-/// Ok(_) => println!("created {:?}", fifo_path), +-/// Err(err) => println!("Error creating fifo: {}", err), +-/// } ++/// // create new fifo and give read, write and execute rights to the owner ++/// match unistd::mkfifo(&fifo_path, stat::Mode::S_IRWXU) { ++/// Ok(_) => println!("created {:?}", fifo_path), ++/// Err(err) => println!("Error creating fifo: {}", err), + /// } + /// ``` + #[inline] ++#[cfg(not(target_os = "redox"))] // RedoxFS does not support fifo yet + pub fn mkfifo(path: &P, mode: Mode) -> Result<()> { + let res = path.with_nix_path(|cstr| { + unsafe { libc::mkfifo(cstr.as_ptr(), mode.bits() as mode_t) } +@@ -507,17 +574,19 @@ pub fn mkfifo(path: &P, mode: Mode) -> Result<()> { + } + + /// Creates new fifo special file (named pipe) with path `path` and access rights `mode`. +-/// ++/// + /// If `dirfd` has a value, then `path` is relative to directory associated with the file descriptor. +-/// +-/// If `dirfd` is `None`, then `path` is relative to the current working directory. +-/// ++/// ++/// If `dirfd` is `None`, then `path` is relative to the current working directory. ++/// + /// # References +-/// +-/// [mkfifoat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifoat.html). ++/// ++/// [mkfifoat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifoat.html). + // mkfifoat is not implemented in OSX or android + #[inline] +-#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))] ++#[cfg(not(any( ++ target_os = "macos", target_os = "ios", target_os = "haiku", ++ target_os = "android", target_os = "redox")))] + pub fn mkfifoat(dirfd: Option, path: &P, mode: Mode) -> Result<()> { + let res = path.with_nix_path(|cstr| unsafe { + libc::mkfifoat(at_rawfd(dirfd), cstr.as_ptr(), mode.bits() as mode_t) +@@ -534,7 +603,8 @@ pub fn mkfifoat(dirfd: Option, path: &P, mode: Mode) + /// If `dirfd` is `None`, then `path2` is relative to the current working + /// directory. This is identical to `libc::symlink(path1, path2)`. + /// +-/// See also [symlinkat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/symlinkat.html). ++/// See also [symlinkat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/symlinkat.html). ++#[cfg(not(target_os = "redox"))] + pub fn symlinkat( + path1: &P1, + dirfd: Option, +@@ -553,14 +623,16 @@ pub fn symlinkat( + })??; + Errno::result(res).map(drop) + } ++} + + // Double the buffer capacity up to limit. In case it already has + // reached the limit, return Errno::ERANGE. ++#[cfg(any(feature = "fs", feature = "user"))] + fn reserve_double_buffer_size(buf: &mut Vec, limit: usize) -> Result<()> { + use std::cmp::min; + +- if buf.len() >= limit { +- return Err(Error::Sys(Errno::ERANGE)) ++ if buf.capacity() >= limit { ++ return Err(Errno::ERANGE); + } + + let capacity = min(buf.capacity() * 2, limit); +@@ -569,6 +641,9 @@ fn reserve_double_buffer_size(buf: &mut Vec, limit: usize) -> Result<()> { + Ok(()) + } + ++feature! { ++#![feature = "fs"] ++ + /// Returns the current directory as a `PathBuf` + /// + /// Err is returned if the current user doesn't have the permission to read or search a component +@@ -577,15 +652,11 @@ fn reserve_double_buffer_size(buf: &mut Vec, limit: usize) -> Result<()> { + /// # Example + /// + /// ```rust +-/// extern crate nix; +-/// + /// use nix::unistd; + /// +-/// fn main() { +-/// // assume that we are allowed to get current directory +-/// let dir = unistd::getcwd().unwrap(); +-/// println!("The current directory is {:?}", dir); +-/// } ++/// // assume that we are allowed to get current directory ++/// let dir = unistd::getcwd().unwrap(); ++/// println!("The current directory is {:?}", dir); + /// ``` + #[inline] + pub fn getcwd() -> Result { +@@ -607,17 +678,23 @@ pub fn getcwd() -> Result { + let error = Errno::last(); + // ERANGE means buffer was too small to store directory name + if error != Errno::ERANGE { +- return Err(Error::Sys(error)); ++ return Err(error); + } +- } ++ } + + // Trigger the internal buffer resizing logic. + reserve_double_buffer_size(&mut buf, PATH_MAX as usize)?; + } + } + } ++} ++ ++feature! { ++#![all(feature = "user", feature = "fs")] + + /// Computes the raw UID and GID values to pass to a `*chown` call. ++// The cast is not unnecessary on all platforms. ++#[allow(clippy::unnecessary_cast)] + fn chown_raw_ids(owner: Option, group: Option) -> (libc::uid_t, libc::gid_t) { + // According to the POSIX specification, -1 is used to indicate that owner and group + // are not to be changed. Since uid_t and gid_t are unsigned types, we have to wrap +@@ -631,7 +708,7 @@ fn chown_raw_ids(owner: Option, group: Option) -> (libc::uid_t, libc:: + + /// Change the ownership of the file at `path` to be owned by the specified + /// `owner` (user) and `group` (see +-/// [chown(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/chown.html)). ++/// [chown(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/chown.html)). + /// + /// The owner/group for the provided path name will not be modified if `None` is + /// provided for that argument. Ownership change will be attempted for the path +@@ -646,6 +723,20 @@ pub fn chown(path: &P, owner: Option, group: Option, group: Option) -> Result<()> { ++ let (uid, gid) = chown_raw_ids(owner, group); ++ let res = unsafe { libc::fchown(fd, uid, gid) }; ++ Errno::result(res).map(drop) ++} ++ + /// Flags for `fchownat` function. + #[derive(Clone, Copy, Debug)] + pub enum FchownatFlags { +@@ -667,13 +758,14 @@ pub enum FchownatFlags { + /// If `flag` is `FchownatFlags::NoFollowSymlink` and `path` names a symbolic link, + /// then the mode of the symbolic link is changed. + /// +-/// `fchownat(None, path, mode, FchownatFlags::NoFollowSymlink)` is identical to +-/// a call `libc::lchown(path, mode)`. That's why `lchmod` is unimplemented in ++/// `fchownat(None, path, owner, group, FchownatFlags::NoFollowSymlink)` is identical to ++/// a call `libc::lchown(path, owner, group)`. That's why `lchown` is unimplemented in + /// the `nix` crate. + /// + /// # References + /// +-/// [fchownat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchownat.html). ++/// [fchownat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchownat.html). ++#[cfg(not(target_os = "redox"))] + pub fn fchownat( + dirfd: Option, + path: &P, +@@ -694,32 +786,38 @@ pub fn fchownat( + + Errno::result(res).map(drop) + } ++} + +-fn to_exec_array(args: &[&CStr]) -> Vec<*const c_char> { ++feature! { ++#![feature = "process"] ++fn to_exec_array>(args: &[S]) -> Vec<*const c_char> { + use std::iter::once; +- args.iter().map(|s| s.as_ptr()).chain(once(ptr::null())).collect() ++ args.iter() ++ .map(|s| s.as_ref().as_ptr()) ++ .chain(once(ptr::null())) ++ .collect() + } + + /// Replace the current process image with a new one (see +-/// [exec(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)). ++/// [exec(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)). + /// + /// See the `::nix::unistd::execve` system call for additional details. `execv` + /// performs the same action but does not allow for customization of the + /// environment for the new process. + #[inline] +-pub fn execv(path: &CStr, argv: &[&CStr]) -> Result { ++pub fn execv>(path: &CStr, argv: &[S]) -> Result { + let args_p = to_exec_array(argv); + + unsafe { + libc::execv(path.as_ptr(), args_p.as_ptr()) + }; + +- Err(Error::Sys(Errno::last())) ++ Err(Errno::last()) + } + + + /// Replace the current process image with a new one (see +-/// [execve(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)). ++/// [execve(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)). + /// + /// The execve system call allows for another process to be "called" which will + /// replace the current process image. That is, this process becomes the new +@@ -731,7 +829,7 @@ pub fn execv(path: &CStr, argv: &[&CStr]) -> Result { + /// in the `args` list is an argument to the new process. Each element in the + /// `env` list should be a string in the form "key=value". + #[inline] +-pub fn execve(path: &CStr, args: &[&CStr], env: &[&CStr]) -> Result { ++pub fn execve, SE: AsRef>(path: &CStr, args: &[SA], env: &[SE]) -> Result { + let args_p = to_exec_array(args); + let env_p = to_exec_array(env); + +@@ -739,12 +837,12 @@ pub fn execve(path: &CStr, args: &[&CStr], env: &[&CStr]) -> Result { + libc::execve(path.as_ptr(), args_p.as_ptr(), env_p.as_ptr()) + }; + +- Err(Error::Sys(Errno::last())) ++ Err(Errno::last()) + } + + /// Replace the current process image with a new one and replicate shell `PATH` + /// searching behavior (see +-/// [exec(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)). ++/// [exec(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)). + /// + /// See `::nix::unistd::execve` for additional details. `execvp` behaves the + /// same as execv except that it will examine the `PATH` environment variables +@@ -752,19 +850,19 @@ pub fn execve(path: &CStr, args: &[&CStr], env: &[&CStr]) -> Result { + /// would not work if "bash" was specified for the path argument, but `execvp` + /// would assuming that a bash executable was on the system `PATH`. + #[inline] +-pub fn execvp(filename: &CStr, args: &[&CStr]) -> Result { ++pub fn execvp>(filename: &CStr, args: &[S]) -> Result { + let args_p = to_exec_array(args); + + unsafe { + libc::execvp(filename.as_ptr(), args_p.as_ptr()) + }; + +- Err(Error::Sys(Errno::last())) ++ Err(Errno::last()) + } + + /// Replace the current process image with a new one and replicate shell `PATH` + /// searching behavior (see +-/// [`execvpe(3)`](http://man7.org/linux/man-pages/man3/exec.3.html)). ++/// [`execvpe(3)`](https://man7.org/linux/man-pages/man3/exec.3.html)). + /// + /// This functions like a combination of `execvp(2)` and `execve(2)` to pass an + /// environment and have a search path. See these two for additional +@@ -772,7 +870,7 @@ pub fn execvp(filename: &CStr, args: &[&CStr]) -> Result { + #[cfg(any(target_os = "haiku", + target_os = "linux", + target_os = "openbsd"))] +-pub fn execvpe(filename: &CStr, args: &[&CStr], env: &[&CStr]) -> Result { ++pub fn execvpe, SE: AsRef>(filename: &CStr, args: &[SA], env: &[SE]) -> Result { + let args_p = to_exec_array(args); + let env_p = to_exec_array(env); + +@@ -780,11 +878,11 @@ pub fn execvpe(filename: &CStr, args: &[&CStr], env: &[&CStr]) -> Result { + libc::execvpe(filename.as_ptr(), args_p.as_ptr(), env_p.as_ptr()) + }; + +- Err(Error::Sys(Errno::last())) ++ Err(Errno::last()) + } + + /// Replace the current process image with a new one (see +-/// [fexecve(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fexecve.html)). ++/// [fexecve(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fexecve.html)). + /// + /// The `fexecve` function allows for another process to be "called" which will + /// replace the current process image. That is, this process becomes the new +@@ -793,14 +891,12 @@ pub fn execvpe(filename: &CStr, args: &[&CStr], env: &[&CStr]) -> Result { + /// + /// This function is similar to `execve`, except that the program to be executed + /// is referenced as a file descriptor instead of a path. +-// Note for NetBSD and OpenBSD: although rust-lang/libc includes it (under +-// unix/bsd/netbsdlike/) fexecve is not currently implemented on NetBSD nor on +-// OpenBSD. + #[cfg(any(target_os = "android", + target_os = "linux", ++ target_os = "dragonfly", + target_os = "freebsd"))] + #[inline] +-pub fn fexecve(fd: RawFd, args: &[&CStr], env: &[&CStr]) -> Result { ++pub fn fexecve ,SE: AsRef>(fd: RawFd, args: &[SA], env: &[SE]) -> Result { + let args_p = to_exec_array(args); + let env_p = to_exec_array(env); + +@@ -808,11 +904,11 @@ pub fn fexecve(fd: RawFd, args: &[&CStr], env: &[&CStr]) -> Result { + libc::fexecve(fd, args_p.as_ptr(), env_p.as_ptr()) + }; + +- Err(Error::Sys(Errno::last())) ++ Err(Errno::last()) + } + + /// Execute program relative to a directory file descriptor (see +-/// [execveat(2)](http://man7.org/linux/man-pages/man2/execveat.2.html)). ++/// [execveat(2)](https://man7.org/linux/man-pages/man2/execveat.2.html)). + /// + /// The `execveat` function allows for another process to be "called" which will + /// replace the current process image. That is, this process becomes the new +@@ -823,8 +919,8 @@ pub fn fexecve(fd: RawFd, args: &[&CStr], env: &[&CStr]) -> Result { + /// is referenced as a file descriptor to the base directory plus a path. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[inline] +-pub fn execveat(dirfd: RawFd, pathname: &CStr, args: &[&CStr], +- env: &[&CStr], flags: super::fcntl::AtFlags) -> Result { ++pub fn execveat,SE: AsRef>(dirfd: RawFd, pathname: &CStr, args: &[SA], ++ env: &[SE], flags: super::fcntl::AtFlags) -> Result { + let args_p = to_exec_array(args); + let env_p = to_exec_array(env); + +@@ -833,11 +929,11 @@ pub fn execveat(dirfd: RawFd, pathname: &CStr, args: &[&CStr], + args_p.as_ptr(), env_p.as_ptr(), flags); + }; + +- Err(Error::Sys(Errno::last())) ++ Err(Errno::last()) + } + + /// Daemonize this process by detaching from the controlling terminal (see +-/// [daemon(3)](http://man7.org/linux/man-pages/man3/daemon.3.html)). ++/// [daemon(3)](https://man7.org/linux/man-pages/man3/daemon.3.html)). + /// + /// When a process is launched it is typically associated with a parent and it, + /// in turn, by its controlling terminal/process. In order for a process to run +@@ -861,30 +957,40 @@ pub fn execveat(dirfd: RawFd, pathname: &CStr, args: &[&CStr], + /// descriptors will remain identical after daemonizing. + /// * `noclose = false`: The process' stdin, stdout, and stderr will point to + /// `/dev/null` after daemonizing. +-#[cfg_attr(any(target_os = "macos", target_os = "ios"), deprecated( +- since="0.14.0", +- note="Deprecated in MacOSX 10.5" +-))] +-#[cfg_attr(any(target_os = "macos", target_os = "ios"), allow(deprecated))] ++#[cfg(any(target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "netbsd", ++ target_os = "openbsd", ++ target_os = "solaris"))] + pub fn daemon(nochdir: bool, noclose: bool) -> Result<()> { + let res = unsafe { libc::daemon(nochdir as c_int, noclose as c_int) }; + Errno::result(res).map(drop) + } ++} ++ ++feature! { ++#![feature = "hostname"] + + /// Set the system host name (see +-/// [sethostname(2)](http://man7.org/linux/man-pages/man2/gethostname.2.html)). ++/// [sethostname(2)](https://man7.org/linux/man-pages/man2/gethostname.2.html)). + /// + /// Given a name, attempt to update the system host name to the given string. + /// On some systems, the host name is limited to as few as 64 bytes. An error +-/// will be return if the name is not valid or the current process does not have +-/// permissions to update the host name. ++/// will be returned if the name is not valid or the current process does not ++/// have permissions to update the host name. ++#[cfg(not(target_os = "redox"))] + pub fn sethostname>(name: S) -> Result<()> { + // Handle some differences in type of the len arg across platforms. + cfg_if! { + if #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", ++ target_os = "illumos", + target_os = "ios", +- target_os = "macos", ))] { ++ target_os = "macos", ++ target_os = "solaris", ))] { + type sethostname_len_t = c_int; + } else { + type sethostname_len_t = size_t; +@@ -897,36 +1003,37 @@ pub fn sethostname>(name: S) -> Result<()> { + Errno::result(res).map(drop) + } + +-/// Get the host name and store it in the provided buffer, returning a pointer +-/// the `CStr` in that buffer on success (see +-/// [gethostname(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html)). ++/// Get the host name and store it in an internally allocated buffer, returning an ++/// `OsString` on success (see ++/// [gethostname(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html)). + /// + /// This function call attempts to get the host name for the running system and +-/// store it in a provided buffer. The buffer will be populated with bytes up +-/// to the length of the provided slice including a NUL terminating byte. If +-/// the hostname is longer than the length provided, no error will be provided. +-/// The posix specification does not specify whether implementations will +-/// null-terminate in this case, but the nix implementation will ensure that the +-/// buffer is null terminated in this case. ++/// store it in an internal buffer, returning it as an `OsString` if successful. + /// + /// ```no_run + /// use nix::unistd; + /// +-/// let mut buf = [0u8; 64]; +-/// let hostname_cstr = unistd::gethostname(&mut buf).expect("Failed getting hostname"); +-/// let hostname = hostname_cstr.to_str().expect("Hostname wasn't valid UTF-8"); ++/// let hostname = unistd::gethostname().expect("Failed getting hostname"); ++/// let hostname = hostname.into_string().expect("Hostname wasn't valid UTF-8"); + /// println!("Hostname: {}", hostname); + /// ``` +-pub fn gethostname(buffer: &mut [u8]) -> Result<&CStr> { ++pub fn gethostname() -> Result { ++ // The capacity is the max length of a hostname plus the NUL terminator. ++ let mut buffer: Vec = Vec::with_capacity(256); + let ptr = buffer.as_mut_ptr() as *mut c_char; +- let len = buffer.len() as size_t; ++ let len = buffer.capacity() as size_t; + + let res = unsafe { libc::gethostname(ptr, len) }; + Errno::result(res).map(|_| { +- buffer[len - 1] = 0; // ensure always null-terminated +- unsafe { CStr::from_ptr(buffer.as_ptr() as *const c_char) } ++ unsafe { ++ buffer.as_mut_ptr().wrapping_add(len - 1).write(0); // ensure always null-terminated ++ let len = CStr::from_ptr(buffer.as_ptr() as *const c_char).len(); ++ buffer.set_len(len); ++ } ++ OsString::from_vec(buffer) + }) + } ++} + + /// Close a raw file descriptor + /// +@@ -934,34 +1041,24 @@ pub fn gethostname(buffer: &mut [u8]) -> Result<&CStr> { + /// `std::fs::File`. Explicitly closing them with this method too can result in + /// a double-close condition, which can cause confusing `EBADF` errors in + /// seemingly unrelated code. Caveat programmer. See also +-/// [close(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html). ++/// [close(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html). + /// + /// # Examples + /// + /// ```no_run +-/// extern crate tempfile; +-/// extern crate nix; +-/// + /// use std::os::unix::io::AsRawFd; + /// use nix::unistd::close; + /// +-/// fn main() { +-/// let f = tempfile::tempfile().unwrap(); +-/// close(f.as_raw_fd()).unwrap(); // Bad! f will also close on drop! +-/// } ++/// let f = tempfile::tempfile().unwrap(); ++/// close(f.as_raw_fd()).unwrap(); // Bad! f will also close on drop! + /// ``` + /// + /// ```rust +-/// extern crate tempfile; +-/// extern crate nix; +-/// + /// use std::os::unix::io::IntoRawFd; + /// use nix::unistd::close; + /// +-/// fn main() { +-/// let f = tempfile::tempfile().unwrap(); +-/// close(f.into_raw_fd()).unwrap(); // Good. into_raw_fd consumes f +-/// } ++/// let f = tempfile::tempfile().unwrap(); ++/// close(f.into_raw_fd()).unwrap(); // Good. into_raw_fd consumes f + /// ``` + pub fn close(fd: RawFd) -> Result<()> { + let res = unsafe { libc::close(fd) }; +@@ -970,22 +1067,29 @@ pub fn close(fd: RawFd) -> Result<()> { + + /// Read from a raw file descriptor. + /// +-/// See also [read(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html) ++/// See also [read(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html) + pub fn read(fd: RawFd, buf: &mut [u8]) -> Result { +- let res = unsafe { libc::read(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t) }; ++ let res = unsafe { ++ libc::read(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t) ++ }; + + Errno::result(res).map(|r| r as usize) + } + + /// Write to a raw file descriptor. + /// +-/// See also [write(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html) ++/// See also [write(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html) + pub fn write(fd: RawFd, buf: &[u8]) -> Result { +- let res = unsafe { libc::write(fd, buf.as_ptr() as *const c_void, buf.len() as size_t) }; ++ let res = unsafe { ++ libc::write(fd, buf.as_ptr() as *const c_void, buf.len() as size_t) ++ }; + + Errno::result(res).map(|r| r as usize) + } + ++feature! { ++#![feature = "fs"] ++ + /// Directive that tells [`lseek`] and [`lseek64`] what the offset is relative to. + /// + /// [`lseek`]: ./fn.lseek.html +@@ -1002,26 +1106,28 @@ pub enum Whence { + /// Specify an offset relative to the next location in the file greater than or + /// equal to offset that contains some data. If offset points to + /// some data, then the file offset is set to offset. +- #[cfg(any(target_os = "dragonfly", target_os = "freebsd", +- all(target_os = "linux", not(any(target_env = "musl", +- target_arch = "mips", +- target_arch = "mips64")))))] ++ #[cfg(any(target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "solaris"))] + SeekData = libc::SEEK_DATA, + /// Specify an offset relative to the next hole in the file greater than + /// or equal to offset. If offset points into the middle of a hole, then + /// the file offset should be set to offset. If there is no hole past offset, + /// then the file offset should be adjusted to the end of the file (i.e., there + /// is an implicit hole at the end of any file). +- #[cfg(any(target_os = "dragonfly", target_os = "freebsd", +- all(target_os = "linux", not(any(target_env = "musl", +- target_arch = "mips", +- target_arch = "mips64")))))] ++ #[cfg(any(target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "solaris"))] + SeekHole = libc::SEEK_HOLE + } + + /// Move the read/write file offset. + /// +-/// See also [lseek(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html) ++/// See also [lseek(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html) + pub fn lseek(fd: RawFd, offset: off_t, whence: Whence) -> Result { + let res = unsafe { libc::lseek(fd, offset, whence as i32) }; + +@@ -1034,38 +1140,44 @@ pub fn lseek64(fd: RawFd, offset: libc::off64_t, whence: Whence) -> Result Result<(RawFd, RawFd)> { +- unsafe { +- let mut fds = mem::MaybeUninit::<[c_int; 2]>::uninit(); ++/// See also [pipe(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pipe.html) ++pub fn pipe() -> std::result::Result<(RawFd, RawFd), Error> { ++ let mut fds = mem::MaybeUninit::<[c_int; 2]>::uninit(); + +- let res = libc::pipe(fds.as_mut_ptr() as *mut c_int); ++ let res = unsafe { libc::pipe(fds.as_mut_ptr() as *mut c_int) }; + +- Errno::result(res)?; ++ Error::result(res)?; + +- Ok((fds.assume_init()[0], fds.assume_init()[1])) +- } ++ unsafe { Ok((fds.assume_init()[0], fds.assume_init()[1])) } + } + ++feature! { ++#![feature = "fs"] + /// Like `pipe`, but allows setting certain file descriptor flags. + /// + /// The following flags are supported, and will be set atomically as the pipe is + /// created: + /// +-/// `O_CLOEXEC`: Set the close-on-exec flag for the new file descriptors. +-/// `O_NONBLOCK`: Set the non-blocking flag for the ends of the pipe. ++/// - `O_CLOEXEC`: Set the close-on-exec flag for the new file descriptors. ++#[cfg_attr(target_os = "linux", doc = "- `O_DIRECT`: Create a pipe that performs I/O in \"packet\" mode.")] ++#[cfg_attr(target_os = "netbsd", doc = "- `O_NOSIGPIPE`: Return `EPIPE` instead of raising `SIGPIPE`.")] ++/// - `O_NONBLOCK`: Set the non-blocking flag for the ends of the pipe. + /// +-/// See also [pipe(2)](http://man7.org/linux/man-pages/man2/pipe.2.html) ++/// See also [pipe(2)](https://man7.org/linux/man-pages/man2/pipe.2.html) + #[cfg(any(target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", ++ target_os = "illumos", + target_os = "linux", ++ target_os = "redox", + target_os = "netbsd", +- target_os = "openbsd"))] ++ target_os = "openbsd", ++ target_os = "solaris"))] + pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> { + let mut fds = mem::MaybeUninit::<[c_int; 2]>::uninit(); + +@@ -1078,64 +1190,11 @@ pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> { + unsafe { Ok((fds.assume_init()[0], fds.assume_init()[1])) } + } + +-/// Like `pipe`, but allows setting certain file descriptor flags. +-/// +-/// The following flags are supported, and will be set after the pipe is +-/// created: +-/// +-/// `O_CLOEXEC`: Set the close-on-exec flag for the new file descriptors. +-/// `O_NONBLOCK`: Set the non-blocking flag for the ends of the pipe. +-#[cfg(any(target_os = "ios", target_os = "macos"))] +-#[deprecated( +- since="0.10.0", +- note="pipe2(2) is not actually atomic on these platforms. Use pipe(2) and fcntl(2) instead" +-)] +-pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> { +- let mut fds = mem::MaybeUninit::<[c_int; 2]>::uninit(); +- +- let res = unsafe { libc::pipe(fds.as_mut_ptr() as *mut c_int) }; +- +- Errno::result(res)?; +- +- unsafe { +- pipe2_setflags(fds.assume_init()[0], fds.assume_init()[1], flags)?; +- +- Ok((fds.assume_init()[0], fds.assume_init()[1])) +- } +-} +- +-#[cfg(any(target_os = "ios", target_os = "macos"))] +-fn pipe2_setflags(fd1: RawFd, fd2: RawFd, flags: OFlag) -> Result<()> { +- use fcntl::FcntlArg::F_SETFL; +- +- let mut res = Ok(0); +- +- if flags.contains(OFlag::O_CLOEXEC) { +- res = res +- .and_then(|_| fcntl(fd1, F_SETFD(FdFlag::FD_CLOEXEC))) +- .and_then(|_| fcntl(fd2, F_SETFD(FdFlag::FD_CLOEXEC))); +- } +- +- if flags.contains(OFlag::O_NONBLOCK) { +- res = res +- .and_then(|_| fcntl(fd1, F_SETFL(OFlag::O_NONBLOCK))) +- .and_then(|_| fcntl(fd2, F_SETFL(OFlag::O_NONBLOCK))); +- } +- +- match res { +- Ok(_) => Ok(()), +- Err(e) => { +- let _ = close(fd1); +- let _ = close(fd2); +- Err(e) +- } +- } +-} +- + /// Truncate a file to a specified length + /// + /// See also +-/// [truncate(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html) ++/// [truncate(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html) ++#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))] + pub fn truncate(path: &P, len: off_t) -> Result<()> { + let res = path.with_nix_path(|cstr| { + unsafe { +@@ -1149,7 +1208,7 @@ pub fn truncate(path: &P, len: off_t) -> Result<()> { + /// Truncate a file to a specified length + /// + /// See also +-/// [ftruncate(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html) ++/// [ftruncate(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html) + pub fn ftruncate(fd: RawFd, len: off_t) -> Result<()> { + Errno::result(unsafe { libc::ftruncate(fd, len) }).map(drop) + } +@@ -1163,9 +1222,9 @@ pub fn isatty(fd: RawFd) -> Result { + } else { + match Errno::last() { + Errno::ENOTTY => Ok(false), +- err => Err(Error::Sys(err)), ++ err => Err(err), + } +- } ++ } + } + } + +@@ -1188,7 +1247,8 @@ pub enum LinkatFlags { + /// process. If either `oldpath` or `newpath` is absolute, then `dirfd` is ignored. + /// + /// # References +-/// See also [linkat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/linkat.html) ++/// See also [linkat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/linkat.html) ++#[cfg(not(target_os = "redox"))] // RedoxFS does not support symlinks yet + pub fn linkat( + olddirfd: Option, + oldpath: &P, +@@ -1223,7 +1283,7 @@ pub fn linkat( + + /// Remove a directory entry + /// +-/// See also [unlink(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html) ++/// See also [unlink(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html) + pub fn unlink(path: &P) -> Result<()> { + let res = path.with_nix_path(|cstr| { + unsafe { +@@ -1249,7 +1309,8 @@ pub enum UnlinkatFlags { + /// is performed. + /// + /// # References +-/// See also [unlinkat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlinkat.html) ++/// See also [unlinkat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlinkat.html) ++#[cfg(not(target_os = "redox"))] + pub fn unlinkat( + dirfd: Option, + path: &P, +@@ -1270,6 +1331,7 @@ pub fn unlinkat( + + + #[inline] ++#[cfg(not(target_os = "fuchsia"))] + pub fn chroot(path: &P) -> Result<()> { + let res = path.with_nix_path(|cstr| { + unsafe { libc::chroot(cstr.as_ptr()) } +@@ -1280,7 +1342,7 @@ pub fn chroot(path: &P) -> Result<()> { + + /// Commit filesystem caches to disk + /// +-/// See also [sync(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sync.html) ++/// See also [sync(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sync.html) + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", +@@ -1292,9 +1354,20 @@ pub fn sync() { + unsafe { libc::sync() }; + } + ++/// Commit filesystem caches containing file referred to by the open file ++/// descriptor `fd` to disk ++/// ++/// See also [syncfs(2)](https://man7.org/linux/man-pages/man2/sync.2.html) ++#[cfg(target_os = "linux")] ++pub fn syncfs(fd: RawFd) -> Result<()> { ++ let res = unsafe { libc::syncfs(fd) }; ++ ++ Errno::result(res).map(drop) ++} ++ + /// Synchronize changes to a file + /// +-/// See also [fsync(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html) ++/// See also [fsync(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html) + #[inline] + pub fn fsync(fd: RawFd) -> Result<()> { + let res = unsafe { libc::fsync(fd) }; +@@ -1305,22 +1378,30 @@ pub fn fsync(fd: RawFd) -> Result<()> { + /// Synchronize the data of a file + /// + /// See also +-/// [fdatasync(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html) +-// `fdatasync(2) is in POSIX, but in libc it is only defined in `libc::notbsd`. +-// TODO: exclude only Apple systems after https://github.com/rust-lang/libc/pull/211 ++/// [fdatasync(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html) + #[cfg(any(target_os = "linux", + target_os = "android", +- target_os = "emscripten"))] ++ target_os = "emscripten", ++ target_os = "freebsd", ++ target_os = "fuchsia", ++ target_os = "netbsd", ++ target_os = "openbsd", ++ target_os = "illumos", ++ target_os = "solaris"))] + #[inline] + pub fn fdatasync(fd: RawFd) -> Result<()> { + let res = unsafe { libc::fdatasync(fd) }; + + Errno::result(res).map(drop) + } ++} ++ ++feature! { ++#![feature = "user"] + + /// Get a real user ID + /// +-/// See also [getuid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getuid.html) ++/// See also [getuid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getuid.html) + // POSIX requires that getuid is always successful, so no need to check return + // value or errno. + #[inline] +@@ -1330,7 +1411,7 @@ pub fn getuid() -> Uid { + + /// Get the effective user ID + /// +-/// See also [geteuid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/geteuid.html) ++/// See also [geteuid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/geteuid.html) + // POSIX requires that geteuid is always successful, so no need to check return + // value or errno. + #[inline] +@@ -1340,7 +1421,7 @@ pub fn geteuid() -> Uid { + + /// Get the real group ID + /// +-/// See also [getgid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getgid.html) ++/// See also [getgid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getgid.html) + // POSIX requires that getgid is always successful, so no need to check return + // value or errno. + #[inline] +@@ -1350,7 +1431,7 @@ pub fn getgid() -> Gid { + + /// Get the effective group ID + /// +-/// See also [getegid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getegid.html) ++/// See also [getegid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getegid.html) + // POSIX requires that getegid is always successful, so no need to check return + // value or errno. + #[inline] +@@ -1360,7 +1441,7 @@ pub fn getegid() -> Gid { + + /// Set the effective user ID + /// +-/// See also [seteuid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/seteuid.html) ++/// See also [seteuid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/seteuid.html) + #[inline] + pub fn seteuid(euid: Uid) -> Result<()> { + let res = unsafe { libc::seteuid(euid.into()) }; +@@ -1370,7 +1451,7 @@ pub fn seteuid(euid: Uid) -> Result<()> { + + /// Set the effective group ID + /// +-/// See also [setegid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setegid.html) ++/// See also [setegid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setegid.html) + #[inline] + pub fn setegid(egid: Gid) -> Result<()> { + let res = unsafe { libc::setegid(egid.into()) }; +@@ -1380,7 +1461,7 @@ pub fn setegid(egid: Gid) -> Result<()> { + + /// Set the user ID + /// +-/// See also [setuid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setuid.html) ++/// See also [setuid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setuid.html) + #[inline] + pub fn setuid(uid: Uid) -> Result<()> { + let res = unsafe { libc::setuid(uid.into()) }; +@@ -1390,17 +1471,46 @@ pub fn setuid(uid: Uid) -> Result<()> { + + /// Set the group ID + /// +-/// See also [setgid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setgid.html) ++/// See also [setgid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setgid.html) + #[inline] + pub fn setgid(gid: Gid) -> Result<()> { + let res = unsafe { libc::setgid(gid.into()) }; + + Errno::result(res).map(drop) + } ++} ++ ++feature! { ++#![all(feature = "fs", feature = "user")] ++/// Set the user identity used for filesystem checks per-thread. ++/// On both success and failure, this call returns the previous filesystem user ++/// ID of the caller. ++/// ++/// See also [setfsuid(2)](https://man7.org/linux/man-pages/man2/setfsuid.2.html) ++#[cfg(any(target_os = "linux", target_os = "android"))] ++pub fn setfsuid(uid: Uid) -> Uid { ++ let prev_fsuid = unsafe { libc::setfsuid(uid.into()) }; ++ Uid::from_raw(prev_fsuid as uid_t) ++} ++ ++/// Set the group identity used for filesystem checks per-thread. ++/// On both success and failure, this call returns the previous filesystem group ++/// ID of the caller. ++/// ++/// See also [setfsgid(2)](https://man7.org/linux/man-pages/man2/setfsgid.2.html) ++#[cfg(any(target_os = "linux", target_os = "android"))] ++pub fn setfsgid(gid: Gid) -> Gid { ++ let prev_fsgid = unsafe { libc::setfsgid(gid.into()) }; ++ Gid::from_raw(prev_fsgid as gid_t) ++} ++} ++ ++feature! { ++#![feature = "user"] + + /// Get the list of supplementary group IDs of the calling process. + /// +-/// [Further reading](http://pubs.opengroup.org/onlinepubs/009695399/functions/getgroups.html) ++/// [Further reading](https://pubs.opengroup.org/onlinepubs/009695399/functions/getgroups.html) + /// + /// **Note:** This function is not available for Apple platforms. On those + /// platforms, checking group membership should be achieved via communication +@@ -1418,6 +1528,14 @@ pub fn getgroups() -> Result> { + // Next, get the number of groups so we can size our Vec + let ngroups = unsafe { libc::getgroups(0, ptr::null_mut()) }; + ++ // If there are no supplementary groups, return early. ++ // This prevents a potential buffer over-read if the number of groups ++ // increases from zero before the next call. It would return the total ++ // number of groups beyond the capacity of the buffer. ++ if ngroups == 0 { ++ return Ok(Vec::new()); ++ } ++ + // Now actually get the groups. We try multiple times in case the number of + // groups has changed since the first call to getgroups() and the buffer is + // now too small. +@@ -1435,11 +1553,11 @@ pub fn getgroups() -> Result> { + unsafe { groups.set_len(s as usize) }; + return Ok(groups); + }, +- Err(Error::Sys(Errno::EINVAL)) => { ++ Err(Errno::EINVAL) => { + // EINVAL indicates that the buffer size was too + // small, resize it up to ngroups_max as limit. + reserve_double_buffer_size(&mut groups, ngroups_max) +- .or(Err(Error::Sys(Errno::EINVAL)))?; ++ .or(Err(Errno::EINVAL))?; + }, + Err(e) => return Err(e) + } +@@ -1448,7 +1566,7 @@ pub fn getgroups() -> Result> { + + /// Set the list of supplementary group IDs for the calling process. + /// +-/// [Further reading](http://man7.org/linux/man-pages/man2/getgroups.2.html) ++/// [Further reading](https://man7.org/linux/man-pages/man2/getgroups.2.html) + /// + /// **Note:** This function is not available for Apple platforms. On those + /// platforms, group membership management should be achieved via communication +@@ -1465,7 +1583,7 @@ pub fn getgroups() -> Result> { + /// # use std::error::Error; + /// # use nix::unistd::*; + /// # +-/// # fn try_main() -> Result<(), Box> { ++/// # fn try_main() -> Result<(), Box> { + /// let uid = Uid::from_raw(33); + /// let gid = Gid::from_raw(34); + /// setgroups(&[gid])?; +@@ -1475,18 +1593,18 @@ pub fn getgroups() -> Result> { + /// # Ok(()) + /// # } + /// # +-/// # fn main() { +-/// # try_main().unwrap(); +-/// # } ++/// # try_main().unwrap(); + /// ``` +-#[cfg(not(any(target_os = "ios", target_os = "macos")))] ++#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox", target_os = "haiku")))] + pub fn setgroups(groups: &[Gid]) -> Result<()> { + cfg_if! { + if #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", ++ target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", ++ target_os = "illumos", + target_os = "openbsd"))] { + type setgroups_ngroups_t = c_int; + } else { +@@ -1508,7 +1626,7 @@ pub fn setgroups(groups: &[Gid]) -> Result<()> { + /// Gets the group IDs of all groups that `user` is a member of. The additional + /// group `group` is also added to the list. + /// +-/// [Further reading](http://man7.org/linux/man-pages/man3/getgrouplist.3.html) ++/// [Further reading](https://man7.org/linux/man-pages/man3/getgrouplist.3.html) + /// + /// **Note:** This function is not available for Apple platforms. On those + /// platforms, checking group membership should be achieved via communication +@@ -1523,15 +1641,17 @@ pub fn setgroups(groups: &[Gid]) -> Result<()> { + /// and `setgroups()`. Additionally, while some implementations will return a + /// partial list of groups when `NGROUPS_MAX` is exceeded, this implementation + /// will only ever return the complete list or else an error. +-#[cfg(not(any(target_os = "ios", target_os = "macos")))] ++#[cfg(not(any(target_os = "illumos", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "redox")))] + pub fn getgrouplist(user: &CStr, group: Gid) -> Result> { + let ngroups_max = match sysconf(SysconfVar::NGROUPS_MAX) { + Ok(Some(n)) => n as c_int, + Ok(None) | Err(_) => ::max_value(), + }; + use std::cmp::min; +- let mut ngroups = min(ngroups_max, 8); +- let mut groups = Vec::::with_capacity(ngroups as usize); ++ let mut groups = Vec::::with_capacity(min(ngroups_max, 8) as usize); + cfg_if! { + if #[cfg(any(target_os = "ios", target_os = "macos"))] { + type getgrouplist_group_t = c_int; +@@ -1541,6 +1661,7 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result> { + } + let gid: gid_t = group.into(); + loop { ++ let mut ngroups = groups.capacity() as i32; + let ret = unsafe { + libc::getgrouplist(user.as_ptr(), + gid as getgrouplist_group_t, +@@ -1558,7 +1679,7 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result> { + // groups as possible, but Linux manpages do not mention this + // behavior. + reserve_double_buffer_size(&mut groups, ngroups_max as usize) +- .or_else(|_| Err(Error::invalid_argument()))?; ++ .map_err(|_| Errno::EINVAL)?; + } + } + } +@@ -1569,7 +1690,7 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result> { + /// that `user` is a member of. The additional group `group` is also added to + /// the list. + /// +-/// [Further reading](http://man7.org/linux/man-pages/man3/initgroups.3.html) ++/// [Further reading](https://man7.org/linux/man-pages/man3/initgroups.3.html) + /// + /// **Note:** This function is not available for Apple platforms. On those + /// platforms, group membership management should be achieved via communication +@@ -1588,7 +1709,7 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result> { + /// # use std::ffi::CString; + /// # use nix::unistd::*; + /// # +-/// # fn try_main() -> Result<(), Box> { ++/// # fn try_main() -> Result<(), Box> { + /// let user = CString::new("www-data").unwrap(); + /// let uid = Uid::from_raw(33); + /// let gid = Gid::from_raw(33); +@@ -1599,11 +1720,9 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result> { + /// # Ok(()) + /// # } + /// # +-/// # fn main() { +-/// # try_main().unwrap(); +-/// # } ++/// # try_main().unwrap(); + /// ``` +-#[cfg(not(any(target_os = "ios", target_os = "macos")))] ++#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox", target_os = "haiku")))] + pub fn initgroups(user: &CStr, group: Gid) -> Result<()> { + cfg_if! { + if #[cfg(any(target_os = "ios", target_os = "macos"))] { +@@ -1617,11 +1736,16 @@ pub fn initgroups(user: &CStr, group: Gid) -> Result<()> { + + Errno::result(res).map(drop) + } ++} ++ ++feature! { ++#![feature = "signal"] + + /// Suspend the thread until a signal is received. + /// +-/// See also [pause(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pause.html). ++/// See also [pause(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pause.html). + #[inline] ++#[cfg(not(target_os = "redox"))] + pub fn pause() { + unsafe { libc::pause() }; + } +@@ -1652,7 +1776,8 @@ pub mod alarm { + //! + //! Scheduling an alarm and waiting for the signal: + //! +- //! ``` ++#![cfg_attr(target_os = "redox", doc = " ```rust,ignore")] ++#![cfg_attr(not(target_os = "redox"), doc = " ```rust")] + //! use std::time::{Duration, Instant}; + //! + //! use nix::unistd::{alarm, pause}; +@@ -1661,23 +1786,31 @@ pub mod alarm { + //! // We need to setup an empty signal handler to catch the alarm signal, + //! // otherwise the program will be terminated once the signal is delivered. + //! extern fn signal_handler(_: nix::libc::c_int) { } +- //! unsafe { sigaction(Signal::SIGALRM, &SigAction::new(SigHandler::Handler(signal_handler), SaFlags::empty(), SigSet::empty())); } ++ //! let sa = SigAction::new( ++ //! SigHandler::Handler(signal_handler), ++ //! SaFlags::SA_RESTART, ++ //! SigSet::empty() ++ //! ); ++ //! unsafe { ++ //! sigaction(Signal::SIGALRM, &sa); ++ //! } ++ //! ++ //! let start = Instant::now(); + //! + //! // Set an alarm for 1 second from now. + //! alarm::set(1); + //! +- //! let start = Instant::now(); + //! // Pause the process until the alarm signal is received. +- //! pause(); ++ //! let mut sigset = SigSet::empty(); ++ //! sigset.add(Signal::SIGALRM); ++ //! sigset.wait(); + //! + //! assert!(start.elapsed() >= Duration::from_secs(1)); + //! ``` + //! + //! # References + //! +- //! See also [alarm(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/alarm.html). +- +- use libc; ++ //! See also [alarm(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/alarm.html). + + /// Schedule an alarm signal. + /// +@@ -1704,20 +1837,24 @@ pub mod alarm { + } + } + } ++} + + /// Suspend execution for an interval of time + /// +-/// See also [sleep(2)](http://pubs.opengroup.org/onlinepubs/009695399/functions/sleep.html#tag_03_705_05) ++/// See also [sleep(2)](https://pubs.opengroup.org/onlinepubs/009695399/functions/sleep.html#tag_03_705_05) + // Per POSIX, does not fail + #[inline] + pub fn sleep(seconds: c_uint) -> c_uint { + unsafe { libc::sleep(seconds) } + } + ++feature! { ++#![feature = "acct"] ++ ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] + pub mod acct { +- use libc; +- use {Result, NixPath}; +- use errno::Errno; ++ use crate::{Result, NixPath}; ++ use crate::errno::Errno; + use std::ptr; + + /// Enable process accounting +@@ -1738,7 +1875,10 @@ pub mod acct { + Errno::result(res).map(drop) + } + } ++} + ++feature! { ++#![feature = "fs"] + /// Creates a regular file which persists even after process termination + /// + /// * `template`: a path whose 6 rightmost characters must be X, e.g. `/tmp/tmpfile_XXXXXX` +@@ -1747,7 +1887,7 @@ pub mod acct { + /// Err is returned either if no temporary filename could be created or the template doesn't + /// end with XXXXXX + /// +-/// See also [mkstemp(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mkstemp.html) ++/// See also [mkstemp(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkstemp.html) + /// + /// # Example + /// +@@ -1774,11 +1914,15 @@ pub fn mkstemp(template: &P) -> Result<(RawFd, PathBuf)> { + Errno::result(fd)?; + Ok((fd, PathBuf::from(pathname))) + } ++} ++ ++feature! { ++#![all(feature = "fs", feature = "feature")] + + /// Variable names for `pathconf` + /// + /// Nix uses the same naming convention for these variables as the +-/// [getconf(1)](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getconf.html) utility. ++/// [getconf(1)](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/getconf.html) utility. + /// That is, `PathconfVar` variables have the same name as the abstract + /// variables shown in the `pathconf(2)` man page. Usually, it's the same as + /// the C variable name without the leading `_PC_`. +@@ -1788,16 +1932,18 @@ pub fn mkstemp(template: &P) -> Result<(RawFd, PathBuf)> { + /// + /// # References + /// +-/// - [pathconf(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html) +-/// - [limits.h](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html) +-/// - [unistd.h](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html) ++/// - [pathconf(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html) ++/// - [limits.h](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html) ++/// - [unistd.h](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html) + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] + #[repr(i32)] ++#[non_exhaustive] + pub enum PathconfVar { + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "linux", +- target_os = "netbsd", target_os = "openbsd"))] ++ target_os = "netbsd", target_os = "openbsd", target_os = "redox"))] + /// Minimum number of bits needed to represent, as a signed integer value, + /// the maximum size of a regular file allowed in the specified directory. ++ #[cfg_attr(docsrs, doc(cfg(all())))] + FILESIZEBITS = libc::_PC_FILESIZEBITS, + /// Maximum number of links to a single file. + LINK_MAX = libc::_PC_LINK_MAX, +@@ -1818,34 +1964,43 @@ pub enum PathconfVar { + /// Maximum number of bytes that is guaranteed to be atomic when writing to + /// a pipe. + PIPE_BUF = libc::_PC_PIPE_BUF, +- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "linux", +- target_os = "netbsd", target_os = "openbsd"))] ++ #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "illumos", ++ target_os = "linux", target_os = "netbsd", target_os = "openbsd", ++ target_os = "redox", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// Symbolic links can be created. + POSIX2_SYMLINKS = libc::_PC_2_SYMLINKS, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", +- target_os = "linux", target_os = "openbsd"))] ++ target_os = "linux", target_os = "openbsd", target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// Minimum number of bytes of storage actually allocated for any portion of + /// a file. + POSIX_ALLOC_SIZE_MIN = libc::_PC_ALLOC_SIZE_MIN, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", + target_os = "linux", target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// Recommended increment for file transfer sizes between the + /// `POSIX_REC_MIN_XFER_SIZE` and `POSIX_REC_MAX_XFER_SIZE` values. + POSIX_REC_INCR_XFER_SIZE = libc::_PC_REC_INCR_XFER_SIZE, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", +- target_os = "linux", target_os = "openbsd"))] ++ target_os = "linux", target_os = "openbsd", target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// Maximum recommended file transfer size. + POSIX_REC_MAX_XFER_SIZE = libc::_PC_REC_MAX_XFER_SIZE, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", +- target_os = "linux", target_os = "openbsd"))] ++ target_os = "linux", target_os = "openbsd", target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// Minimum recommended file transfer size. + POSIX_REC_MIN_XFER_SIZE = libc::_PC_REC_MIN_XFER_SIZE, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", +- target_os = "linux", target_os = "openbsd"))] ++ target_os = "linux", target_os = "openbsd", target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// Recommended file transfer buffer alignment. + POSIX_REC_XFER_ALIGN = libc::_PC_REC_XFER_ALIGN, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", +- target_os = "linux", target_os = "netbsd", target_os = "openbsd"))] ++ target_os = "illumos", target_os = "linux", target_os = "netbsd", ++ target_os = "openbsd", target_os = "redox", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// Maximum number of bytes in a symbolic link. + SYMLINK_MAX = libc::_PC_SYMLINK_MAX, + /// The use of `chown` and `fchown` is restricted to a process with +@@ -1859,27 +2014,34 @@ pub enum PathconfVar { + /// disable terminal special character handling. + _POSIX_VDISABLE = libc::_PC_VDISABLE, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", +- target_os = "linux", target_os = "openbsd"))] ++ target_os = "illumos", target_os = "linux", target_os = "openbsd", ++ target_os = "redox", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// Asynchronous input or output operations may be performed for the + /// associated file. + _POSIX_ASYNC_IO = libc::_PC_ASYNC_IO, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", +- target_os = "linux", target_os = "openbsd"))] ++ target_os = "illumos", target_os = "linux", target_os = "openbsd", ++ target_os = "redox", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// Prioritized input or output operations may be performed for the + /// associated file. + _POSIX_PRIO_IO = libc::_PC_PRIO_IO, + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", +- target_os = "linux", target_os = "netbsd", target_os = "openbsd"))] ++ target_os = "illumos", target_os = "linux", target_os = "netbsd", ++ target_os = "openbsd", target_os = "redox", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// Synchronized input or output operations may be performed for the + /// associated file. + _POSIX_SYNC_IO = libc::_PC_SYNC_IO, + #[cfg(any(target_os = "dragonfly", target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The resolution in nanoseconds for all file timestamps. + _POSIX_TIMESTAMP_RESOLUTION = libc::_PC_TIMESTAMP_RESOLUTION + } + + /// Like `pathconf`, but works with file descriptors instead of paths (see +-/// [fpathconf(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html)) ++/// [fpathconf(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html)) + /// + /// # Parameters + /// +@@ -1903,7 +2065,7 @@ pub fn fpathconf(fd: RawFd, var: PathconfVar) -> Result> { + if errno::errno() == 0 { + Ok(None) + } else { +- Err(Error::Sys(Errno::last())) ++ Err(Errno::last()) + } + } else { + Ok(Some(raw)) +@@ -1911,12 +2073,12 @@ pub fn fpathconf(fd: RawFd, var: PathconfVar) -> Result> { + } + + /// Get path-dependent configurable system variables (see +-/// [pathconf(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html)) ++/// [pathconf(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html)) + /// + /// Returns the value of a path-dependent configurable system variable. Most + /// supported variables also have associated compile-time constants, but POSIX + /// allows their values to change at runtime. There are generally two types of +-/// `pathconf` variables: options and limits. See [pathconf(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html) for more details. ++/// `pathconf` variables: options and limits. See [pathconf(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html) for more details. + /// + /// # Parameters + /// +@@ -1942,17 +2104,21 @@ pub fn pathconf(path: &P, var: PathconfVar) -> Result(path: &P, var: PathconfVar) -> Result. ++ /// trailing newline. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + LINE_MAX = libc::_SC_LINE_MAX, + /// Maximum length of a login name. ++ #[cfg(not(target_os = "haiku"))] + LOGIN_NAME_MAX = libc::_SC_LOGIN_NAME_MAX, + /// Maximum number of simultaneous supplementary group IDs per process. + NGROUPS_MAX = libc::_SC_NGROUPS_MAX, + /// Initial size of `getgrgid_r` and `getgrnam_r` data buffers ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + GETGR_R_SIZE_MAX = libc::_SC_GETGR_R_SIZE_MAX, + /// Initial size of `getpwuid_r` and `getpwnam_r` data buffers ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + GETPW_R_SIZE_MAX = libc::_SC_GETPW_R_SIZE_MAX, + /// The maximum number of open message queue descriptors a process may hold. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MQ_OPEN_MAX = libc::_SC_MQ_OPEN_MAX, + /// The maximum number of message priorities supported by the implementation. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + MQ_PRIO_MAX = libc::_SC_MQ_PRIO_MAX, + /// A value one greater than the maximum value that the system may assign to + /// a newly-created file descriptor. + OPEN_MAX = libc::_SC_OPEN_MAX, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Advisory Information option. + _POSIX_ADVISORY_INFO = libc::_SC_ADVISORY_INFO, +- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", +- target_os="linux", target_os = "macos", target_os="netbsd", +- target_os="openbsd"))] ++ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", ++ target_os = "ios", target_os="linux", target_os = "macos", ++ target_os="netbsd", target_os="openbsd", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports barriers. + _POSIX_BARRIERS = libc::_SC_BARRIERS, + /// The implementation supports asynchronous input and output. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_ASYNCHRONOUS_IO = libc::_SC_ASYNCHRONOUS_IO, +- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", +- target_os="linux", target_os = "macos", target_os="netbsd", +- target_os="openbsd"))] ++ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", ++ target_os = "ios", target_os="linux", target_os = "macos", ++ target_os="netbsd", target_os="openbsd", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports clock selection. + _POSIX_CLOCK_SELECTION = libc::_SC_CLOCK_SELECTION, +- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", +- target_os="linux", target_os = "macos", target_os="netbsd", +- target_os="openbsd"))] ++ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", ++ target_os = "ios", target_os="linux", target_os = "macos", ++ target_os="netbsd", target_os="openbsd", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Process CPU-Time Clocks option. + _POSIX_CPUTIME = libc::_SC_CPUTIME, + /// The implementation supports the File Synchronization option. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_FSYNC = libc::_SC_FSYNC, +- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", +- target_os="linux", target_os = "macos", target_os="openbsd"))] ++ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", ++ target_os = "ios", target_os="linux", target_os = "macos", ++ target_os="openbsd", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the IPv6 option. + _POSIX_IPV6 = libc::_SC_IPV6, + /// The implementation supports job control. ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_JOB_CONTROL = libc::_SC_JOB_CONTROL, + /// The implementation supports memory mapped Files. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_MAPPED_FILES = libc::_SC_MAPPED_FILES, + /// The implementation supports the Process Memory Locking option. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_MEMLOCK = libc::_SC_MEMLOCK, + /// The implementation supports the Range Memory Locking option. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_MEMLOCK_RANGE = libc::_SC_MEMLOCK_RANGE, + /// The implementation supports memory protection. ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_MEMORY_PROTECTION = libc::_SC_MEMORY_PROTECTION, + /// The implementation supports the Message Passing option. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_MESSAGE_PASSING = libc::_SC_MESSAGE_PASSING, + /// The implementation supports the Monotonic Clock option. ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_MONOTONIC_CLOCK = libc::_SC_MONOTONIC_CLOCK, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", +- target_os = "ios", target_os="linux", target_os = "macos", +- target_os="openbsd"))] ++ target_os = "illumos", target_os = "ios", target_os="linux", ++ target_os = "macos", target_os="openbsd", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Prioritized Input and Output option. + _POSIX_PRIORITIZED_IO = libc::_SC_PRIORITIZED_IO, + /// The implementation supports the Process Scheduling option. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_PRIORITY_SCHEDULING = libc::_SC_PRIORITY_SCHEDULING, +- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", +- target_os="linux", target_os = "macos", target_os="openbsd"))] ++ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", ++ target_os = "ios", target_os="linux", target_os = "macos", ++ target_os="openbsd", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Raw Sockets option. + _POSIX_RAW_SOCKETS = libc::_SC_RAW_SOCKETS, +- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", +- target_os="linux", target_os = "macos", target_os="netbsd", +- target_os="openbsd"))] ++ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", ++ target_os = "ios", target_os="linux", target_os = "macos", ++ target_os="netbsd", target_os="openbsd", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports read-write locks. + _POSIX_READER_WRITER_LOCKS = libc::_SC_READER_WRITER_LOCKS, + #[cfg(any(target_os = "android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports realtime signals. + _POSIX_REALTIME_SIGNALS = libc::_SC_REALTIME_SIGNALS, +- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", +- target_os="linux", target_os = "macos", target_os="netbsd", +- target_os="openbsd"))] ++ #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", ++ target_os = "ios", target_os="linux", target_os = "macos", ++ target_os="netbsd", target_os="openbsd", target_os = "solaris"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Regular Expression Handling option. + _POSIX_REGEXP = libc::_SC_REGEXP, + /// Each process has a saved set-user-ID and a saved set-group-ID. ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_SAVED_IDS = libc::_SC_SAVED_IDS, + /// The implementation supports semaphores. ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_SEMAPHORES = libc::_SC_SEMAPHORES, + /// The implementation supports the Shared Memory Objects option. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_SHARED_MEMORY_OBJECTS = libc::_SC_SHARED_MEMORY_OBJECTS, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the POSIX shell. + _POSIX_SHELL = libc::_SC_SHELL, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Spawn option. + _POSIX_SPAWN = libc::_SC_SPAWN, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports spin locks. + _POSIX_SPIN_LOCKS = libc::_SC_SPIN_LOCKS, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Process Sporadic Server option. + _POSIX_SPORADIC_SERVER = libc::_SC_SPORADIC_SERVER, + #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_SS_REPL_MAX = libc::_SC_SS_REPL_MAX, + /// The implementation supports the Synchronized Input and Output option. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_SYNCHRONIZED_IO = libc::_SC_SYNCHRONIZED_IO, + /// The implementation supports the Thread Stack Address Attribute option. ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_THREAD_ATTR_STACKADDR = libc::_SC_THREAD_ATTR_STACKADDR, + /// The implementation supports the Thread Stack Size Attribute option. ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_THREAD_ATTR_STACKSIZE = libc::_SC_THREAD_ATTR_STACKSIZE, + #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos", + target_os="netbsd", target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Thread CPU-Time Clocks option. + _POSIX_THREAD_CPUTIME = libc::_SC_THREAD_CPUTIME, + /// The implementation supports the Non-Robust Mutex Priority Inheritance + /// option. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_THREAD_PRIO_INHERIT = libc::_SC_THREAD_PRIO_INHERIT, + /// The implementation supports the Non-Robust Mutex Priority Protection option. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_THREAD_PRIO_PROTECT = libc::_SC_THREAD_PRIO_PROTECT, + /// The implementation supports the Thread Execution Scheduling option. ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_THREAD_PRIORITY_SCHEDULING = libc::_SC_THREAD_PRIORITY_SCHEDULING, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Thread Process-Shared Synchronization + /// option. + _POSIX_THREAD_PROCESS_SHARED = libc::_SC_THREAD_PROCESS_SHARED, + #[cfg(any(target_os="dragonfly", target_os="linux", target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Robust Mutex Priority Inheritance option. + _POSIX_THREAD_ROBUST_PRIO_INHERIT = libc::_SC_THREAD_ROBUST_PRIO_INHERIT, + #[cfg(any(target_os="dragonfly", target_os="linux", target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Robust Mutex Priority Protection option. + _POSIX_THREAD_ROBUST_PRIO_PROTECT = libc::_SC_THREAD_ROBUST_PRIO_PROTECT, + /// The implementation supports thread-safe functions. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_THREAD_SAFE_FUNCTIONS = libc::_SC_THREAD_SAFE_FUNCTIONS, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Thread Sporadic Server option. + _POSIX_THREAD_SPORADIC_SERVER = libc::_SC_THREAD_SPORADIC_SERVER, + /// The implementation supports threads. ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_THREADS = libc::_SC_THREADS, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports timeouts. + _POSIX_TIMEOUTS = libc::_SC_TIMEOUTS, + /// The implementation supports timers. ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_TIMERS = libc::_SC_TIMERS, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Trace option. + _POSIX_TRACE = libc::_SC_TRACE, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Trace Event Filter option. + _POSIX_TRACE_EVENT_FILTER = libc::_SC_TRACE_EVENT_FILTER, + #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_TRACE_EVENT_NAME_MAX = libc::_SC_TRACE_EVENT_NAME_MAX, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Trace Inherit option. + _POSIX_TRACE_INHERIT = libc::_SC_TRACE_INHERIT, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Trace Log option. + _POSIX_TRACE_LOG = libc::_SC_TRACE_LOG, + #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_TRACE_NAME_MAX = libc::_SC_TRACE_NAME_MAX, + #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_TRACE_SYS_MAX = libc::_SC_TRACE_SYS_MAX, + #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX_TRACE_USER_EVENT_MAX = libc::_SC_TRACE_USER_EVENT_MAX, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Typed Memory Objects option. + _POSIX_TYPED_MEMORY_OBJECTS = libc::_SC_TYPED_MEMORY_OBJECTS, + /// Integer value indicating version of this standard (C-language binding) +@@ -2210,12 +2488,14 @@ pub enum SysconfVar { + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation provides a C-language compilation environment with + /// 32-bit `int`, `long`, `pointer`, and `off_t` types. + _POSIX_V6_ILP32_OFF32 = libc::_SC_V6_ILP32_OFF32, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation provides a C-language compilation environment with + /// 32-bit `int`, `long`, and pointer types and an `off_t` type using at + /// least 64 bits. +@@ -2223,145 +2503,211 @@ pub enum SysconfVar { + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation provides a C-language compilation environment with + /// 32-bit `int` and 64-bit `long`, `pointer`, and `off_t` types. + _POSIX_V6_LP64_OFF64 = libc::_SC_V6_LP64_OFF64, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation provides a C-language compilation environment with an + /// `int` type using at least 32 bits and `long`, pointer, and `off_t` types + /// using at least 64 bits. + _POSIX_V6_LPBIG_OFFBIG = libc::_SC_V6_LPBIG_OFFBIG, + /// The implementation supports the C-Language Binding option. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_C_BIND = libc::_SC_2_C_BIND, + /// The implementation supports the C-Language Development Utilities option. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_C_DEV = libc::_SC_2_C_DEV, + /// The implementation supports the Terminal Characteristics option. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_CHAR_TERM = libc::_SC_2_CHAR_TERM, + /// The implementation supports the FORTRAN Development Utilities option. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_FORT_DEV = libc::_SC_2_FORT_DEV, + /// The implementation supports the FORTRAN Runtime Utilities option. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_FORT_RUN = libc::_SC_2_FORT_RUN, + /// The implementation supports the creation of locales by the localedef + /// utility. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_LOCALEDEF = libc::_SC_2_LOCALEDEF, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Batch Environment Services and Utilities + /// option. + _POSIX2_PBS = libc::_SC_2_PBS, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Batch Accounting option. + _POSIX2_PBS_ACCOUNTING = libc::_SC_2_PBS_ACCOUNTING, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Batch Checkpoint/Restart option. + _POSIX2_PBS_CHECKPOINT = libc::_SC_2_PBS_CHECKPOINT, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Locate Batch Job Request option. + _POSIX2_PBS_LOCATE = libc::_SC_2_PBS_LOCATE, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Batch Job Message Request option. + _POSIX2_PBS_MESSAGE = libc::_SC_2_PBS_MESSAGE, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Track Batch Job Request option. + _POSIX2_PBS_TRACK = libc::_SC_2_PBS_TRACK, + /// The implementation supports the Software Development Utilities option. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_SW_DEV = libc::_SC_2_SW_DEV, + /// The implementation supports the User Portability Utilities option. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_UPE = libc::_SC_2_UPE, + /// Integer value indicating version of the Shell and Utilities volume of + /// POSIX.1 to which the implementation conforms. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _POSIX2_VERSION = libc::_SC_2_VERSION, + /// The size of a system page in bytes. + /// + /// POSIX also defines an alias named `PAGESIZE`, but Rust does not allow two + /// enum constants to have the same value, so nix omits `PAGESIZE`. + PAGE_SIZE = libc::_SC_PAGE_SIZE, ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + PTHREAD_DESTRUCTOR_ITERATIONS = libc::_SC_THREAD_DESTRUCTOR_ITERATIONS, ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + PTHREAD_KEYS_MAX = libc::_SC_THREAD_KEYS_MAX, ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + PTHREAD_STACK_MIN = libc::_SC_THREAD_STACK_MIN, ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + PTHREAD_THREADS_MAX = libc::_SC_THREAD_THREADS_MAX, ++ #[cfg(not(target_os = "haiku"))] + RE_DUP_MAX = libc::_SC_RE_DUP_MAX, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + RTSIG_MAX = libc::_SC_RTSIG_MAX, ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + SEM_NSEMS_MAX = libc::_SC_SEM_NSEMS_MAX, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + SEM_VALUE_MAX = libc::_SC_SEM_VALUE_MAX, + #[cfg(any(target_os = "android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os = "openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + SIGQUEUE_MAX = libc::_SC_SIGQUEUE_MAX, + STREAM_MAX = libc::_SC_STREAM_MAX, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="netbsd", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + SYMLOOP_MAX = libc::_SC_SYMLOOP_MAX, ++ #[cfg(not(target_os = "redox"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + TIMER_MAX = libc::_SC_TIMER_MAX, + TTY_NAME_MAX = libc::_SC_TTY_NAME_MAX, + TZNAME_MAX = libc::_SC_TZNAME_MAX, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the X/Open Encryption Option Group. + _XOPEN_CRYPT = libc::_SC_XOPEN_CRYPT, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the Issue 4, Version 2 Enhanced + /// Internationalization Option Group. + _XOPEN_ENH_I18N = libc::_SC_XOPEN_ENH_I18N, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _XOPEN_LEGACY = libc::_SC_XOPEN_LEGACY, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the X/Open Realtime Option Group. + _XOPEN_REALTIME = libc::_SC_XOPEN_REALTIME, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the X/Open Realtime Threads Option Group. + _XOPEN_REALTIME_THREADS = libc::_SC_XOPEN_REALTIME_THREADS, + /// The implementation supports the Issue 4, Version 2 Shared Memory Option + /// Group. ++ #[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + _XOPEN_SHM = libc::_SC_XOPEN_SHM, + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", + target_os="linux", target_os = "macos", target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the XSI STREAMS Option Group. + _XOPEN_STREAMS = libc::_SC_XOPEN_STREAMS, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// The implementation supports the XSI option + _XOPEN_UNIX = libc::_SC_XOPEN_UNIX, + #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd"))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + /// Integer value indicating version of the X/Open Portability Guide to + /// which the implementation conforms. + _XOPEN_VERSION = libc::_SC_XOPEN_VERSION, ++ /// The number of pages of physical memory. Note that it is possible for ++ /// the product of this value to overflow. ++ #[cfg(any(target_os="android", target_os="linux"))] ++ _PHYS_PAGES = libc::_SC_PHYS_PAGES, ++ /// The number of currently available pages of physical memory. ++ #[cfg(any(target_os="android", target_os="linux"))] ++ _AVPHYS_PAGES = libc::_SC_AVPHYS_PAGES, ++ /// The number of processors configured. ++ #[cfg(any(target_os="android", target_os="linux"))] ++ _NPROCESSORS_CONF = libc::_SC_NPROCESSORS_CONF, ++ /// The number of processors currently online (available). ++ #[cfg(any(target_os="android", target_os="linux"))] ++ _NPROCESSORS_ONLN = libc::_SC_NPROCESSORS_ONLN, + } + + /// Get configurable system variables (see +-/// [sysconf(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html)) ++/// [sysconf(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html)) + /// + /// Returns the value of a configurable system variable. Most supported + /// variables also have associated compile-time constants, but POSIX +@@ -2385,18 +2731,21 @@ pub fn sysconf(var: SysconfVar) -> Result> { + if errno::errno() == 0 { + Ok(None) + } else { +- Err(Error::Sys(Errno::last())) ++ Err(Errno::last()) + } + } else { + Ok(Some(raw)) + } + } ++} ++ ++feature! { ++#![feature = "fs"] + + #[cfg(any(target_os = "android", target_os = "linux"))] + mod pivot_root { +- use libc; +- use {Result, NixPath}; +- use errno::Errno; ++ use crate::{Result, NixPath}; ++ use crate::errno::Errno; + + pub fn pivot_root( + new_root: &P1, put_old: &P2) -> Result<()> { +@@ -2411,17 +2760,25 @@ mod pivot_root { + Errno::result(res).map(drop) + } + } ++} + +-#[cfg(any(target_os = "android", target_os = "freebsd", +- target_os = "linux", target_os = "openbsd"))] ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "linux", ++ target_os = "openbsd" ++))] + mod setres { +- use libc; +- use Result; +- use errno::Errno; ++ feature! { ++ #![feature = "user"] ++ ++ use crate::Result; ++ use crate::errno::Errno; + use super::{Uid, Gid}; + + /// Sets the real, effective, and saved uid. +- /// ([see setresuid(2)](http://man7.org/linux/man-pages/man2/setresuid.2.html)) ++ /// ([see setresuid(2)](https://man7.org/linux/man-pages/man2/setresuid.2.html)) + /// + /// * `ruid`: real user id + /// * `euid`: effective user id +@@ -2437,7 +2794,7 @@ mod setres { + } + + /// Sets the real, effective, and saved gid. +- /// ([see setresuid(2)](http://man7.org/linux/man-pages/man2/setresuid.2.html)) ++ /// ([see setresuid(2)](https://man7.org/linux/man-pages/man2/setresuid.2.html)) + /// + /// * `rgid`: real group id + /// * `egid`: effective group id +@@ -2451,10 +2808,84 @@ mod setres { + + Errno::result(res).map(drop) + } ++ } + } + +-libc_bitflags!{ ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "linux", ++ target_os = "openbsd" ++))] ++mod getres { ++ feature! { ++ #![feature = "user"] ++ ++ use crate::Result; ++ use crate::errno::Errno; ++ use super::{Uid, Gid}; ++ ++ /// Real, effective and saved user IDs. ++ #[derive(Debug, Copy, Clone, Eq, PartialEq)] ++ pub struct ResUid { ++ pub real: Uid, ++ pub effective: Uid, ++ pub saved: Uid ++ } ++ ++ /// Real, effective and saved group IDs. ++ #[derive(Debug, Copy, Clone, Eq, PartialEq)] ++ pub struct ResGid { ++ pub real: Gid, ++ pub effective: Gid, ++ pub saved: Gid ++ } ++ ++ /// Gets the real, effective, and saved user IDs. ++ /// ++ /// ([see getresuid(2)](http://man7.org/linux/man-pages/man2/getresuid.2.html)) ++ /// ++ /// #Returns ++ /// ++ /// - `Ok((Uid, Uid, Uid))`: tuple of real, effective and saved uids on success. ++ /// - `Err(x)`: libc error code on failure. ++ /// ++ #[inline] ++ pub fn getresuid() -> Result { ++ let mut ruid = libc::uid_t::max_value(); ++ let mut euid = libc::uid_t::max_value(); ++ let mut suid = libc::uid_t::max_value(); ++ let res = unsafe { libc::getresuid(&mut ruid, &mut euid, &mut suid) }; ++ ++ Errno::result(res).map(|_| ResUid{ real: Uid(ruid), effective: Uid(euid), saved: Uid(suid) }) ++ } ++ ++ /// Gets the real, effective, and saved group IDs. ++ /// ++ /// ([see getresgid(2)](http://man7.org/linux/man-pages/man2/getresgid.2.html)) ++ /// ++ /// #Returns ++ /// ++ /// - `Ok((Gid, Gid, Gid))`: tuple of real, effective and saved gids on success. ++ /// - `Err(x)`: libc error code on failure. ++ /// ++ #[inline] ++ pub fn getresgid() -> Result { ++ let mut rgid = libc::gid_t::max_value(); ++ let mut egid = libc::gid_t::max_value(); ++ let mut sgid = libc::gid_t::max_value(); ++ let res = unsafe { libc::getresgid(&mut rgid, &mut egid, &mut sgid) }; ++ ++ Errno::result(res).map(|_| ResGid { real: Gid(rgid), effective: Gid(egid), saved: Gid(sgid) } ) ++ } ++ } ++} ++ ++#[cfg(feature = "fs")] ++libc_bitflags! { + /// Options for access() ++ #[cfg_attr(docsrs, doc(cfg(feature = "fs")))] + pub struct AccessFlags : c_int { + /// Test for existence of file. + F_OK; +@@ -2467,8 +2898,11 @@ libc_bitflags!{ + } + } + ++feature! { ++#![feature = "fs"] ++ + /// Checks the file named by `path` for accessibility according to the flags given by `amode` +-/// See [access(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html) ++/// See [access(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html) + pub fn access(path: &P, amode: AccessFlags) -> Result<()> { + let res = path.with_nix_path(|cstr| { + unsafe { +@@ -2478,75 +2912,211 @@ pub fn access(path: &P, amode: AccessFlags) -> Result<()> { + Errno::result(res).map(drop) + } + ++/// Checks the file named by `path` for accessibility according to the flags given by `mode` ++/// ++/// If `dirfd` has a value, then `path` is relative to directory associated with the file descriptor. ++/// ++/// If `dirfd` is `None`, then `path` is relative to the current working directory. ++/// ++/// # References ++/// ++/// [faccessat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/faccessat.html) ++// redox: does not appear to support the *at family of syscalls. ++#[cfg(not(target_os = "redox"))] ++pub fn faccessat(dirfd: Option, path: &P, mode: AccessFlags, flags: AtFlags) -> Result<()> { ++ let res = path.with_nix_path(|cstr| { ++ unsafe { ++ libc::faccessat(at_rawfd(dirfd), cstr.as_ptr(), mode.bits(), flags.bits()) ++ } ++ })?; ++ Errno::result(res).map(drop) ++} ++ ++/// Checks the file named by `path` for accessibility according to the flags given ++/// by `mode` using effective UID, effective GID and supplementary group lists. ++/// ++/// # References ++/// ++/// * [FreeBSD man page](https://www.freebsd.org/cgi/man.cgi?query=eaccess&sektion=2&n=1) ++/// * [Linux man page](https://man7.org/linux/man-pages/man3/euidaccess.3.html) ++#[cfg(any( ++ all(target_os = "linux", not(target_env = "uclibc")), ++ target_os = "freebsd", ++ target_os = "dragonfly" ++))] ++pub fn eaccess(path: &P, mode: AccessFlags) -> Result<()> { ++ let res = path.with_nix_path(|cstr| { ++ unsafe { ++ libc::eaccess(cstr.as_ptr(), mode.bits) ++ } ++ })?; ++ Errno::result(res).map(drop) ++} ++} ++ ++feature! { ++#![feature = "user"] ++ + /// Representation of a User, based on `libc::passwd` + /// + /// The reason some fields in this struct are `String` and others are `CString` is because some + /// fields are based on the user's locale, which could be non-UTF8, while other fields are + /// guaranteed to conform to [`NAME_REGEX`](https://serverfault.com/a/73101/407341), which only + /// contains ASCII. +-#[derive(Debug, Clone, PartialEq)] ++#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd ++#[derive(Debug, Clone, Eq, PartialEq)] + pub struct User { + /// Username + pub name: String, +- /// User password (probably encrypted) ++ /// User password (probably hashed) + pub passwd: CString, + /// User ID + pub uid: Uid, + /// Group ID + pub gid: Gid, + /// User information +- #[cfg(not(target_os = "android"))] ++ #[cfg(not(all(target_os = "android", target_pointer_width = "32")))] + pub gecos: CString, + /// Home directory + pub dir: PathBuf, + /// Path to shell + pub shell: PathBuf, + /// Login class +- #[cfg(not(any(target_os = "android", target_os = "linux")))] ++ #[cfg(not(any(target_os = "android", ++ target_os = "fuchsia", ++ target_os = "haiku", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "solaris")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub class: CString, + /// Last password change +- #[cfg(not(any(target_os = "android", target_os = "linux")))] ++ #[cfg(not(any(target_os = "android", ++ target_os = "fuchsia", ++ target_os = "haiku", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "solaris")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub change: libc::time_t, + /// Expiration time of account +- #[cfg(not(any(target_os = "android", target_os = "linux")))] ++ #[cfg(not(any(target_os = "android", ++ target_os = "fuchsia", ++ target_os = "haiku", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "solaris")))] ++ #[cfg_attr(docsrs, doc(cfg(all())))] + pub expire: libc::time_t + } + ++#[cfg(not(target_os = "redox"))] //RedoxFS does not support passwd + impl From<&libc::passwd> for User { + fn from(pw: &libc::passwd) -> User { + unsafe { + User { +- name: CStr::from_ptr((*pw).pw_name).to_string_lossy().into_owned(), +- passwd: CString::new(CStr::from_ptr((*pw).pw_passwd).to_bytes()).unwrap(), +- #[cfg(not(target_os = "android"))] +- gecos: CString::new(CStr::from_ptr((*pw).pw_gecos).to_bytes()).unwrap(), +- dir: PathBuf::from(OsStr::from_bytes(CStr::from_ptr((*pw).pw_dir).to_bytes())), +- shell: PathBuf::from(OsStr::from_bytes(CStr::from_ptr((*pw).pw_shell).to_bytes())), +- uid: Uid::from_raw((*pw).pw_uid), +- gid: Gid::from_raw((*pw).pw_gid), +- #[cfg(not(any(target_os = "android", target_os = "linux")))] +- class: CString::new(CStr::from_ptr((*pw).pw_class).to_bytes()).unwrap(), +- #[cfg(not(any(target_os = "android", target_os = "linux")))] +- change: (*pw).pw_change, +- #[cfg(not(any(target_os = "android", target_os = "linux")))] +- expire: (*pw).pw_expire ++ name: if pw.pw_name.is_null() { Default::default() } else { CStr::from_ptr(pw.pw_name).to_string_lossy().into_owned() }, ++ passwd: if pw.pw_passwd.is_null() { Default::default() } else { CString::new(CStr::from_ptr(pw.pw_passwd).to_bytes()).unwrap() }, ++ #[cfg(not(all(target_os = "android", target_pointer_width = "32")))] ++ gecos: if pw.pw_gecos.is_null() { Default::default() } else { CString::new(CStr::from_ptr(pw.pw_gecos).to_bytes()).unwrap() }, ++ dir: if pw.pw_dir.is_null() { Default::default() } else { PathBuf::from(OsStr::from_bytes(CStr::from_ptr(pw.pw_dir).to_bytes())) }, ++ shell: if pw.pw_shell.is_null() { Default::default() } else { PathBuf::from(OsStr::from_bytes(CStr::from_ptr(pw.pw_shell).to_bytes())) }, ++ uid: Uid::from_raw(pw.pw_uid), ++ gid: Gid::from_raw(pw.pw_gid), ++ #[cfg(not(any(target_os = "android", ++ target_os = "fuchsia", ++ target_os = "haiku", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "solaris")))] ++ class: CString::new(CStr::from_ptr(pw.pw_class).to_bytes()).unwrap(), ++ #[cfg(not(any(target_os = "android", ++ target_os = "fuchsia", ++ target_os = "haiku", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "solaris")))] ++ change: pw.pw_change, ++ #[cfg(not(any(target_os = "android", ++ target_os = "fuchsia", ++ target_os = "haiku", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "solaris")))] ++ expire: pw.pw_expire + } + } + } + } + ++#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd ++impl From for libc::passwd { ++ fn from(u: User) -> Self { ++ let name = match CString::new(u.name) { ++ Ok(n) => n.into_raw(), ++ Err(_) => CString::new("").unwrap().into_raw(), ++ }; ++ let dir = match u.dir.into_os_string().into_string() { ++ Ok(s) => CString::new(s.as_str()).unwrap().into_raw(), ++ Err(_) => CString::new("").unwrap().into_raw(), ++ }; ++ let shell = match u.shell.into_os_string().into_string() { ++ Ok(s) => CString::new(s.as_str()).unwrap().into_raw(), ++ Err(_) => CString::new("").unwrap().into_raw(), ++ }; ++ Self { ++ pw_name: name, ++ pw_passwd: u.passwd.into_raw(), ++ #[cfg(not(all(target_os = "android", target_pointer_width = "32")))] ++ pw_gecos: u.gecos.into_raw(), ++ pw_dir: dir, ++ pw_shell: shell, ++ pw_uid: u.uid.0, ++ pw_gid: u.gid.0, ++ #[cfg(not(any(target_os = "android", ++ target_os = "fuchsia", ++ target_os = "haiku", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "solaris")))] ++ pw_class: u.class.into_raw(), ++ #[cfg(not(any(target_os = "android", ++ target_os = "fuchsia", ++ target_os = "haiku", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "solaris")))] ++ pw_change: u.change, ++ #[cfg(not(any(target_os = "android", ++ target_os = "fuchsia", ++ target_os = "haiku", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "solaris")))] ++ pw_expire: u.expire, ++ #[cfg(target_os = "illumos")] ++ pw_age: CString::new("").unwrap().into_raw(), ++ #[cfg(target_os = "illumos")] ++ pw_comment: CString::new("").unwrap().into_raw(), ++ #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] ++ pw_fields: 0, ++ } ++ } ++} ++ ++#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd + impl User { + fn from_anything(f: F) -> Result> + where + F: Fn(*mut libc::passwd, +- *mut libc::c_char, ++ *mut c_char, + libc::size_t, + *mut *mut libc::passwd) -> libc::c_int + { +- let buflimit = 16384; ++ let buflimit = 1048576; + let bufsize = match sysconf(SysconfVar::GETPW_R_SIZE_MAX) { + Ok(Some(n)) => n as usize, +- Ok(None) | Err(_) => buflimit as usize, ++ Ok(None) | Err(_) => 16384, + }; + + let mut cbuf = Vec::with_capacity(bufsize); +@@ -2566,7 +3136,7 @@ impl User { + // Trigger the internal buffer resizing logic. + reserve_double_buffer_size(&mut cbuf, buflimit)?; + } else { +- return Err(Error::Sys(Errno::last())); ++ return Err(Errno::last()); + } + } + } +@@ -2574,7 +3144,7 @@ impl User { + /// Get a user by UID. + /// + /// Internally, this function calls +- /// [getpwuid_r(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html) ++ /// [getpwuid_r(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html) + /// + /// # Examples + /// +@@ -2582,7 +3152,7 @@ impl User { + /// use nix::unistd::{Uid, User}; + /// // Returns an Result>, thus the double unwrap. + /// let res = User::from_uid(Uid::from_raw(0)).unwrap().unwrap(); +- /// assert!(res.name == "root"); ++ /// assert_eq!(res.name, "root"); + /// ``` + pub fn from_uid(uid: Uid) -> Result> { + User::from_anything(|pwd, cbuf, cap, res| { +@@ -2593,7 +3163,7 @@ impl User { + /// Get a user by name. + /// + /// Internally, this function calls +- /// [getpwnam_r(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html) ++ /// [getpwnam_r(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html) + /// + /// # Examples + /// +@@ -2601,10 +3171,13 @@ impl User { + /// use nix::unistd::User; + /// // Returns an Result>, thus the double unwrap. + /// let res = User::from_name("root").unwrap().unwrap(); +- /// assert!(res.name == "root"); ++ /// assert_eq!(res.name, "root"); + /// ``` + pub fn from_name(name: &str) -> Result> { +- let name = CString::new(name).unwrap(); ++ let name = match CString::new(name) { ++ Ok(c_str) => c_str, ++ Err(_nul_error) => return Ok(None), ++ }; + User::from_anything(|pwd, cbuf, cap, res| { + unsafe { libc::getpwnam_r(name.as_ptr(), pwd, cbuf, cap, res) } + }) +@@ -2612,28 +3185,34 @@ impl User { + } + + /// Representation of a Group, based on `libc::group` +-#[derive(Debug, Clone, PartialEq)] ++#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd ++#[derive(Debug, Clone, Eq, PartialEq)] + pub struct Group { + /// Group name + pub name: String, ++ /// Group password ++ pub passwd: CString, + /// Group ID + pub gid: Gid, + /// List of Group members + pub mem: Vec + } + ++#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd + impl From<&libc::group> for Group { + fn from(gr: &libc::group) -> Group { + unsafe { + Group { +- name: CStr::from_ptr((*gr).gr_name).to_string_lossy().into_owned(), +- gid: Gid::from_raw((*gr).gr_gid), +- mem: Group::members((*gr).gr_mem) ++ name: CStr::from_ptr(gr.gr_name).to_string_lossy().into_owned(), ++ passwd: CString::new(CStr::from_ptr(gr.gr_passwd).to_bytes()).unwrap(), ++ gid: Gid::from_raw(gr.gr_gid), ++ mem: Group::members(gr.gr_mem) + } + } + } + } + ++#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd + impl Group { + unsafe fn members(mem: *mut *mut c_char) -> Vec { + let mut ret = Vec::new(); +@@ -2654,14 +3233,14 @@ impl Group { + fn from_anything(f: F) -> Result> + where + F: Fn(*mut libc::group, +- *mut libc::c_char, ++ *mut c_char, + libc::size_t, + *mut *mut libc::group) -> libc::c_int + { +- let buflimit = 16384; ++ let buflimit = 1048576; + let bufsize = match sysconf(SysconfVar::GETGR_R_SIZE_MAX) { + Ok(Some(n)) => n as usize, +- Ok(None) | Err(_) => buflimit as usize, ++ Ok(None) | Err(_) => 16384, + }; + + let mut cbuf = Vec::with_capacity(bufsize); +@@ -2681,7 +3260,7 @@ impl Group { + // Trigger the internal buffer resizing logic. + reserve_double_buffer_size(&mut cbuf, buflimit)?; + } else { +- return Err(Error::Sys(Errno::last())); ++ return Err(Errno::last()); + } + } + } +@@ -2689,7 +3268,7 @@ impl Group { + /// Get a group by GID. + /// + /// Internally, this function calls +- /// [getgrgid_r(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html) ++ /// [getgrgid_r(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html) + /// + /// # Examples + /// +@@ -2710,7 +3289,7 @@ impl Group { + /// Get a group by name. + /// + /// Internally, this function calls +- /// [getgrnam_r(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html) ++ /// [getgrnam_r(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html) + /// + /// # Examples + /// +@@ -2723,9 +3302,82 @@ impl Group { + /// assert!(res.name == "root"); + /// ``` + pub fn from_name(name: &str) -> Result> { +- let name = CString::new(name).unwrap(); ++ let name = match CString::new(name) { ++ Ok(c_str) => c_str, ++ Err(_nul_error) => return Ok(None), ++ }; + Group::from_anything(|grp, cbuf, cap, res| { + unsafe { libc::getgrnam_r(name.as_ptr(), grp, cbuf, cap, res) } + }) + } + } ++} ++ ++feature! { ++#![feature = "term"] ++ ++/// Get the name of the terminal device that is open on file descriptor fd ++/// (see [`ttyname(3)`](https://man7.org/linux/man-pages/man3/ttyname.3.html)). ++#[cfg(not(target_os = "fuchsia"))] ++pub fn ttyname(fd: RawFd) -> Result { ++ const PATH_MAX: usize = libc::PATH_MAX as usize; ++ let mut buf = vec![0_u8; PATH_MAX]; ++ let c_buf = buf.as_mut_ptr() as *mut libc::c_char; ++ ++ let ret = unsafe { libc::ttyname_r(fd, c_buf, buf.len()) }; ++ if ret != 0 { ++ return Err(Errno::from_i32(ret)); ++ } ++ ++ let nul = buf.iter().position(|c| *c == b'\0').unwrap(); ++ buf.truncate(nul); ++ Ok(OsString::from_vec(buf).into()) ++} ++} ++ ++feature! { ++#![all(feature = "socket", feature = "user")] ++ ++/// Get the effective user ID and group ID associated with a Unix domain socket. ++/// ++/// See also [getpeereid(3)](https://www.freebsd.org/cgi/man.cgi?query=getpeereid) ++#[cfg(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "freebsd", ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "dragonfly", ++))] ++pub fn getpeereid(fd: RawFd) -> Result<(Uid, Gid)> { ++ let mut uid = 1; ++ let mut gid = 1; ++ ++ let ret = unsafe { libc::getpeereid(fd, &mut uid, &mut gid) }; ++ ++ Errno::result(ret).map(|_| (Uid(uid), Gid(gid))) ++} ++} ++ ++feature! { ++#![all(feature = "fs")] ++ ++/// Set the file flags. ++/// ++/// See also [chflags(2)](https://www.freebsd.org/cgi/man.cgi?query=chflags&sektion=2) ++#[cfg(any( ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "macos", ++ target_os = "ios" ++))] ++pub fn chflags(path: &P, flags: FileFlag) -> Result<()> { ++ let res = path.with_nix_path(|cstr| unsafe { ++ libc::chflags(cstr.as_ptr(), flags.bits()) ++ })?; ++ ++ Errno::result(res).map(drop) ++} ++} +diff --git a/vendor/nix/test/common/mod.rs b/vendor/nix/test/common/mod.rs +new file mode 100644 +index 0000000..bb056aa +--- /dev/null ++++ b/vendor/nix/test/common/mod.rs +@@ -0,0 +1,149 @@ ++use cfg_if::cfg_if; ++ ++#[macro_export] ++macro_rules! skip { ++ ($($reason: expr),+) => { ++ use ::std::io::{self, Write}; ++ ++ let stderr = io::stderr(); ++ let mut handle = stderr.lock(); ++ writeln!(handle, $($reason),+).unwrap(); ++ return; ++ } ++} ++ ++cfg_if! { ++ if #[cfg(any(target_os = "android", target_os = "linux"))] { ++ #[macro_export] macro_rules! require_capability { ++ ($name:expr, $capname:ident) => { ++ use ::caps::{Capability, CapSet, has_cap}; ++ ++ if !has_cap(None, CapSet::Effective, Capability::$capname) ++ .unwrap() ++ { ++ skip!("{} requires capability {}. Skipping test.", $name, Capability::$capname); ++ } ++ } ++ } ++ } else if #[cfg(not(target_os = "redox"))] { ++ #[macro_export] macro_rules! require_capability { ++ ($name:expr, $capname:ident) => {} ++ } ++ } ++} ++ ++/// Skip the test if we don't have the ability to mount file systems. ++#[cfg(target_os = "freebsd")] ++#[macro_export] ++macro_rules! require_mount { ++ ($name:expr) => { ++ use ::sysctl::{CtlValue, Sysctl}; ++ use nix::unistd::Uid; ++ ++ let ctl = ::sysctl::Ctl::new("vfs.usermount").unwrap(); ++ if !Uid::current().is_root() && CtlValue::Int(0) == ctl.value().unwrap() ++ { ++ skip!( ++ "{} requires the ability to mount file systems. Skipping test.", ++ $name ++ ); ++ } ++ }; ++} ++ ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[macro_export] ++macro_rules! skip_if_cirrus { ++ ($reason:expr) => { ++ if std::env::var_os("CIRRUS_CI").is_some() { ++ skip!("{}", $reason); ++ } ++ }; ++} ++ ++#[cfg(target_os = "freebsd")] ++#[macro_export] ++macro_rules! skip_if_jailed { ++ ($name:expr) => { ++ use ::sysctl::{CtlValue, Sysctl}; ++ ++ let ctl = ::sysctl::Ctl::new("security.jail.jailed").unwrap(); ++ if let CtlValue::Int(1) = ctl.value().unwrap() { ++ skip!("{} cannot run in a jail. Skipping test.", $name); ++ } ++ }; ++} ++ ++#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))] ++#[macro_export] ++macro_rules! skip_if_not_root { ++ ($name:expr) => { ++ use nix::unistd::Uid; ++ ++ if !Uid::current().is_root() { ++ skip!("{} requires root privileges. Skipping test.", $name); ++ } ++ }; ++} ++ ++cfg_if! { ++ if #[cfg(any(target_os = "android", target_os = "linux"))] { ++ #[macro_export] macro_rules! skip_if_seccomp { ++ ($name:expr) => { ++ if let Ok(s) = std::fs::read_to_string("/proc/self/status") { ++ for l in s.lines() { ++ let mut fields = l.split_whitespace(); ++ if fields.next() == Some("Seccomp:") && ++ fields.next() != Some("0") ++ { ++ skip!("{} cannot be run in Seccomp mode. Skipping test.", ++ stringify!($name)); ++ } ++ } ++ } ++ } ++ } ++ } else if #[cfg(not(target_os = "redox"))] { ++ #[macro_export] macro_rules! skip_if_seccomp { ++ ($name:expr) => {} ++ } ++ } ++} ++ ++cfg_if! { ++ if #[cfg(target_os = "linux")] { ++ #[macro_export] macro_rules! require_kernel_version { ++ ($name:expr, $version_requirement:expr) => { ++ use semver::{Version, VersionReq}; ++ ++ let version_requirement = VersionReq::parse($version_requirement) ++ .expect("Bad match_version provided"); ++ ++ let uname = nix::sys::utsname::uname().unwrap(); ++ println!("{}", uname.sysname().to_str().unwrap()); ++ println!("{}", uname.nodename().to_str().unwrap()); ++ println!("{}", uname.release().to_str().unwrap()); ++ println!("{}", uname.version().to_str().unwrap()); ++ println!("{}", uname.machine().to_str().unwrap()); ++ ++ // Fix stuff that the semver parser can't handle ++ let fixed_release = &uname.release().to_str().unwrap().to_string() ++ // Fedora 33 reports version as 4.18.el8_2.x86_64 or ++ // 5.18.200-fc33.x86_64. Remove the underscore. ++ .replace("_", "-") ++ // Cirrus-CI reports version as 4.19.112+ . Remove the + ++ .replace("+", ""); ++ let mut version = Version::parse(fixed_release).unwrap(); ++ ++ //Keep only numeric parts ++ version.pre = semver::Prerelease::EMPTY; ++ version.build = semver::BuildMetadata::EMPTY; ++ ++ if !version_requirement.matches(&version) { ++ skip!("Skip {} because kernel version `{}` doesn't match the requirement `{}`", ++ stringify!($name), version, version_requirement); ++ } ++ } ++ } ++ } ++} +diff --git a/vendor/nix/test/sys/mod.rs b/vendor/nix/test/sys/mod.rs +index 60a58dd..2031212 100644 +--- a/vendor/nix/test/sys/mod.rs ++++ b/vendor/nix/test/sys/mod.rs +@@ -5,34 +5,56 @@ mod test_signal; + // works or not heavily depends on which pthread implementation is chosen + // by the user at link time. For this reason we do not want to run aio test + // cases on DragonFly. +-#[cfg(any(target_os = "freebsd", +- target_os = "ios", +- target_os = "linux", +- target_os = "macos", +- target_os = "netbsd"))] ++#[cfg(any( ++ target_os = "freebsd", ++ target_os = "ios", ++ all(target_os = "linux", not(target_env = "uclibc")), ++ target_os = "macos", ++ target_os = "netbsd" ++))] + mod test_aio; ++#[cfg(not(any( ++ target_os = "redox", ++ target_os = "fuchsia", ++ target_os = "haiku" ++)))] ++mod test_ioctl; ++#[cfg(not(target_os = "redox"))] ++mod test_mman; ++#[cfg(not(target_os = "redox"))] ++mod test_select; + #[cfg(target_os = "linux")] + mod test_signalfd; ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] + mod test_socket; ++#[cfg(not(any(target_os = "redox")))] + mod test_sockopt; +-mod test_select; ++mod test_stat; + #[cfg(any(target_os = "android", target_os = "linux"))] + mod test_sysinfo; ++#[cfg(not(any( ++ target_os = "redox", ++ target_os = "fuchsia", ++ target_os = "haiku" ++)))] + mod test_termios; +-mod test_ioctl; +-mod test_wait; + mod test_uio; ++mod test_wait; + +-#[cfg(target_os = "linux")] ++#[cfg(any(target_os = "android", target_os = "linux"))] + mod test_epoll; + #[cfg(target_os = "linux")] + mod test_inotify; + mod test_pthread; +-#[cfg(any(target_os = "android", +- target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "linux", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "linux", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++))] + mod test_ptrace; ++#[cfg(any(target_os = "android", target_os = "linux"))] ++mod test_timerfd; +diff --git a/vendor/nix/test/sys/test_aio.rs b/vendor/nix/test/sys/test_aio.rs +index d03adc5..84086f8 100644 +--- a/vendor/nix/test/sys/test_aio.rs ++++ b/vendor/nix/test/sys/test_aio.rs +@@ -1,454 +1,516 @@ +-use bytes::{Bytes, BytesMut}; +-use libc::{c_int, c_void}; +-use nix::{Error, Result}; +-use nix::errno::*; +-use nix::sys::aio::*; +-use nix::sys::signal::{SaFlags, SigAction, sigaction, SigevNotify, SigHandler, Signal, SigSet}; +-use nix::sys::time::{TimeSpec, TimeValLike}; +-use std::io::{Write, Read, Seek, SeekFrom}; +-use std::ops::Deref; +-use std::os::unix::io::AsRawFd; +-use std::sync::atomic::{AtomicBool, Ordering}; +-use std::{thread, time}; ++use std::{ ++ io::{Read, Seek, Write}, ++ ops::Deref, ++ os::unix::io::AsRawFd, ++ pin::Pin, ++ sync::atomic::{AtomicBool, Ordering}, ++ thread, time, ++}; ++ ++use libc::c_int; ++use nix::{ ++ errno::*, ++ sys::{ ++ aio::*, ++ signal::{ ++ sigaction, SaFlags, SigAction, SigHandler, SigSet, SigevNotify, ++ Signal, ++ }, ++ time::{TimeSpec, TimeValLike}, ++ }, ++}; + use tempfile::tempfile; + +-// Helper that polls an AioCb for completion or error +-fn poll_aio(aiocb: &mut AioCb) -> Result<()> { +- loop { +- let err = aiocb.error(); +- if err != Err(Error::from(Errno::EINPROGRESS)) { return err; }; +- thread::sleep(time::Duration::from_millis(10)); +- } ++lazy_static! { ++ pub static ref SIGNALED: AtomicBool = AtomicBool::new(false); + } + +-#[test] +-fn test_accessors() { +- let mut rbuf = vec![0; 4]; +- let aiocb = AioCb::from_mut_slice( 1001, +- 2, //offset +- &mut rbuf, +- 42, //priority +- SigevNotify::SigevSignal { +- signal: Signal::SIGUSR2, +- si_value: 99 +- }, +- LioOpcode::LIO_NOP); +- assert_eq!(1001, aiocb.fd()); +- assert_eq!(Some(LioOpcode::LIO_NOP), aiocb.lio_opcode()); +- assert_eq!(4, aiocb.nbytes()); +- assert_eq!(2, aiocb.offset()); +- assert_eq!(42, aiocb.priority()); +- let sev = aiocb.sigevent().sigevent(); +- assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo); +- assert_eq!(99, sev.sigev_value.sival_ptr as i64); ++extern "C" fn sigfunc(_: c_int) { ++ SIGNALED.store(true, Ordering::Relaxed); + } + +-// Tests AioCb.cancel. We aren't trying to test the OS's implementation, only +-// our bindings. So it's sufficient to check that AioCb.cancel returned any +-// AioCancelStat value. +-#[test] +-#[cfg_attr(target_env = "musl", ignore)] +-fn test_cancel() { +- let wbuf: &[u8] = b"CDEF"; +- +- let f = tempfile().unwrap(); +- let mut aiocb = AioCb::from_slice( f.as_raw_fd(), +- 0, //offset +- wbuf, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_NOP); +- aiocb.write().unwrap(); +- let err = aiocb.error(); +- assert!(err == Ok(()) || err == Err(Error::from(Errno::EINPROGRESS))); +- +- let cancelstat = aiocb.cancel(); +- assert!(cancelstat.is_ok()); +- +- // Wait for aiocb to complete, but don't care whether it succeeded +- let _ = poll_aio(&mut aiocb); +- let _ = aiocb.aio_return(); ++// Helper that polls an AioCb for completion or error ++macro_rules! poll_aio { ++ ($aiocb: expr) => { ++ loop { ++ let err = $aiocb.as_mut().error(); ++ if err != Err(Errno::EINPROGRESS) { ++ break err; ++ }; ++ thread::sleep(time::Duration::from_millis(10)); ++ } ++ }; + } + +-// Tests using aio_cancel_all for all outstanding IOs. +-#[test] +-#[cfg_attr(target_env = "musl", ignore)] +-fn test_aio_cancel_all() { +- let wbuf: &[u8] = b"CDEF"; +- +- let f = tempfile().unwrap(); +- let mut aiocb = AioCb::from_slice(f.as_raw_fd(), +- 0, //offset +- wbuf, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_NOP); +- aiocb.write().unwrap(); +- let err = aiocb.error(); +- assert!(err == Ok(()) || err == Err(Error::from(Errno::EINPROGRESS))); +- +- let cancelstat = aio_cancel_all(f.as_raw_fd()); +- assert!(cancelstat.is_ok()); ++mod aio_fsync { ++ use super::*; ++ ++ #[test] ++ fn test_accessors() { ++ let aiocb = AioFsync::new( ++ 1001, ++ AioFsyncMode::O_SYNC, ++ 42, ++ SigevNotify::SigevSignal { ++ signal: Signal::SIGUSR2, ++ si_value: 99, ++ }, ++ ); ++ assert_eq!(1001, aiocb.fd()); ++ assert_eq!(AioFsyncMode::O_SYNC, aiocb.mode()); ++ assert_eq!(42, aiocb.priority()); ++ let sev = aiocb.sigevent().sigevent(); ++ assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo); ++ assert_eq!(99, sev.sigev_value.sival_ptr as i64); ++ } + +- // Wait for aiocb to complete, but don't care whether it succeeded +- let _ = poll_aio(&mut aiocb); +- let _ = aiocb.aio_return(); +-} ++ /// `AioFsync::submit` should not modify the `AioCb` object if ++ /// `libc::aio_fsync` returns an error ++ // Skip on Linux, because Linux's AIO implementation can't detect errors ++ // synchronously ++ #[test] ++ #[cfg(any(target_os = "freebsd", target_os = "macos"))] ++ fn error() { ++ use std::mem; ++ ++ const INITIAL: &[u8] = b"abcdef123456"; ++ // Create an invalid AioFsyncMode ++ let mode = unsafe { mem::transmute(666) }; ++ let mut f = tempfile().unwrap(); ++ f.write_all(INITIAL).unwrap(); ++ let mut aiof = Box::pin(AioFsync::new( ++ f.as_raw_fd(), ++ mode, ++ 0, ++ SigevNotify::SigevNone, ++ )); ++ let err = aiof.as_mut().submit(); ++ err.expect_err("assertion failed"); ++ } + +-#[test] +-#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] +-fn test_fsync() { +- const INITIAL: &[u8] = b"abcdef123456"; +- let mut f = tempfile().unwrap(); +- f.write_all(INITIAL).unwrap(); +- let mut aiocb = AioCb::from_fd( f.as_raw_fd(), +- 0, //priority +- SigevNotify::SigevNone); +- let err = aiocb.fsync(AioFsyncMode::O_SYNC); +- assert!(err.is_ok()); +- poll_aio(&mut aiocb).unwrap(); +- aiocb.aio_return().unwrap(); ++ #[test] ++ #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] ++ fn ok() { ++ const INITIAL: &[u8] = b"abcdef123456"; ++ let mut f = tempfile().unwrap(); ++ f.write_all(INITIAL).unwrap(); ++ let fd = f.as_raw_fd(); ++ let mut aiof = Box::pin(AioFsync::new( ++ fd, ++ AioFsyncMode::O_SYNC, ++ 0, ++ SigevNotify::SigevNone, ++ )); ++ aiof.as_mut().submit().unwrap(); ++ poll_aio!(&mut aiof).unwrap(); ++ aiof.as_mut().aio_return().unwrap(); ++ } + } + +-/// `AioCb::fsync` should not modify the `AioCb` object if `libc::aio_fsync` returns +-/// an error +-// Skip on Linux, because Linux's AIO implementation can't detect errors +-// synchronously +-#[test] +-#[cfg(any(target_os = "freebsd", target_os = "macos"))] +-fn test_fsync_error() { +- use std::mem; ++mod aio_read { ++ use super::*; ++ ++ #[test] ++ fn test_accessors() { ++ let mut rbuf = vec![0; 4]; ++ let aiocb = AioRead::new( ++ 1001, ++ 2, //offset ++ &mut rbuf, ++ 42, //priority ++ SigevNotify::SigevSignal { ++ signal: Signal::SIGUSR2, ++ si_value: 99, ++ }, ++ ); ++ assert_eq!(1001, aiocb.fd()); ++ assert_eq!(4, aiocb.nbytes()); ++ assert_eq!(2, aiocb.offset()); ++ assert_eq!(42, aiocb.priority()); ++ let sev = aiocb.sigevent().sigevent(); ++ assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo); ++ assert_eq!(99, sev.sigev_value.sival_ptr as i64); ++ } + +- const INITIAL: &[u8] = b"abcdef123456"; +- // Create an invalid AioFsyncMode +- let mode = unsafe { mem::transmute(666) }; +- let mut f = tempfile().unwrap(); +- f.write_all(INITIAL).unwrap(); +- let mut aiocb = AioCb::from_fd( f.as_raw_fd(), +- 0, //priority +- SigevNotify::SigevNone); +- let err = aiocb.fsync(mode); +- assert!(err.is_err()); +-} ++ // Tests AioWrite.cancel. We aren't trying to test the OS's implementation, ++ // only our bindings. So it's sufficient to check that cancel ++ // returned any AioCancelStat value. ++ #[test] ++ #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] ++ fn cancel() { ++ const INITIAL: &[u8] = b"abcdef123456"; ++ let mut rbuf = vec![0; 4]; ++ let mut f = tempfile().unwrap(); ++ f.write_all(INITIAL).unwrap(); ++ let fd = f.as_raw_fd(); ++ let mut aior = ++ Box::pin(AioRead::new(fd, 2, &mut rbuf, 0, SigevNotify::SigevNone)); ++ aior.as_mut().submit().unwrap(); ++ ++ aior.as_mut().cancel().unwrap(); ++ ++ // Wait for aiow to complete, but don't care whether it succeeded ++ let _ = poll_aio!(&mut aior); ++ let _ = aior.as_mut().aio_return(); ++ } + +-#[test] +-#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] +-// On Travis, aio_suspend hits an assertion within glibc. This is either a bug +-// in Travis's version of glibc or Linux. Either way, we must skip the test. +-// https://github.com/nix-rust/nix/issues/1099 +-#[cfg_attr(target_os = "linux", ignore)] +-fn test_aio_suspend() { +- const INITIAL: &[u8] = b"abcdef123456"; +- const WBUF: &[u8] = b"CDEFG"; +- let timeout = TimeSpec::seconds(10); +- let mut rbuf = vec![0; 4]; +- let rlen = rbuf.len(); +- let mut f = tempfile().unwrap(); +- f.write_all(INITIAL).unwrap(); ++ /// `AioRead::submit` should not modify the `AioCb` object if ++ /// `libc::aio_read` returns an error ++ // Skip on Linux, because Linux's AIO implementation can't detect errors ++ // synchronously ++ #[test] ++ #[cfg(any(target_os = "freebsd", target_os = "macos"))] ++ fn error() { ++ const INITIAL: &[u8] = b"abcdef123456"; ++ let mut rbuf = vec![0; 4]; ++ let mut f = tempfile().unwrap(); ++ f.write_all(INITIAL).unwrap(); ++ let mut aior = Box::pin(AioRead::new( ++ f.as_raw_fd(), ++ -1, //an invalid offset ++ &mut rbuf, ++ 0, //priority ++ SigevNotify::SigevNone, ++ )); ++ aior.as_mut().submit().expect_err("assertion failed"); ++ } + +- let mut wcb = AioCb::from_slice( f.as_raw_fd(), +- 2, //offset +- WBUF, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_WRITE); +- +- let mut rcb = AioCb::from_mut_slice( f.as_raw_fd(), +- 8, //offset +- &mut rbuf, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_READ); +- wcb.write().unwrap(); +- rcb.read().unwrap(); +- loop { ++ // Test a simple aio operation with no completion notification. We must ++ // poll for completion ++ #[test] ++ #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] ++ fn ok() { ++ const INITIAL: &[u8] = b"abcdef123456"; ++ let mut rbuf = vec![0; 4]; ++ const EXPECT: &[u8] = b"cdef"; ++ let mut f = tempfile().unwrap(); ++ f.write_all(INITIAL).unwrap(); + { +- let cbbuf = [&wcb, &rcb]; +- assert!(aio_suspend(&cbbuf[..], Some(timeout)).is_ok()); +- } +- if rcb.error() != Err(Error::from(Errno::EINPROGRESS)) && +- wcb.error() != Err(Error::from(Errno::EINPROGRESS)) { +- break ++ let fd = f.as_raw_fd(); ++ let mut aior = Box::pin(AioRead::new( ++ fd, ++ 2, ++ &mut rbuf, ++ 0, ++ SigevNotify::SigevNone, ++ )); ++ aior.as_mut().submit().unwrap(); ++ ++ let err = poll_aio!(&mut aior); ++ assert_eq!(err, Ok(())); ++ assert_eq!(aior.as_mut().aio_return().unwrap(), EXPECT.len()); + } ++ assert_eq!(EXPECT, rbuf.deref().deref()); + } + +- assert_eq!(wcb.aio_return().unwrap() as usize, WBUF.len()); +- assert_eq!(rcb.aio_return().unwrap() as usize, rlen); +-} +- +-// Test a simple aio operation with no completion notification. We must poll +-// for completion +-#[test] +-#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] +-fn test_read() { +- const INITIAL: &[u8] = b"abcdef123456"; +- let mut rbuf = vec![0; 4]; +- const EXPECT: &[u8] = b"cdef"; +- let mut f = tempfile().unwrap(); +- f.write_all(INITIAL).unwrap(); +- { +- let mut aiocb = AioCb::from_mut_slice( f.as_raw_fd(), +- 2, //offset +- &mut rbuf, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_NOP); +- aiocb.read().unwrap(); +- +- let err = poll_aio(&mut aiocb); +- assert_eq!(err, Ok(())); +- assert_eq!(aiocb.aio_return().unwrap() as usize, EXPECT.len()); ++ // Like ok, but allocates the structure on the stack. ++ #[test] ++ #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] ++ fn on_stack() { ++ const INITIAL: &[u8] = b"abcdef123456"; ++ let mut rbuf = vec![0; 4]; ++ const EXPECT: &[u8] = b"cdef"; ++ let mut f = tempfile().unwrap(); ++ f.write_all(INITIAL).unwrap(); ++ { ++ let fd = f.as_raw_fd(); ++ let mut aior = ++ AioRead::new(fd, 2, &mut rbuf, 0, SigevNotify::SigevNone); ++ let mut aior = unsafe { Pin::new_unchecked(&mut aior) }; ++ aior.as_mut().submit().unwrap(); ++ ++ let err = poll_aio!(&mut aior); ++ assert_eq!(err, Ok(())); ++ assert_eq!(aior.as_mut().aio_return().unwrap(), EXPECT.len()); ++ } ++ assert_eq!(EXPECT, rbuf.deref().deref()); + } +- +- assert_eq!(EXPECT, rbuf.deref().deref()); + } + +-/// `AioCb::read` should not modify the `AioCb` object if `libc::aio_read` +-/// returns an error +-// Skip on Linux, because Linux's AIO implementation can't detect errors +-// synchronously +-#[test] +-#[cfg(any(target_os = "freebsd", target_os = "macos"))] +-fn test_read_error() { +- const INITIAL: &[u8] = b"abcdef123456"; +- let mut rbuf = vec![0; 4]; +- let mut f = tempfile().unwrap(); +- f.write_all(INITIAL).unwrap(); +- let mut aiocb = AioCb::from_mut_slice( f.as_raw_fd(), +- -1, //an invalid offset +- &mut rbuf, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_NOP); +- assert!(aiocb.read().is_err()); +-} +- +-// Tests from_mut_slice +-#[test] +-#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] +-fn test_read_into_mut_slice() { +- const INITIAL: &[u8] = b"abcdef123456"; +- let mut rbuf = vec![0; 4]; +- const EXPECT: &[u8] = b"cdef"; +- let mut f = tempfile().unwrap(); +- f.write_all(INITIAL).unwrap(); +- { +- let mut aiocb = AioCb::from_mut_slice( f.as_raw_fd(), +- 2, //offset +- &mut rbuf, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_NOP); +- aiocb.read().unwrap(); +- +- let err = poll_aio(&mut aiocb); +- assert_eq!(err, Ok(())); +- assert_eq!(aiocb.aio_return().unwrap() as usize, EXPECT.len()); ++#[cfg(target_os = "freebsd")] ++#[cfg(fbsd14)] ++mod aio_readv { ++ use std::io::IoSliceMut; ++ ++ use super::*; ++ ++ #[test] ++ fn test_accessors() { ++ let mut rbuf0 = vec![0; 4]; ++ let mut rbuf1 = vec![0; 8]; ++ let mut rbufs = ++ [IoSliceMut::new(&mut rbuf0), IoSliceMut::new(&mut rbuf1)]; ++ let aiocb = AioReadv::new( ++ 1001, ++ 2, //offset ++ &mut rbufs, ++ 42, //priority ++ SigevNotify::SigevSignal { ++ signal: Signal::SIGUSR2, ++ si_value: 99, ++ }, ++ ); ++ assert_eq!(1001, aiocb.fd()); ++ assert_eq!(2, aiocb.iovlen()); ++ assert_eq!(2, aiocb.offset()); ++ assert_eq!(42, aiocb.priority()); ++ let sev = aiocb.sigevent().sigevent(); ++ assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo); ++ assert_eq!(99, sev.sigev_value.sival_ptr as i64); + } + +- assert_eq!(rbuf, EXPECT); +-} +- +-// Tests from_ptr +-#[test] +-#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] +-fn test_read_into_pointer() { +- const INITIAL: &[u8] = b"abcdef123456"; +- let mut rbuf = vec![0; 4]; +- const EXPECT: &[u8] = b"cdef"; +- let mut f = tempfile().unwrap(); +- f.write_all(INITIAL).unwrap(); +- { +- // Safety: ok because rbuf lives until after poll_aio +- let mut aiocb = unsafe { +- AioCb::from_mut_ptr( f.as_raw_fd(), +- 2, //offset +- rbuf.as_mut_ptr() as *mut c_void, +- rbuf.len(), +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_NOP) +- }; +- aiocb.read().unwrap(); +- +- let err = poll_aio(&mut aiocb); +- assert_eq!(err, Ok(())); +- assert_eq!(aiocb.aio_return().unwrap() as usize, EXPECT.len()); ++ #[test] ++ #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] ++ fn ok() { ++ const INITIAL: &[u8] = b"abcdef123456"; ++ let mut rbuf0 = vec![0; 4]; ++ let mut rbuf1 = vec![0; 2]; ++ let mut rbufs = ++ [IoSliceMut::new(&mut rbuf0), IoSliceMut::new(&mut rbuf1)]; ++ const EXPECT0: &[u8] = b"cdef"; ++ const EXPECT1: &[u8] = b"12"; ++ let mut f = tempfile().unwrap(); ++ f.write_all(INITIAL).unwrap(); ++ { ++ let fd = f.as_raw_fd(); ++ let mut aior = Box::pin(AioReadv::new( ++ fd, ++ 2, ++ &mut rbufs, ++ 0, ++ SigevNotify::SigevNone, ++ )); ++ aior.as_mut().submit().unwrap(); ++ ++ let err = poll_aio!(&mut aior); ++ assert_eq!(err, Ok(())); ++ assert_eq!( ++ aior.as_mut().aio_return().unwrap(), ++ EXPECT0.len() + EXPECT1.len() ++ ); ++ } ++ assert_eq!(&EXPECT0, &rbuf0); ++ assert_eq!(&EXPECT1, &rbuf1); + } +- +- assert_eq!(rbuf, EXPECT); +-} +- +-// Test reading into an immutable buffer. It should fail +-// FIXME: This test fails to panic on Linux/musl +-#[test] +-#[should_panic(expected = "Can't read into an immutable buffer")] +-#[cfg_attr(target_env = "musl", ignore)] +-fn test_read_immutable_buffer() { +- let rbuf: &[u8] = b"CDEF"; +- let f = tempfile().unwrap(); +- let mut aiocb = AioCb::from_slice( f.as_raw_fd(), +- 2, //offset +- rbuf, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_NOP); +- aiocb.read().unwrap(); + } + ++mod aio_write { ++ use super::*; ++ ++ #[test] ++ fn test_accessors() { ++ let wbuf = vec![0; 4]; ++ let aiocb = AioWrite::new( ++ 1001, ++ 2, //offset ++ &wbuf, ++ 42, //priority ++ SigevNotify::SigevSignal { ++ signal: Signal::SIGUSR2, ++ si_value: 99, ++ }, ++ ); ++ assert_eq!(1001, aiocb.fd()); ++ assert_eq!(4, aiocb.nbytes()); ++ assert_eq!(2, aiocb.offset()); ++ assert_eq!(42, aiocb.priority()); ++ let sev = aiocb.sigevent().sigevent(); ++ assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo); ++ assert_eq!(99, sev.sigev_value.sival_ptr as i64); ++ } + +-// Test a simple aio operation with no completion notification. We must poll +-// for completion. Unlike test_aio_read, this test uses AioCb::from_slice +-#[test] +-#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] +-fn test_write() { +- const INITIAL: &[u8] = b"abcdef123456"; +- let wbuf = "CDEF".to_string().into_bytes(); +- let mut rbuf = Vec::new(); +- const EXPECT: &[u8] = b"abCDEF123456"; ++ // Tests AioWrite.cancel. We aren't trying to test the OS's implementation, ++ // only our bindings. So it's sufficient to check that cancel ++ // returned any AioCancelStat value. ++ #[test] ++ #[cfg_attr(target_env = "musl", ignore)] ++ fn cancel() { ++ let wbuf: &[u8] = b"CDEF"; ++ ++ let f = tempfile().unwrap(); ++ let mut aiow = Box::pin(AioWrite::new( ++ f.as_raw_fd(), ++ 0, ++ wbuf, ++ 0, ++ SigevNotify::SigevNone, ++ )); ++ aiow.as_mut().submit().unwrap(); ++ let err = aiow.as_mut().error(); ++ assert!(err == Ok(()) || err == Err(Errno::EINPROGRESS)); + +- let mut f = tempfile().unwrap(); +- f.write_all(INITIAL).unwrap(); +- let mut aiocb = AioCb::from_slice( f.as_raw_fd(), +- 2, //offset +- &wbuf, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_NOP); +- aiocb.write().unwrap(); +- +- let err = poll_aio(&mut aiocb); +- assert_eq!(err, Ok(())); +- assert_eq!(aiocb.aio_return().unwrap() as usize, wbuf.len()); +- +- f.seek(SeekFrom::Start(0)).unwrap(); +- let len = f.read_to_end(&mut rbuf).unwrap(); +- assert_eq!(len, EXPECT.len()); +- assert_eq!(rbuf, EXPECT); +-} ++ aiow.as_mut().cancel().unwrap(); + +-// Tests `AioCb::from_boxed_slice` with `Bytes` +-#[test] +-#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] +-fn test_write_bytes() { +- const INITIAL: &[u8] = b"abcdef123456"; +- let wbuf = Box::new(Bytes::from(&b"CDEF"[..])); +- let mut rbuf = Vec::new(); +- const EXPECT: &[u8] = b"abCDEF123456"; +- let expected_len = wbuf.len(); ++ // Wait for aiow to complete, but don't care whether it succeeded ++ let _ = poll_aio!(&mut aiow); ++ let _ = aiow.as_mut().aio_return(); ++ } + +- let mut f = tempfile().unwrap(); +- f.write_all(INITIAL).unwrap(); +- let mut aiocb = AioCb::from_boxed_slice( f.as_raw_fd(), +- 2, //offset +- wbuf, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_NOP); +- aiocb.write().unwrap(); +- +- let err = poll_aio(&mut aiocb); +- assert_eq!(err, Ok(())); +- assert_eq!(aiocb.aio_return().unwrap() as usize, expected_len); +- +- f.seek(SeekFrom::Start(0)).unwrap(); +- let len = f.read_to_end(&mut rbuf).unwrap(); +- assert_eq!(len, EXPECT.len()); +- assert_eq!(rbuf, EXPECT); +-} ++ // Test a simple aio operation with no completion notification. We must ++ // poll for completion. ++ #[test] ++ #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] ++ fn ok() { ++ const INITIAL: &[u8] = b"abcdef123456"; ++ let wbuf = "CDEF".to_string().into_bytes(); ++ let mut rbuf = Vec::new(); ++ const EXPECT: &[u8] = b"abCDEF123456"; ++ ++ let mut f = tempfile().unwrap(); ++ f.write_all(INITIAL).unwrap(); ++ let mut aiow = Box::pin(AioWrite::new( ++ f.as_raw_fd(), ++ 2, ++ &wbuf, ++ 0, ++ SigevNotify::SigevNone, ++ )); ++ aiow.as_mut().submit().unwrap(); + +-// Tests `AioCb::from_boxed_mut_slice` with `BytesMut` +-#[test] +-#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] +-fn test_read_bytes_mut_small() { +- const INITIAL: &[u8] = b"abcdef"; +- let rbuf = Box::new(BytesMut::from(vec![0; 4])); +- const EXPECT: &[u8] = b"cdef"; +- let mut f = tempfile().unwrap(); +- f.write_all(INITIAL).unwrap(); ++ let err = poll_aio!(&mut aiow); ++ assert_eq!(err, Ok(())); ++ assert_eq!(aiow.as_mut().aio_return().unwrap(), wbuf.len()); + +- let mut aiocb = AioCb::from_boxed_mut_slice( f.as_raw_fd(), +- 2, //offset +- rbuf, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_NOP); +- aiocb.read().unwrap(); +- +- let err = poll_aio(&mut aiocb); +- assert_eq!(err, Ok(())); +- assert_eq!(aiocb.aio_return().unwrap() as usize, EXPECT.len()); +- let buffer = aiocb.boxed_mut_slice().unwrap(); +- assert_eq!(buffer.borrow(), EXPECT); +-} ++ f.rewind().unwrap(); ++ let len = f.read_to_end(&mut rbuf).unwrap(); ++ assert_eq!(len, EXPECT.len()); ++ assert_eq!(rbuf, EXPECT); ++ } + +-// Tests `AioCb::from_ptr` +-#[test] +-#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] +-fn test_write_from_pointer() { +- const INITIAL: &[u8] = b"abcdef123456"; +- let wbuf = "CDEF".to_string().into_bytes(); +- let mut rbuf = Vec::new(); +- const EXPECT: &[u8] = b"abCDEF123456"; ++ // Like ok, but allocates the structure on the stack. ++ #[test] ++ #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] ++ fn on_stack() { ++ const INITIAL: &[u8] = b"abcdef123456"; ++ let wbuf = "CDEF".to_string().into_bytes(); ++ let mut rbuf = Vec::new(); ++ const EXPECT: &[u8] = b"abCDEF123456"; ++ ++ let mut f = tempfile().unwrap(); ++ f.write_all(INITIAL).unwrap(); ++ let mut aiow = AioWrite::new( ++ f.as_raw_fd(), ++ 2, //offset ++ &wbuf, ++ 0, //priority ++ SigevNotify::SigevNone, ++ ); ++ let mut aiow = unsafe { Pin::new_unchecked(&mut aiow) }; ++ aiow.as_mut().submit().unwrap(); + +- let mut f = tempfile().unwrap(); +- f.write_all(INITIAL).unwrap(); +- // Safety: ok because aiocb outlives poll_aio +- let mut aiocb = unsafe { +- AioCb::from_ptr( f.as_raw_fd(), +- 2, //offset +- wbuf.as_ptr() as *const c_void, +- wbuf.len(), +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_NOP) +- }; +- aiocb.write().unwrap(); ++ let err = poll_aio!(&mut aiow); ++ assert_eq!(err, Ok(())); ++ assert_eq!(aiow.as_mut().aio_return().unwrap(), wbuf.len()); + +- let err = poll_aio(&mut aiocb); +- assert_eq!(err, Ok(())); +- assert_eq!(aiocb.aio_return().unwrap() as usize, wbuf.len()); ++ f.rewind().unwrap(); ++ let len = f.read_to_end(&mut rbuf).unwrap(); ++ assert_eq!(len, EXPECT.len()); ++ assert_eq!(rbuf, EXPECT); ++ } + +- f.seek(SeekFrom::Start(0)).unwrap(); +- let len = f.read_to_end(&mut rbuf).unwrap(); +- assert_eq!(len, EXPECT.len()); +- assert_eq!(rbuf, EXPECT); ++ /// `AioWrite::write` should not modify the `AioCb` object if ++ /// `libc::aio_write` returns an error. ++ // Skip on Linux, because Linux's AIO implementation can't detect errors ++ // synchronously ++ #[test] ++ #[cfg(any(target_os = "freebsd", target_os = "macos"))] ++ fn error() { ++ let wbuf = "CDEF".to_string().into_bytes(); ++ let mut aiow = Box::pin(AioWrite::new( ++ 666, // An invalid file descriptor ++ 0, //offset ++ &wbuf, ++ 0, //priority ++ SigevNotify::SigevNone, ++ )); ++ aiow.as_mut().submit().expect_err("assertion failed"); ++ // Dropping the AioWrite at this point should not panic ++ } + } + +-/// `AioCb::write` should not modify the `AioCb` object if `libc::aio_write` +-/// returns an error +-// Skip on Linux, because Linux's AIO implementation can't detect errors +-// synchronously +-#[test] +-#[cfg(any(target_os = "freebsd", target_os = "macos"))] +-fn test_write_error() { +- let wbuf = "CDEF".to_string().into_bytes(); +- let mut aiocb = AioCb::from_slice( 666, // An invalid file descriptor +- 0, //offset +- &wbuf, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_NOP); +- assert!(aiocb.write().is_err()); +-} ++#[cfg(target_os = "freebsd")] ++#[cfg(fbsd14)] ++mod aio_writev { ++ use std::io::IoSlice; ++ ++ use super::*; ++ ++ #[test] ++ fn test_accessors() { ++ let wbuf0 = vec![0; 4]; ++ let wbuf1 = vec![0; 8]; ++ let wbufs = [IoSlice::new(&wbuf0), IoSlice::new(&wbuf1)]; ++ let aiocb = AioWritev::new( ++ 1001, ++ 2, //offset ++ &wbufs, ++ 42, //priority ++ SigevNotify::SigevSignal { ++ signal: Signal::SIGUSR2, ++ si_value: 99, ++ }, ++ ); ++ assert_eq!(1001, aiocb.fd()); ++ assert_eq!(2, aiocb.iovlen()); ++ assert_eq!(2, aiocb.offset()); ++ assert_eq!(42, aiocb.priority()); ++ let sev = aiocb.sigevent().sigevent(); ++ assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo); ++ assert_eq!(99, sev.sigev_value.sival_ptr as i64); ++ } + +-lazy_static! { +- pub static ref SIGNALED: AtomicBool = AtomicBool::new(false); +-} ++ // Test a simple aio operation with no completion notification. We must ++ // poll for completion. ++ #[test] ++ #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] ++ fn ok() { ++ const INITIAL: &[u8] = b"abcdef123456"; ++ let wbuf0 = b"BC"; ++ let wbuf1 = b"DEF"; ++ let wbufs = [IoSlice::new(wbuf0), IoSlice::new(wbuf1)]; ++ let wlen = wbuf0.len() + wbuf1.len(); ++ let mut rbuf = Vec::new(); ++ const EXPECT: &[u8] = b"aBCDEF123456"; ++ ++ let mut f = tempfile().unwrap(); ++ f.write_all(INITIAL).unwrap(); ++ let mut aiow = Box::pin(AioWritev::new( ++ f.as_raw_fd(), ++ 1, ++ &wbufs, ++ 0, ++ SigevNotify::SigevNone, ++ )); ++ aiow.as_mut().submit().unwrap(); + +-extern fn sigfunc(_: c_int) { +- SIGNALED.store(true, Ordering::Relaxed); ++ let err = poll_aio!(&mut aiow); ++ assert_eq!(err, Ok(())); ++ assert_eq!(aiow.as_mut().aio_return().unwrap(), wlen); ++ ++ f.rewind().unwrap(); ++ let len = f.read_to_end(&mut rbuf).unwrap(); ++ assert_eq!(len, EXPECT.len()); ++ assert_eq!(rbuf, EXPECT); ++ } + } + + // Test an aio operation with completion delivered by a signal +-// FIXME: This test is ignored on mips because of failures in qemu in CI + #[test] +-#[cfg_attr(any(all(target_env = "musl", target_arch = "x86_64"), target_arch = "mips", target_arch = "mips64"), ignore)] +-fn test_write_sigev_signal() { +- let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); +- let sa = SigAction::new(SigHandler::Handler(sigfunc), +- SaFlags::SA_RESETHAND, +- SigSet::empty()); ++#[cfg_attr( ++ any( ++ all(target_env = "musl", target_arch = "x86_64"), ++ target_arch = "mips", ++ target_arch = "mips64" ++ ), ++ ignore ++)] ++fn sigev_signal() { ++ let _m = crate::SIGNAL_MTX.lock(); ++ let sa = SigAction::new( ++ SigHandler::Handler(sigfunc), ++ SaFlags::SA_RESETHAND, ++ SigSet::empty(), ++ ); + SIGNALED.store(false, Ordering::Relaxed); + unsafe { sigaction(Signal::SIGUSR2, &sa) }.unwrap(); + +@@ -459,200 +521,106 @@ fn test_write_sigev_signal() { + + let mut f = tempfile().unwrap(); + f.write_all(INITIAL).unwrap(); +- let mut aiocb = AioCb::from_slice( f.as_raw_fd(), +- 2, //offset +- WBUF, +- 0, //priority +- SigevNotify::SigevSignal { +- signal: Signal::SIGUSR2, +- si_value: 0 //TODO: validate in sigfunc +- }, +- LioOpcode::LIO_NOP); +- aiocb.write().unwrap(); ++ let mut aiow = Box::pin(AioWrite::new( ++ f.as_raw_fd(), ++ 2, //offset ++ WBUF, ++ 0, //priority ++ SigevNotify::SigevSignal { ++ signal: Signal::SIGUSR2, ++ si_value: 0, //TODO: validate in sigfunc ++ }, ++ )); ++ aiow.as_mut().submit().unwrap(); + while !SIGNALED.load(Ordering::Relaxed) { + thread::sleep(time::Duration::from_millis(10)); + } + +- assert_eq!(aiocb.aio_return().unwrap() as usize, WBUF.len()); +- f.seek(SeekFrom::Start(0)).unwrap(); ++ assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len()); ++ f.rewind().unwrap(); + let len = f.read_to_end(&mut rbuf).unwrap(); + assert_eq!(len, EXPECT.len()); + assert_eq!(rbuf, EXPECT); + } + +-// Test LioCb::listio with LIO_WAIT, so all AIO ops should be complete by the +-// time listio returns. +-#[test] +-#[cfg(not(any(target_os = "ios", target_os = "macos")))] +-#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] +-fn test_liocb_listio_wait() { +- const INITIAL: &[u8] = b"abcdef123456"; +- const WBUF: &[u8] = b"CDEF"; +- let mut rbuf = vec![0; 4]; +- let rlen = rbuf.len(); +- let mut rbuf2 = Vec::new(); +- const EXPECT: &[u8] = b"abCDEF123456"; +- let mut f = tempfile().unwrap(); +- +- f.write_all(INITIAL).unwrap(); +- +- { +- let wcb = AioCb::from_slice( f.as_raw_fd(), +- 2, //offset +- WBUF, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_WRITE); +- +- let rcb = AioCb::from_mut_slice( f.as_raw_fd(), +- 8, //offset +- &mut rbuf, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_READ); +- let mut liocb = LioCb::with_capacity(2); +- liocb.aiocbs.push(wcb); +- liocb.aiocbs.push(rcb); +- let err = liocb.listio(LioMode::LIO_WAIT, SigevNotify::SigevNone); +- err.expect("lio_listio"); +- +- assert_eq!(liocb.aio_return(0).unwrap() as usize, WBUF.len()); +- assert_eq!(liocb.aio_return(1).unwrap() as usize, rlen); +- } +- assert_eq!(rbuf.deref().deref(), b"3456"); +- +- f.seek(SeekFrom::Start(0)).unwrap(); +- let len = f.read_to_end(&mut rbuf2).unwrap(); +- assert_eq!(len, EXPECT.len()); +- assert_eq!(rbuf2, EXPECT); +-} +- +-// Test LioCb::listio with LIO_NOWAIT and no SigEvent, so we must use some other +-// mechanism to check for the individual AioCb's completion. ++// Tests using aio_cancel_all for all outstanding IOs. + #[test] +-#[cfg(not(any(target_os = "ios", target_os = "macos")))] +-#[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)] +-fn test_liocb_listio_nowait() { +- const INITIAL: &[u8] = b"abcdef123456"; +- const WBUF: &[u8] = b"CDEF"; +- let mut rbuf = vec![0; 4]; +- let rlen = rbuf.len(); +- let mut rbuf2 = Vec::new(); +- const EXPECT: &[u8] = b"abCDEF123456"; +- let mut f = tempfile().unwrap(); +- +- f.write_all(INITIAL).unwrap(); ++#[cfg_attr(target_env = "musl", ignore)] ++fn test_aio_cancel_all() { ++ let wbuf: &[u8] = b"CDEF"; + +- { +- let wcb = AioCb::from_slice( f.as_raw_fd(), +- 2, //offset +- WBUF, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_WRITE); +- +- let rcb = AioCb::from_mut_slice( f.as_raw_fd(), +- 8, //offset +- &mut rbuf, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_READ); +- let mut liocb = LioCb::with_capacity(2); +- liocb.aiocbs.push(wcb); +- liocb.aiocbs.push(rcb); +- let err = liocb.listio(LioMode::LIO_NOWAIT, SigevNotify::SigevNone); +- err.expect("lio_listio"); +- +- poll_aio(&mut liocb.aiocbs[0]).unwrap(); +- poll_aio(&mut liocb.aiocbs[1]).unwrap(); +- assert_eq!(liocb.aiocbs[0].aio_return().unwrap() as usize, WBUF.len()); +- assert_eq!(liocb.aiocbs[1].aio_return().unwrap() as usize, rlen); +- } +- assert_eq!(rbuf.deref().deref(), b"3456"); ++ let f = tempfile().unwrap(); ++ let mut aiocb = Box::pin(AioWrite::new( ++ f.as_raw_fd(), ++ 0, //offset ++ wbuf, ++ 0, //priority ++ SigevNotify::SigevNone, ++ )); ++ aiocb.as_mut().submit().unwrap(); ++ let err = aiocb.as_mut().error(); ++ assert!(err == Ok(()) || err == Err(Errno::EINPROGRESS)); ++ ++ aio_cancel_all(f.as_raw_fd()).unwrap(); + +- f.seek(SeekFrom::Start(0)).unwrap(); +- let len = f.read_to_end(&mut rbuf2).unwrap(); +- assert_eq!(len, EXPECT.len()); +- assert_eq!(rbuf2, EXPECT); ++ // Wait for aiocb to complete, but don't care whether it succeeded ++ let _ = poll_aio!(&mut aiocb); ++ let _ = aiocb.as_mut().aio_return(); + } + +-// Test LioCb::listio with LIO_NOWAIT and a SigEvent to indicate when all +-// AioCb's are complete. +-// FIXME: This test is ignored on mips/mips64 because of failures in qemu in CI. + #[test] +-#[cfg(not(any(target_os = "ios", target_os = "macos")))] +-#[cfg_attr(any(target_arch = "mips", target_arch = "mips64", target_env = "musl"), ignore)] +-fn test_liocb_listio_signal() { +- let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); ++// On Cirrus on Linux, this test fails due to a glibc bug. ++// https://github.com/nix-rust/nix/issues/1099 ++#[cfg_attr(target_os = "linux", ignore)] ++// On Cirrus, aio_suspend is failing with EINVAL ++// https://github.com/nix-rust/nix/issues/1361 ++#[cfg_attr(target_os = "macos", ignore)] ++fn test_aio_suspend() { + const INITIAL: &[u8] = b"abcdef123456"; +- const WBUF: &[u8] = b"CDEF"; ++ const WBUF: &[u8] = b"CDEFG"; ++ let timeout = TimeSpec::seconds(10); + let mut rbuf = vec![0; 4]; + let rlen = rbuf.len(); +- let mut rbuf2 = Vec::new(); +- const EXPECT: &[u8] = b"abCDEF123456"; + let mut f = tempfile().unwrap(); +- let sa = SigAction::new(SigHandler::Handler(sigfunc), +- SaFlags::SA_RESETHAND, +- SigSet::empty()); +- let sigev_notify = SigevNotify::SigevSignal { signal: Signal::SIGUSR2, +- si_value: 0 }; +- + f.write_all(INITIAL).unwrap(); + +- { +- let wcb = AioCb::from_slice( f.as_raw_fd(), +- 2, //offset +- WBUF, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_WRITE); +- +- let rcb = AioCb::from_mut_slice( f.as_raw_fd(), +- 8, //offset +- &mut rbuf, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_READ); +- let mut liocb = LioCb::with_capacity(2); +- liocb.aiocbs.push(wcb); +- liocb.aiocbs.push(rcb); +- SIGNALED.store(false, Ordering::Relaxed); +- unsafe { sigaction(Signal::SIGUSR2, &sa) }.unwrap(); +- let err = liocb.listio(LioMode::LIO_NOWAIT, sigev_notify); +- err.expect("lio_listio"); +- while !SIGNALED.load(Ordering::Relaxed) { +- thread::sleep(time::Duration::from_millis(10)); ++ let mut wcb = Box::pin(AioWrite::new( ++ f.as_raw_fd(), ++ 2, //offset ++ WBUF, ++ 0, //priority ++ SigevNotify::SigevNone, ++ )); ++ ++ let mut rcb = Box::pin(AioRead::new( ++ f.as_raw_fd(), ++ 8, //offset ++ &mut rbuf, ++ 0, //priority ++ SigevNotify::SigevNone, ++ )); ++ wcb.as_mut().submit().unwrap(); ++ rcb.as_mut().submit().unwrap(); ++ loop { ++ { ++ let cbbuf = [ ++ &*wcb as &dyn AsRef, ++ &*rcb as &dyn AsRef, ++ ]; ++ let r = aio_suspend(&cbbuf[..], Some(timeout)); ++ match r { ++ Err(Errno::EINTR) => continue, ++ Err(e) => panic!("aio_suspend returned {:?}", e), ++ Ok(_) => (), ++ }; ++ } ++ if rcb.as_mut().error() != Err(Errno::EINPROGRESS) ++ && wcb.as_mut().error() != Err(Errno::EINPROGRESS) ++ { ++ break; + } +- +- assert_eq!(liocb.aiocbs[0].aio_return().unwrap() as usize, WBUF.len()); +- assert_eq!(liocb.aiocbs[1].aio_return().unwrap() as usize, rlen); + } +- assert_eq!(rbuf.deref().deref(), b"3456"); +- +- f.seek(SeekFrom::Start(0)).unwrap(); +- let len = f.read_to_end(&mut rbuf2).unwrap(); +- assert_eq!(len, EXPECT.len()); +- assert_eq!(rbuf2, EXPECT); +-} + +-// Try to use LioCb::listio to read into an immutable buffer. It should fail +-// FIXME: This test fails to panic on Linux/musl +-#[test] +-#[cfg(not(any(target_os = "ios", target_os = "macos")))] +-#[should_panic(expected = "Can't read into an immutable buffer")] +-#[cfg_attr(target_env = "musl", ignore)] +-fn test_liocb_listio_read_immutable() { +- let rbuf: &[u8] = b"abcd"; +- let f = tempfile().unwrap(); +- +- +- let mut liocb = LioCb::from(vec![ +- AioCb::from_slice( f.as_raw_fd(), +- 2, //offset +- rbuf, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_READ) +- ]); +- let _ = liocb.listio(LioMode::LIO_NOWAIT, SigevNotify::SigevNone); ++ assert_eq!(wcb.as_mut().aio_return().unwrap(), WBUF.len()); ++ assert_eq!(rcb.as_mut().aio_return().unwrap(), rlen); + } +diff --git a/vendor/nix/test/sys/test_aio_drop.rs b/vendor/nix/test/sys/test_aio_drop.rs +index 492da40..bbe6623 100644 +--- a/vendor/nix/test/sys/test_aio_drop.rs ++++ b/vendor/nix/test/sys/test_aio_drop.rs +@@ -1,17 +1,19 @@ +-extern crate nix; +-extern crate tempfile; +- + // Test dropping an AioCb that hasn't yet finished. + // This must happen in its own process, because on OSX this test seems to hose + // the AIO subsystem and causes subsequent tests to fail + #[test] + #[should_panic(expected = "Dropped an in-progress AioCb")] +-#[cfg(all(not(target_env = "musl"), +- any(target_os = "linux", +- target_os = "ios", +- target_os = "macos", +- target_os = "freebsd", +- target_os = "netbsd")))] ++#[cfg(all( ++ not(target_env = "musl"), ++ not(target_env = "uclibc"), ++ any( ++ target_os = "linux", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "netbsd" ++ ) ++))] + fn test_drop() { + use nix::sys::aio::*; + use nix::sys::signal::*; +@@ -22,11 +24,12 @@ fn test_drop() { + + let f = tempfile().unwrap(); + f.set_len(6).unwrap(); +- let mut aiocb = AioCb::from_slice( f.as_raw_fd(), +- 2, //offset +- WBUF, +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_NOP); +- aiocb.write().unwrap(); ++ let mut aiocb = Box::pin(AioWrite::new( ++ f.as_raw_fd(), ++ 2, //offset ++ WBUF, ++ 0, //priority ++ SigevNotify::SigevNone, ++ )); ++ aiocb.as_mut().submit().unwrap(); + } +diff --git a/vendor/nix/test/sys/test_epoll.rs b/vendor/nix/test/sys/test_epoll.rs +index e0dc513..9156915 100644 +--- a/vendor/nix/test/sys/test_epoll.rs ++++ b/vendor/nix/test/sys/test_epoll.rs +@@ -1,24 +1,24 @@ +-use nix::sys::epoll::{EpollCreateFlags, EpollFlags, EpollOp, EpollEvent}; +-use nix::sys::epoll::{epoll_create1, epoll_ctl}; +-use nix::Error; + use nix::errno::Errno; ++use nix::sys::epoll::{epoll_create1, epoll_ctl}; ++use nix::sys::epoll::{EpollCreateFlags, EpollEvent, EpollFlags, EpollOp}; + + #[test] + pub fn test_epoll_errno() { + let efd = epoll_create1(EpollCreateFlags::empty()).unwrap(); + let result = epoll_ctl(efd, EpollOp::EpollCtlDel, 1, None); +- assert!(result.is_err()); +- assert_eq!(result.unwrap_err(), Error::Sys(Errno::ENOENT)); ++ result.expect_err("assertion failed"); ++ assert_eq!(result.unwrap_err(), Errno::ENOENT); + + let result = epoll_ctl(efd, EpollOp::EpollCtlAdd, 1, None); +- assert!(result.is_err()); +- assert_eq!(result.unwrap_err(), Error::Sys(Errno::EINVAL)); ++ result.expect_err("assertion failed"); ++ assert_eq!(result.unwrap_err(), Errno::EINVAL); + } + + #[test] + pub fn test_epoll_ctl() { + let efd = epoll_create1(EpollCreateFlags::empty()).unwrap(); +- let mut event = EpollEvent::new(EpollFlags::EPOLLIN | EpollFlags::EPOLLERR, 1); ++ let mut event = ++ EpollEvent::new(EpollFlags::EPOLLIN | EpollFlags::EPOLLERR, 1); + epoll_ctl(efd, EpollOp::EpollCtlAdd, 1, &mut event).unwrap(); + epoll_ctl(efd, EpollOp::EpollCtlDel, 1, None).unwrap(); + } +diff --git a/vendor/nix/test/sys/test_inotify.rs b/vendor/nix/test/sys/test_inotify.rs +index a8ead46..bb5851a 100644 +--- a/vendor/nix/test/sys/test_inotify.rs ++++ b/vendor/nix/test/sys/test_inotify.rs +@@ -1,20 +1,19 @@ +-use nix::sys::inotify::{AddWatchFlags,InitFlags,Inotify}; +-use nix::Error; + use nix::errno::Errno; +-use tempfile; ++use nix::sys::inotify::{AddWatchFlags, InitFlags, Inotify}; + use std::ffi::OsString; + use std::fs::{rename, File}; + + #[test] + pub fn test_inotify() { +- let instance = Inotify::init(InitFlags::IN_NONBLOCK) +- .unwrap(); ++ let instance = Inotify::init(InitFlags::IN_NONBLOCK).unwrap(); + let tempdir = tempfile::tempdir().unwrap(); + +- instance.add_watch(tempdir.path(), AddWatchFlags::IN_ALL_EVENTS).unwrap(); ++ instance ++ .add_watch(tempdir.path(), AddWatchFlags::IN_ALL_EVENTS) ++ .unwrap(); + + let events = instance.read_events(); +- assert_eq!(events.unwrap_err(), Error::Sys(Errno::EAGAIN)); ++ assert_eq!(events.unwrap_err(), Errno::EAGAIN); + + File::create(tempdir.path().join("test")).unwrap(); + +@@ -24,14 +23,15 @@ pub fn test_inotify() { + + #[test] + pub fn test_inotify_multi_events() { +- let instance = Inotify::init(InitFlags::IN_NONBLOCK) +- .unwrap(); ++ let instance = Inotify::init(InitFlags::IN_NONBLOCK).unwrap(); + let tempdir = tempfile::tempdir().unwrap(); + +- instance.add_watch(tempdir.path(), AddWatchFlags::IN_ALL_EVENTS).unwrap(); ++ instance ++ .add_watch(tempdir.path(), AddWatchFlags::IN_ALL_EVENTS) ++ .unwrap(); + + let events = instance.read_events(); +- assert_eq!(events.unwrap_err(), Error::Sys(Errno::EAGAIN)); ++ assert_eq!(events.unwrap_err(), Errno::EAGAIN); + + File::create(tempdir.path().join("test")).unwrap(); + rename(tempdir.path().join("test"), tempdir.path().join("test2")).unwrap(); +diff --git a/vendor/nix/test/sys/test_ioctl.rs b/vendor/nix/test/sys/test_ioctl.rs +index f8e313b..40f60cf 100644 +--- a/vendor/nix/test/sys/test_ioctl.rs ++++ b/vendor/nix/test/sys/test_ioctl.rs +@@ -30,9 +30,16 @@ ioctl_readwrite_buf!(readwritebuf_test, 0, 0, u32); + + #[cfg(any(target_os = "linux", target_os = "android"))] + mod linux { ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] + #[test] + fn test_op_none() { +- if cfg!(any(target_arch = "mips", target_arch = "mips64", target_arch="powerpc", target_arch="powerpc64")){ ++ if cfg!(any( ++ target_arch = "mips", ++ target_arch = "mips64", ++ target_arch = "powerpc", ++ target_arch = "powerpc64" ++ )) { + assert_eq!(request_code_none!(b'q', 10) as u32, 0x2000_710A); + assert_eq!(request_code_none!(b'a', 255) as u32, 0x2000_61FF); + } else { +@@ -41,9 +48,16 @@ mod linux { + } + } + ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] + #[test] + fn test_op_write() { +- if cfg!(any(target_arch = "mips", target_arch = "mips64", target_arch="powerpc", target_arch="powerpc64")){ ++ if cfg!(any( ++ target_arch = "mips", ++ target_arch = "mips64", ++ target_arch = "powerpc", ++ target_arch = "powerpc64" ++ )) { + assert_eq!(request_code_write!(b'z', 10, 1) as u32, 0x8001_7A0A); + assert_eq!(request_code_write!(b'z', 10, 512) as u32, 0x8200_7A0A); + } else { +@@ -55,19 +69,29 @@ mod linux { + #[cfg(target_pointer_width = "64")] + #[test] + fn test_op_write_64() { +- if cfg!(any(target_arch = "mips64", target_arch="powerpc64")){ +- assert_eq!(request_code_write!(b'z', 10, (1 as u64) << 32) as u32, +- 0x8000_7A0A); ++ if cfg!(any(target_arch = "mips64", target_arch = "powerpc64")) { ++ assert_eq!( ++ request_code_write!(b'z', 10, 1u64 << 32) as u32, ++ 0x8000_7A0A ++ ); + } else { +- assert_eq!(request_code_write!(b'z', 10, (1 as u64) << 32) as u32, +- 0x4000_7A0A); ++ assert_eq!( ++ request_code_write!(b'z', 10, 1u64 << 32) as u32, ++ 0x4000_7A0A ++ ); + } +- + } + ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] + #[test] + fn test_op_read() { +- if cfg!(any(target_arch = "mips", target_arch = "mips64", target_arch="powerpc", target_arch="powerpc64")){ ++ if cfg!(any( ++ target_arch = "mips", ++ target_arch = "mips64", ++ target_arch = "powerpc", ++ target_arch = "powerpc64" ++ )) { + assert_eq!(request_code_read!(b'z', 10, 1) as u32, 0x4001_7A0A); + assert_eq!(request_code_read!(b'z', 10, 512) as u32, 0x4200_7A0A); + } else { +@@ -79,15 +103,21 @@ mod linux { + #[cfg(target_pointer_width = "64")] + #[test] + fn test_op_read_64() { +- if cfg!(any(target_arch = "mips64", target_arch="powerpc64")){ +- assert_eq!(request_code_read!(b'z', 10, (1 as u64) << 32) as u32, +- 0x4000_7A0A); ++ if cfg!(any(target_arch = "mips64", target_arch = "powerpc64")) { ++ assert_eq!( ++ request_code_read!(b'z', 10, 1u64 << 32) as u32, ++ 0x4000_7A0A ++ ); + } else { +- assert_eq!(request_code_read!(b'z', 10, (1 as u64) << 32) as u32, +- 0x8000_7A0A); ++ assert_eq!( ++ request_code_read!(b'z', 10, 1u64 << 32) as u32, ++ 0x8000_7A0A ++ ); + } + } + ++ // The cast is not unnecessary on all platforms. ++ #[allow(clippy::unnecessary_cast)] + #[test] + fn test_op_read_write() { + assert_eq!(request_code_readwrite!(b'z', 10, 1) as u32, 0xC001_7A0A); +@@ -97,17 +127,21 @@ mod linux { + #[cfg(target_pointer_width = "64")] + #[test] + fn test_op_read_write_64() { +- assert_eq!(request_code_readwrite!(b'z', 10, (1 as u64) << 32) as u32, +- 0xC000_7A0A); ++ assert_eq!( ++ request_code_readwrite!(b'z', 10, 1u64 << 32) as u32, ++ 0xC000_7A0A ++ ); + } + } + +-#[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "macos", +- target_os = "netbsd", +- target_os = "openbsd"))] ++#[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "openbsd" ++))] + mod bsd { + #[test] + fn test_op_none() { +@@ -131,7 +165,7 @@ mod bsd { + #[cfg(target_pointer_width = "64")] + #[test] + fn test_op_write_64() { +- assert_eq!(request_code_write!(b'z', 10, (1 as u64) << 32), 0x8000_7A0A); ++ assert_eq!(request_code_write!(b'z', 10, 1u64 << 32), 0x8000_7A0A); + } + + #[test] +@@ -143,7 +177,7 @@ mod bsd { + #[cfg(target_pointer_width = "64")] + #[test] + fn test_op_read_64() { +- assert_eq!(request_code_read!(b'z', 10, (1 as u64) << 32), 0x4000_7A0A); ++ assert_eq!(request_code_read!(b'z', 10, 1u64 << 32), 0x4000_7A0A); + } + + #[test] +@@ -155,7 +189,7 @@ mod bsd { + #[cfg(target_pointer_width = "64")] + #[test] + fn test_op_read_write_64() { +- assert_eq!(request_code_readwrite!(b'z', 10, (1 as u64) << 32), 0xC000_7A0A); ++ assert_eq!(request_code_readwrite!(b'z', 10, 1u64 << 32), 0xC000_7A0A); + } + } + +@@ -164,27 +198,26 @@ mod linux_ioctls { + use std::mem; + use std::os::unix::io::AsRawFd; + ++ use libc::{termios, TCGETS, TCSBRK, TCSETS, TIOCNXCL}; + use tempfile::tempfile; +- use libc::{TCGETS, TCSBRK, TCSETS, TIOCNXCL, termios}; + +- use nix::Error::Sys; +- use nix::errno::Errno::{ENOTTY, ENOSYS}; ++ use nix::errno::Errno; + + ioctl_none_bad!(tiocnxcl, TIOCNXCL); + #[test] + fn test_ioctl_none_bad() { + let file = tempfile().unwrap(); + let res = unsafe { tiocnxcl(file.as_raw_fd()) }; +- assert_eq!(res, Err(Sys(ENOTTY))); ++ assert_eq!(res, Err(Errno::ENOTTY)); + } + + ioctl_read_bad!(tcgets, TCGETS, termios); + #[test] + fn test_ioctl_read_bad() { + let file = tempfile().unwrap(); +- let mut termios = unsafe { mem::uninitialized() }; ++ let mut termios = unsafe { mem::zeroed() }; + let res = unsafe { tcgets(file.as_raw_fd(), &mut termios) }; +- assert_eq!(res, Err(Sys(ENOTTY))); ++ assert_eq!(res, Err(Errno::ENOTTY)); + } + + ioctl_write_int_bad!(tcsbrk, TCSBRK); +@@ -192,16 +225,16 @@ mod linux_ioctls { + fn test_ioctl_write_int_bad() { + let file = tempfile().unwrap(); + let res = unsafe { tcsbrk(file.as_raw_fd(), 0) }; +- assert_eq!(res, Err(Sys(ENOTTY))); ++ assert_eq!(res, Err(Errno::ENOTTY)); + } + + ioctl_write_ptr_bad!(tcsets, TCSETS, termios); + #[test] + fn test_ioctl_write_ptr_bad() { + let file = tempfile().unwrap(); +- let termios: termios = unsafe { mem::uninitialized() }; ++ let termios: termios = unsafe { mem::zeroed() }; + let res = unsafe { tcsets(file.as_raw_fd(), &termios) }; +- assert_eq!(res, Err(Sys(ENOTTY))); ++ assert_eq!(res, Err(Errno::ENOTTY)); + } + + // FIXME: Find a suitable example for `ioctl_readwrite_bad` +@@ -212,7 +245,7 @@ mod linux_ioctls { + fn test_ioctl_none() { + let file = tempfile().unwrap(); + let res = unsafe { log_status(file.as_raw_fd()) }; +- assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS))); ++ assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); + } + + #[repr(C)] +@@ -231,7 +264,7 @@ mod linux_ioctls { + let file = tempfile().unwrap(); + let data: v4l2_audio = unsafe { mem::zeroed() }; + let res = unsafe { s_audio(file.as_raw_fd(), &data) }; +- assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS))); ++ assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); + } + + // From linux/net/bluetooth/hci_sock.h +@@ -242,7 +275,7 @@ mod linux_ioctls { + fn test_ioctl_write_int() { + let file = tempfile().unwrap(); + let res = unsafe { hcidevup(file.as_raw_fd(), 0) }; +- assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS))); ++ assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); + } + + // From linux/videodev2.h +@@ -250,19 +283,19 @@ mod linux_ioctls { + #[test] + fn test_ioctl_read() { + let file = tempfile().unwrap(); +- let mut data: v4l2_audio = unsafe { mem::uninitialized() }; ++ let mut data: v4l2_audio = unsafe { mem::zeroed() }; + let res = unsafe { g_audio(file.as_raw_fd(), &mut data) }; +- assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS))); ++ assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); + } + + // From linux/videodev2.h +- ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio); ++ ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio); + #[test] + fn test_ioctl_readwrite() { + let file = tempfile().unwrap(); +- let mut data: v4l2_audio = unsafe { mem::uninitialized() }; ++ let mut data: v4l2_audio = unsafe { mem::zeroed() }; + let res = unsafe { enum_audio(file.as_raw_fd(), &mut data) }; +- assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS))); ++ assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); + } + + // FIXME: Find a suitable example for `ioctl_read_buf`. +@@ -282,13 +315,18 @@ mod linux_ioctls { + } + + // From linux/spi/spidev.h +- ioctl_write_buf!(spi_ioc_message, super::SPI_IOC_MAGIC, super::SPI_IOC_MESSAGE, spi_ioc_transfer); ++ ioctl_write_buf!( ++ spi_ioc_message, ++ super::SPI_IOC_MAGIC, ++ super::SPI_IOC_MESSAGE, ++ spi_ioc_transfer ++ ); + #[test] + fn test_ioctl_write_buf() { + let file = tempfile().unwrap(); + let data: [spi_ioc_transfer; 4] = unsafe { mem::zeroed() }; + let res = unsafe { spi_ioc_message(file.as_raw_fd(), &data[..]) }; +- assert!(res == Err(Sys(ENOTTY)) || res == Err(Sys(ENOSYS))); ++ assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS)); + } + + // FIXME: Find a suitable example for `ioctl_readwrite_buf`. +@@ -299,11 +337,10 @@ mod freebsd_ioctls { + use std::mem; + use std::os::unix::io::AsRawFd; + +- use tempfile::tempfile; + use libc::termios; ++ use tempfile::tempfile; + +- use nix::Error::Sys; +- use nix::errno::Errno::ENOTTY; ++ use nix::errno::Errno; + + // From sys/sys/ttycom.h + const TTY_IOC_MAGIC: u8 = b't'; +@@ -316,7 +353,7 @@ mod freebsd_ioctls { + fn test_ioctl_none() { + let file = tempfile().unwrap(); + let res = unsafe { tiocnxcl(file.as_raw_fd()) }; +- assert_eq!(res, Err(Sys(ENOTTY))); ++ assert_eq!(res, Err(Errno::ENOTTY)); + } + + ioctl_read!(tiocgeta, TTY_IOC_MAGIC, TTY_IOC_TYPE_GETA, termios); +@@ -325,7 +362,7 @@ mod freebsd_ioctls { + let file = tempfile().unwrap(); + let mut termios = unsafe { mem::zeroed() }; + let res = unsafe { tiocgeta(file.as_raw_fd(), &mut termios) }; +- assert_eq!(res, Err(Sys(ENOTTY))); ++ assert_eq!(res, Err(Errno::ENOTTY)); + } + + ioctl_write_ptr!(tiocseta, TTY_IOC_MAGIC, TTY_IOC_TYPE_SETA, termios); +@@ -334,6 +371,6 @@ mod freebsd_ioctls { + let file = tempfile().unwrap(); + let termios: termios = unsafe { mem::zeroed() }; + let res = unsafe { tiocseta(file.as_raw_fd(), &termios) }; +- assert_eq!(res, Err(Sys(ENOTTY))); ++ assert_eq!(res, Err(Errno::ENOTTY)); + } + } +diff --git a/vendor/nix/test/sys/test_lio_listio_resubmit.rs b/vendor/nix/test/sys/test_lio_listio_resubmit.rs +deleted file mode 100644 +index 19ee3fa..0000000 +--- a/vendor/nix/test/sys/test_lio_listio_resubmit.rs ++++ /dev/null +@@ -1,111 +0,0 @@ +-// vim: tw=80 +- +-// Annoyingly, Cargo is unable to conditionally build an entire test binary. So +-// we must disable the test here rather than in Cargo.toml +-#![cfg(target_os = "freebsd")] +- +-extern crate nix; +-extern crate sysctl; +-extern crate tempfile; +- +-use nix::Error; +-use nix::errno::*; +-use nix::libc::off_t; +-use nix::sys::aio::*; +-use nix::sys::signal::SigevNotify; +-use nix::unistd::{SysconfVar, sysconf}; +-use std::os::unix::io::AsRawFd; +-use std::{thread, time}; +-use sysctl::CtlValue; +-use tempfile::tempfile; +- +-const BYTES_PER_OP: usize = 512; +- +-/// Attempt to collect final status for all of `liocb`'s operations, freeing +-/// system resources +-fn finish_liocb(liocb: &mut LioCb) { +- for j in 0..liocb.aiocbs.len() { +- loop { +- let e = liocb.error(j); +- match e { +- Ok(()) => break, +- Err(Error::Sys(Errno::EINPROGRESS)) => +- thread::sleep(time::Duration::from_millis(10)), +- Err(x) => panic!("aio_error({:?})", x) +- } +- } +- assert_eq!(liocb.aio_return(j).unwrap(), BYTES_PER_OP as isize); +- } +-} +- +-// Deliberately exceed system resource limits, causing lio_listio to return EIO. +-// This test must run in its own process since it deliberately uses all AIO +-// resources. ATM it is only enabled on FreeBSD, because I don't know how to +-// check system AIO limits on other operating systems. +-#[test] +-fn test_lio_listio_resubmit() { +- let mut resubmit_count = 0; +- +- // Lookup system resource limits +- let alm = sysconf(SysconfVar::AIO_LISTIO_MAX) +- .expect("sysconf").unwrap() as usize; +- let maqpp = if let CtlValue::Int(x) = sysctl::value( +- "vfs.aio.max_aio_queue_per_proc").unwrap(){ +- x as usize +- } else { +- panic!("unknown sysctl"); +- }; +- +- // Find lio_listio sizes that satisfy the AIO_LISTIO_MAX constraint and also +- // result in a final lio_listio call that can only partially be queued +- let target_ops = maqpp + alm / 2; +- let num_listios = (target_ops + alm - 3) / (alm - 2); +- let ops_per_listio = (target_ops + num_listios - 1) / num_listios; +- assert!((num_listios - 1) * ops_per_listio < maqpp, +- "the last lio_listio won't make any progress; fix the algorithm"); +- println!("Using {:?} LioCbs of {:?} operations apiece", num_listios, +- ops_per_listio); +- +- let f = tempfile().unwrap(); +- let buffer_set = (0..num_listios).map(|_| { +- (0..ops_per_listio).map(|_| { +- vec![0u8; BYTES_PER_OP] +- }).collect::>() +- }).collect::>(); +- +- let mut liocbs = (0..num_listios).map(|i| { +- let mut liocb = LioCb::with_capacity(ops_per_listio); +- for j in 0..ops_per_listio { +- let offset = (BYTES_PER_OP * (i * ops_per_listio + j)) as off_t; +- let wcb = AioCb::from_slice( f.as_raw_fd(), +- offset, +- &buffer_set[i][j][..], +- 0, //priority +- SigevNotify::SigevNone, +- LioOpcode::LIO_WRITE); +- liocb.aiocbs.push(wcb); +- } +- let mut err = liocb.listio(LioMode::LIO_NOWAIT, SigevNotify::SigevNone); +- while err == Err(Error::Sys(Errno::EIO)) || +- err == Err(Error::Sys(Errno::EAGAIN)) || +- err == Err(Error::Sys(Errno::EINTR)) { +- // +- thread::sleep(time::Duration::from_millis(10)); +- resubmit_count += 1; +- err = liocb.listio_resubmit(LioMode::LIO_NOWAIT, +- SigevNotify::SigevNone); +- } +- liocb +- }).collect::>(); +- +- // Ensure that every AioCb completed +- for liocb in liocbs.iter_mut() { +- finish_liocb(liocb); +- } +- +- if resubmit_count > 0 { +- println!("Resubmitted {:?} times, test passed", resubmit_count); +- } else { +- println!("Never resubmitted. Test ambiguous"); +- } +-} +diff --git a/vendor/nix/test/sys/test_mman.rs b/vendor/nix/test/sys/test_mman.rs +new file mode 100644 +index 0000000..e748427 +--- /dev/null ++++ b/vendor/nix/test/sys/test_mman.rs +@@ -0,0 +1,122 @@ ++use nix::sys::mman::{mmap, MapFlags, ProtFlags}; ++use std::num::NonZeroUsize; ++ ++#[test] ++fn test_mmap_anonymous() { ++ unsafe { ++ let ptr = mmap( ++ None, ++ NonZeroUsize::new(1).unwrap(), ++ ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, ++ MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS, ++ -1, ++ 0, ++ ) ++ .unwrap() as *mut u8; ++ assert_eq!(*ptr, 0x00u8); ++ *ptr = 0xffu8; ++ assert_eq!(*ptr, 0xffu8); ++ } ++} ++ ++#[test] ++#[cfg(any(target_os = "linux", target_os = "netbsd"))] ++fn test_mremap_grow() { ++ use nix::libc::{c_void, size_t}; ++ use nix::sys::mman::{mremap, MRemapFlags}; ++ ++ const ONE_K: size_t = 1024; ++ let one_k_non_zero = NonZeroUsize::new(ONE_K).unwrap(); ++ ++ let slice: &mut [u8] = unsafe { ++ let mem = mmap( ++ None, ++ one_k_non_zero, ++ ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, ++ MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE, ++ -1, ++ 0, ++ ) ++ .unwrap(); ++ std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K) ++ }; ++ assert_eq!(slice[ONE_K - 1], 0x00); ++ slice[ONE_K - 1] = 0xFF; ++ assert_eq!(slice[ONE_K - 1], 0xFF); ++ ++ let slice: &mut [u8] = unsafe { ++ #[cfg(target_os = "linux")] ++ let mem = mremap( ++ slice.as_mut_ptr() as *mut c_void, ++ ONE_K, ++ 10 * ONE_K, ++ MRemapFlags::MREMAP_MAYMOVE, ++ None, ++ ) ++ .unwrap(); ++ #[cfg(target_os = "netbsd")] ++ let mem = mremap( ++ slice.as_mut_ptr() as *mut c_void, ++ ONE_K, ++ 10 * ONE_K, ++ MRemapFlags::MAP_REMAPDUP, ++ None, ++ ) ++ .unwrap(); ++ std::slice::from_raw_parts_mut(mem as *mut u8, 10 * ONE_K) ++ }; ++ ++ // The first KB should still have the old data in it. ++ assert_eq!(slice[ONE_K - 1], 0xFF); ++ ++ // The additional range should be zero-init'd and accessible. ++ assert_eq!(slice[10 * ONE_K - 1], 0x00); ++ slice[10 * ONE_K - 1] = 0xFF; ++ assert_eq!(slice[10 * ONE_K - 1], 0xFF); ++} ++ ++#[test] ++#[cfg(any(target_os = "linux", target_os = "netbsd"))] ++// Segfaults for unknown reasons under QEMU for 32-bit targets ++#[cfg_attr(all(target_pointer_width = "32", qemu), ignore)] ++fn test_mremap_shrink() { ++ use nix::libc::{c_void, size_t}; ++ use nix::sys::mman::{mremap, MRemapFlags}; ++ use std::num::NonZeroUsize; ++ ++ const ONE_K: size_t = 1024; ++ let ten_one_k = NonZeroUsize::new(10 * ONE_K).unwrap(); ++ let slice: &mut [u8] = unsafe { ++ let mem = mmap( ++ None, ++ ten_one_k, ++ ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, ++ MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE, ++ -1, ++ 0, ++ ) ++ .unwrap(); ++ std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K) ++ }; ++ assert_eq!(slice[ONE_K - 1], 0x00); ++ slice[ONE_K - 1] = 0xFF; ++ assert_eq!(slice[ONE_K - 1], 0xFF); ++ ++ let slice: &mut [u8] = unsafe { ++ let mem = mremap( ++ slice.as_mut_ptr() as *mut c_void, ++ ten_one_k.into(), ++ ONE_K, ++ MRemapFlags::empty(), ++ None, ++ ) ++ .unwrap(); ++ // Since we didn't supply MREMAP_MAYMOVE, the address should be the ++ // same. ++ assert_eq!(mem, slice.as_mut_ptr() as *mut c_void); ++ std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K) ++ }; ++ ++ // The first KB should still be accessible and have the old data in it. ++ assert_eq!(slice[ONE_K - 1], 0xFF); ++} +diff --git a/vendor/nix/test/sys/test_pthread.rs b/vendor/nix/test/sys/test_pthread.rs +index 8928010..ce048ba 100644 +--- a/vendor/nix/test/sys/test_pthread.rs ++++ b/vendor/nix/test/sys/test_pthread.rs +@@ -1,15 +1,22 @@ + use nix::sys::pthread::*; + +-#[cfg(target_env = "musl")] ++#[cfg(any(target_env = "musl", target_os = "redox"))] + #[test] + fn test_pthread_self() { + let tid = pthread_self(); +- assert!(tid != ::std::ptr::null_mut()); ++ assert!(!tid.is_null()); + } + +-#[cfg(not(target_env = "musl"))] ++#[cfg(not(any(target_env = "musl", target_os = "redox")))] + #[test] + fn test_pthread_self() { + let tid = pthread_self(); +- assert!(tid != 0); ++ assert_ne!(tid, 0); ++} ++ ++#[test] ++#[cfg(not(target_os = "redox"))] ++fn test_pthread_kill_none() { ++ pthread_kill(pthread_self(), None) ++ .expect("Should be able to send signal to my thread."); + } +diff --git a/vendor/nix/test/sys/test_ptrace.rs b/vendor/nix/test/sys/test_ptrace.rs +index cb2f04e..530560f 100644 +--- a/vendor/nix/test/sys/test_ptrace.rs ++++ b/vendor/nix/test/sys/test_ptrace.rs +@@ -1,48 +1,57 @@ +-use nix::Error; ++#[cfg(all( ++ target_os = "linux", ++ any(target_arch = "x86_64", target_arch = "x86"), ++ target_env = "gnu" ++))] ++use memoffset::offset_of; + use nix::errno::Errno; +-use nix::unistd::getpid; + use nix::sys::ptrace; + #[cfg(any(target_os = "android", target_os = "linux"))] + use nix::sys::ptrace::Options; ++use nix::unistd::getpid; + + #[cfg(any(target_os = "android", target_os = "linux"))] + use std::mem; + ++use crate::*; ++ + #[test] + fn test_ptrace() { + // Just make sure ptrace can be called at all, for now. + // FIXME: qemu-user doesn't implement ptrace on all arches, so permit ENOSYS +- require_capability!(CAP_SYS_PTRACE); ++ require_capability!("test_ptrace", CAP_SYS_PTRACE); + let err = ptrace::attach(getpid()).unwrap_err(); +- assert!(err == Error::Sys(Errno::EPERM) || err == Error::Sys(Errno::EINVAL) || +- err == Error::Sys(Errno::ENOSYS)); ++ assert!( ++ err == Errno::EPERM || err == Errno::EINVAL || err == Errno::ENOSYS ++ ); + } + + // Just make sure ptrace_setoptions can be called at all, for now. + #[test] + #[cfg(any(target_os = "android", target_os = "linux"))] + fn test_ptrace_setoptions() { +- require_capability!(CAP_SYS_PTRACE); +- let err = ptrace::setoptions(getpid(), Options::PTRACE_O_TRACESYSGOOD).unwrap_err(); +- assert!(err != Error::UnsupportedOperation); ++ require_capability!("test_ptrace_setoptions", CAP_SYS_PTRACE); ++ let err = ptrace::setoptions(getpid(), Options::PTRACE_O_TRACESYSGOOD) ++ .unwrap_err(); ++ assert_ne!(err, Errno::EOPNOTSUPP); + } + + // Just make sure ptrace_getevent can be called at all, for now. + #[test] + #[cfg(any(target_os = "android", target_os = "linux"))] + fn test_ptrace_getevent() { +- require_capability!(CAP_SYS_PTRACE); ++ require_capability!("test_ptrace_getevent", CAP_SYS_PTRACE); + let err = ptrace::getevent(getpid()).unwrap_err(); +- assert!(err != Error::UnsupportedOperation); ++ assert_ne!(err, Errno::EOPNOTSUPP); + } + + // Just make sure ptrace_getsiginfo can be called at all, for now. + #[test] + #[cfg(any(target_os = "android", target_os = "linux"))] + fn test_ptrace_getsiginfo() { +- require_capability!(CAP_SYS_PTRACE); +- if let Err(Error::UnsupportedOperation) = ptrace::getsiginfo(getpid()) { +- panic!("ptrace_getsiginfo returns Error::UnsupportedOperation!"); ++ require_capability!("test_ptrace_getsiginfo", CAP_SYS_PTRACE); ++ if let Err(Errno::EOPNOTSUPP) = ptrace::getsiginfo(getpid()) { ++ panic!("ptrace_getsiginfo returns Errno::EOPNOTSUPP!"); + } + } + +@@ -50,14 +59,13 @@ fn test_ptrace_getsiginfo() { + #[test] + #[cfg(any(target_os = "android", target_os = "linux"))] + fn test_ptrace_setsiginfo() { +- require_capability!(CAP_SYS_PTRACE); ++ require_capability!("test_ptrace_setsiginfo", CAP_SYS_PTRACE); + let siginfo = unsafe { mem::zeroed() }; +- if let Err(Error::UnsupportedOperation) = ptrace::setsiginfo(getpid(), &siginfo) { +- panic!("ptrace_setsiginfo returns Error::UnsupportedOperation!"); ++ if let Err(Errno::EOPNOTSUPP) = ptrace::setsiginfo(getpid(), &siginfo) { ++ panic!("ptrace_setsiginfo returns Errno::EOPNOTSUPP!"); + } + } + +- + #[test] + fn test_ptrace_cont() { + use nix::sys::ptrace; +@@ -66,22 +74,22 @@ fn test_ptrace_cont() { + use nix::unistd::fork; + use nix::unistd::ForkResult::*; + +- require_capability!(CAP_SYS_PTRACE); ++ require_capability!("test_ptrace_cont", CAP_SYS_PTRACE); + +- let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::FORK_MTX.lock(); + + // FIXME: qemu-user doesn't implement ptrace on all architectures +- // and retunrs ENOSYS in this case. ++ // and returns ENOSYS in this case. + // We (ab)use this behavior to detect the affected platforms + // and skip the test then. + // On valid platforms the ptrace call should return Errno::EPERM, this + // is already tested by `test_ptrace`. + let err = ptrace::attach(getpid()).unwrap_err(); +- if err == Error::Sys(Errno::ENOSYS) { ++ if err == Errno::ENOSYS { + return; + } + +- match fork().expect("Error: Fork Failed") { ++ match unsafe { fork() }.expect("Error: Fork Failed") { + Child => { + ptrace::traceme().unwrap(); + // As recommended by ptrace(2), raise SIGTRAP to pause the child +@@ -89,16 +97,23 @@ fn test_ptrace_cont() { + loop { + raise(Signal::SIGTRAP).unwrap(); + } +- +- }, ++ } + Parent { child } => { +- assert_eq!(waitpid(child, None), Ok(WaitStatus::Stopped(child, Signal::SIGTRAP))); ++ assert_eq!( ++ waitpid(child, None), ++ Ok(WaitStatus::Stopped(child, Signal::SIGTRAP)) ++ ); + ptrace::cont(child, None).unwrap(); +- assert_eq!(waitpid(child, None), Ok(WaitStatus::Stopped(child, Signal::SIGTRAP))); ++ assert_eq!( ++ waitpid(child, None), ++ Ok(WaitStatus::Stopped(child, Signal::SIGTRAP)) ++ ); + ptrace::cont(child, Some(Signal::SIGKILL)).unwrap(); + match waitpid(child, None) { +- Ok(WaitStatus::Signaled(pid, Signal::SIGKILL, _)) if pid == child => { +- // FIXME It's been observed on some systems (apple) the ++ Ok(WaitStatus::Signaled(pid, Signal::SIGKILL, _)) ++ if pid == child => ++ { ++ // FIXME It's been observed on some systems (apple) the + // tracee may not be killed but remain as a zombie process + // affecting other wait based tests. Add an extra kill just + // to make sure there are no zombies. +@@ -109,66 +124,152 @@ fn test_ptrace_cont() { + } + _ => panic!("The process should have been killed"), + } ++ } ++ } ++} ++ ++#[cfg(target_os = "linux")] ++#[test] ++fn test_ptrace_interrupt() { ++ use nix::sys::ptrace; ++ use nix::sys::signal::Signal; ++ use nix::sys::wait::{waitpid, WaitPidFlag, WaitStatus}; ++ use nix::unistd::fork; ++ use nix::unistd::ForkResult::*; ++ use std::thread::sleep; ++ use std::time::Duration; ++ ++ require_capability!("test_ptrace_interrupt", CAP_SYS_PTRACE); ++ ++ let _m = crate::FORK_MTX.lock(); ++ ++ match unsafe { fork() }.expect("Error: Fork Failed") { ++ Child => loop { ++ sleep(Duration::from_millis(1000)); + }, ++ Parent { child } => { ++ ptrace::seize(child, ptrace::Options::PTRACE_O_TRACESYSGOOD) ++ .unwrap(); ++ ptrace::interrupt(child).unwrap(); ++ assert_eq!( ++ waitpid(child, None), ++ Ok(WaitStatus::PtraceEvent(child, Signal::SIGTRAP, 128)) ++ ); ++ ptrace::syscall(child, None).unwrap(); ++ assert_eq!( ++ waitpid(child, None), ++ Ok(WaitStatus::PtraceSyscall(child)) ++ ); ++ ptrace::detach(child, Some(Signal::SIGKILL)).unwrap(); ++ match waitpid(child, None) { ++ Ok(WaitStatus::Signaled(pid, Signal::SIGKILL, _)) ++ if pid == child => ++ { ++ let _ = waitpid(child, Some(WaitPidFlag::WNOHANG)); ++ while ptrace::cont(child, Some(Signal::SIGKILL)).is_ok() { ++ let _ = waitpid(child, Some(WaitPidFlag::WNOHANG)); ++ } ++ } ++ _ => panic!("The process should have been killed"), ++ } ++ } + } + } + + // ptrace::{setoptions, getregs} are only available in these platforms +-#[cfg(all(target_os = "linux", +- any(target_arch = "x86_64", +- target_arch = "x86"), +- target_env = "gnu"))] ++#[cfg(all( ++ target_os = "linux", ++ any(target_arch = "x86_64", target_arch = "x86"), ++ target_env = "gnu" ++))] + #[test] + fn test_ptrace_syscall() { +- use nix::sys::signal::kill; + use nix::sys::ptrace; ++ use nix::sys::signal::kill; + use nix::sys::signal::Signal; + use nix::sys::wait::{waitpid, WaitStatus}; + use nix::unistd::fork; + use nix::unistd::getpid; + use nix::unistd::ForkResult::*; + +- let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test"); ++ require_capability!("test_ptrace_syscall", CAP_SYS_PTRACE); + +- match fork().expect("Error: Fork Failed") { ++ let _m = crate::FORK_MTX.lock(); ++ ++ match unsafe { fork() }.expect("Error: Fork Failed") { + Child => { + ptrace::traceme().unwrap(); + // first sigstop until parent is ready to continue + let pid = getpid(); + kill(pid, Signal::SIGSTOP).unwrap(); + kill(pid, Signal::SIGTERM).unwrap(); +- unsafe { ::libc::_exit(0); } +- }, ++ unsafe { ++ ::libc::_exit(0); ++ } ++ } + + Parent { child } => { +- assert_eq!(waitpid(child, None), Ok(WaitStatus::Stopped(child, Signal::SIGSTOP))); ++ assert_eq!( ++ waitpid(child, None), ++ Ok(WaitStatus::Stopped(child, Signal::SIGSTOP)) ++ ); + + // set this option to recognize syscall-stops +- ptrace::setoptions(child, ptrace::Options::PTRACE_O_TRACESYSGOOD).unwrap(); ++ ptrace::setoptions(child, ptrace::Options::PTRACE_O_TRACESYSGOOD) ++ .unwrap(); ++ ++ #[cfg(target_arch = "x86_64")] ++ let get_syscall_id = ++ || ptrace::getregs(child).unwrap().orig_rax as libc::c_long; + +- #[cfg(target_pointer_width = "64")] +- let get_syscall_id = || ptrace::getregs(child).unwrap().orig_rax as i64; ++ #[cfg(target_arch = "x86")] ++ let get_syscall_id = ++ || ptrace::getregs(child).unwrap().orig_eax as libc::c_long; + +- #[cfg(target_pointer_width = "32")] +- let get_syscall_id = || ptrace::getregs(child).unwrap().orig_eax as i32; ++ // this duplicates `get_syscall_id` for the purpose of testing `ptrace::read_user`. ++ #[cfg(target_arch = "x86_64")] ++ let rax_offset = offset_of!(libc::user_regs_struct, orig_rax); ++ #[cfg(target_arch = "x86")] ++ let rax_offset = offset_of!(libc::user_regs_struct, orig_eax); ++ ++ let get_syscall_from_user_area = || { ++ // Find the offset of `user.regs.rax` (or `user.regs.eax` for x86) ++ let rax_offset = offset_of!(libc::user, regs) + rax_offset; ++ ptrace::read_user(child, rax_offset as _).unwrap() ++ as libc::c_long ++ }; + + // kill entry + ptrace::syscall(child, None).unwrap(); +- assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceSyscall(child))); ++ assert_eq!( ++ waitpid(child, None), ++ Ok(WaitStatus::PtraceSyscall(child)) ++ ); + assert_eq!(get_syscall_id(), ::libc::SYS_kill); ++ assert_eq!(get_syscall_from_user_area(), ::libc::SYS_kill); + + // kill exit + ptrace::syscall(child, None).unwrap(); +- assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceSyscall(child))); ++ assert_eq!( ++ waitpid(child, None), ++ Ok(WaitStatus::PtraceSyscall(child)) ++ ); + assert_eq!(get_syscall_id(), ::libc::SYS_kill); ++ assert_eq!(get_syscall_from_user_area(), ::libc::SYS_kill); + + // receive signal + ptrace::syscall(child, None).unwrap(); +- assert_eq!(waitpid(child, None), Ok(WaitStatus::Stopped(child, Signal::SIGTERM))); ++ assert_eq!( ++ waitpid(child, None), ++ Ok(WaitStatus::Stopped(child, Signal::SIGTERM)) ++ ); + + // inject signal + ptrace::syscall(child, Signal::SIGTERM).unwrap(); +- assert_eq!(waitpid(child, None), Ok(WaitStatus::Signaled(child, Signal::SIGTERM, false))); +- }, ++ assert_eq!( ++ waitpid(child, None), ++ Ok(WaitStatus::Signaled(child, Signal::SIGTERM, false)) ++ ); ++ } + } + } +diff --git a/vendor/nix/test/sys/test_select.rs b/vendor/nix/test/sys/test_select.rs +index cf68700..40bda4d 100644 +--- a/vendor/nix/test/sys/test_select.rs ++++ b/vendor/nix/test/sys/test_select.rs +@@ -1,13 +1,11 @@ + use nix::sys::select::*; +-use nix::unistd::{pipe, write}; + use nix::sys::signal::SigSet; + use nix::sys::time::{TimeSpec, TimeValLike}; ++use nix::unistd::{pipe, write}; + + #[test] + pub fn test_pselect() { +- let _mtx = ::SIGNAL_MTX +- .lock() +- .expect("Mutex got poisoned by another test"); ++ let _mtx = crate::SIGNAL_MTX.lock(); + + let (r1, w1) = pipe().unwrap(); + write(w1, b"hi!").unwrap(); +@@ -47,8 +45,37 @@ pub fn test_pselect_nfds2() { + None, + &timeout, + None +- ).unwrap() ++ ) ++ .unwrap() + ); + assert!(fd_set.contains(r1)); + assert!(!fd_set.contains(r2)); + } ++ ++macro_rules! generate_fdset_bad_fd_tests { ++ ($fd:expr, $($method:ident),* $(,)?) => { ++ $( ++ #[test] ++ #[should_panic] ++ fn $method() { ++ FdSet::new().$method($fd); ++ } ++ )* ++ } ++} ++ ++mod test_fdset_negative_fd { ++ use super::*; ++ generate_fdset_bad_fd_tests!(-1, insert, remove, contains); ++} ++ ++mod test_fdset_too_large_fd { ++ use super::*; ++ use std::convert::TryInto; ++ generate_fdset_bad_fd_tests!( ++ FD_SETSIZE.try_into().unwrap(), ++ insert, ++ remove, ++ contains, ++ ); ++} +diff --git a/vendor/nix/test/sys/test_signal.rs b/vendor/nix/test/sys/test_signal.rs +index 4cb394c..3ad14f4 100644 +--- a/vendor/nix/test/sys/test_signal.rs ++++ b/vendor/nix/test/sys/test_signal.rs +@@ -1,5 +1,5 @@ +-use libc; +-use nix::Error; ++#[cfg(not(target_os = "redox"))] ++use nix::errno::Errno; + use nix::sys::signal::*; + use nix::unistd::*; + use std::convert::TryFrom; +@@ -11,6 +11,7 @@ fn test_kill_none() { + } + + #[test] ++#[cfg(not(target_os = "fuchsia"))] + fn test_killpg_none() { + killpg(getpgrp(), None) + .expect("Should be able to send signal to my process group."); +@@ -18,7 +19,7 @@ fn test_killpg_none() { + + #[test] + fn test_old_sigaction_flags() { +- let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::SIGNAL_MTX.lock(); + + extern "C" fn handler(_: ::libc::c_int) {} + let act = SigAction::new( +@@ -40,7 +41,7 @@ fn test_sigprocmask_noop() { + + #[test] + fn test_sigprocmask() { +- let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::SIGNAL_MTX.lock(); + + // This needs to be a signal that rust doesn't use in the test harness. + const SIGNAL: Signal = Signal::SIGCHLD; +@@ -51,9 +52,12 @@ fn test_sigprocmask() { + + // Make sure the old set doesn't contain the signal, otherwise the following + // test don't make sense. +- assert_eq!(old_signal_set.contains(SIGNAL), false, +- "the {:?} signal is already blocked, please change to a \ +- different one", SIGNAL); ++ assert!( ++ !old_signal_set.contains(SIGNAL), ++ "the {:?} signal is already blocked, please change to a \ ++ different one", ++ SIGNAL ++ ); + + // Now block the signal. + let mut signal_set = SigSet::empty(); +@@ -65,8 +69,11 @@ fn test_sigprocmask() { + old_signal_set.clear(); + sigprocmask(SigmaskHow::SIG_BLOCK, None, Some(&mut old_signal_set)) + .expect("expect to be able to retrieve old signals"); +- assert_eq!(old_signal_set.contains(SIGNAL), true, +- "expected the {:?} to be blocked", SIGNAL); ++ assert!( ++ old_signal_set.contains(SIGNAL), ++ "expected the {:?} to be blocked", ++ SIGNAL ++ ); + + // Reset the signal. + sigprocmask(SigmaskHow::SIG_UNBLOCK, Some(&signal_set), None) +@@ -77,30 +84,63 @@ lazy_static! { + static ref SIGNALED: AtomicBool = AtomicBool::new(false); + } + +-extern fn test_sigaction_handler(signal: libc::c_int) { ++extern "C" fn test_sigaction_handler(signal: libc::c_int) { + let signal = Signal::try_from(signal).unwrap(); + SIGNALED.store(signal == Signal::SIGINT, Ordering::Relaxed); + } + +-extern fn test_sigaction_action(_: libc::c_int, _: *mut libc::siginfo_t, _: *mut libc::c_void) { ++#[cfg(not(target_os = "redox"))] ++extern "C" fn test_sigaction_action( ++ _: libc::c_int, ++ _: *mut libc::siginfo_t, ++ _: *mut libc::c_void, ++) { ++} ++ ++#[test] ++#[cfg(not(target_os = "redox"))] ++fn test_signal_sigaction() { ++ let _m = crate::SIGNAL_MTX.lock(); ++ ++ let action_handler = SigHandler::SigAction(test_sigaction_action); ++ assert_eq!( ++ unsafe { signal(Signal::SIGINT, action_handler) }.unwrap_err(), ++ Errno::ENOTSUP ++ ); + } + + #[test] + fn test_signal() { +- let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::SIGNAL_MTX.lock(); + + unsafe { signal(Signal::SIGINT, SigHandler::SigIgn) }.unwrap(); + raise(Signal::SIGINT).unwrap(); +- assert_eq!(unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(), SigHandler::SigIgn); ++ assert_eq!( ++ unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(), ++ SigHandler::SigIgn ++ ); + + let handler = SigHandler::Handler(test_sigaction_handler); +- assert_eq!(unsafe { signal(Signal::SIGINT, handler) }.unwrap(), SigHandler::SigDfl); ++ assert_eq!( ++ unsafe { signal(Signal::SIGINT, handler) }.unwrap(), ++ SigHandler::SigDfl ++ ); + raise(Signal::SIGINT).unwrap(); + assert!(SIGNALED.load(Ordering::Relaxed)); +- assert_eq!(unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(), handler); + +- let action_handler = SigHandler::SigAction(test_sigaction_action); +- assert_eq!(unsafe { signal(Signal::SIGINT, action_handler) }.unwrap_err(), Error::UnsupportedOperation); ++ #[cfg(not(any(target_os = "illumos", target_os = "solaris")))] ++ assert_eq!( ++ unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(), ++ handler ++ ); ++ ++ // System V based OSes (e.g. illumos and Solaris) always resets the ++ // disposition to SIG_DFL prior to calling the signal handler ++ #[cfg(any(target_os = "illumos", target_os = "solaris"))] ++ assert_eq!( ++ unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(), ++ SigHandler::SigDfl ++ ); + + // Restore default signal handler + unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(); +diff --git a/vendor/nix/test/sys/test_signalfd.rs b/vendor/nix/test/sys/test_signalfd.rs +index 92759a4..87153c9 100644 +--- a/vendor/nix/test/sys/test_signalfd.rs ++++ b/vendor/nix/test/sys/test_signalfd.rs +@@ -2,11 +2,11 @@ use std::convert::TryFrom; + + #[test] + fn test_signalfd() { ++ use nix::sys::signal::{self, raise, SigSet, Signal}; + use nix::sys::signalfd::SignalFd; +- use nix::sys::signal::{self, raise, Signal, SigSet}; + + // Grab the mutex for altering signals so we don't interfere with other tests. +- let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::SIGNAL_MTX.lock(); + + // Block the SIGUSR1 signal from automatic processing for this thread + let mut mask = SigSet::empty(); +diff --git a/vendor/nix/test/sys/test_socket.rs b/vendor/nix/test/sys/test_socket.rs +index bd5c373..5adc77e 100644 +--- a/vendor/nix/test/sys/test_socket.rs ++++ b/vendor/nix/test/sys/test_socket.rs +@@ -1,15 +1,21 @@ +-use nix::ifaddrs::InterfaceAddress; +-use nix::sys::socket::{AddressFamily, InetAddr, UnixAddr, getsockname}; ++#[cfg(any(target_os = "linux", target_os = "android"))] ++use crate::*; ++use libc::{c_char, sockaddr_storage}; ++#[allow(deprecated)] ++use nix::sys::socket::InetAddr; ++use nix::sys::socket::{ ++ getsockname, sockaddr, sockaddr_in6, AddressFamily, UnixAddr, ++}; + use std::collections::hash_map::DefaultHasher; + use std::hash::{Hash, Hasher}; +-use std::net::{self, Ipv6Addr, SocketAddr, SocketAddrV6}; ++use std::mem::{self, MaybeUninit}; ++use std::net::{self, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; + use std::os::unix::io::RawFd; + use std::path::Path; + use std::slice; + use std::str::FromStr; +-use libc::c_char; +-use tempfile; + ++#[allow(deprecated)] + #[test] + pub fn test_inetv4_addr_to_sock_addr() { + let actual: net::SocketAddr = FromStr::from_str("127.0.0.1:3000").unwrap(); +@@ -27,32 +33,137 @@ pub fn test_inetv4_addr_to_sock_addr() { + _ => panic!("nope"), + } + +- assert_eq!(addr.to_str(), "127.0.0.1:3000"); ++ assert_eq!(addr.to_string(), "127.0.0.1:3000"); + + let inet = addr.to_std(); + assert_eq!(actual, inet); + } + ++#[allow(deprecated)] + #[test] +-pub fn test_inetv6_addr_to_sock_addr() { ++pub fn test_inetv4_addr_roundtrip_sockaddr_storage_to_addr() { ++ use nix::sys::socket::{sockaddr_storage_to_addr, SockAddr}; ++ ++ let actual: net::SocketAddr = FromStr::from_str("127.0.0.1:3000").unwrap(); ++ let addr = InetAddr::from_std(&actual); ++ let sockaddr = SockAddr::new_inet(addr); ++ ++ let (storage, ffi_size) = { ++ let mut storage = MaybeUninit::::zeroed(); ++ let storage_ptr = storage.as_mut_ptr().cast::(); ++ let (ffi_ptr, ffi_size) = sockaddr.as_ffi_pair(); ++ assert_eq!(mem::size_of::(), ffi_size as usize); ++ unsafe { ++ storage_ptr.copy_from_nonoverlapping(ffi_ptr as *const sockaddr, 1); ++ (storage.assume_init(), ffi_size) ++ } ++ }; ++ ++ let from_storage = ++ sockaddr_storage_to_addr(&storage, ffi_size as usize).unwrap(); ++ assert_eq!(from_storage, sockaddr); ++ let from_storage = ++ sockaddr_storage_to_addr(&storage, mem::size_of::()) ++ .unwrap(); ++ assert_eq!(from_storage, sockaddr); ++} ++ ++#[cfg(any(target_os = "linux"))] ++#[cfg_attr(qemu, ignore)] ++#[test] ++pub fn test_timestamping() { ++ use nix::sys::socket::{ ++ recvmsg, sendmsg, setsockopt, socket, sockopt::Timestamping, ++ ControlMessageOwned, MsgFlags, SockFlag, SockType, SockaddrIn, ++ TimestampingFlag, ++ }; ++ use std::io::{IoSlice, IoSliceMut}; ++ ++ let sock_addr = SockaddrIn::from_str("127.0.0.1:6790").unwrap(); ++ ++ let ssock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("send socket failed"); ++ ++ let rsock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); ++ nix::sys::socket::bind(rsock, &sock_addr).unwrap(); ++ ++ setsockopt(rsock, Timestamping, &TimestampingFlag::all()).unwrap(); ++ ++ let sbuf = [0u8; 2048]; ++ let mut rbuf = [0u8; 2048]; ++ let flags = MsgFlags::empty(); ++ let iov1 = [IoSlice::new(&sbuf)]; ++ let mut iov2 = [IoSliceMut::new(&mut rbuf)]; ++ ++ let mut cmsg = cmsg_space!(nix::sys::socket::Timestamps); ++ sendmsg(ssock, &iov1, &[], flags, Some(&sock_addr)).unwrap(); ++ let recv = recvmsg::<()>(rsock, &mut iov2, Some(&mut cmsg), flags).unwrap(); ++ ++ let mut ts = None; ++ for c in recv.cmsgs() { ++ if let ControlMessageOwned::ScmTimestampsns(timestamps) = c { ++ ts = Some(timestamps.system); ++ } ++ } ++ let ts = ts.expect("ScmTimestampns is present"); ++ let sys_time = ++ ::nix::time::clock_gettime(::nix::time::ClockId::CLOCK_REALTIME) ++ .unwrap(); ++ let diff = if ts > sys_time { ++ ts - sys_time ++ } else { ++ sys_time - ts ++ }; ++ assert!(std::time::Duration::from(diff).as_secs() < 60); ++} ++ ++#[allow(deprecated)] ++#[test] ++pub fn test_inetv6_addr_roundtrip_sockaddr_storage_to_addr() { ++ use nix::sys::socket::{sockaddr_storage_to_addr, SockAddr}; ++ + let port: u16 = 3000; + let flowinfo: u32 = 1; + let scope_id: u32 = 2; + let ip: Ipv6Addr = "fe80::1".parse().unwrap(); + +- let actual = SocketAddr::V6(SocketAddrV6::new(ip, port, flowinfo, scope_id)); ++ let actual = ++ SocketAddr::V6(SocketAddrV6::new(ip, port, flowinfo, scope_id)); + let addr = InetAddr::from_std(&actual); +- +- match addr { +- InetAddr::V6(addr) => { +- assert_eq!(addr.sin6_port, port.to_be()); +- assert_eq!(addr.sin6_flowinfo, flowinfo); +- assert_eq!(addr.sin6_scope_id, scope_id); ++ let sockaddr = SockAddr::new_inet(addr); ++ ++ let (storage, ffi_size) = { ++ let mut storage = MaybeUninit::::zeroed(); ++ let storage_ptr = storage.as_mut_ptr().cast::(); ++ let (ffi_ptr, ffi_size) = sockaddr.as_ffi_pair(); ++ assert_eq!(mem::size_of::(), ffi_size as usize); ++ unsafe { ++ storage_ptr.copy_from_nonoverlapping( ++ (ffi_ptr as *const sockaddr).cast::(), ++ 1, ++ ); ++ (storage.assume_init(), ffi_size) + } +- _ => panic!("nope"), +- } ++ }; + +- assert_eq!(actual, addr.to_std()); ++ let from_storage = ++ sockaddr_storage_to_addr(&storage, ffi_size as usize).unwrap(); ++ assert_eq!(from_storage, sockaddr); ++ let from_storage = ++ sockaddr_storage_to_addr(&storage, mem::size_of::()) ++ .unwrap(); ++ assert_eq!(from_storage, sockaddr); + } + + #[test] +@@ -62,9 +173,9 @@ pub fn test_path_to_sock_addr() { + let addr = UnixAddr::new(actual).unwrap(); + + let expect: &[c_char] = unsafe { +- slice::from_raw_parts(path.as_bytes().as_ptr() as *const c_char, path.len()) ++ slice::from_raw_parts(path.as_ptr() as *const c_char, path.len()) + }; +- assert_eq!(&addr.0.sun_path[..8], expect); ++ assert_eq!(unsafe { &(*addr.as_ptr()).sun_path[..8] }, expect); + + assert_eq!(addr.path(), Some(actual)); + } +@@ -80,9 +191,9 @@ pub fn test_addr_equality_path() { + let path = "/foo/bar"; + let actual = Path::new(path); + let addr1 = UnixAddr::new(actual).unwrap(); +- let mut addr2 = addr1.clone(); ++ let mut addr2 = addr1; + +- addr2.0.sun_path[10] = 127; ++ unsafe { (*addr2.as_mut_ptr()).sun_path[10] = 127 }; + + assert_eq!(addr1, addr2); + assert_eq!(calculate_hash(&addr1), calculate_hash(&addr2)); +@@ -93,7 +204,7 @@ pub fn test_addr_equality_path() { + pub fn test_abstract_sun_path_too_long() { + let name = String::from("nix\0abstract\0tesnix\0abstract\0tesnix\0abstract\0tesnix\0abstract\0tesnix\0abstract\0testttttnix\0abstract\0test\0make\0sure\0this\0is\0long\0enough"); + let addr = UnixAddr::new_abstract(name.as_bytes()); +- assert!(addr.is_err()); ++ addr.expect_err("assertion failed"); + } + + #[cfg(any(target_os = "android", target_os = "linux"))] +@@ -101,18 +212,18 @@ pub fn test_abstract_sun_path_too_long() { + pub fn test_addr_equality_abstract() { + let name = String::from("nix\0abstract\0test"); + let addr1 = UnixAddr::new_abstract(name.as_bytes()).unwrap(); +- let mut addr2 = addr1.clone(); ++ let mut addr2 = addr1; + + assert_eq!(addr1, addr2); + assert_eq!(calculate_hash(&addr1), calculate_hash(&addr2)); + +- addr2.0.sun_path[17] = 127; ++ unsafe { (*addr2.as_mut_ptr()).sun_path[17] = 127 }; + assert_ne!(addr1, addr2); + assert_ne!(calculate_hash(&addr1), calculate_hash(&addr2)); + } + + // Test getting/setting abstract addresses (without unix socket creation) +-#[cfg(target_os = "linux")] ++#[cfg(any(target_os = "android", target_os = "linux"))] + #[test] + pub fn test_abstract_uds_addr() { + let empty = String::new(); +@@ -123,54 +234,100 @@ pub fn test_abstract_uds_addr() { + let name = String::from("nix\0abstract\0test"); + let addr = UnixAddr::new_abstract(name.as_bytes()).unwrap(); + let sun_path = [ +- 110u8, 105, 120, 0, 97, 98, 115, 116, 114, 97, 99, 116, 0, 116, 101, 115, 116 ++ 110u8, 105, 120, 0, 97, 98, 115, 116, 114, 97, 99, 116, 0, 116, 101, ++ 115, 116, + ]; + assert_eq!(addr.as_abstract(), Some(&sun_path[..])); + assert_eq!(addr.path(), None); + + // Internally, name is null-prefixed (abstract namespace) +- assert_eq!(addr.0.sun_path[0], 0); ++ assert_eq!(unsafe { (*addr.as_ptr()).sun_path[0] }, 0); ++} ++ ++// Test getting an unnamed address (without unix socket creation) ++#[cfg(any(target_os = "android", target_os = "linux"))] ++#[test] ++pub fn test_unnamed_uds_addr() { ++ use crate::nix::sys::socket::SockaddrLike; ++ ++ let addr = UnixAddr::new_unnamed(); ++ ++ assert!(addr.is_unnamed()); ++ assert_eq!(addr.len(), 2); ++ assert!(addr.path().is_none()); ++ assert_eq!(addr.path_len(), 0); ++ ++ assert!(addr.as_abstract().is_none()); + } + + #[test] + pub fn test_getsockname() { +- use nix::sys::socket::{socket, AddressFamily, SockType, SockFlag}; +- use nix::sys::socket::{bind, SockAddr}; ++ use nix::sys::socket::bind; ++ use nix::sys::socket::{socket, AddressFamily, SockFlag, SockType}; + + let tempdir = tempfile::tempdir().unwrap(); + let sockname = tempdir.path().join("sock"); +- let sock = socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(), None) +- .expect("socket failed"); +- let sockaddr = SockAddr::new_unix(&sockname).unwrap(); ++ let sock = socket( ++ AddressFamily::Unix, ++ SockType::Stream, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("socket failed"); ++ let sockaddr = UnixAddr::new(&sockname).unwrap(); + bind(sock, &sockaddr).expect("bind failed"); +- assert_eq!(sockaddr.to_str(), +- getsockname(sock).expect("getsockname failed").to_str()); ++ assert_eq!(sockaddr, getsockname(sock).expect("getsockname failed")); + } + + #[test] + pub fn test_socketpair() { ++ use nix::sys::socket::{socketpair, AddressFamily, SockFlag, SockType}; + use nix::unistd::{read, write}; +- use nix::sys::socket::{socketpair, AddressFamily, SockType, SockFlag}; + +- let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()) +- .unwrap(); ++ let (fd1, fd2) = socketpair( ++ AddressFamily::Unix, ++ SockType::Stream, ++ None, ++ SockFlag::empty(), ++ ) ++ .unwrap(); + write(fd1, b"hello").unwrap(); +- let mut buf = [0;5]; ++ let mut buf = [0; 5]; + read(fd2, &mut buf).unwrap(); + + assert_eq!(&buf[..], b"hello"); + } + ++#[test] ++pub fn test_std_conversions() { ++ use nix::sys::socket::*; ++ ++ let std_sa = SocketAddrV4::from_str("127.0.0.1:6789").unwrap(); ++ let sock_addr = SockaddrIn::from(std_sa); ++ assert_eq!(std_sa, sock_addr.into()); ++ ++ let std_sa = SocketAddrV6::from_str("[::1]:6000").unwrap(); ++ let sock_addr: SockaddrIn6 = SockaddrIn6::from(std_sa); ++ assert_eq!(std_sa, sock_addr.into()); ++} ++ + mod recvfrom { +- use nix::Result; ++ use super::*; + use nix::sys::socket::*; ++ use nix::{errno::Errno, Result}; + use std::thread; +- use super::*; +- +- const MSG: &'static [u8] = b"Hello, World!"; + +- fn sendrecv(rsock: RawFd, ssock: RawFd, f: F) -> Option +- where F: Fn(RawFd, &[u8], MsgFlags) -> Result + Send + 'static ++ const MSG: &[u8] = b"Hello, World!"; ++ ++ fn sendrecv( ++ rsock: RawFd, ++ ssock: RawFd, ++ f_send: Fs, ++ mut f_recv: Fr, ++ ) -> Option ++ where ++ Fs: Fn(RawFd, &[u8], MsgFlags) -> Result + Send + 'static, ++ Fr: FnMut(usize, Option), + { + let mut buf: [u8; 13] = [0u8; 13]; + let mut l = 0; +@@ -179,12 +336,13 @@ mod recvfrom { + let send_thread = thread::spawn(move || { + let mut l = 0; + while l < std::mem::size_of_val(MSG) { +- l += f(ssock, &MSG[l..], MsgFlags::empty()).unwrap(); ++ l += f_send(ssock, &MSG[l..], MsgFlags::empty()).unwrap(); + } + }); + + while l < std::mem::size_of_val(MSG) { + let (len, from_) = recvfrom(rsock, &mut buf[l..]).unwrap(); ++ f_recv(len, from_); + from = from_; + l += len; + } +@@ -195,84 +353,462 @@ mod recvfrom { + + #[test] + pub fn stream() { +- let (fd2, fd1) = socketpair(AddressFamily::Unix, SockType::Stream, +- None, SockFlag::empty()).unwrap(); ++ let (fd2, fd1) = socketpair( ++ AddressFamily::Unix, ++ SockType::Stream, ++ None, ++ SockFlag::empty(), ++ ) ++ .unwrap(); + // Ignore from for stream sockets +- let _ = sendrecv(fd1, fd2, |s, m, flags| { +- send(s, m, flags) +- }); ++ let _ = sendrecv(fd1, fd2, send, |_, _| {}); + } + + #[test] + pub fn udp() { +- let std_sa = SocketAddr::from_str("127.0.0.1:6789").unwrap(); +- let inet_addr = InetAddr::from_std(&std_sa); +- let sock_addr = SockAddr::new_inet(inet_addr); +- let rsock = socket(AddressFamily::Inet, ++ let std_sa = SocketAddrV4::from_str("127.0.0.1:6789").unwrap(); ++ let sock_addr = SockaddrIn::from(std_sa); ++ let rsock = socket( ++ AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), +- None +- ).unwrap(); ++ None, ++ ) ++ .unwrap(); + bind(rsock, &sock_addr).unwrap(); + let ssock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, +- ).expect("send socket failed"); +- let from = sendrecv(rsock, ssock, move |s, m, flags| { +- sendto(s, m, &sock_addr, flags) +- }); ++ ) ++ .expect("send socket failed"); ++ let from = sendrecv( ++ rsock, ++ ssock, ++ move |s, m, flags| sendto(s, m, &sock_addr, flags), ++ |_, _| {}, ++ ); ++ // UDP sockets should set the from address ++ assert_eq!(AddressFamily::Inet, from.unwrap().family().unwrap()); ++ } ++ ++ #[cfg(target_os = "linux")] ++ mod udp_offload { ++ use super::*; ++ use nix::sys::socket::sockopt::{UdpGroSegment, UdpGsoSegment}; ++ use std::io::IoSlice; ++ ++ #[test] ++ // Disable the test under emulation because it fails in Cirrus-CI. Lack ++ // of QEMU support is suspected. ++ #[cfg_attr(qemu, ignore)] ++ pub fn gso() { ++ require_kernel_version!(udp_offload::gso, ">= 4.18"); ++ ++ // In this test, we send the data and provide a GSO segment size. ++ // Since we are sending the buffer of size 13, six UDP packets ++ // with size 2 and two UDP packet with size 1 will be sent. ++ let segment_size: u16 = 2; ++ ++ let sock_addr = SockaddrIn::new(127, 0, 0, 1, 6791); ++ let rsock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); ++ ++ setsockopt(rsock, UdpGsoSegment, &(segment_size as _)) ++ .expect("setsockopt UDP_SEGMENT failed"); ++ ++ bind(rsock, &sock_addr).unwrap(); ++ let ssock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("send socket failed"); ++ ++ let mut num_packets_received: i32 = 0; ++ ++ sendrecv( ++ rsock, ++ ssock, ++ move |s, m, flags| { ++ let iov = [IoSlice::new(m)]; ++ let cmsg = ControlMessage::UdpGsoSegments(&segment_size); ++ sendmsg(s, &iov, &[cmsg], flags, Some(&sock_addr)) ++ }, ++ { ++ let num_packets_received_ref = &mut num_packets_received; ++ ++ move |len, _| { ++ // check that we receive UDP packets with payload size ++ // less or equal to segment size ++ assert!(len <= segment_size as usize); ++ *num_packets_received_ref += 1; ++ } ++ }, ++ ); ++ ++ // Buffer size is 13, we will receive six packets of size 2, ++ // and one packet of size 1. ++ assert_eq!(7, num_packets_received); ++ } ++ ++ #[test] ++ // Disable the test on emulated platforms because it fails in Cirrus-CI. ++ // Lack of QEMU support is suspected. ++ #[cfg_attr(qemu, ignore)] ++ pub fn gro() { ++ require_kernel_version!(udp_offload::gro, ">= 5.3"); ++ ++ // It's hard to guarantee receiving GRO packets. Just checking ++ // that `setsockopt` doesn't fail with error ++ ++ let rsock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); ++ ++ setsockopt(rsock, UdpGroSegment, &true) ++ .expect("setsockopt UDP_GRO failed"); ++ } ++ } ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "freebsd", ++ target_os = "netbsd", ++ ))] ++ #[test] ++ pub fn udp_sendmmsg() { ++ use std::io::IoSlice; ++ ++ let std_sa = SocketAddrV4::from_str("127.0.0.1:6793").unwrap(); ++ let std_sa2 = SocketAddrV4::from_str("127.0.0.1:6794").unwrap(); ++ let sock_addr = SockaddrIn::from(std_sa); ++ let sock_addr2 = SockaddrIn::from(std_sa2); ++ ++ let rsock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); ++ bind(rsock, &sock_addr).unwrap(); ++ let ssock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("send socket failed"); ++ ++ let from = sendrecv( ++ rsock, ++ ssock, ++ move |s, m, flags| { ++ let batch_size = 15; ++ let mut iovs = Vec::with_capacity(1 + batch_size); ++ let mut addrs = Vec::with_capacity(1 + batch_size); ++ let mut data = MultiHeaders::preallocate(1 + batch_size, None); ++ let iov = IoSlice::new(m); ++ // first chunk: ++ iovs.push([iov]); ++ addrs.push(Some(sock_addr)); ++ ++ for _ in 0..batch_size { ++ iovs.push([iov]); ++ addrs.push(Some(sock_addr2)); ++ } ++ ++ let res = sendmmsg(s, &mut data, &iovs, addrs, [], flags)?; ++ let mut sent_messages = 0; ++ let mut sent_bytes = 0; ++ for item in res { ++ sent_messages += 1; ++ sent_bytes += item.bytes; ++ } ++ // ++ assert_eq!(sent_messages, iovs.len()); ++ assert_eq!(sent_bytes, sent_messages * m.len()); ++ Ok(sent_messages) ++ }, ++ |_, _| {}, ++ ); + // UDP sockets should set the from address +- assert_eq!(AddressFamily::Inet, from.unwrap().family()); ++ assert_eq!(AddressFamily::Inet, from.unwrap().family().unwrap()); ++ } ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "freebsd", ++ target_os = "netbsd", ++ ))] ++ #[test] ++ pub fn udp_recvmmsg() { ++ use nix::sys::socket::{recvmmsg, MsgFlags}; ++ use std::io::IoSliceMut; ++ ++ const NUM_MESSAGES_SENT: usize = 2; ++ const DATA: [u8; 2] = [1, 2]; ++ ++ let inet_addr = SocketAddrV4::from_str("127.0.0.1:6798").unwrap(); ++ let sock_addr = SockaddrIn::from(inet_addr); ++ ++ let rsock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); ++ bind(rsock, &sock_addr).unwrap(); ++ let ssock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("send socket failed"); ++ ++ let send_thread = thread::spawn(move || { ++ for _ in 0..NUM_MESSAGES_SENT { ++ sendto(ssock, &DATA[..], &sock_addr, MsgFlags::empty()) ++ .unwrap(); ++ } ++ }); ++ ++ let mut msgs = std::collections::LinkedList::new(); ++ ++ // Buffers to receive exactly `NUM_MESSAGES_SENT` messages ++ let mut receive_buffers = [[0u8; 32]; NUM_MESSAGES_SENT]; ++ msgs.extend( ++ receive_buffers ++ .iter_mut() ++ .map(|buf| [IoSliceMut::new(&mut buf[..])]), ++ ); ++ ++ let mut data = ++ MultiHeaders::::preallocate(msgs.len(), None); ++ ++ let res: Vec> = ++ recvmmsg(rsock, &mut data, msgs.iter(), MsgFlags::empty(), None) ++ .expect("recvmmsg") ++ .collect(); ++ assert_eq!(res.len(), DATA.len()); ++ ++ for RecvMsg { address, bytes, .. } in res.into_iter() { ++ assert_eq!(AddressFamily::Inet, address.unwrap().family().unwrap()); ++ assert_eq!(DATA.len(), bytes); ++ } ++ ++ for buf in &receive_buffers { ++ assert_eq!(&buf[..DATA.len()], DATA); ++ } ++ ++ send_thread.join().unwrap(); ++ } ++ ++ #[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "freebsd", ++ target_os = "netbsd", ++ ))] ++ #[test] ++ pub fn udp_recvmmsg_dontwait_short_read() { ++ use nix::sys::socket::{recvmmsg, MsgFlags}; ++ use std::io::IoSliceMut; ++ ++ const NUM_MESSAGES_SENT: usize = 2; ++ const DATA: [u8; 4] = [1, 2, 3, 4]; ++ ++ let inet_addr = SocketAddrV4::from_str("127.0.0.1:6799").unwrap(); ++ let sock_addr = SockaddrIn::from(inet_addr); ++ ++ let rsock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); ++ bind(rsock, &sock_addr).unwrap(); ++ let ssock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("send socket failed"); ++ ++ let send_thread = thread::spawn(move || { ++ for _ in 0..NUM_MESSAGES_SENT { ++ sendto(ssock, &DATA[..], &sock_addr, MsgFlags::empty()) ++ .unwrap(); ++ } ++ }); ++ // Ensure we've sent all the messages before continuing so `recvmmsg` ++ // will return right away ++ send_thread.join().unwrap(); ++ ++ let mut msgs = std::collections::LinkedList::new(); ++ ++ // Buffers to receive >`NUM_MESSAGES_SENT` messages to ensure `recvmmsg` ++ // will return when there are fewer than requested messages in the ++ // kernel buffers when using `MSG_DONTWAIT`. ++ let mut receive_buffers = [[0u8; 32]; NUM_MESSAGES_SENT + 2]; ++ msgs.extend( ++ receive_buffers ++ .iter_mut() ++ .map(|buf| [IoSliceMut::new(&mut buf[..])]), ++ ); ++ ++ let mut data = MultiHeaders::::preallocate( ++ NUM_MESSAGES_SENT + 2, ++ None, ++ ); ++ ++ let res: Vec> = recvmmsg( ++ rsock, ++ &mut data, ++ msgs.iter(), ++ MsgFlags::MSG_DONTWAIT, ++ None, ++ ) ++ .expect("recvmmsg") ++ .collect(); ++ assert_eq!(res.len(), NUM_MESSAGES_SENT); ++ ++ for RecvMsg { address, bytes, .. } in res.into_iter() { ++ assert_eq!(AddressFamily::Inet, address.unwrap().family().unwrap()); ++ assert_eq!(DATA.len(), bytes); ++ } ++ ++ for buf in &receive_buffers[..NUM_MESSAGES_SENT] { ++ assert_eq!(&buf[..DATA.len()], DATA); ++ } ++ } ++ ++ #[test] ++ pub fn udp_inet6() { ++ let addr = std::net::Ipv6Addr::from_str("::1").unwrap(); ++ let rport = 6789; ++ let rstd_sa = SocketAddrV6::new(addr, rport, 0, 0); ++ let raddr = SockaddrIn6::from(rstd_sa); ++ let sport = 6790; ++ let sstd_sa = SocketAddrV6::new(addr, sport, 0, 0); ++ let saddr = SockaddrIn6::from(sstd_sa); ++ let rsock = socket( ++ AddressFamily::Inet6, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("receive socket failed"); ++ match bind(rsock, &raddr) { ++ Err(Errno::EADDRNOTAVAIL) => { ++ println!("IPv6 not available, skipping test."); ++ return; ++ } ++ Err(e) => panic!("bind: {}", e), ++ Ok(()) => (), ++ } ++ let ssock = socket( ++ AddressFamily::Inet6, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("send socket failed"); ++ bind(ssock, &saddr).unwrap(); ++ let from = sendrecv( ++ rsock, ++ ssock, ++ move |s, m, flags| sendto(s, m, &raddr, flags), ++ |_, _| {}, ++ ); ++ assert_eq!(AddressFamily::Inet6, from.unwrap().family().unwrap()); ++ let osent_addr = from.unwrap(); ++ let sent_addr = osent_addr.as_sockaddr_in6().unwrap(); ++ assert_eq!(sent_addr.ip(), addr); ++ assert_eq!(sent_addr.port(), sport); + } + } + + // Test error handling of our recvmsg wrapper + #[test] + pub fn test_recvmsg_ebadf() { +- use nix::Error; + use nix::errno::Errno; +- use nix::sys::socket::{MsgFlags, recvmsg}; +- use nix::sys::uio::IoVec; ++ use nix::sys::socket::{recvmsg, MsgFlags}; ++ use std::io::IoSliceMut; + + let mut buf = [0u8; 5]; +- let iov = [IoVec::from_mut_slice(&mut buf[..])]; +- let fd = -1; // Bad file descriptor +- let r = recvmsg(fd, &iov, None, MsgFlags::empty()); +- assert_eq!(r.err().unwrap(), Error::Sys(Errno::EBADF)); ++ let mut iov = [IoSliceMut::new(&mut buf[..])]; ++ ++ let fd = -1; // Bad file descriptor ++ let r = recvmsg::<()>(fd, &mut iov, None, MsgFlags::empty()); ++ ++ assert_eq!(r.err().unwrap(), Errno::EBADF); + } + + // Disable the test on emulated platforms due to a bug in QEMU versions < + // 2.12.0. https://bugs.launchpad.net/qemu/+bug/1701808 +-#[cfg_attr(not(any(target_arch = "x86_64", target_arch="i686")), ignore)] ++#[cfg_attr(qemu, ignore)] + #[test] + pub fn test_scm_rights() { +- use nix::sys::uio::IoVec; +- use nix::unistd::{pipe, read, write, close}; +- use nix::sys::socket::{socketpair, sendmsg, recvmsg, +- AddressFamily, SockType, SockFlag, +- ControlMessage, ControlMessageOwned, MsgFlags}; +- +- let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()) +- .unwrap(); ++ use nix::sys::socket::{ ++ recvmsg, sendmsg, socketpair, AddressFamily, ControlMessage, ++ ControlMessageOwned, MsgFlags, SockFlag, SockType, ++ }; ++ use nix::unistd::{close, pipe, read, write}; ++ use std::io::{IoSlice, IoSliceMut}; ++ ++ let (fd1, fd2) = socketpair( ++ AddressFamily::Unix, ++ SockType::Stream, ++ None, ++ SockFlag::empty(), ++ ) ++ .unwrap(); + let (r, w) = pipe().unwrap(); + let mut received_r: Option = None; + + { +- let iov = [IoVec::from_slice(b"hello")]; ++ let iov = [IoSlice::new(b"hello")]; + let fds = [r]; + let cmsg = ControlMessage::ScmRights(&fds); +- assert_eq!(sendmsg(fd1, &iov, &[cmsg], MsgFlags::empty(), None).unwrap(), 5); ++ assert_eq!( ++ sendmsg::<()>(fd1, &iov, &[cmsg], MsgFlags::empty(), None).unwrap(), ++ 5 ++ ); + close(r).unwrap(); + close(fd1).unwrap(); + } + + { + let mut buf = [0u8; 5]; +- let iov = [IoVec::from_mut_slice(&mut buf[..])]; ++ ++ let mut iov = [IoSliceMut::new(&mut buf[..])]; + let mut cmsgspace = cmsg_space!([RawFd; 1]); +- let msg = recvmsg(fd2, &iov, Some(&mut cmsgspace), MsgFlags::empty()).unwrap(); ++ let msg = recvmsg::<()>( ++ fd2, ++ &mut iov, ++ Some(&mut cmsgspace), ++ MsgFlags::empty(), ++ ) ++ .unwrap(); + + for cmsg in msg.cmsgs() { + if let ControlMessageOwned::ScmRights(fd) = cmsg { +@@ -284,7 +820,9 @@ pub fn test_scm_rights() { + } + } + assert_eq!(msg.bytes, 5); +- assert!(!msg.flags.intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); ++ assert!(!msg ++ .flags ++ .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); + close(fd2).unwrap(); + } + +@@ -299,24 +837,25 @@ pub fn test_scm_rights() { + } + + // Disable the test on emulated platforms due to not enabled support of AF_ALG in QEMU from rust cross +-#[cfg_attr(not(any(target_arch = "x86_64", target_arch = "i686")), ignore)] +-#[cfg(any(target_os = "linux", target_os= "android"))] ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[cfg_attr(qemu, ignore)] + #[test] + pub fn test_af_alg_cipher() { +- use libc; +- use nix::sys::uio::IoVec; +- use nix::unistd::read; +- use nix::sys::socket::{socket, sendmsg, bind, accept, setsockopt, +- AddressFamily, SockType, SockFlag, SockAddr, +- ControlMessage, MsgFlags}; + use nix::sys::socket::sockopt::AlgSetKey; ++ use nix::sys::socket::{ ++ accept, bind, sendmsg, setsockopt, socket, AddressFamily, AlgAddr, ++ ControlMessage, MsgFlags, SockFlag, SockType, ++ }; ++ use nix::unistd::read; ++ use std::io::IoSlice; + ++ skip_if_cirrus!("Fails for an unknown reason Cirrus CI. Bug #1352"); + // Travis's seccomp profile blocks AF_ALG + // https://docs.docker.com/engine/security/seccomp/ + skip_if_seccomp!(test_af_alg_cipher); + + let alg_type = "skcipher"; +- let alg_name = "ctr(aes)"; ++ let alg_name = "ctr-aes-aesni"; + // 256-bits secret key + let key = vec![0u8; 32]; + // 16-bytes IV +@@ -326,37 +865,46 @@ pub fn test_af_alg_cipher() { + let payload_len = 256; + let payload = vec![2u8; payload_len]; + +- let sock = socket(AddressFamily::Alg, SockType::SeqPacket, SockFlag::empty(), None) +- .expect("socket failed"); ++ let sock = socket( ++ AddressFamily::Alg, ++ SockType::SeqPacket, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("socket failed"); + +- let sockaddr = SockAddr::new_alg(alg_type, alg_name); ++ let sockaddr = AlgAddr::new(alg_type, alg_name); + bind(sock, &sockaddr).expect("bind failed"); + +- if let SockAddr::Alg(alg) = sockaddr { +- assert_eq!(alg.alg_name().to_string_lossy(), alg_name); +- assert_eq!(alg.alg_type().to_string_lossy(), alg_type); +- } else { +- panic!("unexpected SockAddr"); +- } ++ assert_eq!(sockaddr.alg_name().to_string_lossy(), alg_name); ++ assert_eq!(sockaddr.alg_type().to_string_lossy(), alg_type); + + setsockopt(sock, AlgSetKey::default(), &key).expect("setsockopt"); + let session_socket = accept(sock).expect("accept failed"); + +- let msgs = [ControlMessage::AlgSetOp(&libc::ALG_OP_ENCRYPT), ControlMessage::AlgSetIv(iv.as_slice())]; +- let iov = IoVec::from_slice(&payload); +- sendmsg(session_socket, &[iov], &msgs, MsgFlags::empty(), None).expect("sendmsg encrypt"); ++ let msgs = [ ++ ControlMessage::AlgSetOp(&libc::ALG_OP_ENCRYPT), ++ ControlMessage::AlgSetIv(iv.as_slice()), ++ ]; ++ let iov = IoSlice::new(&payload); ++ sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None) ++ .expect("sendmsg encrypt"); + + // allocate buffer for encrypted data + let mut encrypted = vec![0u8; payload_len]; + let num_bytes = read(session_socket, &mut encrypted).expect("read encrypt"); + assert_eq!(num_bytes, payload_len); + +- let iov = IoVec::from_slice(&encrypted); ++ let iov = IoSlice::new(&encrypted); + + let iv = vec![1u8; iv_len]; + +- let msgs = [ControlMessage::AlgSetOp(&libc::ALG_OP_DECRYPT), ControlMessage::AlgSetIv(iv.as_slice())]; +- sendmsg(session_socket, &[iov], &msgs, MsgFlags::empty(), None).expect("sendmsg decrypt"); ++ let msgs = [ ++ ControlMessage::AlgSetOp(&libc::ALG_OP_DECRYPT), ++ ControlMessage::AlgSetIv(iv.as_slice()), ++ ]; ++ sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None) ++ .expect("sendmsg decrypt"); + + // allocate buffer for decrypted data + let mut decrypted = vec![0u8; payload_len]; +@@ -366,19 +914,23 @@ pub fn test_af_alg_cipher() { + assert_eq!(decrypted, payload); + } + +-// Disable the test on emulated platforms due to not enabled support of AF_ALG in QEMU from rust cross +-#[cfg_attr(not(any(target_arch = "x86_64", target_arch = "i686")), ignore)] +-#[cfg(any(target_os = "linux", target_os= "android"))] ++// Disable the test on emulated platforms due to not enabled support of AF_ALG ++// in QEMU from rust cross ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[cfg_attr(qemu, ignore)] + #[test] + pub fn test_af_alg_aead() { + use libc::{ALG_OP_DECRYPT, ALG_OP_ENCRYPT}; +- use nix::sys::uio::IoVec; +- use nix::unistd::{read, close}; +- use nix::sys::socket::{socket, sendmsg, bind, accept, setsockopt, +- AddressFamily, SockType, SockFlag, SockAddr, +- ControlMessage, MsgFlags}; +- use nix::sys::socket::sockopt::{AlgSetKey, AlgSetAeadAuthSize}; ++ use nix::fcntl::{fcntl, FcntlArg, OFlag}; ++ use nix::sys::socket::sockopt::{AlgSetAeadAuthSize, AlgSetKey}; ++ use nix::sys::socket::{ ++ accept, bind, sendmsg, setsockopt, socket, AddressFamily, AlgAddr, ++ ControlMessage, MsgFlags, SockFlag, SockType, ++ }; ++ use nix::unistd::{close, read}; ++ use std::io::IoSlice; + ++ skip_if_cirrus!("Fails for an unknown reason Cirrus CI. Bug #1352"); + // Travis's seccomp profile blocks AF_ALG + // https://docs.docker.com/engine/security/seccomp/ + skip_if_seccomp!(test_af_alg_aead); +@@ -395,7 +947,8 @@ pub fn test_af_alg_aead() { + let iv = vec![1u8; iv_len]; + // 256-bytes plain payload + let payload_len = 256; +- let mut payload = vec![2u8; payload_len + (assoc_size as usize) + auth_size]; ++ let mut payload = ++ vec![2u8; payload_len + (assoc_size as usize) + auth_size]; + + for i in 0..assoc_size { + payload[i as usize] = 10; +@@ -407,25 +960,35 @@ pub fn test_af_alg_aead() { + payload[len - 1 - i] = 0; + } + +- let sock = socket(AddressFamily::Alg, SockType::SeqPacket, SockFlag::empty(), None) +- .expect("socket failed"); ++ let sock = socket( ++ AddressFamily::Alg, ++ SockType::SeqPacket, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("socket failed"); + +- let sockaddr = SockAddr::new_alg(alg_type, alg_name); ++ let sockaddr = AlgAddr::new(alg_type, alg_name); + bind(sock, &sockaddr).expect("bind failed"); + +- setsockopt(sock, AlgSetAeadAuthSize, &auth_size).expect("setsockopt AlgSetAeadAuthSize"); ++ setsockopt(sock, AlgSetAeadAuthSize, &auth_size) ++ .expect("setsockopt AlgSetAeadAuthSize"); + setsockopt(sock, AlgSetKey::default(), &key).expect("setsockopt AlgSetKey"); + let session_socket = accept(sock).expect("accept failed"); + + let msgs = [ + ControlMessage::AlgSetOp(&ALG_OP_ENCRYPT), + ControlMessage::AlgSetIv(iv.as_slice()), +- ControlMessage::AlgSetAeadAssoclen(&assoc_size)]; +- let iov = IoVec::from_slice(&payload); +- sendmsg(session_socket, &[iov], &msgs, MsgFlags::empty(), None).expect("sendmsg encrypt"); ++ ControlMessage::AlgSetAeadAssoclen(&assoc_size), ++ ]; ++ ++ let iov = IoSlice::new(&payload); ++ sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None) ++ .expect("sendmsg encrypt"); + + // allocate buffer for encrypted data +- let mut encrypted = vec![0u8; (assoc_size as usize) + payload_len + auth_size]; ++ let mut encrypted = ++ vec![0u8; (assoc_size as usize) + payload_len + auth_size]; + let num_bytes = read(session_socket, &mut encrypted).expect("read encrypt"); + assert_eq!(num_bytes, payload_len + auth_size + (assoc_size as usize)); + close(session_socket).expect("close"); +@@ -434,7 +997,7 @@ pub fn test_af_alg_aead() { + encrypted[i as usize] = 10; + } + +- let iov = IoVec::from_slice(&encrypted); ++ let iov = IoSlice::new(&encrypted); + + let iv = vec![1u8; iv_len]; + +@@ -445,149 +1008,379 @@ pub fn test_af_alg_aead() { + ControlMessage::AlgSetIv(iv.as_slice()), + ControlMessage::AlgSetAeadAssoclen(&assoc_size), + ]; +- sendmsg(session_socket, &[iov], &msgs, MsgFlags::empty(), None).expect("sendmsg decrypt"); ++ sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None) ++ .expect("sendmsg decrypt"); + + // allocate buffer for decrypted data +- let mut decrypted = vec![0u8; payload_len + (assoc_size as usize) + auth_size]; ++ let mut decrypted = ++ vec![0u8; payload_len + (assoc_size as usize) + auth_size]; ++ // Starting with kernel 4.9, the interface changed slightly such that the ++ // authentication tag memory is only needed in the output buffer for encryption ++ // and in the input buffer for decryption. ++ // Do not block on read, as we may have fewer bytes than buffer size ++ fcntl(session_socket, FcntlArg::F_SETFL(OFlag::O_NONBLOCK)) ++ .expect("fcntl non_blocking"); + let num_bytes = read(session_socket, &mut decrypted).expect("read decrypt"); + + assert!(num_bytes >= payload_len + (assoc_size as usize)); +- assert_eq!(decrypted[(assoc_size as usize)..(payload_len + (assoc_size as usize))], payload[(assoc_size as usize)..payload_len + (assoc_size as usize)]); ++ assert_eq!( ++ decrypted[(assoc_size as usize)..(payload_len + (assoc_size as usize))], ++ payload[(assoc_size as usize)..payload_len + (assoc_size as usize)] ++ ); + } + +-/// Tests that passing multiple fds using a single `ControlMessage` works. +-// Disable the test on emulated platforms due to a bug in QEMU versions < +-// 2.12.0. https://bugs.launchpad.net/qemu/+bug/1701808 +-#[cfg_attr(not(any(target_arch = "x86_64", target_arch="i686")), ignore)] ++// Verify `ControlMessage::Ipv4PacketInfo` for `sendmsg`. ++// This creates a (udp) socket bound to localhost, then sends a message to ++// itself but uses Ipv4PacketInfo to force the source address to be localhost. ++// ++// This would be a more interesting test if we could assume that the test host ++// has more than one IP address (since we could select a different address to ++// test from). ++#[cfg(any(target_os = "linux", target_os = "macos", target_os = "netbsd"))] + #[test] +-fn test_scm_rights_single_cmsg_multiple_fds() { +- use std::os::unix::net::UnixDatagram; +- use std::os::unix::io::{RawFd, AsRawFd}; +- use std::thread; +- use nix::sys::socket::{ControlMessage, ControlMessageOwned, MsgFlags, +- sendmsg, recvmsg}; +- use nix::sys::uio::IoVec; +- use libc; ++pub fn test_sendmsg_ipv4packetinfo() { ++ use cfg_if::cfg_if; ++ use nix::sys::socket::{ ++ bind, sendmsg, socket, AddressFamily, ControlMessage, MsgFlags, ++ SockFlag, SockType, SockaddrIn, ++ }; ++ use std::io::IoSlice; + +- let (send, receive) = UnixDatagram::pair().unwrap(); +- let thread = thread::spawn(move || { +- let mut buf = [0u8; 8]; +- let iovec = [IoVec::from_mut_slice(&mut buf)]; +- let mut space = cmsg_space!([RawFd; 2]); +- let msg = recvmsg( +- receive.as_raw_fd(), +- &iovec, +- Some(&mut space), +- MsgFlags::empty() +- ).unwrap(); +- assert!(!msg.flags.intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); ++ let sock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("socket failed"); + +- let mut cmsgs = msg.cmsgs(); +- match cmsgs.next() { +- Some(ControlMessageOwned::ScmRights(fds)) => { +- assert_eq!(fds.len(), 2, +- "unexpected fd count (expected 2 fds, got {})", +- fds.len()); +- }, +- _ => panic!(), +- } +- assert!(cmsgs.next().is_none(), "unexpected control msg"); ++ let sock_addr = SockaddrIn::new(127, 0, 0, 1, 4000); + +- assert_eq!(msg.bytes, 8); +- assert_eq!(iovec[0].as_slice(), [1u8, 2, 3, 4, 5, 6, 7, 8]); +- }); ++ bind(sock, &sock_addr).expect("bind failed"); + + let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; +- let iov = [IoVec::from_slice(&slice)]; +- let fds = [libc::STDIN_FILENO, libc::STDOUT_FILENO]; // pass stdin and stdout +- let cmsg = [ControlMessage::ScmRights(&fds)]; +- sendmsg(send.as_raw_fd(), &iov, &cmsg, MsgFlags::empty(), None).unwrap(); +- thread.join().unwrap(); ++ let iov = [IoSlice::new(&slice)]; ++ ++ cfg_if! { ++ if #[cfg(target_os = "netbsd")] { ++ let pi = libc::in_pktinfo { ++ ipi_ifindex: 0, /* Unspecified interface */ ++ ipi_addr: libc::in_addr { s_addr: 0 }, ++ }; ++ } else { ++ let pi = libc::in_pktinfo { ++ ipi_ifindex: 0, /* Unspecified interface */ ++ ipi_addr: libc::in_addr { s_addr: 0 }, ++ ipi_spec_dst: sock_addr.as_ref().sin_addr, ++ }; ++ } ++ } ++ ++ let cmsg = [ControlMessage::Ipv4PacketInfo(&pi)]; ++ ++ sendmsg(sock, &iov, &cmsg, MsgFlags::empty(), Some(&sock_addr)) ++ .expect("sendmsg"); + } + +-// Verify `sendmsg` builds a valid `msghdr` when passing an empty +-// `cmsgs` argument. This should result in a msghdr with a nullptr +-// msg_control field and a msg_controllen of 0 when calling into the +-// raw `sendmsg`. ++// Verify `ControlMessage::Ipv6PacketInfo` for `sendmsg`. ++// This creates a (udp) socket bound to ip6-localhost, then sends a message to ++// itself but uses Ipv6PacketInfo to force the source address to be ++// ip6-localhost. ++// ++// This would be a more interesting test if we could assume that the test host ++// has more than one IP address (since we could select a different address to ++// test from). ++#[cfg(any( ++ target_os = "linux", ++ target_os = "macos", ++ target_os = "netbsd", ++ target_os = "freebsd" ++))] + #[test] +-pub fn test_sendmsg_empty_cmsgs() { +- use nix::sys::uio::IoVec; +- use nix::unistd::close; +- use nix::sys::socket::{socketpair, sendmsg, recvmsg, +- AddressFamily, SockType, SockFlag, MsgFlags}; ++pub fn test_sendmsg_ipv6packetinfo() { ++ use nix::errno::Errno; ++ use nix::sys::socket::{ ++ bind, sendmsg, socket, AddressFamily, ControlMessage, MsgFlags, ++ SockFlag, SockType, SockaddrIn6, ++ }; ++ use std::io::IoSlice; + +- let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()) +- .unwrap(); ++ let sock = socket( ++ AddressFamily::Inet6, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("socket failed"); ++ ++ let std_sa = SocketAddrV6::from_str("[::1]:6000").unwrap(); ++ let sock_addr: SockaddrIn6 = SockaddrIn6::from(std_sa); ++ ++ if let Err(Errno::EADDRNOTAVAIL) = bind(sock, &sock_addr) { ++ println!("IPv6 not available, skipping test."); ++ return; ++ } ++ ++ let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; ++ let iov = [IoSlice::new(&slice)]; ++ ++ let pi = libc::in6_pktinfo { ++ ipi6_ifindex: 0, /* Unspecified interface */ ++ ipi6_addr: sock_addr.as_ref().sin6_addr, ++ }; ++ ++ let cmsg = [ControlMessage::Ipv6PacketInfo(&pi)]; ++ ++ sendmsg::( ++ sock, ++ &iov, ++ &cmsg, ++ MsgFlags::empty(), ++ Some(&sock_addr), ++ ) ++ .expect("sendmsg"); ++} ++ ++// Verify that ControlMessage::Ipv4SendSrcAddr works for sendmsg. This ++// creates a UDP socket bound to all local interfaces (0.0.0.0). It then ++// sends message to itself at 127.0.0.1 while explicitly specifying ++// 127.0.0.1 as the source address through an Ipv4SendSrcAddr ++// (IP_SENDSRCADDR) control message. ++// ++// Note that binding to 0.0.0.0 is *required* on FreeBSD; sendmsg ++// returns EINVAL otherwise. (See FreeBSD's ip(4) man page.) ++#[cfg(any( ++ target_os = "netbsd", ++ target_os = "freebsd", ++ target_os = "openbsd", ++ target_os = "dragonfly", ++))] ++#[test] ++pub fn test_sendmsg_ipv4sendsrcaddr() { ++ use nix::sys::socket::{ ++ bind, sendmsg, socket, AddressFamily, ControlMessage, MsgFlags, ++ SockFlag, SockType, SockaddrIn, ++ }; ++ use std::io::IoSlice; ++ ++ let sock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("socket failed"); ++ ++ let unspec_sock_addr = SockaddrIn::new(0, 0, 0, 0, 0); ++ bind(sock, &unspec_sock_addr).expect("bind failed"); ++ let bound_sock_addr: SockaddrIn = getsockname(sock).unwrap(); ++ let localhost_sock_addr: SockaddrIn = ++ SockaddrIn::new(127, 0, 0, 1, bound_sock_addr.port()); ++ ++ let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; ++ let iov = [IoSlice::new(&slice)]; ++ let cmsg = [ControlMessage::Ipv4SendSrcAddr( ++ &localhost_sock_addr.as_ref().sin_addr, ++ )]; ++ ++ sendmsg( ++ sock, ++ &iov, ++ &cmsg, ++ MsgFlags::empty(), ++ Some(&localhost_sock_addr), ++ ) ++ .expect("sendmsg"); ++} ++ ++/// Tests that passing multiple fds using a single `ControlMessage` works. ++// Disable the test on emulated platforms due to a bug in QEMU versions < ++// 2.12.0. https://bugs.launchpad.net/qemu/+bug/1701808 ++#[cfg_attr(qemu, ignore)] ++#[test] ++fn test_scm_rights_single_cmsg_multiple_fds() { ++ use nix::sys::socket::{ ++ recvmsg, sendmsg, ControlMessage, ControlMessageOwned, MsgFlags, ++ }; ++ use std::io::{IoSlice, IoSliceMut}; ++ use std::os::unix::io::{AsRawFd, RawFd}; ++ use std::os::unix::net::UnixDatagram; ++ use std::thread; ++ ++ let (send, receive) = UnixDatagram::pair().unwrap(); ++ let thread = thread::spawn(move || { ++ let mut buf = [0u8; 8]; ++ let mut iovec = [IoSliceMut::new(&mut buf)]; ++ ++ let mut space = cmsg_space!([RawFd; 2]); ++ let msg = recvmsg::<()>( ++ receive.as_raw_fd(), ++ &mut iovec, ++ Some(&mut space), ++ MsgFlags::empty(), ++ ) ++ .unwrap(); ++ assert!(!msg ++ .flags ++ .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); ++ ++ let mut cmsgs = msg.cmsgs(); ++ match cmsgs.next() { ++ Some(ControlMessageOwned::ScmRights(fds)) => { ++ assert_eq!( ++ fds.len(), ++ 2, ++ "unexpected fd count (expected 2 fds, got {})", ++ fds.len() ++ ); ++ } ++ _ => panic!(), ++ } ++ assert!(cmsgs.next().is_none(), "unexpected control msg"); ++ ++ assert_eq!(msg.bytes, 8); ++ assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]); ++ }); ++ ++ let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; ++ let iov = [IoSlice::new(&slice)]; ++ let fds = [libc::STDIN_FILENO, libc::STDOUT_FILENO]; // pass stdin and stdout ++ let cmsg = [ControlMessage::ScmRights(&fds)]; ++ sendmsg::<()>(send.as_raw_fd(), &iov, &cmsg, MsgFlags::empty(), None) ++ .unwrap(); ++ thread.join().unwrap(); ++} ++ ++// Verify `sendmsg` builds a valid `msghdr` when passing an empty ++// `cmsgs` argument. This should result in a msghdr with a nullptr ++// msg_control field and a msg_controllen of 0 when calling into the ++// raw `sendmsg`. ++#[test] ++pub fn test_sendmsg_empty_cmsgs() { ++ use nix::sys::socket::{ ++ recvmsg, sendmsg, socketpair, AddressFamily, MsgFlags, SockFlag, ++ SockType, ++ }; ++ use nix::unistd::close; ++ use std::io::{IoSlice, IoSliceMut}; ++ ++ let (fd1, fd2) = socketpair( ++ AddressFamily::Unix, ++ SockType::Stream, ++ None, ++ SockFlag::empty(), ++ ) ++ .unwrap(); + + { +- let iov = [IoVec::from_slice(b"hello")]; +- assert_eq!(sendmsg(fd1, &iov, &[], MsgFlags::empty(), None).unwrap(), 5); ++ let iov = [IoSlice::new(b"hello")]; ++ assert_eq!( ++ sendmsg::<()>(fd1, &iov, &[], MsgFlags::empty(), None).unwrap(), ++ 5 ++ ); + close(fd1).unwrap(); + } + + { + let mut buf = [0u8; 5]; +- let iov = [IoVec::from_mut_slice(&mut buf[..])]; ++ let mut iov = [IoSliceMut::new(&mut buf[..])]; ++ + let mut cmsgspace = cmsg_space!([RawFd; 1]); +- let msg = recvmsg(fd2, &iov, Some(&mut cmsgspace), MsgFlags::empty()).unwrap(); ++ let msg = recvmsg::<()>( ++ fd2, ++ &mut iov, ++ Some(&mut cmsgspace), ++ MsgFlags::empty(), ++ ) ++ .unwrap(); + + for _ in msg.cmsgs() { + panic!("unexpected cmsg"); + } +- assert!(!msg.flags.intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); ++ assert!(!msg ++ .flags ++ .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); + assert_eq!(msg.bytes, 5); + close(fd2).unwrap(); + } + } + +-#[cfg(any(target_os = "android", target_os = "linux"))] ++#[cfg(any( ++ target_os = "android", ++ target_os = "linux", ++ target_os = "freebsd", ++ target_os = "dragonfly", ++))] + #[test] + fn test_scm_credentials() { +- use libc; +- use nix::sys::uio::IoVec; +- use nix::unistd::{close, getpid, getuid, getgid}; +- use nix::sys::socket::{socketpair, sendmsg, recvmsg, setsockopt, +- AddressFamily, SockType, SockFlag, +- ControlMessage, ControlMessageOwned, MsgFlags}; +- use nix::sys::socket::sockopt::PassCred; +- +- let (send, recv) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()) +- .unwrap(); ++ use nix::sys::socket::{ ++ recvmsg, sendmsg, socketpair, AddressFamily, ControlMessage, ++ ControlMessageOwned, MsgFlags, SockFlag, SockType, UnixCredentials, ++ }; ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ use nix::sys::socket::{setsockopt, sockopt::PassCred}; ++ use nix::unistd::{close, getgid, getpid, getuid}; ++ use std::io::{IoSlice, IoSliceMut}; ++ ++ let (send, recv) = socketpair( ++ AddressFamily::Unix, ++ SockType::Stream, ++ None, ++ SockFlag::empty(), ++ ) ++ .unwrap(); ++ #[cfg(any(target_os = "android", target_os = "linux"))] + setsockopt(recv, PassCred, &true).unwrap(); + + { +- let iov = [IoVec::from_slice(b"hello")]; +- let cred = libc::ucred { +- pid: getpid().as_raw(), +- uid: getuid().as_raw(), +- gid: getgid().as_raw(), +- }.into(); ++ let iov = [IoSlice::new(b"hello")]; ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ let cred = UnixCredentials::new(); ++ #[cfg(any(target_os = "android", target_os = "linux"))] + let cmsg = ControlMessage::ScmCredentials(&cred); +- assert_eq!(sendmsg(send, &iov, &[cmsg], MsgFlags::empty(), None).unwrap(), 5); ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ let cmsg = ControlMessage::ScmCreds; ++ assert_eq!( ++ sendmsg::<()>(send, &iov, &[cmsg], MsgFlags::empty(), None) ++ .unwrap(), ++ 5 ++ ); + close(send).unwrap(); + } + + { + let mut buf = [0u8; 5]; +- let iov = [IoVec::from_mut_slice(&mut buf[..])]; +- let mut cmsgspace = cmsg_space!(libc::ucred); +- let msg = recvmsg(recv, &iov, Some(&mut cmsgspace), MsgFlags::empty()).unwrap(); ++ let mut iov = [IoSliceMut::new(&mut buf[..])]; ++ ++ let mut cmsgspace = cmsg_space!(UnixCredentials); ++ let msg = recvmsg::<()>( ++ recv, ++ &mut iov, ++ Some(&mut cmsgspace), ++ MsgFlags::empty(), ++ ) ++ .unwrap(); + let mut received_cred = None; + + for cmsg in msg.cmsgs() { +- if let ControlMessageOwned::ScmCredentials(cred) = cmsg { +- assert!(received_cred.is_none()); +- assert_eq!(cred.pid(), getpid().as_raw()); +- assert_eq!(cred.uid(), getuid().as_raw()); +- assert_eq!(cred.gid(), getgid().as_raw()); +- received_cred = Some(cred); +- } else { +- panic!("unexpected cmsg"); +- } ++ let cred = match cmsg { ++ #[cfg(any(target_os = "android", target_os = "linux"))] ++ ControlMessageOwned::ScmCredentials(cred) => cred, ++ #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] ++ ControlMessageOwned::ScmCreds(cred) => cred, ++ other => panic!("unexpected cmsg {:?}", other), ++ }; ++ assert!(received_cred.is_none()); ++ assert_eq!(cred.pid(), getpid().as_raw()); ++ assert_eq!(cred.uid(), getuid().as_raw()); ++ assert_eq!(cred.gid(), getgid().as_raw()); ++ received_cred = Some(cred); + } + received_cred.expect("no creds received"); + assert_eq!(msg.bytes, 5); +- assert!(!msg.flags.intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); ++ assert!(!msg ++ .flags ++ .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); + close(recv).unwrap(); + } + } +@@ -595,13 +1388,11 @@ fn test_scm_credentials() { + /// Ensure that we can send `SCM_CREDENTIALS` and `SCM_RIGHTS` with a single + /// `sendmsg` call. + #[cfg(any(target_os = "android", target_os = "linux"))] +-// qemu's handling of multiple cmsgs is bugged, ignore tests on non-x86 ++// qemu's handling of multiple cmsgs is bugged, ignore tests under emulation + // see https://bugs.launchpad.net/qemu/+bug/1781280 +-#[cfg_attr(not(any(target_arch = "x86_64", target_arch = "x86")), ignore)] ++#[cfg_attr(qemu, ignore)] + #[test] + fn test_scm_credentials_and_rights() { +- use libc; +- + let space = cmsg_space!(libc::ucred, RawFd); + test_impl_scm_credentials_and_rights(space); + } +@@ -609,9 +1400,9 @@ fn test_scm_credentials_and_rights() { + /// Ensure that passing a an oversized control message buffer to recvmsg + /// still works. + #[cfg(any(target_os = "android", target_os = "linux"))] +-// qemu's handling of multiple cmsgs is bugged, ignore tests on non-x86 ++// qemu's handling of multiple cmsgs is bugged, ignore tests under emulation + // see https://bugs.launchpad.net/qemu/+bug/1781280 +-#[cfg_attr(not(any(target_arch = "x86_64", target_arch = "x86")), ignore)] ++#[cfg_attr(qemu, ignore)] + #[test] + fn test_too_large_cmsgspace() { + let space = vec![0u8; 1024]; +@@ -621,41 +1412,53 @@ fn test_too_large_cmsgspace() { + #[cfg(any(target_os = "android", target_os = "linux"))] + fn test_impl_scm_credentials_and_rights(mut space: Vec) { + use libc::ucred; +- use nix::sys::uio::IoVec; +- use nix::unistd::{pipe, read, write, close, getpid, getuid, getgid}; +- use nix::sys::socket::{socketpair, sendmsg, recvmsg, setsockopt, +- SockType, SockFlag, +- ControlMessage, ControlMessageOwned, MsgFlags}; + use nix::sys::socket::sockopt::PassCred; ++ use nix::sys::socket::{ ++ recvmsg, sendmsg, setsockopt, socketpair, ControlMessage, ++ ControlMessageOwned, MsgFlags, SockFlag, SockType, ++ }; ++ use nix::unistd::{close, getgid, getpid, getuid, pipe, write}; ++ use std::io::{IoSlice, IoSliceMut}; + +- let (send, recv) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()) +- .unwrap(); ++ let (send, recv) = socketpair( ++ AddressFamily::Unix, ++ SockType::Stream, ++ None, ++ SockFlag::empty(), ++ ) ++ .unwrap(); + setsockopt(recv, PassCred, &true).unwrap(); + + let (r, w) = pipe().unwrap(); + let mut received_r: Option = None; + + { +- let iov = [IoVec::from_slice(b"hello")]; ++ let iov = [IoSlice::new(b"hello")]; + let cred = ucred { + pid: getpid().as_raw(), + uid: getuid().as_raw(), + gid: getgid().as_raw(), +- }.into(); ++ } ++ .into(); + let fds = [r]; + let cmsgs = [ + ControlMessage::ScmCredentials(&cred), + ControlMessage::ScmRights(&fds), + ]; +- assert_eq!(sendmsg(send, &iov, &cmsgs, MsgFlags::empty(), None).unwrap(), 5); ++ assert_eq!( ++ sendmsg::<()>(send, &iov, &cmsgs, MsgFlags::empty(), None).unwrap(), ++ 5 ++ ); + close(r).unwrap(); + close(send).unwrap(); + } + + { + let mut buf = [0u8; 5]; +- let iov = [IoVec::from_mut_slice(&mut buf[..])]; +- let msg = recvmsg(recv, &iov, Some(&mut space), MsgFlags::empty()).unwrap(); ++ let mut iov = [IoSliceMut::new(&mut buf[..])]; ++ let msg = ++ recvmsg::<()>(recv, &mut iov, Some(&mut space), MsgFlags::empty()) ++ .unwrap(); + let mut received_cred = None; + + assert_eq!(msg.cmsgs().count(), 2, "expected 2 cmsgs"); +@@ -679,7 +1482,9 @@ fn test_impl_scm_credentials_and_rights(mut space: Vec) { + } + received_cred.expect("no creds received"); + assert_eq!(msg.bytes, 5); +- assert!(!msg.flags.intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); ++ assert!(!msg ++ .flags ++ .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); + close(recv).unwrap(); + } + +@@ -695,23 +1500,33 @@ fn test_impl_scm_credentials_and_rights(mut space: Vec) { + + // Test creating and using named unix domain sockets + #[test] +-pub fn test_unixdomain() { +- use nix::sys::socket::{SockType, SockFlag}; +- use nix::sys::socket::{bind, socket, connect, listen, accept, SockAddr}; +- use nix::unistd::{read, write, close}; ++pub fn test_named_unixdomain() { ++ use nix::sys::socket::{accept, bind, connect, listen, socket, UnixAddr}; ++ use nix::sys::socket::{SockFlag, SockType}; ++ use nix::unistd::{close, read, write}; + use std::thread; + + let tempdir = tempfile::tempdir().unwrap(); + let sockname = tempdir.path().join("sock"); +- let s1 = socket(AddressFamily::Unix, SockType::Stream, +- SockFlag::empty(), None).expect("socket failed"); +- let sockaddr = SockAddr::new_unix(&sockname).unwrap(); ++ let s1 = socket( ++ AddressFamily::Unix, ++ SockType::Stream, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("socket failed"); ++ let sockaddr = UnixAddr::new(&sockname).unwrap(); + bind(s1, &sockaddr).expect("bind failed"); + listen(s1, 10).expect("listen failed"); + + let thr = thread::spawn(move || { +- let s2 = socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(), None) +- .expect("socket failed"); ++ let s2 = socket( ++ AddressFamily::Unix, ++ SockType::Stream, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("socket failed"); + connect(s2, &sockaddr).expect("connect failed"); + write(s2, b"hello").expect("write failed"); + close(s2).unwrap(); +@@ -719,7 +1534,7 @@ pub fn test_unixdomain() { + + let s3 = accept(s1).expect("accept failed"); + +- let mut buf = [0;5]; ++ let mut buf = [0; 5]; + read(s3, &mut buf).unwrap(); + close(s3).unwrap(); + close(s1).unwrap(); +@@ -728,19 +1543,81 @@ pub fn test_unixdomain() { + assert_eq!(&buf[..], b"hello"); + } + ++// Test using unnamed unix domain addresses ++#[cfg(any(target_os = "android", target_os = "linux"))] ++#[test] ++pub fn test_unnamed_unixdomain() { ++ use nix::sys::socket::{getsockname, socketpair}; ++ use nix::sys::socket::{SockFlag, SockType}; ++ use nix::unistd::close; ++ ++ let (fd_1, fd_2) = socketpair( ++ AddressFamily::Unix, ++ SockType::Stream, ++ None, ++ SockFlag::empty(), ++ ) ++ .expect("socketpair failed"); ++ ++ let addr_1: UnixAddr = getsockname(fd_1).expect("getsockname failed"); ++ assert!(addr_1.is_unnamed()); ++ ++ close(fd_1).unwrap(); ++ close(fd_2).unwrap(); ++} ++ ++// Test creating and using unnamed unix domain addresses for autobinding sockets ++#[cfg(any(target_os = "android", target_os = "linux"))] ++#[test] ++pub fn test_unnamed_unixdomain_autobind() { ++ use nix::sys::socket::{bind, getsockname, socket}; ++ use nix::sys::socket::{SockFlag, SockType}; ++ use nix::unistd::close; ++ ++ let fd = socket( ++ AddressFamily::Unix, ++ SockType::Stream, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("socket failed"); ++ ++ // unix(7): "If a bind(2) call specifies addrlen as `sizeof(sa_family_t)`, or [...], then the ++ // socket is autobound to an abstract address" ++ bind(fd, &UnixAddr::new_unnamed()).expect("bind failed"); ++ ++ let addr: UnixAddr = getsockname(fd).expect("getsockname failed"); ++ let addr = addr.as_abstract().unwrap(); ++ ++ // changed from 8 to 5 bytes in Linux 2.3.15, and rust's minimum supported Linux version is 3.2 ++ // (as of 2022-11) ++ assert_eq!(addr.len(), 5); ++ ++ close(fd).unwrap(); ++} ++ + // Test creating and using named system control sockets + #[cfg(any(target_os = "macos", target_os = "ios"))] + #[test] + pub fn test_syscontrol() { +- use nix::Error; + use nix::errno::Errno; +- use nix::sys::socket::{socket, SockAddr, SockType, SockFlag, SockProtocol}; ++ use nix::sys::socket::{ ++ socket, SockFlag, SockProtocol, SockType, SysControlAddr, ++ }; + +- let fd = socket(AddressFamily::System, SockType::Datagram, +- SockFlag::empty(), SockProtocol::KextControl) +- .expect("socket failed"); +- let _sockaddr = SockAddr::new_sys_control(fd, "com.apple.net.utun_control", 0).expect("resolving sys_control name failed"); +- assert_eq!(SockAddr::new_sys_control(fd, "foo.bar.lol", 0).err(), Some(Error::Sys(Errno::ENOENT))); ++ let fd = socket( ++ AddressFamily::System, ++ SockType::Datagram, ++ SockFlag::empty(), ++ SockProtocol::KextControl, ++ ) ++ .expect("socket failed"); ++ SysControlAddr::from_name(fd, "com.apple.net.utun_control", 0) ++ .expect("resolving sys_control name failed"); ++ assert_eq!( ++ SysControlAddr::from_name(fd, "foo.bar.lol", 0).err(), ++ Some(Errno::ENOENT) ++ ); + + // requires root privileges + // connect(fd, &sockaddr).expect("connect failed"); +@@ -755,43 +1632,30 @@ pub fn test_syscontrol() { + target_os = "netbsd", + target_os = "openbsd", + ))] +-fn loopback_address(family: AddressFamily) -> Option { +- use std::io; +- use std::io::Write; ++fn loopback_address( ++ family: AddressFamily, ++) -> Option { + use nix::ifaddrs::getifaddrs; +- use nix::sys::socket::SockAddr; + use nix::net::if_::*; ++ use nix::sys::socket::SockaddrLike; ++ use std::io; ++ use std::io::Write; + +- let addrs = match getifaddrs() { ++ let mut addrs = match getifaddrs() { + Ok(iter) => iter, + Err(e) => { + let stdioerr = io::stderr(); + let mut handle = stdioerr.lock(); + writeln!(handle, "getifaddrs: {:?}", e).unwrap(); + return None; +- }, ++ } + }; + // return first address matching family +- for ifaddr in addrs { +- if ifaddr.flags.contains(InterfaceFlags::IFF_LOOPBACK) { +- match ifaddr.address { +- Some(SockAddr::Inet(InetAddr::V4(..))) => { +- match family { +- AddressFamily::Inet => return Some(ifaddr), +- _ => continue +- } +- }, +- Some(SockAddr::Inet(InetAddr::V6(..))) => { +- match family { +- AddressFamily::Inet6 => return Some(ifaddr), +- _ => continue +- } +- }, +- _ => continue, +- } +- } +- } +- None ++ addrs.find(|ifaddr| { ++ ifaddr.flags.contains(InterfaceFlags::IFF_LOOPBACK) ++ && ifaddr.address.as_ref().and_then(SockaddrLike::family) ++ == Some(family) ++ }) + } + + #[cfg(any( +@@ -802,85 +1666,89 @@ fn loopback_address(family: AddressFamily) -> Option { + target_os = "netbsd", + ))] + // qemu doesn't seem to be emulating this correctly in these architectures +-#[cfg_attr(any( +- target_arch = "mips", +- target_arch = "mips64", +- target_arch = "powerpc64", +-), ignore)] ++#[cfg_attr( ++ all( ++ qemu, ++ any( ++ target_arch = "mips", ++ target_arch = "mips64", ++ target_arch = "powerpc64", ++ ) ++ ), ++ ignore ++)] + #[test] + pub fn test_recv_ipv4pktinfo() { +- use libc; ++ use nix::net::if_::*; + use nix::sys::socket::sockopt::Ipv4PacketInfo; +- use nix::sys::socket::{bind, SockFlag, SockType}; ++ use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn}; + use nix::sys::socket::{getsockname, setsockopt, socket}; + use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags}; +- use nix::sys::uio::IoVec; +- use nix::net::if_::*; ++ use std::io::{IoSlice, IoSliceMut}; + + let lo_ifaddr = loopback_address(AddressFamily::Inet); + let (lo_name, lo) = match lo_ifaddr { +- Some(ifaddr) => (ifaddr.interface_name, +- ifaddr.address.expect("Expect IPv4 address on interface")), ++ Some(ifaddr) => ( ++ ifaddr.interface_name, ++ ifaddr.address.expect("Expect IPv4 address on interface"), ++ ), + None => return, + }; + let receive = socket( +- AddressFamily::Inet, +- SockType::Datagram, +- SockFlag::empty(), +- None, +- ).expect("receive socket failed"); ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("receive socket failed"); + bind(receive, &lo).expect("bind failed"); +- let sa = getsockname(receive).expect("getsockname failed"); ++ let sa: SockaddrIn = getsockname(receive).expect("getsockname failed"); + setsockopt(receive, Ipv4PacketInfo, &true).expect("setsockopt failed"); + + { + let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; +- let iov = [IoVec::from_slice(&slice)]; ++ let iov = [IoSlice::new(&slice)]; + + let send = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, +- ).expect("send socket failed"); +- sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa)).expect("sendmsg failed"); ++ ) ++ .expect("send socket failed"); ++ sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa)) ++ .expect("sendmsg failed"); + } + + { + let mut buf = [0u8; 8]; +- let iovec = [IoVec::from_mut_slice(&mut buf)]; ++ let mut iovec = [IoSliceMut::new(&mut buf)]; ++ + let mut space = cmsg_space!(libc::in_pktinfo); +- let msg = recvmsg( ++ let msg = recvmsg::<()>( + receive, +- &iovec, ++ &mut iovec, + Some(&mut space), + MsgFlags::empty(), +- ).expect("recvmsg failed"); +- assert!( +- !msg.flags +- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC) +- ); ++ ) ++ .expect("recvmsg failed"); ++ assert!(!msg ++ .flags ++ .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); + + let mut cmsgs = msg.cmsgs(); +- match cmsgs.next() { +- Some(ControlMessageOwned::Ipv4PacketInfo(pktinfo)) => { +- let i = if_nametoindex(lo_name.as_bytes()).expect("if_nametoindex"); +- assert_eq!( +- pktinfo.ipi_ifindex as libc::c_uint, +- i, +- "unexpected ifindex (expected {}, got {})", +- i, +- pktinfo.ipi_ifindex +- ); +- } +- _ => (), ++ if let Some(ControlMessageOwned::Ipv4PacketInfo(pktinfo)) = cmsgs.next() ++ { ++ let i = if_nametoindex(lo_name.as_bytes()).expect("if_nametoindex"); ++ assert_eq!( ++ pktinfo.ipi_ifindex as libc::c_uint, i, ++ "unexpected ifindex (expected {}, got {})", ++ i, pktinfo.ipi_ifindex ++ ); + } + assert!(cmsgs.next().is_none(), "unexpected additional control msg"); + assert_eq!(msg.bytes, 8); +- assert_eq!( +- iovec[0].as_slice(), +- [1u8, 2, 3, 4, 5, 6, 7, 8] +- ); ++ assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]); + } + } + +@@ -892,25 +1760,32 @@ pub fn test_recv_ipv4pktinfo() { + target_os = "openbsd", + ))] + // qemu doesn't seem to be emulating this correctly in these architectures +-#[cfg_attr(any( +- target_arch = "mips", +- target_arch = "mips64", +- target_arch = "powerpc64", +-), ignore)] ++#[cfg_attr( ++ all( ++ qemu, ++ any( ++ target_arch = "mips", ++ target_arch = "mips64", ++ target_arch = "powerpc64", ++ ) ++ ), ++ ignore ++)] + #[test] + pub fn test_recvif() { +- use libc; + use nix::net::if_::*; +- use nix::sys::socket::sockopt::{Ipv4RecvIf, Ipv4RecvDstAddr}; +- use nix::sys::socket::{bind, SockFlag, SockType}; +- use nix::sys::socket::{getsockname, setsockopt, socket, SockAddr}; ++ use nix::sys::socket::sockopt::{Ipv4RecvDstAddr, Ipv4RecvIf}; ++ use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn}; ++ use nix::sys::socket::{getsockname, setsockopt, socket}; + use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags}; +- use nix::sys::uio::IoVec; ++ use std::io::{IoSlice, IoSliceMut}; + + let lo_ifaddr = loopback_address(AddressFamily::Inet); + let (lo_name, lo) = match lo_ifaddr { +- Some(ifaddr) => (ifaddr.interface_name, +- ifaddr.address.expect("Expect IPv4 address on interface")), ++ Some(ifaddr) => ( ++ ifaddr.interface_name, ++ ifaddr.address.expect("Expect IPv4 address on interface"), ++ ), + None => return, + }; + let receive = socket( +@@ -918,39 +1793,44 @@ pub fn test_recvif() { + SockType::Datagram, + SockFlag::empty(), + None, +- ).expect("receive socket failed"); ++ ) ++ .expect("receive socket failed"); + bind(receive, &lo).expect("bind failed"); +- let sa = getsockname(receive).expect("getsockname failed"); +- setsockopt(receive, Ipv4RecvIf, &true).expect("setsockopt IP_RECVIF failed"); +- setsockopt(receive, Ipv4RecvDstAddr, &true).expect("setsockopt IP_RECVDSTADDR failed"); ++ let sa: SockaddrIn = getsockname(receive).expect("getsockname failed"); ++ setsockopt(receive, Ipv4RecvIf, &true) ++ .expect("setsockopt IP_RECVIF failed"); ++ setsockopt(receive, Ipv4RecvDstAddr, &true) ++ .expect("setsockopt IP_RECVDSTADDR failed"); + + { + let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; +- let iov = [IoVec::from_slice(&slice)]; ++ let iov = [IoSlice::new(&slice)]; + + let send = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + None, +- ).expect("send socket failed"); +- sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa)).expect("sendmsg failed"); ++ ) ++ .expect("send socket failed"); ++ sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa)) ++ .expect("sendmsg failed"); + } + + { + let mut buf = [0u8; 8]; +- let iovec = [IoVec::from_mut_slice(&mut buf)]; ++ let mut iovec = [IoSliceMut::new(&mut buf)]; + let mut space = cmsg_space!(libc::sockaddr_dl, libc::in_addr); +- let msg = recvmsg( ++ let msg = recvmsg::<()>( + receive, +- &iovec, ++ &mut iovec, + Some(&mut space), + MsgFlags::empty(), +- ).expect("recvmsg failed"); +- assert!( +- !msg.flags +- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC) +- ); ++ ) ++ .expect("recvmsg failed"); ++ assert!(!msg ++ .flags ++ .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); + assert_eq!(msg.cmsgs().count(), 2, "expected 2 cmsgs"); + + let mut rx_recvif = false; +@@ -959,37 +1839,203 @@ pub fn test_recvif() { + match cmsg { + ControlMessageOwned::Ipv4RecvIf(dl) => { + rx_recvif = true; +- let i = if_nametoindex(lo_name.as_bytes()).expect("if_nametoindex"); ++ let i = if_nametoindex(lo_name.as_bytes()) ++ .expect("if_nametoindex"); + assert_eq!( +- dl.sdl_index as libc::c_uint, +- i, ++ dl.sdl_index as libc::c_uint, i, + "unexpected ifindex (expected {}, got {})", +- i, +- dl.sdl_index ++ i, dl.sdl_index + ); +- }, ++ } + ControlMessageOwned::Ipv4RecvDstAddr(addr) => { + rx_recvdstaddr = true; +- if let SockAddr::Inet(InetAddr::V4(a)) = lo { +- assert_eq!(a.sin_addr.s_addr, ++ if let Some(sin) = lo.as_sockaddr_in() { ++ assert_eq!(sin.as_ref().sin_addr.s_addr, + addr.s_addr, + "unexpected destination address (expected {}, got {})", +- a.sin_addr.s_addr, ++ sin.as_ref().sin_addr.s_addr, + addr.s_addr); + } else { + panic!("unexpected Sockaddr"); + } +- }, ++ } + _ => panic!("unexpected additional control msg"), + } + } +- assert_eq!(rx_recvif, true); +- assert_eq!(rx_recvdstaddr, true); ++ assert!(rx_recvif); ++ assert!(rx_recvdstaddr); + assert_eq!(msg.bytes, 8); +- assert_eq!( +- iovec[0].as_slice(), +- [1u8, 2, 3, 4, 5, 6, 7, 8] +- ); ++ assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]); ++ } ++} ++ ++#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] ++#[cfg_attr(qemu, ignore)] ++#[test] ++pub fn test_recvif_ipv4() { ++ use nix::sys::socket::sockopt::Ipv4OrigDstAddr; ++ use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn}; ++ use nix::sys::socket::{getsockname, setsockopt, socket}; ++ use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags}; ++ use std::io::{IoSlice, IoSliceMut}; ++ ++ let lo_ifaddr = loopback_address(AddressFamily::Inet); ++ let (_lo_name, lo) = match lo_ifaddr { ++ Some(ifaddr) => ( ++ ifaddr.interface_name, ++ ifaddr.address.expect("Expect IPv4 address on interface"), ++ ), ++ None => return, ++ }; ++ let receive = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("receive socket failed"); ++ bind(receive, &lo).expect("bind failed"); ++ let sa: SockaddrIn = getsockname(receive).expect("getsockname failed"); ++ setsockopt(receive, Ipv4OrigDstAddr, &true) ++ .expect("setsockopt IP_ORIGDSTADDR failed"); ++ ++ { ++ let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; ++ let iov = [IoSlice::new(&slice)]; ++ ++ let send = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("send socket failed"); ++ sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa)) ++ .expect("sendmsg failed"); ++ } ++ ++ { ++ let mut buf = [0u8; 8]; ++ let mut iovec = [IoSliceMut::new(&mut buf)]; ++ let mut space = cmsg_space!(libc::sockaddr_in); ++ let msg = recvmsg::<()>( ++ receive, ++ &mut iovec, ++ Some(&mut space), ++ MsgFlags::empty(), ++ ) ++ .expect("recvmsg failed"); ++ assert!(!msg ++ .flags ++ .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); ++ assert_eq!(msg.cmsgs().count(), 1, "expected 1 cmsgs"); ++ ++ let mut rx_recvorigdstaddr = false; ++ for cmsg in msg.cmsgs() { ++ match cmsg { ++ ControlMessageOwned::Ipv4OrigDstAddr(addr) => { ++ rx_recvorigdstaddr = true; ++ if let Some(sin) = lo.as_sockaddr_in() { ++ assert_eq!(sin.as_ref().sin_addr.s_addr, ++ addr.sin_addr.s_addr, ++ "unexpected destination address (expected {}, got {})", ++ sin.as_ref().sin_addr.s_addr, ++ addr.sin_addr.s_addr); ++ } else { ++ panic!("unexpected Sockaddr"); ++ } ++ } ++ _ => panic!("unexpected additional control msg"), ++ } ++ } ++ assert!(rx_recvorigdstaddr); ++ assert_eq!(msg.bytes, 8); ++ assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]); ++ } ++} ++ ++#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] ++#[cfg_attr(qemu, ignore)] ++#[test] ++pub fn test_recvif_ipv6() { ++ use nix::sys::socket::sockopt::Ipv6OrigDstAddr; ++ use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn6}; ++ use nix::sys::socket::{getsockname, setsockopt, socket}; ++ use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags}; ++ use std::io::{IoSlice, IoSliceMut}; ++ ++ let lo_ifaddr = loopback_address(AddressFamily::Inet6); ++ let (_lo_name, lo) = match lo_ifaddr { ++ Some(ifaddr) => ( ++ ifaddr.interface_name, ++ ifaddr.address.expect("Expect IPv6 address on interface"), ++ ), ++ None => return, ++ }; ++ let receive = socket( ++ AddressFamily::Inet6, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("receive socket failed"); ++ bind(receive, &lo).expect("bind failed"); ++ let sa: SockaddrIn6 = getsockname(receive).expect("getsockname failed"); ++ setsockopt(receive, Ipv6OrigDstAddr, &true) ++ .expect("setsockopt IP_ORIGDSTADDR failed"); ++ ++ { ++ let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; ++ let iov = [IoSlice::new(&slice)]; ++ ++ let send = socket( ++ AddressFamily::Inet6, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("send socket failed"); ++ sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa)) ++ .expect("sendmsg failed"); ++ } ++ ++ { ++ let mut buf = [0u8; 8]; ++ let mut iovec = [IoSliceMut::new(&mut buf)]; ++ let mut space = cmsg_space!(libc::sockaddr_in6); ++ let msg = recvmsg::<()>( ++ receive, ++ &mut iovec, ++ Some(&mut space), ++ MsgFlags::empty(), ++ ) ++ .expect("recvmsg failed"); ++ assert!(!msg ++ .flags ++ .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); ++ assert_eq!(msg.cmsgs().count(), 1, "expected 1 cmsgs"); ++ ++ let mut rx_recvorigdstaddr = false; ++ for cmsg in msg.cmsgs() { ++ match cmsg { ++ ControlMessageOwned::Ipv6OrigDstAddr(addr) => { ++ rx_recvorigdstaddr = true; ++ if let Some(sin) = lo.as_sockaddr_in6() { ++ assert_eq!(sin.as_ref().sin6_addr.s6_addr, ++ addr.sin6_addr.s6_addr, ++ "unexpected destination address (expected {:?}, got {:?})", ++ sin.as_ref().sin6_addr.s6_addr, ++ addr.sin6_addr.s6_addr); ++ } else { ++ panic!("unexpected Sockaddr"); ++ } ++ } ++ _ => panic!("unexpected additional control msg"), ++ } ++ } ++ assert!(rx_recvorigdstaddr); ++ assert_eq!(msg.bytes, 8); ++ assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]); + } + } + +@@ -1003,25 +2049,32 @@ pub fn test_recvif() { + target_os = "openbsd", + ))] + // qemu doesn't seem to be emulating this correctly in these architectures +-#[cfg_attr(any( +- target_arch = "mips", +- target_arch = "mips64", +- target_arch = "powerpc64", +-), ignore)] ++#[cfg_attr( ++ all( ++ qemu, ++ any( ++ target_arch = "mips", ++ target_arch = "mips64", ++ target_arch = "powerpc64", ++ ) ++ ), ++ ignore ++)] + #[test] + pub fn test_recv_ipv6pktinfo() { +- use libc; + use nix::net::if_::*; + use nix::sys::socket::sockopt::Ipv6RecvPacketInfo; +- use nix::sys::socket::{bind, SockFlag, SockType}; ++ use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn6}; + use nix::sys::socket::{getsockname, setsockopt, socket}; + use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags}; +- use nix::sys::uio::IoVec; ++ use std::io::{IoSlice, IoSliceMut}; + + let lo_ifaddr = loopback_address(AddressFamily::Inet6); + let (lo_name, lo) = match lo_ifaddr { +- Some(ifaddr) => (ifaddr.interface_name, +- ifaddr.address.expect("Expect IPv4 address on interface")), ++ Some(ifaddr) => ( ++ ifaddr.interface_name, ++ ifaddr.address.expect("Expect IPv6 address on interface"), ++ ), + None => return, + }; + let receive = socket( +@@ -1029,106 +2082,105 @@ pub fn test_recv_ipv6pktinfo() { + SockType::Datagram, + SockFlag::empty(), + None, +- ).expect("receive socket failed"); ++ ) ++ .expect("receive socket failed"); + bind(receive, &lo).expect("bind failed"); +- let sa = getsockname(receive).expect("getsockname failed"); ++ let sa: SockaddrIn6 = getsockname(receive).expect("getsockname failed"); + setsockopt(receive, Ipv6RecvPacketInfo, &true).expect("setsockopt failed"); + + { + let slice = [1u8, 2, 3, 4, 5, 6, 7, 8]; +- let iov = [IoVec::from_slice(&slice)]; ++ let iov = [IoSlice::new(&slice)]; + + let send = socket( + AddressFamily::Inet6, + SockType::Datagram, + SockFlag::empty(), + None, +- ).expect("send socket failed"); +- sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa)).expect("sendmsg failed"); ++ ) ++ .expect("send socket failed"); ++ sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa)) ++ .expect("sendmsg failed"); + } + + { + let mut buf = [0u8; 8]; +- let iovec = [IoVec::from_mut_slice(&mut buf)]; ++ let mut iovec = [IoSliceMut::new(&mut buf)]; ++ + let mut space = cmsg_space!(libc::in6_pktinfo); +- let msg = recvmsg( ++ let msg = recvmsg::<()>( + receive, +- &iovec, ++ &mut iovec, + Some(&mut space), + MsgFlags::empty(), +- ).expect("recvmsg failed"); +- assert!( +- !msg.flags +- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC) +- ); ++ ) ++ .expect("recvmsg failed"); ++ assert!(!msg ++ .flags ++ .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC)); + + let mut cmsgs = msg.cmsgs(); +- match cmsgs.next() { +- Some(ControlMessageOwned::Ipv6PacketInfo(pktinfo)) => { +- let i = if_nametoindex(lo_name.as_bytes()).expect("if_nametoindex"); +- assert_eq!( +- pktinfo.ipi6_ifindex, +- i, +- "unexpected ifindex (expected {}, got {})", +- i, +- pktinfo.ipi6_ifindex +- ); +- } +- _ => (), ++ if let Some(ControlMessageOwned::Ipv6PacketInfo(pktinfo)) = cmsgs.next() ++ { ++ let i = if_nametoindex(lo_name.as_bytes()).expect("if_nametoindex"); ++ assert_eq!( ++ pktinfo.ipi6_ifindex as libc::c_uint, i, ++ "unexpected ifindex (expected {}, got {})", ++ i, pktinfo.ipi6_ifindex ++ ); + } + assert!(cmsgs.next().is_none(), "unexpected additional control msg"); + assert_eq!(msg.bytes, 8); +- assert_eq!( +- iovec[0].as_slice(), +- [1u8, 2, 3, 4, 5, 6, 7, 8] +- ); ++ assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]); + } + } + +-#[cfg(target_os = "linux")] ++#[cfg(any(target_os = "android", target_os = "linux"))] ++#[cfg_attr(graviton, ignore = "Not supported by the CI environment")] + #[test] + pub fn test_vsock() { +- use libc; +- use nix::Error; + use nix::errno::Errno; +- use nix::sys::socket::{AddressFamily, socket, bind, connect, listen, +- SockAddr, SockType, SockFlag}; +- use nix::unistd::{close}; ++ use nix::sys::socket::{ ++ bind, connect, listen, socket, AddressFamily, SockFlag, SockType, ++ VsockAddr, ++ }; ++ use nix::unistd::close; + use std::thread; + + let port: u32 = 3000; + +- let s1 = socket(AddressFamily::Vsock, SockType::Stream, +- SockFlag::empty(), None) +- .expect("socket failed"); +- +- // VMADDR_CID_HYPERVISOR and VMADDR_CID_RESERVED are reserved, so we expect +- // an EADDRNOTAVAIL error. +- let sockaddr = SockAddr::new_vsock(libc::VMADDR_CID_HYPERVISOR, port); +- assert_eq!(bind(s1, &sockaddr).err(), +- Some(Error::Sys(Errno::EADDRNOTAVAIL))); +- +- let sockaddr = SockAddr::new_vsock(libc::VMADDR_CID_RESERVED, port); +- assert_eq!(bind(s1, &sockaddr).err(), +- Some(Error::Sys(Errno::EADDRNOTAVAIL))); ++ let s1 = socket( ++ AddressFamily::Vsock, ++ SockType::Stream, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("socket failed"); + ++ // VMADDR_CID_HYPERVISOR is reserved, so we expect an EADDRNOTAVAIL error. ++ let sockaddr_hv = VsockAddr::new(libc::VMADDR_CID_HYPERVISOR, port); ++ assert_eq!(bind(s1, &sockaddr_hv).err(), Some(Errno::EADDRNOTAVAIL)); + +- let sockaddr = SockAddr::new_vsock(libc::VMADDR_CID_ANY, port); +- assert_eq!(bind(s1, &sockaddr), Ok(())); ++ let sockaddr_any = VsockAddr::new(libc::VMADDR_CID_ANY, port); ++ assert_eq!(bind(s1, &sockaddr_any), Ok(())); + listen(s1, 10).expect("listen failed"); + + let thr = thread::spawn(move || { + let cid: u32 = libc::VMADDR_CID_HOST; + +- let s2 = socket(AddressFamily::Vsock, SockType::Stream, +- SockFlag::empty(), None) +- .expect("socket failed"); ++ let s2 = socket( ++ AddressFamily::Vsock, ++ SockType::Stream, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("socket failed"); + +- let sockaddr = SockAddr::new_vsock(cid, port); ++ let sockaddr_host = VsockAddr::new(cid, port); + + // The current implementation does not support loopback devices, so, + // for now, we expect a failure on the connect. +- assert_ne!(connect(s2, &sockaddr), Ok(())); ++ assert_ne!(connect(s2, &sockaddr_host), Ok(())); + + close(s2).unwrap(); + }); +@@ -1136,3 +2188,441 @@ pub fn test_vsock() { + close(s1).unwrap(); + thr.join().unwrap(); + } ++ ++// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack ++// of QEMU support is suspected. ++#[cfg_attr(qemu, ignore)] ++#[cfg(all(target_os = "linux"))] ++#[test] ++fn test_recvmsg_timestampns() { ++ use nix::sys::socket::*; ++ use nix::sys::time::*; ++ use std::io::{IoSlice, IoSliceMut}; ++ use std::time::*; ++ ++ // Set up ++ let message = "Ohayō!".as_bytes(); ++ let in_socket = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); ++ setsockopt(in_socket, sockopt::ReceiveTimestampns, &true).unwrap(); ++ let localhost = SockaddrIn::new(127, 0, 0, 1, 0); ++ bind(in_socket, &localhost).unwrap(); ++ let address: SockaddrIn = getsockname(in_socket).unwrap(); ++ // Get initial time ++ let time0 = SystemTime::now(); ++ // Send the message ++ let iov = [IoSlice::new(message)]; ++ let flags = MsgFlags::empty(); ++ let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap(); ++ assert_eq!(message.len(), l); ++ // Receive the message ++ let mut buffer = vec![0u8; message.len()]; ++ let mut cmsgspace = nix::cmsg_space!(TimeSpec); ++ ++ let mut iov = [IoSliceMut::new(&mut buffer)]; ++ let r = recvmsg::<()>(in_socket, &mut iov, Some(&mut cmsgspace), flags) ++ .unwrap(); ++ let rtime = match r.cmsgs().next() { ++ Some(ControlMessageOwned::ScmTimestampns(rtime)) => rtime, ++ Some(_) => panic!("Unexpected control message"), ++ None => panic!("No control message"), ++ }; ++ // Check the final time ++ let time1 = SystemTime::now(); ++ // the packet's received timestamp should lie in-between the two system ++ // times, unless the system clock was adjusted in the meantime. ++ let rduration = ++ Duration::new(rtime.tv_sec() as u64, rtime.tv_nsec() as u32); ++ assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration); ++ assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap()); ++ // Close socket ++ nix::unistd::close(in_socket).unwrap(); ++} ++ ++// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack ++// of QEMU support is suspected. ++#[cfg_attr(qemu, ignore)] ++#[cfg(all(target_os = "linux"))] ++#[test] ++fn test_recvmmsg_timestampns() { ++ use nix::sys::socket::*; ++ use nix::sys::time::*; ++ use std::io::{IoSlice, IoSliceMut}; ++ use std::time::*; ++ ++ // Set up ++ let message = "Ohayō!".as_bytes(); ++ let in_socket = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); ++ setsockopt(in_socket, sockopt::ReceiveTimestampns, &true).unwrap(); ++ let localhost = SockaddrIn::from_str("127.0.0.1:0").unwrap(); ++ bind(in_socket, &localhost).unwrap(); ++ let address: SockaddrIn = getsockname(in_socket).unwrap(); ++ // Get initial time ++ let time0 = SystemTime::now(); ++ // Send the message ++ let iov = [IoSlice::new(message)]; ++ let flags = MsgFlags::empty(); ++ let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap(); ++ assert_eq!(message.len(), l); ++ // Receive the message ++ let mut buffer = vec![0u8; message.len()]; ++ let cmsgspace = nix::cmsg_space!(TimeSpec); ++ let iov = vec![[IoSliceMut::new(&mut buffer)]]; ++ let mut data = MultiHeaders::preallocate(1, Some(cmsgspace)); ++ let r: Vec> = ++ recvmmsg(in_socket, &mut data, iov.iter(), flags, None) ++ .unwrap() ++ .collect(); ++ let rtime = match r[0].cmsgs().next() { ++ Some(ControlMessageOwned::ScmTimestampns(rtime)) => rtime, ++ Some(_) => panic!("Unexpected control message"), ++ None => panic!("No control message"), ++ }; ++ // Check the final time ++ let time1 = SystemTime::now(); ++ // the packet's received timestamp should lie in-between the two system ++ // times, unless the system clock was adjusted in the meantime. ++ let rduration = ++ Duration::new(rtime.tv_sec() as u64, rtime.tv_nsec() as u32); ++ assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration); ++ assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap()); ++ // Close socket ++ nix::unistd::close(in_socket).unwrap(); ++} ++ ++// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack ++// of QEMU support is suspected. ++#[cfg_attr(qemu, ignore)] ++#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] ++#[test] ++fn test_recvmsg_rxq_ovfl() { ++ use nix::sys::socket::sockopt::{RcvBuf, RxqOvfl}; ++ use nix::sys::socket::*; ++ use nix::Error; ++ use std::io::{IoSlice, IoSliceMut}; ++ ++ let message = [0u8; 2048]; ++ let bufsize = message.len() * 2; ++ ++ let in_socket = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); ++ let out_socket = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); ++ ++ let localhost = SockaddrIn::from_str("127.0.0.1:0").unwrap(); ++ bind(in_socket, &localhost).unwrap(); ++ ++ let address: SockaddrIn = getsockname(in_socket).unwrap(); ++ connect(out_socket, &address).unwrap(); ++ ++ // Set SO_RXQ_OVFL flag. ++ setsockopt(in_socket, RxqOvfl, &1).unwrap(); ++ ++ // Set the receiver buffer size to hold only 2 messages. ++ setsockopt(in_socket, RcvBuf, &bufsize).unwrap(); ++ ++ let mut drop_counter = 0; ++ ++ for _ in 0..2 { ++ let iov = [IoSlice::new(&message)]; ++ let flags = MsgFlags::empty(); ++ ++ // Send the 3 messages (the receiver buffer can only hold 2 messages) ++ // to create an overflow. ++ for _ in 0..3 { ++ let l = ++ sendmsg(out_socket, &iov, &[], flags, Some(&address)).unwrap(); ++ assert_eq!(message.len(), l); ++ } ++ ++ // Receive the message and check the drop counter if any. ++ loop { ++ let mut buffer = vec![0u8; message.len()]; ++ let mut cmsgspace = nix::cmsg_space!(u32); ++ ++ let mut iov = [IoSliceMut::new(&mut buffer)]; ++ ++ match recvmsg::<()>( ++ in_socket, ++ &mut iov, ++ Some(&mut cmsgspace), ++ MsgFlags::MSG_DONTWAIT, ++ ) { ++ Ok(r) => { ++ drop_counter = match r.cmsgs().next() { ++ Some(ControlMessageOwned::RxqOvfl(drop_counter)) => { ++ drop_counter ++ } ++ Some(_) => panic!("Unexpected control message"), ++ None => 0, ++ }; ++ } ++ Err(Error::EAGAIN) => { ++ break; ++ } ++ _ => { ++ panic!("unknown recvmsg() error"); ++ } ++ } ++ } ++ } ++ ++ // One packet lost. ++ assert_eq!(drop_counter, 1); ++ ++ // Close sockets ++ nix::unistd::close(in_socket).unwrap(); ++ nix::unistd::close(out_socket).unwrap(); ++} ++ ++#[cfg(any(target_os = "linux", target_os = "android",))] ++mod linux_errqueue { ++ use super::FromStr; ++ use nix::sys::socket::*; ++ ++ // Send a UDP datagram to a bogus destination address and observe an ICMP error (v4). ++ // ++ // Disable the test on QEMU because QEMU emulation of IP_RECVERR is broken (as documented on PR ++ // #1514). ++ #[cfg_attr(qemu, ignore)] ++ #[test] ++ fn test_recverr_v4() { ++ #[repr(u8)] ++ enum IcmpTypes { ++ DestUnreach = 3, // ICMP_DEST_UNREACH ++ } ++ #[repr(u8)] ++ enum IcmpUnreachCodes { ++ PortUnreach = 3, // ICMP_PORT_UNREACH ++ } ++ ++ test_recverr_impl::( ++ "127.0.0.1:6800", ++ AddressFamily::Inet, ++ sockopt::Ipv4RecvErr, ++ libc::SO_EE_ORIGIN_ICMP, ++ IcmpTypes::DestUnreach as u8, ++ IcmpUnreachCodes::PortUnreach as u8, ++ // Closure handles protocol-specific testing and returns generic sock_extended_err for ++ // protocol-independent test impl. ++ |cmsg| { ++ if let ControlMessageOwned::Ipv4RecvErr(ext_err, err_addr) = ++ cmsg ++ { ++ if let Some(origin) = err_addr { ++ // Validate that our network error originated from 127.0.0.1:0. ++ assert_eq!(origin.sin_family, AddressFamily::Inet as _); ++ assert_eq!( ++ origin.sin_addr.s_addr, ++ u32::from_be(0x7f000001) ++ ); ++ assert_eq!(origin.sin_port, 0); ++ } else { ++ panic!("Expected some error origin"); ++ } ++ *ext_err ++ } else { ++ panic!("Unexpected control message {:?}", cmsg); ++ } ++ }, ++ ) ++ } ++ ++ // Essentially the same test as v4. ++ // ++ // Disable the test on QEMU because QEMU emulation of IPV6_RECVERR is broken (as documented on ++ // PR #1514). ++ #[cfg_attr(qemu, ignore)] ++ #[test] ++ fn test_recverr_v6() { ++ #[repr(u8)] ++ enum IcmpV6Types { ++ DestUnreach = 1, // ICMPV6_DEST_UNREACH ++ } ++ #[repr(u8)] ++ enum IcmpV6UnreachCodes { ++ PortUnreach = 4, // ICMPV6_PORT_UNREACH ++ } ++ ++ test_recverr_impl::( ++ "[::1]:6801", ++ AddressFamily::Inet6, ++ sockopt::Ipv6RecvErr, ++ libc::SO_EE_ORIGIN_ICMP6, ++ IcmpV6Types::DestUnreach as u8, ++ IcmpV6UnreachCodes::PortUnreach as u8, ++ // Closure handles protocol-specific testing and returns generic sock_extended_err for ++ // protocol-independent test impl. ++ |cmsg| { ++ if let ControlMessageOwned::Ipv6RecvErr(ext_err, err_addr) = ++ cmsg ++ { ++ if let Some(origin) = err_addr { ++ // Validate that our network error originated from localhost:0. ++ assert_eq!( ++ origin.sin6_family, ++ AddressFamily::Inet6 as _ ++ ); ++ assert_eq!( ++ origin.sin6_addr.s6_addr, ++ std::net::Ipv6Addr::LOCALHOST.octets() ++ ); ++ assert_eq!(origin.sin6_port, 0); ++ } else { ++ panic!("Expected some error origin"); ++ } ++ *ext_err ++ } else { ++ panic!("Unexpected control message {:?}", cmsg); ++ } ++ }, ++ ) ++ } ++ ++ fn test_recverr_impl( ++ sa: &str, ++ af: AddressFamily, ++ opt: OPT, ++ ee_origin: u8, ++ ee_type: u8, ++ ee_code: u8, ++ testf: TESTF, ++ ) where ++ OPT: SetSockOpt, ++ TESTF: FnOnce(&ControlMessageOwned) -> libc::sock_extended_err, ++ { ++ use nix::errno::Errno; ++ use std::io::IoSliceMut; ++ ++ const MESSAGE_CONTENTS: &str = "ABCDEF"; ++ let std_sa = std::net::SocketAddr::from_str(sa).unwrap(); ++ let sock_addr = SockaddrStorage::from(std_sa); ++ let sock = socket(af, SockType::Datagram, SockFlag::SOCK_CLOEXEC, None) ++ .unwrap(); ++ setsockopt(sock, opt, &true).unwrap(); ++ if let Err(e) = sendto( ++ sock, ++ MESSAGE_CONTENTS.as_bytes(), ++ &sock_addr, ++ MsgFlags::empty(), ++ ) { ++ assert_eq!(e, Errno::EADDRNOTAVAIL); ++ println!("{:?} not available, skipping test.", af); ++ return; ++ } ++ ++ let mut buf = [0u8; 8]; ++ let mut iovec = [IoSliceMut::new(&mut buf)]; ++ let mut cspace = cmsg_space!(libc::sock_extended_err, SA); ++ ++ let msg = recvmsg( ++ sock, ++ &mut iovec, ++ Some(&mut cspace), ++ MsgFlags::MSG_ERRQUEUE, ++ ) ++ .unwrap(); ++ // The sent message / destination associated with the error is returned: ++ assert_eq!(msg.bytes, MESSAGE_CONTENTS.as_bytes().len()); ++ // recvmsg(2): "The original destination address of the datagram that caused the error is ++ // supplied via msg_name;" however, this is not literally true. E.g., an earlier version ++ // of this test used 0.0.0.0 (::0) as the destination address, which was mutated into ++ // 127.0.0.1 (::1). ++ assert_eq!(msg.address, Some(sock_addr)); ++ ++ // Check for expected control message. ++ let ext_err = match msg.cmsgs().next() { ++ Some(cmsg) => testf(&cmsg), ++ None => panic!("No control message"), ++ }; ++ ++ assert_eq!(ext_err.ee_errno, libc::ECONNREFUSED as u32); ++ assert_eq!(ext_err.ee_origin, ee_origin); ++ // ip(7): ee_type and ee_code are set from the type and code fields of the ICMP (ICMPv6) ++ // header. ++ assert_eq!(ext_err.ee_type, ee_type); ++ assert_eq!(ext_err.ee_code, ee_code); ++ // ip(7): ee_info contains the discovered MTU for EMSGSIZE errors. ++ assert_eq!(ext_err.ee_info, 0); ++ ++ let bytes = msg.bytes; ++ assert_eq!(&buf[..bytes], MESSAGE_CONTENTS.as_bytes()); ++ } ++} ++ ++// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack ++// of QEMU support is suspected. ++#[cfg_attr(qemu, ignore)] ++#[cfg(target_os = "linux")] ++#[test] ++pub fn test_txtime() { ++ use nix::sys::socket::{ ++ bind, recvmsg, sendmsg, setsockopt, socket, sockopt, ControlMessage, ++ MsgFlags, SockFlag, SockType, SockaddrIn, ++ }; ++ use nix::sys::time::TimeValLike; ++ use nix::time::{clock_gettime, ClockId}; ++ ++ require_kernel_version!(test_txtime, ">= 5.8"); ++ ++ let sock_addr = SockaddrIn::from_str("127.0.0.1:6802").unwrap(); ++ ++ let ssock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .expect("send socket failed"); ++ ++ let txtime_cfg = libc::sock_txtime { ++ clockid: libc::CLOCK_MONOTONIC, ++ flags: 0, ++ }; ++ setsockopt(ssock, sockopt::TxTime, &txtime_cfg).unwrap(); ++ ++ let rsock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); ++ bind(rsock, &sock_addr).unwrap(); ++ ++ let sbuf = [0u8; 2048]; ++ let iov1 = [std::io::IoSlice::new(&sbuf)]; ++ ++ let now = clock_gettime(ClockId::CLOCK_MONOTONIC).unwrap(); ++ let delay = std::time::Duration::from_secs(1).into(); ++ let txtime = (now + delay).num_nanoseconds() as u64; ++ ++ let cmsg = ControlMessage::TxTime(&txtime); ++ sendmsg(ssock, &iov1, &[cmsg], MsgFlags::empty(), Some(&sock_addr)) ++ .unwrap(); ++ ++ let mut rbuf = [0u8; 2048]; ++ let mut iov2 = [std::io::IoSliceMut::new(&mut rbuf)]; ++ recvmsg::<()>(rsock, &mut iov2, None, MsgFlags::empty()).unwrap(); ++} +diff --git a/vendor/nix/test/sys/test_sockopt.rs b/vendor/nix/test/sys/test_sockopt.rs +index c4860c0..34bef94 100644 +--- a/vendor/nix/test/sys/test_sockopt.rs ++++ b/vendor/nix/test/sys/test_sockopt.rs +@@ -1,14 +1,73 @@ ++#[cfg(any(target_os = "android", target_os = "linux"))] ++use crate::*; ++use nix::sys::socket::{ ++ getsockopt, setsockopt, socket, sockopt, AddressFamily, SockFlag, ++ SockProtocol, SockType, ++}; + use rand::{thread_rng, Rng}; +-use nix::sys::socket::{socket, sockopt, getsockopt, setsockopt, AddressFamily, SockType, SockFlag, SockProtocol}; ++ ++// NB: FreeBSD supports LOCAL_PEERCRED for SOCK_SEQPACKET, but OSX does not. ++#[cfg(any(target_os = "dragonfly", target_os = "freebsd",))] ++#[test] ++pub fn test_local_peercred_seqpacket() { ++ use nix::{ ++ sys::socket::socketpair, ++ unistd::{Gid, Uid}, ++ }; ++ ++ let (fd1, _fd2) = socketpair( ++ AddressFamily::Unix, ++ SockType::SeqPacket, ++ None, ++ SockFlag::empty(), ++ ) ++ .unwrap(); ++ let xucred = getsockopt(fd1, sockopt::LocalPeerCred).unwrap(); ++ assert_eq!(xucred.version(), 0); ++ assert_eq!(Uid::from_raw(xucred.uid()), Uid::current()); ++ assert_eq!(Gid::from_raw(xucred.groups()[0]), Gid::current()); ++} ++ ++#[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "macos", ++ target_os = "ios" ++))] ++#[test] ++pub fn test_local_peercred_stream() { ++ use nix::{ ++ sys::socket::socketpair, ++ unistd::{Gid, Uid}, ++ }; ++ ++ let (fd1, _fd2) = socketpair( ++ AddressFamily::Unix, ++ SockType::Stream, ++ None, ++ SockFlag::empty(), ++ ) ++ .unwrap(); ++ let xucred = getsockopt(fd1, sockopt::LocalPeerCred).unwrap(); ++ assert_eq!(xucred.version(), 0); ++ assert_eq!(Uid::from_raw(xucred.uid()), Uid::current()); ++ assert_eq!(Gid::from_raw(xucred.groups()[0]), Gid::current()); ++} + + #[cfg(target_os = "linux")] + #[test] + fn is_so_mark_functional() { + use nix::sys::socket::sockopt; + +- require_capability!(CAP_NET_ADMIN); ++ require_capability!("is_so_mark_functional", CAP_NET_ADMIN); + +- let s = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), None).unwrap(); ++ let s = socket( ++ AddressFamily::Inet, ++ SockType::Stream, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); + setsockopt(s, sockopt::Mark, &1337).unwrap(); + let mark = getsockopt(s, sockopt::Mark).unwrap(); + assert_eq!(mark, 1337); +@@ -16,9 +75,14 @@ fn is_so_mark_functional() { + + #[test] + fn test_so_buf() { +- let fd = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), SockProtocol::Udp) +- .unwrap(); +- let bufsize: usize = thread_rng().gen_range(4096, 131_072); ++ let fd = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ SockProtocol::Udp, ++ ) ++ .unwrap(); ++ let bufsize: usize = thread_rng().gen_range(4096..131_072); + setsockopt(fd, sockopt::SndBuf, &bufsize).unwrap(); + let actual = getsockopt(fd, sockopt::SndBuf).unwrap(); + assert!(actual >= bufsize); +@@ -27,8 +91,95 @@ fn test_so_buf() { + assert!(actual >= bufsize); + } + ++#[test] ++fn test_so_tcp_maxseg() { ++ use nix::sys::socket::{accept, bind, connect, listen, SockaddrIn}; ++ use nix::unistd::{close, write}; ++ use std::net::SocketAddrV4; ++ use std::str::FromStr; ++ ++ let std_sa = SocketAddrV4::from_str("127.0.0.1:4001").unwrap(); ++ let sock_addr = SockaddrIn::from(std_sa); ++ ++ let rsock = socket( ++ AddressFamily::Inet, ++ SockType::Stream, ++ SockFlag::empty(), ++ SockProtocol::Tcp, ++ ) ++ .unwrap(); ++ bind(rsock, &sock_addr).unwrap(); ++ listen(rsock, 10).unwrap(); ++ let initial = getsockopt(rsock, sockopt::TcpMaxSeg).unwrap(); ++ // Initial MSS is expected to be 536 (https://tools.ietf.org/html/rfc879#section-1) but some ++ // platforms keep it even lower. This might fail if you've tuned your initial MSS to be larger ++ // than 700 ++ cfg_if! { ++ if #[cfg(any(target_os = "android", target_os = "linux"))] { ++ let segsize: u32 = 873; ++ assert!(initial < segsize); ++ setsockopt(rsock, sockopt::TcpMaxSeg, &segsize).unwrap(); ++ } else { ++ assert!(initial < 700); ++ } ++ } ++ ++ // Connect and check the MSS that was advertised ++ let ssock = socket( ++ AddressFamily::Inet, ++ SockType::Stream, ++ SockFlag::empty(), ++ SockProtocol::Tcp, ++ ) ++ .unwrap(); ++ connect(ssock, &sock_addr).unwrap(); ++ let rsess = accept(rsock).unwrap(); ++ write(rsess, b"hello").unwrap(); ++ let actual = getsockopt(ssock, sockopt::TcpMaxSeg).unwrap(); ++ // Actual max segment size takes header lengths into account, max IPv4 options (60 bytes) + max ++ // TCP options (40 bytes) are subtracted from the requested maximum as a lower boundary. ++ cfg_if! { ++ if #[cfg(any(target_os = "android", target_os = "linux"))] { ++ assert!((segsize - 100) <= actual); ++ assert!(actual <= segsize); ++ } else { ++ assert!(initial < actual); ++ assert!(536 < actual); ++ } ++ } ++ close(rsock).unwrap(); ++ close(ssock).unwrap(); ++} ++ ++#[test] ++fn test_so_type() { ++ let sockfd = socket( ++ AddressFamily::Inet, ++ SockType::Stream, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); ++ ++ assert_eq!(Ok(SockType::Stream), getsockopt(sockfd, sockopt::SockType)); ++} ++ ++/// getsockopt(_, sockopt::SockType) should gracefully handle unknown socket ++/// types. Regression test for https://github.com/nix-rust/nix/issues/1819 ++#[cfg(any(target_os = "android", target_os = "linux",))] ++#[test] ++fn test_so_type_unknown() { ++ use nix::errno::Errno; ++ ++ require_capability!("test_so_type", CAP_NET_RAW); ++ let sockfd = unsafe { libc::socket(libc::AF_PACKET, libc::SOCK_PACKET, 0) }; ++ assert!(sockfd >= 0, "Error opening socket: {}", nix::Error::last()); ++ ++ assert_eq!(Err(Errno::EINVAL), getsockopt(sockfd, sockopt::SockType)); ++} ++ + // The CI doesn't supported getsockopt and setsockopt on emulated processors. +-// It's beleived that a QEMU issue, the tests run ok on a fully emulated system. ++// It's believed that a QEMU issue, the tests run ok on a fully emulated system. + // Current CI just run the binary with QEMU but the Kernel remains the same as the host. + // So the syscall doesn't work properly unless the kernel is also emulated. + #[test] +@@ -39,15 +190,242 @@ fn test_so_buf() { + fn test_tcp_congestion() { + use std::ffi::OsString; + +- let fd = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), None).unwrap(); ++ let fd = socket( ++ AddressFamily::Inet, ++ SockType::Stream, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); + + let val = getsockopt(fd, sockopt::TcpCongestion).unwrap(); + setsockopt(fd, sockopt::TcpCongestion, &val).unwrap(); + +- setsockopt(fd, sockopt::TcpCongestion, &OsString::from("tcp_congestion_does_not_exist")).unwrap_err(); ++ setsockopt( ++ fd, ++ sockopt::TcpCongestion, ++ &OsString::from("tcp_congestion_does_not_exist"), ++ ) ++ .unwrap_err(); ++ ++ assert_eq!(getsockopt(fd, sockopt::TcpCongestion).unwrap(), val); ++} ++ ++#[test] ++#[cfg(any(target_os = "android", target_os = "linux"))] ++fn test_bindtodevice() { ++ skip_if_not_root!("test_bindtodevice"); ++ ++ let fd = socket( ++ AddressFamily::Inet, ++ SockType::Stream, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); ++ ++ let val = getsockopt(fd, sockopt::BindToDevice).unwrap(); ++ setsockopt(fd, sockopt::BindToDevice, &val).unwrap(); ++ ++ assert_eq!(getsockopt(fd, sockopt::BindToDevice).unwrap(), val); ++} ++ ++#[test] ++fn test_so_tcp_keepalive() { ++ let fd = socket( ++ AddressFamily::Inet, ++ SockType::Stream, ++ SockFlag::empty(), ++ SockProtocol::Tcp, ++ ) ++ .unwrap(); ++ setsockopt(fd, sockopt::KeepAlive, &true).unwrap(); ++ assert!(getsockopt(fd, sockopt::KeepAlive).unwrap()); ++ ++ #[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "linux" ++ ))] ++ { ++ let x = getsockopt(fd, sockopt::TcpKeepIdle).unwrap(); ++ setsockopt(fd, sockopt::TcpKeepIdle, &(x + 1)).unwrap(); ++ assert_eq!(getsockopt(fd, sockopt::TcpKeepIdle).unwrap(), x + 1); ++ ++ let x = getsockopt(fd, sockopt::TcpKeepCount).unwrap(); ++ setsockopt(fd, sockopt::TcpKeepCount, &(x + 1)).unwrap(); ++ assert_eq!(getsockopt(fd, sockopt::TcpKeepCount).unwrap(), x + 1); + +- assert_eq!( +- getsockopt(fd, sockopt::TcpCongestion).unwrap(), +- val ++ let x = getsockopt(fd, sockopt::TcpKeepInterval).unwrap(); ++ setsockopt(fd, sockopt::TcpKeepInterval, &(x + 1)).unwrap(); ++ assert_eq!(getsockopt(fd, sockopt::TcpKeepInterval).unwrap(), x + 1); ++ } ++} ++ ++#[test] ++#[cfg(any(target_os = "android", target_os = "linux"))] ++#[cfg_attr(qemu, ignore)] ++fn test_get_mtu() { ++ use nix::sys::socket::{bind, connect, SockaddrIn}; ++ use std::net::SocketAddrV4; ++ use std::str::FromStr; ++ ++ let std_sa = SocketAddrV4::from_str("127.0.0.1:4001").unwrap(); ++ let std_sb = SocketAddrV4::from_str("127.0.0.1:4002").unwrap(); ++ ++ let usock = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ SockProtocol::Udp, ++ ) ++ .unwrap(); ++ ++ // Bind and initiate connection ++ bind(usock, &SockaddrIn::from(std_sa)).unwrap(); ++ connect(usock, &SockaddrIn::from(std_sb)).unwrap(); ++ ++ // Loopback connections have 2^16 - the maximum - MTU ++ assert_eq!(getsockopt(usock, sockopt::IpMtu), Ok(u16::MAX as i32)) ++} ++ ++#[test] ++#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] ++fn test_ttl_opts() { ++ let fd4 = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); ++ setsockopt(fd4, sockopt::Ipv4Ttl, &1) ++ .expect("setting ipv4ttl on an inet socket should succeed"); ++ let fd6 = socket( ++ AddressFamily::Inet6, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); ++ setsockopt(fd6, sockopt::Ipv6Ttl, &1) ++ .expect("setting ipv6ttl on an inet6 socket should succeed"); ++} ++ ++#[test] ++#[cfg(any(target_os = "ios", target_os = "macos"))] ++fn test_dontfrag_opts() { ++ let fd4 = socket( ++ AddressFamily::Inet, ++ SockType::Stream, ++ SockFlag::empty(), ++ SockProtocol::Tcp, ++ ) ++ .unwrap(); ++ setsockopt(fd4, sockopt::IpDontFrag, &true) ++ .expect("setting IP_DONTFRAG on an inet stream socket should succeed"); ++ setsockopt(fd4, sockopt::IpDontFrag, &false).expect( ++ "unsetting IP_DONTFRAG on an inet stream socket should succeed", ++ ); ++ let fd4d = socket( ++ AddressFamily::Inet, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); ++ setsockopt(fd4d, sockopt::IpDontFrag, &true).expect( ++ "setting IP_DONTFRAG on an inet datagram socket should succeed", + ); ++ setsockopt(fd4d, sockopt::IpDontFrag, &false).expect( ++ "unsetting IP_DONTFRAG on an inet datagram socket should succeed", ++ ); ++} ++ ++#[test] ++#[cfg(any( ++ target_os = "android", ++ target_os = "ios", ++ target_os = "linux", ++ target_os = "macos", ++))] ++// Disable the test under emulation because it fails in Cirrus-CI. Lack ++// of QEMU support is suspected. ++#[cfg_attr(qemu, ignore)] ++fn test_v6dontfrag_opts() { ++ let fd6 = socket( ++ AddressFamily::Inet6, ++ SockType::Stream, ++ SockFlag::empty(), ++ SockProtocol::Tcp, ++ ) ++ .unwrap(); ++ setsockopt(fd6, sockopt::Ipv6DontFrag, &true).expect( ++ "setting IPV6_DONTFRAG on an inet6 stream socket should succeed", ++ ); ++ setsockopt(fd6, sockopt::Ipv6DontFrag, &false).expect( ++ "unsetting IPV6_DONTFRAG on an inet6 stream socket should succeed", ++ ); ++ let fd6d = socket( ++ AddressFamily::Inet6, ++ SockType::Datagram, ++ SockFlag::empty(), ++ None, ++ ) ++ .unwrap(); ++ setsockopt(fd6d, sockopt::Ipv6DontFrag, &true).expect( ++ "setting IPV6_DONTFRAG on an inet6 datagram socket should succeed", ++ ); ++ setsockopt(fd6d, sockopt::Ipv6DontFrag, &false).expect( ++ "unsetting IPV6_DONTFRAG on an inet6 datagram socket should succeed", ++ ); ++} ++ ++#[test] ++#[cfg(target_os = "linux")] ++fn test_so_priority() { ++ let fd = socket( ++ AddressFamily::Inet, ++ SockType::Stream, ++ SockFlag::empty(), ++ SockProtocol::Tcp, ++ ) ++ .unwrap(); ++ let priority = 3; ++ setsockopt(fd, sockopt::Priority, &priority).unwrap(); ++ assert_eq!(getsockopt(fd, sockopt::Priority).unwrap(), priority); ++} ++ ++#[test] ++#[cfg(target_os = "linux")] ++fn test_ip_tos() { ++ let fd = socket( ++ AddressFamily::Inet, ++ SockType::Stream, ++ SockFlag::empty(), ++ SockProtocol::Tcp, ++ ) ++ .unwrap(); ++ let tos = 0x80; // CS4 ++ setsockopt(fd, sockopt::IpTos, &tos).unwrap(); ++ assert_eq!(getsockopt(fd, sockopt::IpTos).unwrap(), tos); ++} ++ ++#[test] ++#[cfg(target_os = "linux")] ++// Disable the test under emulation because it fails in Cirrus-CI. Lack ++// of QEMU support is suspected. ++#[cfg_attr(qemu, ignore)] ++fn test_ipv6_tclass() { ++ let fd = socket( ++ AddressFamily::Inet6, ++ SockType::Stream, ++ SockFlag::empty(), ++ SockProtocol::Tcp, ++ ) ++ .unwrap(); ++ let class = 0x80; // CS4 ++ setsockopt(fd, sockopt::Ipv6TClass, &class).unwrap(); ++ assert_eq!(getsockopt(fd, sockopt::Ipv6TClass).unwrap(), class); + } +diff --git a/vendor/nix/test/sys/test_stat.rs b/vendor/nix/test/sys/test_stat.rs +new file mode 100644 +index 0000000..426b4b6 +--- /dev/null ++++ b/vendor/nix/test/sys/test_stat.rs +@@ -0,0 +1,29 @@ ++// The conversion is not useless on all platforms. ++#[allow(clippy::useless_conversion)] ++#[cfg(target_os = "freebsd")] ++#[test] ++fn test_chflags() { ++ use nix::{ ++ sys::stat::{fstat, FileFlag}, ++ unistd::chflags, ++ }; ++ use std::os::unix::io::AsRawFd; ++ use tempfile::NamedTempFile; ++ ++ let f = NamedTempFile::new().unwrap(); ++ ++ let initial = FileFlag::from_bits_truncate( ++ fstat(f.as_raw_fd()).unwrap().st_flags.into(), ++ ); ++ // UF_OFFLINE is preserved by all FreeBSD file systems, but not interpreted ++ // in any way, so it's handy for testing. ++ let commanded = initial ^ FileFlag::UF_OFFLINE; ++ ++ chflags(f.path(), commanded).unwrap(); ++ ++ let changed = FileFlag::from_bits_truncate( ++ fstat(f.as_raw_fd()).unwrap().st_flags.into(), ++ ); ++ ++ assert_eq!(commanded, changed); ++} +diff --git a/vendor/nix/test/sys/test_sysinfo.rs b/vendor/nix/test/sys/test_sysinfo.rs +index 73e6586..2897366 100644 +--- a/vendor/nix/test/sys/test_sysinfo.rs ++++ b/vendor/nix/test/sys/test_sysinfo.rs +@@ -9,10 +9,12 @@ fn sysinfo_works() { + assert!(l5 >= 0.0); + assert!(l15 >= 0.0); + +- info.uptime(); // just test Duration construction ++ info.uptime(); // just test Duration construction + +- assert!(info.swap_free() <= info.swap_total(), +- "more swap available than installed (free: {}, total: {})", +- info.swap_free(), +- info.swap_total()); ++ assert!( ++ info.swap_free() <= info.swap_total(), ++ "more swap available than installed (free: {}, total: {})", ++ info.swap_free(), ++ info.swap_total() ++ ); + } +diff --git a/vendor/nix/test/sys/test_termios.rs b/vendor/nix/test/sys/test_termios.rs +index a14b8ce..aaf0008 100644 +--- a/vendor/nix/test/sys/test_termios.rs ++++ b/vendor/nix/test/sys/test_termios.rs +@@ -1,11 +1,11 @@ + use std::os::unix::prelude::*; + use tempfile::tempfile; + +-use nix::{Error, fcntl}; + use nix::errno::Errno; ++use nix::fcntl; + use nix::pty::openpty; +-use nix::sys::termios::{self, LocalFlags, OutputFlags, Termios, tcgetattr}; +-use nix::unistd::{read, write, close}; ++use nix::sys::termios::{self, tcgetattr, LocalFlags, OutputFlags}; ++use nix::unistd::{close, read, write}; + + /// Helper function analogous to `std::io::Write::write_all`, but for `RawFd`s + fn write_all(f: RawFd, buf: &[u8]) { +@@ -19,10 +19,10 @@ fn write_all(f: RawFd, buf: &[u8]) { + #[test] + fn test_tcgetattr_pty() { + // openpty uses ptname(3) internally +- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::PTSNAME_MTX.lock(); + + let pty = openpty(None, None).expect("openpty failed"); +- assert!(termios::tcgetattr(pty.master).is_ok()); ++ termios::tcgetattr(pty.slave).unwrap(); + close(pty.master).expect("closing the master failed"); + close(pty.slave).expect("closing the slave failed"); + } +@@ -31,40 +31,45 @@ fn test_tcgetattr_pty() { + #[test] + fn test_tcgetattr_enotty() { + let file = tempfile().unwrap(); +- assert_eq!(termios::tcgetattr(file.as_raw_fd()).err(), +- Some(Error::Sys(Errno::ENOTTY))); ++ assert_eq!( ++ termios::tcgetattr(file.as_raw_fd()).err(), ++ Some(Errno::ENOTTY) ++ ); + } + + // Test tcgetattr on an invalid file descriptor + #[test] + fn test_tcgetattr_ebadf() { +- assert_eq!(termios::tcgetattr(-1).err(), +- Some(Error::Sys(Errno::EBADF))); ++ assert_eq!(termios::tcgetattr(-1).err(), Some(Errno::EBADF)); + } + + // Test modifying output flags + #[test] + fn test_output_flags() { + // openpty uses ptname(3) internally +- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::PTSNAME_MTX.lock(); + + // Open one pty to get attributes for the second one + let mut termios = { + let pty = openpty(None, None).expect("openpty failed"); + assert!(pty.master > 0); + assert!(pty.slave > 0); +- let termios = tcgetattr(pty.master).expect("tcgetattr failed"); ++ let termios = tcgetattr(pty.slave).expect("tcgetattr failed"); + close(pty.master).unwrap(); + close(pty.slave).unwrap(); + termios + }; + + // Make sure postprocessing '\r' isn't specified by default or this test is useless. +- assert!(!termios.output_flags.contains(OutputFlags::OPOST | OutputFlags::OCRNL)); ++ assert!(!termios ++ .output_flags ++ .contains(OutputFlags::OPOST | OutputFlags::OCRNL)); + + // Specify that '\r' characters should be transformed to '\n' + // OPOST is specified to enable post-processing +- termios.output_flags.insert(OutputFlags::OPOST | OutputFlags::OCRNL); ++ termios ++ .output_flags ++ .insert(OutputFlags::OPOST | OutputFlags::OCRNL); + + // Open a pty + let pty = openpty(None, &termios).unwrap(); +@@ -77,7 +82,7 @@ fn test_output_flags() { + + // Read from the slave verifying that the output has been properly transformed + let mut buf = [0u8; 10]; +- ::read_exact(pty.slave, &mut buf); ++ crate::read_exact(pty.slave, &mut buf); + let transformed_string = "foofoofoo\n"; + close(pty.master).unwrap(); + close(pty.slave).unwrap(); +@@ -88,14 +93,14 @@ fn test_output_flags() { + #[test] + fn test_local_flags() { + // openpty uses ptname(3) internally +- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::PTSNAME_MTX.lock(); + + // Open one pty to get attributes for the second one + let mut termios = { + let pty = openpty(None, None).unwrap(); + assert!(pty.master > 0); + assert!(pty.slave > 0); +- let termios = tcgetattr(pty.master).unwrap(); ++ let termios = tcgetattr(pty.slave).unwrap(); + close(pty.master).unwrap(); + close(pty.slave).unwrap(); + termios +@@ -114,7 +119,8 @@ fn test_local_flags() { + + // Set the master is in nonblocking mode or reading will never return. + let flags = fcntl::fcntl(pty.master, fcntl::F_GETFL).unwrap(); +- let new_flags = fcntl::OFlag::from_bits_truncate(flags) | fcntl::OFlag::O_NONBLOCK; ++ let new_flags = ++ fcntl::OFlag::from_bits_truncate(flags) | fcntl::OFlag::O_NONBLOCK; + fcntl::fcntl(pty.master, fcntl::F_SETFL(new_flags)).unwrap(); + + // Write into the master +@@ -126,11 +132,5 @@ fn test_local_flags() { + let read = read(pty.master, &mut buf).unwrap_err(); + close(pty.master).unwrap(); + close(pty.slave).unwrap(); +- assert_eq!(read, Error::Sys(Errno::EAGAIN)); +-} +- +-#[test] +-fn test_cfmakeraw() { +- let mut termios = unsafe { Termios::default_uninit() }; +- termios::cfmakeraw(&mut termios); ++ assert_eq!(read, Errno::EAGAIN); + } +diff --git a/vendor/nix/test/sys/test_timerfd.rs b/vendor/nix/test/sys/test_timerfd.rs +new file mode 100644 +index 0000000..08e2921 +--- /dev/null ++++ b/vendor/nix/test/sys/test_timerfd.rs +@@ -0,0 +1,69 @@ ++use nix::sys::time::{TimeSpec, TimeValLike}; ++use nix::sys::timerfd::{ ++ ClockId, Expiration, TimerFd, TimerFlags, TimerSetTimeFlags, ++}; ++use std::time::Instant; ++ ++#[test] ++pub fn test_timerfd_oneshot() { ++ let timer = ++ TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty()).unwrap(); ++ ++ let before = Instant::now(); ++ ++ timer ++ .set( ++ Expiration::OneShot(TimeSpec::seconds(1)), ++ TimerSetTimeFlags::empty(), ++ ) ++ .unwrap(); ++ ++ timer.wait().unwrap(); ++ ++ let millis = before.elapsed().as_millis(); ++ assert!(millis > 900); ++} ++ ++#[test] ++pub fn test_timerfd_interval() { ++ let timer = ++ TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty()).unwrap(); ++ ++ let before = Instant::now(); ++ timer ++ .set( ++ Expiration::IntervalDelayed( ++ TimeSpec::seconds(1), ++ TimeSpec::seconds(2), ++ ), ++ TimerSetTimeFlags::empty(), ++ ) ++ .unwrap(); ++ ++ timer.wait().unwrap(); ++ ++ let start_delay = before.elapsed().as_millis(); ++ assert!(start_delay > 900); ++ ++ timer.wait().unwrap(); ++ ++ let interval_delay = before.elapsed().as_millis(); ++ assert!(interval_delay > 2900); ++} ++ ++#[test] ++pub fn test_timerfd_unset() { ++ let timer = ++ TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty()).unwrap(); ++ ++ timer ++ .set( ++ Expiration::OneShot(TimeSpec::seconds(1)), ++ TimerSetTimeFlags::empty(), ++ ) ++ .unwrap(); ++ ++ timer.unset().unwrap(); ++ ++ assert!(timer.get().unwrap().is_none()); ++} +diff --git a/vendor/nix/test/sys/test_uio.rs b/vendor/nix/test/sys/test_uio.rs +index 62c9f95..0f4b8a6 100644 +--- a/vendor/nix/test/sys/test_uio.rs ++++ b/vendor/nix/test/sys/test_uio.rs +@@ -1,18 +1,28 @@ + use nix::sys::uio::*; + use nix::unistd::*; +-use rand::{thread_rng, Rng}; + use rand::distributions::Alphanumeric; +-use std::{cmp, iter}; +-use std::fs::{OpenOptions}; ++use rand::{thread_rng, Rng}; ++use std::fs::OpenOptions; ++use std::io::IoSlice; + use std::os::unix::io::AsRawFd; ++use std::{cmp, iter}; ++ ++#[cfg(not(target_os = "redox"))] ++use std::io::IoSliceMut; + +-use tempfile::{tempfile, tempdir}; ++use tempfile::tempdir; ++#[cfg(not(target_os = "redox"))] ++use tempfile::tempfile; + + #[test] + fn test_writev() { + let mut to_write = Vec::with_capacity(16 * 128); + for _ in 0..16 { +- let s: String = thread_rng().sample_iter(&Alphanumeric).take(128).collect(); ++ let s: String = thread_rng() ++ .sample_iter(&Alphanumeric) ++ .map(char::from) ++ .take(128) ++ .collect(); + let b = s.as_bytes(); + to_write.extend(b.iter().cloned()); + } +@@ -21,92 +31,91 @@ fn test_writev() { + let mut consumed = 0; + while consumed < to_write.len() { + let left = to_write.len() - consumed; +- let slice_len = if left <= 64 { left } else { thread_rng().gen_range(64, cmp::min(256, left)) }; +- let b = &to_write[consumed..consumed+slice_len]; +- iovecs.push(IoVec::from_slice(b)); ++ let slice_len = if left <= 64 { ++ left ++ } else { ++ thread_rng().gen_range(64..cmp::min(256, left)) ++ }; ++ let b = &to_write[consumed..consumed + slice_len]; ++ iovecs.push(IoSlice::new(b)); + consumed += slice_len; + } + let pipe_res = pipe(); +- assert!(pipe_res.is_ok()); +- let (reader, writer) = pipe_res.ok().unwrap(); ++ let (reader, writer) = pipe_res.expect("Couldn't create pipe"); + // FileDesc will close its filedesc (reader). + let mut read_buf: Vec = iter::repeat(0u8).take(128 * 16).collect(); + // Blocking io, should write all data. + let write_res = writev(writer, &iovecs); +- // Successful write +- assert!(write_res.is_ok()); +- let written = write_res.ok().unwrap(); ++ let written = write_res.expect("couldn't write"); + // Check whether we written all data + assert_eq!(to_write.len(), written); + let read_res = read(reader, &mut read_buf[..]); +- // Successful read +- assert!(read_res.is_ok()); +- let read = read_res.ok().unwrap() as usize; ++ let read = read_res.expect("couldn't read"); + // Check we have read as much as we written + assert_eq!(read, written); + // Check equality of written and read data + assert_eq!(&to_write, &read_buf); +- let close_res = close(writer); +- assert!(close_res.is_ok()); +- let close_res = close(reader); +- assert!(close_res.is_ok()); ++ close(writer).expect("closed writer"); ++ close(reader).expect("closed reader"); + } + + #[test] ++#[cfg(not(target_os = "redox"))] + fn test_readv() { +- let s:String = thread_rng().sample_iter(&Alphanumeric).take(128).collect(); ++ let s: String = thread_rng() ++ .sample_iter(&Alphanumeric) ++ .map(char::from) ++ .take(128) ++ .collect(); + let to_write = s.as_bytes().to_vec(); + let mut storage = Vec::new(); + let mut allocated = 0; + while allocated < to_write.len() { + let left = to_write.len() - allocated; +- let vec_len = if left <= 64 { left } else { thread_rng().gen_range(64, cmp::min(256, left)) }; ++ let vec_len = if left <= 64 { ++ left ++ } else { ++ thread_rng().gen_range(64..cmp::min(256, left)) ++ }; + let v: Vec = iter::repeat(0u8).take(vec_len).collect(); + storage.push(v); + allocated += vec_len; + } + let mut iovecs = Vec::with_capacity(storage.len()); + for v in &mut storage { +- iovecs.push(IoVec::from_mut_slice(&mut v[..])); ++ iovecs.push(IoSliceMut::new(&mut v[..])); + } +- let pipe_res = pipe(); +- assert!(pipe_res.is_ok()); +- let (reader, writer) = pipe_res.ok().unwrap(); ++ let (reader, writer) = pipe().expect("couldn't create pipe"); + // Blocking io, should write all data. +- let write_res = write(writer, &to_write); +- // Successful write +- assert!(write_res.is_ok()); +- let read_res = readv(reader, &mut iovecs[..]); +- assert!(read_res.is_ok()); +- let read = read_res.ok().unwrap(); ++ write(writer, &to_write).expect("write failed"); ++ let read = readv(reader, &mut iovecs[..]).expect("read failed"); + // Check whether we've read all data + assert_eq!(to_write.len(), read); + // Cccumulate data from iovecs + let mut read_buf = Vec::with_capacity(to_write.len()); + for iovec in &iovecs { +- read_buf.extend(iovec.as_slice().iter().cloned()); ++ read_buf.extend(iovec.iter().cloned()); + } + // Check whether iovecs contain all written data + assert_eq!(read_buf.len(), to_write.len()); + // Check equality of written and read data + assert_eq!(&read_buf, &to_write); +- let close_res = close(reader); +- assert!(close_res.is_ok()); +- let close_res = close(writer); +- assert!(close_res.is_ok()); ++ close(reader).expect("couldn't close reader"); ++ close(writer).expect("couldn't close writer"); + } + + #[test] ++#[cfg(not(target_os = "redox"))] + fn test_pwrite() { + use std::io::Read; + + let mut file = tempfile().unwrap(); +- let buf = [1u8;8]; ++ let buf = [1u8; 8]; + assert_eq!(Ok(8), pwrite(file.as_raw_fd(), &buf, 8)); + let mut file_content = Vec::new(); + file.read_to_end(&mut file_content).unwrap(); +- let mut expected = vec![0u8;8]; +- expected.extend(vec![1;8]); ++ let mut expected = vec![0u8; 8]; ++ expected.extend(vec![1; 8]); + assert_eq!(file_content, expected); + } + +@@ -117,37 +126,47 @@ fn test_pread() { + let tempdir = tempdir().unwrap(); + + let path = tempdir.path().join("pread_test_file"); +- let mut file = OpenOptions::new().write(true).read(true).create(true) +- .truncate(true).open(path).unwrap(); ++ let mut file = OpenOptions::new() ++ .write(true) ++ .read(true) ++ .create(true) ++ .truncate(true) ++ .open(path) ++ .unwrap(); + let file_content: Vec = (0..64).collect(); + file.write_all(&file_content).unwrap(); + +- let mut buf = [0u8;16]; ++ let mut buf = [0u8; 16]; + assert_eq!(Ok(16), pread(file.as_raw_fd(), &mut buf, 16)); + let expected: Vec<_> = (16..32).collect(); + assert_eq!(&buf[..], &expected[..]); + } + + #[test] +-#[cfg(target_os = "linux")] ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] + fn test_pwritev() { + use std::io::Read; + + let to_write: Vec = (0..128).collect(); +- let expected: Vec = [vec![0;100], to_write.clone()].concat(); ++ let expected: Vec = [vec![0; 100], to_write.clone()].concat(); + + let iovecs = [ +- IoVec::from_slice(&to_write[0..17]), +- IoVec::from_slice(&to_write[17..64]), +- IoVec::from_slice(&to_write[64..128]), ++ IoSlice::new(&to_write[0..17]), ++ IoSlice::new(&to_write[17..64]), ++ IoSlice::new(&to_write[64..128]), + ]; + + let tempdir = tempdir().unwrap(); + + // pwritev them into a temporary file + let path = tempdir.path().join("pwritev_test_file"); +- let mut file = OpenOptions::new().write(true).read(true).create(true) +- .truncate(true).open(path).unwrap(); ++ let mut file = OpenOptions::new() ++ .write(true) ++ .read(true) ++ .create(true) ++ .truncate(true) ++ .open(path) ++ .unwrap(); + + let written = pwritev(file.as_raw_fd(), &iovecs, 100).ok().unwrap(); + assert_eq!(written, to_write.len()); +@@ -159,7 +178,7 @@ fn test_pwritev() { + } + + #[test] +-#[cfg(target_os = "linux")] ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] + fn test_preadv() { + use std::io::Write; + +@@ -170,21 +189,24 @@ fn test_preadv() { + + let path = tempdir.path().join("preadv_test_file"); + +- let mut file = OpenOptions::new().read(true).write(true).create(true) +- .truncate(true).open(path).unwrap(); ++ let mut file = OpenOptions::new() ++ .read(true) ++ .write(true) ++ .create(true) ++ .truncate(true) ++ .open(path) ++ .unwrap(); + file.write_all(&to_write).unwrap(); + +- let mut buffers: Vec> = vec![ +- vec![0; 24], +- vec![0; 1], +- vec![0; 75], +- ]; ++ let mut buffers: Vec> = vec![vec![0; 24], vec![0; 1], vec![0; 75]]; + + { + // Borrow the buffers into IoVecs and preadv into them +- let iovecs: Vec<_> = buffers.iter_mut().map( +- |buf| IoVec::from_mut_slice(&mut buf[..])).collect(); +- assert_eq!(Ok(100), preadv(file.as_raw_fd(), &iovecs, 100)); ++ let mut iovecs: Vec<_> = buffers ++ .iter_mut() ++ .map(|buf| IoSliceMut::new(&mut buf[..])) ++ .collect(); ++ assert_eq!(Ok(100), preadv(file.as_raw_fd(), &mut iovecs, 100)); + } + + let all = buffers.concat(); +@@ -192,23 +214,25 @@ fn test_preadv() { + } + + #[test] +-#[cfg(target_os = "linux")] +-// FIXME: qemu-user doesn't implement process_vm_readv/writev on most arches +-#[cfg_attr(not(any(target_arch = "x86", target_arch = "x86_64")), ignore)] ++#[cfg(all(target_os = "linux", not(target_env = "uclibc")))] ++// uclibc doesn't implement process_vm_readv ++// qemu-user doesn't implement process_vm_readv/writev on most arches ++#[cfg_attr(qemu, ignore)] + fn test_process_vm_readv() { +- use nix::unistd::ForkResult::*; ++ use crate::*; + use nix::sys::signal::*; + use nix::sys::wait::*; ++ use nix::unistd::ForkResult::*; + +- require_capability!(CAP_SYS_PTRACE); +- let _ = ::FORK_MTX.lock().expect("Mutex got poisoned by another test"); ++ require_capability!("test_process_vm_readv", CAP_SYS_PTRACE); ++ let _m = crate::FORK_MTX.lock(); + + // Pre-allocate memory in the child, since allocation isn't safe + // post-fork (~= async-signal-safe) + let mut vector = vec![1u8, 2, 3, 4, 5]; + + let (r, w) = pipe().unwrap(); +- match fork().expect("Error: Fork Failed") { ++ match unsafe { fork() }.expect("Error: Fork Failed") { + Parent { child } => { + close(w).unwrap(); + // wait for child +@@ -219,16 +243,18 @@ fn test_process_vm_readv() { + let remote_iov = RemoteIoVec { base: ptr, len: 5 }; + let mut buf = vec![0u8; 5]; + +- let ret = process_vm_readv(child, +- &[IoVec::from_mut_slice(&mut buf)], +- &[remote_iov]); ++ let ret = process_vm_readv( ++ child, ++ &mut [IoSliceMut::new(&mut buf)], ++ &[remote_iov], ++ ); + + kill(child, SIGTERM).unwrap(); + waitpid(child, None).unwrap(); + + assert_eq!(Ok(5), ret); + assert_eq!(20u8, buf.iter().sum()); +- }, ++ } + Child => { + let _ = close(r); + for i in &mut vector { +@@ -236,7 +262,9 @@ fn test_process_vm_readv() { + } + let _ = write(w, b"\0"); + let _ = close(w); +- loop { let _ = pause(); } +- }, ++ loop { ++ pause(); ++ } ++ } + } + } +diff --git a/vendor/nix/test/sys/test_wait.rs b/vendor/nix/test/sys/test_wait.rs +index 1a189a3..d472f1e 100644 +--- a/vendor/nix/test/sys/test_wait.rs ++++ b/vendor/nix/test/sys/test_wait.rs +@@ -1,53 +1,118 @@ +-use nix::Error; +-use nix::unistd::*; +-use nix::unistd::ForkResult::*; ++use libc::_exit; ++use nix::errno::Errno; + use nix::sys::signal::*; + use nix::sys::wait::*; +-use libc::_exit; ++use nix::unistd::ForkResult::*; ++use nix::unistd::*; + + #[test] ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] + fn test_wait_signal() { +- let _ = ::FORK_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::FORK_MTX.lock(); ++ ++ // Safe: The child only calls `pause` and/or `_exit`, which are async-signal-safe. ++ match unsafe { fork() }.expect("Error: Fork Failed") { ++ Child => { ++ pause(); ++ unsafe { _exit(123) } ++ } ++ Parent { child } => { ++ kill(child, Some(SIGKILL)).expect("Error: Kill Failed"); ++ assert_eq!( ++ waitpid(child, None), ++ Ok(WaitStatus::Signaled(child, SIGKILL, false)) ++ ); ++ } ++ } ++} ++ ++#[test] ++#[cfg(any( ++ target_os = "android", ++ target_os = "freebsd", ++ //target_os = "haiku", ++ all(target_os = "linux", not(target_env = "uclibc")), ++))] ++#[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] ++fn test_waitid_signal() { ++ let _m = crate::FORK_MTX.lock(); + + // Safe: The child only calls `pause` and/or `_exit`, which are async-signal-safe. +- match fork().expect("Error: Fork Failed") { +- Child => { +- pause(); +- unsafe { _exit(123) } +- }, +- Parent { child } => { +- kill(child, Some(SIGKILL)).expect("Error: Kill Failed"); +- assert_eq!(waitpid(child, None), Ok(WaitStatus::Signaled(child, SIGKILL, false))); +- }, ++ match unsafe { fork() }.expect("Error: Fork Failed") { ++ Child => { ++ pause(); ++ unsafe { _exit(123) } ++ } ++ Parent { child } => { ++ kill(child, Some(SIGKILL)).expect("Error: Kill Failed"); ++ assert_eq!( ++ waitid(Id::Pid(child), WaitPidFlag::WEXITED), ++ Ok(WaitStatus::Signaled(child, SIGKILL, false)), ++ ); ++ } + } + } + + #[test] + fn test_wait_exit() { +- let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::FORK_MTX.lock(); ++ ++ // Safe: Child only calls `_exit`, which is async-signal-safe. ++ match unsafe { fork() }.expect("Error: Fork Failed") { ++ Child => unsafe { ++ _exit(12); ++ }, ++ Parent { child } => { ++ assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 12))); ++ } ++ } ++} ++ ++#[cfg(not(target_os = "haiku"))] ++#[test] ++#[cfg(any( ++ target_os = "android", ++ target_os = "freebsd", ++ target_os = "haiku", ++ all(target_os = "linux", not(target_env = "uclibc")), ++))] ++#[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] ++fn test_waitid_exit() { ++ let _m = crate::FORK_MTX.lock(); + + // Safe: Child only calls `_exit`, which is async-signal-safe. +- match fork().expect("Error: Fork Failed") { +- Child => unsafe { _exit(12); }, +- Parent { child } => { +- assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 12))); +- }, ++ match unsafe { fork() }.expect("Error: Fork Failed") { ++ Child => unsafe { ++ _exit(12); ++ }, ++ Parent { child } => { ++ assert_eq!( ++ waitid(Id::Pid(child), WaitPidFlag::WEXITED), ++ Ok(WaitStatus::Exited(child, 12)), ++ ); ++ } + } + } + + #[test] + fn test_waitstatus_from_raw() { + let pid = Pid::from_raw(1); +- assert_eq!(WaitStatus::from_raw(pid, 0x0002), Ok(WaitStatus::Signaled(pid, Signal::SIGINT, false))); +- assert_eq!(WaitStatus::from_raw(pid, 0x0200), Ok(WaitStatus::Exited(pid, 2))); +- assert_eq!(WaitStatus::from_raw(pid, 0x7f7f), Err(Error::invalid_argument())); ++ assert_eq!( ++ WaitStatus::from_raw(pid, 0x0002), ++ Ok(WaitStatus::Signaled(pid, Signal::SIGINT, false)) ++ ); ++ assert_eq!( ++ WaitStatus::from_raw(pid, 0x0200), ++ Ok(WaitStatus::Exited(pid, 2)) ++ ); ++ assert_eq!(WaitStatus::from_raw(pid, 0x7f7f), Err(Errno::EINVAL)); + } + + #[test] + fn test_waitstatus_pid() { +- let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::FORK_MTX.lock(); + +- match fork().unwrap() { ++ match unsafe { fork() }.unwrap() { + Child => unsafe { _exit(0) }, + Parent { child } => { + let status = waitpid(child, None).unwrap(); +@@ -56,16 +121,36 @@ fn test_waitstatus_pid() { + } + } + ++#[test] ++#[cfg(any( ++ target_os = "android", ++ target_os = "freebsd", ++ target_os = "haiku", ++ all(target_os = "linux", not(target_env = "uclibc")), ++))] ++fn test_waitid_pid() { ++ let _m = crate::FORK_MTX.lock(); ++ ++ match unsafe { fork() }.unwrap() { ++ Child => unsafe { _exit(0) }, ++ Parent { child } => { ++ let status = waitid(Id::Pid(child), WaitPidFlag::WEXITED).unwrap(); ++ assert_eq!(status.pid(), Some(child)); ++ } ++ } ++} ++ + #[cfg(any(target_os = "linux", target_os = "android"))] + // FIXME: qemu-user doesn't implement ptrace on most arches + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + mod ptrace { +- use nix::sys::ptrace::{self, Options, Event}; ++ use crate::*; ++ use libc::_exit; ++ use nix::sys::ptrace::{self, Event, Options}; + use nix::sys::signal::*; + use nix::sys::wait::*; +- use nix::unistd::*; + use nix::unistd::ForkResult::*; +- use libc::_exit; ++ use nix::unistd::*; + + fn ptrace_child() -> ! { + ptrace::traceme().unwrap(); +@@ -75,31 +160,98 @@ mod ptrace { + unsafe { _exit(0) } + } + +- fn ptrace_parent(child: Pid) { ++ fn ptrace_wait_parent(child: Pid) { + // Wait for the raised SIGTRAP +- assert_eq!(waitpid(child, None), Ok(WaitStatus::Stopped(child, SIGTRAP))); ++ assert_eq!( ++ waitpid(child, None), ++ Ok(WaitStatus::Stopped(child, SIGTRAP)) ++ ); + // We want to test a syscall stop and a PTRACE_EVENT stop +- assert!(ptrace::setoptions(child, Options::PTRACE_O_TRACESYSGOOD | Options::PTRACE_O_TRACEEXIT).is_ok()); ++ ptrace::setoptions( ++ child, ++ Options::PTRACE_O_TRACESYSGOOD | Options::PTRACE_O_TRACEEXIT, ++ ) ++ .expect("setoptions failed"); + + // First, stop on the next system call, which will be exit() +- assert!(ptrace::syscall(child, None).is_ok()); ++ ptrace::syscall(child, None).expect("syscall failed"); + assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceSyscall(child))); + // Then get the ptrace event for the process exiting +- assert!(ptrace::cont(child, None).is_ok()); +- assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceEvent(child, SIGTRAP, Event::PTRACE_EVENT_EXIT as i32))); ++ ptrace::cont(child, None).expect("cont failed"); ++ assert_eq!( ++ waitpid(child, None), ++ Ok(WaitStatus::PtraceEvent( ++ child, ++ SIGTRAP, ++ Event::PTRACE_EVENT_EXIT as i32 ++ )) ++ ); + // Finally get the normal wait() result, now that the process has exited +- assert!(ptrace::cont(child, None).is_ok()); ++ ptrace::cont(child, None).expect("cont failed"); + assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 0))); + } + ++ #[cfg(not(target_env = "uclibc"))] ++ fn ptrace_waitid_parent(child: Pid) { ++ // Wait for the raised SIGTRAP ++ // ++ // Unlike waitpid(), waitid() can distinguish trap events from regular ++ // stop events, so unlike ptrace_wait_parent(), we get a PtraceEvent here ++ assert_eq!( ++ waitid(Id::Pid(child), WaitPidFlag::WEXITED), ++ Ok(WaitStatus::PtraceEvent(child, SIGTRAP, 0)), ++ ); ++ // We want to test a syscall stop and a PTRACE_EVENT stop ++ ptrace::setoptions( ++ child, ++ Options::PTRACE_O_TRACESYSGOOD | Options::PTRACE_O_TRACEEXIT, ++ ) ++ .expect("setopts failed"); ++ ++ // First, stop on the next system call, which will be exit() ++ ptrace::syscall(child, None).expect("syscall failed"); ++ assert_eq!( ++ waitid(Id::Pid(child), WaitPidFlag::WEXITED), ++ Ok(WaitStatus::PtraceSyscall(child)), ++ ); ++ // Then get the ptrace event for the process exiting ++ ptrace::cont(child, None).expect("cont failed"); ++ assert_eq!( ++ waitid(Id::Pid(child), WaitPidFlag::WEXITED), ++ Ok(WaitStatus::PtraceEvent( ++ child, ++ SIGTRAP, ++ Event::PTRACE_EVENT_EXIT as i32 ++ )), ++ ); ++ // Finally get the normal wait() result, now that the process has exited ++ ptrace::cont(child, None).expect("cont failed"); ++ assert_eq!( ++ waitid(Id::Pid(child), WaitPidFlag::WEXITED), ++ Ok(WaitStatus::Exited(child, 0)), ++ ); ++ } ++ + #[test] + fn test_wait_ptrace() { +- require_capability!(CAP_SYS_PTRACE); +- let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test"); ++ require_capability!("test_wait_ptrace", CAP_SYS_PTRACE); ++ let _m = crate::FORK_MTX.lock(); ++ ++ match unsafe { fork() }.expect("Error: Fork Failed") { ++ Child => ptrace_child(), ++ Parent { child } => ptrace_wait_parent(child), ++ } ++ } ++ ++ #[test] ++ #[cfg(not(target_env = "uclibc"))] ++ fn test_waitid_ptrace() { ++ require_capability!("test_waitid_ptrace", CAP_SYS_PTRACE); ++ let _m = crate::FORK_MTX.lock(); + +- match fork().expect("Error: Fork Failed") { ++ match unsafe { fork() }.expect("Error: Fork Failed") { + Child => ptrace_child(), +- Parent { child } => ptrace_parent(child), ++ Parent { child } => ptrace_waitid_parent(child), + } + } + } +diff --git a/vendor/nix/test/test.rs b/vendor/nix/test/test.rs +index 370ae03..6b42aad 100644 +--- a/vendor/nix/test/test.rs ++++ b/vendor/nix/test/test.rs +@@ -1,140 +1,76 @@ +-extern crate bytes; +-#[cfg(any(target_os = "android", target_os = "linux"))] +-extern crate caps; + #[macro_use] + extern crate cfg_if; +-#[macro_use] ++#[cfg_attr(not(any(target_os = "redox", target_os = "haiku")), macro_use)] + extern crate nix; + #[macro_use] + extern crate lazy_static; +-extern crate libc; +-extern crate rand; +-#[cfg(target_os = "freebsd")] +-extern crate sysctl; +-extern crate tempfile; +- +-cfg_if! { +- if #[cfg(any(target_os = "android", target_os = "linux"))] { +- macro_rules! require_capability { +- ($capname:ident) => { +- use ::caps::{Capability, CapSet, has_cap}; +- use ::std::io::{self, Write}; +- +- if !has_cap(None, CapSet::Effective, Capability::$capname) +- .unwrap() +- { +- let stderr = io::stderr(); +- let mut handle = stderr.lock(); +- writeln!(handle, +- "Insufficient capabilities. Skipping test.") +- .unwrap(); +- return; +- } +- } +- } +- } else { +- macro_rules! require_capability { +- ($capname:ident) => {} +- } +- } +-} +- +-#[cfg(target_os = "freebsd")] +-macro_rules! skip_if_jailed { +- ($name:expr) => { +- use ::sysctl::CtlValue; +- +- if let CtlValue::Int(1) = ::sysctl::value("security.jail.jailed") +- .unwrap() +- { +- use ::std::io::Write; +- let stderr = ::std::io::stderr(); +- let mut handle = stderr.lock(); +- writeln!(handle, "{} cannot run in a jail. Skipping test.", $name) +- .unwrap(); +- return; +- } +- } +-} +- +-macro_rules! skip_if_not_root { +- ($name:expr) => { +- use nix::unistd::Uid; +- +- if !Uid::current().is_root() { +- use ::std::io::Write; +- let stderr = ::std::io::stderr(); +- let mut handle = stderr.lock(); +- writeln!(handle, "{} requires root privileges. Skipping test.", $name).unwrap(); +- return; +- } +- }; +-} +- +-cfg_if! { +- if #[cfg(any(target_os = "android", target_os = "linux"))] { +- macro_rules! skip_if_seccomp { +- ($name:expr) => { +- if let Ok(s) = std::fs::read_to_string("/proc/self/status") { +- for l in s.lines() { +- let mut fields = l.split_whitespace(); +- if fields.next() == Some("Seccomp:") && +- fields.next() != Some("0") +- { +- use ::std::io::Write; +- let stderr = ::std::io::stderr(); +- let mut handle = stderr.lock(); +- writeln!(handle, +- "{} cannot be run in Seccomp mode. Skipping test.", +- stringify!($name)).unwrap(); +- return; +- } +- } +- } +- } +- } +- } else { +- macro_rules! skip_if_seccomp { +- ($name:expr) => {} +- } +- } +-} + ++mod common; + mod sys; ++#[cfg(not(target_os = "redox"))] + mod test_dir; + mod test_fcntl; +-#[cfg(any(target_os = "android", +- target_os = "linux"))] ++#[cfg(any(target_os = "android", target_os = "linux"))] + mod test_kmod; +-#[cfg(any(target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "fushsia", +- target_os = "linux", +- target_os = "netbsd"))] ++#[cfg(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "fushsia", ++ target_os = "linux", ++ target_os = "netbsd" ++))] + mod test_mq; ++#[cfg(not(target_os = "redox"))] + mod test_net; + mod test_nix_path; ++#[cfg(target_os = "freebsd")] ++mod test_nmount; + mod test_poll; ++#[cfg(not(any( ++ target_os = "redox", ++ target_os = "fuchsia", ++ target_os = "haiku" ++)))] + mod test_pty; +-#[cfg(any(target_os = "android", +- target_os = "linux"))] ++mod test_resource; ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ all(target_os = "freebsd", fbsd14), ++ target_os = "linux" ++))] + mod test_sched; +-#[cfg(any(target_os = "android", +- target_os = "freebsd", +- target_os = "ios", +- target_os = "linux", +- target_os = "macos"))] ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "linux", ++ target_os = "macos" ++))] + mod test_sendfile; + mod test_stat; ++mod test_time; ++#[cfg(all( ++ any( ++ target_os = "freebsd", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "netbsd" ++ ), ++ feature = "time", ++ feature = "signal" ++))] ++mod test_timer; + mod test_unistd; + ++use nix::unistd::{chdir, getcwd, read}; ++use parking_lot::{Mutex, RwLock, RwLockWriteGuard}; + use std::os::unix::io::RawFd; + use std::path::PathBuf; +-use std::sync::{Mutex, RwLock, RwLockWriteGuard}; +-use nix::unistd::{chdir, getcwd, read}; + + /// Helper function analogous to `std::io::Read::read_exact`, but for `RawFD`s +-fn read_exact(f: RawFd, buf: &mut [u8]) { ++fn read_exact(f: RawFd, buf: &mut [u8]) { + let mut len = 0; + while len < buf.len() { + // get_mut would be better than split_at_mut, but it requires nightly +@@ -165,14 +101,13 @@ lazy_static! { + /// RAII object that restores a test's original directory on drop + struct DirRestore<'a> { + d: PathBuf, +- _g: RwLockWriteGuard<'a, ()> ++ _g: RwLockWriteGuard<'a, ()>, + } + + impl<'a> DirRestore<'a> { + fn new() -> Self { +- let guard = ::CWD_LOCK.write() +- .expect("Lock got poisoned by another test"); +- DirRestore{ ++ let guard = crate::CWD_LOCK.write(); ++ DirRestore { + _g: guard, + d: getcwd().unwrap(), + } +diff --git a/vendor/nix/test/test_clearenv.rs b/vendor/nix/test/test_clearenv.rs +new file mode 100644 +index 0000000..28a7768 +--- /dev/null ++++ b/vendor/nix/test/test_clearenv.rs +@@ -0,0 +1,9 @@ ++use std::env; ++ ++#[test] ++fn clearenv() { ++ env::set_var("FOO", "BAR"); ++ unsafe { nix::env::clearenv() }.unwrap(); ++ assert_eq!(env::var("FOO").unwrap_err(), env::VarError::NotPresent); ++ assert_eq!(env::vars().count(), 0); ++} +diff --git a/vendor/nix/test/test_dir.rs b/vendor/nix/test/test_dir.rs +index c42fbcd..2af4aa5 100644 +--- a/vendor/nix/test/test_dir.rs ++++ b/vendor/nix/test/test_dir.rs +@@ -1,19 +1,27 @@ +-extern crate nix; +-extern crate tempfile; +- + use nix::dir::{Dir, Type}; + use nix::fcntl::OFlag; + use nix::sys::stat::Mode; + use std::fs::File; +-use self::tempfile::tempdir; ++use tempfile::tempdir; ++ ++#[cfg(test)] ++fn flags() -> OFlag { ++ #[cfg(target_os = "illumos")] ++ let f = OFlag::O_RDONLY | OFlag::O_CLOEXEC; ++ ++ #[cfg(not(target_os = "illumos"))] ++ let f = OFlag::O_RDONLY | OFlag::O_CLOEXEC | OFlag::O_DIRECTORY; ++ ++ f ++} + + #[test] ++#[allow(clippy::unnecessary_sort_by)] // False positive + fn read() { + let tmp = tempdir().unwrap(); +- File::create(&tmp.path().join("foo")).unwrap(); +- ::std::os::unix::fs::symlink("foo", tmp.path().join("bar")).unwrap(); +- let mut dir = Dir::open(tmp.path(), OFlag::O_DIRECTORY | OFlag::O_RDONLY | OFlag::O_CLOEXEC, +- Mode::empty()).unwrap(); ++ File::create(tmp.path().join("foo")).unwrap(); ++ std::os::unix::fs::symlink("foo", tmp.path().join("bar")).unwrap(); ++ let mut dir = Dir::open(tmp.path(), flags(), Mode::empty()).unwrap(); + let mut entries: Vec<_> = dir.iter().map(|e| e.unwrap()).collect(); + entries.sort_by(|a, b| a.file_name().cmp(b.file_name())); + let entry_names: Vec<_> = entries +@@ -33,14 +41,25 @@ fn read() { + #[test] + fn rewind() { + let tmp = tempdir().unwrap(); +- let mut dir = Dir::open(tmp.path(), OFlag::O_DIRECTORY | OFlag::O_RDONLY | OFlag::O_CLOEXEC, +- Mode::empty()).unwrap(); +- let entries1: Vec<_> = dir.iter().map(|e| e.unwrap().file_name().to_owned()).collect(); +- let entries2: Vec<_> = dir.iter().map(|e| e.unwrap().file_name().to_owned()).collect(); ++ let mut dir = Dir::open(tmp.path(), flags(), Mode::empty()).unwrap(); ++ let entries1: Vec<_> = dir ++ .iter() ++ .map(|e| e.unwrap().file_name().to_owned()) ++ .collect(); ++ let entries2: Vec<_> = dir ++ .iter() ++ .map(|e| e.unwrap().file_name().to_owned()) ++ .collect(); ++ let entries3: Vec<_> = dir ++ .into_iter() ++ .map(|e| e.unwrap().file_name().to_owned()) ++ .collect(); + assert_eq!(entries1, entries2); ++ assert_eq!(entries2, entries3); + } + ++#[cfg(not(target_os = "haiku"))] + #[test] + fn ebadf() { +- assert_eq!(Dir::from_fd(-1).unwrap_err(), nix::Error::Sys(nix::errno::Errno::EBADF)); ++ assert_eq!(Dir::from_fd(-1).unwrap_err(), nix::Error::EBADF); + } +diff --git a/vendor/nix/test/test_fcntl.rs b/vendor/nix/test/test_fcntl.rs +index 38a1e7b..e51044a 100644 +--- a/vendor/nix/test/test_fcntl.rs ++++ b/vendor/nix/test/test_fcntl.rs +@@ -1,26 +1,53 @@ +-use nix::Error; ++#[cfg(not(target_os = "redox"))] + use nix::errno::*; +-use nix::fcntl::{openat, open, OFlag, readlink, readlinkat, renameat}; ++#[cfg(not(target_os = "redox"))] ++use nix::fcntl::{open, readlink, OFlag}; ++#[cfg(not(target_os = "redox"))] ++use nix::fcntl::{openat, readlinkat, renameat}; ++#[cfg(all( ++ target_os = "linux", ++ target_env = "gnu", ++ any( ++ target_arch = "x86_64", ++ target_arch = "x32", ++ target_arch = "powerpc", ++ target_arch = "s390x" ++ ) ++))] ++use nix::fcntl::{renameat2, RenameFlags}; ++#[cfg(not(target_os = "redox"))] + use nix::sys::stat::Mode; ++#[cfg(not(target_os = "redox"))] + use nix::unistd::{close, read}; +-use tempfile::{self, NamedTempFile}; ++#[cfg(not(target_os = "redox"))] + use std::fs::File; ++#[cfg(not(target_os = "redox"))] + use std::io::prelude::*; ++#[cfg(not(target_os = "redox"))] + use std::os::unix::fs; ++#[cfg(not(target_os = "redox"))] ++use tempfile::{self, NamedTempFile}; + + #[test] ++#[cfg(not(target_os = "redox"))] ++// QEMU does not handle openat well enough to satisfy this test ++// https://gitlab.com/qemu-project/qemu/-/issues/829 ++#[cfg_attr(qemu, ignore)] + fn test_openat() { + const CONTENTS: &[u8] = b"abcd"; + let mut tmp = NamedTempFile::new().unwrap(); + tmp.write_all(CONTENTS).unwrap(); + +- let dirfd = open(tmp.path().parent().unwrap(), +- OFlag::empty(), +- Mode::empty()).unwrap(); +- let fd = openat(dirfd, +- tmp.path().file_name().unwrap(), +- OFlag::O_RDONLY, +- Mode::empty()).unwrap(); ++ let dirfd = ++ open(tmp.path().parent().unwrap(), OFlag::empty(), Mode::empty()) ++ .unwrap(); ++ let fd = openat( ++ dirfd, ++ tmp.path().file_name().unwrap(), ++ OFlag::O_RDONLY, ++ Mode::empty(), ++ ) ++ .unwrap(); + + let mut buf = [0u8; 1024]; + assert_eq!(4, read(fd, &mut buf).unwrap()); +@@ -31,51 +58,190 @@ fn test_openat() { + } + + #[test] ++#[cfg(not(target_os = "redox"))] + fn test_renameat() { + let old_dir = tempfile::tempdir().unwrap(); +- let old_dirfd = open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); ++ let old_dirfd = ++ open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); + let old_path = old_dir.path().join("old"); +- File::create(&old_path).unwrap(); ++ File::create(old_path).unwrap(); + let new_dir = tempfile::tempdir().unwrap(); +- let new_dirfd = open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); ++ let new_dirfd = ++ open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); + renameat(Some(old_dirfd), "old", Some(new_dirfd), "new").unwrap(); +- assert_eq!(renameat(Some(old_dirfd), "old", Some(new_dirfd), "new").unwrap_err(), +- Error::Sys(Errno::ENOENT)); ++ assert_eq!( ++ renameat(Some(old_dirfd), "old", Some(new_dirfd), "new").unwrap_err(), ++ Errno::ENOENT ++ ); ++ close(old_dirfd).unwrap(); ++ close(new_dirfd).unwrap(); ++ assert!(new_dir.path().join("new").exists()); ++} ++ ++#[test] ++#[cfg(all( ++ target_os = "linux", ++ target_env = "gnu", ++ any( ++ target_arch = "x86_64", ++ target_arch = "x32", ++ target_arch = "powerpc", ++ target_arch = "s390x" ++ ) ++))] ++fn test_renameat2_behaves_like_renameat_with_no_flags() { ++ let old_dir = tempfile::tempdir().unwrap(); ++ let old_dirfd = ++ open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); ++ let old_path = old_dir.path().join("old"); ++ File::create(old_path).unwrap(); ++ let new_dir = tempfile::tempdir().unwrap(); ++ let new_dirfd = ++ open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); ++ renameat2( ++ Some(old_dirfd), ++ "old", ++ Some(new_dirfd), ++ "new", ++ RenameFlags::empty(), ++ ) ++ .unwrap(); ++ assert_eq!( ++ renameat2( ++ Some(old_dirfd), ++ "old", ++ Some(new_dirfd), ++ "new", ++ RenameFlags::empty() ++ ) ++ .unwrap_err(), ++ Errno::ENOENT ++ ); ++ close(old_dirfd).unwrap(); ++ close(new_dirfd).unwrap(); ++ assert!(new_dir.path().join("new").exists()); ++} ++ ++#[test] ++#[cfg(all( ++ target_os = "linux", ++ target_env = "gnu", ++ any( ++ target_arch = "x86_64", ++ target_arch = "x32", ++ target_arch = "powerpc", ++ target_arch = "s390x" ++ ) ++))] ++fn test_renameat2_exchange() { ++ let old_dir = tempfile::tempdir().unwrap(); ++ let old_dirfd = ++ open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); ++ let old_path = old_dir.path().join("old"); ++ { ++ let mut old_f = File::create(&old_path).unwrap(); ++ old_f.write_all(b"old").unwrap(); ++ } ++ let new_dir = tempfile::tempdir().unwrap(); ++ let new_dirfd = ++ open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); ++ let new_path = new_dir.path().join("new"); ++ { ++ let mut new_f = File::create(&new_path).unwrap(); ++ new_f.write_all(b"new").unwrap(); ++ } ++ renameat2( ++ Some(old_dirfd), ++ "old", ++ Some(new_dirfd), ++ "new", ++ RenameFlags::RENAME_EXCHANGE, ++ ) ++ .unwrap(); ++ let mut buf = String::new(); ++ let mut new_f = File::open(&new_path).unwrap(); ++ new_f.read_to_string(&mut buf).unwrap(); ++ assert_eq!(buf, "old"); ++ buf = "".to_string(); ++ let mut old_f = File::open(&old_path).unwrap(); ++ old_f.read_to_string(&mut buf).unwrap(); ++ assert_eq!(buf, "new"); ++ close(old_dirfd).unwrap(); ++ close(new_dirfd).unwrap(); ++} ++ ++#[test] ++#[cfg(all( ++ target_os = "linux", ++ target_env = "gnu", ++ any( ++ target_arch = "x86_64", ++ target_arch = "x32", ++ target_arch = "powerpc", ++ target_arch = "s390x" ++ ) ++))] ++fn test_renameat2_noreplace() { ++ let old_dir = tempfile::tempdir().unwrap(); ++ let old_dirfd = ++ open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); ++ let old_path = old_dir.path().join("old"); ++ File::create(old_path).unwrap(); ++ let new_dir = tempfile::tempdir().unwrap(); ++ let new_dirfd = ++ open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); ++ let new_path = new_dir.path().join("new"); ++ File::create(new_path).unwrap(); ++ assert_eq!( ++ renameat2( ++ Some(old_dirfd), ++ "old", ++ Some(new_dirfd), ++ "new", ++ RenameFlags::RENAME_NOREPLACE ++ ) ++ .unwrap_err(), ++ Errno::EEXIST ++ ); + close(old_dirfd).unwrap(); + close(new_dirfd).unwrap(); + assert!(new_dir.path().join("new").exists()); ++ assert!(old_dir.path().join("old").exists()); + } + + #[test] ++#[cfg(not(target_os = "redox"))] + fn test_readlink() { + let tempdir = tempfile::tempdir().unwrap(); + let src = tempdir.path().join("a"); + let dst = tempdir.path().join("b"); + println!("a: {:?}, b: {:?}", &src, &dst); +- fs::symlink(&src.as_path(), &dst.as_path()).unwrap(); +- let dirfd = open(tempdir.path(), +- OFlag::empty(), +- Mode::empty()).unwrap(); ++ fs::symlink(src.as_path(), dst.as_path()).unwrap(); ++ let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); + let expected_dir = src.to_str().unwrap(); + + assert_eq!(readlink(&dst).unwrap().to_str().unwrap(), expected_dir); +- assert_eq!(readlinkat(dirfd, "b").unwrap().to_str().unwrap(), expected_dir); +- ++ assert_eq!( ++ readlinkat(dirfd, "b").unwrap().to_str().unwrap(), ++ expected_dir ++ ); + } + + #[cfg(any(target_os = "linux", target_os = "android"))] + mod linux_android { ++ use libc::loff_t; + use std::io::prelude::*; +- use std::io::SeekFrom; ++ use std::io::IoSlice; + use std::os::unix::prelude::*; + +- use libc::loff_t; +- + use nix::fcntl::*; +- use nix::sys::uio::IoVec; + use nix::unistd::{close, pipe, read, write}; + +- use tempfile::{tempfile, NamedTempFile}; ++ use tempfile::tempfile; ++ #[cfg(any(target_os = "linux"))] ++ use tempfile::NamedTempFile; ++ ++ use crate::*; + + /// This test creates a temporary file containing the contents + /// 'foobarbaz' and uses the `copy_file_range` call to transfer +@@ -83,11 +249,9 @@ mod linux_android { + /// resulting file is read and should contain the contents `bar`. + /// The from_offset should be updated by the call to reflect + /// the 3 bytes read (6). +- /// +- /// FIXME: This test is disabled for linux based builds, because Travis +- /// Linux version is too old for `copy_file_range`. + #[test] +- #[ignore] ++ // QEMU does not support copy_file_range. Skip under qemu ++ #[cfg_attr(qemu, ignore)] + fn test_copy_file_range() { + const CONTENTS: &[u8] = b"foobarbaz"; + +@@ -108,7 +272,7 @@ mod linux_android { + .unwrap(); + + let mut res: String = String::new(); +- tmp2.seek(SeekFrom::Start(0)).unwrap(); ++ tmp2.rewind().unwrap(); + tmp2.read_to_string(&mut res).unwrap(); + + assert_eq!(res, String::from("bar")); +@@ -123,8 +287,15 @@ mod linux_android { + + let (rd, wr) = pipe().unwrap(); + let mut offset: loff_t = 5; +- let res = splice(tmp.as_raw_fd(), Some(&mut offset), +- wr, None, 2, SpliceFFlags::empty()).unwrap(); ++ let res = splice( ++ tmp.as_raw_fd(), ++ Some(&mut offset), ++ wr, ++ None, ++ 2, ++ SpliceFFlags::empty(), ++ ) ++ .unwrap(); + + assert_eq!(2, res); + +@@ -169,9 +340,7 @@ mod linux_android { + + let buf1 = b"abcdef"; + let buf2 = b"defghi"; +- let mut iovecs = Vec::with_capacity(2); +- iovecs.push(IoVec::from_slice(&buf1[0..3])); +- iovecs.push(IoVec::from_slice(&buf2[0..3])); ++ let iovecs = vec![IoSlice::new(&buf1[0..3]), IoSlice::new(&buf2[0..3])]; + + let res = vmsplice(wr, &iovecs[..], SpliceFFlags::empty()).unwrap(); + +@@ -186,6 +355,7 @@ mod linux_android { + close(wr).unwrap(); + } + ++ #[cfg(any(target_os = "linux"))] + #[test] + fn test_fallocate() { + let tmp = NamedTempFile::new().unwrap(); +@@ -197,54 +367,167 @@ mod linux_android { + let mut buf = [0u8; 200]; + assert_eq!(100, read(fd, &mut buf).unwrap()); + } ++ ++ // The tests below are disabled for the listed targets ++ // due to OFD locks not being available in the kernel/libc ++ // versions used in the CI environment, probably because ++ // they run under QEMU. ++ ++ #[test] ++ #[cfg(all(target_os = "linux", not(target_env = "musl")))] ++ #[cfg_attr(target_env = "uclibc", ignore)] // uclibc doesn't support OFD locks, but the test should still compile ++ fn test_ofd_write_lock() { ++ use nix::sys::stat::fstat; ++ use std::mem; ++ ++ let tmp = NamedTempFile::new().unwrap(); ++ ++ let fd = tmp.as_raw_fd(); ++ let statfs = nix::sys::statfs::fstatfs(&tmp).unwrap(); ++ if statfs.filesystem_type() == nix::sys::statfs::OVERLAYFS_SUPER_MAGIC { ++ // OverlayFS is a union file system. It returns one inode value in ++ // stat(2), but a different one shows up in /proc/locks. So we must ++ // skip the test. ++ skip!("/proc/locks does not work on overlayfs"); ++ } ++ let inode = fstat(fd).expect("fstat failed").st_ino as usize; ++ ++ let mut flock: libc::flock = unsafe { ++ mem::zeroed() // required for Linux/mips ++ }; ++ flock.l_type = libc::F_WRLCK as libc::c_short; ++ flock.l_whence = libc::SEEK_SET as libc::c_short; ++ flock.l_start = 0; ++ flock.l_len = 0; ++ flock.l_pid = 0; ++ fcntl(fd, FcntlArg::F_OFD_SETLKW(&flock)).expect("write lock failed"); ++ assert_eq!( ++ Some(("OFDLCK".to_string(), "WRITE".to_string())), ++ lock_info(inode) ++ ); ++ ++ flock.l_type = libc::F_UNLCK as libc::c_short; ++ fcntl(fd, FcntlArg::F_OFD_SETLKW(&flock)).expect("write unlock failed"); ++ assert_eq!(None, lock_info(inode)); ++ } ++ ++ #[test] ++ #[cfg(all(target_os = "linux", not(target_env = "musl")))] ++ #[cfg_attr(target_env = "uclibc", ignore)] // uclibc doesn't support OFD locks, but the test should still compile ++ fn test_ofd_read_lock() { ++ use nix::sys::stat::fstat; ++ use std::mem; ++ ++ let tmp = NamedTempFile::new().unwrap(); ++ ++ let fd = tmp.as_raw_fd(); ++ let statfs = nix::sys::statfs::fstatfs(&tmp).unwrap(); ++ if statfs.filesystem_type() == nix::sys::statfs::OVERLAYFS_SUPER_MAGIC { ++ // OverlayFS is a union file system. It returns one inode value in ++ // stat(2), but a different one shows up in /proc/locks. So we must ++ // skip the test. ++ skip!("/proc/locks does not work on overlayfs"); ++ } ++ let inode = fstat(fd).expect("fstat failed").st_ino as usize; ++ ++ let mut flock: libc::flock = unsafe { ++ mem::zeroed() // required for Linux/mips ++ }; ++ flock.l_type = libc::F_RDLCK as libc::c_short; ++ flock.l_whence = libc::SEEK_SET as libc::c_short; ++ flock.l_start = 0; ++ flock.l_len = 0; ++ flock.l_pid = 0; ++ fcntl(fd, FcntlArg::F_OFD_SETLKW(&flock)).expect("read lock failed"); ++ assert_eq!( ++ Some(("OFDLCK".to_string(), "READ".to_string())), ++ lock_info(inode) ++ ); ++ ++ flock.l_type = libc::F_UNLCK as libc::c_short; ++ fcntl(fd, FcntlArg::F_OFD_SETLKW(&flock)).expect("read unlock failed"); ++ assert_eq!(None, lock_info(inode)); ++ } ++ ++ #[cfg(all(target_os = "linux", not(target_env = "musl")))] ++ fn lock_info(inode: usize) -> Option<(String, String)> { ++ use std::{fs::File, io::BufReader}; ++ ++ let file = File::open("/proc/locks").expect("open /proc/locks failed"); ++ let buf = BufReader::new(file); ++ ++ for line in buf.lines() { ++ let line = line.unwrap(); ++ let parts: Vec<_> = line.split_whitespace().collect(); ++ let lock_type = parts[1]; ++ let lock_access = parts[3]; ++ let ino_parts: Vec<_> = parts[5].split(':').collect(); ++ let ino: usize = ino_parts[2].parse().unwrap(); ++ if ino == inode { ++ return Some((lock_type.to_string(), lock_access.to_string())); ++ } ++ } ++ None ++ } + } + +-#[cfg(any(target_os = "linux", +- target_os = "android", +- target_os = "emscripten", +- target_os = "fuchsia", +- any(target_os = "wasi", target_env = "wasi"), +- target_env = "uclibc", +- target_env = "freebsd"))] ++#[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "wasi", ++ target_env = "uclibc", ++ target_os = "freebsd" ++))] + mod test_posix_fadvise { + +- use tempfile::NamedTempFile; +- use std::os::unix::io::{RawFd, AsRawFd}; + use nix::errno::Errno; + use nix::fcntl::*; + use nix::unistd::pipe; ++ use std::os::unix::io::{AsRawFd, RawFd}; ++ use tempfile::NamedTempFile; + + #[test] + fn test_success() { + let tmp = NamedTempFile::new().unwrap(); + let fd = tmp.as_raw_fd(); +- let res = posix_fadvise(fd, 0, 100, PosixFadviseAdvice::POSIX_FADV_WILLNEED).unwrap(); +- +- assert_eq!(res, 0); ++ posix_fadvise(fd, 0, 100, PosixFadviseAdvice::POSIX_FADV_WILLNEED) ++ .expect("posix_fadvise failed"); + } + + #[test] + fn test_errno() { + let (rd, _wr) = pipe().unwrap(); +- let errno = posix_fadvise(rd as RawFd, 0, 100, PosixFadviseAdvice::POSIX_FADV_WILLNEED) +- .unwrap(); +- assert_eq!(errno, Errno::ESPIPE as i32); ++ let res = posix_fadvise( ++ rd as RawFd, ++ 0, ++ 100, ++ PosixFadviseAdvice::POSIX_FADV_WILLNEED, ++ ); ++ assert_eq!(res, Err(Errno::ESPIPE)); + } + } + +-#[cfg(any(target_os = "linux", +- target_os = "android", +- target_os = "emscripten", +- target_os = "fuchsia", +- any(target_os = "wasi", target_env = "wasi"), +- target_os = "freebsd"))] ++#[cfg(any( ++ target_os = "linux", ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "emscripten", ++ target_os = "fuchsia", ++ target_os = "wasi", ++ target_os = "freebsd" ++))] + mod test_posix_fallocate { + +- use tempfile::NamedTempFile; +- use std::{io::Read, os::unix::io::{RawFd, AsRawFd}}; + use nix::errno::Errno; + use nix::fcntl::*; + use nix::unistd::pipe; ++ use std::{ ++ io::Read, ++ os::unix::io::{AsRawFd, RawFd}, ++ }; ++ use tempfile::NamedTempFile; + + #[test] + fn success() { +@@ -258,7 +541,7 @@ mod test_posix_fallocate { + assert_eq!(tmp.read(&mut data).expect("read failure"), LEN); + assert_eq!(&data[..], &[0u8; LEN][..]); + } +- Err(nix::Error::Sys(Errno::EINVAL)) => { ++ Err(Errno::EINVAL) => { + // POSIX requires posix_fallocate to return EINVAL both for + // invalid arguments (i.e. len < 0) and if the operation is not + // supported by the file system. +@@ -274,17 +557,9 @@ mod test_posix_fallocate { + fn errno() { + let (rd, _wr) = pipe().unwrap(); + let err = posix_fallocate(rd as RawFd, 0, 100).unwrap_err(); +- use nix::Error::Sys; + match err { +- Sys(Errno::EINVAL) +- | Sys(Errno::ENODEV) +- | Sys(Errno::ESPIPE) +- | Sys(Errno::EBADF) => (), +- errno => +- panic!( +- "unexpected errno {}", +- errno, +- ), ++ Errno::EINVAL | Errno::ENODEV | Errno::ESPIPE | Errno::EBADF => (), ++ errno => panic!("unexpected errno {}", errno,), + } + } + } +diff --git a/vendor/nix/test/test_kmod/mod.rs b/vendor/nix/test/test_kmod/mod.rs +index ad40635..6f9aaa8 100644 +--- a/vendor/nix/test/test_kmod/mod.rs ++++ b/vendor/nix/test/test_kmod/mod.rs +@@ -1,23 +1,25 @@ ++use crate::*; + use std::fs::copy; + use std::path::PathBuf; + use std::process::Command; + use tempfile::{tempdir, TempDir}; + + fn compile_kernel_module() -> (PathBuf, String, TempDir) { +- let _m = ::FORK_MTX +- .lock() +- .expect("Mutex got poisoned by another test"); ++ let _m = crate::FORK_MTX.lock(); + +- let tmp_dir = tempdir().expect("unable to create temporary build directory"); ++ let tmp_dir = ++ tempdir().expect("unable to create temporary build directory"); + + copy( + "test/test_kmod/hello_mod/hello.c", +- &tmp_dir.path().join("hello.c"), +- ).expect("unable to copy hello.c to temporary build directory"); ++ tmp_dir.path().join("hello.c"), ++ ) ++ .expect("unable to copy hello.c to temporary build directory"); + copy( + "test/test_kmod/hello_mod/Makefile", +- &tmp_dir.path().join("Makefile"), +- ).expect("unable to copy Makefile to temporary build directory"); ++ tmp_dir.path().join("Makefile"), ++ ) ++ .expect("unable to copy Makefile to temporary build directory"); + + let status = Command::new("make") + .current_dir(tmp_dir.path()) +@@ -33,16 +35,15 @@ fn compile_kernel_module() -> (PathBuf, String, TempDir) { + use nix::errno::Errno; + use nix::kmod::{delete_module, DeleteModuleFlags}; + use nix::kmod::{finit_module, init_module, ModuleInitFlags}; +-use nix::Error; + use std::ffi::CString; + use std::fs::File; + use std::io::Read; + + #[test] + fn test_finit_and_delete_module() { +- require_capability!(CAP_SYS_MODULE); +- let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test"); +- let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test"); ++ require_capability!("test_finit_and_delete_module", CAP_SYS_MODULE); ++ let _m0 = crate::KMOD_MTX.lock(); ++ let _m1 = crate::CWD_LOCK.read(); + + let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); + +@@ -53,14 +54,18 @@ fn test_finit_and_delete_module() { + delete_module( + &CString::new(kmod_name).unwrap(), + DeleteModuleFlags::empty(), +- ).expect("unable to unload kernel module"); ++ ) ++ .expect("unable to unload kernel module"); + } + + #[test] +-fn test_finit_and_delete_modul_with_params() { +- require_capability!(CAP_SYS_MODULE); +- let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test"); +- let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test"); ++fn test_finit_and_delete_module_with_params() { ++ require_capability!( ++ "test_finit_and_delete_module_with_params", ++ CAP_SYS_MODULE ++ ); ++ let _m0 = crate::KMOD_MTX.lock(); ++ let _m1 = crate::CWD_LOCK.read(); + + let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); + +@@ -69,19 +74,21 @@ fn test_finit_and_delete_modul_with_params() { + &f, + &CString::new("who=Rust number=2018").unwrap(), + ModuleInitFlags::empty(), +- ).expect("unable to load kernel module"); ++ ) ++ .expect("unable to load kernel module"); + + delete_module( + &CString::new(kmod_name).unwrap(), + DeleteModuleFlags::empty(), +- ).expect("unable to unload kernel module"); ++ ) ++ .expect("unable to unload kernel module"); + } + + #[test] + fn test_init_and_delete_module() { +- require_capability!(CAP_SYS_MODULE); +- let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test"); +- let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test"); ++ require_capability!("test_init_and_delete_module", CAP_SYS_MODULE); ++ let _m0 = crate::KMOD_MTX.lock(); ++ let _m1 = crate::CWD_LOCK.read(); + + let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); + +@@ -89,19 +96,24 @@ fn test_init_and_delete_module() { + let mut contents: Vec = Vec::new(); + f.read_to_end(&mut contents) + .expect("unable to read kernel module content to buffer"); +- init_module(&mut contents, &CString::new("").unwrap()).expect("unable to load kernel module"); ++ init_module(&contents, &CString::new("").unwrap()) ++ .expect("unable to load kernel module"); + + delete_module( + &CString::new(kmod_name).unwrap(), + DeleteModuleFlags::empty(), +- ).expect("unable to unload kernel module"); ++ ) ++ .expect("unable to unload kernel module"); + } + + #[test] + fn test_init_and_delete_module_with_params() { +- require_capability!(CAP_SYS_MODULE); +- let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test"); +- let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test"); ++ require_capability!( ++ "test_init_and_delete_module_with_params", ++ CAP_SYS_MODULE ++ ); ++ let _m0 = crate::KMOD_MTX.lock(); ++ let _m1 = crate::CWD_LOCK.read(); + + let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); + +@@ -109,34 +121,39 @@ fn test_init_and_delete_module_with_params() { + let mut contents: Vec = Vec::new(); + f.read_to_end(&mut contents) + .expect("unable to read kernel module content to buffer"); +- init_module(&mut contents, &CString::new("who=Nix number=2015").unwrap()) ++ init_module(&contents, &CString::new("who=Nix number=2015").unwrap()) + .expect("unable to load kernel module"); + + delete_module( + &CString::new(kmod_name).unwrap(), + DeleteModuleFlags::empty(), +- ).expect("unable to unload kernel module"); ++ ) ++ .expect("unable to unload kernel module"); + } + + #[test] + fn test_finit_module_invalid() { +- require_capability!(CAP_SYS_MODULE); +- let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test"); +- let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test"); ++ require_capability!("test_finit_module_invalid", CAP_SYS_MODULE); ++ let _m0 = crate::KMOD_MTX.lock(); ++ let _m1 = crate::CWD_LOCK.read(); + + let kmod_path = "/dev/zero"; + + let f = File::open(kmod_path).expect("unable to open kernel module"); +- let result = finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()); ++ let result = ++ finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()); + +- assert_eq!(result.unwrap_err(), Error::Sys(Errno::EINVAL)); ++ assert_eq!(result.unwrap_err(), Errno::EINVAL); + } + + #[test] + fn test_finit_module_twice_and_delete_module() { +- require_capability!(CAP_SYS_MODULE); +- let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test"); +- let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test"); ++ require_capability!( ++ "test_finit_module_twice_and_delete_module", ++ CAP_SYS_MODULE ++ ); ++ let _m0 = crate::KMOD_MTX.lock(); ++ let _m1 = crate::CWD_LOCK.read(); + + let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); + +@@ -144,23 +161,28 @@ fn test_finit_module_twice_and_delete_module() { + finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()) + .expect("unable to load kernel module"); + +- let result = finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()); ++ let result = ++ finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()); + +- assert_eq!(result.unwrap_err(), Error::Sys(Errno::EEXIST)); ++ assert_eq!(result.unwrap_err(), Errno::EEXIST); + + delete_module( + &CString::new(kmod_name).unwrap(), + DeleteModuleFlags::empty(), +- ).expect("unable to unload kernel module"); ++ ) ++ .expect("unable to unload kernel module"); + } + + #[test] + fn test_delete_module_not_loaded() { +- require_capability!(CAP_SYS_MODULE); +- let _m0 = ::KMOD_MTX.lock().expect("Mutex got poisoned by another test"); +- let _m1 = ::CWD_LOCK.read().expect("Mutex got poisoned by another test"); ++ require_capability!("test_delete_module_not_loaded", CAP_SYS_MODULE); ++ let _m0 = crate::KMOD_MTX.lock(); ++ let _m1 = crate::CWD_LOCK.read(); + +- let result = delete_module(&CString::new("hello").unwrap(), DeleteModuleFlags::empty()); ++ let result = delete_module( ++ &CString::new("hello").unwrap(), ++ DeleteModuleFlags::empty(), ++ ); + +- assert_eq!(result.unwrap_err(), Error::Sys(Errno::ENOENT)); ++ assert_eq!(result.unwrap_err(), Errno::ENOENT); + } +diff --git a/vendor/nix/test/test_mount.rs b/vendor/nix/test/test_mount.rs +index d2e08bc..2fd612e 100644 +--- a/vendor/nix/test/test_mount.rs ++++ b/vendor/nix/test/test_mount.rs +@@ -1,12 +1,10 @@ +-// Impelmentation note: to allow unprivileged users to run it, this test makes ++mod common; ++ ++// Implementation note: to allow unprivileged users to run it, this test makes + // use of user and mount namespaces. On systems that allow unprivileged user + // namespaces (Linux >= 3.8 compiled with CONFIG_USER_NS), the test should run + // without root. + +-extern crate libc; +-extern crate nix; +-extern crate tempfile; +- + #[cfg(target_os = "linux")] + mod test_mount { + use std::fs::{self, File}; +@@ -23,23 +21,24 @@ mod test_mount { + use nix::sys::stat::{self, Mode}; + use nix::unistd::getuid; + +- use tempfile; +- +- static SCRIPT_CONTENTS: &'static [u8] = b"#!/bin/sh ++ static SCRIPT_CONTENTS: &[u8] = b"#!/bin/sh + exit 23"; + + const EXPECTED_STATUS: i32 = 23; + + const NONE: Option<&'static [u8]> = None; ++ #[allow(clippy::bind_instead_of_map)] // False positive + pub fn test_mount_tmpfs_without_flags_allows_rwx() { + let tempdir = tempfile::tempdir().unwrap(); + +- mount(NONE, +- tempdir.path(), +- Some(b"tmpfs".as_ref()), +- MsFlags::empty(), +- NONE) +- .unwrap_or_else(|e| panic!("mount failed: {}", e)); ++ mount( ++ NONE, ++ tempdir.path(), ++ Some(b"tmpfs".as_ref()), ++ MsFlags::empty(), ++ NONE, ++ ) ++ .unwrap_or_else(|e| panic!("mount failed: {}", e)); + + let test_path = tempdir.path().join("test"); + +@@ -49,8 +48,10 @@ exit 23"; + .write(true) + .mode((Mode::S_IRWXU | Mode::S_IRWXG | Mode::S_IRWXO).bits()) + .open(&test_path) +- .or_else(|e| +- if Errno::from_i32(e.raw_os_error().unwrap()) == Errno::EOVERFLOW { ++ .or_else(|e| { ++ if Errno::from_i32(e.raw_os_error().unwrap()) ++ == Errno::EOVERFLOW ++ { + // Skip tests on certain Linux kernels which have a bug + // regarding tmpfs in namespaces. + // Ubuntu 14.04 and 16.04 are known to be affected; 16.10 is +@@ -59,13 +60,16 @@ exit 23"; + // https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1659087 + let stderr = io::stderr(); + let mut handle = stderr.lock(); +- writeln!(handle, "Buggy Linux kernel detected. Skipping test.") ++ writeln!( ++ handle, ++ "Buggy Linux kernel detected. Skipping test." ++ ) + .unwrap(); + process::exit(0); +- } else { +- panic!("open failed: {}", e); +- } +- ) ++ } else { ++ panic!("open failed: {}", e); ++ } ++ }) + .and_then(|mut f| f.write(SCRIPT_CONTENTS)) + .unwrap_or_else(|e| panic!("write failed: {}", e)); + +@@ -77,42 +81,55 @@ exit 23"; + assert_eq!(buf, SCRIPT_CONTENTS); + + // Verify execute. +- assert_eq!(EXPECTED_STATUS, +- Command::new(&test_path) +- .status() +- .unwrap_or_else(|e| panic!("exec failed: {}", e)) +- .code() +- .unwrap_or_else(|| panic!("child killed by signal"))); +- +- umount(tempdir.path()).unwrap_or_else(|e| panic!("umount failed: {}", e)); ++ assert_eq!( ++ EXPECTED_STATUS, ++ Command::new(&test_path) ++ .status() ++ .unwrap_or_else(|e| panic!("exec failed: {}", e)) ++ .code() ++ .unwrap_or_else(|| panic!("child killed by signal")) ++ ); ++ ++ umount(tempdir.path()) ++ .unwrap_or_else(|e| panic!("umount failed: {}", e)); + } + + pub fn test_mount_rdonly_disallows_write() { + let tempdir = tempfile::tempdir().unwrap(); + +- mount(NONE, +- tempdir.path(), +- Some(b"tmpfs".as_ref()), +- MsFlags::MS_RDONLY, +- NONE) +- .unwrap_or_else(|e| panic!("mount failed: {}", e)); ++ mount( ++ NONE, ++ tempdir.path(), ++ Some(b"tmpfs".as_ref()), ++ MsFlags::MS_RDONLY, ++ NONE, ++ ) ++ .unwrap_or_else(|e| panic!("mount failed: {}", e)); + + // EROFS: Read-only file system +- assert_eq!(EROFS as i32, +- File::create(tempdir.path().join("test")).unwrap_err().raw_os_error().unwrap()); +- +- umount(tempdir.path()).unwrap_or_else(|e| panic!("umount failed: {}", e)); ++ assert_eq!( ++ EROFS, ++ File::create(tempdir.path().join("test")) ++ .unwrap_err() ++ .raw_os_error() ++ .unwrap() ++ ); ++ ++ umount(tempdir.path()) ++ .unwrap_or_else(|e| panic!("umount failed: {}", e)); + } + + pub fn test_mount_noexec_disallows_exec() { + let tempdir = tempfile::tempdir().unwrap(); + +- mount(NONE, +- tempdir.path(), +- Some(b"tmpfs".as_ref()), +- MsFlags::MS_NOEXEC, +- NONE) +- .unwrap_or_else(|e| panic!("mount failed: {}", e)); ++ mount( ++ NONE, ++ tempdir.path(), ++ Some(b"tmpfs".as_ref()), ++ MsFlags::MS_NOEXEC, ++ NONE, ++ ) ++ .unwrap_or_else(|e| panic!("mount failed: {}", e)); + + let test_path = tempdir.path().join("test"); + +@@ -125,21 +142,30 @@ exit 23"; + .unwrap_or_else(|e| panic!("write failed: {}", e)); + + // Verify that we cannot execute despite a+x permissions being set. +- let mode = stat::Mode::from_bits_truncate(fs::metadata(&test_path) +- .map(|md| md.permissions().mode()) +- .unwrap_or_else(|e| { +- panic!("metadata failed: {}", e) +- })); +- +- assert!(mode.contains(Mode::S_IXUSR | Mode::S_IXGRP | Mode::S_IXOTH), +- "{:?} did not have execute permissions", +- &test_path); ++ let mode = stat::Mode::from_bits_truncate( ++ fs::metadata(&test_path) ++ .map(|md| md.permissions().mode()) ++ .unwrap_or_else(|e| panic!("metadata failed: {}", e)), ++ ); ++ ++ assert!( ++ mode.contains(Mode::S_IXUSR | Mode::S_IXGRP | Mode::S_IXOTH), ++ "{:?} did not have execute permissions", ++ &test_path ++ ); + + // EACCES: Permission denied +- assert_eq!(EACCES as i32, +- Command::new(&test_path).status().unwrap_err().raw_os_error().unwrap()); +- +- umount(tempdir.path()).unwrap_or_else(|e| panic!("umount failed: {}", e)); ++ assert_eq!( ++ EACCES, ++ Command::new(&test_path) ++ .status() ++ .unwrap_err() ++ .raw_os_error() ++ .unwrap() ++ ); ++ ++ umount(tempdir.path()) ++ .unwrap_or_else(|e| panic!("umount failed: {}", e)); + } + + pub fn test_mount_bind() { +@@ -149,12 +175,14 @@ exit 23"; + { + let mount_point = tempfile::tempdir().unwrap(); + +- mount(Some(tempdir.path()), +- mount_point.path(), +- NONE, +- MsFlags::MS_BIND, +- NONE) +- .unwrap_or_else(|e| panic!("mount failed: {}", e)); ++ mount( ++ Some(tempdir.path()), ++ mount_point.path(), ++ NONE, ++ MsFlags::MS_BIND, ++ NONE, ++ ) ++ .unwrap_or_else(|e| panic!("mount failed: {}", e)); + + fs::OpenOptions::new() + .create(true) +@@ -164,7 +192,8 @@ exit 23"; + .and_then(|mut f| f.write(SCRIPT_CONTENTS)) + .unwrap_or_else(|e| panic!("write failed: {}", e)); + +- umount(mount_point.path()).unwrap_or_else(|e| panic!("umount failed: {}", e)); ++ umount(mount_point.path()) ++ .unwrap_or_else(|e| panic!("umount failed: {}", e)); + } + + // Verify the file written in the mount shows up in source directory, even +@@ -202,7 +231,6 @@ exit 23"; + } + } + +- + // Test runner + + /// Mimic normal test output (hackishly). +@@ -223,15 +251,20 @@ macro_rules! run_tests { + + #[cfg(target_os = "linux")] + fn main() { +- use test_mount::{setup_namespaces, test_mount_tmpfs_without_flags_allows_rwx, +- test_mount_rdonly_disallows_write, test_mount_noexec_disallows_exec, +- test_mount_bind}; ++ use test_mount::{ ++ setup_namespaces, test_mount_bind, test_mount_noexec_disallows_exec, ++ test_mount_rdonly_disallows_write, ++ test_mount_tmpfs_without_flags_allows_rwx, ++ }; ++ skip_if_cirrus!("Fails for an unknown reason Cirrus CI. Bug #1351"); + setup_namespaces(); + +- run_tests!(test_mount_tmpfs_without_flags_allows_rwx, +- test_mount_rdonly_disallows_write, +- test_mount_noexec_disallows_exec, +- test_mount_bind); ++ run_tests!( ++ test_mount_tmpfs_without_flags_allows_rwx, ++ test_mount_rdonly_disallows_write, ++ test_mount_noexec_disallows_exec, ++ test_mount_bind ++ ); + } + + #[cfg(not(target_os = "linux"))] +diff --git a/vendor/nix/test/test_mq.rs b/vendor/nix/test/test_mq.rs +index ecee200..7b48e7a 100644 +--- a/vendor/nix/test/test_mq.rs ++++ b/vendor/nix/test/test_mq.rs +@@ -1,36 +1,53 @@ +-use libc::c_long; +- ++use cfg_if::cfg_if; + use std::ffi::CString; + use std::str; + +-use nix::errno::Errno::*; +-use nix::Error::Sys; +-use nix::mqueue::{mq_open, mq_close, mq_send, mq_receive}; +-use nix::mqueue::{MqAttr, MQ_OFlag}; ++use nix::errno::Errno; ++use nix::mqueue::{mq_attr_member_t, mq_close, mq_open, mq_receive, mq_send}; ++use nix::mqueue::{MQ_OFlag, MqAttr}; + use nix::sys::stat::Mode; + ++// Defined as a macro such that the error source is reported as the caller's location. ++macro_rules! assert_attr_eq { ++ ($read_attr:ident, $initial_attr:ident) => { ++ cfg_if! { ++ if #[cfg(any(target_os = "dragonfly", target_os = "netbsd"))] { ++ // NetBSD (and others which inherit its implementation) include other flags ++ // in read_attr, such as those specified by oflag. Just make sure at least ++ // the correct bits are set. ++ assert_eq!($read_attr.flags() & $initial_attr.flags(), $initial_attr.flags()); ++ assert_eq!($read_attr.maxmsg(), $initial_attr.maxmsg()); ++ assert_eq!($read_attr.msgsize(), $initial_attr.msgsize()); ++ assert_eq!($read_attr.curmsgs(), $initial_attr.curmsgs()); ++ } else { ++ assert_eq!($read_attr, $initial_attr); ++ } ++ } ++ } ++} ++ + #[test] + fn test_mq_send_and_receive() { +- const MSG_SIZE: c_long = 32; +- let attr = MqAttr::new(0, 10, MSG_SIZE, 0); +- let mq_name= &CString::new(b"/a_nix_test_queue".as_ref()).unwrap(); ++ const MSG_SIZE: mq_attr_member_t = 32; ++ let attr = MqAttr::new(0, 10, MSG_SIZE, 0); ++ let mq_name = &CString::new(b"/a_nix_test_queue".as_ref()).unwrap(); + + let oflag0 = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY; + let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH; + let r0 = mq_open(mq_name, oflag0, mode, Some(&attr)); +- if let Err(Sys(ENOSYS)) = r0 { ++ if let Err(Errno::ENOSYS) = r0 { + println!("message queues not supported or module not loaded?"); + return; + }; + let mqd0 = r0.unwrap(); + let msg_to_send = "msg_1"; +- mq_send(mqd0, msg_to_send.as_bytes(), 1).unwrap(); ++ mq_send(&mqd0, msg_to_send.as_bytes(), 1).unwrap(); + + let oflag1 = MQ_OFlag::O_CREAT | MQ_OFlag::O_RDONLY; + let mqd1 = mq_open(mq_name, oflag1, mode, Some(&attr)).unwrap(); + let mut buf = [0u8; 32]; + let mut prio = 0u32; +- let len = mq_receive(mqd1, &mut buf, &mut prio).unwrap(); ++ let len = mq_receive(&mqd1, &mut buf, &mut prio).unwrap(); + assert_eq!(prio, 1); + + mq_close(mqd1).unwrap(); +@@ -38,115 +55,136 @@ fn test_mq_send_and_receive() { + assert_eq!(msg_to_send, str::from_utf8(&buf[0..len]).unwrap()); + } + +- + #[test] +-#[cfg(not(any(target_os = "netbsd")))] + fn test_mq_getattr() { + use nix::mqueue::mq_getattr; +- const MSG_SIZE: c_long = 32; +- let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0); ++ const MSG_SIZE: mq_attr_member_t = 32; ++ let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0); + let mq_name = &CString::new(b"/attr_test_get_attr".as_ref()).unwrap(); + let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY; + let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH; + let r = mq_open(mq_name, oflag, mode, Some(&initial_attr)); +- if let Err(Sys(ENOSYS)) = r { ++ if let Err(Errno::ENOSYS) = r { + println!("message queues not supported or module not loaded?"); + return; + }; + let mqd = r.unwrap(); + +- let read_attr = mq_getattr(mqd).unwrap(); +- assert_eq!(read_attr, initial_attr); ++ let read_attr = mq_getattr(&mqd).unwrap(); ++ assert_attr_eq!(read_attr, initial_attr); + mq_close(mqd).unwrap(); + } + + // FIXME: Fix failures for mips in QEMU + #[test] +-#[cfg(not(any(target_os = "netbsd")))] +-#[cfg_attr(any(target_arch = "mips", target_arch = "mips64"), ignore)] ++#[cfg_attr( ++ all(qemu, any(target_arch = "mips", target_arch = "mips64")), ++ ignore ++)] + fn test_mq_setattr() { + use nix::mqueue::{mq_getattr, mq_setattr}; +- const MSG_SIZE: c_long = 32; +- let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0); ++ const MSG_SIZE: mq_attr_member_t = 32; ++ let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0); + let mq_name = &CString::new(b"/attr_test_get_attr".as_ref()).unwrap(); + let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY; + let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH; + let r = mq_open(mq_name, oflag, mode, Some(&initial_attr)); +- if let Err(Sys(ENOSYS)) = r { ++ if let Err(Errno::ENOSYS) = r { + println!("message queues not supported or module not loaded?"); + return; + }; + let mqd = r.unwrap(); + +- let new_attr = MqAttr::new(0, 20, MSG_SIZE * 2, 100); +- let old_attr = mq_setattr(mqd, &new_attr).unwrap(); +- assert_eq!(old_attr, initial_attr); ++ let new_attr = MqAttr::new(0, 20, MSG_SIZE * 2, 100); ++ let old_attr = mq_setattr(&mqd, &new_attr).unwrap(); ++ assert_attr_eq!(old_attr, initial_attr); + +- let new_attr_get = mq_getattr(mqd).unwrap(); +- // The following tests make sense. No changes here because according to the Linux man page only ++ // No changes here because according to the Linux man page only + // O_NONBLOCK can be set (see tests below) +- assert_ne!(new_attr_get, new_attr); +- +- let new_attr_non_blocking = MqAttr::new(MQ_OFlag::O_NONBLOCK.bits() as c_long, 10, MSG_SIZE, 0); +- mq_setattr(mqd, &new_attr_non_blocking).unwrap(); +- let new_attr_get = mq_getattr(mqd).unwrap(); ++ #[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))] ++ { ++ let new_attr_get = mq_getattr(&mqd).unwrap(); ++ assert_ne!(new_attr_get, new_attr); ++ } ++ ++ let new_attr_non_blocking = MqAttr::new( ++ MQ_OFlag::O_NONBLOCK.bits() as mq_attr_member_t, ++ 10, ++ MSG_SIZE, ++ 0, ++ ); ++ mq_setattr(&mqd, &new_attr_non_blocking).unwrap(); ++ let new_attr_get = mq_getattr(&mqd).unwrap(); + + // now the O_NONBLOCK flag has been set +- assert_ne!(new_attr_get, initial_attr); +- assert_eq!(new_attr_get, new_attr_non_blocking); ++ #[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))] ++ { ++ assert_ne!(new_attr_get, initial_attr); ++ } ++ assert_attr_eq!(new_attr_get, new_attr_non_blocking); + mq_close(mqd).unwrap(); + } + + // FIXME: Fix failures for mips in QEMU + #[test] +-#[cfg(not(any(target_os = "netbsd")))] +-#[cfg_attr(any(target_arch = "mips", target_arch = "mips64"), ignore)] ++#[cfg_attr( ++ all(qemu, any(target_arch = "mips", target_arch = "mips64")), ++ ignore ++)] + fn test_mq_set_nonblocking() { +- use nix::mqueue::{mq_getattr, mq_set_nonblock, mq_remove_nonblock}; +- const MSG_SIZE: c_long = 32; +- let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0); ++ use nix::mqueue::{mq_getattr, mq_remove_nonblock, mq_set_nonblock}; ++ const MSG_SIZE: mq_attr_member_t = 32; ++ let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0); + let mq_name = &CString::new(b"/attr_test_get_attr".as_ref()).unwrap(); + let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY; + let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH; + let r = mq_open(mq_name, oflag, mode, Some(&initial_attr)); +- if let Err(Sys(ENOSYS)) = r { ++ if let Err(Errno::ENOSYS) = r { + println!("message queues not supported or module not loaded?"); + return; + }; + let mqd = r.unwrap(); +- mq_set_nonblock(mqd).unwrap(); +- let new_attr = mq_getattr(mqd); +- assert_eq!(new_attr.unwrap().flags(), MQ_OFlag::O_NONBLOCK.bits() as c_long); +- mq_remove_nonblock(mqd).unwrap(); +- let new_attr = mq_getattr(mqd); +- assert_eq!(new_attr.unwrap().flags(), 0); ++ mq_set_nonblock(&mqd).unwrap(); ++ let new_attr = mq_getattr(&mqd); ++ let o_nonblock_bits = MQ_OFlag::O_NONBLOCK.bits() as mq_attr_member_t; ++ assert_eq!(new_attr.unwrap().flags() & o_nonblock_bits, o_nonblock_bits); ++ mq_remove_nonblock(&mqd).unwrap(); ++ let new_attr = mq_getattr(&mqd); ++ assert_eq!(new_attr.unwrap().flags() & o_nonblock_bits, 0); + mq_close(mqd).unwrap(); + } + + #[test] +-#[cfg(not(any(target_os = "netbsd")))] + fn test_mq_unlink() { + use nix::mqueue::mq_unlink; +- const MSG_SIZE: c_long = 32; +- let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0); ++ const MSG_SIZE: mq_attr_member_t = 32; ++ let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0); + let mq_name_opened = &CString::new(b"/mq_unlink_test".as_ref()).unwrap(); +- let mq_name_not_opened = &CString::new(b"/mq_unlink_test".as_ref()).unwrap(); ++ #[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))] ++ let mq_name_not_opened = ++ &CString::new(b"/mq_unlink_test".as_ref()).unwrap(); + let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY; + let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH; + let r = mq_open(mq_name_opened, oflag, mode, Some(&initial_attr)); +- if let Err(Sys(ENOSYS)) = r { ++ if let Err(Errno::ENOSYS) = r { + println!("message queues not supported or module not loaded?"); + return; + }; + let mqd = r.unwrap(); + + let res_unlink = mq_unlink(mq_name_opened); +- assert_eq!(res_unlink, Ok(()) ); ++ assert_eq!(res_unlink, Ok(())); + +- let res_unlink_not_opened = mq_unlink(mq_name_not_opened); +- assert_eq!(res_unlink_not_opened, Err(Sys(ENOENT)) ); ++ // NetBSD (and others which inherit its implementation) defer removing the message ++ // queue name until all references are closed, whereas Linux and others remove the ++ // message queue name immediately. ++ #[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))] ++ { ++ let res_unlink_not_opened = mq_unlink(mq_name_not_opened); ++ assert_eq!(res_unlink_not_opened, Err(Errno::ENOENT)); ++ } + + mq_close(mqd).unwrap(); + let res_unlink_after_close = mq_unlink(mq_name_opened); +- assert_eq!(res_unlink_after_close, Err(Sys(ENOENT)) ); ++ assert_eq!(res_unlink_after_close, Err(Errno::ENOENT)); + } +diff --git a/vendor/nix/test/test_net.rs b/vendor/nix/test/test_net.rs +index b8940e7..c44655a 100644 +--- a/vendor/nix/test/test_net.rs ++++ b/vendor/nix/test/test_net.rs +@@ -3,10 +3,17 @@ use nix::net::if_::*; + #[cfg(any(target_os = "android", target_os = "linux"))] + const LOOPBACK: &[u8] = b"lo"; + +-#[cfg(not(any(target_os = "android", target_os = "linux")))] ++#[cfg(not(any( ++ target_os = "android", ++ target_os = "linux", ++ target_os = "haiku" ++)))] + const LOOPBACK: &[u8] = b"lo0"; + ++#[cfg(target_os = "haiku")] ++const LOOPBACK: &[u8] = b"loop"; ++ + #[test] + fn test_if_nametoindex() { +- assert!(if_nametoindex(&LOOPBACK[..]).is_ok()); ++ if_nametoindex(LOOPBACK).expect("assertion failed"); + } +diff --git a/vendor/nix/test/test_nix_path.rs b/vendor/nix/test/test_nix_path.rs +index e69de29..8b13789 100644 +--- a/vendor/nix/test/test_nix_path.rs ++++ b/vendor/nix/test/test_nix_path.rs +@@ -0,0 +1 @@ ++ +diff --git a/vendor/nix/test/test_nmount.rs b/vendor/nix/test/test_nmount.rs +new file mode 100644 +index 0000000..dec806a +--- /dev/null ++++ b/vendor/nix/test/test_nmount.rs +@@ -0,0 +1,49 @@ ++use crate::*; ++use nix::{ ++ errno::Errno, ++ mount::{unmount, MntFlags, Nmount}, ++}; ++use std::{ffi::CString, fs::File, path::Path}; ++use tempfile::tempdir; ++ ++#[test] ++fn ok() { ++ require_mount!("nullfs"); ++ ++ let mountpoint = tempdir().unwrap(); ++ let target = tempdir().unwrap(); ++ let _sentry = File::create(target.path().join("sentry")).unwrap(); ++ ++ let fstype = CString::new("fstype").unwrap(); ++ let nullfs = CString::new("nullfs").unwrap(); ++ Nmount::new() ++ .str_opt(&fstype, &nullfs) ++ .str_opt_owned("fspath", mountpoint.path().to_str().unwrap()) ++ .str_opt_owned("target", target.path().to_str().unwrap()) ++ .nmount(MntFlags::empty()) ++ .unwrap(); ++ ++ // Now check that the sentry is visible through the mountpoint ++ let exists = Path::exists(&mountpoint.path().join("sentry")); ++ ++ // Cleanup the mountpoint before asserting ++ unmount(mountpoint.path(), MntFlags::empty()).unwrap(); ++ ++ assert!(exists); ++} ++ ++#[test] ++fn bad_fstype() { ++ let mountpoint = tempdir().unwrap(); ++ let target = tempdir().unwrap(); ++ let _sentry = File::create(target.path().join("sentry")).unwrap(); ++ ++ let e = Nmount::new() ++ .str_opt_owned("fspath", mountpoint.path().to_str().unwrap()) ++ .str_opt_owned("target", target.path().to_str().unwrap()) ++ .nmount(MntFlags::empty()) ++ .unwrap_err(); ++ ++ assert_eq!(e.error(), Errno::EINVAL); ++ assert_eq!(e.errmsg(), Some("Invalid fstype")); ++} +diff --git a/vendor/nix/test/test_poll.rs b/vendor/nix/test/test_poll.rs +index aef40e4..53964e2 100644 +--- a/vendor/nix/test/test_poll.rs ++++ b/vendor/nix/test/test_poll.rs +@@ -1,5 +1,20 @@ +-use nix::poll::{PollFlags, poll, PollFd}; +-use nix::unistd::{write, pipe}; ++use nix::{ ++ errno::Errno, ++ poll::{poll, PollFd, PollFlags}, ++ unistd::{pipe, write}, ++}; ++ ++macro_rules! loop_while_eintr { ++ ($poll_expr: expr) => { ++ loop { ++ match $poll_expr { ++ Ok(nfds) => break nfds, ++ Err(Errno::EINTR) => (), ++ Err(e) => panic!("{}", e), ++ } ++ } ++ }; ++} + + #[test] + fn test_poll() { +@@ -7,7 +22,7 @@ fn test_poll() { + let mut fds = [PollFd::new(r, PollFlags::POLLIN)]; + + // Poll an idle pipe. Should timeout +- let nfds = poll(&mut fds, 100).unwrap(); ++ let nfds = loop_while_eintr!(poll(&mut fds, 100)); + assert_eq!(nfds, 0); + assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN)); + +@@ -22,10 +37,12 @@ fn test_poll() { + // ppoll(2) is the same as poll except for how it handles timeouts and signals. + // Repeating the test for poll(2) should be sufficient to check that our + // bindings are correct. +-#[cfg(any(target_os = "android", +- target_os = "dragonfly", +- target_os = "freebsd", +- target_os = "linux"))] ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "linux" ++))] + #[test] + fn test_ppoll() { + use nix::poll::ppoll; +@@ -37,14 +54,31 @@ fn test_ppoll() { + let mut fds = [PollFd::new(r, PollFlags::POLLIN)]; + + // Poll an idle pipe. Should timeout +- let nfds = ppoll(&mut fds, timeout, SigSet::empty()).unwrap(); ++ let sigset = SigSet::empty(); ++ let nfds = loop_while_eintr!(ppoll(&mut fds, Some(timeout), Some(sigset))); + assert_eq!(nfds, 0); + assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN)); + + write(w, b".").unwrap(); + + // Poll a readable pipe. Should return an event. +- let nfds = ppoll(&mut fds, timeout, SigSet::empty()).unwrap(); ++ let nfds = ppoll(&mut fds, Some(timeout), None).unwrap(); + assert_eq!(nfds, 1); + assert!(fds[0].revents().unwrap().contains(PollFlags::POLLIN)); + } ++ ++#[test] ++fn test_pollfd_fd() { ++ use std::os::unix::io::AsRawFd; ++ ++ let pfd = PollFd::new(0x1234, PollFlags::empty()); ++ assert_eq!(pfd.as_raw_fd(), 0x1234); ++} ++ ++#[test] ++fn test_pollfd_events() { ++ let mut pfd = PollFd::new(-1, PollFlags::POLLIN); ++ assert_eq!(pfd.events(), PollFlags::POLLIN); ++ pfd.set_events(PollFlags::POLLOUT); ++ assert_eq!(pfd.events(), PollFlags::POLLOUT); ++} +diff --git a/vendor/nix/test/test_pty.rs b/vendor/nix/test/test_pty.rs +index dab34ca..5c27e2d 100644 +--- a/vendor/nix/test/test_pty.rs ++++ b/vendor/nix/test/test_pty.rs +@@ -1,14 +1,15 @@ +-use std::io::Write; +-use std::path::Path; ++use std::fs::File; ++use std::io::{Read, Write}; + use std::os::unix::prelude::*; ++use std::path::Path; + use tempfile::tempfile; + + use libc::{_exit, STDOUT_FILENO}; +-use nix::fcntl::{OFlag, open}; ++use nix::fcntl::{open, OFlag}; + use nix::pty::*; + use nix::sys::stat; + use nix::sys::termios::*; +-use nix::unistd::{write, close, pause}; ++use nix::unistd::{close, pause, write}; + + /// Regression test for Issue #659 + /// This is the correct way to explicitly close a `PtyMaster` +@@ -28,14 +29,14 @@ fn test_explicit_close() { + #[test] + #[cfg(any(target_os = "android", target_os = "linux"))] + fn test_ptsname_equivalence() { +- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::PTSNAME_MTX.lock(); + + // Open a new PTTY master + let master_fd = posix_openpt(OFlag::O_RDWR).unwrap(); + assert!(master_fd.as_raw_fd() > 0); + + // Get the name of the slave +- let slave_name = unsafe { ptsname(&master_fd) }.unwrap() ; ++ let slave_name = unsafe { ptsname(&master_fd) }.unwrap(); + let slave_name_r = ptsname_r(&master_fd).unwrap(); + assert_eq!(slave_name, slave_name_r); + } +@@ -45,7 +46,7 @@ fn test_ptsname_equivalence() { + #[test] + #[cfg(any(target_os = "android", target_os = "linux"))] + fn test_ptsname_copy() { +- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::PTSNAME_MTX.lock(); + + // Open a new PTTY master + let master_fd = posix_openpt(OFlag::O_RDWR).unwrap(); +@@ -57,7 +58,7 @@ fn test_ptsname_copy() { + assert_eq!(slave_name1, slave_name2); + // Also make sure that the string was actually copied and they point to different parts of + // memory. +- assert!(slave_name1.as_ptr() != slave_name2.as_ptr()); ++ assert_ne!(slave_name1.as_ptr(), slave_name2.as_ptr()); + } + + /// Test data copying of `ptsname_r` +@@ -72,14 +73,14 @@ fn test_ptsname_r_copy() { + let slave_name1 = ptsname_r(&master_fd).unwrap(); + let slave_name2 = ptsname_r(&master_fd).unwrap(); + assert_eq!(slave_name1, slave_name2); +- assert!(slave_name1.as_ptr() != slave_name2.as_ptr()); ++ assert_ne!(slave_name1.as_ptr(), slave_name2.as_ptr()); + } + + /// Test that `ptsname` returns different names for different devices + #[test] + #[cfg(any(target_os = "android", target_os = "linux"))] + fn test_ptsname_unique() { +- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::PTSNAME_MTX.lock(); + + // Open a new PTTY master + let master1_fd = posix_openpt(OFlag::O_RDWR).unwrap(); +@@ -92,38 +93,113 @@ fn test_ptsname_unique() { + // Get the name of the slave + let slave_name1 = unsafe { ptsname(&master1_fd) }.unwrap(); + let slave_name2 = unsafe { ptsname(&master2_fd) }.unwrap(); +- assert!(slave_name1 != slave_name2); ++ assert_ne!(slave_name1, slave_name2); + } + +-/// Test opening a master/slave PTTY pair +-/// +-/// This is a single larger test because much of these functions aren't useful by themselves. So for +-/// this test we perform the basic act of getting a file handle for a connect master/slave PTTY +-/// pair. +-#[test] +-fn test_open_ptty_pair() { +- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); ++/// Common setup for testing PTTY pairs ++fn open_ptty_pair() -> (PtyMaster, File) { ++ let _m = crate::PTSNAME_MTX.lock(); + + // Open a new PTTY master +- let master_fd = posix_openpt(OFlag::O_RDWR).expect("posix_openpt failed"); +- assert!(master_fd.as_raw_fd() > 0); ++ let master = posix_openpt(OFlag::O_RDWR).expect("posix_openpt failed"); + + // Allow a slave to be generated for it +- grantpt(&master_fd).expect("grantpt failed"); +- unlockpt(&master_fd).expect("unlockpt failed"); ++ grantpt(&master).expect("grantpt failed"); ++ unlockpt(&master).expect("unlockpt failed"); + + // Get the name of the slave +- let slave_name = unsafe { ptsname(&master_fd) }.expect("ptsname failed"); ++ let slave_name = unsafe { ptsname(&master) }.expect("ptsname failed"); + + // Open the slave device +- let slave_fd = open(Path::new(&slave_name), OFlag::O_RDWR, stat::Mode::empty()).unwrap(); +- assert!(slave_fd > 0); ++ let slave_fd = ++ open(Path::new(&slave_name), OFlag::O_RDWR, stat::Mode::empty()) ++ .unwrap(); ++ ++ #[cfg(target_os = "illumos")] ++ // TODO: rewrite using ioctl! ++ #[allow(clippy::comparison_chain)] ++ { ++ use libc::{ioctl, I_FIND, I_PUSH}; ++ ++ // On illumos systems, as per pts(7D), one must push STREAMS modules ++ // after opening a device path returned from ptsname(). ++ let ptem = b"ptem\0"; ++ let ldterm = b"ldterm\0"; ++ let r = unsafe { ioctl(slave_fd, I_FIND, ldterm.as_ptr()) }; ++ if r < 0 { ++ panic!("I_FIND failure"); ++ } else if r == 0 { ++ if unsafe { ioctl(slave_fd, I_PUSH, ptem.as_ptr()) } < 0 { ++ panic!("I_PUSH ptem failure"); ++ } ++ if unsafe { ioctl(slave_fd, I_PUSH, ldterm.as_ptr()) } < 0 { ++ panic!("I_PUSH ldterm failure"); ++ } ++ } ++ } ++ ++ let slave = unsafe { File::from_raw_fd(slave_fd) }; ++ ++ (master, slave) ++} ++ ++/// Test opening a master/slave PTTY pair ++/// ++/// This uses a common `open_ptty_pair` because much of these functions aren't useful by ++/// themselves. So for this test we perform the basic act of getting a file handle for a ++/// master/slave PTTY pair, then just sanity-check the raw values. ++#[test] ++fn test_open_ptty_pair() { ++ let (master, slave) = open_ptty_pair(); ++ assert!(master.as_raw_fd() > 0); ++ assert!(slave.as_raw_fd() > 0); ++} ++ ++/// Put the terminal in raw mode. ++fn make_raw(fd: RawFd) { ++ let mut termios = tcgetattr(fd).unwrap(); ++ cfmakeraw(&mut termios); ++ tcsetattr(fd, SetArg::TCSANOW, &termios).unwrap(); ++} ++ ++/// Test `io::Read` on the PTTY master ++#[test] ++fn test_read_ptty_pair() { ++ let (mut master, mut slave) = open_ptty_pair(); ++ make_raw(slave.as_raw_fd()); ++ ++ let mut buf = [0u8; 5]; ++ slave.write_all(b"hello").unwrap(); ++ master.read_exact(&mut buf).unwrap(); ++ assert_eq!(&buf, b"hello"); ++ ++ let mut master = &master; ++ slave.write_all(b"hello").unwrap(); ++ master.read_exact(&mut buf).unwrap(); ++ assert_eq!(&buf, b"hello"); ++} ++ ++/// Test `io::Write` on the PTTY master ++#[test] ++fn test_write_ptty_pair() { ++ let (mut master, mut slave) = open_ptty_pair(); ++ make_raw(slave.as_raw_fd()); ++ ++ let mut buf = [0u8; 5]; ++ master.write_all(b"adios").unwrap(); ++ slave.read_exact(&mut buf).unwrap(); ++ assert_eq!(&buf, b"adios"); ++ ++ let mut master = &master; ++ master.write_all(b"adios").unwrap(); ++ slave.read_exact(&mut buf).unwrap(); ++ assert_eq!(&buf, b"adios"); + } + + #[test] + fn test_openpty() { + // openpty uses ptname(3) internally +- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::PTSNAME_MTX.lock(); + + let pty = openpty(None, None).unwrap(); + assert!(pty.master > 0); +@@ -133,21 +209,21 @@ fn test_openpty() { + let string = "foofoofoo\n"; + let mut buf = [0u8; 10]; + write(pty.master, string.as_bytes()).unwrap(); +- ::read_exact(pty.slave, &mut buf); ++ crate::read_exact(pty.slave, &mut buf); + + assert_eq!(&buf, string.as_bytes()); + + // Read the echo as well + let echoed_string = "foofoofoo\r\n"; + let mut buf = [0u8; 11]; +- ::read_exact(pty.master, &mut buf); ++ crate::read_exact(pty.master, &mut buf); + assert_eq!(&buf, echoed_string.as_bytes()); + + let string2 = "barbarbarbar\n"; + let echoed_string2 = "barbarbarbar\r\n"; + let mut buf = [0u8; 14]; + write(pty.slave, string2.as_bytes()).unwrap(); +- ::read_exact(pty.master, &mut buf); ++ crate::read_exact(pty.master, &mut buf); + + assert_eq!(&buf, echoed_string2.as_bytes()); + +@@ -158,14 +234,14 @@ fn test_openpty() { + #[test] + fn test_openpty_with_termios() { + // openpty uses ptname(3) internally +- let _m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::PTSNAME_MTX.lock(); + + // Open one pty to get attributes for the second one + let mut termios = { + let pty = openpty(None, None).unwrap(); + assert!(pty.master > 0); + assert!(pty.slave > 0); +- let termios = tcgetattr(pty.master).unwrap(); ++ let termios = tcgetattr(pty.slave).unwrap(); + close(pty.master).unwrap(); + close(pty.slave).unwrap(); + termios +@@ -182,20 +258,20 @@ fn test_openpty_with_termios() { + let string = "foofoofoo\n"; + let mut buf = [0u8; 10]; + write(pty.master, string.as_bytes()).unwrap(); +- ::read_exact(pty.slave, &mut buf); ++ crate::read_exact(pty.slave, &mut buf); + + assert_eq!(&buf, string.as_bytes()); + + // read the echo as well + let echoed_string = "foofoofoo\n"; +- ::read_exact(pty.master, &mut buf); ++ crate::read_exact(pty.master, &mut buf); + assert_eq!(&buf, echoed_string.as_bytes()); + + let string2 = "barbarbarbar\n"; + let echoed_string2 = "barbarbarbar\n"; + let mut buf = [0u8; 13]; + write(pty.slave, string2.as_bytes()).unwrap(); +- ::read_exact(pty.master, &mut buf); ++ crate::read_exact(pty.master, &mut buf); + + assert_eq!(&buf, echoed_string2.as_bytes()); + +@@ -205,31 +281,33 @@ fn test_openpty_with_termios() { + + #[test] + fn test_forkpty() { +- use nix::unistd::ForkResult::*; + use nix::sys::signal::*; + use nix::sys::wait::wait; ++ use nix::unistd::ForkResult::*; + // forkpty calls openpty which uses ptname(3) internally. +- let _m0 = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m0 = crate::PTSNAME_MTX.lock(); + // forkpty spawns a child process +- let _m1 = ::FORK_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m1 = crate::FORK_MTX.lock(); + + let string = "naninani\n"; + let echoed_string = "naninani\r\n"; +- let pty = forkpty(None, None).unwrap(); ++ let pty = unsafe { forkpty(None, None).unwrap() }; + match pty.fork_result { + Child => { + write(STDOUT_FILENO, string.as_bytes()).unwrap(); +- pause(); // we need the child to stay alive until the parent calls read +- unsafe { _exit(0); } +- }, ++ pause(); // we need the child to stay alive until the parent calls read ++ unsafe { ++ _exit(0); ++ } ++ } + Parent { child } => { + let mut buf = [0u8; 10]; + assert!(child.as_raw() > 0); +- ::read_exact(pty.master, &mut buf); ++ crate::read_exact(pty.master, &mut buf); + kill(child, SIGTERM).unwrap(); + wait().unwrap(); // keep other tests using generic wait from getting our child + assert_eq!(&buf, echoed_string.as_bytes()); + close(pty.master).unwrap(); +- }, ++ } + } + } +diff --git a/vendor/nix/test/test_ptymaster_drop.rs b/vendor/nix/test/test_ptymaster_drop.rs +index 9b59d66..ffbaa56 100644 +--- a/vendor/nix/test/test_ptymaster_drop.rs ++++ b/vendor/nix/test/test_ptymaster_drop.rs +@@ -1,21 +1,20 @@ +-extern crate nix; ++#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))] ++mod t { ++ use nix::fcntl::OFlag; ++ use nix::pty::*; ++ use nix::unistd::close; ++ use std::os::unix::io::AsRawFd; + +-use nix::fcntl::OFlag; +-use nix::pty::*; +-use nix::unistd::close; +-use std::os::unix::io::AsRawFd; +- +-/// Regression test for Issue #659 +-/// `PtyMaster` should panic rather than double close the file descriptor +-/// This must run in its own test process because it deliberately creates a race +-/// condition. +-#[test] +-#[should_panic(expected = "Closing an invalid file descriptor!")] +-// In Travis on i686-unknown-linux-musl, this test gets SIGABRT. I don't know +-// why. It doesn't happen on any other target, and it doesn't happen on my PC. +-#[cfg_attr(all(target_env = "musl", target_arch = "x86"), ignore)] +-fn test_double_close() { +- let m = posix_openpt(OFlag::O_RDWR).unwrap(); +- close(m.as_raw_fd()).unwrap(); +- drop(m); // should panic here ++ /// Regression test for Issue #659 ++ /// ++ /// `PtyMaster` should panic rather than double close the file descriptor ++ /// This must run in its own test process because it deliberately creates a ++ /// race condition. ++ #[test] ++ #[should_panic(expected = "Closing an invalid file descriptor!")] ++ fn test_double_close() { ++ let m = posix_openpt(OFlag::O_RDWR).unwrap(); ++ close(m.as_raw_fd()).unwrap(); ++ drop(m); // should panic here ++ } + } +diff --git a/vendor/nix/test/test_resource.rs b/vendor/nix/test/test_resource.rs +new file mode 100644 +index 0000000..2ab581b +--- /dev/null ++++ b/vendor/nix/test/test_resource.rs +@@ -0,0 +1,34 @@ ++#[cfg(not(any( ++ target_os = "redox", ++ target_os = "fuchsia", ++ target_os = "illumos", ++ target_os = "haiku" ++)))] ++use nix::sys::resource::{getrlimit, setrlimit, Resource}; ++ ++/// Tests the RLIMIT_NOFILE functionality of getrlimit(), where the resource RLIMIT_NOFILE refers ++/// to the maximum file descriptor number that can be opened by the process (aka the maximum number ++/// of file descriptors that the process can open, since Linux 4.5). ++/// ++/// We first fetch the existing file descriptor maximum values using getrlimit(), then edit the ++/// soft limit to make sure it has a new and distinct value to the hard limit. We then setrlimit() ++/// to put the new soft limit in effect, and then getrlimit() once more to ensure the limits have ++/// been updated. ++#[test] ++#[cfg(not(any( ++ target_os = "redox", ++ target_os = "fuchsia", ++ target_os = "illumos", ++ target_os = "haiku" ++)))] ++pub fn test_resource_limits_nofile() { ++ let (mut soft_limit, hard_limit) = ++ getrlimit(Resource::RLIMIT_NOFILE).unwrap(); ++ ++ soft_limit -= 1; ++ assert_ne!(soft_limit, hard_limit); ++ setrlimit(Resource::RLIMIT_NOFILE, soft_limit, hard_limit).unwrap(); ++ ++ let (new_soft_limit, _) = getrlimit(Resource::RLIMIT_NOFILE).unwrap(); ++ assert_eq!(new_soft_limit, soft_limit); ++} +diff --git a/vendor/nix/test/test_sched.rs b/vendor/nix/test/test_sched.rs +index 922196a..c52616b 100644 +--- a/vendor/nix/test/test_sched.rs ++++ b/vendor/nix/test/test_sched.rs +@@ -1,4 +1,4 @@ +-use nix::sched::{sched_getaffinity, sched_setaffinity, CpuSet}; ++use nix::sched::{sched_getaffinity, sched_getcpu, sched_setaffinity, CpuSet}; + use nix::unistd::Pid; + + #[test] +@@ -24,9 +24,16 @@ fn test_sched_affinity() { + let updated_affinity = sched_getaffinity(Pid::from_raw(0)).unwrap(); + for field in 0..CpuSet::count() { + // Should be set only for the CPU we set previously +- assert_eq!(updated_affinity.is_set(field).unwrap(), field==last_valid_cpu) ++ assert_eq!( ++ updated_affinity.is_set(field).unwrap(), ++ field == last_valid_cpu ++ ) + } + ++ // Now check that we're also currently running on the CPU in question. ++ let cur_cpu = sched_getcpu().unwrap(); ++ assert_eq!(cur_cpu, last_valid_cpu); ++ + // Finally, reset the initial CPU set + sched_setaffinity(Pid::from_raw(0), &initial_affinity).unwrap(); + } +diff --git a/vendor/nix/test/test_sendfile.rs b/vendor/nix/test/test_sendfile.rs +index 3bc7932..f73a3b5 100644 +--- a/vendor/nix/test/test_sendfile.rs ++++ b/vendor/nix/test/test_sendfile.rs +@@ -8,7 +8,7 @@ use tempfile::tempfile; + cfg_if! { + if #[cfg(any(target_os = "android", target_os = "linux"))] { + use nix::unistd::{close, pipe, read}; +- } else if #[cfg(any(target_os = "freebsd", target_os = "ios", target_os = "macos"))] { ++ } else if #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos"))] { + use std::net::Shutdown; + use std::os::unix::net::UnixStream; + } +@@ -36,11 +36,34 @@ fn test_sendfile_linux() { + close(wr).unwrap(); + } + ++#[cfg(target_os = "linux")] ++#[test] ++fn test_sendfile64_linux() { ++ const CONTENTS: &[u8] = b"abcdef123456"; ++ let mut tmp = tempfile().unwrap(); ++ tmp.write_all(CONTENTS).unwrap(); ++ ++ let (rd, wr) = pipe().unwrap(); ++ let mut offset: libc::off64_t = 5; ++ let res = sendfile64(wr, tmp.as_raw_fd(), Some(&mut offset), 2).unwrap(); ++ ++ assert_eq!(2, res); ++ ++ let mut buf = [0u8; 1024]; ++ assert_eq!(2, read(rd, &mut buf).unwrap()); ++ assert_eq!(b"f1", &buf[0..2]); ++ assert_eq!(7, offset); ++ ++ close(rd).unwrap(); ++ close(wr).unwrap(); ++} ++ + #[cfg(target_os = "freebsd")] + #[test] + fn test_sendfile_freebsd() { + // Declare the content +- let header_strings = vec!["HTTP/1.1 200 OK\n", "Content-Type: text/plain\n", "\n"]; ++ let header_strings = ++ vec!["HTTP/1.1 200 OK\n", "Content-Type: text/plain\n", "\n"]; + let body = "Xabcdef123456"; + let body_offset = 1; + let trailer_strings = vec!["\n", "Served by Make Believe\n"]; +@@ -50,8 +73,10 @@ fn test_sendfile_freebsd() { + tmp.write_all(body.as_bytes()).unwrap(); + + // Prepare headers and trailers for sendfile +- let headers: Vec<&[u8]> = header_strings.iter().map(|s| s.as_bytes()).collect(); +- let trailers: Vec<&[u8]> = trailer_strings.iter().map(|s| s.as_bytes()).collect(); ++ let headers: Vec<&[u8]> = ++ header_strings.iter().map(|s| s.as_bytes()).collect(); ++ let trailers: Vec<&[u8]> = ++ trailer_strings.iter().map(|s| s.as_bytes()).collect(); + + // Prepare socket pair + let (mut rd, wr) = UnixStream::pair().unwrap(); +@@ -71,8 +96,58 @@ fn test_sendfile_freebsd() { + wr.shutdown(Shutdown::Both).unwrap(); + + // Prepare the expected result +- let expected_string = +- header_strings.concat() + &body[body_offset..] + &trailer_strings.concat(); ++ let expected_string = header_strings.concat() ++ + &body[body_offset..] ++ + &trailer_strings.concat(); ++ ++ // Verify the message that was sent ++ assert_eq!(bytes_written as usize, expected_string.as_bytes().len()); ++ ++ let mut read_string = String::new(); ++ let bytes_read = rd.read_to_string(&mut read_string).unwrap(); ++ assert_eq!(bytes_written as usize, bytes_read); ++ assert_eq!(expected_string, read_string); ++} ++ ++#[cfg(target_os = "dragonfly")] ++#[test] ++fn test_sendfile_dragonfly() { ++ // Declare the content ++ let header_strings = ++ vec!["HTTP/1.1 200 OK\n", "Content-Type: text/plain\n", "\n"]; ++ let body = "Xabcdef123456"; ++ let body_offset = 1; ++ let trailer_strings = vec!["\n", "Served by Make Believe\n"]; ++ ++ // Write the body to a file ++ let mut tmp = tempfile().unwrap(); ++ tmp.write_all(body.as_bytes()).unwrap(); ++ ++ // Prepare headers and trailers for sendfile ++ let headers: Vec<&[u8]> = ++ header_strings.iter().map(|s| s.as_bytes()).collect(); ++ let trailers: Vec<&[u8]> = ++ trailer_strings.iter().map(|s| s.as_bytes()).collect(); ++ ++ // Prepare socket pair ++ let (mut rd, wr) = UnixStream::pair().unwrap(); ++ ++ // Call the test method ++ let (res, bytes_written) = sendfile( ++ tmp.as_raw_fd(), ++ wr.as_raw_fd(), ++ body_offset as off_t, ++ None, ++ Some(headers.as_slice()), ++ Some(trailers.as_slice()), ++ ); ++ assert!(res.is_ok()); ++ wr.shutdown(Shutdown::Both).unwrap(); ++ ++ // Prepare the expected result ++ let expected_string = header_strings.concat() ++ + &body[body_offset..] ++ + &trailer_strings.concat(); + + // Verify the message that was sent + assert_eq!(bytes_written as usize, expected_string.as_bytes().len()); +@@ -87,7 +162,8 @@ fn test_sendfile_freebsd() { + #[test] + fn test_sendfile_darwin() { + // Declare the content +- let header_strings = vec!["HTTP/1.1 200 OK\n", "Content-Type: text/plain\n", "\n"]; ++ let header_strings = ++ vec!["HTTP/1.1 200 OK\n", "Content-Type: text/plain\n", "\n"]; + let body = "Xabcdef123456"; + let body_offset = 1; + let trailer_strings = vec!["\n", "Served by Make Believe\n"]; +@@ -97,8 +173,10 @@ fn test_sendfile_darwin() { + tmp.write_all(body.as_bytes()).unwrap(); + + // Prepare headers and trailers for sendfile +- let headers: Vec<&[u8]> = header_strings.iter().map(|s| s.as_bytes()).collect(); +- let trailers: Vec<&[u8]> = trailer_strings.iter().map(|s| s.as_bytes()).collect(); ++ let headers: Vec<&[u8]> = ++ header_strings.iter().map(|s| s.as_bytes()).collect(); ++ let trailers: Vec<&[u8]> = ++ trailer_strings.iter().map(|s| s.as_bytes()).collect(); + + // Prepare socket pair + let (mut rd, wr) = UnixStream::pair().unwrap(); +@@ -116,8 +194,9 @@ fn test_sendfile_darwin() { + wr.shutdown(Shutdown::Both).unwrap(); + + // Prepare the expected result +- let expected_string = +- header_strings.concat() + &body[body_offset..] + &trailer_strings.concat(); ++ let expected_string = header_strings.concat() ++ + &body[body_offset..] ++ + &trailer_strings.concat(); + + // Verify the message that was sent + assert_eq!(bytes_written as usize, expected_string.as_bytes().len()); +diff --git a/vendor/nix/test/test_stat.rs b/vendor/nix/test/test_stat.rs +index d180938..55f15c0 100644 +--- a/vendor/nix/test/test_stat.rs ++++ b/vendor/nix/test/test_stat.rs +@@ -1,82 +1,98 @@ +-use std::fs::{self, File}; +-use std::os::unix::fs::{symlink, PermissionsExt}; ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++use std::fs; ++use std::fs::File; ++#[cfg(not(target_os = "redox"))] ++use std::os::unix::fs::symlink; ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++use std::os::unix::fs::PermissionsExt; + use std::os::unix::prelude::AsRawFd; +-use std::time::{Duration, UNIX_EPOCH}; ++#[cfg(not(target_os = "redox"))] + use std::path::Path; ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++use std::time::{Duration, UNIX_EPOCH}; + +-#[cfg(not(any(target_os = "netbsd")))] +-use libc::{S_IFMT, S_IFLNK, mode_t}; +- +-use nix::{fcntl, Error}; +-use nix::errno::{Errno}; +-use nix::sys::stat::{self, fchmod, fchmodat, futimens, stat, utimes, utimensat, mkdirat}; +-#[cfg(any(target_os = "linux", +- target_os = "haiku", +- target_os = "ios", +- target_os = "macos", +- target_os = "freebsd", +- target_os = "netbsd"))] ++use libc::mode_t; ++#[cfg(not(any(target_os = "netbsd", target_os = "redox")))] ++use libc::{S_IFLNK, S_IFMT}; ++ ++#[cfg(not(target_os = "redox"))] ++use nix::errno::Errno; ++#[cfg(not(target_os = "redox"))] ++use nix::fcntl; ++#[cfg(any( ++ target_os = "linux", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "netbsd" ++))] + use nix::sys::stat::lutimes; +-use nix::sys::stat::{Mode, FchmodatFlags, UtimensatFlags}; +- +-#[cfg(not(any(target_os = "netbsd")))] ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++use nix::sys::stat::utimensat; ++#[cfg(not(target_os = "redox"))] ++use nix::sys::stat::FchmodatFlags; ++use nix::sys::stat::Mode; ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++use nix::sys::stat::UtimensatFlags; ++#[cfg(not(target_os = "redox"))] ++use nix::sys::stat::{self}; ++use nix::sys::stat::{fchmod, stat}; ++#[cfg(not(target_os = "redox"))] ++use nix::sys::stat::{fchmodat, mkdirat}; ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++use nix::sys::stat::{futimens, utimes}; ++ ++#[cfg(not(any(target_os = "netbsd", target_os = "redox")))] + use nix::sys::stat::FileStat; + ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] + use nix::sys::time::{TimeSpec, TimeVal, TimeValLike}; ++#[cfg(not(target_os = "redox"))] + use nix::unistd::chdir; + +-#[cfg(not(any(target_os = "netbsd")))] ++#[cfg(not(any(target_os = "netbsd", target_os = "redox")))] + use nix::Result; +-use tempfile; +- +-#[allow(unused_comparisons)] +-// uid and gid are signed on Windows, but not on other platforms. This function +-// allows warning free compiles on all platforms, and can be removed when +-// expression-level #[allow] is available. +-#[cfg(not(any(target_os = "netbsd")))] +-fn valid_uid_gid(stat: FileStat) -> bool { +- // uid could be 0 for the `root` user. This quite possible when +- // the tests are being run on a rooted Android device. +- stat.st_uid >= 0 && stat.st_gid >= 0 +-} + +-#[cfg(not(any(target_os = "netbsd")))] ++#[cfg(not(any(target_os = "netbsd", target_os = "redox")))] + fn assert_stat_results(stat_result: Result) { + let stats = stat_result.expect("stat call failed"); +- assert!(stats.st_dev > 0); // must be positive integer, exact number machine dependent +- assert!(stats.st_ino > 0); // inode is positive integer, exact number machine dependent +- assert!(stats.st_mode > 0); // must be positive integer +- assert_eq!(stats.st_nlink, 1); // there links created, must be 1 +- assert!(valid_uid_gid(stats)); // must be positive integers +- assert_eq!(stats.st_size, 0); // size is 0 because we did not write anything to the file +- assert!(stats.st_blksize > 0); // must be positive integer, exact number machine dependent +- assert!(stats.st_blocks <= 16); // Up to 16 blocks can be allocated for a blank file ++ assert!(stats.st_dev > 0); // must be positive integer, exact number machine dependent ++ assert!(stats.st_ino > 0); // inode is positive integer, exact number machine dependent ++ assert!(stats.st_mode > 0); // must be positive integer ++ assert_eq!(stats.st_nlink, 1); // there links created, must be 1 ++ assert_eq!(stats.st_size, 0); // size is 0 because we did not write anything to the file ++ assert!(stats.st_blksize > 0); // must be positive integer, exact number machine dependent ++ assert!(stats.st_blocks <= 16); // Up to 16 blocks can be allocated for a blank file + } + +-#[cfg(not(any(target_os = "netbsd")))] ++#[cfg(not(any(target_os = "netbsd", target_os = "redox")))] ++// (Android's st_blocks is ulonglong which is always non-negative.) ++#[cfg_attr(target_os = "android", allow(unused_comparisons))] ++#[allow(clippy::absurd_extreme_comparisons)] // Not absurd on all OSes + fn assert_lstat_results(stat_result: Result) { + let stats = stat_result.expect("stat call failed"); +- assert!(stats.st_dev > 0); // must be positive integer, exact number machine dependent +- assert!(stats.st_ino > 0); // inode is positive integer, exact number machine dependent +- assert!(stats.st_mode > 0); // must be positive integer ++ assert!(stats.st_dev > 0); // must be positive integer, exact number machine dependent ++ assert!(stats.st_ino > 0); // inode is positive integer, exact number machine dependent ++ assert!(stats.st_mode > 0); // must be positive integer + + // st_mode is c_uint (u32 on Android) while S_IFMT is mode_t + // (u16 on Android), and that will be a compile error. + // On other platforms they are the same (either both are u16 or u32). +- assert_eq!((stats.st_mode as usize) & (S_IFMT as usize), S_IFLNK as usize); // should be a link +- assert_eq!(stats.st_nlink, 1); // there links created, must be 1 +- assert!(valid_uid_gid(stats)); // must be positive integers +- assert!(stats.st_size > 0); // size is > 0 because it points to another file +- assert!(stats.st_blksize > 0); // must be positive integer, exact number machine dependent ++ assert_eq!( ++ (stats.st_mode as usize) & (S_IFMT as usize), ++ S_IFLNK as usize ++ ); // should be a link ++ assert_eq!(stats.st_nlink, 1); // there links created, must be 1 ++ assert!(stats.st_size > 0); // size is > 0 because it points to another file ++ assert!(stats.st_blksize > 0); // must be positive integer, exact number machine dependent + + // st_blocks depends on whether the machine's file system uses fast + // or slow symlinks, so just make sure it's not negative +- // (Android's st_blocks is ulonglong which is always non-negative.) + assert!(stats.st_blocks >= 0); + } + + #[test] +-#[cfg(not(any(target_os = "netbsd")))] ++#[cfg(not(any(target_os = "netbsd", target_os = "redox")))] + fn test_stat_and_fstat() { + use nix::sys::stat::fstat; + +@@ -92,23 +108,21 @@ fn test_stat_and_fstat() { + } + + #[test] +-#[cfg(not(any(target_os = "netbsd")))] ++#[cfg(not(any(target_os = "netbsd", target_os = "redox")))] + fn test_fstatat() { + let tempdir = tempfile::tempdir().unwrap(); + let filename = tempdir.path().join("foo.txt"); + File::create(&filename).unwrap(); +- let dirfd = fcntl::open(tempdir.path(), +- fcntl::OFlag::empty(), +- stat::Mode::empty()); ++ let dirfd = ++ fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()); + +- let result = stat::fstatat(dirfd.unwrap(), +- &filename, +- fcntl::AtFlags::empty()); ++ let result = ++ stat::fstatat(dirfd.unwrap(), &filename, fcntl::AtFlags::empty()); + assert_stat_results(result); + } + + #[test] +-#[cfg(not(any(target_os = "netbsd")))] ++#[cfg(not(any(target_os = "netbsd", target_os = "redox")))] + fn test_stat_fstat_lstat() { + use nix::sys::stat::{fstat, lstat}; + +@@ -144,33 +158,37 @@ fn test_fchmod() { + fchmod(file.as_raw_fd(), mode1).unwrap(); + + let file_stat1 = stat(&filename).unwrap(); +- assert_eq!(file_stat1.st_mode & 0o7777, mode1.bits()); ++ assert_eq!(file_stat1.st_mode as mode_t & 0o7777, mode1.bits()); + + let mut mode2 = Mode::empty(); + mode2.insert(Mode::S_IROTH); + fchmod(file.as_raw_fd(), mode2).unwrap(); + + let file_stat2 = stat(&filename).unwrap(); +- assert_eq!(file_stat2.st_mode & 0o7777, mode2.bits()); ++ assert_eq!(file_stat2.st_mode as mode_t & 0o7777, mode2.bits()); + } + + #[test] ++#[cfg(not(target_os = "redox"))] + fn test_fchmodat() { +- let _dr = ::DirRestore::new(); ++ let _dr = crate::DirRestore::new(); + let tempdir = tempfile::tempdir().unwrap(); + let filename = "foo.txt"; + let fullpath = tempdir.path().join(filename); + File::create(&fullpath).unwrap(); + +- let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); ++ let dirfd = ++ fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) ++ .unwrap(); + + let mut mode1 = Mode::empty(); + mode1.insert(Mode::S_IRUSR); + mode1.insert(Mode::S_IWUSR); +- fchmodat(Some(dirfd), filename, mode1, FchmodatFlags::FollowSymlink).unwrap(); ++ fchmodat(Some(dirfd), filename, mode1, FchmodatFlags::FollowSymlink) ++ .unwrap(); + + let file_stat1 = stat(&fullpath).unwrap(); +- assert_eq!(file_stat1.st_mode & 0o7777, mode1.bits()); ++ assert_eq!(file_stat1.st_mode as mode_t & 0o7777, mode1.bits()); + + chdir(tempdir.path()).unwrap(); + +@@ -179,39 +197,49 @@ fn test_fchmodat() { + fchmodat(None, filename, mode2, FchmodatFlags::FollowSymlink).unwrap(); + + let file_stat2 = stat(&fullpath).unwrap(); +- assert_eq!(file_stat2.st_mode & 0o7777, mode2.bits()); ++ assert_eq!(file_stat2.st_mode as mode_t & 0o7777, mode2.bits()); + } + + /// Asserts that the atime and mtime in a file's metadata match expected values. + /// + /// The atime and mtime are expressed with a resolution of seconds because some file systems + /// (like macOS's HFS+) do not have higher granularity. +-fn assert_times_eq(exp_atime_sec: u64, exp_mtime_sec: u64, attr: &fs::Metadata) { ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++fn assert_times_eq( ++ exp_atime_sec: u64, ++ exp_mtime_sec: u64, ++ attr: &fs::Metadata, ++) { + assert_eq!( + Duration::new(exp_atime_sec, 0), +- attr.accessed().unwrap().duration_since(UNIX_EPOCH).unwrap()); ++ attr.accessed().unwrap().duration_since(UNIX_EPOCH).unwrap() ++ ); + assert_eq!( + Duration::new(exp_mtime_sec, 0), +- attr.modified().unwrap().duration_since(UNIX_EPOCH).unwrap()); ++ attr.modified().unwrap().duration_since(UNIX_EPOCH).unwrap() ++ ); + } + + #[test] ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] + fn test_utimes() { + let tempdir = tempfile::tempdir().unwrap(); + let fullpath = tempdir.path().join("file"); + drop(File::create(&fullpath).unwrap()); + +- utimes(&fullpath, &TimeVal::seconds(9990), &TimeVal::seconds(5550)).unwrap(); ++ utimes(&fullpath, &TimeVal::seconds(9990), &TimeVal::seconds(5550)) ++ .unwrap(); + assert_times_eq(9990, 5550, &fs::metadata(&fullpath).unwrap()); + } + + #[test] +-#[cfg(any(target_os = "linux", +- target_os = "haiku", +- target_os = "ios", +- target_os = "macos", +- target_os = "freebsd", +- target_os = "netbsd"))] ++#[cfg(any( ++ target_os = "linux", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "freebsd", ++ target_os = "netbsd" ++))] + fn test_lutimes() { + let tempdir = tempfile::tempdir().unwrap(); + let target = tempdir.path().join("target"); +@@ -220,77 +248,174 @@ fn test_lutimes() { + symlink(&target, &fullpath).unwrap(); + + let exp_target_metadata = fs::symlink_metadata(&target).unwrap(); +- lutimes(&fullpath, &TimeVal::seconds(4560), &TimeVal::seconds(1230)).unwrap(); ++ lutimes(&fullpath, &TimeVal::seconds(4560), &TimeVal::seconds(1230)) ++ .unwrap(); + assert_times_eq(4560, 1230, &fs::symlink_metadata(&fullpath).unwrap()); + + let target_metadata = fs::symlink_metadata(&target).unwrap(); +- assert_eq!(exp_target_metadata.accessed().unwrap(), target_metadata.accessed().unwrap(), +- "atime of symlink target was unexpectedly modified"); +- assert_eq!(exp_target_metadata.modified().unwrap(), target_metadata.modified().unwrap(), +- "mtime of symlink target was unexpectedly modified"); ++ assert_eq!( ++ exp_target_metadata.accessed().unwrap(), ++ target_metadata.accessed().unwrap(), ++ "atime of symlink target was unexpectedly modified" ++ ); ++ assert_eq!( ++ exp_target_metadata.modified().unwrap(), ++ target_metadata.modified().unwrap(), ++ "mtime of symlink target was unexpectedly modified" ++ ); + } + + #[test] ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] + fn test_futimens() { + let tempdir = tempfile::tempdir().unwrap(); + let fullpath = tempdir.path().join("file"); + drop(File::create(&fullpath).unwrap()); + +- let fd = fcntl::open(&fullpath, fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); ++ let fd = fcntl::open(&fullpath, fcntl::OFlag::empty(), stat::Mode::empty()) ++ .unwrap(); + + futimens(fd, &TimeSpec::seconds(10), &TimeSpec::seconds(20)).unwrap(); + assert_times_eq(10, 20, &fs::metadata(&fullpath).unwrap()); + } + + #[test] ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] + fn test_utimensat() { +- let _dr = ::DirRestore::new(); ++ let _dr = crate::DirRestore::new(); + let tempdir = tempfile::tempdir().unwrap(); + let filename = "foo.txt"; + let fullpath = tempdir.path().join(filename); + drop(File::create(&fullpath).unwrap()); + +- let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); +- +- utimensat(Some(dirfd), filename, &TimeSpec::seconds(12345), &TimeSpec::seconds(678), +- UtimensatFlags::FollowSymlink).unwrap(); ++ let dirfd = ++ fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) ++ .unwrap(); ++ ++ utimensat( ++ Some(dirfd), ++ filename, ++ &TimeSpec::seconds(12345), ++ &TimeSpec::seconds(678), ++ UtimensatFlags::FollowSymlink, ++ ) ++ .unwrap(); + assert_times_eq(12345, 678, &fs::metadata(&fullpath).unwrap()); + + chdir(tempdir.path()).unwrap(); + +- utimensat(None, filename, &TimeSpec::seconds(500), &TimeSpec::seconds(800), +- UtimensatFlags::FollowSymlink).unwrap(); ++ utimensat( ++ None, ++ filename, ++ &TimeSpec::seconds(500), ++ &TimeSpec::seconds(800), ++ UtimensatFlags::FollowSymlink, ++ ) ++ .unwrap(); + assert_times_eq(500, 800, &fs::metadata(&fullpath).unwrap()); + } + + #[test] ++#[cfg(not(target_os = "redox"))] + fn test_mkdirat_success_path() { + let tempdir = tempfile::tempdir().unwrap(); + let filename = "example_subdir"; +- let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); +- assert!((mkdirat(dirfd, filename, Mode::S_IRWXU)).is_ok()); ++ let dirfd = ++ fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) ++ .unwrap(); ++ mkdirat(dirfd, filename, Mode::S_IRWXU).expect("mkdirat failed"); + assert!(Path::exists(&tempdir.path().join(filename))); + } + + #[test] ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] + fn test_mkdirat_success_mode() { +- let expected_bits = stat::SFlag::S_IFDIR.bits() | stat::Mode::S_IRWXU.bits(); ++ let expected_bits = ++ stat::SFlag::S_IFDIR.bits() | stat::Mode::S_IRWXU.bits(); + let tempdir = tempfile::tempdir().unwrap(); + let filename = "example_subdir"; +- let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); +- assert!((mkdirat(dirfd, filename, Mode::S_IRWXU)).is_ok()); +- let permissions = fs::metadata(tempdir.path().join(filename)).unwrap().permissions(); ++ let dirfd = ++ fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) ++ .unwrap(); ++ mkdirat(dirfd, filename, Mode::S_IRWXU).expect("mkdirat failed"); ++ let permissions = fs::metadata(tempdir.path().join(filename)) ++ .unwrap() ++ .permissions(); + let mode = permissions.mode(); + assert_eq!(mode as mode_t, expected_bits) + } + + #[test] ++#[cfg(not(target_os = "redox"))] + fn test_mkdirat_fail() { + let tempdir = tempfile::tempdir().unwrap(); +- let not_dir_filename= "example_not_dir"; ++ let not_dir_filename = "example_not_dir"; + let filename = "example_subdir_dir"; +- let dirfd = fcntl::open(&tempdir.path().join(not_dir_filename), fcntl::OFlag::O_CREAT, +- stat::Mode::empty()).unwrap(); ++ let dirfd = fcntl::open( ++ &tempdir.path().join(not_dir_filename), ++ fcntl::OFlag::O_CREAT, ++ stat::Mode::empty(), ++ ) ++ .unwrap(); + let result = mkdirat(dirfd, filename, Mode::S_IRWXU).unwrap_err(); +- assert_eq!(result, Error::Sys(Errno::ENOTDIR)); ++ assert_eq!(result, Errno::ENOTDIR); ++} ++ ++#[test] ++#[cfg(not(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "haiku", ++ target_os = "redox" ++)))] ++fn test_mknod() { ++ use stat::{lstat, mknod, SFlag}; ++ ++ let file_name = "test_file"; ++ let tempdir = tempfile::tempdir().unwrap(); ++ let target = tempdir.path().join(file_name); ++ mknod(&target, SFlag::S_IFREG, Mode::S_IRWXU, 0).unwrap(); ++ let mode = lstat(&target).unwrap().st_mode as mode_t; ++ assert_eq!(mode & libc::S_IFREG, libc::S_IFREG); ++ assert_eq!(mode & libc::S_IRWXU, libc::S_IRWXU); ++} ++ ++#[test] ++#[cfg(not(any( ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "illumos", ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "haiku", ++ target_os = "redox" ++)))] ++fn test_mknodat() { ++ use fcntl::{AtFlags, OFlag}; ++ use nix::dir::Dir; ++ use stat::{fstatat, mknodat, SFlag}; ++ ++ let file_name = "test_file"; ++ let tempdir = tempfile::tempdir().unwrap(); ++ let target_dir = ++ Dir::open(tempdir.path(), OFlag::O_DIRECTORY, Mode::S_IRWXU).unwrap(); ++ mknodat( ++ target_dir.as_raw_fd(), ++ file_name, ++ SFlag::S_IFREG, ++ Mode::S_IRWXU, ++ 0, ++ ) ++ .unwrap(); ++ let mode = fstatat( ++ target_dir.as_raw_fd(), ++ file_name, ++ AtFlags::AT_SYMLINK_NOFOLLOW, ++ ) ++ .unwrap() ++ .st_mode as mode_t; ++ assert_eq!(mode & libc::S_IFREG, libc::S_IFREG); ++ assert_eq!(mode & libc::S_IRWXU, libc::S_IRWXU); + } +diff --git a/vendor/nix/test/test_time.rs b/vendor/nix/test/test_time.rs +new file mode 100644 +index 0000000..5f76e61 +--- /dev/null ++++ b/vendor/nix/test/test_time.rs +@@ -0,0 +1,59 @@ ++#[cfg(any( ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "linux", ++ target_os = "android", ++ target_os = "emscripten", ++))] ++use nix::time::clock_getcpuclockid; ++use nix::time::{clock_gettime, ClockId}; ++ ++#[cfg(not(target_os = "redox"))] ++#[test] ++pub fn test_clock_getres() { ++ nix::time::clock_getres(ClockId::CLOCK_REALTIME).expect("assertion failed"); ++} ++ ++#[test] ++pub fn test_clock_gettime() { ++ clock_gettime(ClockId::CLOCK_REALTIME).expect("assertion failed"); ++} ++ ++#[cfg(any( ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "linux", ++ target_os = "android", ++ target_os = "emscripten", ++))] ++#[test] ++pub fn test_clock_getcpuclockid() { ++ let clock_id = clock_getcpuclockid(nix::unistd::Pid::this()).unwrap(); ++ clock_gettime(clock_id).unwrap(); ++} ++ ++#[cfg(not(target_os = "redox"))] ++#[test] ++pub fn test_clock_id_res() { ++ ClockId::CLOCK_REALTIME.res().unwrap(); ++} ++ ++#[test] ++pub fn test_clock_id_now() { ++ ClockId::CLOCK_REALTIME.now().unwrap(); ++} ++ ++#[cfg(any( ++ target_os = "freebsd", ++ target_os = "dragonfly", ++ target_os = "linux", ++ target_os = "android", ++ target_os = "emscripten", ++))] ++#[test] ++pub fn test_clock_id_pid_cpu_clock_id() { ++ ClockId::pid_cpu_clock_id(nix::unistd::Pid::this()) ++ .map(ClockId::now) ++ .unwrap() ++ .unwrap(); ++} +diff --git a/vendor/nix/test/test_timer.rs b/vendor/nix/test/test_timer.rs +new file mode 100644 +index 0000000..ffd1468 +--- /dev/null ++++ b/vendor/nix/test/test_timer.rs +@@ -0,0 +1,102 @@ ++use nix::sys::signal::{ ++ sigaction, SaFlags, SigAction, SigEvent, SigHandler, SigSet, SigevNotify, ++ Signal, ++}; ++use nix::sys::timer::{Expiration, Timer, TimerSetTimeFlags}; ++use nix::time::ClockId; ++use std::convert::TryFrom; ++use std::sync::atomic::{AtomicBool, Ordering}; ++use std::thread; ++use std::time::{Duration, Instant}; ++ ++const SIG: Signal = Signal::SIGALRM; ++static ALARM_CALLED: AtomicBool = AtomicBool::new(false); ++ ++pub extern "C" fn handle_sigalarm(raw_signal: libc::c_int) { ++ let signal = Signal::try_from(raw_signal).unwrap(); ++ if signal == SIG { ++ ALARM_CALLED.store(true, Ordering::Release); ++ } ++} ++ ++#[test] ++fn alarm_fires() { ++ // Avoid interfering with other signal using tests by taking a mutex shared ++ // among other tests in this crate. ++ let _m = crate::SIGNAL_MTX.lock(); ++ const TIMER_PERIOD: Duration = Duration::from_millis(100); ++ ++ // ++ // Setup ++ // ++ ++ // Create a handler for the test signal, `SIG`. The handler is responsible ++ // for flipping `ALARM_CALLED`. ++ let handler = SigHandler::Handler(handle_sigalarm); ++ let signal_action = ++ SigAction::new(handler, SaFlags::SA_RESTART, SigSet::empty()); ++ let old_handler = unsafe { ++ sigaction(SIG, &signal_action) ++ .expect("unable to set signal handler for alarm") ++ }; ++ ++ // Create the timer. We use the monotonic clock here, though any would do ++ // really. The timer is set to fire every 250 milliseconds with no delay for ++ // the initial firing. ++ let clockid = ClockId::CLOCK_MONOTONIC; ++ let sigevent = SigEvent::new(SigevNotify::SigevSignal { ++ signal: SIG, ++ si_value: 0, ++ }); ++ let mut timer = ++ Timer::new(clockid, sigevent).expect("failed to create timer"); ++ let expiration = Expiration::Interval(TIMER_PERIOD.into()); ++ let flags = TimerSetTimeFlags::empty(); ++ timer.set(expiration, flags).expect("could not set timer"); ++ ++ // ++ // Test ++ // ++ ++ // Determine that there's still an expiration tracked by the ++ // timer. Depending on when this runs either an `Expiration::Interval` or ++ // `Expiration::IntervalDelayed` will be present. That is, if the timer has ++ // not fired yet we'll get our original `expiration`, else the one that ++ // represents a delay to the next expiration. We're only interested in the ++ // timer still being extant. ++ match timer.get() { ++ Ok(Some(exp)) => assert!(matches!( ++ exp, ++ Expiration::Interval(..) | Expiration::IntervalDelayed(..) ++ )), ++ _ => panic!("timer lost its expiration"), ++ } ++ ++ // Wait for 2 firings of the alarm before checking that it has fired and ++ // been handled at least the once. If we wait for 3 seconds and the handler ++ // is never called something has gone sideways and the test fails. ++ let starttime = Instant::now(); ++ loop { ++ thread::sleep(2 * TIMER_PERIOD); ++ if ALARM_CALLED.load(Ordering::Acquire) { ++ break; ++ } ++ if starttime.elapsed() > Duration::from_secs(3) { ++ panic!("Timeout waiting for SIGALRM"); ++ } ++ } ++ ++ // Cleanup: ++ // 1) deregister the OS's timer. ++ // 2) Wait for a full timer period, since POSIX does not require that ++ // disabling the timer will clear pending signals, and on NetBSD at least ++ // it does not. ++ // 2) Replace the old signal handler now that we've completed the test. If ++ // the test fails this process panics, so the fact we might not get here ++ // is okay. ++ drop(timer); ++ thread::sleep(TIMER_PERIOD); ++ unsafe { ++ sigaction(SIG, &old_handler).expect("unable to reset signal handler"); ++ } ++} +diff --git a/vendor/nix/test/test_unistd.rs b/vendor/nix/test/test_unistd.rs +index 24e0c86..9e20f97 100644 +--- a/vendor/nix/test/test_unistd.rs ++++ b/vendor/nix/test/test_unistd.rs +@@ -1,26 +1,49 @@ +-use nix::fcntl::{self, fcntl, FcntlArg, FdFlag, open, OFlag, readlink}; +-use nix::unistd::*; +-use nix::unistd::ForkResult::*; +-use nix::sys::signal::{SaFlags, SigAction, SigHandler, SigSet, Signal, sigaction}; +-use nix::sys::wait::*; +-use nix::sys::stat::{self, Mode, SFlag}; ++use libc::{_exit, mode_t, off_t}; + use nix::errno::Errno; +-use nix::Error; +-use std::{env, iter}; ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] ++use nix::fcntl::readlink; ++use nix::fcntl::OFlag; ++#[cfg(not(target_os = "redox"))] ++use nix::fcntl::{self, open}; ++#[cfg(not(any( ++ target_os = "redox", ++ target_os = "fuchsia", ++ target_os = "haiku" ++)))] ++use nix::pty::{grantpt, posix_openpt, ptsname, unlockpt}; ++#[cfg(not(target_os = "redox"))] ++use nix::sys::signal::{ ++ sigaction, SaFlags, SigAction, SigHandler, SigSet, Signal, ++}; ++use nix::sys::stat::{self, Mode, SFlag}; ++use nix::sys::wait::*; ++use nix::unistd::ForkResult::*; ++use nix::unistd::*; ++use std::env; ++#[cfg(not(any(target_os = "fuchsia", target_os = "redox")))] + use std::ffi::CString; +-use std::fs::{self, DirBuilder, File}; ++#[cfg(not(target_os = "redox"))] ++use std::fs::DirBuilder; ++use std::fs::{self, File}; + use std::io::Write; + use std::os::unix::prelude::*; +-use tempfile::{self, tempfile}; +-use libc::{self, _exit, off_t}; ++#[cfg(not(any( ++ target_os = "fuchsia", ++ target_os = "redox", ++ target_os = "haiku" ++)))] ++use std::path::Path; ++use tempfile::{tempdir, tempfile}; ++ ++use crate::*; + + #[test] + #[cfg(not(any(target_os = "netbsd")))] + fn test_fork_and_waitpid() { +- let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::FORK_MTX.lock(); + + // Safe: Child only calls `_exit`, which is signal-safe +- match fork().expect("Error: Fork Failed") { ++ match unsafe { fork() }.expect("Error: Fork Failed") { + Child => unsafe { _exit(0) }, + Parent { child } => { + // assert that child was created and pid > 0 +@@ -29,33 +52,34 @@ fn test_fork_and_waitpid() { + let wait_status = waitpid(child, None); + match wait_status { + // assert that waitpid returned correct status and the pid is the one of the child +- Ok(WaitStatus::Exited(pid_t, _)) => assert_eq!(pid_t, child), ++ Ok(WaitStatus::Exited(pid_t, _)) => assert_eq!(pid_t, child), + + // panic, must never happen +- s @ Ok(_) => panic!("Child exited {:?}, should never happen", s), ++ s @ Ok(_) => { ++ panic!("Child exited {:?}, should never happen", s) ++ } + + // panic, waitpid should never fail +- Err(s) => panic!("Error: waitpid returned Err({:?}", s) ++ Err(s) => panic!("Error: waitpid returned Err({:?}", s), + } +- +- }, ++ } + } + } + + #[test] + fn test_wait() { + // Grab FORK_MTX so wait doesn't reap a different test's child process +- let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::FORK_MTX.lock(); + + // Safe: Child only calls `_exit`, which is signal-safe +- match fork().expect("Error: Fork Failed") { ++ match unsafe { fork() }.expect("Error: Fork Failed") { + Child => unsafe { _exit(0) }, + Parent { child } => { + let wait_status = wait(); + + // just assert that (any) one child returns with WaitStatus::Exited + assert_eq!(wait_status, Ok(WaitStatus::Exited(child, 0))); +- }, ++ } + } + } + +@@ -69,41 +93,49 @@ fn test_mkstemp() { + Ok((fd, path)) => { + close(fd).unwrap(); + unlink(path.as_path()).unwrap(); +- }, +- Err(e) => panic!("mkstemp failed: {}", e) ++ } ++ Err(e) => panic!("mkstemp failed: {}", e), + } + } + + #[test] + fn test_mkstemp_directory() { + // mkstemp should fail if a directory is given +- assert!(mkstemp(&env::temp_dir()).is_err()); ++ mkstemp(&env::temp_dir()).expect_err("assertion failed"); + } + + #[test] ++#[cfg(not(target_os = "redox"))] + fn test_mkfifo() { +- let tempdir = tempfile::tempdir().unwrap(); ++ let tempdir = tempdir().unwrap(); + let mkfifo_fifo = tempdir.path().join("mkfifo_fifo"); + + mkfifo(&mkfifo_fifo, Mode::S_IRUSR).unwrap(); + + let stats = stat::stat(&mkfifo_fifo).unwrap(); +- let typ = stat::SFlag::from_bits_truncate(stats.st_mode); +- assert!(typ == SFlag::S_IFIFO); ++ let typ = stat::SFlag::from_bits_truncate(stats.st_mode as mode_t); ++ assert_eq!(typ, SFlag::S_IFIFO); + } + + #[test] ++#[cfg(not(target_os = "redox"))] + fn test_mkfifo_directory() { + // mkfifo should fail if a directory is given +- assert!(mkfifo(&env::temp_dir(), Mode::S_IRUSR).is_err()); ++ mkfifo(&env::temp_dir(), Mode::S_IRUSR).expect_err("assertion failed"); + } + + #[test] +-#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))] ++#[cfg(not(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "android", ++ target_os = "redox", ++ target_os = "haiku" ++)))] + fn test_mkfifoat_none() { +- let _m = ::CWD_LOCK.read().expect("Mutex got poisoned by another test"); ++ let _m = crate::CWD_LOCK.read(); + +- let tempdir = tempfile::tempdir().unwrap(); ++ let tempdir = tempdir().unwrap(); + let mkfifoat_fifo = tempdir.path().join("mkfifoat_fifo"); + + mkfifoat(None, &mkfifoat_fifo, Mode::S_IRUSR).unwrap(); +@@ -114,38 +146,61 @@ fn test_mkfifoat_none() { + } + + #[test] +-#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))] ++#[cfg(not(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "android", ++ target_os = "redox", ++ target_os = "haiku" ++)))] + fn test_mkfifoat() { +- let tempdir = tempfile::tempdir().unwrap(); ++ use nix::fcntl; ++ ++ let tempdir = tempdir().unwrap(); + let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); + let mkfifoat_name = "mkfifoat_name"; + + mkfifoat(Some(dirfd), mkfifoat_name, Mode::S_IRUSR).unwrap(); + +- let stats = stat::fstatat(dirfd, mkfifoat_name, fcntl::AtFlags::empty()).unwrap(); ++ let stats = ++ stat::fstatat(dirfd, mkfifoat_name, fcntl::AtFlags::empty()).unwrap(); + let typ = stat::SFlag::from_bits_truncate(stats.st_mode); + assert_eq!(typ, SFlag::S_IFIFO); + } + + #[test] +-#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))] ++#[cfg(not(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "android", ++ target_os = "redox", ++ target_os = "haiku" ++)))] + fn test_mkfifoat_directory_none() { +- let _m = ::CWD_LOCK.read().expect("Mutex got poisoned by another test"); ++ let _m = crate::CWD_LOCK.read(); + + // mkfifoat should fail if a directory is given +- assert!(!mkfifoat(None, &env::temp_dir(), Mode::S_IRUSR).is_ok()); ++ mkfifoat(None, &env::temp_dir(), Mode::S_IRUSR) ++ .expect_err("assertion failed"); + } + + #[test] +-#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))] ++#[cfg(not(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "android", ++ target_os = "redox", ++ target_os = "haiku" ++)))] + fn test_mkfifoat_directory() { + // mkfifoat should fail if a directory is given +- let tempdir = tempfile::tempdir().unwrap(); ++ let tempdir = tempdir().unwrap(); + let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); + let mkfifoat_dir = "mkfifoat_dir"; + stat::mkdirat(dirfd, mkfifoat_dir, Mode::S_IRUSR).unwrap(); + +- assert!(!mkfifoat(Some(dirfd), mkfifoat_dir, Mode::S_IRUSR).is_ok()); ++ mkfifoat(Some(dirfd), mkfifoat_dir, Mode::S_IRUSR) ++ .expect_err("assertion failed"); + } + + #[test] +@@ -157,6 +212,7 @@ fn test_getpid() { + } + + #[test] ++#[cfg(not(target_os = "redox"))] + fn test_getsid() { + let none_sid: ::libc::pid_t = getsid(None).unwrap().into(); + let pid_sid: ::libc::pid_t = getsid(Some(getpid())).unwrap().into(); +@@ -177,12 +233,18 @@ mod linux_android { + + #[test] + // `getgroups()` and `setgroups()` do not behave as expected on Apple platforms +-#[cfg(not(any(target_os = "ios", target_os = "macos")))] ++#[cfg(not(any( ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "redox", ++ target_os = "fuchsia", ++ target_os = "haiku" ++)))] + fn test_setgroups() { + // Skip this test when not run as root as `setgroups()` requires root. + skip_if_not_root!("test_setgroups"); + +- let _m = ::GROUPS_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::GROUPS_MTX.lock(); + + // Save the existing groups + let old_groups = getgroups().unwrap(); +@@ -200,13 +262,20 @@ fn test_setgroups() { + + #[test] + // `getgroups()` and `setgroups()` do not behave as expected on Apple platforms +-#[cfg(not(any(target_os = "ios", target_os = "macos")))] ++#[cfg(not(any( ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "redox", ++ target_os = "fuchsia", ++ target_os = "haiku", ++ target_os = "illumos" ++)))] + fn test_initgroups() { + // Skip this test when not run as root as `initgroups()` and `setgroups()` + // require root. + skip_if_not_root!("test_initgroups"); + +- let _m = ::GROUPS_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::GROUPS_MTX.lock(); + + // Save the existing groups + let old_groups = getgroups().unwrap(); +@@ -230,17 +299,53 @@ fn test_initgroups() { + setgroups(&old_groups).unwrap(); + } + +-macro_rules! execve_test_factory( ++#[cfg(not(any(target_os = "fuchsia", target_os = "redox")))] ++macro_rules! execve_test_factory ( + ($test_name:ident, $syscall:ident, $exe: expr $(, $pathname:expr, $flags:expr)*) => ( +- #[test] +- fn $test_name() { ++ ++ #[cfg(test)] ++ mod $test_name { ++ use std::ffi::CStr; ++ use super::*; ++ ++ const EMPTY: &'static [u8] = b"\0"; ++ const DASH_C: &'static [u8] = b"-c\0"; ++ const BIGARG: &'static [u8] = b"echo nix!!! && echo foo=$foo && echo baz=$baz\0"; ++ const FOO: &'static [u8] = b"foo=bar\0"; ++ const BAZ: &'static [u8] = b"baz=quux\0"; ++ ++ fn syscall_cstr_ref() -> Result { ++ $syscall( ++ $exe, ++ $(CString::new($pathname).unwrap().as_c_str(), )* ++ &[CStr::from_bytes_with_nul(EMPTY).unwrap(), ++ CStr::from_bytes_with_nul(DASH_C).unwrap(), ++ CStr::from_bytes_with_nul(BIGARG).unwrap()], ++ &[CStr::from_bytes_with_nul(FOO).unwrap(), ++ CStr::from_bytes_with_nul(BAZ).unwrap()] ++ $(, $flags)*) ++ } ++ ++ fn syscall_cstring() -> Result { ++ $syscall( ++ $exe, ++ $(CString::new($pathname).unwrap().as_c_str(), )* ++ &[CString::from(CStr::from_bytes_with_nul(EMPTY).unwrap()), ++ CString::from(CStr::from_bytes_with_nul(DASH_C).unwrap()), ++ CString::from(CStr::from_bytes_with_nul(BIGARG).unwrap())], ++ &[CString::from(CStr::from_bytes_with_nul(FOO).unwrap()), ++ CString::from(CStr::from_bytes_with_nul(BAZ).unwrap())] ++ $(, $flags)*) ++ } ++ ++ fn common_test(syscall: fn() -> Result) { + if "execveat" == stringify!($syscall) { + // Though undocumented, Docker's default seccomp profile seems to + // block this syscall. https://github.com/nix-rust/nix/issues/1122 + skip_if_seccomp!($test_name); + } + +- let m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test"); ++ let m = crate::FORK_MTX.lock(); + // The `exec`d process will write to `writer`, and we'll read that + // data from `reader`. + let (reader, writer) = pipe().unwrap(); +@@ -248,20 +353,11 @@ macro_rules! execve_test_factory( + // Safe: Child calls `exit`, `dup`, `close` and the provided `exec*` family function. + // NOTE: Technically, this makes the macro unsafe to use because you could pass anything. + // The tests make sure not to do that, though. +- match fork().unwrap() { ++ match unsafe{fork()}.unwrap() { + Child => { + // Make `writer` be the stdout of the new process. + dup2(writer, 1).unwrap(); +- let r = $syscall( +- $exe, +- $(CString::new($pathname).unwrap().as_c_str(), )* +- &[CString::new(b"".as_ref()).unwrap().as_c_str(), +- CString::new(b"-c".as_ref()).unwrap().as_c_str(), +- CString::new(b"echo nix!!! && echo foo=$foo && echo baz=$baz" +- .as_ref()).unwrap().as_c_str()], +- &[CString::new(b"foo=bar".as_ref()).unwrap().as_c_str(), +- CString::new(b"baz=quux".as_ref()).unwrap().as_c_str()] +- $(, $flags)*); ++ let r = syscall(); + let _ = std::io::stderr() + .write_all(format!("{:?}", r).as_bytes()); + // Should only get here in event of error +@@ -283,44 +379,65 @@ macro_rules! execve_test_factory( + } + } + } ++ ++ // These tests frequently fail on musl, probably due to ++ // https://github.com/nix-rust/nix/issues/555 ++ #[cfg_attr(target_env = "musl", ignore)] ++ #[test] ++ fn test_cstr_ref() { ++ common_test(syscall_cstr_ref); ++ } ++ ++ // These tests frequently fail on musl, probably due to ++ // https://github.com/nix-rust/nix/issues/555 ++ #[cfg_attr(target_env = "musl", ignore)] ++ #[test] ++ fn test_cstring() { ++ common_test(syscall_cstring); ++ } ++ } ++ + ) + ); + +-cfg_if!{ ++cfg_if! { + if #[cfg(target_os = "android")] { + execve_test_factory!(test_execve, execve, CString::new("/system/bin/sh").unwrap().as_c_str()); + execve_test_factory!(test_fexecve, fexecve, File::open("/system/bin/sh").unwrap().into_raw_fd()); +- } else if #[cfg(any(target_os = "freebsd", ++ } else if #[cfg(any(target_os = "dragonfly", ++ target_os = "freebsd", + target_os = "linux"))] { ++ // These tests frequently fail on musl, probably due to ++ // https://github.com/nix-rust/nix/issues/555 + execve_test_factory!(test_execve, execve, CString::new("/bin/sh").unwrap().as_c_str()); + execve_test_factory!(test_fexecve, fexecve, File::open("/bin/sh").unwrap().into_raw_fd()); +- } else if #[cfg(any(target_os = "dragonfly", ++ } else if #[cfg(any(target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", +- target_os = "openbsd"))] { ++ target_os = "openbsd", ++ target_os = "solaris"))] { + execve_test_factory!(test_execve, execve, CString::new("/bin/sh").unwrap().as_c_str()); +- // No fexecve() on DragonFly, ios, macos, NetBSD, OpenBSD. +- // +- // Note for NetBSD and OpenBSD: although rust-lang/libc includes it +- // (under unix/bsd/netbsdlike/) fexecve is not currently implemented on +- // NetBSD nor on OpenBSD. ++ // No fexecve() on ios, macos, NetBSD, OpenBSD. + } + } + + #[cfg(any(target_os = "haiku", target_os = "linux", target_os = "openbsd"))] + execve_test_factory!(test_execvpe, execvpe, &CString::new("sh").unwrap()); + +-cfg_if!{ ++cfg_if! { + if #[cfg(target_os = "android")] { + use nix::fcntl::AtFlags; +- execve_test_factory!(test_execveat_empty, execveat, File::open("/system/bin/sh").unwrap().into_raw_fd(), ++ execve_test_factory!(test_execveat_empty, execveat, ++ File::open("/system/bin/sh").unwrap().into_raw_fd(), + "", AtFlags::AT_EMPTY_PATH); +- execve_test_factory!(test_execveat_relative, execveat, File::open("/system/bin/").unwrap().into_raw_fd(), ++ execve_test_factory!(test_execveat_relative, execveat, ++ File::open("/system/bin/").unwrap().into_raw_fd(), + "./sh", AtFlags::empty()); +- execve_test_factory!(test_execveat_absolute, execveat, File::open("/").unwrap().into_raw_fd(), ++ execve_test_factory!(test_execveat_absolute, execveat, ++ File::open("/").unwrap().into_raw_fd(), + "/system/bin/sh", AtFlags::empty()); +- } else if #[cfg(all(target_os = "linux"), any(target_arch ="x86_64", target_arch ="x86"))] { ++ } else if #[cfg(all(target_os = "linux", any(target_arch ="x86_64", target_arch ="x86")))] { + use nix::fcntl::AtFlags; + execve_test_factory!(test_execveat_empty, execveat, File::open("/bin/sh").unwrap().into_raw_fd(), + "", AtFlags::AT_EMPTY_PATH); +@@ -332,41 +449,43 @@ cfg_if!{ + } + + #[test] ++#[cfg(not(target_os = "fuchsia"))] + fn test_fchdir() { + // fchdir changes the process's cwd +- let _dr = ::DirRestore::new(); ++ let _dr = crate::DirRestore::new(); + +- let tmpdir = tempfile::tempdir().unwrap(); ++ let tmpdir = tempdir().unwrap(); + let tmpdir_path = tmpdir.path().canonicalize().unwrap(); + let tmpdir_fd = File::open(&tmpdir_path).unwrap().into_raw_fd(); + +- assert!(fchdir(tmpdir_fd).is_ok()); ++ fchdir(tmpdir_fd).expect("assertion failed"); + assert_eq!(getcwd().unwrap(), tmpdir_path); + +- assert!(close(tmpdir_fd).is_ok()); ++ close(tmpdir_fd).expect("assertion failed"); + } + + #[test] + fn test_getcwd() { + // chdir changes the process's cwd +- let _dr = ::DirRestore::new(); ++ let _dr = crate::DirRestore::new(); + +- let tmpdir = tempfile::tempdir().unwrap(); ++ let tmpdir = tempdir().unwrap(); + let tmpdir_path = tmpdir.path().canonicalize().unwrap(); +- assert!(chdir(&tmpdir_path).is_ok()); ++ chdir(&tmpdir_path).expect("assertion failed"); + assert_eq!(getcwd().unwrap(), tmpdir_path); + + // make path 500 chars longer so that buffer doubling in getcwd + // kicks in. Note: One path cannot be longer than 255 bytes + // (NAME_MAX) whole path cannot be longer than PATH_MAX (usually + // 4096 on linux, 1024 on macos) +- let mut inner_tmp_dir = tmpdir_path.to_path_buf(); ++ let mut inner_tmp_dir = tmpdir_path; + for _ in 0..5 { +- let newdir = iter::repeat("a").take(100).collect::(); ++ let newdir = "a".repeat(100); + inner_tmp_dir.push(newdir); +- assert!(mkdir(inner_tmp_dir.as_path(), Mode::S_IRWXU).is_ok()); ++ mkdir(inner_tmp_dir.as_path(), Mode::S_IRWXU) ++ .expect("assertion failed"); + } +- assert!(chdir(inner_tmp_dir.as_path()).is_ok()); ++ chdir(inner_tmp_dir.as_path()).expect("assertion failed"); + assert_eq!(getcwd().unwrap(), inner_tmp_dir.as_path()); + } + +@@ -376,7 +495,7 @@ fn test_chown() { + let uid = Some(getuid()); + let gid = Some(getgid()); + +- let tempdir = tempfile::tempdir().unwrap(); ++ let tempdir = tempdir().unwrap(); + let path = tempdir.path().join("file"); + { + File::create(&path).unwrap(); +@@ -391,13 +510,29 @@ fn test_chown() { + } + + #[test] ++fn test_fchown() { ++ // Testing for anything other than our own UID/GID is hard. ++ let uid = Some(getuid()); ++ let gid = Some(getgid()); ++ ++ let path = tempfile().unwrap(); ++ let fd = path.as_raw_fd(); ++ ++ fchown(fd, uid, gid).unwrap(); ++ fchown(fd, uid, None).unwrap(); ++ fchown(fd, None, gid).unwrap(); ++ fchown(999999999, uid, gid).unwrap_err(); ++} ++ ++#[test] ++#[cfg(not(target_os = "redox"))] + fn test_fchownat() { +- let _dr = ::DirRestore::new(); ++ let _dr = crate::DirRestore::new(); + // Testing for anything other than our own UID/GID is hard. + let uid = Some(getuid()); + let gid = Some(getgid()); + +- let tempdir = tempfile::tempdir().unwrap(); ++ let tempdir = tempdir().unwrap(); + let path = tempdir.path().join("file"); + { + File::create(&path).unwrap(); +@@ -405,7 +540,8 @@ fn test_fchownat() { + + let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); + +- fchownat(Some(dirfd), "file", uid, gid, FchownatFlags::FollowSymlink).unwrap(); ++ fchownat(Some(dirfd), "file", uid, gid, FchownatFlags::FollowSymlink) ++ .unwrap(); + + chdir(tempdir.path()).unwrap(); + fchownat(None, "file", uid, gid, FchownatFlags::FollowSymlink).unwrap(); +@@ -425,7 +561,7 @@ fn test_lseek() { + lseek(tmpfd, offset, Whence::SeekSet).unwrap(); + + let mut buf = [0u8; 7]; +- ::read_exact(tmpfd, &mut buf); ++ crate::read_exact(tmpfd, &mut buf); + assert_eq!(b"f123456", &buf); + + close(tmpfd).unwrap(); +@@ -442,17 +578,17 @@ fn test_lseek64() { + lseek64(tmpfd, 5, Whence::SeekSet).unwrap(); + + let mut buf = [0u8; 7]; +- ::read_exact(tmpfd, &mut buf); ++ crate::read_exact(tmpfd, &mut buf); + assert_eq!(b"f123456", &buf); + + close(tmpfd).unwrap(); + } + +-cfg_if!{ ++cfg_if! { + if #[cfg(any(target_os = "android", target_os = "linux"))] { + macro_rules! require_acct{ + () => { +- require_capability!(CAP_SYS_PACCT); ++ require_capability!("test_acct", CAP_SYS_PACCT); + } + } + } else if #[cfg(target_os = "freebsd")] { +@@ -462,7 +598,7 @@ cfg_if!{ + skip_if_jailed!("test_acct"); + } + } +- } else { ++ } else if #[cfg(not(any(target_os = "redox", target_os = "fuchsia", target_os = "haiku")))] { + macro_rules! require_acct{ + () => { + skip_if_not_root!("test_acct"); +@@ -472,12 +608,17 @@ cfg_if!{ + } + + #[test] ++#[cfg(not(any( ++ target_os = "redox", ++ target_os = "fuchsia", ++ target_os = "haiku" ++)))] + fn test_acct() { +- use tempfile::NamedTempFile; + use std::process::Command; + use std::{thread, time}; ++ use tempfile::NamedTempFile; + +- let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::FORK_MTX.lock(); + require_acct!(); + + let file = NamedTempFile::new().unwrap(); +@@ -486,9 +627,11 @@ fn test_acct() { + acct::enable(path).unwrap(); + + loop { +- Command::new("echo").arg("Hello world"); ++ Command::new("echo").arg("Hello world").output().unwrap(); + let len = fs::metadata(path).unwrap().len(); +- if len > 0 { break; } ++ if len > 0 { ++ break; ++ } + thread::sleep(time::Duration::from_millis(10)); + } + acct::disable().unwrap(); +@@ -499,21 +642,36 @@ fn test_fpathconf_limited() { + let f = tempfile().unwrap(); + // AFAIK, PATH_MAX is limited on all platforms, so it makes a good test + let path_max = fpathconf(f.as_raw_fd(), PathconfVar::PATH_MAX); +- assert!(path_max.expect("fpathconf failed").expect("PATH_MAX is unlimited") > 0); ++ assert!( ++ path_max ++ .expect("fpathconf failed") ++ .expect("PATH_MAX is unlimited") ++ > 0 ++ ); + } + + #[test] + fn test_pathconf_limited() { + // AFAIK, PATH_MAX is limited on all platforms, so it makes a good test + let path_max = pathconf("/", PathconfVar::PATH_MAX); +- assert!(path_max.expect("pathconf failed").expect("PATH_MAX is unlimited") > 0); ++ assert!( ++ path_max ++ .expect("pathconf failed") ++ .expect("PATH_MAX is unlimited") ++ > 0 ++ ); + } + + #[test] + fn test_sysconf_limited() { + // AFAIK, OPEN_MAX is limited on all platforms, so it makes a good test + let open_max = sysconf(SysconfVar::OPEN_MAX); +- assert!(open_max.expect("sysconf failed").expect("OPEN_MAX is unlimited") > 0); ++ assert!( ++ open_max ++ .expect("sysconf failed") ++ .expect("OPEN_MAX is unlimited") ++ > 0 ++ ); + } + + #[cfg(target_os = "freebsd")] +@@ -526,22 +684,70 @@ fn test_sysconf_unsupported() { + assert!(open_max.expect("sysconf failed").is_none()) + } + ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "linux", ++ target_os = "openbsd" ++))] ++#[test] ++fn test_getresuid() { ++ let resuids = getresuid().unwrap(); ++ assert_ne!(resuids.real.as_raw(), libc::uid_t::MAX); ++ assert_ne!(resuids.effective.as_raw(), libc::uid_t::MAX); ++ assert_ne!(resuids.saved.as_raw(), libc::uid_t::MAX); ++} ++ ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "freebsd", ++ target_os = "linux", ++ target_os = "openbsd" ++))] ++#[test] ++fn test_getresgid() { ++ let resgids = getresgid().unwrap(); ++ assert_ne!(resgids.real.as_raw(), libc::gid_t::MAX); ++ assert_ne!(resgids.effective.as_raw(), libc::gid_t::MAX); ++ assert_ne!(resgids.saved.as_raw(), libc::gid_t::MAX); ++} ++ + // Test that we can create a pair of pipes. No need to verify that they pass + // data; that's the domain of the OS, not nix. + #[test] + fn test_pipe() { + let (fd0, fd1) = pipe().unwrap(); +- let m0 = stat::SFlag::from_bits_truncate(stat::fstat(fd0).unwrap().st_mode); ++ let m0 = stat::SFlag::from_bits_truncate( ++ stat::fstat(fd0).unwrap().st_mode as mode_t, ++ ); + // S_IFIFO means it's a pipe + assert_eq!(m0, SFlag::S_IFIFO); +- let m1 = stat::SFlag::from_bits_truncate(stat::fstat(fd1).unwrap().st_mode); ++ let m1 = stat::SFlag::from_bits_truncate( ++ stat::fstat(fd1).unwrap().st_mode as mode_t, ++ ); + assert_eq!(m1, SFlag::S_IFIFO); + } + + // pipe2(2) is the same as pipe(2), except it allows setting some flags. Check + // that we can set a flag. ++#[cfg(any( ++ target_os = "android", ++ target_os = "dragonfly", ++ target_os = "emscripten", ++ target_os = "freebsd", ++ target_os = "illumos", ++ target_os = "linux", ++ target_os = "netbsd", ++ target_os = "openbsd", ++ target_os = "redox", ++ target_os = "solaris" ++))] + #[test] + fn test_pipe2() { ++ use nix::fcntl::{fcntl, FcntlArg, FdFlag}; ++ + let (fd0, fd1) = pipe2(OFlag::O_CLOEXEC).unwrap(); + let f0 = FdFlag::from_bits_truncate(fcntl(fd0, FcntlArg::F_GETFD).unwrap()); + assert!(f0.contains(FdFlag::FD_CLOEXEC)); +@@ -550,8 +756,9 @@ fn test_pipe2() { + } + + #[test] ++#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))] + fn test_truncate() { +- let tempdir = tempfile::tempdir().unwrap(); ++ let tempdir = tempdir().unwrap(); + let path = tempdir.path().join("file"); + + { +@@ -568,7 +775,7 @@ fn test_truncate() { + + #[test] + fn test_ftruncate() { +- let tempdir = tempfile::tempdir().unwrap(); ++ let tempdir = tempdir().unwrap(); + let path = tempdir.path().join("file"); + + let tmpfd = { +@@ -586,20 +793,35 @@ fn test_ftruncate() { + } + + // Used in `test_alarm`. ++#[cfg(not(target_os = "redox"))] + static mut ALARM_CALLED: bool = false; + + // Used in `test_alarm`. +-pub extern fn alarm_signal_handler(raw_signal: libc::c_int) { +- assert_eq!(raw_signal, libc::SIGALRM, "unexpected signal: {}", raw_signal); ++#[cfg(not(target_os = "redox"))] ++pub extern "C" fn alarm_signal_handler(raw_signal: libc::c_int) { ++ assert_eq!( ++ raw_signal, ++ libc::SIGALRM, ++ "unexpected signal: {}", ++ raw_signal ++ ); + unsafe { ALARM_CALLED = true }; + } + + #[test] ++#[cfg(not(target_os = "redox"))] + fn test_alarm() { +- let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); ++ use std::{ ++ thread, ++ time::{Duration, Instant}, ++ }; ++ ++ // Maybe other tests that fork interfere with this one? ++ let _m = crate::SIGNAL_MTX.lock(); + + let handler = SigHandler::Handler(alarm_signal_handler); +- let signal_action = SigAction::new(handler, SaFlags::SA_RESTART, SigSet::empty()); ++ let signal_action = ++ SigAction::new(handler, SaFlags::SA_RESTART, SigSet::empty()); + let old_handler = unsafe { + sigaction(Signal::SIGALRM, &signal_action) + .expect("unable to set signal handler for alarm") +@@ -611,10 +833,18 @@ fn test_alarm() { + // Overwriting an alarm should return the old alarm. + assert_eq!(alarm::set(1), Some(60)); + +- // We should be woken up after 1 second by the alarm, so we'll sleep for 2 ++ // We should be woken up after 1 second by the alarm, so we'll sleep for 3 + // seconds to be sure. +- sleep(2); +- assert_eq!(unsafe { ALARM_CALLED }, true, "expected our alarm signal handler to be called"); ++ let starttime = Instant::now(); ++ loop { ++ thread::sleep(Duration::from_millis(100)); ++ if unsafe { ALARM_CALLED } { ++ break; ++ } ++ if starttime.elapsed() > Duration::from_secs(3) { ++ panic!("Timeout waiting for SIGALRM"); ++ } ++ } + + // Reset the signal. + unsafe { +@@ -624,8 +854,9 @@ fn test_alarm() { + } + + #[test] ++#[cfg(not(target_os = "redox"))] + fn test_canceling_alarm() { +- let _m = ::SIGNAL_MTX.lock().expect("Mutex got poisoned by another test"); ++ let _m = crate::SIGNAL_MTX.lock(); + + assert_eq!(alarm::cancel(), None); + +@@ -634,10 +865,11 @@ fn test_canceling_alarm() { + } + + #[test] ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] + fn test_symlinkat() { +- let _m = ::CWD_LOCK.read().expect("Mutex got poisoned by another test"); ++ let _m = crate::CWD_LOCK.read(); + +- let tempdir = tempfile::tempdir().unwrap(); ++ let tempdir = tempdir().unwrap(); + + let target = tempdir.path().join("a"); + let linkpath = tempdir.path().join("b"); +@@ -661,8 +893,9 @@ fn test_symlinkat() { + } + + #[test] ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] + fn test_linkat_file() { +- let tempdir = tempfile::tempdir().unwrap(); ++ let tempdir = tempdir().unwrap(); + let oldfilename = "foo.txt"; + let oldfilepath = tempdir.path().join(oldfilename); + +@@ -670,70 +903,110 @@ fn test_linkat_file() { + let newfilepath = tempdir.path().join(newfilename); + + // Create file +- File::create(&oldfilepath).unwrap(); ++ File::create(oldfilepath).unwrap(); + + // Get file descriptor for base directory +- let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); ++ let dirfd = ++ fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) ++ .unwrap(); + + // Attempt hard link file at relative path +- linkat(Some(dirfd), oldfilename, Some(dirfd), newfilename, LinkatFlags::SymlinkFollow).unwrap(); ++ linkat( ++ Some(dirfd), ++ oldfilename, ++ Some(dirfd), ++ newfilename, ++ LinkatFlags::SymlinkFollow, ++ ) ++ .unwrap(); + assert!(newfilepath.exists()); + } + + #[test] ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] + fn test_linkat_olddirfd_none() { +- let _dr = ::DirRestore::new(); ++ let _dr = crate::DirRestore::new(); + +- let tempdir_oldfile = tempfile::tempdir().unwrap(); ++ let tempdir_oldfile = tempdir().unwrap(); + let oldfilename = "foo.txt"; + let oldfilepath = tempdir_oldfile.path().join(oldfilename); + +- let tempdir_newfile = tempfile::tempdir().unwrap(); ++ let tempdir_newfile = tempdir().unwrap(); + let newfilename = "bar.txt"; + let newfilepath = tempdir_newfile.path().join(newfilename); + + // Create file +- File::create(&oldfilepath).unwrap(); ++ File::create(oldfilepath).unwrap(); + + // Get file descriptor for base directory of new file +- let dirfd = fcntl::open(tempdir_newfile.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); ++ let dirfd = fcntl::open( ++ tempdir_newfile.path(), ++ fcntl::OFlag::empty(), ++ stat::Mode::empty(), ++ ) ++ .unwrap(); + + // Attempt hard link file using curent working directory as relative path for old file path + chdir(tempdir_oldfile.path()).unwrap(); +- linkat(None, oldfilename, Some(dirfd), newfilename, LinkatFlags::SymlinkFollow).unwrap(); ++ linkat( ++ None, ++ oldfilename, ++ Some(dirfd), ++ newfilename, ++ LinkatFlags::SymlinkFollow, ++ ) ++ .unwrap(); + assert!(newfilepath.exists()); + } + + #[test] ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] + fn test_linkat_newdirfd_none() { +- let _dr = ::DirRestore::new(); ++ let _dr = crate::DirRestore::new(); + +- let tempdir_oldfile = tempfile::tempdir().unwrap(); ++ let tempdir_oldfile = tempdir().unwrap(); + let oldfilename = "foo.txt"; + let oldfilepath = tempdir_oldfile.path().join(oldfilename); + +- let tempdir_newfile = tempfile::tempdir().unwrap(); ++ let tempdir_newfile = tempdir().unwrap(); + let newfilename = "bar.txt"; + let newfilepath = tempdir_newfile.path().join(newfilename); + + // Create file +- File::create(&oldfilepath).unwrap(); ++ File::create(oldfilepath).unwrap(); + + // Get file descriptor for base directory of old file +- let dirfd = fcntl::open(tempdir_oldfile.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); ++ let dirfd = fcntl::open( ++ tempdir_oldfile.path(), ++ fcntl::OFlag::empty(), ++ stat::Mode::empty(), ++ ) ++ .unwrap(); + + // Attempt hard link file using current working directory as relative path for new file path + chdir(tempdir_newfile.path()).unwrap(); +- linkat(Some(dirfd), oldfilename, None, newfilename, LinkatFlags::SymlinkFollow).unwrap(); ++ linkat( ++ Some(dirfd), ++ oldfilename, ++ None, ++ newfilename, ++ LinkatFlags::SymlinkFollow, ++ ) ++ .unwrap(); + assert!(newfilepath.exists()); + } + + #[test] +-#[cfg(not(any(target_os = "ios", target_os = "macos")))] ++#[cfg(not(any( ++ target_os = "ios", ++ target_os = "macos", ++ target_os = "redox", ++ target_os = "haiku" ++)))] + fn test_linkat_no_follow_symlink() { +- let _m = ::CWD_LOCK.read().expect("Mutex got poisoned by another test"); ++ let _m = crate::CWD_LOCK.read(); + +- let tempdir = tempfile::tempdir().unwrap(); ++ let tempdir = tempdir().unwrap(); + let oldfilename = "foo.txt"; + let oldfilepath = tempdir.path().join(oldfilename); + +@@ -750,26 +1023,33 @@ fn test_linkat_no_follow_symlink() { + symlinkat(&oldfilepath, None, &symoldfilepath).unwrap(); + + // Get file descriptor for base directory +- let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); ++ let dirfd = ++ fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) ++ .unwrap(); + + // Attempt link symlink of file at relative path +- linkat(Some(dirfd), symoldfilename, Some(dirfd), newfilename, LinkatFlags::NoSymlinkFollow).unwrap(); ++ linkat( ++ Some(dirfd), ++ symoldfilename, ++ Some(dirfd), ++ newfilename, ++ LinkatFlags::NoSymlinkFollow, ++ ) ++ .unwrap(); + + // Assert newfile is actually a symlink to oldfile. + assert_eq!( +- readlink(&newfilepath) +- .unwrap() +- .to_str() +- .unwrap(), ++ readlink(&newfilepath).unwrap().to_str().unwrap(), + oldfilepath.to_str().unwrap() + ); + } + + #[test] ++#[cfg(not(any(target_os = "redox", target_os = "haiku")))] + fn test_linkat_follow_symlink() { +- let _m = ::CWD_LOCK.read().expect("Mutex got poisoned by another test"); ++ let _m = crate::CWD_LOCK.read(); + +- let tempdir = tempfile::tempdir().unwrap(); ++ let tempdir = tempdir().unwrap(); + let oldfilename = "foo.txt"; + let oldfilepath = tempdir.path().join(oldfilename); + +@@ -786,40 +1066,58 @@ fn test_linkat_follow_symlink() { + symlinkat(&oldfilepath, None, &symoldfilepath).unwrap(); + + // Get file descriptor for base directory +- let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); ++ let dirfd = ++ fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) ++ .unwrap(); + + // Attempt link target of symlink of file at relative path +- linkat(Some(dirfd), symoldfilename, Some(dirfd), newfilename, LinkatFlags::SymlinkFollow).unwrap(); ++ linkat( ++ Some(dirfd), ++ symoldfilename, ++ Some(dirfd), ++ newfilename, ++ LinkatFlags::SymlinkFollow, ++ ) ++ .unwrap(); + + let newfilestat = stat::stat(&newfilepath).unwrap(); + + // Check the file type of the new link +- assert!((stat::SFlag::from_bits_truncate(newfilestat.st_mode) & SFlag::S_IFMT) == SFlag::S_IFREG); ++ assert_eq!( ++ (stat::SFlag::from_bits_truncate(newfilestat.st_mode as mode_t) ++ & SFlag::S_IFMT), ++ SFlag::S_IFREG ++ ); + + // Check the number of hard links to the original file + assert_eq!(newfilestat.st_nlink, 2); + } + + #[test] ++#[cfg(not(target_os = "redox"))] + fn test_unlinkat_dir_noremovedir() { +- let tempdir = tempfile::tempdir().unwrap(); ++ let tempdir = tempdir().unwrap(); + let dirname = "foo_dir"; + let dirpath = tempdir.path().join(dirname); + + // Create dir +- DirBuilder::new().recursive(true).create(&dirpath).unwrap(); ++ DirBuilder::new().recursive(true).create(dirpath).unwrap(); + + // Get file descriptor for base directory +- let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); ++ let dirfd = ++ fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) ++ .unwrap(); + + // Attempt unlink dir at relative path without proper flag +- let err_result = unlinkat(Some(dirfd), dirname, UnlinkatFlags::NoRemoveDir).unwrap_err(); +- assert!(err_result == Error::Sys(Errno::EISDIR) || err_result == Error::Sys(Errno::EPERM)); +- } ++ let err_result = ++ unlinkat(Some(dirfd), dirname, UnlinkatFlags::NoRemoveDir).unwrap_err(); ++ assert!(err_result == Errno::EISDIR || err_result == Errno::EPERM); ++} + + #[test] ++#[cfg(not(target_os = "redox"))] + fn test_unlinkat_dir_removedir() { +- let tempdir = tempfile::tempdir().unwrap(); ++ let tempdir = tempdir().unwrap(); + let dirname = "foo_dir"; + let dirpath = tempdir.path().join(dirname); + +@@ -827,16 +1125,19 @@ fn test_unlinkat_dir_removedir() { + DirBuilder::new().recursive(true).create(&dirpath).unwrap(); + + // Get file descriptor for base directory +- let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); ++ let dirfd = ++ fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) ++ .unwrap(); + + // Attempt unlink dir at relative path with proper flag + unlinkat(Some(dirfd), dirname, UnlinkatFlags::RemoveDir).unwrap(); + assert!(!dirpath.exists()); +- } ++} + + #[test] ++#[cfg(not(target_os = "redox"))] + fn test_unlinkat_file() { +- let tempdir = tempfile::tempdir().unwrap(); ++ let tempdir = tempdir().unwrap(); + let filename = "foo.txt"; + let filepath = tempdir.path().join(filename); + +@@ -844,25 +1145,263 @@ fn test_unlinkat_file() { + File::create(&filepath).unwrap(); + + // Get file descriptor for base directory +- let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); ++ let dirfd = ++ fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()) ++ .unwrap(); + + // Attempt unlink file at relative path + unlinkat(Some(dirfd), filename, UnlinkatFlags::NoRemoveDir).unwrap(); + assert!(!filepath.exists()); +- } ++} + + #[test] + fn test_access_not_existing() { +- let tempdir = tempfile::tempdir().unwrap(); ++ let tempdir = tempdir().unwrap(); + let dir = tempdir.path().join("does_not_exist.txt"); +- assert_eq!(access(&dir, AccessFlags::F_OK).err().unwrap().as_errno().unwrap(), +- Errno::ENOENT); ++ assert_eq!( ++ access(&dir, AccessFlags::F_OK).err().unwrap(), ++ Errno::ENOENT ++ ); + } + + #[test] + fn test_access_file_exists() { ++ let tempdir = tempdir().unwrap(); ++ let path = tempdir.path().join("does_exist.txt"); ++ let _file = File::create(path.clone()).unwrap(); ++ access(&path, AccessFlags::R_OK | AccessFlags::W_OK) ++ .expect("assertion failed"); ++} ++ ++//Clippy false positive https://github.com/rust-lang/rust-clippy/issues/9111 ++#[allow(clippy::needless_borrow)] ++#[cfg(not(target_os = "redox"))] ++#[test] ++fn test_user_into_passwd() { ++ // get the UID of the "nobody" user ++ #[cfg(not(target_os = "haiku"))] ++ let test_username = "nobody"; ++ // "nobody" unavailable on haiku ++ #[cfg(target_os = "haiku")] ++ let test_username = "user"; ++ ++ let nobody = User::from_name(test_username).unwrap().unwrap(); ++ let pwd: libc::passwd = nobody.into(); ++ let _: User = (&pwd).into(); ++} ++ ++/// Tests setting the filesystem UID with `setfsuid`. ++#[cfg(any(target_os = "linux", target_os = "android"))] ++#[test] ++fn test_setfsuid() { ++ use std::os::unix::fs::PermissionsExt; ++ use std::{fs, io, thread}; ++ require_capability!("test_setfsuid", CAP_SETUID); ++ ++ // get the UID of the "nobody" user ++ let nobody = User::from_name("nobody").unwrap().unwrap(); ++ ++ // create a temporary file with permissions '-rw-r-----' ++ let file = tempfile::NamedTempFile::new_in("/var/tmp").unwrap(); ++ let temp_path = file.into_temp_path(); ++ let temp_path_2 = temp_path.to_path_buf(); ++ let mut permissions = fs::metadata(&temp_path).unwrap().permissions(); ++ permissions.set_mode(0o640); ++ ++ // spawn a new thread where to test setfsuid ++ thread::spawn(move || { ++ // set filesystem UID ++ let fuid = setfsuid(nobody.uid); ++ // trying to open the temporary file should fail with EACCES ++ let res = fs::File::open(&temp_path); ++ let err = res.expect_err("assertion failed"); ++ assert_eq!(err.kind(), io::ErrorKind::PermissionDenied); ++ ++ // assert fuid actually changes ++ let prev_fuid = setfsuid(Uid::from_raw(-1i32 as u32)); ++ assert_ne!(prev_fuid, fuid); ++ }) ++ .join() ++ .unwrap(); ++ ++ // open the temporary file with the current thread filesystem UID ++ fs::File::open(temp_path_2).unwrap(); ++} ++ ++#[test] ++#[cfg(not(any( ++ target_os = "redox", ++ target_os = "fuchsia", ++ target_os = "haiku" ++)))] ++fn test_ttyname() { ++ let fd = posix_openpt(OFlag::O_RDWR).expect("posix_openpt failed"); ++ assert!(fd.as_raw_fd() > 0); ++ ++ // on linux, we can just call ttyname on the pty master directly, but ++ // apparently osx requires that ttyname is called on a slave pty (can't ++ // find this documented anywhere, but it seems to empirically be the case) ++ grantpt(&fd).expect("grantpt failed"); ++ unlockpt(&fd).expect("unlockpt failed"); ++ let sname = unsafe { ptsname(&fd) }.expect("ptsname failed"); ++ let fds = open(Path::new(&sname), OFlag::O_RDWR, stat::Mode::empty()) ++ .expect("open failed"); ++ assert!(fds > 0); ++ ++ let name = ttyname(fds).expect("ttyname failed"); ++ assert!(name.starts_with("/dev")); ++} ++ ++#[test] ++#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))] ++fn test_ttyname_not_pty() { ++ let fd = File::open("/dev/zero").unwrap(); ++ assert!(fd.as_raw_fd() > 0); ++ assert_eq!(ttyname(fd.as_raw_fd()), Err(Errno::ENOTTY)); ++} ++ ++#[test] ++#[cfg(not(any( ++ target_os = "redox", ++ target_os = "fuchsia", ++ target_os = "haiku" ++)))] ++fn test_ttyname_invalid_fd() { ++ assert_eq!(ttyname(-1), Err(Errno::EBADF)); ++} ++ ++#[test] ++#[cfg(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "freebsd", ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "dragonfly", ++))] ++fn test_getpeereid() { ++ use std::os::unix::net::UnixStream; ++ let (sock_a, sock_b) = UnixStream::pair().unwrap(); ++ ++ let (uid_a, gid_a) = getpeereid(sock_a.as_raw_fd()).unwrap(); ++ let (uid_b, gid_b) = getpeereid(sock_b.as_raw_fd()).unwrap(); ++ ++ let uid = geteuid(); ++ let gid = getegid(); ++ ++ assert_eq!(uid, uid_a); ++ assert_eq!(gid, gid_a); ++ assert_eq!(uid_a, uid_b); ++ assert_eq!(gid_a, gid_b); ++} ++ ++#[test] ++#[cfg(any( ++ target_os = "macos", ++ target_os = "ios", ++ target_os = "freebsd", ++ target_os = "openbsd", ++ target_os = "netbsd", ++ target_os = "dragonfly", ++))] ++fn test_getpeereid_invalid_fd() { ++ // getpeereid is not POSIX, so error codes are inconsistent between different Unices. ++ getpeereid(-1).expect_err("assertion failed"); ++} ++ ++#[test] ++#[cfg(not(target_os = "redox"))] ++fn test_faccessat_none_not_existing() { ++ use nix::fcntl::AtFlags; ++ let tempdir = tempfile::tempdir().unwrap(); ++ let dir = tempdir.path().join("does_not_exist.txt"); ++ assert_eq!( ++ faccessat(None, &dir, AccessFlags::F_OK, AtFlags::empty()) ++ .err() ++ .unwrap(), ++ Errno::ENOENT ++ ); ++} ++ ++#[test] ++#[cfg(not(target_os = "redox"))] ++fn test_faccessat_not_existing() { ++ use nix::fcntl::AtFlags; ++ let tempdir = tempfile::tempdir().unwrap(); ++ let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); ++ let not_exist_file = "does_not_exist.txt"; ++ assert_eq!( ++ faccessat( ++ Some(dirfd), ++ not_exist_file, ++ AccessFlags::F_OK, ++ AtFlags::empty(), ++ ) ++ .err() ++ .unwrap(), ++ Errno::ENOENT ++ ); ++} ++ ++#[test] ++#[cfg(not(target_os = "redox"))] ++fn test_faccessat_none_file_exists() { ++ use nix::fcntl::AtFlags; ++ let tempdir = tempfile::tempdir().unwrap(); ++ let path = tempdir.path().join("does_exist.txt"); ++ let _file = File::create(path.clone()).unwrap(); ++ assert!(faccessat( ++ None, ++ &path, ++ AccessFlags::R_OK | AccessFlags::W_OK, ++ AtFlags::empty(), ++ ) ++ .is_ok()); ++} ++ ++#[test] ++#[cfg(not(target_os = "redox"))] ++fn test_faccessat_file_exists() { ++ use nix::fcntl::AtFlags; + let tempdir = tempfile::tempdir().unwrap(); +- let path = tempdir.path().join("does_exist.txt"); ++ let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); ++ let exist_file = "does_exist.txt"; ++ let path = tempdir.path().join(exist_file); ++ let _file = File::create(path.clone()).unwrap(); ++ assert!(faccessat( ++ Some(dirfd), ++ &path, ++ AccessFlags::R_OK | AccessFlags::W_OK, ++ AtFlags::empty(), ++ ) ++ .is_ok()); ++} ++ ++#[test] ++#[cfg(any( ++ all(target_os = "linux", not(target_env = "uclibc")), ++ target_os = "freebsd", ++ target_os = "dragonfly" ++))] ++fn test_eaccess_not_existing() { ++ let tempdir = tempdir().unwrap(); ++ let dir = tempdir.path().join("does_not_exist.txt"); ++ assert_eq!( ++ eaccess(&dir, AccessFlags::F_OK).err().unwrap(), ++ Errno::ENOENT ++ ); ++} ++ ++#[test] ++#[cfg(any( ++ all(target_os = "linux", not(target_env = "uclibc")), ++ target_os = "freebsd", ++ target_os = "dragonfly" ++))] ++fn test_eaccess_file_exists() { ++ let tempdir = tempdir().unwrap(); ++ let path = tempdir.path().join("does_exist.txt"); + let _file = File::create(path.clone()).unwrap(); +- assert!(access(&path, AccessFlags::R_OK | AccessFlags::W_OK).is_ok()); ++ eaccess(&path, AccessFlags::R_OK | AccessFlags::W_OK) ++ .expect("assertion failed"); + } +diff --git a/vendor/pin-utils/.cargo-checksum.json b/vendor/pin-utils/.cargo-checksum.json +new file mode 100644 +index 0000000..9711659 +--- /dev/null ++++ b/vendor/pin-utils/.cargo-checksum.json +@@ -0,0 +1 @@ ++{"files":{"Cargo.toml":"0f8296bda5b928d57bb84443422f21db3aa35d6873ce651297634d80c183dc6b","LICENSE-APACHE":"a4db788775cb25f2da419a7ccd3f1f89c3d2cfa8748fb25257596b88183b4c77","LICENSE-MIT":"28802412d2bfbafe432b305634413b41a984d30fba0df41d30aa2c8a2077c5b1","README.md":"1b0cfd43afdfb6bb718a65f9fa9954b8de3a2638f155ee021465b35f0ae98336","src/lib.rs":"bed1d1c013f78036a7288ac3ebbe07c097d9a5a435b1367085484529d784b4e0","src/projection.rs":"18dbf1a747c3c4eec31768a51e1cfbce2ec83dc80dc44a5a80bb67b21ac5715d","src/stack_pin.rs":"b79661dc21f5ab923d75e3ddb52d43faf68fba7c7d592ec1929d1fd5275d70d8","tests/projection.rs":"04dd66b306e9d43d01a181da38add1ae8b8dee9e1fd16a3a0f39571cbb467f62","tests/stack_pin.rs":"2b2245ef1fb99176dd7fef74601fe6b69d394831e20dcdbd73268b34e17ce032"},"package":"8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"} +\ No newline at end of file +diff --git a/vendor/pin-utils/Cargo.toml b/vendor/pin-utils/Cargo.toml +new file mode 100644 +index 0000000..5e2f779 +--- /dev/null ++++ b/vendor/pin-utils/Cargo.toml +@@ -0,0 +1,22 @@ ++# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO ++# ++# When uploading crates to the registry Cargo will automatically ++# "normalize" Cargo.toml files for maximal compatibility ++# with all versions of Cargo and also rewrite `path` dependencies ++# to registry (e.g., crates.io) dependencies ++# ++# If you believe there's an error in this file please file an ++# issue against the rust-lang/cargo repository. If you're ++# editing this file be aware that the upstream Cargo.toml ++# will likely look very different (and much more reasonable) ++ ++[package] ++edition = "2018" ++name = "pin-utils" ++version = "0.1.0" ++authors = ["Josef Brandl "] ++description = "Utilities for pinning\n" ++documentation = "https://docs.rs/pin-utils" ++readme = "README.md" ++license = "MIT OR Apache-2.0" ++repository = "https://github.com/rust-lang-nursery/pin-utils" +diff --git a/vendor/cfg-if-0.1.10/LICENSE-APACHE b/vendor/pin-utils/LICENSE-APACHE +similarity index 99% +rename from vendor/cfg-if-0.1.10/LICENSE-APACHE +rename to vendor/pin-utils/LICENSE-APACHE +index 16fe87b..66ccced 100644 +--- a/vendor/cfg-if-0.1.10/LICENSE-APACHE ++++ b/vendor/pin-utils/LICENSE-APACHE +@@ -186,7 +186,7 @@ APPENDIX: How to apply the Apache License to your work. + same "printed page" as the copyright notice for easier + identification within third-party archives. + +-Copyright [yyyy] [name of copyright owner] ++Copyright 2018 The pin-utils authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. +diff --git a/vendor/cc/LICENSE-MIT b/vendor/pin-utils/LICENSE-MIT +similarity index 96% +rename from vendor/cc/LICENSE-MIT +rename to vendor/pin-utils/LICENSE-MIT +index 39e0ed6..06e51c4 100644 +--- a/vendor/cc/LICENSE-MIT ++++ b/vendor/pin-utils/LICENSE-MIT +@@ -1,4 +1,4 @@ +-Copyright (c) 2014 Alex Crichton ++Copyright (c) 2018 The pin-utils authors + + Permission is hereby granted, free of charge, to any + person obtaining a copy of this software and associated +diff --git a/vendor/pin-utils/README.md b/vendor/pin-utils/README.md +new file mode 100644 +index 0000000..93fdeb6 +--- /dev/null ++++ b/vendor/pin-utils/README.md +@@ -0,0 +1,42 @@ ++# pin-utils ++ ++Utilities for pinning ++ ++[![Build Status](https://travis-ci.com/rust-lang-nursery/pin-utils.svg?branch=master)](https://travis-ci.com/rust-lang-nursery/pin-utils) ++[![Crates.io](https://img.shields.io/crates/v/pin-utils.svg)](https://crates.io/crates/pin-utils) ++ ++[Documentation](https://docs.rs/pin-utils) ++ ++## Usage ++ ++First, add this to your `Cargo.toml`: ++ ++```toml ++[dependencies] ++pin-utils = "0.1.0-alpha.4" ++``` ++ ++Now, you can use it: ++ ++```rust ++use pin_utils::pin_mut; // And more... ++``` ++ ++The current version of pin-utils requires Rust 1.33 or later. ++ ++# License ++ ++This project is licensed under either of ++ ++ * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or ++ http://www.apache.org/licenses/LICENSE-2.0) ++ * MIT license ([LICENSE-MIT](LICENSE-MIT) or ++ http://opensource.org/licenses/MIT) ++ ++at your option. ++ ++### Contribution ++ ++Unless you explicitly state otherwise, any contribution intentionally submitted ++for inclusion in pin-utils by you, as defined in the Apache-2.0 license, shall be ++dual licensed as above, without any additional terms or conditions. +diff --git a/vendor/pin-utils/src/lib.rs b/vendor/pin-utils/src/lib.rs +new file mode 100644 +index 0000000..6198e98 +--- /dev/null ++++ b/vendor/pin-utils/src/lib.rs +@@ -0,0 +1,17 @@ ++//! Utilities for pinning ++ ++#![no_std] ++#![warn(missing_docs, missing_debug_implementations)] ++#![deny(bare_trait_objects)] ++#![allow(unknown_lints)] ++#![doc(html_root_url = "https://docs.rs/pin-utils/0.1.0")] ++ ++#[doc(hidden)] ++pub mod core_reexport { ++ pub use core::*; ++} ++ ++#[macro_use] ++mod stack_pin; ++#[macro_use] ++mod projection; +diff --git a/vendor/pin-utils/src/projection.rs b/vendor/pin-utils/src/projection.rs +new file mode 100644 +index 0000000..6af90c5 +--- /dev/null ++++ b/vendor/pin-utils/src/projection.rs +@@ -0,0 +1,100 @@ ++/// A pinned projection of a struct field. ++/// ++/// # Safety ++/// ++/// To make using this macro safe, three things need to be ensured: ++/// - If the struct implements [`Drop`], the [`drop`] method is not allowed to ++/// move the value of the field. ++/// - If the struct wants to implement [`Unpin`], it has to do so conditionally: ++/// The struct can only implement [`Unpin`] if the field's type is [`Unpin`]. ++/// - The struct must not be `#[repr(packed)]`. ++/// ++/// # Example ++/// ++/// ```rust ++/// use pin_utils::unsafe_pinned; ++/// use std::marker::Unpin; ++/// use std::pin::Pin; ++/// ++/// struct Foo { ++/// field: T, ++/// } ++/// ++/// impl Foo { ++/// unsafe_pinned!(field: T); ++/// ++/// fn baz(mut self: Pin<&mut Self>) { ++/// let _: Pin<&mut T> = self.field(); // Pinned reference to the field ++/// } ++/// } ++/// ++/// impl Unpin for Foo {} // Conditional Unpin impl ++/// ``` ++/// ++/// Note: borrowing the field multiple times requires using `.as_mut()` to ++/// avoid consuming the `Pin`. ++/// ++/// [`Unpin`]: core::marker::Unpin ++/// [`drop`]: Drop::drop ++#[macro_export] ++macro_rules! unsafe_pinned { ++ ($f:tt: $t:ty) => ( ++ #[allow(unsafe_code)] ++ fn $f<'__a>( ++ self: $crate::core_reexport::pin::Pin<&'__a mut Self> ++ ) -> $crate::core_reexport::pin::Pin<&'__a mut $t> { ++ unsafe { ++ $crate::core_reexport::pin::Pin::map_unchecked_mut( ++ self, |x| &mut x.$f ++ ) ++ } ++ } ++ ) ++} ++ ++/// An unpinned projection of a struct field. ++/// ++/// # Safety ++/// ++/// This macro is unsafe because it creates a method that returns a normal ++/// non-pin reference to the struct field. It is up to the programmer to ensure ++/// that the contained value can be considered not pinned in the current ++/// context. ++/// ++/// # Example ++/// ++/// ```rust ++/// use pin_utils::unsafe_unpinned; ++/// use std::pin::Pin; ++/// ++/// struct Bar; ++/// struct Foo { ++/// field: Bar, ++/// } ++/// ++/// impl Foo { ++/// unsafe_unpinned!(field: Bar); ++/// ++/// fn baz(mut self: Pin<&mut Self>) { ++/// let _: &mut Bar = self.field(); // Normal reference to the field ++/// } ++/// } ++/// ``` ++/// ++/// Note: borrowing the field multiple times requires using `.as_mut()` to ++/// avoid consuming the [`Pin`]. ++/// ++/// [`Pin`]: core::pin::Pin ++#[macro_export] ++macro_rules! unsafe_unpinned { ++ ($f:tt: $t:ty) => ( ++ #[allow(unsafe_code)] ++ fn $f<'__a>( ++ self: $crate::core_reexport::pin::Pin<&'__a mut Self> ++ ) -> &'__a mut $t { ++ unsafe { ++ &mut $crate::core_reexport::pin::Pin::get_unchecked_mut(self).$f ++ } ++ } ++ ) ++} +diff --git a/vendor/pin-utils/src/stack_pin.rs b/vendor/pin-utils/src/stack_pin.rs +new file mode 100644 +index 0000000..8a1ed2c +--- /dev/null ++++ b/vendor/pin-utils/src/stack_pin.rs +@@ -0,0 +1,25 @@ ++/// Pins a value on the stack. ++/// ++/// # Example ++/// ++/// ```rust ++/// # use pin_utils::pin_mut; ++/// # use core::pin::Pin; ++/// # struct Foo {} ++/// let foo = Foo { /* ... */ }; ++/// pin_mut!(foo); ++/// let _: Pin<&mut Foo> = foo; ++/// ``` ++#[macro_export] ++macro_rules! pin_mut { ++ ($($x:ident),* $(,)?) => { $( ++ // Move the value to ensure that it is owned ++ let mut $x = $x; ++ // Shadow the original binding so that it can't be directly accessed ++ // ever again. ++ #[allow(unused_mut)] ++ let mut $x = unsafe { ++ $crate::core_reexport::pin::Pin::new_unchecked(&mut $x) ++ }; ++ )* } ++} +diff --git a/vendor/pin-utils/tests/projection.rs b/vendor/pin-utils/tests/projection.rs +new file mode 100644 +index 0000000..492c26d +--- /dev/null ++++ b/vendor/pin-utils/tests/projection.rs +@@ -0,0 +1,27 @@ ++use pin_utils::{unsafe_pinned, unsafe_unpinned, pin_mut}; ++use std::pin::Pin; ++use std::marker::Unpin; ++ ++struct Foo { ++ field1: T1, ++ field2: T2, ++} ++ ++impl Foo { ++ unsafe_pinned!(field1: T1); ++ unsafe_unpinned!(field2: T2); ++} ++ ++impl Unpin for Foo {} // Conditional Unpin impl ++ ++#[test] ++fn projection() { ++ let foo = Foo { field1: 1, field2: 2 }; ++ pin_mut!(foo); ++ ++ let x1: Pin<&mut i32> = foo.as_mut().field1(); ++ assert_eq!(*x1, 1); ++ ++ let x2: &mut i32 = foo.as_mut().field2(); ++ assert_eq!(*x2, 2); ++} +diff --git a/vendor/pin-utils/tests/stack_pin.rs b/vendor/pin-utils/tests/stack_pin.rs +new file mode 100644 +index 0000000..4b6758d +--- /dev/null ++++ b/vendor/pin-utils/tests/stack_pin.rs +@@ -0,0 +1,21 @@ ++#![forbid(unsafe_code)] // pin_mut! is completely safe. ++ ++use pin_utils::pin_mut; ++use core::pin::Pin; ++ ++#[test] ++fn stack_pin() { ++ struct Foo {} ++ let foo = Foo {}; ++ pin_mut!(foo); ++ let _: Pin<&mut Foo> = foo; ++ ++ let bar = Foo {}; ++ let baz = Foo {}; ++ pin_mut!( ++ bar, ++ baz, ++ ); ++ let _: Pin<&mut Foo> = bar; ++ let _: Pin<&mut Foo> = baz; ++} +diff --git a/vendor/void/.cargo-checksum.json b/vendor/void/.cargo-checksum.json +deleted file mode 100644 +index 9554bcd..0000000 +--- a/vendor/void/.cargo-checksum.json ++++ /dev/null +@@ -1 +0,0 @@ +-{"files":{"Cargo.toml":"ea686f87a150a8e43c4b7db57c56d3eda2a4963420d5570d91d99d7d610dd3fb","README.md":"f85783a6fcf9ecc19edabd710775a88430d9e886f46728bfd7d65cef55ff3e73","src/lib.rs":"7ab8269f30715c0729b0e04e5a09be4c413664dc4b530746ea3240ac80a64c66"},"package":"6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"} +\ No newline at end of file +diff --git a/vendor/void/Cargo.toml b/vendor/void/Cargo.toml +deleted file mode 100644 +index 1a03139..0000000 +--- a/vendor/void/Cargo.toml ++++ /dev/null +@@ -1,15 +0,0 @@ +-[package] +- +-name = "void" +-version = "1.0.2" +-authors = ["Jonathan Reem "] +-repository = "https://github.com/reem/rust-void.git" +-description = "The uninhabited void type for use in statically impossible cases." +-readme = "README.md" +-license = "MIT" +- +-[features] +- +-default = ["std"] +-std = [] +- +diff --git a/vendor/void/README.md b/vendor/void/README.md +deleted file mode 100644 +index 4f86c21..0000000 +--- a/vendor/void/README.md ++++ /dev/null +@@ -1,39 +0,0 @@ +-# Void +- +-> The uninhabited void type for use in statically impossible cases. +- +-## [Documentation](https://crates.fyi/crates/void/1.0.1) +- +-The uninhabited type, `enum Void { }` is useful in dealing with cases you +-know to be impossible. For instance, if you are implementing a trait which +-allows for error checking, but your case always succeeds, you can mark the +-error case or type as `Void`, signaling to the compiler it can never happen. +- +-This crate also comes packed with a few traits offering extension methods to +-`Result` and `Result`. +- +-## Usage +- +-Use the crates.io repository; add this to your `Cargo.toml` along +-with the rest of your dependencies: +- +-```toml +-[dependencies] +-void = "1" +-``` +- +-Then, use `Void` in your crate: +- +-```rust +-extern crate void; +-use void::Void; +-``` +- +-## Author +- +-[Jonathan Reem](https://medium.com/@jreem) is the primary author and maintainer of void. +- +-## License +- +-MIT +- +diff --git a/vendor/void/src/lib.rs b/vendor/void/src/lib.rs +deleted file mode 100644 +index 3b6287c..0000000 +--- a/vendor/void/src/lib.rs ++++ /dev/null +@@ -1,121 +0,0 @@ +-#![cfg_attr(test, deny(warnings))] +-#![deny(missing_docs)] +-#![cfg_attr(not(feature = "std"), no_std)] +- +-//! # Void +-//! +-//! The uninhabited void type for use in statically impossible cases. +-//! +-//! In its own crate so all the users in the ecosystem can share the same type. +-//! This crate also comes ready with several extension traits for Result that add +-//! extra functionality to `Result` and `Result`. +-//! +- +-#[cfg(not(feature = "std"))] +-mod coreprovider { +- extern crate core; +- pub use core::{fmt, cmp}; +-} +- +-#[cfg(feature = "std")] +-mod coreprovider { +- pub use std::{fmt, cmp, error}; +-} +- +-use coreprovider::*; +- +-/// The empty type for cases which can't occur. +-#[derive(Copy)] +-pub enum Void { } +- +-impl Clone for Void { +- fn clone(&self) -> Void { +- unreachable(*self) +- } +-} +- +-impl fmt::Debug for Void { +- fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { +- unreachable(*self) +- } +-} +- +-impl fmt::Display for Void { +- fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { +- unreachable(*self) +- } +-} +- +-impl cmp::PartialEq for Void { +- fn eq(&self, _: &T) -> bool { +- unreachable(*self) +- } +-} +- +-impl cmp::PartialOrd for Void { +- fn partial_cmp(&self, _: &T) -> Option { +- unreachable(*self) +- } +-} +- +-#[cfg(feature = "std")] +-impl error::Error for Void { +- fn description(&self) -> &str { +- unreachable(*self) +- } +- +- fn cause(&self) -> Option<&error::Error> { +- unreachable(*self) +- } +-} +- +-/// A safe version of `intrinsincs::unreachable`. +-/// +-/// If this typechecks, anything that causes this to run is unreachable code. +-/// +-/// Calling this function in reachable code invokes undefined behavior, but +-/// should not be possible unless `unsafe` was used elsewhere to construct +-/// an instance of `Void` (which is already undefined behavior). +-#[inline(always)] +-pub fn unreachable(x: Void) -> ! { +- match x {} +-} +- +-/// Extensions to `Result` +-pub trait ResultVoidExt: Sized { +- /// Get the value out of a wrapper. +- fn void_unwrap(self) -> T; +-} +- +-impl ResultVoidExt for Result { +- /// Get the value out of an always-ok Result. +- /// +- /// Never panics, since it is statically known to be Ok. +- #[inline] +- fn void_unwrap(self) -> T { +- match self { +- Ok(val) => val, +- Err(e) => unreachable(e) +- } +- } +-} +- +-/// Extensions to `Result` +-pub trait ResultVoidErrExt: Sized { +- /// Get the error out of a wrapper. +- fn void_unwrap_err(self) -> E; +-} +- +-impl ResultVoidErrExt for Result { +- /// Get the error out of an always-err Result. +- /// +- /// Never panics, since it is statically known to be Err. +- #[inline] +- fn void_unwrap_err(self) -> E { +- match self { +- Ok(v) => unreachable(v), +- Err(e) => e +- } +- } +-} +-